verifiers 0.3.2.dev32__tar.gz → 0.3.2.dev41__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 (211) hide show
  1. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/PKG-INFO +6 -6
  2. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/pyproject.toml +6 -5
  3. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/test_e2e.py +22 -3
  4. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/test_judges.py +62 -6
  5. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/__init__.py +2 -2
  6. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/replay.py +1 -1
  7. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/clients/train.py +3 -3
  8. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/graph.py +34 -31
  9. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/bash/harness.py +2 -0
  10. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/null/harness.py +2 -0
  11. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/prime_agent/harness.py +8 -8
  12. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/rlm/harness.py +80 -15
  13. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/utils/launch.py +6 -5
  14. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/judge.py +10 -2
  15. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/judges/rubric.py +1 -1
  16. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/lean/taskset.py +6 -1
  17. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/trace.py +45 -15
  18. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/types.py +24 -11
  19. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/.gitignore +0 -0
  20. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/LICENSE +0 -0
  21. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/README.md +0 -0
  22. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/conftest.py +0 -0
  23. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/fixtures/counter_tool_v1.py +0 -0
  24. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/fixtures/duet_v1.py +0 -0
  25. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/fixtures/echo_acp_resume_v1.py +0 -0
  26. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
  27. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/fixtures/echo_tool_v1.py +0 -0
  28. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
  29. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/fixtures/echo_v1.py +0 -0
  30. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/fixtures/pyproject.toml +0 -0
  31. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
  32. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/test_color_codeword_tasks.py +0 -0
  33. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/test_configs.py +0 -0
  34. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/test_envs.py +0 -0
  35. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/test_graph.py +0 -0
  36. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/test_scoring.py +0 -0
  37. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/test_taskset.py +0 -0
  38. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/tests/v1/test_trace.py +0 -0
  39. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/__init__.py +0 -0
  40. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/acp/__init__.py +0 -0
  41. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/acp/runner.py +0 -0
  42. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/agent.py +0 -0
  43. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/__init__.py +0 -0
  44. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/dashboard/__init__.py +0 -0
  45. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/dashboard/base.py +0 -0
  46. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/dashboard/eval.py +0 -0
  47. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/dashboard/replay.py +0 -0
  48. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/dashboard/validate.py +0 -0
  49. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/debug.py +0 -0
  50. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/eval/__init__.py +0 -0
  51. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/eval/main.py +0 -0
  52. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/eval/resume.py +0 -0
  53. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/eval/runner.py +0 -0
  54. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/gepa.py +0 -0
  55. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/init.py +0 -0
  56. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/output.py +0 -0
  57. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/resolve.py +0 -0
  58. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/resume.py +0 -0
  59. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/cli/validate.py +0 -0
  60. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/clients/__init__.py +0 -0
  61. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/clients/base.py +0 -0
  62. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/clients/client.py +0 -0
  63. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/clients/eval.py +0 -0
  64. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/__init__.py +0 -0
  65. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/agent.py +0 -0
  66. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/cli/__init__.py +0 -0
  67. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/cli/debug.py +0 -0
  68. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/cli/env.py +0 -0
  69. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/cli/eval.py +0 -0
  70. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/cli/init.py +0 -0
  71. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/cli/replay.py +0 -0
  72. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/cli/validate.py +0 -0
  73. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/client.py +0 -0
  74. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/env.py +0 -0
  75. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/harness.py +0 -0
  76. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/judge.py +0 -0
  77. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/retries.py +0 -0
  78. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/runtime.py +0 -0
  79. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/serve.py +0 -0
  80. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/task.py +0 -0
  81. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/configs/taskset.py +0 -0
  82. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/dialects/__init__.py +0 -0
  83. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/dialects/anthropic.py +0 -0
  84. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/dialects/base.py +0 -0
  85. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/dialects/chat.py +0 -0
  86. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/dialects/responses.py +0 -0
  87. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/env.py +0 -0
  88. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/envs/__init__.py +0 -0
  89. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
  90. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/envs/agentic_judge/env.py +0 -0
  91. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
  92. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/envs/best_of_n/env.py +0 -0
  93. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/envs/shared_agentic_judge/__init__.py +0 -0
  94. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/envs/single_agent/__init__.py +0 -0
  95. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/envs/single_agent/env.py +0 -0
  96. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/envs/user_sim/__init__.py +0 -0
  97. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/envs/user_sim/env.py +0 -0
  98. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/episode.py +0 -0
  99. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/errors.py +0 -0
  100. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/gepa/__init__.py +0 -0
  101. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/gepa/adapter.py +0 -0
  102. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/gepa/config.py +0 -0
  103. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/gepa/dataset.py +0 -0
  104. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/gepa/reflection.py +0 -0
  105. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/gepa/runner.py +0 -0
  106. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harness.py +0 -0
  107. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/__init__.py +0 -0
  108. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/bash/__init__.py +0 -0
  109. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/browser_use/__init__.py +0 -0
  110. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/browser_use/harness.py +0 -0
  111. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/browser_use/program.py +0 -0
  112. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
  113. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/claude_code/harness.py +0 -0
  114. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/codex/__init__.py +0 -0
  115. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/codex/harness.py +0 -0
  116. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/hermes_agent/__init__.py +0 -0
  117. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/hermes_agent/harness.py +0 -0
  118. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/hermes_agent/program.py +0 -0
  119. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
  120. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
  121. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
  122. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
  123. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
  124. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/node.py +0 -0
  125. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/null/__init__.py +0 -0
  126. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/openclaw/__init__.py +0 -0
  127. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/openclaw/harness.py +0 -0
  128. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/pi/__init__.py +0 -0
  129. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/pi/harness.py +0 -0
  130. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/pool/__init__.py +0 -0
  131. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/pool/harness.py +0 -0
  132. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/prime_agent/__init__.py +0 -0
  133. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
  134. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
  135. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
  136. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
  137. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/utils/__init__.py +0 -0
  138. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/utils/compaction.py +0 -0
  139. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/utils/core.py +0 -0
  140. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/harnesses/utils/mcp.py +0 -0
  141. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/interception/__init__.py +0 -0
  142. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/interception/base.py +0 -0
  143. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/interception/pool.py +0 -0
  144. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/interception/server.py +0 -0
  145. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/interception/tool.py +0 -0
  146. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/interception/tunnel/__init__.py +0 -0
  147. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/interception/tunnel/base.py +0 -0
  148. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/interception/tunnel/custom.py +0 -0
  149. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/interception/tunnel/prime.py +0 -0
  150. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/judges/__init__.py +0 -0
  151. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/judges/reference.py +0 -0
  152. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/judges/reference.txt +0 -0
  153. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/judges/rubric.txt +0 -0
  154. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/mcp/__init__.py +0 -0
  155. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/mcp/launch.py +0 -0
  156. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/mcp/server.py +0 -0
  157. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/mcp/toolset.py +0 -0
  158. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/rollout.py +0 -0
  159. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/runtimes/__init__.py +0 -0
  160. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/runtimes/base.py +0 -0
  161. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/runtimes/docker/__init__.py +0 -0
  162. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/runtimes/docker/egress.py +0 -0
  163. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/runtimes/limiters.py +0 -0
  164. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/runtimes/modal.py +0 -0
  165. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/runtimes/prime.py +0 -0
  166. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/runtimes/subprocess.py +0 -0
  167. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/semantic.py +0 -0
  168. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/serve/__init__.py +0 -0
  169. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/serve/client.py +0 -0
  170. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/serve/encoding.py +0 -0
  171. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/serve/pool.py +0 -0
  172. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/serve/server.py +0 -0
  173. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/serve/types.py +0 -0
  174. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/session.py +0 -0
  175. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/state.py +0 -0
  176. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/task.py +0 -0
  177. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/taskset.py +0 -0
  178. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/__init__.py +0 -0
  179. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
  180. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/harbor/env.py +0 -0
  181. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
  182. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/lean/__init__.py +0 -0
  183. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/lean/scoring.py +0 -0
  184. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/nemo_gym/__init__.py +0 -0
  185. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/nemo_gym/response.py +0 -0
  186. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/nemo_gym/server.py +0 -0
  187. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/nemo_gym/taskset.py +0 -0
  188. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/nemo_gym/toolset.py +0 -0
  189. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
  190. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
  191. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
  192. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
  193. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/__init__.py +0 -0
  194. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/aio.py +0 -0
  195. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/artifacts.py +0 -0
  196. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/compile.py +0 -0
  197. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/decorators.py +0 -0
  198. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/format.py +0 -0
  199. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/generic.py +0 -0
  200. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/git.py +0 -0
  201. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/image.py +0 -0
  202. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/interrupt.py +0 -0
  203. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/loaders.py +0 -0
  204. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/logging.py +0 -0
  205. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/memory.py +0 -0
  206. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/paths.py +0 -0
  207. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/platform.py +0 -0
  208. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/prime.py +0 -0
  209. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/retries.py +0 -0
  210. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/verifiers/v1/utils/score.py +0 -0
  211. {verifiers-0.3.2.dev32 → verifiers-0.3.2.dev41}/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.dev32
