verifiers 0.3.2.dev123__tar.gz → 0.3.2.dev125__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.dev123 → verifiers-0.3.2.dev125}/PKG-INFO +1 -1
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_e2e.py +9 -2
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_graph.py +42 -5
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_trace.py +91 -4
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/clients/train.py +5 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/dialects/anthropic.py +27 -12
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/dialects/chat.py +24 -16
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/dialects/responses.py +43 -13
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/graph.py +15 -2
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/nemo_gym/response.py +1 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/trace.py +3 -2
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/types.py +9 -2
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/.gitignore +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/LICENSE +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/README.md +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/pyproject.toml +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/conftest.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/fixtures/counter_tool_v1.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/fixtures/duet_v1.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/fixtures/echo_acp_resume_v1.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/fixtures/echo_tool_v1.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/fixtures/echo_v1.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/fixtures/pyproject.toml +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_color_codeword_tasks.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_configs.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_envs.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_judges.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_platform_run.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_scoring.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_serve_delta.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/test_taskset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/acp/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/acp/runner.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/agent.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/dashboard/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/dashboard/base.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/dashboard/eval.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/dashboard/replay.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/dashboard/validate.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/debug.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/eval/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/eval/hint.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/eval/main.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/eval/resume.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/eval/runner.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/gepa.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/init.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/output.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/replay.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/resolve.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/resume.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/cli/validate.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/clients/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/clients/base.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/clients/client.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/clients/eval.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/agent.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/cli/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/cli/debug.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/cli/env.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/cli/eval.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/cli/init.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/cli/replay.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/cli/validate.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/client.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/env.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/judge.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/retries.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/runtime.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/serve.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/task.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/configs/taskset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/dialects/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/dialects/base.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/env.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/agentic_judge/env.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/best_of_n/env.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/isolated_verifier/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/isolated_verifier/env.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/shared_agentic_judge/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/single_agent/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/single_agent/env.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/user_sim/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/envs/user_sim/env.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/episode.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/errors.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/gepa/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/gepa/adapter.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/gepa/config.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/gepa/dataset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/gepa/reflection.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/gepa/runner.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/bash/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/bash/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/browser_use/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/browser_use/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/browser_use/program.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/claude_code/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/codex/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/codex/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/hermes_agent/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/hermes_agent/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/hermes_agent/program.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/node.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/null/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/null/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/openclaw/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/openclaw/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/pi/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/pi/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/prime_agent/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/prime_agent/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/rlm/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/utils/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/utils/compaction.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/utils/core.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/utils/install.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/utils/launch.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/harnesses/utils/mcp.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/interception/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/interception/base.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/interception/pool.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/interception/server.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/interception/tool.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/interception/tunnel/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/interception/tunnel/base.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/interception/tunnel/custom.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/interception/tunnel/prime.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/judge.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/judges/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/judges/reference.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/judges/reference.txt +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/judges/rubric.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/judges/rubric.txt +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/mcp/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/mcp/launch.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/mcp/server.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/mcp/toolset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/rollout.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/runtimes/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/runtimes/apptainer.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/runtimes/base.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/runtimes/container.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/runtimes/docker/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/runtimes/docker/egress.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/runtimes/limiters.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/runtimes/modal.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/runtimes/prime.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/runtimes/subprocess.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/semantic.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/serve/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/serve/client.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/serve/delta.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/serve/encoding.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/serve/pool.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/serve/server.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/serve/types.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/session.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/state.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/task.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/taskset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/harbor/env.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/harbor/toolset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/lean/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/lean/scoring.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/lean/taskset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/nemo_gym/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/nemo_gym/server.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/nemo_gym/taskset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/nemo_gym/toolset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/__init__.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/aio.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/artifacts.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/compile.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/decorators.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/format.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/generic.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/git.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/image.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/interrupt.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/loaders.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/logging.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/memory.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/paths.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/platform.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/prime.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/retries.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/utils/score.py +0 -0
- {verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/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.dev125
|
|
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
|
|
@@ -373,14 +373,21 @@ async def test_acp_resume_with_tool(run_v1, harness, harness_runtime, tmp_path):
|
|
|
373
373
|
# Kimi Code is broken upstream: its Responses adapter drops message `phase` on replay.
|
|
374
374
|
if harness.id != "kimi-code":
|
|
375
375
|
assert trace.num_branches == 1
|
|
376
|
-
# Native MCP tools need not appear in the intercepted model request that
|
|
377
|
-
# populates trace.tools; the ACP transcript is the source of truth for use.
|
|
378
376
|
assert "tool" in segments[1]["roles"]
|
|
379
377
|
assert segments[1]["tool_outputs"]
|
|
380
378
|
if harness.id == "pi":
|
|
381
379
|
recall = next(tool for tool in trace.tools if tool.name == "resume_recall")
|
|
382
380
|
assert recall.parameters["properties"]["codeword"]["type"] == "string"
|
|
383
381
|
assert "codeword" in recall.parameters["required"]
|
|
382
|
+
if harness.id == "codex":
|
|
383
|
+
recall = next(tool for tool in trace.tools if tool.name.endswith("recall"))
|
|
384
|
+
assert recall.namespace
|
|
385
|
+
assert "codeword" in recall.parameters["properties"]
|
|
386
|
+
assert any(
|
|
387
|
+
call.namespace == recall.namespace and call.name == recall.name
|
|
388
|
+
for message in trace.assistant_messages
|
|
389
|
+
for call in message.tool_calls or []
|
|
390
|
+
)
|
|
384
391
|
if harness.id == "rlm":
|
|
385
392
|
assert "turns_since_last_compaction" in trace.metrics
|
|
386
393
|
assert all(call.acp is not None for call in trace.calls)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
+
import pytest
|
|
4
5
|
|
|
5
6
|
import verifiers.v1 as vf
|
|
6
7
|
from verifiers.v1 import graph
|
|
@@ -203,6 +204,31 @@ def test_tool_call_hash_matches_v0_content_and_arguments_normalization():
|
|
|
203
204
|
|
|
204
205
|
assert graph.message_hash(left) == graph.message_hash(right)
|
|
205
206
|
|
|
207
|
+
# Identical call IDs and short names can occur in different agent branches.
|
|
208
|
+
trace = vf.Trace(
|
|
209
|
+
agent=vf.AgentInfo(config=vf.AgentConfig()),
|
|
210
|
+
task=vf.TraceTask(type="Task", data=vf.TaskData(idx=0, prompt="lookup")),
|
|
211
|
+
)
|
|
212
|
+
user = vf.UserMessage(content="lookup")
|
|
213
|
+
calls = [
|
|
214
|
+
vf.AssistantMessage(
|
|
215
|
+
tool_calls=[
|
|
216
|
+
vf.ToolCall(id="call_0", name="lookup", namespace=ns, arguments="{}")
|
|
217
|
+
]
|
|
218
|
+
)
|
|
219
|
+
for ns in (None, "alpha", "beta")
|
|
220
|
+
]
|
|
221
|
+
node_ids = [
|
|
222
|
+
graph.prepare_turn(trace, [user]).commit(_response(message))
|
|
223
|
+
for message in calls
|
|
224
|
+
]
|
|
225
|
+
for message, node_id in zip(calls, node_ids, strict=True):
|
|
226
|
+
turn = graph.prepare_turn(
|
|
227
|
+
trace,
|
|
228
|
+
[user, message, vf.ToolMessage(content="result", tool_call_id="call_0")],
|
|
229
|
+
)
|
|
230
|
+
assert turn.prefix_node_ids == [0, node_id]
|
|
231
|
+
|
|
206
232
|
|
|
207
233
|
def test_reasoning_content_participates_in_graph_prefix_matching():
|
|
208
234
|
task = vf.TaskData(idx=0, prompt="use a tool")
|
|
@@ -243,7 +269,8 @@ def test_reasoning_content_participates_in_graph_prefix_matching():
|
|
|
243
269
|
assert len(tool_call_nodes) == 2
|
|
244
270
|
|
|
245
271
|
|
|
246
|
-
|
|
272
|
+
@pytest.mark.parametrize("same_tools", [False, True])
|
|
273
|
+
def test_parallel_commits_reconcile_shared_prompt_prefix(same_tools):
|
|
247
274
|
"""Two requests prepared from the same graph snapshot share any common prompt prefix that
|
|
248
275
|
the first response commits while the second is in flight. A later turn must keep following
|
|
249
276
|
its original child path rather than re-rooting through the sibling and stranding an orphan."""
|
|
@@ -257,10 +284,13 @@ def test_parallel_commits_reconcile_shared_prompt_prefix():
|
|
|
257
284
|
assistant_a = vf.AssistantMessage(content="A1")
|
|
258
285
|
|
|
259
286
|
# Both model requests leave before either response has committed its prompt.
|
|
260
|
-
|
|
261
|
-
|
|
287
|
+
tool_a = vf.Tool(name="echo", namespace="a")
|
|
288
|
+
tool_b = vf.Tool(name="echo", namespace="a" if same_tools else "b")
|
|
289
|
+
pending_a = graph.prepare_turn(trace, [system, user_a], [tool_a])
|
|
290
|
+
pending_b = graph.prepare_turn(trace, [system, user_b], [tool_b])
|
|
262
291
|
assistant_a_id = pending_a.commit(_response(assistant_a))
|
|
263
292
|
pending_b.commit(_response(vf.AssistantMessage(content="B1")))
|
|
293
|
+
assert trace.tools == ([tool_a] if same_tools else [tool_a, tool_b])
|
|
264
294
|
|
|
265
295
|
graph.prepare_turn(
|
|
266
296
|
trace,
|
|
@@ -270,16 +300,23 @@ def test_parallel_commits_reconcile_shared_prompt_prefix():
|
|
|
270
300
|
assistant_a,
|
|
271
301
|
vf.ToolMessage(content="tool A", tool_call_id="call_a"),
|
|
272
302
|
],
|
|
303
|
+
[tool_a],
|
|
273
304
|
).commit(_response(vf.AssistantMessage(content="A2")))
|
|
274
305
|
|
|
275
306
|
roots = [node for node in trace.nodes if node.parent is None]
|
|
276
307
|
identities = [
|
|
277
|
-
(
|
|
308
|
+
(
|
|
309
|
+
node.parent,
|
|
310
|
+
tuple(tool.namespace for tool in node.tools),
|
|
311
|
+
graph.message_hash(node.message),
|
|
312
|
+
)
|
|
313
|
+
for node in trace.nodes
|
|
278
314
|
]
|
|
279
|
-
assert len(roots) == 1
|
|
315
|
+
assert len(roots) == (1 if same_tools else 2)
|
|
280
316
|
assert len(identities) == len(set(identities))
|
|
281
317
|
assert trace.num_branches == 2
|
|
282
318
|
assert assistant_a_id not in graph.leaves(trace)
|
|
319
|
+
assert [branch.tools for branch in trace.branches] == [[tool_b], [tool_a]]
|
|
283
320
|
|
|
284
321
|
|
|
285
322
|
def test_parallel_commit_reconciles_only_token_identical_prefixes():
|
|
@@ -11,7 +11,9 @@ import pytest
|
|
|
11
11
|
import verifiers.v1 as vf
|
|
12
12
|
from verifiers.v1.agent import Interaction
|
|
13
13
|
from verifiers.v1.cli.output import write_episode
|
|
14
|
-
from verifiers.v1.
|
|
14
|
+
from verifiers.v1.dialects.chat import ChatDialect
|
|
15
|
+
from verifiers.v1.dialects.responses import ResponsesDialect, fold_assistant
|
|
16
|
+
from verifiers.v1.graph import MessageNode, prepare_turn
|
|
15
17
|
from verifiers.v1.harnesses.rlm.harness import (
|
|
16
18
|
RLM_SESSION_METADATA_KEY,
|
|
17
19
|
RLMHarness,
|
|
@@ -174,16 +176,71 @@ def test_custom_task_state_round_trip(tmp_path):
|
|
|
174
176
|
assert tr.state.artifacts["/artifact.bin"] == b"\xff\x00\xfe"
|
|
175
177
|
|
|
176
178
|
|
|
177
|
-
|
|
179
|
+
@pytest.mark.parametrize("history_type", ["additional_tools", "tool_search_output"])
|
|
180
|
+
def test_wire_trace_round_trip(history_type):
|
|
181
|
+
mcp = {
|
|
182
|
+
"type": "mcp",
|
|
183
|
+
"server_label": "alpha",
|
|
184
|
+
"server_url": "https://example.invalid/mcp",
|
|
185
|
+
"authorization": "trace-test-oauth-token",
|
|
186
|
+
"headers": {"Authorization": "Bearer trace-test-header-token"},
|
|
187
|
+
"Authorization": "trace-test-case-oauth-token",
|
|
188
|
+
"Headers": {"X-Api-Key": "trace-test-case-header-token"},
|
|
189
|
+
}
|
|
190
|
+
function = {
|
|
191
|
+
"type": "function",
|
|
192
|
+
"name": "echo",
|
|
193
|
+
"description": "Echo the supplied text.",
|
|
194
|
+
"parameters": {"type": "object", "properties": {"text": {"type": "string"}}},
|
|
195
|
+
"strict": False,
|
|
196
|
+
}
|
|
197
|
+
stale = function | {"parameters": {"type": "object"}, "strict": True}
|
|
198
|
+
request = ResponsesDialect().parse_request(
|
|
199
|
+
{
|
|
200
|
+
"input": [
|
|
201
|
+
{
|
|
202
|
+
"type": history_type,
|
|
203
|
+
"call_id": "search",
|
|
204
|
+
"tools": [
|
|
205
|
+
stale,
|
|
206
|
+
{"type": "namespace", "name": "mcp__world", "tools": [stale]},
|
|
207
|
+
],
|
|
208
|
+
}
|
|
209
|
+
],
|
|
210
|
+
"tools": [
|
|
211
|
+
function,
|
|
212
|
+
{"type": "namespace", "name": "mcp__world", "tools": [function]},
|
|
213
|
+
{"type": "namespace", "name": "mcp__other", "tools": [function]},
|
|
214
|
+
{"type": "custom", "name": "patch", "format": {"type": "text"}},
|
|
215
|
+
{"type": "web_search", "search_context_size": "low"},
|
|
216
|
+
mcp,
|
|
217
|
+
mcp | {"server_label": "beta"},
|
|
218
|
+
],
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
assert request.tools is not None and len(request.tools) == 7
|
|
222
|
+
assert all(tool.parameters == function["parameters"] for tool in request.tools[:3])
|
|
223
|
+
assert all(tool.strict is False for tool in request.tools[:3])
|
|
224
|
+
assistant = fold_assistant(
|
|
225
|
+
[
|
|
226
|
+
{
|
|
227
|
+
"type": "function_call",
|
|
228
|
+
"call_id": "call_0",
|
|
229
|
+
"name": "echo",
|
|
230
|
+
"namespace": "mcp__world",
|
|
231
|
+
"arguments": '{"text":"hello"}',
|
|
232
|
+
}
|
|
233
|
+
]
|
|
234
|
+
)
|
|
178
235
|
# Two leaves off one root → 2 branches (a compaction-shaped trace), so the round-trip has to
|
|
179
236
|
# carry node `parent` links for `num_branches` to survive.
|
|
180
237
|
tr = vf.Trace[MyTask, vf.State](
|
|
181
238
|
agent=vf.AgentInfo(config=vf.AgentConfig()),
|
|
182
239
|
task=vf.TraceTask(type="MyTask", data=MyTask(idx=0, prompt="q", answer="a")),
|
|
183
|
-
tools=
|
|
240
|
+
tools=request.tools,
|
|
184
241
|
nodes=[
|
|
185
242
|
MessageNode(parent=None, message=UserMessage(content="q"), sampled=False),
|
|
186
|
-
MessageNode(parent=0, message=
|
|
243
|
+
MessageNode(parent=0, message=assistant, sampled=True),
|
|
187
244
|
MessageNode(parent=0, message=AssistantMessage(content="a2"), sampled=True),
|
|
188
245
|
],
|
|
189
246
|
)
|
|
@@ -193,9 +250,26 @@ def test_wire_trace_round_trip():
|
|
|
193
250
|
tr.info = {"build": "ok"}
|
|
194
251
|
tr.root_reply = "root answer"
|
|
195
252
|
tr.stop("done")
|
|
253
|
+
prepare_turn(tr, [], request.tools).commit_prompt()
|
|
196
254
|
|
|
197
255
|
# the dump is plain pydantic — derived values are properties, so they're not serialized
|
|
198
256
|
data = json.loads(tr.model_dump_json(exclude_none=True))
|
|
257
|
+
assert "trace-test-" not in json.dumps(data)
|
|
258
|
+
assert mcp["authorization"] == "trace-test-oauth-token"
|
|
259
|
+
assert mcp["headers"] == {"Authorization": "Bearer trace-test-header-token"}
|
|
260
|
+
assert mcp["Authorization"] == "trace-test-case-oauth-token"
|
|
261
|
+
assert mcp["Headers"] == {"X-Api-Key": "trace-test-case-header-token"}
|
|
262
|
+
chat_request = ChatDialect().parse_request(
|
|
263
|
+
{"tools": [mcp, mcp | {"server_label": "beta"}]}
|
|
264
|
+
)
|
|
265
|
+
chat_trace = tr.model_copy(update={"tools": []})
|
|
266
|
+
prepare_turn(chat_trace, [], chat_request.tools).commit_prompt()
|
|
267
|
+
assert [tool.name for tool in chat_trace.tools] == ["alpha", "beta"]
|
|
268
|
+
assert "trace-test-" not in chat_trace.model_dump_json()
|
|
269
|
+
assert (
|
|
270
|
+
vf.WireTrace.model_validate_json(chat_trace.model_dump_json()).tools
|
|
271
|
+
== chat_request.tools
|
|
272
|
+
)
|
|
199
273
|
assert "reward" not in data and "is_truncated" not in data
|
|
200
274
|
# exclude_none drops None FIELDS, not None dict values — unscored seeds survive
|
|
201
275
|
assert data["rewards"]["solved"] is None and data["metrics"]["acc"] is None
|
|
@@ -214,6 +288,19 @@ def test_wire_trace_round_trip():
|
|
|
214
288
|
assert (
|
|
215
289
|
rt.tools == tr.tools
|
|
216
290
|
) # the advertised tools persist (tool-use SFT reads them)
|
|
291
|
+
assert [tool.namespace for tool in rt.tools[:3]] == [
|
|
292
|
+
None,
|
|
293
|
+
"mcp__world",
|
|
294
|
+
"mcp__other",
|
|
295
|
+
]
|
|
296
|
+
assert all(tool.parameters == function["parameters"] for tool in rt.tools[:3])
|
|
297
|
+
assert all(tool.strict is False for tool in rt.tools[:3])
|
|
298
|
+
assert rt.tools[3].type == "custom"
|
|
299
|
+
assert rt.tools[3].model_extra == {"format": {"type": "text"}}
|
|
300
|
+
assert rt.tools[4].type == "web_search"
|
|
301
|
+
assert rt.tools[4].model_extra == {"search_context_size": "low"}
|
|
302
|
+
assert [tool.name for tool in rt.tools[5:]] == ["alpha", "beta"]
|
|
303
|
+
assert rt.nodes[1].message.tool_calls[0].namespace == "mcp__world"
|
|
217
304
|
assert rt.task.data.model_extra == {
|
|
218
305
|
"answer": "a"
|
|
219
306
|
} # taskset extras preserved on WireTaskData
|
|
@@ -38,6 +38,10 @@ T = TypeVar("T")
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
def tool_to_wire(tool: Tool) -> dict:
|
|
41
|
+
if tool.type != "function" or tool.namespace:
|
|
42
|
+
raise NotImplementedError(
|
|
43
|
+
"The renderer client only supports unnamespaced function tools."
|
|
44
|
+
)
|
|
41
45
|
function: dict = {
|
|
42
46
|
"name": tool.name,
|
|
43
47
|
"description": tool.description,
|
|
@@ -61,6 +65,7 @@ def serialize_completion(response: Response, model: str) -> dict:
|
|
|
61
65
|
"type": c.type,
|
|
62
66
|
c.type: {
|
|
63
67
|
"name": c.name,
|
|
68
|
+
**({"namespace": c.namespace} if c.namespace else {}),
|
|
64
69
|
"input" if c.type == "custom" else "arguments": c.arguments,
|
|
65
70
|
},
|
|
66
71
|
}
|
|
@@ -52,7 +52,8 @@ STOP_REASONS: dict[str, FinishReason] = {
|
|
|
52
52
|
"stop_sequence": "stop",
|
|
53
53
|
}
|
|
54
54
|
# Claude may reorder mixed thinking block types between a response and its replay.
|
|
55
|
-
|
|
55
|
+
# Native tool events share the final rank, preserving their relative order.
|
|
56
|
+
THINKING_ORDER = {"redacted_thinking": 0, "thinking": 1}
|
|
56
57
|
# These versioned tool families return calls to the harness; every other typed tool may execute
|
|
57
58
|
# at the provider. Anchoring the pattern keeps new versions client-side without treating an
|
|
58
59
|
# arbitrary dated provider tool as safe.
|
|
@@ -259,8 +260,10 @@ def parse_messages(body: dict) -> Messages:
|
|
|
259
260
|
if isinstance(content, str)
|
|
260
261
|
else content or []
|
|
261
262
|
)
|
|
262
|
-
state = [
|
|
263
|
-
|
|
263
|
+
state = [
|
|
264
|
+
block for block in blocks if block["type"] not in ("text", "tool_use")
|
|
265
|
+
]
|
|
266
|
+
state.sort(key=lambda block: THINKING_ORDER.get(block["type"], 2))
|
|
264
267
|
text = "".join(b.get("text", "") for b in blocks if b.get("type") == "text")
|
|
265
268
|
reasoning = "".join(
|
|
266
269
|
b.get("thinking", "") for b in blocks if b.get("type") == "thinking"
|
|
@@ -269,6 +272,7 @@ def parse_messages(body: dict) -> Messages:
|
|
|
269
272
|
ToolCall(
|
|
270
273
|
id=b.get("id", ""),
|
|
271
274
|
name=b.get("name", ""),
|
|
275
|
+
namespace=b.get("toolset_name"),
|
|
272
276
|
arguments=json.dumps(b.get("input") or {}),
|
|
273
277
|
)
|
|
274
278
|
for b in blocks
|
|
@@ -311,8 +315,9 @@ def response_from_wire(message: AnthropicMessage) -> Response:
|
|
|
311
315
|
reasoning: list[str] = []
|
|
312
316
|
calls: list[ToolCall] = []
|
|
313
317
|
for block in message.content:
|
|
314
|
-
if block.type in
|
|
315
|
-
|
|
318
|
+
if block.type not in ("text", "tool_use"):
|
|
319
|
+
# SDK-inserted defaults are absent when the native response is replayed.
|
|
320
|
+
state.append(block.model_dump(exclude_unset=True))
|
|
316
321
|
if block.type == "text":
|
|
317
322
|
content.append(block.text)
|
|
318
323
|
elif block.type == "thinking":
|
|
@@ -322,10 +327,11 @@ def response_from_wire(message: AnthropicMessage) -> Response:
|
|
|
322
327
|
ToolCall(
|
|
323
328
|
id=block.id,
|
|
324
329
|
name=block.name,
|
|
330
|
+
namespace=block.toolset_name,
|
|
325
331
|
arguments=json.dumps(block.input or {}),
|
|
326
332
|
)
|
|
327
333
|
)
|
|
328
|
-
state.sort(key=lambda block:
|
|
334
|
+
state.sort(key=lambda block: THINKING_ORDER.get(block["type"], 2))
|
|
329
335
|
finish = STOP_REASONS.get(message.stop_reason or "")
|
|
330
336
|
provider_usage = message.usage
|
|
331
337
|
output_details = provider_usage.model_dump().get("output_tokens_details")
|
|
@@ -580,14 +586,23 @@ class AnthropicDialect(Dialect[AnthropicMessage]):
|
|
|
580
586
|
}
|
|
581
587
|
|
|
582
588
|
def parse_request(self, body: RawRequest) -> Request:
|
|
589
|
+
native_tools = body.get("tools") or []
|
|
590
|
+
if not isinstance(native_tools, list) or any(
|
|
591
|
+
not isinstance(tool, dict) for tool in native_tools
|
|
592
|
+
):
|
|
593
|
+
raise ValueError("tools must be an array of objects")
|
|
583
594
|
tools = [
|
|
584
|
-
Tool(
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
595
|
+
Tool.model_validate(
|
|
596
|
+
{k: v for k, v in t.items() if k != "input_schema"}
|
|
597
|
+
| {
|
|
598
|
+
"name": t.get("name") or t.get("mcp_server_name") or t.get("type"),
|
|
599
|
+
"type": "function"
|
|
600
|
+
if t.get("type") in (None, "custom")
|
|
601
|
+
else t["type"],
|
|
602
|
+
"parameters": t.get("input_schema") or {},
|
|
603
|
+
}
|
|
588
604
|
)
|
|
589
|
-
for t in
|
|
590
|
-
if "input_schema" in t # skip server tools (web_search etc.)
|
|
605
|
+
for t in native_tools
|
|
591
606
|
] or None
|
|
592
607
|
return Request(messages=parse_messages(body), tools=tools)
|
|
593
608
|
|
|
@@ -122,6 +122,7 @@ def parse_message(raw: dict) -> Message:
|
|
|
122
122
|
id=call["id"],
|
|
123
123
|
type=kind,
|
|
124
124
|
name=native["name"],
|
|
125
|
+
namespace=native.get("namespace"),
|
|
125
126
|
arguments=native["input" if kind == "custom" else "arguments"],
|
|
126
127
|
)
|
|
127
128
|
)
|
|
@@ -135,21 +136,26 @@ def parse_message(raw: dict) -> Message:
|
|
|
135
136
|
|
|
136
137
|
|
|
137
138
|
def parse_tools(raw: list[dict] | None) -> list[Tool] | None:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
139
|
+
tools = []
|
|
140
|
+
for declaration in raw or []:
|
|
141
|
+
kind = declaration.get("type", "function")
|
|
142
|
+
tool = declaration.get(kind, declaration)
|
|
143
|
+
if kind == "mcp":
|
|
144
|
+
tool = {
|
|
145
|
+
key: value
|
|
146
|
+
for key, value in tool.items()
|
|
147
|
+
if key.lower() not in ("authorization", "headers")
|
|
148
|
+
}
|
|
149
|
+
tools.append(
|
|
150
|
+
Tool.model_validate(
|
|
151
|
+
tool
|
|
152
|
+
| {
|
|
153
|
+
"type": kind,
|
|
154
|
+
"name": tool.get("name") or tool.get("server_label") or kind,
|
|
155
|
+
}
|
|
156
|
+
)
|
|
149
157
|
)
|
|
150
|
-
|
|
151
|
-
if t.get("type", "function") == "function"
|
|
152
|
-
] or None
|
|
158
|
+
return tools or None
|
|
153
159
|
|
|
154
160
|
|
|
155
161
|
# --- vf -> chat wire ----------------------------------------------------------
|
|
@@ -184,6 +190,7 @@ def message_to_wire(message: Message) -> dict:
|
|
|
184
190
|
"type": call.type,
|
|
185
191
|
call.type: {
|
|
186
192
|
"name": call.name,
|
|
193
|
+
**({"namespace": call.namespace} if call.namespace else {}),
|
|
187
194
|
"input"
|
|
188
195
|
if call.type == "custom"
|
|
189
196
|
else "arguments": call.arguments,
|
|
@@ -302,8 +309,9 @@ class ChatStreamParser(StreamParser):
|
|
|
302
309
|
slot["type"] = kind
|
|
303
310
|
native = slot.setdefault(kind, {"name": ""})
|
|
304
311
|
delta_native = tool_call.get(kind) or {}
|
|
305
|
-
|
|
306
|
-
|
|
312
|
+
for field in ("name", "namespace"):
|
|
313
|
+
if delta_native.get(field):
|
|
314
|
+
native[field] = delta_native[field]
|
|
307
315
|
input_field = "input" if kind == "custom" else "arguments"
|
|
308
316
|
self.tool_inputs.setdefault(index, []).append(
|
|
309
317
|
delta_native.get(input_field) or ""
|
|
@@ -303,6 +303,7 @@ def fold_assistant(items: list[dict] | None) -> AssistantMessage:
|
|
|
303
303
|
id=item.get("call_id", ""),
|
|
304
304
|
type="custom" if kind == "custom_tool_call" else "function",
|
|
305
305
|
name=item.get("name", ""),
|
|
306
|
+
namespace=item.get("namespace"),
|
|
306
307
|
arguments=item.get("arguments", item.get("input", "")),
|
|
307
308
|
)
|
|
308
309
|
)
|
|
@@ -612,17 +613,38 @@ class ResponsesDialect(Dialect[OpenAIResponse]):
|
|
|
612
613
|
prompt.append(UserMessage(content=parse_content(item.get("content"))))
|
|
613
614
|
if run:
|
|
614
615
|
prompt.append(fold_assistant(run))
|
|
615
|
-
tools = [
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
if
|
|
624
|
-
|
|
625
|
-
|
|
616
|
+
tools = []
|
|
617
|
+
declarations = []
|
|
618
|
+
for item in items:
|
|
619
|
+
if item.get("type") in ("additional_tools", "tool_search_output"):
|
|
620
|
+
declarations.extend(item.get("tools") or [])
|
|
621
|
+
# Current declarations take precedence over definitions replayed in history.
|
|
622
|
+
declarations.extend(body.get("tools") or [])
|
|
623
|
+
for group in declarations:
|
|
624
|
+
namespace = group["name"] if group.get("type") == "namespace" else None
|
|
625
|
+
for tool in group["tools"] if namespace else [group]:
|
|
626
|
+
if tool.get("type") == "mcp":
|
|
627
|
+
# Connection credentials belong in the native request, not the trace.
|
|
628
|
+
tool = {
|
|
629
|
+
key: value
|
|
630
|
+
for key, value in tool.items()
|
|
631
|
+
if key.lower() not in ("authorization", "headers")
|
|
632
|
+
}
|
|
633
|
+
tools.append(
|
|
634
|
+
Tool.model_validate(
|
|
635
|
+
tool
|
|
636
|
+
| {
|
|
637
|
+
"name": tool.get("name")
|
|
638
|
+
or tool.get("server_label")
|
|
639
|
+
or tool.get("type"),
|
|
640
|
+
"namespace": namespace,
|
|
641
|
+
"description": tool.get("description") or "",
|
|
642
|
+
"parameters": tool.get("parameters") or {},
|
|
643
|
+
}
|
|
644
|
+
)
|
|
645
|
+
)
|
|
646
|
+
tools = list({(t.namespace, t.name, t.type): t for t in tools}.values())
|
|
647
|
+
return Request(messages=prompt, tools=tools or None)
|
|
626
648
|
|
|
627
649
|
def parse_response(self, response: OpenAIResponse) -> Response:
|
|
628
650
|
return response_from_wire(response)
|
|
@@ -713,6 +735,7 @@ class ResponsesDialect(Dialect[OpenAIResponse]):
|
|
|
713
735
|
item = raw["output"][0]
|
|
714
736
|
part = item["content"][0]
|
|
715
737
|
common = {"output_index": 0, "item_id": item["id"], "content_index": 0}
|
|
738
|
+
logprobs = part.get("logprobs") or []
|
|
716
739
|
head = {
|
|
717
740
|
**raw,
|
|
718
741
|
"status": "in_progress",
|
|
@@ -729,8 +752,15 @@ class ResponsesDialect(Dialect[OpenAIResponse]):
|
|
|
729
752
|
"response.content_part.added",
|
|
730
753
|
{**common, "part": {**part, "text": ""}},
|
|
731
754
|
),
|
|
732
|
-
|
|
733
|
-
(
|
|
755
|
+
# `logprobs` is required on both text events; carry the part's own.
|
|
756
|
+
(
|
|
757
|
+
"response.output_text.delta",
|
|
758
|
+
{**common, "delta": part["text"], "logprobs": logprobs},
|
|
759
|
+
),
|
|
760
|
+
(
|
|
761
|
+
"response.output_text.done",
|
|
762
|
+
{**common, "text": part["text"], "logprobs": logprobs},
|
|
763
|
+
),
|
|
734
764
|
("response.content_part.done", {**common, "part": part}),
|
|
735
765
|
("response.output_item.done", {"output_index": 0, "item": item}),
|
|
736
766
|
("response.completed", {"response": raw}),
|
|
@@ -340,6 +340,7 @@ def message_hash(message: Message) -> str:
|
|
|
340
340
|
add(tc.type)
|
|
341
341
|
add(tc.id)
|
|
342
342
|
add(tc.name)
|
|
343
|
+
add(tc.namespace or "")
|
|
343
344
|
add(
|
|
344
345
|
tc.arguments
|
|
345
346
|
if tc.type == "custom"
|
|
@@ -547,7 +548,13 @@ class PendingTurn:
|
|
|
547
548
|
def commit(self, response: Response) -> int:
|
|
548
549
|
"""Add this turn to the graph; returns the committed assistant node's id."""
|
|
549
550
|
assistant_id = _commit_turn(self, response)
|
|
550
|
-
|
|
551
|
+
if self.tools:
|
|
552
|
+
self.trace.tools = list(
|
|
553
|
+
{
|
|
554
|
+
(tool.namespace, tool.name, tool.type): tool
|
|
555
|
+
for tool in [*self.trace.tools, *self.tools]
|
|
556
|
+
}.values()
|
|
557
|
+
)
|
|
551
558
|
self.trace.clear_preview(self)
|
|
552
559
|
return assistant_id
|
|
553
560
|
|
|
@@ -574,7 +581,13 @@ class PendingTurn:
|
|
|
574
581
|
)
|
|
575
582
|
parent = len(self.trace.nodes) - 1
|
|
576
583
|
index[_node_key(previous, message, self.tools)] = parent
|
|
577
|
-
|
|
584
|
+
if self.tools:
|
|
585
|
+
self.trace.tools = list(
|
|
586
|
+
{
|
|
587
|
+
(tool.namespace, tool.name, tool.type): tool
|
|
588
|
+
for tool in [*self.trace.tools, *self.tools]
|
|
589
|
+
}.values()
|
|
590
|
+
)
|
|
578
591
|
self.trace.clear_preview(self)
|
|
579
592
|
|
|
580
593
|
|
{verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/verifiers/v1/tasksets/nemo_gym/response.py
RENAMED
|
@@ -70,6 +70,7 @@ def trace_to_nemo_response(
|
|
|
70
70
|
else "function_call",
|
|
71
71
|
"call_id": call.id,
|
|
72
72
|
"name": call.name,
|
|
73
|
+
**({"namespace": call.namespace} if call.namespace else {}),
|
|
73
74
|
("input" if call.type == "custom" else "arguments"): call.arguments,
|
|
74
75
|
}
|
|
75
76
|
for call in message.tool_calls or []
|
|
@@ -408,7 +408,7 @@ class Trace(BaseModel, Generic[DataT, StateT, AgentConfigT]):
|
|
|
408
408
|
agent: AgentInfo[AgentConfigT]
|
|
409
409
|
"""The agent (harness x model x runtime) that produced this trace."""
|
|
410
410
|
tools: list[Tool] = Field(default_factory=list)
|
|
411
|
-
"""
|
|
411
|
+
"""Tools observed across requests; the latest definition wins for each identity."""
|
|
412
412
|
|
|
413
413
|
nodes: list[MessageNode] = Field(default_factory=list)
|
|
414
414
|
"""The message graph, including physical and semantic parent links."""
|
|
@@ -709,7 +709,8 @@ class Trace(BaseModel, Generic[DataT, StateT, AgentConfigT]):
|
|
|
709
709
|
if message.content:
|
|
710
710
|
lines.append(message.content)
|
|
711
711
|
lines.extend(
|
|
712
|
-
f"[tool_call {call.
|
|
712
|
+
f"[tool_call {call.namespace + '.' if call.namespace else ''}"
|
|
713
|
+
f"{call.name}({call.arguments})]"
|
|
713
714
|
for call in message.tool_calls or []
|
|
714
715
|
)
|
|
715
716
|
else:
|
|
@@ -68,6 +68,8 @@ class ToolCall(BaseModel):
|
|
|
68
68
|
id: str
|
|
69
69
|
type: Literal["function", "custom"] = "function"
|
|
70
70
|
name: str
|
|
71
|
+
namespace: str | None = None
|
|
72
|
+
"""Provider namespace qualifying the tool name, when sent separately."""
|
|
71
73
|
arguments: str
|
|
72
74
|
"""Raw function arguments or custom-tool input, exactly as the model emitted it."""
|
|
73
75
|
|
|
@@ -97,9 +99,14 @@ Messages = list[Message]
|
|
|
97
99
|
|
|
98
100
|
|
|
99
101
|
class Tool(BaseModel):
|
|
102
|
+
# Native declarations carry format, discovery, and provider-specific settings.
|
|
103
|
+
model_config = ConfigDict(extra="allow")
|
|
104
|
+
|
|
105
|
+
type: str = "function"
|
|
100
106
|
name: str
|
|
101
|
-
|
|
102
|
-
|
|
107
|
+
namespace: str | None = None
|
|
108
|
+
description: str = ""
|
|
109
|
+
parameters: dict[str, Any] = Field(default_factory=dict)
|
|
103
110
|
strict: bool | None = None
|
|
104
111
|
|
|
105
112
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{verifiers-0.3.2.dev123 → verifiers-0.3.2.dev125}/tests/v1/fixtures/tool_response_image_v1.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|