verifiers 0.4.1.dev36__tar.gz → 0.4.1.dev46__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.
Files changed (278) hide show
  1. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/PKG-INFO +2 -2
  2. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/pyproject.toml +1 -1
  3. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/conftest.py +6 -3
  4. verifiers-0.4.1.dev36/tests/integration/fixtures/agent_user_v1.py → verifiers-0.4.1.dev46/tests/integration/fixtures/agent_user.py +1 -1
  5. verifiers-0.4.1.dev36/tests/integration/fixtures/agent_user_harness_v1.py → verifiers-0.4.1.dev46/tests/integration/fixtures/agent_user_harness.py +1 -1
  6. verifiers-0.4.1.dev36/tests/integration/fixtures/duet_v1.py → verifiers-0.4.1.dev46/tests/integration/fixtures/duet.py +2 -2
  7. verifiers-0.4.1.dev36/tests/integration/fixtures/echo_v1.py → verifiers-0.4.1.dev46/tests/integration/fixtures/echo.py +1 -1
  8. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/fixtures/echo_tool_compose/docker-compose.yaml +1 -1
  9. verifiers-0.4.1.dev46/tests/integration/fixtures/fetch_tool.py +36 -0
  10. verifiers-0.4.1.dev36/tests/integration/fixtures/network_policy_v1.py → verifiers-0.4.1.dev46/tests/integration/fixtures/network_policy.py +1 -1
  11. verifiers-0.4.1.dev46/tests/integration/fixtures/parallel.py +84 -0
  12. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/fixtures/pyproject.toml +7 -6
  13. verifiers-0.4.1.dev36/tests/integration/fixtures/skill_codeword_v1.py → verifiers-0.4.1.dev46/tests/integration/fixtures/skill_codeword.py +1 -1
  14. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/grid.py +39 -2
  15. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_agent_user.py +5 -5
  16. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_agentic_judge.py +2 -2
  17. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_limits.py +4 -4
  18. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_multi_agent.py +5 -5
  19. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_multi_turn.py +7 -4
  20. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_multi_turn_tool.py +3 -3
  21. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_multimodal_tool.py +2 -2
  22. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_network_policy.py +2 -2
  23. verifiers-0.4.1.dev46/tests/integration/test_parallel.py +36 -0
  24. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_resume_tool.py +2 -2
  25. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_rubric_judge.py +1 -1
  26. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_sampling.py +1 -1
  27. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_shared_tool.py +1 -1
  28. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_single_turn.py +2 -2
  29. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_skills.py +2 -2
  30. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_stateful_tool.py +2 -2
  31. verifiers-0.4.1.dev46/tests/integration/test_tool_vms.py +88 -0
  32. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_user_echo.py +2 -2
  33. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_user_sim.py +2 -2
  34. verifiers-0.4.1.dev46/tests/unit/runtimes/test_private_network.py +254 -0
  35. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/test_graph.py +66 -23
  36. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/acp/__init__.py +9 -0
  37. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/validate.py +66 -10
  38. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/clients/train.py +4 -0
  39. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/cli/validate.py +3 -0
  40. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/dialects/anthropic.py +11 -6
  41. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/dialects/base.py +11 -2
  42. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/dialects/chat.py +1 -0
  43. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/dialects/responses.py +1 -0
  44. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/grading.py +15 -8
  45. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/graph.py +69 -30
  46. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harness.py +4 -3
  47. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/claude_code/harness.py +2 -2
  48. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/hermes_agent/harness.py +2 -2
  49. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/kimi_code/harness.py +9 -4
  50. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/opencode/harness.py +11 -4
  51. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/pi/harness.py +9 -8
  52. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/prime_agent/harness.py +2 -2
  53. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/interception/server.py +40 -48
  54. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/mcp/launch.py +28 -9
  55. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/mcp/toolset.py +3 -0
  56. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/rollout.py +25 -6
  57. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/deployment.py +19 -5
  58. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/prime.py +43 -16
  59. verifiers-0.4.1.dev46/verifiers/v1/runtimes/private_network.py +148 -0
  60. verifiers-0.4.1.dev46/verifiers/v1/runtimes/strategies.py +119 -0
  61. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/session.py +7 -2
  62. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/harbor/taskset.py +8 -0
  63. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/trace.py +2 -2
  64. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/types.py +15 -0
  65. verifiers-0.4.1.dev36/verifiers/v1/runtimes/strategies.py +0 -64
  66. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/.gitignore +0 -0
  67. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/LICENSE +0 -0
  68. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/README.md +0 -0
  69. /verifiers-0.4.1.dev36/tests/integration/fixtures/counter_tool_v1.py → /verifiers-0.4.1.dev46/tests/integration/fixtures/counter_tool.py +0 -0
  70. /verifiers-0.4.1.dev36/tests/integration/fixtures/echo_acp_resume_v1.py → /verifiers-0.4.1.dev46/tests/integration/fixtures/echo_acp_resume.py +0 -0
  71. /verifiers-0.4.1.dev36/tests/integration/fixtures/echo_agentic_v1.py → /verifiers-0.4.1.dev46/tests/integration/fixtures/echo_agentic.py +0 -0
  72. /verifiers-0.4.1.dev36/tests/integration/fixtures/echo_tool_v1.py → /verifiers-0.4.1.dev46/tests/integration/fixtures/echo_tool.py +0 -0
  73. /verifiers-0.4.1.dev36/tests/integration/fixtures/echo_user_sim_v1.py → /verifiers-0.4.1.dev46/tests/integration/fixtures/echo_user_sim.py +0 -0
  74. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/fixtures/skills/project-codeword/SKILL.md +0 -0
  75. /verifiers-0.4.1.dev36/tests/integration/fixtures/tool_response_image_v1.py → /verifiers-0.4.1.dev46/tests/integration/fixtures/tool_response_image.py +0 -0
  76. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_compose_scoring.py +0 -0
  77. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/integration/test_examples.py +0 -0
  78. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/cli/test_replay.py +0 -0
  79. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/conftest.py +0 -0
  80. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/harnesses/test_core.py +0 -0
  81. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/harnesses/test_rlm.py +0 -0
  82. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/interception/test_tunnel.py +0 -0
  83. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/judges/conftest.py +0 -0
  84. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/judges/test_judge.py +0 -0
  85. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/judges/test_reference.py +0 -0
  86. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/judges/test_rubric.py +0 -0
  87. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/runtimes/test_e2b.py +0 -0
  88. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/serve/test_client.py +0 -0
  89. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/serve/test_delta.py +0 -0
  90. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/serve/test_pool.py +0 -0
  91. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/test_agent.py +0 -0
  92. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/test_dialects.py +0 -0
  93. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/test_semantic.py +0 -0
  94. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/test_task.py +0 -0
  95. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/test_taskset.py +0 -0
  96. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/test_trace.py +0 -0
  97. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/utils/test_compile.py +0 -0
  98. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/utils/test_loaders.py +0 -0
  99. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/utils/test_platform.py +0 -0
  100. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/tests/unit/utils/test_score.py +0 -0
  101. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/__init__.py +0 -0
  102. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/__init__.py +0 -0
  103. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/acp/runner.py +0 -0
  104. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/agent.py +0 -0
  105. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/__init__.py +0 -0
  106. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/dashboard/__init__.py +0 -0
  107. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/dashboard/base.py +0 -0
  108. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/dashboard/eval.py +0 -0
  109. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/dashboard/replay.py +0 -0
  110. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/dashboard/validate.py +0 -0
  111. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/debug.py +0 -0
  112. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/eval/__init__.py +0 -0
  113. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/eval/hint.py +0 -0
  114. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/eval/main.py +0 -0
  115. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/eval/resume.py +0 -0
  116. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/eval/runner.py +0 -0
  117. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/gepa.py +0 -0
  118. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/output.py +0 -0
  119. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/replay.py +0 -0
  120. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/resolve.py +0 -0
  121. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/cli/resume.py +0 -0
  122. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/clients/__init__.py +0 -0
  123. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/clients/base.py +0 -0
  124. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/clients/client.py +0 -0
  125. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/clients/eval.py +0 -0
  126. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/__init__.py +0 -0
  127. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/agent.py +0 -0
  128. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/cli/__init__.py +0 -0
  129. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/cli/debug.py +0 -0
  130. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/cli/env.py +0 -0
  131. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/cli/eval.py +0 -0
  132. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/cli/replay.py +0 -0
  133. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/client.py +0 -0
  134. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/env.py +0 -0
  135. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/harness.py +0 -0
  136. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/judge.py +0 -0
  137. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/retries.py +0 -0
  138. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/runtime.py +0 -0
  139. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/scoring.py +0 -0
  140. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/select.py +0 -0
  141. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/serve.py +0 -0
  142. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/task.py +0 -0
  143. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/configs/taskset.py +0 -0
  144. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/dialects/__init__.py +0 -0
  145. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/env.py +0 -0
  146. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/envs/__init__.py +0 -0
  147. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
  148. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/envs/agentic_judge/env.py +0 -0
  149. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
  150. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/envs/best_of_n/env.py +0 -0
  151. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/envs/single_agent/__init__.py +0 -0
  152. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/envs/single_agent/env.py +0 -0
  153. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/envs/user_sim/__init__.py +0 -0
  154. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/envs/user_sim/env.py +0 -0
  155. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/episode.py +0 -0
  156. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/errors.py +0 -0
  157. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/gepa/__init__.py +0 -0
  158. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/gepa/adapter.py +0 -0
  159. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/gepa/config.py +0 -0
  160. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/gepa/dataset.py +0 -0
  161. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/gepa/reflection.py +0 -0
  162. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/gepa/runner.py +0 -0
  163. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/__init__.py +0 -0
  164. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/bash/__init__.py +0 -0
  165. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/bash/harness.py +0 -0
  166. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/browser_use/__init__.py +0 -0
  167. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/browser_use/harness.py +0 -0
  168. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/browser_use/program.py +0 -0
  169. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
  170. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/codex/__init__.py +0 -0
  171. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/codex/gate.mjs +0 -0
  172. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/codex/harness.py +0 -0
  173. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/deepseek/__init__.py +0 -0
  174. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/deepseek/gate.mjs +0 -0
  175. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/deepseek/harness.py +0 -0
  176. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/deepseek/usage.mjs +0 -0
  177. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/hermes_agent/__init__.py +0 -0
  178. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/hermes_agent/program.py +0 -0
  179. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
  180. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
  181. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
  182. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
  183. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/node.py +0 -0
  184. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/null/__init__.py +0 -0
  185. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/null/harness.py +0 -0
  186. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/openclaw/__init__.py +0 -0
  187. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/openclaw/harness.py +0 -0
  188. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/opencode/__init__.py +0 -0
  189. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/opencode/mcp-ready.js +0 -0
  190. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/pi/__init__.py +0 -0
  191. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/pi/gate.mjs +0 -0
  192. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/prime_agent/__init__.py +0 -0
  193. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
  194. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/rlm/harness.py +0 -0
  195. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
  196. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
  197. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
  198. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/utils/__init__.py +0 -0
  199. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/utils/compaction.py +0 -0
  200. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/utils/core.py +0 -0
  201. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/utils/install.py +0 -0
  202. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/utils/launch.py +0 -0
  203. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/utils/mcp.py +0 -0
  204. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/harnesses/utils/replay.py +0 -0
  205. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/interception/__init__.py +0 -0
  206. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/interception/base.py +0 -0
  207. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/interception/pool.py +0 -0
  208. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/interception/tunnel/__init__.py +0 -0
  209. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/interception/tunnel/base.py +0 -0
  210. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/interception/tunnel/custom.py +0 -0
  211. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/interception/tunnel/prime.py +0 -0
  212. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/judge.py +0 -0
  213. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/judges/__init__.py +0 -0
  214. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/judges/decision.py +0 -0
  215. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/judges/reference.py +0 -0
  216. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/judges/reference.txt +0 -0
  217. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/judges/rubric.py +0 -0
  218. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/judges/rubric.txt +0 -0
  219. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/mcp/__init__.py +0 -0
  220. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/mcp/server.py +0 -0
  221. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/__init__.py +0 -0
  222. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/apptainer.py +0 -0
  223. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/base.py +0 -0
  224. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/compose.py +0 -0
  225. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/container.py +0 -0
  226. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/docker/__init__.py +0 -0
  227. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/docker/egress.py +0 -0
  228. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/e2b.py +0 -0
  229. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/limiters.py +0 -0
  230. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/modal.py +0 -0
  231. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/runtime.py +0 -0
  232. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/runtimes/subprocess.py +0 -0
  233. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/semantic.py +0 -0
  234. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/serve/__init__.py +0 -0
  235. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/serve/client.py +0 -0
  236. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/serve/delta.py +0 -0
  237. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/serve/encoding.py +0 -0
  238. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/serve/pool.py +0 -0
  239. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/serve/server.py +0 -0
  240. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/serve/types.py +0 -0
  241. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/state.py +0 -0
  242. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/task.py +0 -0
  243. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/taskset.py +0 -0
  244. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/__init__.py +0 -0
  245. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
  246. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/harbor/toolset.py +0 -0
  247. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/nemo_gym/__init__.py +0 -0
  248. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/nemo_gym/response.py +0 -0
  249. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/nemo_gym/server.py +0 -0
  250. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/nemo_gym/taskset.py +0 -0
  251. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/nemo_gym/toolset.py +0 -0
  252. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
  253. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
  254. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
  255. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
  256. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/__init__.py +0 -0
  257. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/aio.py +0 -0
  258. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/artifacts.py +0 -0
  259. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/compile.py +0 -0
  260. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/decorators.py +0 -0
  261. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/env.py +0 -0
  262. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/eval.py +0 -0
  263. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/format.py +0 -0
  264. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/generic.py +0 -0
  265. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/git.py +0 -0
  266. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/image.py +0 -0
  267. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/interrupt.py +0 -0
  268. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/loaders.py +0 -0
  269. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/logging.py +0 -0
  270. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/memory.py +0 -0
  271. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/paths.py +0 -0
  272. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/platform.py +0 -0
  273. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/prime.py +0 -0
  274. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/retries.py +0 -0
  275. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/scope.py +0 -0
  276. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/score.py +0 -0
  277. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/trace_store.py +0 -0
  278. {verifiers-0.4.1.dev36 → verifiers-0.4.1.dev46}/verifiers/v1/utils/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: verifiers
