verifiers 0.3.2.dev151__tar.gz → 0.3.2.dev153__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.3.2.dev151 → verifiers-0.3.2.dev153}/PKG-INFO +1 -1
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/conftest.py +6 -3
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/test_color_codeword_tasks.py +1 -1
- verifiers-0.3.2.dev153/tests/v1/test_taskset.py +201 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/__init__.py +4 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/acp/__init__.py +7 -1
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/acp/runner.py +3 -3
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/debug.py +3 -6
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/eval/runner.py +3 -6
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/init.py +1 -1
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/validate.py +3 -6
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/cli/debug.py +4 -8
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/cli/eval.py +4 -8
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/cli/validate.py +4 -8
- verifiers-0.3.2.dev153/verifiers/v1/configs/select.py +118 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/errors.py +6 -1
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/gepa/config.py +7 -6
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/gepa/dataset.py +2 -2
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/gepa/runner.py +2 -4
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harness.py +11 -1
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/rlm/harness.py +1 -1
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/utils/core.py +31 -19
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/task.py +9 -3
- verifiers-0.3.2.dev153/verifiers/v1/taskset.py +230 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/nemo_gym/taskset.py +0 -1
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/openenv/taskset.py +0 -1
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/textarena/taskset.py +0 -1
- verifiers-0.3.2.dev151/tests/v1/test_taskset.py +0 -91
- verifiers-0.3.2.dev151/verifiers/v1/taskset.py +0 -111
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/.gitignore +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/LICENSE +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/README.md +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/pyproject.toml +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/fixtures/counter_tool_v1.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/fixtures/duet_v1.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/fixtures/echo_acp_resume_v1.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/fixtures/echo_tool_v1.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/fixtures/echo_v1.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/fixtures/pyproject.toml +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/test_configs.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/test_e2e.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/test_envs.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/test_graph.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/test_judges.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/test_platform_run.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/test_scoring.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/test_serve_delta.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/tests/v1/test_trace.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/agent.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/dashboard/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/dashboard/base.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/dashboard/eval.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/dashboard/replay.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/dashboard/validate.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/eval/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/eval/hint.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/eval/main.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/eval/resume.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/gepa.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/output.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/replay.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/resolve.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/cli/resume.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/clients/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/clients/base.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/clients/client.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/clients/eval.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/clients/train.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/agent.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/cli/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/cli/env.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/cli/init.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/cli/replay.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/client.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/env.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/judge.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/retries.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/runtime.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/serve.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/task.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/configs/taskset.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/dialects/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/dialects/anthropic.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/dialects/base.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/dialects/chat.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/dialects/responses.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/env.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/agentic_judge/env.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/best_of_n/env.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/isolated_verifier/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/isolated_verifier/env.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/shared_agentic_judge/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/single_agent/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/single_agent/env.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/user_sim/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/envs/user_sim/env.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/episode.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/gepa/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/gepa/adapter.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/gepa/reflection.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/graph.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/bash/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/bash/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/browser_use/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/browser_use/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/browser_use/program.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/claude_code/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/codex/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/codex/gate.mjs +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/codex/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/hermes_agent/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/hermes_agent/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/hermes_agent/program.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/node.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/null/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/null/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/openclaw/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/openclaw/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/pi/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/pi/gate.mjs +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/pi/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/prime_agent/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/prime_agent/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/utils/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/utils/compaction.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/utils/install.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/utils/launch.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/harnesses/utils/mcp.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/interception/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/interception/base.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/interception/pool.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/interception/server.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/interception/tunnel/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/interception/tunnel/base.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/interception/tunnel/custom.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/interception/tunnel/prime.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/judge.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/judges/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/judges/reference.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/judges/reference.txt +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/judges/rubric.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/judges/rubric.txt +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/mcp/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/mcp/launch.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/mcp/server.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/mcp/toolset.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/rollout.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/runtimes/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/runtimes/apptainer.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/runtimes/base.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/runtimes/container.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/runtimes/docker/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/runtimes/docker/egress.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/runtimes/limiters.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/runtimes/modal.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/runtimes/prime.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/runtimes/subprocess.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/semantic.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/serve/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/serve/client.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/serve/delta.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/serve/encoding.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/serve/pool.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/serve/server.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/serve/types.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/session.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/state.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/harbor/compose.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/harbor/env.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/harbor/toolset.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/nemo_gym/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/nemo_gym/response.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/nemo_gym/server.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/nemo_gym/toolset.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/trace.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/types.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/__init__.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/aio.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/artifacts.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/compile.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/decorators.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/format.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/generic.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/git.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/image.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/interrupt.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/loaders.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/logging.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/memory.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/paths.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/platform.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/prime.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/retries.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/scope.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/score.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/trace_store.py +0 -0
- {verifiers-0.3.2.dev151 → verifiers-0.3.2.dev153}/verifiers/v1/utils/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: verifiers
|
|
3
|
-
Version: 0.3.2.
|
|
3
|
+
Version: 0.3.2.dev153
|
|
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
|
|
@@ -155,7 +155,10 @@ def _eval_config(
|
|
|
155
155
|
runtime_cfg = dict(runtime)
|
|
156
156
|
_configure_prime_runtimes(runtime_cfg)
|
|
157
157
|
env_cfg.setdefault("agent", {})["runtime"] = runtime_cfg
|
|
158
|
-
retries = {
|
|
158
|
+
retries = {
|
|
159
|
+
"max_retries": 2,
|
|
160
|
+
"include": ["ProviderError", "InterceptionError", "HarnessError"],
|
|
161
|
+
}
|
|
159
162
|
env_cfg.setdefault("retries", retries)
|
|
160
163
|
# Per-run caps live on the seats: resolve the env's declared roles and cap
|
|
161
164
|
# each one (a test's own seat dict wins over the shared defaults).
|
|
@@ -177,7 +180,7 @@ def _eval_config(
|
|
|
177
180
|
"taskset": taskset_cfg,
|
|
178
181
|
**env_cfg,
|
|
179
182
|
},
|
|
180
|
-
|
|
183
|
+
select={"limit": num_tasks},
|
|
181
184
|
num_rollouts=n,
|
|
182
185
|
sampling={
|
|
183
186
|
"max_tokens": max_tokens,
|
|
@@ -218,7 +221,7 @@ def run_v1_server():
|
|
|
218
221
|
|
|
219
222
|
async def _run(taskset: str, **kwargs) -> list[Trace]:
|
|
220
223
|
config = _eval_config(taskset, **kwargs)
|
|
221
|
-
tasks = list(load_taskset(config.env.taskset).
|
|
224
|
+
tasks = list(load_taskset(config.env.taskset).select(config.select))
|
|
222
225
|
mpctx = mp.get_context("spawn")
|
|
223
226
|
address_queue: mp.Queue = mpctx.Queue()
|
|
224
227
|
proc = mpctx.Process(
|
|
@@ -10,7 +10,7 @@ def test_color_images_are_rendered_once(monkeypatch) -> None:
|
|
|
10
10
|
return render(image)
|
|
11
11
|
|
|
12
12
|
monkeypatch.setattr(taskset, "image_data_url", counted)
|
|
13
|
-
tasks = list(taskset.ColorCodewordTaskset(taskset.ColorCodewordConfig()).
|
|
13
|
+
tasks = list(taskset.ColorCodewordTaskset(taskset.ColorCodewordConfig()).take(100))
|
|
14
14
|
|
|
15
15
|
assert len(tasks) == 100
|
|
16
16
|
assert calls == list(taskset.COLOR_RGB.values())
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"""`Taskset` iteration and selection: the framework-assigned `idx`, the lazy views
|
|
2
|
+
(`include`, `exclude`, `shuffle`, `skip`, `take`), and `select(SelectConfig)`."""
|
|
3
|
+
|
|
4
|
+
import itertools
|
|
5
|
+
import logging
|
|
6
|
+
import random
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
from pydantic import ValidationError
|
|
10
|
+
|
|
11
|
+
import verifiers.v1 as vf
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CountTask(vf.Task[vf.TaskData]):
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def count_task(i: int) -> CountTask:
|
|
19
|
+
# A taskset-set idx (100 + i) that iteration must overwrite.
|
|
20
|
+
return CountTask(
|
|
21
|
+
vf.TaskData(idx=100 + i, id=f"id-{i}", name=f"t{i}", prompt=f"task {i}")
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class FiniteTaskset(vf.Taskset[CountTask, vf.TasksetConfig]):
|
|
26
|
+
def load(self):
|
|
27
|
+
return [count_task(i) for i in range(10)]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class InfiniteTaskset(vf.Taskset[CountTask, vf.TasksetConfig]):
|
|
31
|
+
INFINITE = True
|
|
32
|
+
|
|
33
|
+
def load(self):
|
|
34
|
+
for i in itertools.count():
|
|
35
|
+
yield count_task(i)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def finite() -> FiniteTaskset:
|
|
39
|
+
return FiniteTaskset(vf.TasksetConfig())
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def infinite() -> InfiniteTaskset:
|
|
43
|
+
return InfiniteTaskset(vf.TasksetConfig())
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def idxs(tasks) -> list[int]:
|
|
47
|
+
return [task.data.idx for task in tasks]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def shuffled(xs, seed: int = 0) -> list[int]:
|
|
51
|
+
xs = list(xs)
|
|
52
|
+
random.Random(seed).shuffle(xs)
|
|
53
|
+
return xs
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
# Views
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def test_iteration_sets_idx_to_the_load_position() -> None:
|
|
60
|
+
assert idxs(finite()) == list(range(10))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_include_keeps_tasks_that_any_list_names() -> None:
|
|
64
|
+
assert idxs(finite().include(idx=[3, "5:7", "8:"])) == [3, 5, 6, 8, 9]
|
|
65
|
+
assert idxs(finite().include(idx=":2")) == [0, 1]
|
|
66
|
+
assert idxs(finite().include(idx=["1:8:3", "::4"])) == [0, 1, 4, 7, 8]
|
|
67
|
+
assert idxs(finite().include(ids=["id-1"])) == [1]
|
|
68
|
+
assert idxs(finite().include(names=["t2"])) == [2]
|
|
69
|
+
key = list(finite())[4].key
|
|
70
|
+
assert idxs(finite().include(keys=[key])) == [4]
|
|
71
|
+
union = finite().include(idx=[0], ids=["id-1"], names=["t2"], keys=[key])
|
|
72
|
+
assert idxs(union) == [0, 1, 2, 4]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_keys_match_the_keys_traces_record(tmp_path) -> None:
|
|
76
|
+
prompt = tmp_path / "prompt.txt"
|
|
77
|
+
prompt.write_text("be brief")
|
|
78
|
+
taskset = FiniteTaskset(vf.TasksetConfig(system_prompt=prompt))
|
|
79
|
+
key = list(taskset)[4].key
|
|
80
|
+
assert idxs(taskset.include(keys=[key])) == [4]
|
|
81
|
+
assert 4 not in idxs(taskset.exclude(keys=[key]))
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_exclude_drops_tasks_that_any_list_names() -> None:
|
|
85
|
+
assert idxs(finite().exclude(idx=":7", names=["t8"])) == [7, 9]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_unmatched_entries_warn(caplog) -> None:
|
|
89
|
+
with caplog.at_level(logging.WARNING):
|
|
90
|
+
assert idxs(finite().include(names=["t1", "typo"], idx=[42])) == [1]
|
|
91
|
+
assert "typo" in caplog.text and "42" in caplog.text
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_shuffle_is_seeded_and_reproducible() -> None:
|
|
95
|
+
assert idxs(finite().shuffle()) == shuffled(range(10)) != list(range(10))
|
|
96
|
+
assert idxs(finite().shuffle(seed=7)) == shuffled(range(10), 7)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def test_skip_and_take_slice_the_stream() -> None:
|
|
100
|
+
assert idxs(finite().skip(7)) == [7, 8, 9]
|
|
101
|
+
assert idxs(finite().take(3)) == [0, 1, 2]
|
|
102
|
+
assert idxs(finite().skip(2).take(2)) == [2, 3]
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_views_chain_in_call_order_and_leave_the_base_alone() -> None:
|
|
106
|
+
base = finite()
|
|
107
|
+
assert idxs(base.take(5).shuffle()) == shuffled(range(5))
|
|
108
|
+
assert idxs(base.shuffle().take(5)) == shuffled(range(10))[:5]
|
|
109
|
+
assert base.transform is None and idxs(base) == list(range(10))
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def test_views_read_load_lazily() -> None:
|
|
113
|
+
built: list[int] = []
|
|
114
|
+
|
|
115
|
+
class RecordingTaskset(InfiniteTaskset):
|
|
116
|
+
def load(self):
|
|
117
|
+
for i in itertools.count():
|
|
118
|
+
built.append(i)
|
|
119
|
+
yield count_task(i)
|
|
120
|
+
|
|
121
|
+
base = RecordingTaskset(vf.TasksetConfig())
|
|
122
|
+
assert idxs(base.take(3)) == [0, 1, 2] and built == [0, 1, 2]
|
|
123
|
+
built.clear()
|
|
124
|
+
# An idx-only include stops reading after its last position.
|
|
125
|
+
assert idxs(base.include(idx=["2:4", 6])) == [2, 3, 6] and built == list(range(7))
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_only_a_bounded_view_can_shuffle() -> None:
|
|
129
|
+
assert finite().bounded and not infinite().bounded
|
|
130
|
+
assert infinite().take(3).bounded
|
|
131
|
+
assert infinite().include(idx=["0:4", 9]).bounded
|
|
132
|
+
assert not infinite().include(idx="::2").bounded
|
|
133
|
+
assert not infinite().include(idx="5:").bounded
|
|
134
|
+
with pytest.raises(ValueError, match="may never end"):
|
|
135
|
+
infinite().include(idx=["0:4"], names=["t9"])
|
|
136
|
+
with pytest.raises(ValueError, match="open idx range"):
|
|
137
|
+
infinite().exclude(idx="5:")
|
|
138
|
+
assert idxs(infinite().exclude(idx="::2").take(2)) == [1, 3]
|
|
139
|
+
assert idxs(infinite().include(idx=":20").include(names=["t3"])) == [3]
|
|
140
|
+
with pytest.raises(ValueError, match="infinite"):
|
|
141
|
+
infinite().shuffle()
|
|
142
|
+
assert sorted(idxs(infinite().take(5).shuffle())) == [0, 1, 2, 3, 4]
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# Config and select
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def test_task_match_config_parses_idx() -> None:
|
|
149
|
+
assert vf.TaskMatchConfig(idx=["3", "0:2,4", "8:"]).idx == [3, "0:2", 4, "8:"]
|
|
150
|
+
assert vf.TaskMatchConfig(idx=5).idx == [5]
|
|
151
|
+
assert vf.TaskMatchConfig(idx="0:9:3").idx_stop == 9
|
|
152
|
+
for bad in [-1, "a", "5:5", "7:3", ":0", "1:2:0", "::00", "1:2:3:4"]:
|
|
153
|
+
with pytest.raises(ValidationError):
|
|
154
|
+
vf.TaskMatchConfig(idx=[bad])
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def test_select_config_defaults_and_short_aliases() -> None:
|
|
158
|
+
config = vf.SelectConfig()
|
|
159
|
+
assert config.include.empty and config.exclude.empty
|
|
160
|
+
assert (config.shuffle, config.seed, config.skip, config.limit) == (
|
|
161
|
+
False,
|
|
162
|
+
0,
|
|
163
|
+
0,
|
|
164
|
+
None,
|
|
165
|
+
)
|
|
166
|
+
aliased = vf.SelectCLIConfig.model_validate({"n": 3, "s": True})
|
|
167
|
+
assert (aliased.limit, aliased.shuffle) == (3, True)
|
|
168
|
+
with pytest.raises(ValidationError):
|
|
169
|
+
vf.SelectConfig.model_validate({"n": 3})
|
|
170
|
+
with pytest.raises(ValidationError):
|
|
171
|
+
vf.SelectConfig(limit=0)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def test_default_select_yields_every_task() -> None:
|
|
175
|
+
assert idxs(finite().select(vf.SelectConfig())) == list(range(10))
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def test_select_applies_its_steps_in_a_fixed_order() -> None:
|
|
179
|
+
config = vf.SelectConfig(
|
|
180
|
+
include={"idx": ["2:9"]},
|
|
181
|
+
exclude={"names": ["t5"]},
|
|
182
|
+
shuffle=True,
|
|
183
|
+
seed=3,
|
|
184
|
+
skip=1,
|
|
185
|
+
limit=2,
|
|
186
|
+
)
|
|
187
|
+
kept = [i for i in range(2, 9) if i != 5]
|
|
188
|
+
assert idxs(finite().select(config)) == shuffled(kept, 3)[1:3]
|
|
189
|
+
chained = (
|
|
190
|
+
finite().include(idx=["2:9"]).exclude(names=["t5"]).shuffle(3).skip(1).take(2)
|
|
191
|
+
)
|
|
192
|
+
assert idxs(finite().select(config)) == idxs(chained)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def test_select_bounds_an_infinite_taskset() -> None:
|
|
196
|
+
assert infinite().select(vf.SelectConfig(limit=4)).bounded
|
|
197
|
+
closed = vf.SelectConfig(include={"idx": "0:5"}, shuffle=True)
|
|
198
|
+
assert sorted(idxs(infinite().select(closed))) == [0, 1, 2, 3, 4]
|
|
199
|
+
# The shuffle comes before the limit, so the limit cannot bound it.
|
|
200
|
+
with pytest.raises(ValueError, match="infinite"):
|
|
201
|
+
infinite().select(vf.SelectConfig(shuffle=True, limit=5))
|
|
@@ -23,6 +23,7 @@ from verifiers.v1.configs.env import EnvConfig, SharedEnvConfig, default_agent_h
|
|
|
23
23
|
from verifiers.v1.configs.harness import HarnessConfig
|
|
24
24
|
from verifiers.v1.configs.judge import JudgeConfig, Judges
|
|
25
25
|
from verifiers.v1.configs.retries import RetryConfig
|
|
26
|
+
from verifiers.v1.configs.select import SelectCLIConfig, SelectConfig, TaskMatchConfig
|
|
26
27
|
from verifiers.v1.configs.serve import (
|
|
27
28
|
ElasticPoolConfig,
|
|
28
29
|
ServeConfig,
|
|
@@ -289,6 +290,9 @@ __all__ = [ # noqa: RUF022 - grouped by public API area
|
|
|
289
290
|
# taskset / harness / runtime / environment
|
|
290
291
|
"Taskset",
|
|
291
292
|
"TaskConfig",
|
|
293
|
+
"SelectConfig",
|
|
294
|
+
"SelectCLIConfig",
|
|
295
|
+
"TaskMatchConfig",
|
|
292
296
|
"TasksetConfig",
|
|
293
297
|
"SharedTasksetConfig",
|
|
294
298
|
"DecoratedFunctionConfig",
|
|
@@ -13,7 +13,7 @@ from pydantic import BaseModel, ConfigDict, Field
|
|
|
13
13
|
|
|
14
14
|
from verifiers.v1.clients import ModelContext
|
|
15
15
|
from verifiers.v1.configs.harness import HarnessConfig
|
|
16
|
-
from verifiers.v1.errors import HarnessError
|
|
16
|
+
from verifiers.v1.errors import HarnessError, InterceptionError
|
|
17
17
|
from verifiers.v1.harness import Harness, HarnessSession
|
|
18
18
|
from verifiers.v1.runtimes import ProgramResult, Runtime, RuntimeProcess
|
|
19
19
|
from verifiers.v1.semantic import (
|
|
@@ -308,6 +308,12 @@ class ACPHarnessSession(HarnessSession):
|
|
|
308
308
|
detail = response.get("error") or "ACP session request failed"
|
|
309
309
|
if stderr := self._stderr():
|
|
310
310
|
detail = f"{detail}\n\nACP process stderr:\n{stderr}"
|
|
311
|
+
error_data = response.get("error_data")
|
|
312
|
+
if (
|
|
313
|
+
isinstance(error_data, dict)
|
|
314
|
+
and error_data.get("kind") == "model_transport"
|
|
315
|
+
):
|
|
316
|
+
raise InterceptionError(detail)
|
|
311
317
|
raise RuntimeError(detail)
|
|
312
318
|
harness = cast(ACPHarness, self.harness)
|
|
313
319
|
harness._consume_protocol_metadata(self.trace, turn.response_metadata)
|
|
@@ -224,9 +224,6 @@ async def prompt(
|
|
|
224
224
|
if client.stop_reason != "cancelled":
|
|
225
225
|
raise
|
|
226
226
|
await connection.cancel(session_id=session_id)
|
|
227
|
-
except RequestError as error:
|
|
228
|
-
detail = error.data.get("details") if isinstance(error.data, dict) else None
|
|
229
|
-
raise RuntimeError(detail or str(error)) from error
|
|
230
227
|
finally:
|
|
231
228
|
client.prompt_task = None
|
|
232
229
|
return client.turn_result()
|
|
@@ -377,6 +374,9 @@ async def serve_stream() -> None:
|
|
|
377
374
|
"ok": False,
|
|
378
375
|
"error": f"{type(error).__name__}: {error}",
|
|
379
376
|
}
|
|
377
|
+
if isinstance(error, RequestError) and isinstance(error.data, dict):
|
|
378
|
+
response["error"] = error.data.get("details") or str(error)
|
|
379
|
+
response["error_data"] = error.data
|
|
380
380
|
if operation == "prompt":
|
|
381
381
|
response["result"] = asdict(session.client.turn_result())
|
|
382
382
|
write_packet(sys.stdout.buffer, response)
|
|
@@ -269,15 +269,12 @@ async def debug_task(task: Task, config: DebugConfig) -> tuple[Trace, bool]:
|
|
|
269
269
|
|
|
270
270
|
|
|
271
271
|
async def run_debug(config: DebugConfig) -> list[Trace]:
|
|
272
|
-
taskset = vf.load_taskset(config.taskset)
|
|
273
|
-
if
|
|
272
|
+
taskset = vf.load_taskset(config.taskset).select(config.select)
|
|
273
|
+
if not taskset.bounded:
|
|
274
274
|
raise ValueError(
|
|
275
275
|
f"{type(taskset).__name__} is infinite - bound the run with -n"
|
|
276
276
|
)
|
|
277
|
-
|
|
278
|
-
if config.num_tasks is not None:
|
|
279
|
-
selected = selected.head(config.num_tasks)
|
|
280
|
-
tasks = list(selected)
|
|
277
|
+
tasks = list(taskset)
|
|
281
278
|
if isinstance(config.runtime, vf.SubprocessConfig) and any(
|
|
282
279
|
type(t).NEEDS_CONTAINER or t.data.image for t in tasks
|
|
283
280
|
):
|
|
@@ -82,15 +82,12 @@ async def run_eval(config: EvalConfig) -> list[Episode]:
|
|
|
82
82
|
from verifiers.v1.utils.loaders import load_environment
|
|
83
83
|
|
|
84
84
|
env = load_environment(config.env)
|
|
85
|
-
taskset = env.taskset
|
|
86
|
-
if
|
|
85
|
+
taskset = env.taskset.select(config.select)
|
|
86
|
+
if not taskset.bounded:
|
|
87
87
|
raise ValueError(
|
|
88
88
|
f"{type(taskset).__name__} is infinite - bound the run with -n"
|
|
89
89
|
)
|
|
90
|
-
|
|
91
|
-
if config.num_tasks is not None:
|
|
92
|
-
selected = selected.head(config.num_tasks)
|
|
93
|
-
tasks = list(selected)
|
|
90
|
+
tasks = list(taskset)
|
|
94
91
|
out = output_path(config)
|
|
95
92
|
# One (task, rollouts-to-run) pair per selected task; resume shrinks the counts.
|
|
96
93
|
plan = [(task, config.num_rollouts) for task in tasks]
|
|
@@ -109,7 +109,7 @@ class {prefix}Taskset(vf.Taskset[{prefix}Task, {prefix}Config]):
|
|
|
109
109
|
def load(self) -> list[{prefix}Task]:
|
|
110
110
|
raise NotImplementedError(
|
|
111
111
|
"Return this taskset's tasks, e.g. "
|
|
112
|
-
"[{prefix}Task({prefix}Data(
|
|
112
|
+
"[{prefix}Task({prefix}Data(prompt=...), self.config.task) "
|
|
113
113
|
"for i in range(self.config.num_tasks)]."
|
|
114
114
|
)
|
|
115
115
|
'''
|
|
@@ -325,15 +325,12 @@ async def _validate_task(task: Task, config: ValidateConfig) -> ResultRow:
|
|
|
325
325
|
|
|
326
326
|
|
|
327
327
|
async def run_validate(config: ValidateConfig) -> list[dict]:
|
|
328
|
-
taskset = vf.load_taskset(config.taskset)
|
|
329
|
-
if
|
|
328
|
+
taskset = vf.load_taskset(config.taskset).select(config.select)
|
|
329
|
+
if not taskset.bounded:
|
|
330
330
|
raise ValueError(
|
|
331
331
|
f"{type(taskset).__name__} is infinite - bound the run with -n"
|
|
332
332
|
)
|
|
333
|
-
|
|
334
|
-
if config.num_tasks is not None:
|
|
335
|
-
selected = selected.head(config.num_tasks)
|
|
336
|
-
tasks = list(selected)
|
|
333
|
+
tasks = list(taskset)
|
|
337
334
|
if isinstance(config.runtime, vf.SubprocessConfig) and any(
|
|
338
335
|
type(t).NEEDS_CONTAINER or t.data.image for t in tasks
|
|
339
336
|
):
|
|
@@ -7,6 +7,7 @@ from pydantic import AliasChoices, Field, SerializeAsAny, model_validator
|
|
|
7
7
|
from pydantic_config import BaseConfig
|
|
8
8
|
|
|
9
9
|
from verifiers.v1.configs.cli.validate import CheckTimeoutConfig
|
|
10
|
+
from verifiers.v1.configs.select import SelectCLIConfig
|
|
10
11
|
from verifiers.v1.configs.taskset import TasksetConfig
|
|
11
12
|
from verifiers.v1.runtimes import PrimeConfig, RuntimeConfig
|
|
12
13
|
|
|
@@ -15,6 +16,9 @@ class DebugConfig(BaseConfig):
|
|
|
15
16
|
uuid: str = Field(default_factory=lambda: str(uuid4()), exclude=True)
|
|
16
17
|
"""Auto-generated run id, used as the default output directory leaf."""
|
|
17
18
|
taskset: SerializeAsAny[TasksetConfig] = TasksetConfig()
|
|
19
|
+
select: SelectCLIConfig = SelectCLIConfig()
|
|
20
|
+
"""Which of the taskset's tasks to debug, under `--select.*` (`-n` sets
|
|
21
|
+
`select.limit`, `-s` sets `select.shuffle`)."""
|
|
18
22
|
runtime: RuntimeConfig = PrimeConfig()
|
|
19
23
|
"""Where each task's setup hook and debug action run."""
|
|
20
24
|
command: str | None = None
|
|
@@ -26,14 +30,6 @@ class DebugConfig(BaseConfig):
|
|
|
26
30
|
timeout: CheckTimeoutConfig = CheckTimeoutConfig()
|
|
27
31
|
"""Per-task stage timeouts: `--timeout.setup` for the `setup` hook, `--timeout.total`
|
|
28
32
|
for the debug command/script."""
|
|
29
|
-
num_tasks: int | None = Field(
|
|
30
|
-
None,
|
|
31
|
-
ge=1,
|
|
32
|
-
validation_alias=AliasChoices("num_tasks", "n", "num_examples", "batch_size"),
|
|
33
|
-
)
|
|
34
|
-
"""How many tasks to debug (None = all)."""
|
|
35
|
-
shuffle: bool = Field(False, validation_alias=AliasChoices("shuffle", "s"))
|
|
36
|
-
"""Shuffle tasks before taking the first `num_tasks`."""
|
|
37
33
|
max_concurrent: int | None = Field(
|
|
38
34
|
128, validation_alias=AliasChoices("max_concurrent", "c")
|
|
39
35
|
)
|
|
@@ -9,6 +9,7 @@ from pydantic_config import BaseConfig
|
|
|
9
9
|
from verifiers.v1.clients import ClientConfig, EvalClientConfig
|
|
10
10
|
from verifiers.v1.configs.cli.env import narrowed_env_annotation, resolve_env_field
|
|
11
11
|
from verifiers.v1.configs.env import EnvConfig
|
|
12
|
+
from verifiers.v1.configs.select import SelectCLIConfig
|
|
12
13
|
from verifiers.v1.envs.single_agent import SingleAgentEnvConfig
|
|
13
14
|
from verifiers.v1.types import SamplingConfig
|
|
14
15
|
|
|
@@ -84,12 +85,9 @@ class EvalConfig(BaseConfig):
|
|
|
84
85
|
"""Model id."""
|
|
85
86
|
client: ClientConfig = EvalClientConfig()
|
|
86
87
|
sampling: SamplingConfig = SamplingConfig()
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
validation_alias=AliasChoices("batch_size", "num_examples", "num_tasks", "n"),
|
|
91
|
-
)
|
|
92
|
-
"""How many tasks to evaluate (None = all)."""
|
|
88
|
+
select: SelectCLIConfig = SelectCLIConfig()
|
|
89
|
+
"""Which of the taskset's tasks to evaluate, under `--select.*` (`-n` sets
|
|
90
|
+
`select.limit`, `-s` sets `select.shuffle`)."""
|
|
93
91
|
num_rollouts: int = Field(
|
|
94
92
|
1,
|
|
95
93
|
ge=1,
|
|
@@ -98,8 +96,6 @@ class EvalConfig(BaseConfig):
|
|
|
98
96
|
),
|
|
99
97
|
)
|
|
100
98
|
"""Independent episodes per task — the trainer's group size."""
|
|
101
|
-
shuffle: bool = Field(False, validation_alias=AliasChoices("shuffle", "s"))
|
|
102
|
-
"""Shuffle tasks before taking the first `num_tasks`."""
|
|
103
99
|
max_concurrent: int | None = Field(
|
|
104
100
|
128, ge=1, validation_alias=AliasChoices("max_concurrent", "c")
|
|
105
101
|
)
|
|
@@ -7,6 +7,7 @@ from pydantic import AliasChoices, Field, SerializeAsAny, model_validator
|
|
|
7
7
|
from pydantic_config import BaseConfig
|
|
8
8
|
|
|
9
9
|
from verifiers.v1.configs.cli.eval import RunConfig
|
|
10
|
+
from verifiers.v1.configs.select import SelectCLIConfig
|
|
10
11
|
from verifiers.v1.configs.taskset import TasksetConfig
|
|
11
12
|
from verifiers.v1.runtimes import PrimeConfig, RuntimeConfig
|
|
12
13
|
|
|
@@ -24,6 +25,9 @@ class ValidateConfig(BaseConfig):
|
|
|
24
25
|
"""Run identity: `run.name` auto-generates as `<taskset>--validate--<short-id>` and
|
|
25
26
|
names the run directory under `output_dir`."""
|
|
26
27
|
taskset: SerializeAsAny[TasksetConfig] = TasksetConfig()
|
|
28
|
+
select: SelectCLIConfig = SelectCLIConfig()
|
|
29
|
+
"""Which of the taskset's tasks to validate, under `--select.*` (`-n` sets
|
|
30
|
+
`select.limit`, `-s` sets `select.shuffle`)."""
|
|
27
31
|
runtime: RuntimeConfig = PrimeConfig()
|
|
28
32
|
"""Where each task's validation hooks run."""
|
|
29
33
|
timeout: CheckTimeoutConfig = CheckTimeoutConfig()
|
|
@@ -31,14 +35,6 @@ class ValidateConfig(BaseConfig):
|
|
|
31
35
|
"""Run only `Task.setup`."""
|
|
32
36
|
only_gold: bool = False
|
|
33
37
|
"""Run only `Task.setup` and `Task.validate`."""
|
|
34
|
-
num_tasks: int | None = Field(
|
|
35
|
-
None,
|
|
36
|
-
ge=1,
|
|
37
|
-
validation_alias=AliasChoices("num_tasks", "n", "num_examples", "batch_size"),
|
|
38
|
-
)
|
|
39
|
-
"""How many tasks to validate (None = all)."""
|
|
40
|
-
shuffle: bool = Field(False, validation_alias=AliasChoices("shuffle", "s"))
|
|
41
|
-
"""Shuffle tasks before taking the first `num_tasks`."""
|
|
42
38
|
max_concurrent: int | None = Field(
|
|
43
39
|
128, validation_alias=AliasChoices("max_concurrent", "c")
|
|
44
40
|
)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Which of a taskset's tasks a run uses: `Taskset.select(SelectConfig)`, under
|
|
2
|
+
`--select.*` on the eval, debug, validate and GEPA CLIs (`SelectCLIConfig`)."""
|
|
3
|
+
|
|
4
|
+
import re
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from pydantic import AliasChoices, Field, field_validator
|
|
8
|
+
from pydantic_config import BaseConfig
|
|
9
|
+
|
|
10
|
+
IDX_RANGE = re.compile(r"(\d*):(\d*)(?::(\d*))?")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TaskMatchConfig(BaseConfig):
|
|
14
|
+
"""Tasks named by position or identity; a task matches when any list names it."""
|
|
15
|
+
|
|
16
|
+
idx: list[int | str] = Field(default_factory=list)
|
|
17
|
+
"""Positions in the taskset's `load()` stream (`TaskData.idx`): ints and Python
|
|
18
|
+
slices `start:stop:step`, each part optional (`"100:"`, `":50"`, `"::2"`).
|
|
19
|
+
Negative positions are not supported. A comma-separated string also works
|
|
20
|
+
(`"0:10,17"`)."""
|
|
21
|
+
ids: list[str] = Field(default_factory=list)
|
|
22
|
+
"""`TaskData.id` values."""
|
|
23
|
+
keys: list[str] = Field(default_factory=list)
|
|
24
|
+
"""`Task.key` values, as recorded on each trace (`task.key`)."""
|
|
25
|
+
names: list[str] = Field(default_factory=list)
|
|
26
|
+
"""`TaskData.name` values."""
|
|
27
|
+
|
|
28
|
+
@field_validator("idx", mode="before")
|
|
29
|
+
@classmethod
|
|
30
|
+
def _parse_idx(cls, value):
|
|
31
|
+
if isinstance(value, (int, str)):
|
|
32
|
+
value = [value]
|
|
33
|
+
items: list[int | str] = []
|
|
34
|
+
for item in value:
|
|
35
|
+
parts = item.split(",") if isinstance(item, str) else [item]
|
|
36
|
+
items.extend(_parse_idx_item(part) for part in parts)
|
|
37
|
+
return items
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def empty(self) -> bool:
|
|
41
|
+
return not (self.idx or self.ids or self.keys or self.names)
|
|
42
|
+
|
|
43
|
+
def idx_ranges(self) -> list[range]:
|
|
44
|
+
"""`idx` as ranges; an open-ended slice stops at `sys.maxsize`."""
|
|
45
|
+
ranges: list[range] = []
|
|
46
|
+
for item in self.idx:
|
|
47
|
+
if isinstance(item, int):
|
|
48
|
+
ranges.append(range(item, item + 1))
|
|
49
|
+
continue
|
|
50
|
+
start, stop, step = (item.split(":") + [""])[:3]
|
|
51
|
+
ranges.append(
|
|
52
|
+
range(int(start or 0), int(stop or sys.maxsize), int(step or 1))
|
|
53
|
+
)
|
|
54
|
+
return ranges
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def idx_tail(self) -> bool:
|
|
58
|
+
"""Whether an `idx` slice names every position from some start on."""
|
|
59
|
+
return any(r.stop == sys.maxsize and r.step == 1 for r in self.idx_ranges())
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def idx_stop(self) -> int | None:
|
|
63
|
+
"""One past the last position this can match, when it names only closed `idx`
|
|
64
|
+
ranges; None when a match could lie anywhere in the stream."""
|
|
65
|
+
ranges = self.idx_ranges()
|
|
66
|
+
if not ranges or self.ids or self.keys or self.names:
|
|
67
|
+
return None
|
|
68
|
+
stop = max(r.stop for r in ranges)
|
|
69
|
+
return None if stop == sys.maxsize else stop
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _parse_idx_item(item: int | str) -> int | str:
|
|
73
|
+
if isinstance(item, int):
|
|
74
|
+
if item < 0:
|
|
75
|
+
raise ValueError(f"idx {item} is negative")
|
|
76
|
+
return item
|
|
77
|
+
text = item.strip()
|
|
78
|
+
if text.isdigit():
|
|
79
|
+
return int(text)
|
|
80
|
+
match = IDX_RANGE.fullmatch(text)
|
|
81
|
+
if match is None:
|
|
82
|
+
raise ValueError(f"idx {item!r} is not an int or a 'start:stop:step' slice")
|
|
83
|
+
start, stop, step = match.groups()
|
|
84
|
+
if step and int(step) == 0:
|
|
85
|
+
raise ValueError(f"idx slice {item!r} has step 0")
|
|
86
|
+
if stop and int(start or 0) >= int(stop):
|
|
87
|
+
raise ValueError(f"idx range {item!r} is empty")
|
|
88
|
+
return text
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class SelectConfig(BaseConfig):
|
|
92
|
+
"""The steps apply in a fixed order: `include` keeps tasks, `exclude` drops them,
|
|
93
|
+
then `shuffle`, `skip` and `limit` pick from what is left."""
|
|
94
|
+
|
|
95
|
+
include: TaskMatchConfig = TaskMatchConfig()
|
|
96
|
+
"""Keep only the tasks this names. Empty keeps all."""
|
|
97
|
+
exclude: TaskMatchConfig = TaskMatchConfig()
|
|
98
|
+
"""Drop the tasks this names."""
|
|
99
|
+
shuffle: bool = False
|
|
100
|
+
"""Shuffle the kept tasks under `seed`. Needs a finite stream: an infinite taskset
|
|
101
|
+
must be bounded by closed `include.idx` ranges first."""
|
|
102
|
+
seed: int = 0
|
|
103
|
+
"""Seed for `shuffle`, fixed so runs select the same tasks."""
|
|
104
|
+
skip: int = Field(0, ge=0)
|
|
105
|
+
"""Drop this many tasks after the shuffle."""
|
|
106
|
+
limit: int | None = Field(None, ge=1)
|
|
107
|
+
"""Take at most this many tasks after `skip` (None = all)."""
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class SelectCLIConfig(SelectConfig):
|
|
111
|
+
"""`SelectConfig` with CLI short flags, for the one `select` block of an entrypoint:
|
|
112
|
+
`-n` sets `limit` and `-s` sets `shuffle`."""
|
|
113
|
+
|
|
114
|
+
shuffle: bool = Field(False, validation_alias=AliasChoices("shuffle", "s"))
|
|
115
|
+
"""Shuffle the kept tasks under `seed` (`-s`). Needs a finite stream: an infinite
|
|
116
|
+
taskset must be bounded by closed `include.idx` ranges first."""
|
|
117
|
+
limit: int | None = Field(None, ge=1, validation_alias=AliasChoices("limit", "n"))
|
|
118
|
+
"""Take at most this many tasks after `skip` (`-n`; None = all)."""
|
|
@@ -42,6 +42,11 @@ class ProviderError(RolloutError):
|
|
|
42
42
|
self.status_code = status_code
|
|
43
43
|
|
|
44
44
|
|
|
45
|
+
MODEL_TRANSPORT_ERROR_EXIT_CODE = 97
|
|
46
|
+
"""Reserved harness exit code for an exhausted model transport failure.
|
|
47
|
+
`Harness._check_result` maps it to `InterceptionError`."""
|
|
48
|
+
|
|
49
|
+
|
|
45
50
|
class HarnessError(RolloutError):
|
|
46
51
|
"""The harness failed to install or launch, or its agent process exited unsuccessfully."""
|
|
47
52
|
|
|
@@ -65,7 +70,7 @@ class TaskError(RolloutError):
|
|
|
65
70
|
|
|
66
71
|
|
|
67
72
|
class InterceptionError(RolloutError):
|
|
68
|
-
"""
|
|
73
|
+
"""Communication with the host interception server failed."""
|
|
69
74
|
|
|
70
75
|
|
|
71
76
|
class TunnelError(InterceptionError):
|
|
@@ -17,6 +17,7 @@ from verifiers.v1.clients import EvalClientConfig
|
|
|
17
17
|
from verifiers.v1.configs.cli.env import narrowed_env_annotation, resolve_env_field
|
|
18
18
|
from verifiers.v1.configs.cli.eval import RunConfig, default_run_name
|
|
19
19
|
from verifiers.v1.configs.env import EnvConfig
|
|
20
|
+
from verifiers.v1.configs.select import SelectCLIConfig
|
|
20
21
|
from verifiers.v1.envs.single_agent import SingleAgentEnvConfig
|
|
21
22
|
from verifiers.v1.types import SamplingConfig
|
|
22
23
|
|
|
@@ -49,17 +50,17 @@ class GEPAConfig(BaseConfig):
|
|
|
49
50
|
reflection_client: EvalClientConfig | None = None
|
|
50
51
|
"""Endpoint for `reflection_model`. None = reuse `client`."""
|
|
51
52
|
|
|
53
|
+
select: SelectCLIConfig = SelectCLIConfig()
|
|
54
|
+
"""Which of the taskset's tasks GEPA splits into train/val, under `--select.*`
|
|
55
|
+
(`-n` sets `select.limit`, `-s` sets `select.shuffle`)."""
|
|
52
56
|
num_train: int = Field(100, ge=1)
|
|
53
57
|
"""Tasks reserved for reflection minibatches (GEPA never scores the full trainset at once)."""
|
|
54
58
|
num_val: int = Field(50, ge=1)
|
|
55
59
|
"""Tasks held out to score each candidate system prompt for the pareto frontier."""
|
|
56
|
-
shuffle: bool = Field(True, validation_alias=AliasChoices("shuffle", "s"))
|
|
57
|
-
"""Shuffle tasks before splitting into train/val — v1 tasksets have no generic train/val
|
|
58
|
-
split, so GEPA carves one out of `Taskset.select` the way `run_eval` samples (fixed
|
|
59
|
-
seed, so the split is reproducible across runs)."""
|
|
60
60
|
seed: int = 0
|
|
61
|
-
"""Seed for GEPA's optimizer (candidate selection / minibatch sampling).
|
|
62
|
-
|
|
61
|
+
"""Seed for GEPA's optimizer (candidate selection / minibatch sampling). The train/val
|
|
62
|
+
split comes from `select` (`-s` shuffles it under `select.seed`), so this doesn't
|
|
63
|
+
change it."""
|
|
63
64
|
|
|
64
65
|
max_total_rollouts: int = Field(500)
|
|
65
66
|
"""Total rollouts GEPA may spend across the whole optimization run."""
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
v1 tasksets have no generic train/val split concept (`TasksetConfig` has no `split` field;
|
|
4
4
|
individual tasksets define ad hoc ones inconsistently), so GEPA carves one out of the tasks
|
|
5
|
-
`
|
|
6
|
-
|
|
5
|
+
`select` yields (reproducible across runs like every other entrypoint): two
|
|
6
|
+
disjoint slices.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from verifiers.v1.task import Task
|