3
+ Version: 0.3.2.dev41
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
@@ -22,8 +22,7 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Requires-Python: <3.14,>=3.11
24
24
  Requires-Dist: aiohttp>=3.14.1
25
- Requires-Dist: anthropic>=0.78.0
26
- Requires-Dist: datasets<6.0.0,>=3.3.0
25
+ Requires-Dist: anthropic>=1.0.0
27
26
  Requires-Dist: gepa>=0.0.6
28
27
  Requires-Dist: httpx>=0.27.0
29
28
  Requires-Dist: loguru>=0.7.0
@@ -31,20 +30,21 @@ Requires-Dist: math-verify>=0.8.0
31
30
  Requires-Dist: mcp==2.0.0
32
31
  Requires-Dist: msgpack>=1.1.2
33
32
  Requires-Dist: numpy>=2.1.0
34
- Requires-Dist: openai>=2.9.0
33
+ Requires-Dist: openai<3.0.0,>=2.54.0
35
34
  Requires-Dist: prime-pydantic-config[toml]>=0.4.3
36
35
  Requires-Dist: prime-sandboxes>=0.2.39
37
36
  Requires-Dist: prime-tunnel>=0.1.8
38
37
  Requires-Dist: pydantic>=2.12.3
39
38
  Requires-Dist: pyzmq>=27.1.0
40
- Requires-Dist: renderers[multimodal]>=0.1.11
39
+ Requires-Dist: renderers[multimodal]>=0.1.12.dev2
41
40
  Requires-Dist: rich>=11.0.0
42
41
  Requires-Dist: tenacity>=8.5.0
43
42
  Requires-Dist: tomli-w>=1.0.0