3
- Version: 0.4.1.dev36
3
+ Version: 0.4.1.dev46
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
@@ -36,7 +36,7 @@ Requires-Dist: numpy>=2.1.0
36
36
  Requires-Dist: openai<3.0.0,>=2.54.0
37
37
  Requires-Dist: prime-pydantic-config[toml]>=0.4.3
38
38
  Requires-Dist: prime-runs>=0.1.4
39
- Requires-Dist: prime-sandboxes>=0.4.2
39
+ Requires-Dist: prime-sandboxes>=0.4.7
40
40
  Requires-Dist: prime-tunnel>=0.1.14
41
41
  Requires-Dist: pydantic>=2.12.3
42
42
  Requires-Dist: pyzmq>=27.1.0
@@ -33,7 +33,7 @@ dependencies = [
33
33
  "math-verify>=0.8.0",
34
34
  "openai>=2.54.0,<3.0.0",
35
35
  "prime-tunnel>=0.1.14",
36
- "prime-sandboxes>=0.4.2",
36
+ "prime-sandboxes>=0.4.7",
37
37
  "prime-runs>=0.1.4",
38
38
  "pydantic>=2.12.3",
39
39
  "rich>=11.0.0",
@@ -29,7 +29,7 @@ CI_REASONING_EFFORT = "low"
29
29
  CI_JUDGE = {"model": CI_MODEL, "sampling": {"reasoning_effort": CI_REASONING_EFFORT}}
30
30
  CI_DECISION_JUDGE = {"model": "cloudflare/clef"}
31
31
 
32
- # Fixture tasksets (echo-v1, echo-agentic-v1, ...) live in tests/integration/fixtures,
32
+ # Fixture tasksets (echo, echo-agentic, ...) live in tests/integration/fixtures,
33
33
  # added to the path via `pythonpath` in pyproject so the loader resolves them by id.
34
34
 
35
35
  LIVE_FIXTURES = {"run", "live_ctx"}
@@ -46,11 +46,14 @@ def harness_runtime(request) -> dict:
46
46
  @pytest.fixture
47
47
  def tool_runtime(request) -> dict:
48
48
  """A `taskset.task.tools` override placing the tool server: `colocated` (inside the harness's
49
- runtime), `service` (in the task's `tools` Compose service) or its own runtime, by type."""
49
+ runtime), `service` (in the task's `tools` Compose service), `service-vm` (in the task's
50
+ `tools-vm` service VM) or its own runtime, by type."""
50
51
  if request.param == "colocated":
51
52
  return {"colocated": True}
52
53
  if request.param == "service":
53
54
  return {"service": "tools"}
55
+ if request.param == "service-vm":
56
+ return {"service": "tools-vm"}
54
57
  return {"runtime": {"type": request.param}}
55
58
 
56
59
 
@@ -67,7 +70,7 @@ def harness(request) -> HarnessConfig:
67
70
  def pytest_configure(config) -> None:
68
71
  """Self-launching tool servers run `python -m <module>` in a fresh subprocess, which
