verifiers 0.4.1.dev50__tar.gz → 0.4.1.dev53__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/PKG-INFO +1 -5
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/pyproject.toml +0 -12
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/conftest.py +5 -5
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/agent_user.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/grid.py +108 -92
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_agent_user.py +2 -7
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_agentic_judge.py +3 -3
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_compose_scoring.py +51 -54
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_limits.py +2 -2
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_multi_turn.py +6 -6
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_multi_turn_tool.py +3 -3
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_multimodal_tool.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_network_policy.py +3 -10
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_resume_tool.py +2 -2
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_rubric_judge.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_sampling.py +1 -3
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_scoring_network.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_shared_tool.py +2 -2
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_single_turn.py +2 -2
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_skills.py +2 -2
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_tool_vms.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_user_echo.py +2 -2
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/conftest.py +8 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/runtimes/test_private_network.py +4 -4
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/test_agent.py +50 -17
- verifiers-0.4.1.dev53/tests/unit/test_runtimes.py +543 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/test_scoring_network.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/utils/test_compile.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/__init__.py +4 -4
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/acp/__init__.py +1 -5
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/agent.py +11 -12
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/clients/train.py +8 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/grading.py +6 -3
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/graph.py +41 -14
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/mini_swe_agent/harness.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/openclaw/harness.py +41 -8
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/terminus_2/harness.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/utils/launch.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/interception/tunnel/prime.py +1 -2
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/mcp/launch.py +22 -6
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/mcp/toolset.py +3 -3
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/rollout.py +9 -6
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/runtimes/__init__.py +32 -56
- verifiers-0.4.1.dev53/verifiers/v1/runtimes/backends/custom.py +93 -0
- verifiers-0.4.1.dev53/verifiers/v1/runtimes/backends/docker.py +874 -0
- {verifiers-0.4.1.dev50/verifiers/v1/runtimes → verifiers-0.4.1.dev53/verifiers/v1/runtimes/backends}/prime.py +13 -16
- {verifiers-0.4.1.dev50/verifiers/v1/runtimes → verifiers-0.4.1.dev53/verifiers/v1/runtimes/backends}/subprocess.py +23 -37
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/runtimes/base.py +87 -63
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/runtimes/compose.py +53 -56
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/runtimes/deployment.py +1 -3
- {verifiers-0.4.1.dev50/verifiers/v1/runtimes/docker → verifiers-0.4.1.dev53/verifiers/v1/runtimes}/egress.py +0 -25
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/runtimes/limiters.py +2 -2
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/runtimes/private_network.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/runtimes/runtime.py +21 -26
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/runtimes/strategies.py +6 -4
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/task.py +1 -1
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/trace.py +20 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/types.py +39 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/compile.py +22 -35
- verifiers-0.4.1.dev50/tests/unit/runtimes/test_e2b.py +0 -79
- verifiers-0.4.1.dev50/verifiers/v1/runtimes/apptainer.py +0 -216
- verifiers-0.4.1.dev50/verifiers/v1/runtimes/container.py +0 -336
- verifiers-0.4.1.dev50/verifiers/v1/runtimes/docker/__init__.py +0 -589
- verifiers-0.4.1.dev50/verifiers/v1/runtimes/e2b.py +0 -724
- verifiers-0.4.1.dev50/verifiers/v1/runtimes/modal.py +0 -443
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/.gitignore +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/LICENSE +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/README.md +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/agent_user_harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/counter_tool.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/duet.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/echo.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/echo_acp_resume.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/echo_agentic.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/echo_tool.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/echo_tool_compose/docker-compose.yaml +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/echo_user_sim.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/fetch_tool.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/network_policy.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/parallel.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/pyproject.toml +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/skill_codeword.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/skills/project-codeword/SKILL.md +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/fixtures/tool_response_image.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_examples.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_multi_agent.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_parallel.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_stateful_tool.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/integration/test_user_sim.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/cli/test_replay.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/harnesses/test_core.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/harnesses/test_rlm.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/interception/test_tunnel.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/judges/conftest.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/judges/test_judge.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/judges/test_reference.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/judges/test_rubric.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/serve/test_client.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/serve/test_delta.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/serve/test_pool.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/test_dialects.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/test_graph.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/test_harbor_grading_network.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/test_semantic.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/test_task.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/test_taskset.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/test_trace.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/utils/test_loaders.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/utils/test_platform.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/tests/unit/utils/test_score.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/acp/runner.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/dashboard/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/dashboard/base.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/dashboard/eval.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/dashboard/replay.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/dashboard/validate.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/debug.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/eval/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/eval/hint.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/eval/main.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/eval/resume.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/eval/runner.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/gepa.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/output.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/replay.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/resolve.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/resume.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/cli/validate.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/clients/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/clients/base.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/clients/client.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/clients/eval.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/agent.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/cli/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/cli/debug.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/cli/env.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/cli/eval.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/cli/replay.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/cli/validate.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/client.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/env.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/judge.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/retries.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/runtime.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/scoring.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/select.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/serve.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/task.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/configs/taskset.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/dialects/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/dialects/anthropic.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/dialects/base.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/dialects/chat.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/dialects/responses.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/env.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/envs/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/envs/agentic_judge/env.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/envs/best_of_n/env.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/envs/single_agent/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/envs/single_agent/env.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/envs/user_sim/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/envs/user_sim/env.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/episode.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/errors.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/gepa/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/gepa/adapter.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/gepa/config.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/gepa/dataset.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/gepa/reflection.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/gepa/runner.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/bash/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/bash/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/browser_use/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/browser_use/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/browser_use/program.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/claude_code/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/codex/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/codex/gate.mjs +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/codex/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/deepseek/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/deepseek/gate.mjs +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/deepseek/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/deepseek/usage.mjs +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/hermes_agent/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/hermes_agent/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/hermes_agent/program.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/node.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/null/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/null/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/openclaw/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/opencode/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/opencode/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/opencode/mcp-ready.js +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/pi/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/pi/gate.mjs +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/pi/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/prime_agent/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/prime_agent/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/rlm/harness.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/utils/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/utils/compaction.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/utils/core.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/utils/install.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/utils/mcp.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/harnesses/utils/replay.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/interception/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/interception/base.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/interception/pool.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/interception/server.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/interception/tunnel/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/interception/tunnel/base.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/interception/tunnel/custom.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/judge.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/judges/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/judges/decision.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/judges/reference.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/judges/reference.txt +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/judges/rubric.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/judges/rubric.txt +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/mcp/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/mcp/server.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/semantic.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/serve/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/serve/client.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/serve/delta.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/serve/encoding.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/serve/pool.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/serve/server.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/serve/types.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/session.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/state.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/taskset.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/harbor/toolset.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/nemo_gym/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/nemo_gym/response.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/nemo_gym/server.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/nemo_gym/taskset.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/nemo_gym/toolset.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/__init__.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/aio.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/artifacts.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/decorators.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/env.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/eval.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/format.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/generic.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/git.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/image.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/interrupt.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/loaders.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/logging.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/memory.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/paths.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/platform.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/prime.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/retries.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/scope.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/score.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/trace_store.py +0 -0
- {verifiers-0.4.1.dev50 → verifiers-0.4.1.dev53}/verifiers/v1/utils/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: verifiers
|
|
3
|
-
Version: 0.4.1.
|
|
3
|
+
Version: 0.4.1.dev53
|
|
4
4
|
Summary: Verifiers: Environments for LLM Reinforcement Learning
|
|
5
5
|
Project-URL: Homepage, https://github.com/primeintellect-ai/verifiers
|
|
6
6
|
Project-URL: Documentation, https://github.com/primeintellect-ai/verifiers
|
|
@@ -46,12 +46,8 @@ Requires-Dist: tenacity>=8.5.0
|
|
|
46
46
|
Requires-Dist: tomli-w>=1.0.0
|
|
47
47
|
Requires-Dist: typing-extensions>=4.12.2
|
|
48
48
|
Requires-Dist: uvicorn>=0.52.0
|
|
49
|
-
Provides-Extra: e2b
|
|
50
|
-
Requires-Dist: e2b<3,>=2.35.0; extra == 'e2b'
|
|
51
49
|
Provides-Extra: harbor
|
|
52
50
|
Requires-Dist: harbor==0.24.0; (python_full_version >= '3.12') and extra == 'harbor'
|
|
53
|
-
Provides-Extra: modal
|
|
54
|
-
Requires-Dist: modal>=1.5.4; extra == 'modal'
|
|
55
51
|
Provides-Extra: openenv
|
|
56
52
|
Requires-Dist: openenv>=0.4.1; extra == 'openenv'
|
|
57
53
|
Provides-Extra: ta
|
|
@@ -96,14 +96,6 @@ harbor = [
|
|
|
96
96
|
# Harbor currently publishes Python 3.12+ packages; keep core verifiers installable on 3.11.
|
|
97
97
|
"harbor==0.24.0 ; python_full_version >= '3.12'",
|
|
98
98
|
]
|
|
99
|
-
modal = [
|
|
100
|
-
"modal>=1.5.4",
|
|
101
|
-
]
|
|
102
|
-
e2b = [
|
|
103
|
-
# <3: the runtime swaps the SDK command handle's private stream decoders for
|
|
104
|
-
# byte-accurate live output (see runtimes/e2b.py _byte_handle).
|
|
105
|
-
"e2b>=2.35.0,<3",
|
|
106
|
-
]
|
|
107
99
|
openenv = [
|
|
108
100
|
"openenv>=0.4.1",
|
|
109
101
|
]
|
|
@@ -225,11 +217,7 @@ markers = [
|
|
|
225
217
|
# is applied per axis, so it matches every cell touching that value on any axis.
|
|
226
218
|
"subprocess: integration cells touching the subprocess (host) runtime",
|
|
227
219
|
"docker: integration cells touching the docker runtime",
|
|
228
|
-
"podman: integration cells touching the podman runtime (needs the engine on the host; local-only)",
|
|
229
|
-
"apptainer: integration cells touching the apptainer runtime (needs the engine on the host; local-only)",
|
|
230
220
|
"prime: integration cells touching the prime runtime (real sandbox + tunnel)",
|
|
231
|
-
"modal: integration cells touching the modal runtime (external sandbox; local-only, excluded in CI)",
|
|
232
|
-
"e2b: integration cells touching the e2b runtime (external sandbox; local-only, excluded in CI)",
|
|
233
221
|
"colocated: integration cells with a tool server colocated in the harness runtime",
|
|
234
222
|
"service: integration cells with a tool server in a Compose service beside the harness",
|
|
235
223
|
"null: integration cells on the null harness",
|
|
@@ -5,8 +5,8 @@ model-driven tests skip.
|
|
|
5
5
|
|
|
6
6
|
Each behavior module fixes one task and fans it across the harness x runtime grid in
|
|
7
7
|
`grid.py`, which also says why a cell is skipped. `run` drives the `Env` API in-process,
|
|
8
|
-
the calls the eval CLI makes. The placement fixtures below are indirect-only: they
|
|
9
|
-
`indirect=True` fails loudly.
|
|
8
|
+
the calls the eval CLI makes. The placement fixtures below are indirect-only: they
|
|
9
|
+
translate a parametrized value, and using one without `indirect=True` fails loudly.
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
import asyncio
|
|
@@ -54,7 +54,7 @@ def tool_runtime(request) -> dict:
|
|
|
54
54
|
return {"service": "tools"}
|
|
55
55
|
if request.param == "service-vm":
|
|
56
56
|
return {"service": "tools-vm"}
|
|
57
|
-
return {"runtime":
|
|
57
|
+
return {"runtime": runtime_config(request.param)}
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
# Built-in harnesses are bundled in the `harnesses` package; the agent CLIs (`rlm` /
|
|
@@ -180,7 +180,7 @@ def run():
|
|
|
180
180
|
makes (`serving`, `slots`, `run_slot`, retries included), without its run
|
|
181
181
|
directory, platform push, or dashboard. The Examples job covers that CLI layer."""
|
|
182
182
|
|
|
183
|
-
async def
|
|
183
|
+
async def _episodes(taskset: str, **kwargs) -> list[Episode]:
|
|
184
184
|
config = _eval_config(taskset, **kwargs)
|
|
185
185
|
env = load_environment(config.env)
|
|
186
186
|
tasks = list(env.taskset.select(config.select))
|
|
@@ -198,7 +198,7 @@ def run():
|
|
|
198
198
|
)
|
|
199
199
|
)
|
|
200
200
|
|
|
201
|
-
return
|
|
201
|
+
return _episodes
|
|
202
202
|
|
|
203
203
|
|
|
204
204
|
@pytest.fixture
|
|
@@ -90,7 +90,7 @@ class ScriptedAgentUserHarness(Harness[HarnessConfig]):
|
|
|
90
90
|
"uv_script": script[-1],
|
|
91
91
|
"read_secret_api": read_api,
|
|
92
92
|
}
|
|
93
|
-
return await runtime.
|
|
93
|
+
return await runtime.run(["sh", "-c", PROBE], {})
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
class AgentUserData(vf.TaskData):
|
|
@@ -2,35 +2,31 @@
|
|
|
2
2
|
cell is skipped.
|
|
3
3
|
|
|
4
4
|
Each behavior module fixes one task and fans it over `grid(...)`: every bundled harness
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
capability the code declares, never from a list of names, so the grid follows
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
CI deselects `podman`, `apptainer`, `modal` and `e2b` by mark: local engines and external
|
|
21
|
-
sandboxes.
|
|
5
|
+
on Prime, the production runtime. The basic single- and multi-turn behaviors also run
|
|
6
|
+
on the host (`DEBUG_RUNTIMES`), which needs no container. Docker cells run on the CI
|
|
7
|
+
runner itself and make the jobs too slow, so the Docker runtime is covered by
|
|
8
|
+
`tests/unit/test_runtimes.py` instead. Every reason a cell cannot run derives
|
|
9
|
+
from a capability the code declares, never from a list of names, so the grid follows
|
|
10
|
+
the code.
|
|
11
|
+
|
|
12
|
+
A harness without a capability the behavior needs is collected as a skip with its
|
|
13
|
+
reason (`Harness.EXECUTES_CODE`, `SUPPORTS_MCP`, `SUPPORTS_SKILLS`, resume support via
|
|
14
|
+
`SUPPORTS_RESUME` or a native session).
|
|
15
|
+
|
|
16
|
+
A runtime without a feature the behavior needs (`RuntimeBackend.SUPPORTS_*`, or a
|
|
17
|
+
`NetworkPolicyConfig` for a network policy) skips the cell the same way. That a runtime
|
|
18
|
+
refuses an undeclared feature, with a message naming it, is tested in
|
|
19
|
+
`tests/unit/test_runtimes.py`.
|
|
22
20
|
|
|
23
21
|
Every cell carries its axes' marks, so `-m` selects subsets:
|
|
24
22
|
|
|
25
|
-
uv run pytest tests/integration -n 8 -m "
|
|
26
|
-
uv run pytest tests/integration -n 8 -m
|
|
27
|
-
uv run pytest tests/integration -n 8 -m e2b # local
|
|
23
|
+
uv run pytest tests/integration -n 8 -m "prime and codex"
|
|
24
|
+
uv run pytest tests/integration -n 8 -m prime
|
|
28
25
|
|
|
29
26
|
`terminus-2` (drives the host tmux) and `browser-use` (needs its Playwright image, which
|
|
30
27
|
prime cannot pull) stay outside the grid.
|
|
31
28
|
"""
|
|
32
29
|
|
|
33
|
-
import shutil
|
|
34
30
|
from collections.abc import Sequence
|
|
35
31
|
from typing import get_args
|
|
36
32
|
|
|
@@ -40,7 +36,7 @@ from pydantic import TypeAdapter
|
|
|
40
36
|
import verifiers.v1 as vf
|
|
41
37
|
from verifiers.v1.configs.runtime import NetworkPolicyConfig
|
|
42
38
|
from verifiers.v1.harness import Harness
|
|
43
|
-
from verifiers.v1.runtimes import RuntimeConfig,
|
|
39
|
+
from verifiers.v1.runtimes import RuntimeConfig, backend_cls
|
|
44
40
|
from verifiers.v1.utils.loaders import harness_class, harness_config_type
|
|
45
41
|
|
|
46
42
|
HARNESSES: list[str | dict] = [
|
|
@@ -58,20 +54,48 @@ HARNESSES: list[str | dict] = [
|
|
|
58
54
|
"mini-swe-agent",
|
|
59
55
|
"prime-agent",
|
|
60
56
|
]
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
#
|
|
65
|
-
|
|
57
|
+
DEBUG_RUNTIMES = ("subprocess",)
|
|
58
|
+
RUNTIMES = (*DEBUG_RUNTIMES, "prime")
|
|
59
|
+
|
|
60
|
+
# The runtime features a behavior can need, as `needs` names them.
|
|
61
|
+
RUNTIME_FEATURES = {
|
|
62
|
+
"container": "task images",
|
|
63
|
+
"user": "running as another user",
|
|
64
|
+
"network": "network policies",
|
|
65
|
+
"expose": "port exposure",
|
|
66
|
+
"compose": "Compose services",
|
|
67
|
+
}
|
|
66
68
|
|
|
67
69
|
# Harnesses that cannot run against the CI model yet.
|
|
68
70
|
# TODO: drop each entry once its fix lands.
|
|
69
71
|
CI_MODEL_GAPS = {
|
|
70
72
|
"kimi-code": "Prime chat completions rejects kimi-code's prompt_cache_key",
|
|
71
|
-
"openclaw": "openclaw cannot load the custom `internal/` model provider",
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
|
|
76
|
+
# Harnesses whose program rewrites earlier turns by design, so a rollout can record
|
|
77
|
+
# several branches. Each test names the ones it lets fork. Recheck on version bumps.
|
|
78
|
+
FORKS = {
|
|
79
|
+
# Acts only through tool calls: it drops a tool-less reply from its history and
|
|
80
|
+
# resends only its format error.
|
|
81
|
+
"mini-swe-agent": "https://github.com/SWE-agent/mini-swe-agent/blob/v2.4.6/src/minisweagent/agents/default.py#L114",
|
|
82
|
+
# Moves its runtime-context message to the tail of every request and drops the
|
|
83
|
+
# earlier one, unless the provider's replay policy is append-only.
|
|
84
|
+
"openclaw": "https://github.com/openclaw/openclaw/blob/v2026.9.5/src/agents/internal-runtime-context.ts#L402-L408",
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def assert_one_branch(
|
|
89
|
+
trace: vf.Trace, harness: vf.HarnessConfig, forks: Sequence[str] = ()
|
|
90
|
+
) -> None:
|
|
91
|
+
"""A rollout records one branch, unless its harness is one of `forks` (see `FORKS`)."""
|
|
92
|
+
assert set(forks) <= FORKS.keys(), (
|
|
93
|
+
f"no FORKS reason for {set(forks) - FORKS.keys()}"
|
|
94
|
+
)
|
|
95
|
+
if harness.id not in forks:
|
|
96
|
+
assert trace.num_branches == 1, f"{trace.num_branches} branches"
|
|
97
|
+
|
|
98
|
+
|
|
75
99
|
def agent_seats(taskset: str, env_id: str = "") -> list[str]:
|
|
76
100
|
"""The agent seats the env declares for `taskset`: `agent` for a plain taskset, its
|
|
77
101
|
own roles for a recipe env."""
|
|
@@ -94,26 +118,31 @@ def mark(name: str) -> pytest.MarkDecorator:
|
|
|
94
118
|
def runtime_config(runtime: str, harness: str | dict | None = None) -> dict:
|
|
95
119
|
config: dict = {"type": runtime}
|
|
96
120
|
program = harness is not None and harness_class(harness_id(harness)).NEEDS_CONTAINER
|
|
97
|
-
#
|
|
98
|
-
# starves rlm's ACP startup, and prime's 1 CPU / 2 GB gets openclaw terminated.
|
|
99
|
-
if runtime == "e2b":
|
|
100
|
-
config["memory"] = 2.0
|
|
121
|
+
# Prime's default 1 CPU / 2 GB is too small to install and run an agent CLI.
|
|
101
122
|
if runtime == "prime" and program:
|
|
102
123
|
config.update(cpu=2.0, memory=4.0)
|
|
103
124
|
return config
|
|
104
125
|
|
|
105
126
|
|
|
106
127
|
def runtime_cls(runtime: str) -> type:
|
|
107
|
-
return
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def runtime_supports_user(runtime: str) -> bool:
|
|
111
|
-
return runtime_cls(runtime).supports_user
|
|
128
|
+
return backend_cls(
|
|
129
|
+
TypeAdapter(RuntimeConfig).validate_python(runtime_config(runtime))
|
|
130
|
+
)
|
|
112
131
|
|
|
113
132
|
|
|
114
|
-
def
|
|
115
|
-
|
|
116
|
-
|
|
133
|
+
def supports(runtime: str, feature: str) -> bool:
|
|
134
|
+
"""Whether the runtime declares `feature`: a backend flag, or, for a network policy,
|
|
135
|
+
a config that inherits `NetworkPolicyConfig`."""
|
|
136
|
+
if feature == "network":
|
|
137
|
+
config = TypeAdapter(RuntimeConfig).validate_python(runtime_config(runtime))
|
|
138
|
+
return isinstance(config, NetworkPolicyConfig)
|
|
139
|
+
flag = {
|
|
140
|
+
"container": "SUPPORTS_TASK_IMAGES",
|
|
141
|
+
"user": "SUPPORTS_USER_SWITCHING",
|
|
142
|
+
"expose": "SUPPORTS_PORT_EXPOSURE",
|
|
143
|
+
"compose": "SUPPORTS_COMPOSE",
|
|
144
|
+
}[feature]
|
|
145
|
+
return getattr(runtime_cls(runtime), flag)
|
|
117
146
|
|
|
118
147
|
|
|
119
148
|
def resumes(cls: type[Harness]) -> bool:
|
|
@@ -129,13 +158,10 @@ def resumes(cls: type[Harness]) -> bool:
|
|
|
129
158
|
def unsupported(
|
|
130
159
|
harness: str | dict, runtime: str, needs: tuple[str, ...]
|
|
131
160
|
) -> str | None:
|
|
132
|
-
"""Why this cell cannot run, or None when it can
|
|
161
|
+
"""Why this cell cannot run, or None when it can: a capability the behavior needs
|
|
162
|
+
that the harness or the runtime does not declare."""
|
|
133
163
|
name = harness_id(harness)
|
|
134
164
|
cls = harness_class(name)
|
|
135
|
-
if runtime in ENGINES and shutil.which(runtime) is None:
|
|
136
|
-
return f"needs {runtime} on the host"
|
|
137
|
-
if runtime == "subprocess" and cls.NEEDS_CONTAINER:
|
|
138
|
-
return f"{name} needs a container runtime"
|
|
139
165
|
if "shell" in needs and not cls.EXECUTES_CODE:
|
|
140
166
|
return f"{name} gives the model no shell"
|
|
141
167
|
if "mcp" in needs and not cls.SUPPORTS_MCP:
|
|
@@ -144,43 +170,48 @@ def unsupported(
|
|
|
144
170
|
return f"{name} has no native skill support"
|
|
145
171
|
if "resume" in needs and not resumes(cls):
|
|
146
172
|
return f"{name} cannot resume an exchange"
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return
|
|
173
|
+
runtime_needs = (*(("container",) if cls.NEEDS_CONTAINER else ()), *needs)
|
|
174
|
+
for feature in runtime_needs:
|
|
175
|
+
if feature in RUNTIME_FEATURES and not supports(runtime, feature):
|
|
176
|
+
return f"{runtime} does not support {RUNTIME_FEATURES[feature]}"
|
|
177
|
+
return CI_MODEL_GAPS.get(name)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def cell_marks(
|
|
181
|
+
harness: str | dict, runtime: str, needs: tuple[str, ...]
|
|
182
|
+
) -> list[pytest.MarkDecorator]:
|
|
183
|
+
if reason := unsupported(harness, runtime, needs):
|
|
184
|
+
return [pytest.mark.skip(reason=reason)]
|
|
185
|
+
return []
|
|
152
186
|
|
|
153
187
|
|
|
154
188
|
def runtimes_grid(
|
|
155
|
-
runtimes: Sequence[str] =
|
|
189
|
+
runtimes: Sequence[str] = ("prime",), *, needs: tuple[str, ...] = ()
|
|
156
190
|
) -> list:
|
|
157
191
|
"""`harness_runtime` cells for a behavior with no harness axis."""
|
|
158
192
|
cells = []
|
|
159
193
|
for runtime in runtimes:
|
|
160
|
-
marks = [mark(runtime)]
|
|
161
|
-
if reason := unsupported("null", runtime, needs):
|
|
162
|
-
marks.append(pytest.mark.skip(reason=reason))
|
|
194
|
+
marks = [mark(runtime), *cell_marks("null", runtime, needs)]
|
|
163
195
|
cells.append(pytest.param(runtime, marks=marks, id=f"harness-in-{runtime}"))
|
|
164
196
|
return cells
|
|
165
197
|
|
|
166
198
|
|
|
167
199
|
def grid(
|
|
168
200
|
harnesses: Sequence[str | dict] = HARNESSES,
|
|
169
|
-
runtimes: Sequence[str] =
|
|
201
|
+
runtimes: Sequence[str] = ("prime",),
|
|
170
202
|
*,
|
|
171
203
|
needs: tuple[str, ...] = (),
|
|
172
204
|
) -> list:
|
|
173
|
-
"""`(harness, harness_runtime)` cells, each marked by its axes
|
|
174
|
-
|
|
205
|
+
"""`(harness, harness_runtime)` cells, each marked by its axes, skipped where the
|
|
206
|
+
harness or the runtime rules the behavior out."""
|
|
175
207
|
cells = []
|
|
176
208
|
for harness in harnesses:
|
|
177
209
|
for runtime in runtimes:
|
|
178
|
-
marks = [
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
marks.append(pytest.mark.skip(reason=reason))
|
|
210
|
+
marks = [
|
|
211
|
+
mark(harness_id(harness)),
|
|
212
|
+
mark(runtime),
|
|
213
|
+
*cell_marks(harness, runtime, needs),
|
|
214
|
+
]
|
|
184
215
|
cells.append(
|
|
185
216
|
pytest.param(
|
|
186
217
|
harness,
|
|
@@ -239,45 +270,30 @@ def skip_harness(cells: list, harness: str, reason: str) -> list:
|
|
|
239
270
|
|
|
240
271
|
|
|
241
272
|
def placements(
|
|
242
|
-
harness_runtimes: tuple[str, ...] =
|
|
243
|
-
tool_runtimes: tuple[str, ...] = ("colocated",
|
|
273
|
+
harness_runtimes: tuple[str, ...] = ("prime",),
|
|
274
|
+
tool_runtimes: tuple[str, ...] = ("colocated", "subprocess", "prime"),
|
|
244
275
|
*,
|
|
245
276
|
shared: bool = False,
|
|
246
277
|
) -> list:
|
|
247
278
|
"""`(harness_runtime, tool_runtime)` cells for a tool server placed colocated in the
|
|
248
279
|
harness's box, in a Compose service beside it (`service`), or in its own runtime
|
|
249
|
-
(on Prime beside a Prime harness, a VM on the rollout's private network). A
|
|
250
|
-
server
|
|
280
|
+
(on Prime beside a Prime harness, a VM on the rollout's private network). A
|
|
281
|
+
`subprocess` tool runtime is a server on the host, reached from the sandbox through
|
|
282
|
+
the tunnel. A `shared` server runs once per eval, so it joins no rollout's network."""
|
|
251
283
|
cells = []
|
|
252
284
|
for harness_runtime in harness_runtimes:
|
|
253
285
|
for tool_runtime in tool_runtimes:
|
|
254
286
|
marks = [mark(harness_runtime), mark(tool_runtime)]
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
marks.append(pytest.mark.skip(reason=f"needs {missing[0]} on the host"))
|
|
262
|
-
elif tool_runtime == "service" and harness_runtime not in COMPOSE_VMS:
|
|
263
|
-
marks.append(
|
|
264
|
-
pytest.mark.skip(
|
|
265
|
-
reason="a tool server in a Compose service needs Compose on a "
|
|
266
|
-
"Prime or Modal VM"
|
|
267
|
-
)
|
|
268
|
-
)
|
|
269
|
-
elif (
|
|
270
|
-
tool_runtime not in ("colocated", "service")
|
|
271
|
-
and not runtime_cls(tool_runtime).supports_expose
|
|
272
|
-
# Beside a Prime harness, a rollout's Prime server joins its private network.
|
|
273
|
-
and not (not shared and tool_runtime == harness_runtime == "prime")
|
|
287
|
+
reason = None
|
|
288
|
+
if tool_runtime == "service":
|
|
289
|
+
reason = unsupported("null", harness_runtime, ("compose",))
|
|
290
|
+
# Beside a Prime harness, a rollout's Prime server joins its private network.
|
|
291
|
+
elif tool_runtime != "colocated" and not (
|
|
292
|
+
not shared and tool_runtime == harness_runtime == "prime"
|
|
274
293
|
):
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
"there is reachable only colocated"
|
|
279
|
-
)
|
|
280
|
-
)
|
|
294
|
+
reason = unsupported("null", tool_runtime, ("expose",))
|
|
295
|
+
if reason:
|
|
296
|
+
marks.append(pytest.mark.skip(reason=reason))
|
|
281
297
|
cells.append(
|
|
282
298
|
pytest.param(
|
|
283
299
|
harness_runtime,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
upstream (agent-user-harness), on the runtimes that can switch users."""
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
|
-
from grid import grid, runtimes_grid
|
|
6
|
+
from grid import assert_one_branch, grid, runtimes_grid
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
@pytest.mark.parametrize(
|
|
@@ -52,11 +52,6 @@ async def test_agent_user_harness(run, harness, harness_runtime, scripted_model)
|
|
|
52
52
|
client=scripted_model,
|
|
53
53
|
)
|
|
54
54
|
(trace,) = episode.traces
|
|
55
|
-
|
|
56
|
-
# scripted "OK") from its history and resends only its format error, so the
|
|
57
|
-
# trace forks by design. Recheck on version bumps:
|
|
58
|
-
# https://github.com/SWE-agent/mini-swe-agent/blob/v2.4.6/src/minisweagent/agents/default.py#L114
|
|
59
|
-
if harness.id != "mini-swe-agent":
|
|
60
|
-
assert trace.num_branches == 1
|
|
55
|
+
assert_one_branch(trace, harness, forks=("mini-swe-agent",))
|
|
61
56
|
assert trace.ok, [error.message for error in trace.errors]
|
|
62
57
|
assert trace.num_turns >= 1
|
|
@@ -13,7 +13,7 @@ async def test_agentic_judge_shared_verifier(run, tmp_path):
|
|
|
13
13
|
"id": "agentic-judge",
|
|
14
14
|
"solver": {
|
|
15
15
|
"harness": {"id": "bash"},
|
|
16
|
-
"runtime": {"type": "
|
|
16
|
+
"runtime": {"type": "prime", "block": ["example.com"]},
|
|
17
17
|
"scoring": {"mode": "shared"},
|
|
18
18
|
},
|
|
19
19
|
"judge": {
|
|
@@ -59,7 +59,7 @@ async def test_env_id_agentic_judge(run, tmp_path):
|
|
|
59
59
|
"id": "agentic-judge",
|
|
60
60
|
"solver": {
|
|
61
61
|
"harness": {"id": "bash"},
|
|
62
|
-
"runtime": {"type": "
|
|
62
|
+
"runtime": {"type": "prime", "block": ["example.com"]},
|
|
63
63
|
"scoring": {"mode": "isolated"},
|
|
64
64
|
},
|
|
65
65
|
"judge": {
|
|
@@ -84,7 +84,7 @@ async def test_env_id_agentic_judge(run, tmp_path):
|
|
|
84
84
|
assert judge.agent.trainable is False
|
|
85
85
|
assert solver.agent.runtime is not None and judge.agent.runtime is not None
|
|
86
86
|
assert solver.agent.runtime.id != judge.agent.runtime.id
|
|
87
|
-
assert solver.agent.runtime.type == judge.agent.runtime.type == "
|
|
87
|
+
assert solver.agent.runtime.type == judge.agent.runtime.type == "prime"
|
|
88
88
|
assert "/app/answer.txt" in solver.state.artifacts
|
|
89
89
|
assert solver.rewards["wrote_phrase"].score == 1.0
|
|
90
90
|
assert solver.rewards["wrote_phrase"].weight == 0.5
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"""Compose scoring uses live shared services or a released, collected submission
|
|
1
|
+
"""Compose scoring uses live shared services or a released, collected submission, on
|
|
2
|
+
a Prime VM."""
|
|
2
3
|
|
|
3
|
-
import
|
|
4
|
+
import os
|
|
4
5
|
|
|
5
6
|
import pytest
|
|
6
7
|
|
|
7
8
|
import verifiers.v1 as vf
|
|
8
9
|
from verifiers.v1.configs.agent import TimeoutConfig
|
|
9
|
-
from verifiers.v1.runtimes.container import cli
|
|
10
10
|
from verifiers.v1.tasksets.harbor.taskset import (
|
|
11
11
|
CollectHook,
|
|
12
12
|
HarborArtifact,
|
|
@@ -14,10 +14,8 @@ from verifiers.v1.tasksets.harbor.taskset import (
|
|
|
14
14
|
HarborTask,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
pytest.mark.skipif(not shutil.which("docker"), reason="needs Docker"),
|
|
20
|
-
]
|
|
17
|
+
# Solver service backends by trace id, to check their VM is gone before grading.
|
|
18
|
+
SOLVERS: dict[str, list] = {}
|
|
21
19
|
|
|
22
20
|
IMAGE = "python:3.11-slim"
|
|
23
21
|
COMPOSE = f"""
|
|
@@ -44,7 +42,7 @@ services:
|
|
|
44
42
|
|
|
45
43
|
class ComposeHarness(vf.Harness):
|
|
46
44
|
async def launch(self, ctx, trace, runtime, endpoint, secret, mcp_urls, data):
|
|
47
|
-
return await runtime.
|
|
45
|
+
return await runtime.run(
|
|
48
46
|
[
|
|
49
47
|
"python",
|
|
50
48
|
"-c",
|
|
@@ -61,23 +59,18 @@ class ComposeTask(HarborTask):
|
|
|
61
59
|
async def setup(self, trace, runtime, deployment=None):
|
|
62
60
|
await super().setup(runtime)
|
|
63
61
|
if deployment is not None:
|
|
64
|
-
trace.
|
|
65
|
-
runtime.info.id for runtime in deployment.target_backends.values()
|
|
66
|
-
]
|
|
62
|
+
SOLVERS[trace.id] = list(deployment.target_backends.values())
|
|
67
63
|
else:
|
|
68
|
-
# Fresh verifier setup happens only after the solver
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
64
|
+
# Fresh verifier setup happens only after the solver VM is removed.
|
|
65
|
+
assert all(
|
|
66
|
+
backend._host_backend.stopped for backend in SOLVERS[trace.id]
|
|
67
|
+
), "solver services survived into grading"
|
|
72
68
|
trace.info["solver_released_before_grading"] = True
|
|
73
69
|
|
|
74
70
|
async def finalize_services(self, trace, targets):
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
"inspect",
|
|
78
|
-
"--format",
|
|
79
|
-
"{{.State.Running}}",
|
|
80
|
-
targets["main"].info.id,
|
|
71
|
+
main = targets["main"].backend
|
|
72
|
+
result = await main._run_host(
|
|
73
|
+
"docker", "inspect", "--format", "{{.State.Running}}", main._container
|
|
81
74
|
)
|
|
82
75
|
assert result.stdout.strip() == "false", (
|
|
83
76
|
"workspace must stop before sidecar collection"
|
|
@@ -101,7 +94,43 @@ class ComposeTask(HarborTask):
|
|
|
101
94
|
"isolated-scoring-timeout",
|
|
102
95
|
],
|
|
103
96
|
)
|
|
97
|
+
@pytest.mark.prime
|
|
98
|
+
@pytest.mark.skipif(not os.environ.get("PRIME_API_KEY"), reason="needs PRIME_API_KEY")
|
|
104
99
|
async def test_compose_scoring(tmp_path, mode, collect_fails, scoring_timeout):
|
|
100
|
+
task = compose_task(tmp_path, collect_fails, scoring_timeout, mode)
|
|
101
|
+
config = vf.AgentConfig(
|
|
102
|
+
model="unused",
|
|
103
|
+
runtime=vf.PrimeConfig(labels=["vf-ci"]),
|
|
104
|
+
scoring=vf.ScoringConfig(
|
|
105
|
+
mode=mode,
|
|
106
|
+
env={"EXPECT_SIDECAR": "1" if mode == "isolated" else "0"},
|
|
107
|
+
retries=vf.RetryConfig(max_retries=0),
|
|
108
|
+
),
|
|
109
|
+
timeout=TimeoutConfig(
|
|
110
|
+
setup=600, finalize=60, scoring=1 if scoring_timeout else 120
|
|
111
|
+
),
|
|
112
|
+
)
|
|
113
|
+
async with vf.Agent(config) as agent:
|
|
114
|
+
agent.harness = ComposeHarness(vf.HarnessConfig())
|
|
115
|
+
trace = await agent.run(task)
|
|
116
|
+
assert all(backend._host_backend.stopped for backend in SOLVERS.pop(trace.id, []))
|
|
117
|
+
if mode == "isolated" and collect_fails:
|
|
118
|
+
assert not trace.ok
|
|
119
|
+
assert "collect hook failed" in str(trace.errors)
|
|
120
|
+
assert "solver_released_before_grading" not in trace.info
|
|
121
|
+
elif scoring_timeout:
|
|
122
|
+
assert trace.ok and trace.is_timeout and not trace.errors
|
|
123
|
+
assert trace.stop_condition == "scoring_timeout"
|
|
124
|
+
assert all(reward is None for reward in trace.rewards.values())
|
|
125
|
+
else:
|
|
126
|
+
assert trace.ok and trace.reward == 1, trace.errors
|
|
127
|
+
assert bool(trace.info.get("collected_sidecars")) == (mode == "isolated")
|
|
128
|
+
assert bool(trace.info.get("solver_released_before_grading")) == (
|
|
129
|
+
mode == "isolated"
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def compose_task(tmp_path, collect_fails: bool, scoring_timeout: bool, mode: str):
|
|
105
134
|
environment = tmp_path / "environment"
|
|
106
135
|
environment.mkdir()
|
|
107
136
|
(environment / "docker-compose.yaml").write_text(COMPOSE)
|
|
@@ -114,7 +143,7 @@ async def test_compose_scoring(tmp_path, mode, collect_fails, scoring_timeout):
|
|
|
114
143
|
+ ("sleep 30\n" if scoring_timeout else "")
|
|
115
144
|
+ "echo 1 > /logs/verifier/reward.txt\n"
|
|
116
145
|
)
|
|
117
|
-
|
|
146
|
+
return ComposeTask(
|
|
118
147
|
HarborData(
|
|
119
148
|
prompt="Copy the sidecar answer",
|
|
120
149
|
task_dir=str(tmp_path),
|
|
@@ -135,35 +164,3 @@ async def test_compose_scoring(tmp_path, mode, collect_fails, scoring_timeout):
|
|
|
135
164
|
],
|
|
136
165
|
)
|
|
137
166
|
)
|
|
138
|
-
config = vf.AgentConfig(
|
|
139
|
-
model="unused",
|
|
140
|
-
runtime=vf.DockerConfig(),
|
|
141
|
-
deployment=vf.DeploymentConfig(trust_compose=True),
|
|
142
|
-
scoring=vf.ScoringConfig(
|
|
143
|
-
mode=mode,
|
|
144
|
-
env={"EXPECT_SIDECAR": "1" if mode == "isolated" else "0"},
|
|
145
|
-
retries=vf.RetryConfig(max_retries=0),
|
|
146
|
-
),
|
|
147
|
-
timeout=TimeoutConfig(
|
|
148
|
-
setup=180, finalize=30, scoring=1 if scoring_timeout else 30
|
|
149
|
-
),
|
|
150
|
-
)
|
|
151
|
-
async with vf.Agent(config) as agent:
|
|
152
|
-
agent.harness = ComposeHarness(vf.HarnessConfig())
|
|
153
|
-
trace = await agent.run(task)
|
|
154
|
-
for container in trace.info.get("solver_containers", []):
|
|
155
|
-
assert (await cli("docker", "inspect", container)).exit_code != 0
|
|
156
|
-
if mode == "isolated" and collect_fails:
|
|
157
|
-
assert not trace.ok
|
|
158
|
-
assert "collect hook failed" in str(trace.errors)
|
|
159
|
-
assert "solver_released_before_grading" not in trace.info
|
|
160
|
-
elif scoring_timeout:
|
|
161
|
-
assert trace.ok and trace.is_timeout and not trace.errors
|
|
162
|
-
assert trace.stop_condition == "scoring_timeout"
|
|
163
|
-
assert all(reward is None for reward in trace.rewards.values())
|
|
164
|
-
else:
|
|
165
|
-
assert trace.ok and trace.reward == 1, trace.errors
|
|
166
|
-
assert bool(trace.info.get("collected_sidecars")) == (mode == "isolated")
|
|
167
|
-
assert bool(trace.info.get("solver_released_before_grading")) == (
|
|
168
|
-
mode == "isolated"
|
|
169
|
-
)
|
|
@@ -19,7 +19,7 @@ async def test_cap(run, cap, stop_condition):
|
|
|
19
19
|
(episode,) = await run(
|
|
20
20
|
"counter-tool",
|
|
21
21
|
harness="null",
|
|
22
|
-
runtime={"type": "
|
|
22
|
+
runtime={"type": "prime"},
|
|
23
23
|
env={"agent": cap},
|
|
24
24
|
)
|
|
25
25
|
(trace,) = episode.traces
|
|
@@ -33,7 +33,7 @@ async def test_rollout_timeout(run):
|
|
|
33
33
|
(episode,) = await run(
|
|
34
34
|
"counter-tool",
|
|
35
35
|
harness="null",
|
|
36
|
-
runtime={"type": "
|
|
36
|
+
runtime={"type": "prime"},
|
|
37
37
|
rollout_timeout=1,
|
|
38
38
|
)
|
|
39
39
|
(trace,) = episode.traces
|