Repository navigation
fix(openenv): raise on a step before reset, and end an episode whose end_turn is refused in an observation - #350
Conversation
…end_turn is refused in an observation RFC 015 has an imported env raise on a tool call before reset(), so an agent can't start an episode; AgentEnvEnvironment answered with an ended error observation instead. A step before the session's first reset now raises RuntimeError. Once a reset has happened, an ended episode still answers with the ended observation. Turn.end raises EpisodeError when the proxy no longer has the turn or refuses the reply, and _end_turn called it outside its error handler. It's inside now, so the episode ends in an error observation and is torn down. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f a fixed second The drain test slept 1s and then expected the drain set empty, but a loaded CI runner can take longer to start and finish the background child's sleep 0.4. It failed on both CI systems for an unrelated change. It now polls until the drain set is empty, failing after 10s. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… has Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| await asyncio.sleep(0.05) | ||
|
|
||
| await asyncio.wait_for(drained(), timeout=10) |
There was a problem hiding this comment.
Test timing settings lack names
The drain test uses an inline polling delay of 0.05 and timeout of 10. The repository requires magic numbers to be stored as class or instance variables with descriptive names. Name these settings so readers can tell what each controls. This repository requirement must be satisfied before merging.
Rule Used: Store magic numbers as class or instance variables with descriptive names rather than using them inline in the code. (source)
Learned From
scaleapi/scaleapi#126388
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/agentenv-protocol/tests/test_computer_extensions.py
Line: 170-172
Comment:
**Test timing settings lack names**
The drain test uses an inline polling delay of `0.05` and timeout of `10`. The repository requires magic numbers to be stored as class or instance variables with descriptive names. Name these settings so readers can tell what each controls. This repository requirement must be satisfied before merging.
**Rule Used:** Store magic numbers as class or instance variables with descriptive names rather than using them inline in the code. ([source](https://app.greptile.com/scale-ai/-/custom-context?memory=002e0051-41ad-46c1-9098-47433c580150))
**Learned From**
[scaleapi/scaleapi#126388](https://github.com/scaleapi/scaleapi/pull/126388)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Leaving these inline. This repo writes test timings inline, as this test already does two lines above (DRAIN_S patched to 0.1, the sleep 0.4) and as the package's other tests do (wait_for(..., timeout=1) in test_a2a_agent.py). The rule cited comes from another repository.
There was a problem hiding this comment.
You’re right. This package uses inline timing values, and the 0.05 polling interval and 10-second bound are consistent with that convention. I applied a shared magic-number instruction as though it were a requirement for this repo. I’m withdrawing the finding; no change is needed.
What and why
OpenEnv's review of the
agentenvimporter (openenv/OpenEnv#1493) checkedAgentEnvEnvironmentagainst RFC 015's contract for imported envs, and found two gaps:reset(), so an agent can't start an episode. OpenEnv's ORS wrapper raisesRuntimeError("Call reset() before invoking ORS tools").AgentEnvEnvironmentanswered with an ended error observation instead.RuntimeError, for either action, fromstep_asyncand from the worker-threadstep. Over OpenEnv's WebSocket the client gets an error message, and the session goes on.end_turnthe proxy refuses.Turn.endraisesEpisodeErrorwhen the proxy no longer has the turn (a 404) or refuses the reply._end_turncalled it outside its error handler, so the error escapedstep. It's inside the handler now, so the episode ends in an error observation and is torn down, like every other failure.Teardown was already safe. Closing a turn's tools does nothing that can fail, and
Episode.abandonwaits for the run withasyncio.wait, which doesn't re-raise the run's error. A new test pins this down: a teardown that fails still answers with an observation and frees the session. The observation is unscored, because the run's result reports the teardown error.Also, a flaky test.
test_a_background_apps_output_is_drained_after_the_call_returns(protocol package, computer extension) failed in this PR's first CI run, on both the unit job and CodeBuild.sleep 0.4.How it was tested
pytest tst/unit/openenv tst/unit/test_optional_extras_stay_optional.py: 69 passed.app_test), the refusedend_turn, and the failing teardown.pytest tst/integration/openenvon local Docker (macOS): 6 passed. The seventh failed building the echo agent image for linux/amd64 on this arm64 Mac, before the adapter runs; CI runs it on Linux.pytest packages/agentenv-protocol/tests -n 12, three times: 801 passed each time.ruff checkpasses.🤖 Generated with Claude Code
The timing settings need descriptive names to satisfy the repository rule before merging.
Fix with agent prompt
Summary
The PR makes OpenEnv reject steps before the first reset and return an ended error observation when
end_turnfails.Reviews (3) · Last reviewed commit: "test(protocol): bound the drain wait wit..." · Reviewed by Greptile