verifiers 0.4.1.dev46__tar.gz → 0.4.1.dev48__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.dev46 → verifiers-0.4.1.dev48}/PKG-INFO +1 -1
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/network_policy.py +3 -3
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/grid.py +15 -14
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_multi_turn.py +3 -3
- verifiers-0.4.1.dev48/tests/integration/test_scoring_network.py +175 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_tool_vms.py +3 -1
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/test_graph.py +8 -0
- verifiers-0.4.1.dev48/tests/unit/test_scoring_network.py +113 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/utils/test_loaders.py +2 -2
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/__init__.py +2 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/agent.py +1 -1
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/validate.py +11 -2
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/harness.py +4 -1
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/runtime.py +7 -3
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/scoring.py +6 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/envs/agentic_judge/env.py +3 -5
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/grading.py +22 -1
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/bash/harness.py +2 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/browser_use/harness.py +1 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/claude_code/harness.py +2 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/codex/harness.py +4 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/deepseek/harness.py +4 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/hermes_agent/harness.py +8 -1
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/kimi_code/harness.py +3 -4
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/mini_swe_agent/harness.py +2 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/null/harness.py +3 -1
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/openclaw/harness.py +3 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/opencode/harness.py +2 -3
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/pi/harness.py +5 -6
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/prime_agent/harness.py +11 -2
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/rlm/harness.py +1 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/terminus_2/harness.py +2 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/utils/replay.py +11 -1
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/rollout.py +8 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/base.py +6 -3
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/deployment.py +0 -6
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/docker/__init__.py +7 -4
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/e2b.py +8 -5
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/modal.py +6 -2
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/prime.py +9 -5
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/runtime.py +22 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/task.py +12 -9
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/harbor/taskset.py +24 -26
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/types.py +2 -2
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/compile.py +2 -7
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/loaders.py +2 -1
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/.gitignore +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/LICENSE +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/README.md +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/pyproject.toml +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/conftest.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/agent_user.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/agent_user_harness.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/counter_tool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/duet.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/echo.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/echo_acp_resume.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/echo_agentic.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/echo_tool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/echo_tool_compose/docker-compose.yaml +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/echo_user_sim.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/fetch_tool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/parallel.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/pyproject.toml +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/skill_codeword.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/skills/project-codeword/SKILL.md +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/tool_response_image.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_agent_user.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_agentic_judge.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_compose_scoring.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_examples.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_limits.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_multi_agent.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_multi_turn_tool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_multimodal_tool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_network_policy.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_parallel.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_resume_tool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_rubric_judge.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_sampling.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_shared_tool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_single_turn.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_skills.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_stateful_tool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_user_echo.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/test_user_sim.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/cli/test_replay.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/conftest.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/harnesses/test_core.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/harnesses/test_rlm.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/interception/test_tunnel.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/judges/conftest.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/judges/test_judge.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/judges/test_reference.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/judges/test_rubric.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/runtimes/test_e2b.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/runtimes/test_private_network.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/serve/test_client.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/serve/test_delta.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/serve/test_pool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/test_agent.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/test_dialects.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/test_semantic.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/test_task.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/test_taskset.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/test_trace.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/utils/test_compile.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/utils/test_platform.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/unit/utils/test_score.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/acp/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/acp/runner.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/dashboard/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/dashboard/base.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/dashboard/eval.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/dashboard/replay.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/dashboard/validate.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/debug.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/eval/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/eval/hint.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/eval/main.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/eval/resume.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/eval/runner.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/gepa.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/output.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/replay.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/resolve.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/cli/resume.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/clients/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/clients/base.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/clients/client.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/clients/eval.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/clients/train.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/agent.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/cli/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/cli/debug.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/cli/env.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/cli/eval.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/cli/replay.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/cli/validate.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/client.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/env.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/judge.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/retries.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/select.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/serve.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/task.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/configs/taskset.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/dialects/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/dialects/anthropic.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/dialects/base.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/dialects/chat.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/dialects/responses.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/env.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/envs/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/envs/best_of_n/env.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/envs/single_agent/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/envs/single_agent/env.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/envs/user_sim/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/envs/user_sim/env.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/episode.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/errors.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/gepa/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/gepa/adapter.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/gepa/config.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/gepa/dataset.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/gepa/reflection.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/gepa/runner.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/graph.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harness.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/bash/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/browser_use/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/browser_use/program.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/codex/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/codex/gate.mjs +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/deepseek/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/deepseek/gate.mjs +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/deepseek/usage.mjs +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/hermes_agent/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/hermes_agent/program.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/node.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/null/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/openclaw/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/opencode/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/opencode/mcp-ready.js +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/pi/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/pi/gate.mjs +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/prime_agent/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/utils/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/utils/compaction.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/utils/core.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/utils/install.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/utils/launch.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/utils/mcp.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/interception/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/interception/base.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/interception/pool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/interception/server.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/interception/tunnel/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/interception/tunnel/base.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/interception/tunnel/custom.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/interception/tunnel/prime.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/judge.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/judges/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/judges/decision.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/judges/reference.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/judges/reference.txt +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/judges/rubric.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/judges/rubric.txt +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/mcp/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/mcp/launch.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/mcp/server.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/mcp/toolset.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/apptainer.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/compose.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/container.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/docker/egress.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/limiters.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/private_network.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/strategies.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/runtimes/subprocess.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/semantic.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/serve/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/serve/client.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/serve/delta.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/serve/encoding.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/serve/pool.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/serve/server.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/serve/types.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/session.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/state.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/taskset.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/harbor/toolset.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/nemo_gym/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/nemo_gym/response.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/nemo_gym/server.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/nemo_gym/taskset.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/nemo_gym/toolset.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/trace.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/__init__.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/aio.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/artifacts.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/decorators.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/env.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/eval.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/format.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/generic.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/git.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/image.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/interrupt.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/logging.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/memory.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/paths.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/platform.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/prime.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/retries.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/scope.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/score.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/utils/trace_store.py +0 -0
- {verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/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.dev48
|
|
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
|
{verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/tests/integration/fixtures/network_policy.py
RENAMED
|
@@ -63,9 +63,9 @@ class NetworkPolicyTaskset(vf.Taskset[NetworkPolicyTask, vf.TasksetConfig]):
|
|
|
63
63
|
def load(self) -> list[NetworkPolicyTask]:
|
|
64
64
|
policies = {
|
|
65
65
|
"open": {},
|
|
66
|
-
"off": {"
|
|
67
|
-
"block": {"
|
|
68
|
-
"allow": {"
|
|
66
|
+
"off": {"network": vf.NetworkPolicyConfig(allow=[])},
|
|
67
|
+
"block": {"network": vf.NetworkPolicyConfig(block=[BLOCKED])},
|
|
68
|
+
"allow": {"network": vf.NetworkPolicyConfig(allow=[ALLOWED])},
|
|
69
69
|
}
|
|
70
70
|
prompt = (
|
|
71
71
|
f"Your only task: run the command `python3 {PROBE_PATH}` once in your "
|
|
@@ -192,31 +192,32 @@ def grid(
|
|
|
192
192
|
return cells
|
|
193
193
|
|
|
194
194
|
|
|
195
|
-
def
|
|
196
|
-
"""The
|
|
197
|
-
|
|
198
|
-
field = harness_config_type(harness).model_fields
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
195
|
+
def dialects(harness: str) -> tuple[str, ...]:
|
|
196
|
+
"""The dialects the harness config can select besides its default. Empty when the
|
|
197
|
+
program speaks one dialect or picks its own."""
|
|
198
|
+
field = harness_config_type(harness).model_fields["dialect"]
|
|
199
|
+
return tuple(
|
|
200
|
+
value
|
|
201
|
+
for arg in get_args(field.annotation)
|
|
202
|
+
for value in get_args(arg) or (arg,)
|
|
203
|
+
if value != field.default
|
|
204
|
+
)
|
|
202
205
|
|
|
203
206
|
|
|
204
|
-
def
|
|
207
|
+
def dialect_grid(
|
|
205
208
|
runtimes: Sequence[str] = ("prime",), *, needs: tuple[str, ...] = ()
|
|
206
209
|
) -> list:
|
|
207
|
-
"""`grid` cells for every non-default `
|
|
210
|
+
"""`grid` cells for every non-default `dialect` each harness config can select."""
|
|
208
211
|
cells = []
|
|
209
212
|
for harness in HARNESSES:
|
|
210
213
|
name = harness_id(harness)
|
|
211
|
-
for
|
|
212
|
-
for cell in grid(
|
|
213
|
-
[{"id": name, "transport": transport}], runtimes, needs=needs
|
|
214
|
-
):
|
|
214
|
+
for dialect in dialects(name):
|
|
215
|
+
for cell in grid([{"id": name, "dialect": dialect}], runtimes, needs=needs):
|
|
215
216
|
cells.append(
|
|
216
217
|
pytest.param(
|
|
217
218
|
*cell.values,
|
|
218
219
|
marks=cell.marks,
|
|
219
|
-
id=cell.id.replace(f"{name}-in-", f"{name}-{
|
|
220
|
+
id=cell.id.replace(f"{name}-in-", f"{name}-{dialect}-in-"),
|
|
220
221
|
)
|
|
221
222
|
)
|
|
222
223
|
return cells
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"""One task, many turns: the model completes a shell task (echo-agentic: write a phrase
|
|
2
2
|
to a file, checked in the runtime) across the harness x runtime grid, and on prime over
|
|
3
|
-
every other `
|
|
3
|
+
every other `dialect` a harness config can select. A turn the harness re-sends
|
|
4
4
|
differently, beyond what its `replay_view` declares, forks the trace."""
|
|
5
5
|
|
|
6
6
|
import pytest
|
|
7
|
-
from grid import grid, mark
|
|
7
|
+
from grid import dialect_grid, grid, mark
|
|
8
8
|
|
|
9
9
|
MULTI_TURN = [
|
|
10
10
|
*grid(needs=("shell",)),
|
|
11
|
-
*
|
|
11
|
+
*dialect_grid(needs=("shell",)),
|
|
12
12
|
pytest.param(
|
|
13
13
|
"bash",
|
|
14
14
|
{"type": "modal", "allow": []},
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"""Scoring runs under the network its policy declares: a task with framework-only egress
|
|
2
|
+
probes two public hosts from its scoring hook, in the workspace (shared) and in a fresh
|
|
3
|
+
verifier (isolated), in rollouts and in vf-validate, and a Harbor task's trusted grading
|
|
4
|
+
lifts the policy unless scoring declares its network."""
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import shutil
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
import verifiers.v1 as vf
|
|
12
|
+
from verifiers.v1.cli.validate import _run_check
|
|
13
|
+
from verifiers.v1.configs.agent import TimeoutConfig
|
|
14
|
+
from verifiers.v1.configs.cli.validate import ValidateConfig
|
|
15
|
+
from verifiers.v1.tasksets.harbor.taskset import HarborData, HarborTask
|
|
16
|
+
|
|
17
|
+
pytestmark = [
|
|
18
|
+
pytest.mark.docker,
|
|
19
|
+
pytest.mark.skipif(not shutil.which("docker"), reason="needs Docker"),
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
IMAGE = "python:3.11-slim"
|
|
23
|
+
HOSTS = ["example.com", "pypi.org"]
|
|
24
|
+
# Prints which hosts answer 200. Requests go through the runtime's egress proxy, which
|
|
25
|
+
# refuses a host the policy denies.
|
|
26
|
+
PROBE = f"""
|
|
27
|
+
import json, urllib.request
|
|
28
|
+
reachable = []
|
|
29
|
+
for host in {HOSTS!r}:
|
|
30
|
+
try:
|
|
31
|
+
with urllib.request.urlopen("https://" + host, timeout=15) as response:
|
|
32
|
+
if response.status == 200:
|
|
33
|
+
reachable.append(host)
|
|
34
|
+
except Exception:
|
|
35
|
+
pass
|
|
36
|
+
print(json.dumps(reachable))
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class IdleHarness(vf.Harness):
|
|
41
|
+
async def launch(self, ctx, trace, runtime, endpoint, secret, mcp_urls, data):
|
|
42
|
+
return await runtime.run_program(["true"], {})
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class ProbeTask(vf.Task):
|
|
46
|
+
@vf.reward(weight=1.0)
|
|
47
|
+
async def probe(self, trace, runtime) -> float:
|
|
48
|
+
result = await runtime.run(["python", "-c", PROBE], {})
|
|
49
|
+
trace.info["reachable"] = json.loads(result.stdout)
|
|
50
|
+
return 1.0
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
async def run(task) -> vf.Trace:
|
|
54
|
+
config = vf.AgentConfig(
|
|
55
|
+
model="unused",
|
|
56
|
+
runtime=vf.DockerConfig(),
|
|
57
|
+
timeout=TimeoutConfig(setup=180, finalize=30, scoring=120),
|
|
58
|
+
)
|
|
59
|
+
async with vf.Agent(config) as agent:
|
|
60
|
+
agent.harness = IdleHarness(vf.HarnessConfig())
|
|
61
|
+
return await agent.run(task)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@pytest.mark.parametrize("mode", ["shared", "isolated"])
|
|
65
|
+
@pytest.mark.parametrize(
|
|
66
|
+
("network", "reachable"),
|
|
67
|
+
[
|
|
68
|
+
(None, []),
|
|
69
|
+
(vf.NetworkPolicyConfig(allow=["example.com"]), ["example.com"]),
|
|
70
|
+
(vf.NetworkPolicyConfig(), HOSTS),
|
|
71
|
+
],
|
|
72
|
+
ids=["undeclared", "one-host", "open"],
|
|
73
|
+
)
|
|
74
|
+
async def test_scoring_network(mode, network, reachable):
|
|
75
|
+
task = ProbeTask(
|
|
76
|
+
vf.TaskData(
|
|
77
|
+
prompt="Do nothing",
|
|
78
|
+
image=IMAGE,
|
|
79
|
+
network=vf.NetworkPolicyConfig(allow=[]),
|
|
80
|
+
scoring=vf.ScoringConfig(
|
|
81
|
+
mode=mode, network=network, retries=vf.RetryConfig(max_retries=0)
|
|
82
|
+
),
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
trace = await run(task)
|
|
86
|
+
assert trace.ok, trace.errors
|
|
87
|
+
assert trace.info["reachable"] == reachable
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class ReachTask(vf.Task):
|
|
91
|
+
@vf.reward(weight=1.0)
|
|
92
|
+
async def reach(self, trace, runtime) -> float:
|
|
93
|
+
result = await runtime.run(["python", "-c", PROBE], {})
|
|
94
|
+
return float(json.loads(result.stdout) == ["example.com"])
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@pytest.mark.parametrize("mode", ["shared", "isolated"])
|
|
98
|
+
async def test_validate_scores_under_the_declared_network(mode):
|
|
99
|
+
task = ReachTask(
|
|
100
|
+
vf.TaskData(
|
|
101
|
+
prompt="Do nothing",
|
|
102
|
+
image=IMAGE,
|
|
103
|
+
network=vf.NetworkPolicyConfig(allow=[]),
|
|
104
|
+
scoring=vf.ScoringConfig(
|
|
105
|
+
mode=mode,
|
|
106
|
+
network=vf.NetworkPolicyConfig(allow=["example.com"]),
|
|
107
|
+
retries=vf.RetryConfig(max_retries=0),
|
|
108
|
+
),
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
row = await _run_check(task, ValidateConfig(runtime=vf.DockerConfig()), "noop")
|
|
112
|
+
# vf-validate never applies the agent phase's policy, so the shared workspace is open
|
|
113
|
+
# until scoring declares a network. Scoring that reaches only example.com passes the
|
|
114
|
+
# untouched task, which the noop check reports as invalid.
|
|
115
|
+
assert row["error"] is None
|
|
116
|
+
assert row["valid"] is False
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class GoldReachTask(ReachTask):
|
|
120
|
+
async def validate(self, trace, runtime) -> bool:
|
|
121
|
+
await vf.grade_submission(self, trace, runtime)
|
|
122
|
+
return trace.reward == 1.0
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
async def test_validate_grades_a_submission_under_the_declared_network():
|
|
126
|
+
task = GoldReachTask(
|
|
127
|
+
vf.TaskData(
|
|
128
|
+
prompt="Do nothing",
|
|
129
|
+
image=IMAGE,
|
|
130
|
+
network=vf.NetworkPolicyConfig(allow=[]),
|
|
131
|
+
scoring=vf.ScoringConfig(
|
|
132
|
+
mode="isolated",
|
|
133
|
+
network=vf.NetworkPolicyConfig(allow=["example.com"]),
|
|
134
|
+
retries=vf.RetryConfig(max_retries=0),
|
|
135
|
+
),
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
# vf-validate's trace records its own runtime config, so the verifier can reach
|
|
139
|
+
# example.com although the task's policy is framework-only.
|
|
140
|
+
row = await _run_check(task, ValidateConfig(runtime=vf.DockerConfig()), "gold")
|
|
141
|
+
assert row["error"] is None
|
|
142
|
+
assert row["valid"] is True
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@pytest.mark.parametrize(
|
|
146
|
+
("network", "reward"),
|
|
147
|
+
[(None, 1.0), (vf.NetworkPolicyConfig(allow=["pypi.org"]), 0.0)],
|
|
148
|
+
ids=["trusted-default", "declared"],
|
|
149
|
+
)
|
|
150
|
+
async def test_harbor_grading_network(tmp_path, network, reward):
|
|
151
|
+
tests = tmp_path / "tests"
|
|
152
|
+
tests.mkdir()
|
|
153
|
+
(tests / "test.sh").write_text(
|
|
154
|
+
"python - <<'EOF'\n"
|
|
155
|
+
"import urllib.request\n"
|
|
156
|
+
"try:\n"
|
|
157
|
+
" urllib.request.urlopen('https://example.com', timeout=15)\n"
|
|
158
|
+
" reward = 1\n"
|
|
159
|
+
"except Exception:\n"
|
|
160
|
+
" reward = 0\n"
|
|
161
|
+
"open('/logs/verifier/reward.txt', 'w').write(str(reward))\n"
|
|
162
|
+
"EOF\n"
|
|
163
|
+
)
|
|
164
|
+
task = HarborTask(
|
|
165
|
+
HarborData(
|
|
166
|
+
prompt="Do nothing",
|
|
167
|
+
task_dir=str(tmp_path),
|
|
168
|
+
image=IMAGE,
|
|
169
|
+
network=vf.NetworkPolicyConfig(allow=[]),
|
|
170
|
+
scoring=vf.ScoringConfig(network=network),
|
|
171
|
+
)
|
|
172
|
+
)
|
|
173
|
+
trace = await run(task)
|
|
174
|
+
assert trace.ok, trace.errors
|
|
175
|
+
assert trace.reward == reward
|
|
@@ -69,7 +69,9 @@ async def test_a_tool_vm_keeps_its_own_egress_beside_a_restricted_workspace(
|
|
|
69
69
|
runtime=vf.PrimeConfig(labels=["vf-integration"], allow=allow)
|
|
70
70
|
)
|
|
71
71
|
task = ProbeTask(
|
|
72
|
-
vf.TaskData(
|
|
72
|
+
vf.TaskData(
|
|
73
|
+
prompt="Probe the network", network=vf.NetworkPolicyConfig(allow=[])
|
|
74
|
+
),
|
|
73
75
|
FetchToolTaskConfig(tools=tools),
|
|
74
76
|
)
|
|
75
77
|
config = vf.AgentConfig(
|
|
@@ -305,6 +305,14 @@ def _replayed_trace(replay_view, sampled, replayed, dialect=None):
|
|
|
305
305
|
),
|
|
306
306
|
(strip_text, {"content": "Calling it.\n\n"}, {"content": "Calling it."}),
|
|
307
307
|
(strip_text, {"content": None}, {"reasoning_content": " "}),
|
|
308
|
+
(
|
|
309
|
+
strip_text,
|
|
310
|
+
{"content": "\n\n"},
|
|
311
|
+
{
|
|
312
|
+
"reasoning_content": " ",
|
|
313
|
+
"provider_state": [{"type": "thinking", "thinking": " "}],
|
|
314
|
+
},
|
|
315
|
+
),
|
|
308
316
|
],
|
|
309
317
|
)
|
|
310
318
|
def test_replay_view_matches_cosmetically_rewritten_turns(view, sampled, replayed):
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""Scoring's declared network: how agent and task policies combine, how it combines with
|
|
2
|
+
the runtime's own rules (in `grade_submission`, the agent's), and what the runtime asks
|
|
3
|
+
its provider for."""
|
|
4
|
+
|
|
5
|
+
from typing import cast
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
import verifiers.v1 as vf
|
|
10
|
+
from verifiers.v1 import grading
|
|
11
|
+
from verifiers.v1.configs.scoring import resolve_scoring
|
|
12
|
+
from verifiers.v1.errors import SandboxError, TaskError
|
|
13
|
+
from verifiers.v1.grading import grade_submission, scoring_network
|
|
14
|
+
from verifiers.v1.runtimes import deployment
|
|
15
|
+
from verifiers.v1.runtimes.base import RuntimeBackend
|
|
16
|
+
from verifiers.v1.runtimes.runtime import Runtime
|
|
17
|
+
from verifiers.v1.utils.compile import resolve_runtime_config
|
|
18
|
+
|
|
19
|
+
PYPI = vf.NetworkPolicyConfig(allow=["pypi.org"])
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_agent_network_replaces_the_tasks():
|
|
23
|
+
task = vf.ScoringConfig(network=PYPI)
|
|
24
|
+
assert resolve_scoring(task, vf.ScoringConfig()).network == PYPI
|
|
25
|
+
agent = vf.ScoringConfig(network=vf.NetworkPolicyConfig())
|
|
26
|
+
assert resolve_scoring(task, agent).network == vf.NetworkPolicyConfig()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_scoring_network_combines_with_the_runtimes_rules():
|
|
30
|
+
assert scoring_network(vf.DockerConfig(), PYPI).allow == ["pypi.org"]
|
|
31
|
+
narrowed = vf.DockerConfig(allow=["pypi.org", "example.com"])
|
|
32
|
+
opened = scoring_network(narrowed, vf.NetworkPolicyConfig())
|
|
33
|
+
assert opened.allow == ["pypi.org", "example.com"]
|
|
34
|
+
# As for `TaskData.network`, a concrete allowlist can't sit beside a blocklist.
|
|
35
|
+
with pytest.raises(ValueError):
|
|
36
|
+
scoring_network(vf.DockerConfig(block=["example.com"]), PYPI)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_scoring_network_needs_a_runtime_with_policies():
|
|
40
|
+
with pytest.raises(TaskError):
|
|
41
|
+
scoring_network(vf.SubprocessConfig(), PYPI)
|
|
42
|
+
open_network = vf.NetworkPolicyConfig()
|
|
43
|
+
assert scoring_network(vf.SubprocessConfig(), open_network) is open_network
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Backend:
|
|
47
|
+
supports_user = False
|
|
48
|
+
name = "fake"
|
|
49
|
+
|
|
50
|
+
def __init__(self, config, restricted=True):
|
|
51
|
+
self.config = config
|
|
52
|
+
self.network_restricted = restricted
|
|
53
|
+
self.calls = []
|
|
54
|
+
|
|
55
|
+
async def prepare_execution(self, routes, network=None):
|
|
56
|
+
self.calls.append((routes, None if network is None else network.allow))
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
async def test_set_network_enforces_a_policy_or_lifts_it():
|
|
60
|
+
backend = Backend(vf.DockerConfig(allow=[]))
|
|
61
|
+
runtime = Runtime(cast(RuntimeBackend, backend))
|
|
62
|
+
await runtime.set_network(PYPI)
|
|
63
|
+
await runtime.set_network(vf.NetworkPolicyConfig())
|
|
64
|
+
assert backend.calls == [([], ["pypi.org"]), (None, None)]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
async def test_set_network_cannot_restrict_a_runtime_that_started_open():
|
|
68
|
+
backend = Backend(vf.DockerConfig(), restricted=False)
|
|
69
|
+
runtime = Runtime(cast(RuntimeBackend, backend))
|
|
70
|
+
with pytest.raises(SandboxError):
|
|
71
|
+
await runtime.set_network(PYPI)
|
|
72
|
+
await runtime.set_network(vf.NetworkPolicyConfig())
|
|
73
|
+
assert backend.calls == [(None, None)]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
async def test_grade_submission_widens_from_the_agents_runtime(monkeypatch):
|
|
77
|
+
graded = []
|
|
78
|
+
|
|
79
|
+
async def grade_task(task, trace, config, *args, **kwargs):
|
|
80
|
+
graded.append(config)
|
|
81
|
+
|
|
82
|
+
class Deployment:
|
|
83
|
+
def __init__(self, *args, **kwargs):
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
async def start(self):
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
async def close(self):
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
monkeypatch.setattr(grading, "grade_task", grade_task)
|
|
93
|
+
monkeypatch.setattr(deployment, "Deployment", Deployment)
|
|
94
|
+
task = vf.Task(
|
|
95
|
+
vf.TaskData(
|
|
96
|
+
prompt="",
|
|
97
|
+
image="python:3.11-slim",
|
|
98
|
+
network=vf.NetworkPolicyConfig(allow=[]),
|
|
99
|
+
scoring=vf.ScoringConfig(mode="isolated", network=PYPI),
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
agent_runtime = vf.DockerConfig()
|
|
103
|
+
# The solver's resolved config carries the task's framework-only policy.
|
|
104
|
+
solver = Runtime(
|
|
105
|
+
cast(RuntimeBackend, Backend(resolve_runtime_config(agent_runtime, task)))
|
|
106
|
+
)
|
|
107
|
+
trace = vf.Trace(
|
|
108
|
+
agent=vf.AgentInfo(config=vf.AgentConfig(runtime=agent_runtime)),
|
|
109
|
+
task=vf.TraceTask(type="Task", data=task.data),
|
|
110
|
+
)
|
|
111
|
+
await grade_submission(task, trace, solver)
|
|
112
|
+
[config] = graded
|
|
113
|
+
assert config.allow == ["pypi.org"]
|
|
@@ -29,10 +29,10 @@ def test_every_builtin_harness_loads() -> None:
|
|
|
29
29
|
|
|
30
30
|
def test_harness_config_narrows_to_its_own_type() -> None:
|
|
31
31
|
config = vf.AgentConfig.model_validate(
|
|
32
|
-
{"harness": {"id": "kimi-code", "
|
|
32
|
+
{"harness": {"id": "kimi-code", "dialect": "responses"}}
|
|
33
33
|
)
|
|
34
34
|
assert type(config.harness) is harness_config_type("kimi-code")
|
|
35
|
-
assert config.harness.
|
|
35
|
+
assert config.harness.dialect == "responses"
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def test_unknown_harness_names_the_builtins() -> None:
|
|
@@ -82,6 +82,7 @@ from verifiers.v1.mcp import (
|
|
|
82
82
|
from verifiers.v1.runtimes import (
|
|
83
83
|
ApptainerConfig,
|
|
84
84
|
DockerConfig,
|
|
85
|
+
NetworkPolicyConfig,
|
|
85
86
|
PodmanConfig,
|
|
86
87
|
PrimeConfig,
|
|
87
88
|
ProgramResult,
|
|
@@ -315,6 +316,7 @@ __all__ = [ # noqa: RUF022 - grouped by public API area
|
|
|
315
316
|
"ProgramResult",
|
|
316
317
|
"SubprocessConfig",
|
|
317
318
|
"DockerConfig",
|
|
319
|
+
"NetworkPolicyConfig",
|
|
318
320
|
"PodmanConfig",
|
|
319
321
|
"ApptainerConfig",
|
|
320
322
|
"PrimeConfig",
|
|
@@ -94,7 +94,7 @@ def _check_borrowed_placement(
|
|
|
94
94
|
"""A borrowed box is never re-provisioned, so a task's placement fields can't
|
|
95
95
|
be honored. Reject requirements that cannot be applied to the running box; an
|
|
96
96
|
image mismatch on a container only warns, since sharing its world is the point."""
|
|
97
|
-
task_policy =
|
|
97
|
+
task_policy = task.data.network.network_restricted
|
|
98
98
|
base_policy = base_config if isinstance(base_config, NetworkPolicyConfig) else None
|
|
99
99
|
if task_policy or (base_policy is not None and base_policy.network_restricted):
|
|
100
100
|
config = runtime.config
|
|
@@ -31,7 +31,12 @@ from verifiers.v1.cli.resolve import (
|
|
|
31
31
|
from verifiers.v1.cli.resume import distribute
|
|
32
32
|
from verifiers.v1.configs.cli.validate import ValidateConfig
|
|
33
33
|
from verifiers.v1.errors import TaskError, boundary
|
|
34
|
-
from verifiers.v1.grading import
|
|
34
|
+
from verifiers.v1.grading import (
|
|
35
|
+
bind_scoring_env,
|
|
36
|
+
grade_task,
|
|
37
|
+
scoring_network,
|
|
38
|
+
verifier_runtime,
|
|
39
|
+
)
|
|
35
40
|
from verifiers.v1.runtimes import make_backend
|
|
36
41
|
from verifiers.v1.runtimes.deployment import Deployment
|
|
37
42
|
from verifiers.v1.state import state_cls
|
|
@@ -244,7 +249,7 @@ async def _setup_only(task: Task, trace: Trace, runtime) -> bool:
|
|
|
244
249
|
|
|
245
250
|
async def _gold(task: Task, trace: Trace, runtime) -> bool | None:
|
|
246
251
|
"""Apply and check the reference answer."""
|
|
247
|
-
return await task.validate
|
|
252
|
+
return await invoke(task.validate, {"trace": trace, "runtime": runtime})
|
|
248
253
|
|
|
249
254
|
|
|
250
255
|
async def _score_untouched(
|
|
@@ -288,6 +293,10 @@ async def _score_untouched(
|
|
|
288
293
|
async with asyncio.timeout(task.data.timeout.scoring):
|
|
289
294
|
runtime = bind_scoring_env(runtime, policy)
|
|
290
295
|
await invoke(grader.stage_verifier, {"trace": trace, "runtime": runtime})
|
|
296
|
+
if policy.network is not None:
|
|
297
|
+
await runtime.set_network(
|
|
298
|
+
scoring_network(config.runtime, policy.network)
|
|
299
|
+
)
|
|
291
300
|
await grader.score(trace, runtime, deployment)
|
|
292
301
|
if not trace.rewards:
|
|
293
302
|
return None
|
|
@@ -9,7 +9,7 @@ from typing import Annotated, Literal
|
|
|
9
9
|
from pydantic import ConfigDict, Field, FiniteFloat
|
|
10
10
|
from pydantic_config import BaseConfig
|
|
11
11
|
|
|
12
|
-
from verifiers.v1.types import ID
|
|
12
|
+
from verifiers.v1.types import ID, DialectName
|
|
13
13
|
|
|
14
14
|
PinnedVersion = Annotated[str, Field(pattern=r"^[A-Za-z0-9._+-]+$")]
|
|
15
15
|
"""A release/tag a harness pins its program install to."""
|
|
@@ -52,6 +52,9 @@ class HarnessConfig(BaseConfig):
|
|
|
52
52
|
tool_timeout: FiniteFloat = Field(600.0, gt=0)
|
|
53
53
|
"""Seconds a single MCP tool call may take; raise it for tools that boot a VM."""
|
|
54
54
|
disabled_tools: list[str] | None = None
|
|
55
|
+
dialect: DialectName | Literal["auto"] = "auto"
|
|
56
|
+
"""Model API wire format the program speaks. `auto` lets the program pick, e.g. from
|
|
57
|
+
the model. Each harness narrows this to the formats it can select."""
|
|
55
58
|
skills: list[SkillSource] = Field(default_factory=list)
|
|
56
59
|
"""Host skill folders or `{runtime: path}` roots of skills inside the runtime.
|
|
57
60
|
Sources are installed in order; later files override matching earlier files.
|
|
@@ -55,7 +55,9 @@ def intersect_network_hosts(left: str, right: str) -> str:
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
class NetworkPolicyConfig(BaseConfig):
|
|
58
|
-
"""
|
|
58
|
+
"""What a box may reach. A runtime's own rules, a task's (`TaskData.network`) and a
|
|
59
|
+
task's scoring (`ScoringConfig.network`) all use it; a task's policy combines with its
|
|
60
|
+
runtime's rules: allowlists intersect and blocklists merge."""
|
|
59
61
|
|
|
60
62
|
allow: list[str] = Field(default_factory=lambda: ["*"])
|
|
61
63
|
"""Destinations allowed during execution; `*` is unrestricted and `[]` is
|
|
@@ -87,10 +89,12 @@ class NetworkPolicyConfig(BaseConfig):
|
|
|
87
89
|
for rule in self.block
|
|
88
90
|
) and any(network_rule_matches(rule, scheme, host, port) for rule in self.allow)
|
|
89
91
|
|
|
90
|
-
def with_task_network_policy(self,
|
|
92
|
+
def with_task_network_policy(self, network: "NetworkPolicyConfig") -> Self:
|
|
91
93
|
values = self.model_dump()
|
|
92
94
|
# Intersection must not erase syntax the runtime cannot enforce.
|
|
93
|
-
task = type(self).model_validate(
|
|
95
|
+
task = type(self).model_validate(
|
|
96
|
+
{**values, "allow": network.allow, "block": network.block}
|
|
97
|
+
)
|
|
94
98
|
allow, block = task.allow, task.block
|
|
95
99
|
if "*" in allow:
|
|
96
100
|
allow = self.allow
|
|
@@ -6,6 +6,7 @@ from pydantic import SerializationInfo, field_serializer
|
|
|
6
6
|
from pydantic_config import BaseConfig
|
|
7
7
|
|
|
8
8
|
from verifiers.v1.configs.retries import RetryConfig
|
|
9
|
+
from verifiers.v1.configs.runtime import NetworkPolicyConfig
|
|
9
10
|
from verifiers.v1.runtimes import RuntimeConfig
|
|
10
11
|
from verifiers.v1.utils.generic import merge_defaults
|
|
11
12
|
|
|
@@ -19,6 +20,11 @@ class ScoringConfig(BaseConfig):
|
|
|
19
20
|
"""Scoring-only variables, merged over task defaults and resolved at scoring time."""
|
|
20
21
|
retries: RetryConfig = RetryConfig(max_retries=2)
|
|
21
22
|
"""Retry rules for fresh isolated scoring attempts; shared scoring is not retried."""
|
|
23
|
+
network: NetworkPolicyConfig | None = None
|
|
24
|
+
"""The task's network policy while scoring runs, in place of `TaskData.network` and
|
|
25
|
+
combined with the runtime's own rules the same way. None keeps the default: isolated
|
|
26
|
+
scoring runs under `TaskData.network`, shared scoring keeps the agent phase's network,
|
|
27
|
+
and Harbor's shared grading lifts the policy."""
|
|
22
28
|
|
|
23
29
|
@field_serializer("runtime")
|
|
24
30
|
def serialize_runtime(
|
|
@@ -165,8 +165,7 @@ class JudgeTask(vf.Task):
|
|
|
165
165
|
image=solved.image,
|
|
166
166
|
workdir=solved.workdir,
|
|
167
167
|
resources=solved.resources,
|
|
168
|
-
|
|
169
|
-
network_block=solved.network_block,
|
|
168
|
+
network=solved.network,
|
|
170
169
|
),
|
|
171
170
|
files=files,
|
|
172
171
|
)
|
|
@@ -334,9 +333,8 @@ class AgenticJudgeEnv(vf.Env[AgenticJudgeEnvConfig]):
|
|
|
334
333
|
"workdir": runtime.config.workdir,
|
|
335
334
|
}
|
|
336
335
|
if isinstance(runtime.config, NetworkPolicyConfig):
|
|
337
|
-
updates
|
|
338
|
-
|
|
339
|
-
network_block=runtime.config.block,
|
|
336
|
+
updates["network"] = NetworkPolicyConfig(
|
|
337
|
+
allow=runtime.config.allow, block=runtime.config.block
|
|
340
338
|
)
|
|
341
339
|
judge_task = judge_task.with_data(**updates)
|
|
342
340
|
# A per-invocation view retains episode accounting and concurrency while
|
|
@@ -9,6 +9,7 @@ from pathlib import PurePosixPath
|
|
|
9
9
|
from verifiers.v1.configs.scoring import ScoringConfig
|
|
10
10
|
from verifiers.v1.errors import TaskError, boundary
|
|
11
11
|
from verifiers.v1.runtimes import (
|
|
12
|
+
NetworkPolicyConfig,
|
|
12
13
|
PrimeConfig,
|
|
13
14
|
Runtime,
|
|
14
15
|
RuntimeConfig,
|
|
@@ -56,6 +57,8 @@ def verifier_runtime(
|
|
|
56
57
|
image=task.data.image or getattr(solver_runtime.config, "image", None),
|
|
57
58
|
workdir=task.data.workdir or getattr(solver_runtime.config, "workdir", None),
|
|
58
59
|
)
|
|
60
|
+
if policy.network is not None:
|
|
61
|
+
task = task.with_data(network=policy.network)
|
|
59
62
|
config = resolve_runtime_config(source, task)
|
|
60
63
|
if policy.runtime is not None and "image" in policy.runtime.model_fields_set:
|
|
61
64
|
config = config.model_copy(update={"image": policy.runtime.image})
|
|
@@ -75,6 +78,21 @@ def verifier_runtime(
|
|
|
75
78
|
return config
|
|
76
79
|
|
|
77
80
|
|
|
81
|
+
def scoring_network(
|
|
82
|
+
base: RuntimeConfig, network: NetworkPolicyConfig
|
|
83
|
+
) -> NetworkPolicyConfig:
|
|
84
|
+
"""`network` as the task's policy while scoring, combined with the runtime's own
|
|
85
|
+
rules the way `TaskData.network` is."""
|
|
86
|
+
if isinstance(base, NetworkPolicyConfig):
|
|
87
|
+
return base.with_task_network_policy(network)
|
|
88
|
+
if network.network_restricted:
|
|
89
|
+
raise TaskError(
|
|
90
|
+
f"scoring requires a network policy, but the {base.type} runtime does not "
|
|
91
|
+
"support one"
|
|
92
|
+
)
|
|
93
|
+
return network
|
|
94
|
+
|
|
95
|
+
|
|
78
96
|
def bind_scoring_env(runtime: Runtime, policy: ScoringConfig) -> Runtime:
|
|
79
97
|
"""Bind scoring variables without changing the solver's runtime or backend."""
|
|
80
98
|
return runtime.with_env({**runtime.env, **resolve_env(policy.env or {})})
|
|
@@ -188,6 +206,9 @@ async def grade_submission(
|
|
|
188
206
|
|
|
189
207
|
The caller finalizes the submission and collects artifacts into the trace first.
|
|
190
208
|
Uses the task's grader, scoring policy, and timeouts, including retry behavior.
|
|
209
|
+
As in a rollout, the verifier derives from the agent's runtime config on the trace
|
|
210
|
+
(`trace.agent.config.runtime`), not from the solver's resolved one, so the solver
|
|
211
|
+
task's requirements, such as its network policy, don't carry over.
|
|
191
212
|
"""
|
|
192
213
|
from verifiers.v1.runtimes.deployment import Deployment
|
|
193
214
|
|
|
@@ -195,7 +216,7 @@ async def grade_submission(
|
|
|
195
216
|
if policy.mode != "isolated":
|
|
196
217
|
raise ValueError("grade_submission requires isolated scoring")
|
|
197
218
|
grader = task.grading_task(runtime, scoring=policy)
|
|
198
|
-
config = verifier_runtime(grader, runtime,
|
|
219
|
+
config = verifier_runtime(grader, runtime, trace.agent.config.runtime, policy)
|
|
199
220
|
deployment = Deployment(
|
|
200
221
|
runtime.backend, borrowed_runtime=runtime, env=dict(runtime.env)
|
|
201
222
|
)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
from typing import Literal
|
|
2
3
|
|
|
3
4
|
from pydantic import PositiveInt
|
|
4
5
|
from pydantic_config import BaseConfig
|
|
@@ -38,6 +39,7 @@ class CompactionConfig(BaseConfig):
|
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
class BashHarnessConfig(HarnessConfig):
|
|
42
|
+
dialect: Literal["chat_completions"] = "chat_completions"
|
|
41
43
|
edit: bool = True
|
|
42
44
|
"""Offer the local `edit` tool (single-occurrence string replacement in a file) alongside
|
|
43
45
|
`bash`. On by default; set `--env.agent.harness.edit false` for a bash-only agent."""
|
{verifiers-0.4.1.dev46 → verifiers-0.4.1.dev48}/verifiers/v1/harnesses/browser_use/harness.py
RENAMED
|
@@ -32,6 +32,7 @@ Finding elements: prefer the accessibility tree over screenshots. cdp("Accessibi
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
class BrowserUseHarnessConfig(HarnessConfig):
|
|
35
|
+
dialect: Literal["chat_completions"] = "chat_completions"
|
|
35
36
|
browser: Literal["chromium", "cdp"] = "chromium"
|
|
36
37
|
"""`chromium` launches locally; `cdp` attaches to `cdp_url` without owning it."""
|
|
37
38
|
|