44
43
  Requires-Dist: typing-extensions>=4.12.2
45
- Requires-Dist: uvloop>=0.21.0; sys_platform != 'win32' and sys_platform != 'cygwin' and platform_python_implementation != 'PyPy'
46
44
  Provides-Extra: harbor
47
45
  Requires-Dist: harbor==0.21.0; (python_full_version >= '3.12') and extra == 'harbor'
46
+ Provides-Extra: lean
47
+ Requires-Dist: datasets<6.0.0,>=3.3.0; extra == 'lean'
48
48
  Provides-Extra: modal
49
49
  Requires-Dist: modal>=1.4.0; extra == 'modal'
50
50
  Provides-Extra: openenv
@@ -27,11 +27,10 @@ classifiers = [
27
27
  ]
28
28
 
29
29
  dependencies = [
30
- "anthropic>=0.78.0",
31
- "datasets>=3.3.0,<6.0.0",
30
+ "anthropic>=1.0.0",
32
31
  "numpy>=2.1.0",
33
32
  "math-verify>=0.8.0",
34
- "openai>=2.9.0",
33
+ "openai>=2.54.0,<3.0.0",
35
34
  "prime-tunnel>=0.1.8",
36
35
  "prime-sandboxes>=0.2.39",
37
36
  "pydantic>=2.12.3",
@@ -43,10 +42,9 @@ dependencies = [
43
42
  "httpx>=0.27.0",
44
43
  "aiohttp>=3.14.1",
45
44
  "prime-pydantic-config[toml]>=0.4.3",
46
- "uvloop>=0.21.0; sys_platform != 'win32' and sys_platform != 'cygwin' and platform_python_implementation != 'PyPy'",
47
45
  "loguru>=0.7.0",
48
46
  "tomli-w>=1.0.0",
49
- "renderers[multimodal]>=0.1.11",
47
+ "renderers[multimodal]>=0.1.12.dev2",
50
48
  "typing_extensions>=4.12.2",
51
49
  "mcp==2.0.0",
52
50
  ]
@@ -86,6 +84,9 @@ examples = [
86
84
  ]
87
85
 
88
86
  [project.optional-dependencies]
87
+ lean = [
88
+ "datasets>=3.3.0,<6.0.0",
89
+ ]
89
90
  ta = [
90
91
  "textarena==0.7.4",
91
92
  "nltk>=3.9.2",
@@ -404,7 +404,7 @@ async def test_rubric_judge(run_v1, tmp_path):
404
404
  assert trace.ok
405
405
  assert trace.rewards["rubric"].score > 0 # the judge's verdict landed in the reward
406
406
  assert trace.metrics["rubric/always_yes"] == 1.0
407
- assert trace.info["judge"] # the call was recorded onto the trace
407
+ assert trace.info["judge_calls"] # the call was recorded onto the trace
408
408
 
409
409
 
410
410
  @pytest.mark.e2e
@@ -701,11 +701,29 @@ async def test_replay_round_trip(run_v1, tmp_path):
701
701
  assert source.ok
702
702
  assert "lcs" in source.rewards
703
703
 
704
+ # Replay must not mix the source run's judge transcript into newly computed
705
+ # judge calls. Seed a saved call directly because this task scores without a
706
+ # judge; cleanup happens before task scoring and therefore does not inspect it.
707
+ import json
708
+
709
+ stream = run_dir / "traces.jsonl"
710
+ record = json.loads(stream.read_text())
711
+ record["traces"][0]["info"]["judge_calls"] = [
712
+ {
713
+ "name": "source-judge",
714
+ "request": {"model": "source-model", "messages": []},
715
+ "response": {
716
+ "message": {"role": "assistant", "content": "stale"},
717
+ "parsed": None,
718
+ "usage": None,
719
+ },
720
+ }
721
+ ]
722
+ stream.write_text(json.dumps(record) + "\n")
723
+
704
724
  async def replay(source_dir: Path, out: Path):
705
725
  # The CLI's layering, minus the argv plumbing: the saved run's config is the base
706
726
  # (`ReplayConfig` ignores its eval-only keys), the source's output_dir is dropped.
707
- import json
708
-
709
727
  data = json.loads(saved_config_path(source_dir).read_text())
710
728
  data.pop("output_dir", None)
711
729
  config = ReplayConfig(**{**data, "rich": False})
@@ -720,6 +738,7 @@ async def test_replay_round_trip(run_v1, tmp_path):
720
738
  # and recomputed the same value.
721
739
  assert replayed.rewards.keys() == source.rewards.keys()
722
740
  assert replayed.reward == pytest.approx(source.reward)
741
+ assert "judge_calls" not in replayed.info
723
742
  # The wire task keeps its taskset-specific fields in the replay's own output.
724
743
  raw = (tmp_path / "replay2" / "traces.jsonl").read_text()
725
744
  assert '"answer"' in raw
@@ -92,7 +92,20 @@ def fake_judge_model(monkeypatch):
92
92
  if parse is not None:
93
93
  response.parsed = parse(response)
94
94
  if trace is not None:
95
- trace.record_judge(response)
95
+ from verifiers.v1.dialects.chat import message_to_wire
96
+
97
+ wire = (
98
+ [{"role": "user", "content": messages}]
99
+ if isinstance(messages, str)
100
+ else [message_to_wire(message) for message in messages]
101
+ )
102
+ kwargs = {"model": self.config.model, "messages": wire}
103
+ kwargs.update(sampling)
104
+ trace.record_judge_call(
105
+ name=self.reward_name,
106
+ request={"model": kwargs["model"], "messages": kwargs["messages"]},
107
+ response=response,
108
+ )
96
109
  return response
97
110
 
98
111
  monkeypatch.setattr(Judge, "complete", fake_complete)
@@ -225,7 +238,43 @@ async def test_reference_score(fake_judge_model):
225
238
  assert (
226
239
  "Capital of France?" in fake_judge_model[0]
227
240
  ) # the task prompt is in the judge prompt
228
- assert len(trace.info["judge"]) == 1 # the call is recorded onto the trace
241
+ assert len(trace.info["judge_calls"]) == 1 # the call is recorded onto the trace
242
+ judge_record = trace.info["judge_calls"][0]
243
+ assert judge_record["name"] == "reference"
244
+ assert judge_record["request"]["model"] == "openai/gpt-5.4-nano"
245
+ assert "Capital of France?" in judge_record["request"]["messages"][0]["content"]
246
+ assert judge_record["response"]["message"] == {
247
+ "role": "assistant",
248
+ "content": "yes",
249
+ "reasoning_content": None,
250
+ "tool_calls": None,
251
+ "provider_state": None,
252
+ }
253
+ assert judge_record["response"]["parsed"] == 1.0
254
+
255
+ request_messages = [{"role": "user", "content": "original"}]
256
+ request = {
257
+ "model": "openai/gpt-5.4-nano",
258
+ "messages": request_messages,
259
+ }
260
+ trace.record_judge_call(
261
+ name="snapshot",
262
+ request=request,
263
+ response=JudgeResponse(text="yes"),
264
+ )
265
+ request_messages[0]["content"] = "mutated"
266
+ assert (
267
+ trace.info["judge_calls"][-1]["request"]["messages"][0]["content"] == "original"
268
+ )
269
+
270
+ override_trace = make_trace()
271
+ await vf.ReferenceJudge().complete(
272
+ "Judge this response.", trace=override_trace, model="openai/gpt-5.4-mini"
273
+ )
274
+ assert (
275
+ override_trace.info["judge_calls"][0]["request"]["model"]
276
+ == "openai/gpt-5.4-mini"
277
+ )
229
278
 
230
279
  trace = make_trace(reply="It is Rome.")
231
280
  assert await vf.ReferenceJudge().score(trace.task.data, trace) == 0.0
@@ -446,7 +495,14 @@ async def test_error_attribution(monkeypatch, tmp_path):
446
495
  return response
447
496
  finally:
448
497
  if trace is not None:
449
- trace.record_judge(response)
498
+ trace.record_judge_call(
499
+ name=self.reward_name,
500
+ request={
501
+ "model": self.config.model,
502
+ "messages": [{"role": "user", "content": messages}],
503
+ },
504
+ response=response,
505
+ )
450
506
 
451
507
  monkeypatch.setattr(Judge, "complete", gibberish_judge)
452
508
  taskset = JudgedTaskset(
@@ -463,7 +519,7 @@ async def test_error_attribution(monkeypatch, tmp_path):
463
519
  trace, runtime=None
464
520
  )
465
521
  assert trace.rewards["reference"] is None # seeded: expected but never scored
466
- assert len(trace.info["judge"]) == 1 # the billed call is still recorded
522
+ assert len(trace.info["judge_calls"]) == 1 # the billed call is still recorded
467
523
 
468
524
 
469
525
  # --- rubric --------------------------------------------------------------------------------
@@ -542,7 +598,7 @@ async def test_rubric_score(tmp_path, fake_judge_model):
542
598
  trace = make_trace()
543
599
  assert await judge.score(trace.task.data, trace) == 0.75
544
600
  assert trace.metrics == {"rubric/mentions_paris": 1.0, "rubric/is_polite": 0.0}
545
- assert len(trace.info["judge"]) == 1 # one call for the whole rubric
601
+ assert len(trace.info["judge_calls"]) == 1 # one call for the whole rubric
546
602
 
547
603
 
548
604
  async def test_rubric_verdict_mismatch_raises(tmp_path, monkeypatch):
@@ -652,7 +708,7 @@ async def test_task_score_runs_plugged_judges(tmp_path, fake_judge_model):
652
708
  trace.rewards["quality"].score == 0.75
653
709
  ) # the rubric's aggregate, under its `name`
654
710
  assert (
655
- len(trace.info["judge"]) == 2
711
+ len(trace.info["judge_calls"]) == 2
656
712
  ) # every judge call recorded (rubric = one call)
657
713
 
658
714
 
@@ -116,7 +116,6 @@ from verifiers.v1.types import (
116
116
  ContentPart,
117
117
  ImageUrlContentPart,
118
118
  ImageUrlSource,
119
- KeptTokens,
120
119
  Message,
121
120
  MessageContent,
122
121
  Messages,
@@ -124,6 +123,7 @@ from verifiers.v1.types import (
124
123
  Response,
125
124
  Sampling,
126
125
  SamplingConfig,
126
+ SamplingMask,
127
127
  SystemMessage,
128
128
  TextContentPart,
129
129
  Tool,
@@ -249,7 +249,7 @@ __all__ = [ # noqa: RUF022 - grouped by public API area
249
249
  "MessageNode",
250
250
  "Branch",
251
251
  "TurnTokens",
252
- "KeptTokens",
252
+ "SamplingMask",
253
253
  "Timing",
254
254
  "TimeSpan",
255
255
  "TimeSplit",
@@ -156,7 +156,7 @@ async def run_replay(config: ReplayConfig, source: Path, out: Path) -> list[Trac
156
156
  else:
157
157
  st.state = "running"
158
158
  # Clear the recorded scores; only offline-recomputable ones come back.
159
- trace.info.pop("judge", None)
159
+ trace.info.pop("judge_calls", None)
160
160
  trace.rewards, trace.metrics, trace.extra_usage = {}, {}, []
161
161
  # The declared Task for a rebuilt row, the base Task for the
162
162
  # WireTaskData fallback.
@@ -23,9 +23,9 @@ from verifiers.v1.graph import PendingTurn
23
23
  from verifiers.v1.types import (
24
24
  AssistantMessage,
25
25
  FinishReason,
26
- KeptTokens,
27
26
  Response,
28
27
  SamplingConfig,
28
+ SamplingMask,
29
29
  Tool,
30
30
  ToolCall,
31
31
  TurnTokens,
@@ -161,8 +161,8 @@ def response_from_generate(
161
161
  multi_modal_data=result.get("multi_modal_data"),
162
162
  mm_token_type_id_map=mm_token_type_id_map,
163
163
  routed_experts=result.get("routed_experts"),
164
- kept_tokens=KeptTokens(**kept)
165
- if (kept := result.get("kept_tokens"))
164
+ sampling_mask=SamplingMask.from_sampling_mask(mask)
165
+ if (mask := result.get("sampling_mask"))
166
166
  else None,
167
167
  ),
168
168
  )
@@ -35,9 +35,9 @@ from renderers.base import MultiModalData, PlaceholderRange, RenderedTokens
35
35
  from verifiers.v1.semantic import ParentLink
36
36
  from verifiers.v1.types import (
37
37
  AssistantMessage,
38
- KeptTokens,
39
38
  Message,
40
39
  Response,
40
+ SamplingMask,
41
41
  TextContentPart,
42
42
  Tool,
43
43
  ToolMessage,
@@ -121,6 +121,12 @@ class MessageNode(BaseModel):
121
121
  reference_logprobs: list[float] | None = None
122
122
  """Reference-model logprobs over the sampled tokens, in the same compact layout as
123
123
  `logprobs`. None means no reference model scored this node."""
124
+ trainer_logprobs: list[float] | None = None
125
+ """Trainer-recomputed logprobs over the sampled tokens, in the same compact layout as
126
+ `logprobs`. None means no trainer forward annotated this node."""
127
+ entropies: list[float] | None = None
128
+ """Trainer policy entropies over the sampled tokens, in the same compact layout as
129
+ `logprobs`. None means no trainer forward annotated this node."""
124
130
  loss_weights: dict[str, list[float]] | None = None
125
131
  """Named loss-weight streams aligned to `token_ids`, consumer-stamped."""
126
132
  multi_modal_data: SkipJsonSchema[MultiModalData | None] = None
@@ -135,12 +141,12 @@ class MessageNode(BaseModel):
135
141
  the turn's `generate` payload by `_attribute_routed_experts`; `Branch.routed_experts`
136
142
  concatenates these along the path into the trainer's router-replay input. Rides the wire as
137
143
  a raw-bytes `__nd__` dict; kept off disk by the dump-site `exclude` in prime-rl."""
138
- kept_tokens: SkipJsonSchema[KeptTokens | None] = None
139
- """Kept-set sampling masks for this node's sampled tokens, decoded: `ids` flat int32
140
- in position order, `counts` the per-token kept-set sizes (aligned with `logprobs`;
141
- 0 = no mask). Assistant nodes only; consumed via `Branch.kept_tokens` for
142
- sampling-replay training. Rides the wire as raw-bytes `__nd__` dicts; kept off disk
143
- by the dump-site `exclude` in prime-rl."""
144
+ sampling_mask: SkipJsonSchema[SamplingMask | None] = None
145
+ """Sampling masks for this node's sampled tokens.
146
+
147
+ `ids` stores the flat token ids and `counts` stores each token's row size. Assistant
148
+ nodes only. The arrays serialize as raw-byte `__nd__` dictionaries.
149
+ """
144
150
 
145
151
  model_config = ConfigDict(arbitrary_types_allowed=True)
146
152
 
@@ -202,27 +208,26 @@ class MessageNode(BaseModel):
202
208
  return _decode_ndarray(value)
203
209
  raise TypeError(f"cannot build ndarray field from {type(value).__name__}")
204
210
 
205
- @field_serializer("kept_tokens")
206
- def serialize_kept_tokens(self, kept: KeptTokens | None) -> dict | None:
207
- """`KeptTokens` -> dict of raw-bytes `__nd__` entries so the arrays ride the wire."""
208
- if kept is None:
211
+ @field_serializer("sampling_mask")
212
+ def serialize_sampling_mask(self, mask: SamplingMask | None) -> dict | None:
213
+ if mask is None:
209
214
  return None
210
215
  return {
211
- "ids": _encode_ndarray(kept.ids),
212
- "counts": _encode_ndarray(kept.counts),
216
+ "ids": _encode_ndarray(mask.ids),
217
+ "counts": _encode_ndarray(mask.counts),
213
218
  }
214
219
 
215
- @field_validator("kept_tokens", mode="before")
220
+ @field_validator("sampling_mask", mode="before")
216
221
  @classmethod
217
- def deserialize_kept_tokens(cls, value: Any) -> KeptTokens | None:
218
- if value is None or isinstance(value, KeptTokens):
222
+ def deserialize_sampling_mask(cls, value: Any) -> SamplingMask | None:
223
+ if value is None or isinstance(value, SamplingMask):
219
224
  return value
220
225
  if isinstance(value, dict):
221
- return KeptTokens(
226
+ return SamplingMask(
222
227
  ids=_decode_ndarray(value["ids"]),
223
228
  counts=_decode_ndarray(value["counts"]),
224
229
  )
225
- raise TypeError(f"cannot build KeptTokens from {type(value).__name__}")
230
+ raise TypeError(f"cannot build SamplingMask from {type(value).__name__}")
226
231
 
227
232
 
228
233
  def _canonical_tool_arguments(arguments: str) -> str:
@@ -606,21 +611,18 @@ def _attribute_routed_experts(
606
611
  off = end
607
612
 
608
613
 
609
- def _attribute_kept_tokens(
610
- trace: Trace, assistant_id: int, payload: KeptTokens | None
614
+ def _attribute_sampling_mask(
615
+ trace: Trace, assistant_id: int, payload: SamplingMask | None
611
616
  ) -> None:
612
- """Attach this turn's kept-set sampling masks to the assistant node (the payload
613
- covers exactly the turn's completion tokens, so no path arithmetic). A payload
614
- that doesn't line up with the node's sampled tokens is dropped, not misaligned."""
617
+ """Attach a completion-aligned sampling mask to the assistant node."""
615
618
  if payload is None:
616
619
  return
617
- counts = np.frombuffer(binascii.a2b_base64(payload.counts), dtype=np.int32)
618
- ids = np.frombuffer(binascii.a2b_base64(payload.ids), dtype=np.int32)
619
620
  node = trace.nodes[assistant_id]
620
- if len(counts) != sum(node.mask) or int(counts.sum()) != len(ids):
621
+ if len(payload.counts) != sum(node.mask) or int(payload.counts.sum()) != len(
622
+ payload.ids
623
+ ):
621
624
  return
622
- # Own the buffers — the payload views reference the turn's response bytes.
623
- node.kept_tokens = KeptTokens(ids=ids.copy(), counts=counts.copy())
625
+ node.sampling_mask = payload
624
626
 
625
627
 
626
628
  def _commit_turn(turn: PendingTurn, response: Response) -> int:
@@ -769,9 +771,10 @@ def _commit_turn(turn: PendingTurn, response: Response) -> int:
769
771
  trace, new_node_ids, path_len, tokens.routed_experts if tokens else None
770
772
  )
771
773
 
772
- # Attribute this turn's kept-set sampling masks onto the assistant node (they are
773
- # completion-aligned, so only the sampled node carries them).
774
- _attribute_kept_tokens(trace, assistant_id, tokens.kept_tokens if tokens else None)
774
+ # Sampling masks are completion-aligned, so only the sampled node carries them.
775
+ _attribute_sampling_mask(
776
+ trace, assistant_id, tokens.sampling_mask if tokens else None
777
+ )
775
778
 
776
779
  return assistant_id
777
780
 
@@ -8,6 +8,7 @@ from verifiers.v1.configs.harness import HarnessConfig
8
8
  from verifiers.v1.harness import Harness
9
9
  from verifiers.v1.harnesses.utils.launch import (
10
10
  CHAT_PROGRAM_SOURCE,
11
+ MCP_CHAT_PROGRAM_SOURCE,
11
12
  launch_chat_program,
12
13
  )
13
14
  from verifiers.v1.runtimes import ProgramResult, Runtime
@@ -121,6 +122,7 @@ class BashHarness(Harness[BashHarnessConfig]):
121
122
  mcp_urls,
122
123
  system_prompt,
123
124
  prompt,
125
+ source_with_mcp=MCP_CHAT_PROGRAM_SOURCE,
124
126
  extra_args=args,
125
127
  env=env,
126
128
  activate=False,
@@ -3,6 +3,7 @@ from verifiers.v1.configs.harness import HarnessConfig
3
3
  from verifiers.v1.harness import Harness
4
4
  from verifiers.v1.harnesses.utils.launch import (
5
5
  CHAT_PROGRAM_SOURCE,
6
+ MCP_CHAT_PROGRAM_SOURCE,
6
7
  launch_chat_program,
7
8
  )
8
9
  from verifiers.v1.runtimes import ProgramResult, Runtime
@@ -46,4 +47,5 @@ class NullHarness(Harness[NullHarnessConfig]):
46
47
  mcp_urls,
47
48
  system_prompt,
48
49
  prompt,
50
+ source_with_mcp=MCP_CHAT_PROGRAM_SOURCE,
49
51
  )
@@ -19,10 +19,10 @@ logger = logging.getLogger(__name__)
19
19
  GITHUB_RELEASE_URL = (
20
20
  "https://github.com/PrimeIntellect-ai/prime-agent/releases/download"
21
21
  )
22
- PRIME_AGENT_COMMIT: Literal["514633727bf26d74f39f3119c2b0e31a5ceb2a9d"] = (
23
- "514633727bf26d74f39f3119c2b0e31a5ceb2a9d"
22
+ PRIME_AGENT_COMMIT: Literal["81ae3cb34d27d38ee37f9e205a1e73694993b344"] = (
23
+ "81ae3cb34d27d38ee37f9e205a1e73694993b344"
24
24
  )
25
- PRIME_AGENT_VERSION = "0.8.1"
25
+ PRIME_AGENT_VERSION = "0.9.1"
26
26
  PRIME_AGENT_DIR = "/var/tmp/vf-prime-agent"
27
27
  STATE_ROOT = "/tmp/vf-prime-agent-runs"
28
28
  SKILLS_DIR = ".agents/skills"
@@ -51,10 +51,10 @@ for tarball in "$agent_tarball" "$ai_tarball" "$core_tarball" "$tui_tarball"; do
51
51
  "$release_url/$tarball" -o "$download_dir/$tarball"
52
52
  done
53
53
  printf '%s %s\n' \
54
- '46c24db1782dd31adc35d5c6cbcc75564faba6ced3bf2ccf03d836ee77134475' "$agent_tarball" \
55
- 'f6c3bdb6093bc24a327546fe865ef9a4a172c734fcd4c4093e30c19476f0134d' "$ai_tarball" \
56
- '0cc3660953545f8ac9a7e704fcb9875f954d58c3085304080ef615c280aa5748' "$core_tarball" \
57
- 'bd07bccee0ca495565b1d62e9411f3fdebe49e3dfa52870564f08af5e61fde15' "$tui_tarball" \
54
+ '573bce0cd004fc62052e9a924089941b7f39266ab71e66a94c85a1f9d35835ba' "$agent_tarball" \
55
+ '11b5b4cf67b6bb2d3420a44fb69181bc9d94d81e69a2b4fde07eb9c99f5faf4f' "$ai_tarball" \
56
+ 'fb6f3a5dcc8b69c5eeb3beff722b5e0f09885c14849db50bc1d7c0f1d064151c' "$core_tarball" \
57
+ '4f3eaca2814944d3993073e0b88c0bde54a641ddb5132fbe107e392b997e38ec' "$tui_tarball" \
58
58
  > "$download_dir/SHA256SUMS"
59
59
  (cd "$download_dir" && sha256sum -c SHA256SUMS)
60
60
  mkdir "$download_dir/package-root"
@@ -87,7 +87,7 @@ PRIME_AGENT_BOOTSTRAP_TOOLS_ON_INSTALL=1 npm install -g \
87
87
 
88
88
 
89
89
  class PrimeAgentHarnessConfig(HarnessConfig):
90
- commit: Literal["514633727bf26d74f39f3119c2b0e31a5ceb2a9d"] = PRIME_AGENT_COMMIT
90
+ commit: Literal["81ae3cb34d27d38ee37f9e205a1e73694993b344"] = PRIME_AGENT_COMMIT
91
91
  """Prime Agent main commit to install."""
92
92
 
93
93
  autonomous: bool = False
@@ -5,7 +5,14 @@ import logging
5
5
  import shlex
6
6
  from typing import Any, Literal
7
7
 
8
- from pydantic import BaseModel, ConfigDict, Field, PositiveInt, model_validator
8
+ from pydantic import (
9
+ BaseModel,
10
+ ConfigDict,
11
+ Field,
12
+ NonNegativeInt,
13
+ PositiveInt,
14
+ model_validator,
15
+ )
9
16
  from pydantic_config import BaseConfig
10
17
 
11
18
  from verifiers.v1.acp import ACPConfig, ACPHarness, ACPTurn, JsonObject
@@ -17,7 +24,7 @@ from verifiers.v1.trace import Trace
17
24
 
18
25
  logger = logging.getLogger(__name__)
19
26
 
20
- BuiltinSkill = Literal["edit", "search"]
27
+ BuiltinSkill = Literal["bash", "edit", "fetch", "search"]
21
28
 
22
29
  RLM_REPO = "github.com/PrimeIntellect-ai/nano-rlm.git"
23
30
  RLM_CACHE_DIR = "/tmp/vf-rlm"
@@ -40,18 +47,45 @@ class CompactionConfig(BaseConfig):
40
47
  summarize_at_tokens: PositiveInt | None = None
41
48
  """Compact at this token count. When unset, compact when 16k tokens remain below the
42
49
  model context window when the provider advertises it."""
50
+ max_compactions: PositiveInt | None = None
51
+ """Compactions per session before the engine stops compacting; `None` =
52
+ nano-rlm's default."""
43
53
 
44
54
 
45
55
  class RLMHarnessConfig(HarnessConfig):
46
- version: str = Field(default="4ef3438", min_length=1)
47
- """Git ref (branch, tag, or commit) of nano-rlm to install."""
48
- max_depth: int = 0
49
- """Recursion depth RLM may spawn sub-harnesses to."""
56
+ version: str = Field(default="dd2c04f", min_length=1)
57
+ """Git ref (branch, tag, or commit) of nano-rlm to install. Must know every
58
+ field this harness puts on the wire, i.e. be at least the default ref."""
59
+ max_depth: NonNegativeInt | None = None
60
+ """Recursion depth RLM may spawn sub-agents to; `None` = nano-rlm's default (1).
61
+ Set 0 to disable recursion."""
50
62
  builtin_skills: list[BuiltinSkill] = Field(default_factory=list)
51
63
  """Built-in rlm skills to enable (RLM_SKILLS), e.g. `["edit"]`; empty enables none.
52
64
  The tool set is fixed (ipython); the base `skills` field takes SKILL.md paths."""
53
- compaction: CompactionConfig | None = None
54
- """Context compaction policy. Set an empty config to use automatic thresholds."""
65
+ compaction: CompactionConfig | bool | None = None
66
+ """Context compaction: a `[compaction]` section (or `true`) enables it with the
67
+ given settings, `false` disables it (an overflowing session then fails), and
68
+ unset defers to nano-rlm's default (on, automatic thresholds, bounded by its
69
+ default 1M tree-token budget)."""
70
+ max_concurrent_subagents: PositiveInt | None = None
71
+ """Sub-agents running at once per session tree; `None` = nano-rlm's default (4),
72
+ raised to an explicit `max_depth` when needed to keep the policy valid."""
73
+ max_total_turns: PositiveInt | None = None
74
+ """Tree-total turn budget (one turn = one work-loop model call, any engine); every
75
+ engine stops before its next call once spent. `None` = uncapped."""
76
+ max_total_tokens: PositiveInt | None = None
77
+ """Tree-total budget of NEW tokens (completion + uncached prompt) across the session
78
+ tree; once spent every engine stops and no further sub-agents spawn. `None` = unbounded."""
79
+ max_tool_output_bytes: PositiveInt | None = None
80
+ """Byte budget for a single tool result entering the conversation (middle truncation);
81
+ overrides rlm's built-in 20KB default in either direction."""
82
+ append_to_system_prompt: str | None = None
83
+ """Appended to the root engine's system prompt, after the taskset's system prompt."""
84
+ subagent_append_to_system_prompt: str | None = None
85
+ """Append for sub-agent engines that can still delegate (depth >= 1, below
86
+ `max_depth`); unset falls back to `append_to_system_prompt`."""
87
+ leaf_append_to_system_prompt: str | None = None
88
+ """Append for depth-capped leaf engines; unset falls back to the sub-agent append."""
55
89
 
56
90
  @model_validator(mode="after")
57
91
  def reject_disabled_tools(self) -> "RLMHarnessConfig":
@@ -60,6 +94,15 @@ class RLMHarnessConfig(HarnessConfig):
60
94
  "the rlm harness has a fixed tool set (ipython) and does not support "
61
95
  "`disabled_tools`; use `builtin_skills` to enable built-in skills instead."
62
96
  )
97
+ if (
98
+ self.max_depth is not None
99
+ and self.max_concurrent_subagents is not None
100
+ and self.max_concurrent_subagents < self.max_depth
101
+ ):
102
+ raise ValueError(
103
+ "`max_concurrent_subagents` must be at least `max_depth` "
104
+ "(nano-rlm rejects the policy otherwise)."
105
+ )
63
106
  return self
64
107
 
65
108
 
@@ -109,6 +152,27 @@ class RLMHarness(ACPHarness[RLMHarnessConfig]):
109
152
  system_prompt: str | None,
110
153
  ) -> JsonObject:
111
154
  compaction = self.config.compaction
155
+ max_concurrent_subagents = self.config.max_concurrent_subagents
156
+ if max_concurrent_subagents is None and self.config.max_depth is not None:
157
+ max_concurrent_subagents = max(4, self.config.max_depth)
158
+ policy_knobs: dict[str, Any] = {
159
+ "max_depth": self.config.max_depth,
160
+ "max_concurrent_subagents": max_concurrent_subagents,
161
+ "max_total_turns": self.config.max_total_turns,
162
+ "max_total_tokens": self.config.max_total_tokens,
163
+ "max_tool_output_bytes": self.config.max_tool_output_bytes,
164
+ }
165
+ if isinstance(compaction, bool):
166
+ policy_knobs["compaction"] = compaction
167
+ elif compaction is not None:
168
+ policy_knobs["compaction"] = True
169
+ policy_knobs["summarize_at_tokens"] = compaction.summarize_at_tokens
170
+ policy_knobs["max_compactions"] = compaction.max_compactions
171
+ appends = [
172
+ text
173
+ for text in (system_prompt, self.config.append_to_system_prompt)
174
+ if text
175
+ ]
112
176
  payload = {
113
177
  "session_id": trace.id,
114
178
  "model": ctx.model,
@@ -116,16 +180,17 @@ class RLMHarness(ACPHarness[RLMHarnessConfig]):
116
180
  "base_url": endpoint,
117
181
  "api_key": secret,
118
182
  },
183
+ # None = passthrough: the key stays off the wire and nano-rlm's own
184
+ # default applies.
119
185
  "policy": {
120
- "max_depth": self.config.max_depth,
121
- "compaction": compaction is not None,
122
- "summarize_at_tokens": (
123
- compaction.summarize_at_tokens if compaction else None
124
- ),
125
- "max_concurrent_subagents": max(4, self.config.max_depth),
186
+ key: value for key, value in policy_knobs.items() if value is not None
126
187
  },
127
188
  "system_prompt_path": None,
128
- "append_to_system_prompt": system_prompt,
189
+ "append_to_system_prompt": "\n\n".join(appends) or None,
190
+ "subagent_append_to_system_prompt": (
191
+ self.config.subagent_append_to_system_prompt
192
+ ),
193
+ "leaf_append_to_system_prompt": self.config.leaf_append_to_system_prompt,
129
194
  "skills": list(self.config.builtin_skills),
130
195
  "kernel_env": runtime.env,
131
196
  "search_api_key": self.config.resolved_env.get("SERPER_API_KEY"),