69
72
  inherits `PYTHONPATH` but not pytest's in-process `pythonpath`. Put the fixture dir on
70
- `PYTHONPATH` so a fixture server module (e.g. `tool_response_image_v1`)
73
+ `PYTHONPATH` so a fixture server module (e.g. `tool_response_image`)
71
74
  resolves there too — an installed example package (e.g. `glossary`) already would."""
72
75
  config.addinivalue_line(
73
76
  "markers", "opencode: integration cells on the OpenCode harness"
@@ -1,4 +1,4 @@
1
- """agent-user-v1: a scripted, model-free agent that runs as a non-root user and tries root actions.
1
+ """agent-user: a scripted, model-free agent that runs as a non-root user and tries root actions.
2
2
 
3
3
  Root setup creates the task's `agent_user`, plants a root-only secret, and prepares a uv
4
4
  script; the workdir stays root-owned, like a typical image WORKDIR. The scripted harness runs
@@ -1,4 +1,4 @@
1
- """agent-user-harness-v1: one turn of any harness running as a non-root agent user.
1
+ """agent-user-harness: one turn of any harness running as a non-root agent user.
2
2
 
3
3
  Root setup creates the task's `agent_user` (images normally ship one) and hands it the
4
4
  workdir; the harness then installs, launches as that user, and answers a one-line prompt.
@@ -1,6 +1,6 @@
1
1
  """duet: the smallest multi-agent environment — two roles echo the same phrase.
2
2
 
3
- The multi-agent fixture for the v1 integration suite (resolved by id `duet-v1`): an
3
+ The multi-agent fixture for the v1 integration suite (resolved by id `duet`): an
4
4
  `Env` subclass exported alongside its taskset, with two roles ("a", a trainable
5
5
  seat on the run's model; "b", pinned untrainable), a `run()` that fans both out on
6
6
  the task, and a `finalize()` that records a sibling-dependent signal. One episode
@@ -9,7 +9,7 @@ should land one record carrying two role-stamped traces.
9
9
 
10
10
  import asyncio
11
11
 
12
- from echo_v1 import EchoTaskset, lenient_match
12
+ from echo import EchoTaskset, lenient_match
13
13
 
14
14
  import verifiers.v1 as vf
15
15
 
@@ -3,7 +3,7 @@
3
3
  The smallest possible reward-1 taskset — no dataset, no tools, no reasoning required — so an
4
4
  end-to-end eval run is fast and deterministic. The reward is 1.0 when the phrase appears in
5
5
  the model's reply. It's a fixture taskset for the integration suite (in tests/integration/fixtures,
6
- resolved by id `echo-v1` via pytest's `pythonpath`).
6
+ resolved by id `echo` via pytest's `pythonpath`).
7
7
  """
8
8
 
9
9
  from pydantic import Field
@@ -1,4 +1,4 @@
1
- # echo-tool-v1 with its tool server placed in a Compose service: the server runs in
1
+ # echo-tool with its tool server placed in a Compose service: the server runs in
2
2
  # `tools`, beside the workspace (`main`, the runtime's image), and the harness reaches it
3
3
  # over the Compose network by the service's name.
4
4
  services:
@@ -0,0 +1,36 @@
1
+ """fetch (v1, MCP tool): a tool server on a Prime VM of its own, under its own egress.
2
+
3
+ The integration test places a `FetchToolset` on a Prime runtime of its own
4
+ (`tools.runtime`) beside an offline workspace. The server's VM joins the workspace over
5
+ the rollout's private network and keeps the egress policy of its own runtime.
6
+ """
7
+
8
+ import urllib.request
9
+
10
+ import verifiers.v1 as vf
11
+
12
+
13
+ class FetchToolset(vf.Toolset[vf.ToolsetConfig]):
14
+ TOOL_PREFIX = "fetch"
15
+
16
+ @vf.tool
17
+ def fetch(self, url: str) -> str:
18
+ """Fetch a URL; return its HTTP status, or the type of the error."""
19
+ try:
20
+ return str(urllib.request.urlopen(url, timeout=15).status)
21
+ except (OSError, ValueError) as error: # URLError and timeouts are OSErrors
22
+ return type(error).__name__
23
+
24
+
25
+ class FetchToolTaskConfig(vf.TaskConfig):
26
+ tools: vf.ToolsetConfig = vf.ToolsetConfig()
27
+
28
+
29
+ class FetchToolTask(vf.Task[vf.TaskData, vf.State, FetchToolTaskConfig]):
30
+ @classmethod
31
+ def toolsets(cls, config: FetchToolTaskConfig) -> list[vf.Toolset]:
32
+ return [FetchToolset(config.tools)]
33
+
34
+
35
+ if __name__ == "__main__":
36
+ FetchToolset.run()
@@ -1,4 +1,4 @@
1
- """network-policy-v1: the agent runs an egress probe under the task's network policy.
1
+ """network-policy: the agent runs an egress probe under the task's network policy.
2
2
 
3
3
  One task per policy the task data can declare: `open` (the default), `off` (an empty
4
4
  allowlist), `block` (blocks `example.com`) and `allow` (allows only `pypi.org`). Setup
@@ -0,0 +1,84 @@
1
+ """parallel: one rollout whose harness sends `n` chat programs at the model at once,
2
+ so their requests overlap on one trace. With `same_prompt`, every copy sends the task
3
+ prompt; otherwise copy `i` appends its index, so the copies diverge after the system
4
+ prompt."""
5
+
6
+ import asyncio
7
+
8
+ from pydantic import PositiveInt
9
+
10
+ import verifiers.v1 as vf
11
+ from verifiers.v1.clients import ModelContext
12
+ from verifiers.v1.configs.harness import HarnessConfig
13
+ from verifiers.v1.harness import Harness
14
+ from verifiers.v1.harnesses.utils.launch import (
15
+ CHAT_PROGRAM_SOURCE,
16
+ launch_chat_program,
17
+ )
18
+ from verifiers.v1.runtimes import ProgramResult, Runtime
19
+
20
+ __all__ = ["ParallelHarness", "ParallelTaskset"]
21
+
22
+
23
+ class ParallelHarnessConfig(HarnessConfig):
24
+ n: PositiveInt = 4
25
+ same_prompt: bool = True
26
+
27
+
28
+ class ParallelHarness(Harness[ParallelHarnessConfig]):
29
+ APPENDS_SYSTEM_PROMPT = True
30
+ EXECUTES_CODE = False
31
+ NEEDS_CONTAINER = False
32
+
33
+ async def setup(self, runtime: Runtime) -> None:
34
+ await runtime.prepare_uv_script(CHAT_PROGRAM_SOURCE, self.config.resolved_env)
35
+
36
+ async def launch(
37
+ self,
38
+ ctx: ModelContext,
39
+ trace: vf.Trace,
40
+ runtime: Runtime,
41
+ endpoint: str,
42
+ secret: str,
43
+ mcp_urls: dict[str, str],
44
+ data: vf.TaskData,
45
+ tool_interception_url: str | None = None,
46
+ ) -> ProgramResult:
47
+ system_prompt, prompt = self.resolve_prompt(data)
48
+
49
+ def copy_prompt(i: int) -> str:
50
+ return prompt if self.config.same_prompt else f"{prompt} ({i})"
51
+
52
+ results = await asyncio.gather(
53
+ *(
54
+ launch_chat_program(
55
+ CHAT_PROGRAM_SOURCE,
56
+ self.config,
57
+ ctx,
58
+ trace,
59
+ runtime,
60
+ endpoint,
61
+ secret,
62
+ mcp_urls,
63
+ system_prompt,
64
+ copy_prompt(i),
65
+ )
66
+ for i in range(self.config.n)
67
+ )
68
+ )
69
+ return next((r for r in results if r.exit_code != 0), results[0])
70
+
71
+
72
+ class ParallelTask(vf.Task):
73
+ @vf.reward(weight=1.0)
74
+ async def answered(self, trace: vf.Trace) -> float:
75
+ return float(trace.num_turns >= 1)
76
+
77
+
78
+ class ParallelTaskset(vf.Taskset[ParallelTask, vf.TasksetConfig]):
79
+ def load(self) -> list[ParallelTask]:
80
+ return [
81
+ ParallelTask(
82
+ vf.TaskData(idx=0, system_prompt="Be brief.", prompt="Reply with OK.")
83
+ )
84
+ ]
@@ -10,14 +10,15 @@ requires = ["hatchling"]
10
10
  build-backend = "hatchling.build"
11
11
 
12
12
  # Flat fixture modules whose tool servers self-launch in a sandbox (docker/prime) and so must
13
- # be importable there. The others (echo_v1, echo_user_sim_v1, echo_*_v0) have no server, so they
13
+ # be importable there. The others (e.g. echo, echo_user_sim) have no server, so they
14
14
  # never get installed.
15
15
  [tool.hatch.build]
16
16
  include = [
17
- "agent_user_v1.py",
18
- "counter_tool_v1.py",
19
- "echo_acp_resume_v1.py",
20
- "echo_tool_v1.py",
21
- "tool_response_image_v1.py",
17
+ "agent_user.py",
18
+ "counter_tool.py",
19
+ "echo_acp_resume.py",
20
+ "echo_tool.py",
21
+ "fetch_tool.py",
22
+ "tool_response_image.py",
22
23
  "pyproject.toml",
23
24
  ]
@@ -1,4 +1,4 @@
1
- """skill-codeword-v1: the answer lives only in a skill the task installs.
1
+ """skill-codeword: the answer lives only in a skill the task installs.
2
2
 
3
3
  The task ships a `project-codeword` skill (fixtures/skills) whose SKILL.md holds a
4
4
  codeword the prompt never reveals, so reward 1.0 proves the harness installed the skill
@@ -32,6 +32,7 @@ prime cannot pull) stay outside the grid.
32
32
 
33
33
  import shutil
34
34
  from collections.abc import Sequence
35
+ from typing import get_args
35
36
 
36
37
  import pytest
37
38
  from pydantic import TypeAdapter
@@ -40,7 +41,7 @@ import verifiers.v1 as vf
40
41
  from verifiers.v1.configs.runtime import NetworkPolicyConfig
41
42
  from verifiers.v1.harness import Harness
42
43
  from verifiers.v1.runtimes import RuntimeConfig, _backend_cls
43
- from verifiers.v1.utils.loaders import harness_class
44
+ from verifiers.v1.utils.loaders import harness_class, harness_config_type
44
45
 
45
46
  HARNESSES: list[str | dict] = [
46
47
  "null",
@@ -191,6 +192,36 @@ def grid(
191
192
  return cells
192
193
 
193
194
 
195
+ def transports(harness: str) -> tuple[str, ...]:
196
+ """The wire formats the harness config can select (`transport`) besides its
197
+ default. Empty when the program speaks one format or picks its own."""
198
+ field = harness_config_type(harness).model_fields.get("transport")
199
+ if field is None:
200
+ return ()
201
+ return tuple(t for t in get_args(field.annotation) if t != field.default)
202
+
203
+
204
+ def transport_grid(
205
+ runtimes: Sequence[str] = ("prime",), *, needs: tuple[str, ...] = ()
206
+ ) -> list:
207
+ """`grid` cells for every non-default `transport` each harness config can select."""
208
+ cells = []
209
+ for harness in HARNESSES:
210
+ name = harness_id(harness)
211
+ for transport in transports(name):
212
+ for cell in grid(
213
+ [{"id": name, "transport": transport}], runtimes, needs=needs
214
+ ):
215
+ cells.append(
216
+ pytest.param(
217
+ *cell.values,
218
+ marks=cell.marks,
219
+ id=cell.id.replace(f"{name}-in-", f"{name}-{transport}-in-"),
220
+ )
221
+ )
222
+ return cells
223
+
224
+
194
225
  def skip_harness(cells: list, harness: str, reason: str) -> list:
195
226
  """Skip one harness's cells for a limit no capability flag declares. Each use names
196
227
  why, so a reader sees the gap and when it can go."""
@@ -209,9 +240,13 @@ def skip_harness(cells: list, harness: str, reason: str) -> list:
209
240
  def placements(
210
241
  harness_runtimes: tuple[str, ...] = tuple(RUNTIMES),
211
242
  tool_runtimes: tuple[str, ...] = ("colocated", *RUNTIMES),
243
+ *,
244
+ shared: bool = False,
212
245
  ) -> list:
213
246
  """`(harness_runtime, tool_runtime)` cells for a tool server placed colocated in the
214
- harness's box, in a Compose service beside it (`service`), or in its own runtime."""
247
+ harness's box, in a Compose service beside it (`service`), or in its own runtime
248
+ (on Prime beside a Prime harness, a VM on the rollout's private network). A `shared`
249
+ server runs once per eval, so it joins no rollout's network."""
215
250
  cells = []
216
251
  for harness_runtime in harness_runtimes:
217
252
  for tool_runtime in tool_runtimes:
@@ -233,6 +268,8 @@ def placements(
233
268
  elif (
234
269
  tool_runtime not in ("colocated", "service")
235
270
  and not runtime_cls(tool_runtime).supports_expose
271
+ # Beside a Prime harness, a rollout's Prime server joins its private network.
272
+ and not (not shared and tool_runtime == harness_runtime == "prime")
236
273
  ):
237
274
  marks.append(
238
275
  pytest.mark.skip(
@@ -1,6 +1,6 @@
1
1
  """The task's non-root agent user: a scripted agent is denied root-only actions
2
- (agent-user-v1), and every harness installs and runs as that user against a scripted
3
- upstream (agent-user-harness-v1), on the runtimes that can switch users."""
2
+ (agent-user), and every harness installs and runs as that user against a scripted
3
+ upstream (agent-user-harness), on the runtimes that can switch users."""
4
4
 
5
5
  import pytest
6
6
  from grid import grid, runtimes_grid
@@ -18,8 +18,8 @@ async def test_agent_user_cannot_act_as_root(run, harness_runtime, preinstalled_
18
18
  all act as the user. With `preinstalled_tools`, the tool's package was first installed
19
19
  by the default user, as on a reused runtime."""
20
20
  (episode,) = await run(
21
- "agent-user-v1",
22
- harness="agent-user-v1",
21
+ "agent-user",
22
+ harness="agent-user",
23
23
  runtime=harness_runtime,
24
24
  taskset_overrides={"preinstalled_tools": preinstalled_tools},
25
25
  )
@@ -46,7 +46,7 @@ async def test_agent_user_harness(run, harness, harness_runtime, scripted_model)
46
46
  """Each harness installs and runs a turn as a non-root agent user against a scripted
47
47
  upstream, so the run fails only if the harness can't set up or run without root."""
48
48
  (episode,) = await run(
49
- "agent-user-harness-v1",
49
+ "agent-user-harness",
50
50
  harness=harness,
51
51
  runtime=harness_runtime,
52
52
  client=scripted_model,
@@ -7,7 +7,7 @@ async def test_agentic_judge_shared_verifier(run, tmp_path):
7
7
  policy = tmp_path / "judge_policy.txt"
8
8
  policy.write_text("Check EMPIRICALLY that the agent echoed the word back.")
9
9
  (episode,) = await run(
10
- "echo-v1",
10
+ "echo",
11
11
  harness=None,
12
12
  env={
13
13
  "id": "agentic-judge",
@@ -53,7 +53,7 @@ async def test_env_id_agentic_judge(run, tmp_path):
53
53
  "Check EMPIRICALLY that answer.txt contains exactly the requested phrase."
54
54
  )
55
55
  (episode,) = await run(
56
- "echo-agentic-v1",
56
+ "echo-agentic",
57
57
  harness=None,
58
58
  env={
59
59
  "id": "agentic-judge",
@@ -1,5 +1,5 @@
1
1
  """The seat's caps stop a rollout that would run on: the counter task wants three tool
2
- turns (counter-tool-v1), and each cap ends it after the first with its own stop
2
+ turns (counter-tool), and each cap ends it after the first with its own stop
3
3
  condition. The turn cap also runs across the harness x runtime grid, since each program
4
4
  handles a refused request in its own way."""
5
5
 
@@ -17,7 +17,7 @@ CAPS = [
17
17
  @pytest.mark.parametrize("cap,stop_condition", CAPS)
18
18
  async def test_cap(run, cap, stop_condition):
19
19
  (episode,) = await run(
20
- "counter-tool-v1",
20
+ "counter-tool",
21
21
  harness="null",
22
22
  runtime={"type": "subprocess"},
23
23
  env={"agent": cap},
@@ -31,7 +31,7 @@ async def test_cap(run, cap, stop_condition):
31
31
 
32
32
  async def test_rollout_timeout(run):
33
33
  (episode,) = await run(
34
- "counter-tool-v1",
34
+ "counter-tool",
35
35
  harness="null",
36
36
  runtime={"type": "subprocess"},
37
37
  rollout_timeout=1,
@@ -44,7 +44,7 @@ async def test_rollout_timeout(run):
44
44
  @pytest.mark.parametrize("harness,harness_runtime", grid(needs=("mcp",)), indirect=True)
45
45
  async def test_max_turns(run, harness, harness_runtime):
46
46
  (episode,) = await run(
47
- "counter-tool-v1",
47
+ "counter-tool",
48
48
  harness=harness,
49
49
  runtime=harness_runtime,
50
50
  max_turns=1,
@@ -1,15 +1,15 @@
1
- """Multi-agent episodes: an `Env` with two roles (duet-v1), best-of-n over a plain
1
+ """Multi-agent episodes: an `Env` with two roles (duet), best-of-n over a plain
2
2
  taskset, and turn-coupled self-play (kuhn-poker)."""
3
3
 
4
4
  import json
5
5
 
6
6
 
7
7
  async def test_multi_agent_env(run):
8
- """An `Env` subclass shipped with its taskset (duet-v1): two roles run the
8
+ """An `Env` subclass shipped with its taskset (duet): two roles run the
9
9
  task, `score()` episodes a sibling-dependent metric, and one episode carries
10
10
  two role-stamped traces."""
11
11
  (episode,) = await run(
12
- "duet-v1",
12
+ "duet",
13
13
  harness=None, # both duet seats pin their own harness
14
14
  max_turns=2,
15
15
  )
@@ -26,7 +26,7 @@ async def test_multi_agent_env(run):
26
26
  # The wire form (what traces.jsonl stores): one episode carrying both traces, each
27
27
  # self-stamped on its agent info (completion order — the seats land in either order).
28
28
  row = json.loads(episode.model_dump_json(exclude_none=True))
29
- assert row["env"] == {"id": "duet-v1"}
29
+ assert row["env"] == {"id": "duet"}
30
30
  by_name = {t["agent"]["name"]: t for t in row["traces"]}
31
31
  assert set(by_name) == {"a", "b"}
32
32
  assert by_name["a"]["agent"]["trainable"] is True
@@ -37,7 +37,7 @@ async def test_env_id_best_of_n(run):
37
37
  """`--env.id` pairs a bundled env with an arbitrary taskset: best-of-n over the
38
38
  plain echo taskset — n solver attempts in one episode, sibling-scored."""
39
39
  (episode,) = await run(
40
- "echo-v1",
40
+ "echo",
41
41
  harness=None, # a multi-agent env refuses the run-level harness
42
42
  env={"id": "best-of-n", "n": 2, "agent": {"harness": {"id": "null"}}},
43
43
  max_turns=2,
@@ -1,11 +1,14 @@
1
- """One task, many turns: the model completes a shell task (echo-agentic-v1: write a phrase
2
- to a file, checked in the runtime) across the harness x runtime grid."""
1
+ """One task, many turns: the model completes a shell task (echo-agentic: write a phrase
2
+ to a file, checked in the runtime) across the harness x runtime grid, and on prime over
3
+ every other `transport` a harness config can select. A turn the harness re-sends
4
+ differently, beyond what its `replay_view` declares, forks the trace."""
3
5
 
4
6
  import pytest
5
- from grid import grid, mark
7
+ from grid import grid, mark, transport_grid
6
8
 
7
9
  MULTI_TURN = [
8
10
  *grid(needs=("shell",)),
11
+ *transport_grid(needs=("shell",)),
9
12
  pytest.param(
10
13
  "bash",
11
14
  {"type": "modal", "allow": []},
@@ -18,7 +21,7 @@ MULTI_TURN = [
18
21
  @pytest.mark.parametrize("harness,harness_runtime", MULTI_TURN, indirect=True)
19
22
  async def test_multi_turn(run, harness, harness_runtime):
20
23
  (episode,) = await run(
21
- "echo-agentic-v1",
24
+ "echo-agentic",
22
25
  harness=harness,
23
26
  runtime=harness_runtime,
24
27
  max_turns=10,
@@ -1,5 +1,5 @@
1
1
  """One task, one MCP tool: the model calls a tool whose output carries a stamp the prompt
2
- never reveals (echo-tool-v1), so reward 1.0 proves the tool ran. Every MCP harness reaches
2
+ never reveals (echo-tool), so reward 1.0 proves the tool ran. Every MCP harness reaches
3
3
  it colocated across the harness x runtime grid; the chat loop reaches it across its
4
4
  placements (colocated in the harness's box, in a Compose service beside it, or its own
5
5
  runtime) on the runtime x runtime grid."""
@@ -14,7 +14,7 @@ import verifiers.v1 as vf
14
14
  async def test_tool(run, harness, harness_runtime):
15
15
  """Every MCP-capable harness reaches a tool colocated in its runtime."""
16
16
  (episode,) = await run(
17
- "echo-tool-v1",
17
+ "echo-tool",
18
18
  harness=harness,
19
19
  runtime=harness_runtime,
20
20
  max_turns=6,
@@ -46,7 +46,7 @@ async def test_tool_placement(run, harness_runtime, tool_runtime):
46
46
  on the chat loop. Eval-wide SHARED servers are a different scope (`Taskset.toolsets`),
47
47
  covered by `test_shared_tool`."""
48
48
  (episode,) = await run(
49
- "echo-tool-v1",
49
+ "echo-tool",
50
50
  harness="null",
51
51
  runtime=harness_runtime,
52
52
  max_turns=6,
@@ -1,11 +1,11 @@
1
1
  """A tool that returns an image: MCP image content from a tool result survives into the
2
- trace (tool-response-image-v1; needs a vision model)."""
2
+ trace (tool-response-image; needs a vision model)."""
3
3
 
4
4
 
5
5
  async def test_multimodal_tool(run):
6
6
  """MCP image content from a tool result survives into the v1 trace (needs a vision model)."""
7
7
  (episode,) = await run(
8
- "tool-response-image-v1",
8
+ "tool-response-image",
9
9
  harness="null",
10
10
  runtime={"type": "subprocess"},
11
11
  reasoning_effort="none",
@@ -1,6 +1,6 @@
1
1
  """A task's network policy holds during execution, and the model is told about it: the
2
2
  agent runs an egress probe under each policy the task data declares
3
- (network-policy-v1), with the agent's `network_notice` on or off, across every harness
3
+ (network-policy), with the agent's `network_notice` on or off, across every harness
4
4
  on prime."""
5
5
 
6
6
  import pytest
@@ -42,7 +42,7 @@ def prompt_text(trace) -> str:
42
42
  )
43
43
  async def test_network_policy(run, harness, harness_runtime, notice):
44
44
  episodes = await run(
45
- "network-policy-v1",
45
+ "network-policy",
46
46
  harness=harness,
47
47
  runtime=harness_runtime,
48
48
  num_tasks=len(NOTICES),
@@ -0,0 +1,36 @@
1
+ """Overlapping requests on one trace: a harness sends `n` chat programs at a scripted
2
+ upstream at once, and the trace graph keeps one branch per copy that shares exactly the
3
+ prefix the copies have in common."""
4
+
5
+ import pytest
6
+ from parallel import ParallelHarnessConfig
7
+
8
+ N = 4
9
+
10
+
11
+ @pytest.mark.parametrize("harness_runtime", ["subprocess"], indirect=True)
12
+ @pytest.mark.parametrize("same_prompt", [True, False], ids=["same", "distinct"])
13
+ async def test_parallel_requests(run, harness_runtime, scripted_model, same_prompt):
14
+ (episode,) = await run(
15
+ "parallel",
16
+ harness=ParallelHarnessConfig(id="parallel", n=N, same_prompt=same_prompt),
17
+ runtime=harness_runtime,
18
+ client=scripted_model,
19
+ )
20
+ (trace,) = episode.traces
21
+ assert trace.ok, [error.message for error in trace.errors]
22
+ assert trace.num_turns == trace.num_branches == len(trace.calls) == N
23
+ assert len({call.node for call in trace.calls}) == N
24
+
25
+ roles = [node.message.role for node in trace.nodes]
26
+ assert roles.count("system") == 1
27
+ users = [i for i, role in enumerate(roles) if role == "user"]
28
+ replies = [node for node in trace.nodes if node.message.role == "assistant"]
29
+ # The same prompt shares the system and user nodes; distinct prompts share only
30
+ # the system node.
31
+ assert len(users) == (1 if same_prompt else N)
32
+ assert len(trace.nodes) == 1 + len(users) + N
33
+ assert {trace.nodes[i].parent for i in users} == {0}
34
+ assert sorted(reply.parent for reply in replies) == sorted(
35
+ users * N if same_prompt else users
36
+ )
@@ -1,5 +1,5 @@
1
1
  """One task, two segments: the harness preserves context and MCP access across a resumed
2
- exchange (echo-acp-resume-v1), across the harness x runtime grid."""
2
+ exchange (echo-acp-resume), across the harness x runtime grid."""
3
3
 
4
4
  import pytest
5
5
  from grid import grid
@@ -11,7 +11,7 @@ from grid import grid
11
11
  async def test_resume_tool(run, harness, harness_runtime):
12
12
  """Each harness preserves context and MCP access across two segments."""
13
13
  (episode,) = await run(
14
- "echo-acp-resume-v1",
14
+ "echo-acp-resume",
15
15
  harness=harness,
16
16
  runtime=harness_runtime,
17
17
  max_turns=8,
@@ -24,7 +24,7 @@ async def test_rubric_judge(run, tmp_path, judge_id):
24
24
  if judge_id == "rubric":
25
25
  judge["path"] = str(rubric)
26
26
  (episode,) = await run(
27
- "echo-v1",
27
+ "echo",
28
28
  harness="null",
29
29
  runtime={"type": "subprocess"},
30
30
  taskset_overrides={"task": {"judges": [judge]}},
@@ -13,7 +13,7 @@ SAMPLING = {"temperature": 0.3, "top_p": 0.9, "reasoning_effort": "high"}
13
13
  )
14
14
  async def test_sampling_overrides(run, harness, harness_runtime):
15
15
  (episode,) = await run(
16
- "echo-v1",
16
+ "echo",
17
17
  harness=harness,
18
18
  runtime=harness_runtime,
19
19
  env={"agent": {"sampling": SAMPLING}},
@@ -8,7 +8,7 @@ from grid import HARNESS_RUNTIMES, placements
8
8
 
9
9
  @pytest.mark.parametrize(
10
10
  "harness_runtime,tool_runtime",
11
- placements(tool_runtimes=tuple(HARNESS_RUNTIMES)),
11
+ placements(tool_runtimes=tuple(HARNESS_RUNTIMES), shared=True),
12
12
  indirect=True,
13
13
  )
14
14
  async def test_shared_tool(run, harness_runtime, tool_runtime):
@@ -1,4 +1,4 @@
1
- """One task, one reply: the model echoes a phrase back (echo-v1), across the harness x
1
+ """One task, one reply: the model echoes a phrase back (echo), across the harness x
2
2
  runtime grid."""
3
3
 
4
4
  import pytest
@@ -16,7 +16,7 @@ SINGLE_TURN = skip_harness(
16
16
  @pytest.mark.parametrize("harness,harness_runtime", SINGLE_TURN, indirect=True)
17
17
  async def test_single_turn(run, harness, harness_runtime):
18
18
  (episode,) = await run(
19
- "echo-v1",
19
+ "echo",
20
20
  harness=harness,
21
21
  runtime=harness_runtime,
22
22
  env={"agent": {"sampling": {"temperature": 0.0}}},