verifiers 0.4.1.dev63__tar.gz → 0.4.1.dev65__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 (280) hide show
  1. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/PKG-INFO +2 -2
  2. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/pyproject.toml +1 -1
  3. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/counter_tool.py +3 -1
  4. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_limits.py +38 -0
  5. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_trace.py +27 -0
  6. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/agent.py +1 -0
  7. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/agent.py +10 -0
  8. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/scoring.py +6 -0
  9. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/rollout.py +16 -1
  10. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/session.py +16 -1
  11. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/trace.py +1 -0
  12. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/.gitignore +0 -0
  13. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/LICENSE +0 -0
  14. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/README.md +0 -0
  15. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/conftest.py +0 -0
  16. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/agent_user.py +0 -0
  17. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/agent_user_harness.py +0 -0
  18. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/duet.py +0 -0
  19. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/echo.py +0 -0
  20. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/echo_acp_resume.py +0 -0
  21. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/echo_agentic.py +0 -0
  22. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/echo_tool.py +0 -0
  23. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/echo_tool_compose/docker-compose.yaml +0 -0
  24. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/echo_user_sim.py +0 -0
  25. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/fetch_tool.py +0 -0
  26. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/network_policy.py +0 -0
  27. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/parallel.py +0 -0
  28. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/pyproject.toml +0 -0
  29. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/skill_codeword.py +0 -0
  30. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/skills/project-codeword/SKILL.md +0 -0
  31. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/fixtures/tool_response_image.py +0 -0
  32. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/grid.py +0 -0
  33. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_agent_user.py +0 -0
  34. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_agentic_judge.py +0 -0
  35. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_compose_scoring.py +0 -0
  36. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_examples.py +0 -0
  37. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_multi_agent.py +0 -0
  38. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_multi_turn.py +0 -0
  39. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_multi_turn_tool.py +0 -0
  40. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_multimodal_tool.py +0 -0
  41. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_network_policy.py +0 -0
  42. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_parallel.py +0 -0
  43. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_resume_tool.py +0 -0
  44. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_rubric_judge.py +0 -0
  45. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_sampling.py +0 -0
  46. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_scoring_network.py +0 -0
  47. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_shared_tool.py +0 -0
  48. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_single_turn.py +0 -0
  49. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_skills.py +0 -0
  50. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_stateful_tool.py +0 -0
  51. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_tool_vms.py +0 -0
  52. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_user_echo.py +0 -0
  53. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/integration/test_user_sim.py +0 -0
  54. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/cli/test_replay.py +0 -0
  55. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/conftest.py +0 -0
  56. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/harnesses/test_core.py +0 -0
  57. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/harnesses/test_rlm.py +0 -0
  58. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/interception/test_tunnel.py +0 -0
  59. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/judges/conftest.py +0 -0
  60. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/judges/test_judge.py +0 -0
  61. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/judges/test_reference.py +0 -0
  62. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/judges/test_rubric.py +0 -0
  63. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/runtimes/test_private_network.py +0 -0
  64. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/serve/test_client.py +0 -0
  65. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/serve/test_delta.py +0 -0
  66. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/serve/test_pool.py +0 -0
  67. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_agent.py +0 -0
  68. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_api.py +0 -0
  69. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_dialects.py +0 -0
  70. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_graph.py +0 -0
  71. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_harbor_grading_network.py +0 -0
  72. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_runtimes.py +0 -0
  73. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_scoring_network.py +0 -0
  74. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_semantic.py +0 -0
  75. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_task.py +0 -0
  76. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/test_taskset.py +0 -0
  77. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/utils/test_compile.py +0 -0
  78. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/utils/test_loaders.py +0 -0
  79. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/utils/test_platform.py +0 -0
  80. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/tests/unit/utils/test_score.py +0 -0
  81. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/__init__.py +0 -0
  82. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/__init__.py +0 -0
  83. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/acp/__init__.py +0 -0
  84. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/acp/runner.py +0 -0
  85. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/__init__.py +0 -0
  86. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/dashboard/__init__.py +0 -0
  87. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/dashboard/base.py +0 -0
  88. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/dashboard/eval.py +0 -0
  89. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/dashboard/replay.py +0 -0
  90. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/dashboard/validate.py +0 -0
  91. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/debug.py +0 -0
  92. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/eval/__init__.py +0 -0
  93. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/eval/hint.py +0 -0
  94. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/eval/main.py +0 -0
  95. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/eval/resume.py +0 -0
  96. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/eval/runner.py +0 -0
  97. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/gepa.py +0 -0
  98. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/output.py +0 -0
  99. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/replay.py +0 -0
  100. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/resolve.py +0 -0
  101. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/resume.py +0 -0
  102. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/cli/validate.py +0 -0
  103. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/clients/__init__.py +0 -0
  104. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/clients/base.py +0 -0
  105. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/clients/client.py +0 -0
  106. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/clients/eval.py +0 -0
  107. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/clients/train.py +0 -0
  108. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/__init__.py +0 -0
  109. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/cli/__init__.py +0 -0
  110. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/cli/debug.py +0 -0
  111. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/cli/env.py +0 -0
  112. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/cli/eval.py +0 -0
  113. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/cli/replay.py +0 -0
  114. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/cli/validate.py +0 -0
  115. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/client.py +0 -0
  116. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/deployment.py +0 -0
  117. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/env.py +0 -0
  118. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/harness.py +0 -0
  119. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/interception.py +0 -0
  120. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/judge.py +0 -0
  121. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/retries.py +0 -0
  122. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/runtime.py +0 -0
  123. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/select.py +0 -0
  124. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/serve.py +0 -0
  125. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/task.py +0 -0
  126. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/configs/taskset.py +0 -0
  127. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/dialects/__init__.py +0 -0
  128. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/dialects/anthropic.py +0 -0
  129. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/dialects/base.py +0 -0
  130. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/dialects/chat.py +0 -0
  131. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/dialects/responses.py +0 -0
  132. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/env.py +0 -0
  133. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/envs/__init__.py +0 -0
  134. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
  135. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/envs/agentic_judge/env.py +0 -0
  136. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
  137. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/envs/best_of_n/env.py +0 -0
  138. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/envs/single_agent/__init__.py +0 -0
  139. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/envs/single_agent/env.py +0 -0
  140. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/envs/user_sim/__init__.py +0 -0
  141. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/envs/user_sim/env.py +0 -0
  142. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/episode.py +0 -0
  143. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/errors.py +0 -0
  144. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/gepa/__init__.py +0 -0
  145. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/gepa/adapter.py +0 -0
  146. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/gepa/config.py +0 -0
  147. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/gepa/dataset.py +0 -0
  148. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/gepa/reflection.py +0 -0
  149. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/gepa/runner.py +0 -0
  150. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/grading.py +0 -0
  151. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/graph.py +0 -0
  152. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harness.py +0 -0
  153. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/__init__.py +0 -0
  154. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/bash/__init__.py +0 -0
  155. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/bash/harness.py +0 -0
  156. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/browser_use/__init__.py +0 -0
  157. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/browser_use/harness.py +0 -0
  158. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/browser_use/program.py +0 -0
  159. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
  160. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/claude_code/harness.py +0 -0
  161. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/codex/__init__.py +0 -0
  162. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/codex/gate.mjs +0 -0
  163. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/codex/harness.py +0 -0
  164. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/deepseek/__init__.py +0 -0
  165. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/deepseek/gate.mjs +0 -0
  166. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/deepseek/harness.py +0 -0
  167. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/deepseek/usage.mjs +0 -0
  168. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/hermes_agent/__init__.py +0 -0
  169. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/hermes_agent/harness.py +0 -0
  170. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/hermes_agent/program.py +0 -0
  171. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
  172. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
  173. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
  174. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
  175. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
  176. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/node.py +0 -0
  177. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/null/__init__.py +0 -0
  178. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/null/harness.py +0 -0
  179. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/openclaw/__init__.py +0 -0
  180. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/openclaw/harness.py +0 -0
  181. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/opencode/__init__.py +0 -0
  182. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/opencode/harness.py +0 -0
  183. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/opencode/mcp-ready.js +0 -0
  184. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/pi/__init__.py +0 -0
  185. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/pi/gate.mjs +0 -0
  186. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/pi/harness.py +0 -0
  187. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/prime_agent/__init__.py +0 -0
  188. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/prime_agent/harness.py +0 -0
  189. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
  190. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/rlm/harness.py +0 -0
  191. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
  192. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
  193. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
  194. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/utils/__init__.py +0 -0
  195. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/utils/compaction.py +0 -0
  196. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/utils/core.py +0 -0
  197. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/utils/install.py +0 -0
  198. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/utils/launch.py +0 -0
  199. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/utils/mcp.py +0 -0
  200. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/harnesses/utils/replay.py +0 -0
  201. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/interception/__init__.py +0 -0
  202. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/interception/base.py +0 -0
  203. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/interception/pool.py +0 -0
  204. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/interception/server.py +0 -0
  205. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/interception/tunnel/__init__.py +0 -0
  206. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/interception/tunnel/base.py +0 -0
  207. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/interception/tunnel/custom.py +0 -0
  208. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/interception/tunnel/prime.py +0 -0
  209. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/judge.py +0 -0
  210. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/judges/__init__.py +0 -0
  211. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/judges/decision.py +0 -0
  212. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/judges/reference.py +0 -0
  213. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/judges/reference.txt +0 -0
  214. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/judges/rubric.py +0 -0
  215. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/judges/rubric.txt +0 -0
  216. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/mcp/__init__.py +0 -0
  217. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/mcp/launch.py +0 -0
  218. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/mcp/server.py +0 -0
  219. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/mcp/toolset.py +0 -0
  220. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/__init__.py +0 -0
  221. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/backends/custom.py +0 -0
  222. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/backends/docker.py +0 -0
  223. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/backends/prime.py +0 -0
  224. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/backends/subprocess.py +0 -0
  225. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/base.py +0 -0
  226. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/compose.py +0 -0
  227. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/deployment.py +0 -0
  228. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/egress.py +0 -0
  229. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/limiters.py +0 -0
  230. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/private_network.py +0 -0
  231. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/runtime.py +0 -0
  232. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/runtimes/strategies.py +0 -0
  233. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/semantic.py +0 -0
  234. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/serve/__init__.py +0 -0
  235. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/serve/client.py +0 -0
  236. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/serve/delta.py +0 -0
  237. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/serve/encoding.py +0 -0
  238. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/serve/pool.py +0 -0
  239. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/serve/server.py +0 -0
  240. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/serve/types.py +0 -0
  241. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/state.py +0 -0
  242. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/task.py +0 -0
  243. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/taskset.py +0 -0
  244. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/__init__.py +0 -0
  245. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
  246. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
  247. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/harbor/toolset.py +0 -0
  248. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/nemo_gym/__init__.py +0 -0
  249. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/nemo_gym/response.py +0 -0
  250. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/nemo_gym/server.py +0 -0
  251. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/nemo_gym/taskset.py +0 -0
  252. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/nemo_gym/toolset.py +0 -0
  253. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
  254. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
  255. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
  256. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
  257. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/types.py +0 -0
  258. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/__init__.py +0 -0
  259. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/aio.py +0 -0
  260. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/artifacts.py +0 -0
  261. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/compile.py +0 -0
  262. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/decorators.py +0 -0
  263. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/env.py +0 -0
  264. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/eval.py +0 -0
  265. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/format.py +0 -0
  266. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/generic.py +0 -0
  267. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/git.py +0 -0
  268. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/image.py +0 -0
  269. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/interrupt.py +0 -0
  270. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/loaders.py +0 -0
  271. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/logging.py +0 -0
  272. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/memory.py +0 -0
  273. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/paths.py +0 -0
  274. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/platform.py +0 -0
  275. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/prime.py +0 -0
  276. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/retries.py +0 -0
  277. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/scope.py +0 -0
  278. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/score.py +0 -0
  279. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/verifiers/v1/utils/trace_store.py +0 -0
  280. {verifiers-0.4.1.dev63 → verifiers-0.4.1.dev65}/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.dev63
3
+ Version: 0.4.1.dev65
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
@@ -40,7 +40,7 @@ Requires-Dist: prime-sandboxes>=0.5.0
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
43
- Requires-Dist: renderers[multimodal]>=0.1.12
43
+ Requires-Dist: renderers[multimodal]>=0.1.13.dev16
44
44
  Requires-Dist: rich>=11.0.0
45
45
  Requires-Dist: tenacity>=8.5.0
46
46
  Requires-Dist: tomli-w>=1.0.0
@@ -49,7 +49,7 @@ dependencies = [
49
49
  "prime-pydantic-config[toml]>=0.4.3",
50
50
  "loguru>=0.7.0",
51
51
  "tomli-w>=1.0.0",
52
- "renderers[multimodal]>=0.1.12",
52
+ "renderers[multimodal]>=0.1.13.dev16",
53
53
  "typing_extensions>=4.12.2",
54
54
  "mcp==2.0.0",
55
55
  ]
@@ -21,6 +21,8 @@ class CounterToolset(vf.Toolset[vf.ToolsetConfig, CounterState]):
21
21
 
22
22
  class CounterTaskConfig(vf.TaskConfig):
23
23
  tools: vf.ToolsetConfig = vf.ToolsetConfig()
24
+ constant_reward: bool = False
25
+ """Score every rollout 1, so a skipped score (reward 0) stands out."""
24
26
 
25
27
 
26
28
  class CounterTask(vf.Task[vf.TaskData, CounterState, CounterTaskConfig]):
@@ -30,7 +32,7 @@ class CounterTask(vf.Task[vf.TaskData, CounterState, CounterTaskConfig]):
30
32
 
31
33
  @vf.reward(weight=1.0)
32
34
  async def counted(self, trace: vf.Trace) -> float:
33
- return float(trace.state.count >= 2)
35
+ return float(self.config.constant_reward or trace.state.count >= 2)
34
36
 
35
37
 
36
38
  class CounterConfig(vf.TasksetConfig):
@@ -41,6 +41,44 @@ async def test_rollout_timeout(run):
41
41
  assert trace.stop_condition == "agent_timeout"
42
42
 
43
43
 
44
+ @pytest.mark.parametrize("skip", [False, True], ids=["scored", "skipped"])
45
+ async def test_skip_scoring_on_truncated(run, skip):
46
+ (episode,) = await run(
47
+ "counter-tool",
48
+ harness="null",
49
+ runtime={"type": "prime"},
50
+ taskset_overrides={"task": {"constant_reward": True}},
51
+ env={"agent": {"max_turns": 1, "scoring": {"skip_on_truncated": skip}}},
52
+ )
53
+ (trace,) = episode.traces
54
+ assert trace.is_truncated and trace.ok
55
+ if skip:
56
+ assert trace.reward == 0 and trace.rewards == {}
57
+ assert trace.info["scoring_skipped"] == "truncated"
58
+ else:
59
+ assert trace.reward == 1
60
+ assert "scoring_skipped" not in trace.info
61
+
62
+
63
+ @pytest.mark.parametrize("skip", [False, True], ids=["scored", "skipped"])
64
+ async def test_skip_scoring_on_timeout(run, skip):
65
+ (episode,) = await run(
66
+ "counter-tool",
67
+ harness="null",
68
+ runtime={"type": "prime"},
69
+ rollout_timeout=1,
70
+ taskset_overrides={"task": {"constant_reward": True}},
71
+ env={"agent": {"scoring": {"skip_on_timeout": skip}}},
72
+ )
73
+ (trace,) = episode.traces
74
+ assert trace.is_timeout and trace.ok
75
+ if skip:
76
+ assert trace.reward == 0 and trace.rewards == {}
77
+ assert trace.info["scoring_skipped"] == "timeout"
78
+ else:
79
+ assert trace.reward == 1
80
+
81
+
44
82
  @pytest.mark.parametrize("harness,harness_runtime", grid(needs=("mcp",)), indirect=True)
45
83
  async def test_max_turns(run, harness, harness_runtime):
46
84
  (episode,) = await run(
@@ -9,6 +9,7 @@ from verifiers.v1.configs.agent import resolve_agent
9
9
  from verifiers.v1.dialects.chat import ChatDialect
10
10
  from verifiers.v1.dialects.responses import ResponsesDialect, fold_assistant
11
11
  from verifiers.v1.graph import MessageNode, prepare_turn
12
+ from verifiers.v1.session import RolloutLimits
12
13
  from verifiers.v1.types import AssistantMessage, UserMessage
13
14
  from verifiers.v1.utils.trace_store import write_episode
14
15
 
@@ -266,3 +267,29 @@ def test_sampling_mask_from_packed_matches_lists():
266
267
  ):
267
268
  np.testing.assert_array_equal(mask.ids, ids)
268
269
  np.testing.assert_array_equal(mask.counts, counts)
270
+
271
+
272
+ def test_max_turn_tokens_limit():
273
+ limits = RolloutLimits(max_turn_tokens=16)
274
+ trace = vf.Trace(
275
+ agent=vf.AgentInfo(config=vf.AgentConfig()),
276
+ task=vf.TraceTask(type="Task", data=vf.TaskData(idx=0, prompt=None)),
277
+ )
278
+ trace.calls.append(vf.ModelCall(finish_reason="stop"))
279
+ assert limits.reached(trace) is None
280
+ # A length finish below the cap ran out of context: not this limit.
281
+ usage = vf.Usage(prompt_tokens=100, completion_tokens=8)
282
+ trace.calls.append(vf.ModelCall(finish_reason="length", usage=usage))
283
+ assert limits.reached(trace) is None
284
+ usage = vf.Usage(prompt_tokens=100, completion_tokens=16)
285
+ trace.calls.append(vf.ModelCall(finish_reason="length", usage=usage))
286
+ assert limits.reached(trace) == "max_turn_tokens"
287
+ trace.stop("max_turn_tokens")
288
+ assert trace.is_truncated
289
+
290
+
291
+ @pytest.mark.parametrize("max_tokens,expected", [(None, 16), (8, 8), (64, 16)])
292
+ def test_max_turn_tokens_caps_sampling(max_tokens, expected):
293
+ spec = vf.AgentConfig(max_turn_tokens=16)
294
+ sampling = vf.SamplingConfig(max_tokens=max_tokens)
295
+ assert resolve_agent(spec, sampling=sampling).sampling.max_tokens == expected
@@ -575,6 +575,7 @@ class Agent:
575
575
  max_input_tokens=config.max_input_tokens,
576
576
  max_output_tokens=config.max_output_tokens,
577
577
  max_total_tokens=config.max_total_tokens,
578
+ max_turn_tokens=config.max_turn_tokens,
578
579
  )
579
580
  self.timeout = config.timeout
580
581
  # Env episode agents replace this with the episode's agent semaphore
@@ -66,6 +66,11 @@ class AgentConfig(BaseConfig):
66
66
  """Max output tokens per run (None = no limit)."""
67
67
  max_total_tokens: int | None = None
68
68
  """Max total tokens per run (None = no limit)."""
69
+ max_turn_tokens: int | None = Field(None, gt=0)
70
+ """Max output tokens per model response (None = no limit). Caps the sampling
71
+ `max_tokens` the framework sets on every request, whatever the harness asks for,
72
+ and stops the run once a response hits it. `sampling.max_tokens` alone caps each
73
+ response without stopping the run."""
69
74
 
70
75
  timeout: TimeoutConfig = TimeoutConfig()
71
76
  retries: RetryConfig = RetryConfig()
@@ -147,6 +152,11 @@ def resolve_agent(
147
152
  defaults = sampling or SamplingConfig()
148
153
  overrides = (spec.sampling or SamplingConfig()).model_dump(exclude_unset=True)
149
154
  merged = {**defaults.model_dump(), **merge_defaults(defaults, overrides)}
155
+ if spec.max_turn_tokens is not None:
156
+ max_tokens = merged.get("max_tokens")
157
+ merged["max_tokens"] = min(
158
+ max_tokens or spec.max_turn_tokens, spec.max_turn_tokens
159
+ )
150
160
  return spec.model_copy(
151
161
  update={
152
162
  "harness": spec.harness if spec.harness is not None else harness,
@@ -24,6 +24,12 @@ class ScoringConfig(BaseConfig):
24
24
  combined with the runtime's own rules the same way. None keeps the default: isolated
25
25
  scoring runs under `TaskData.network`, shared scoring keeps the agent phase's network,
26
26
  and Harbor's shared grading lifts the policy."""
27
+ skip_on_truncated: bool = False
28
+ """Skip task scoring for a truncated trace (`Trace.is_truncated`): it keeps no
29
+ rewards, so its reward is 0."""
30
+ skip_on_timeout: bool = False
31
+ """Skip task scoring for a trace whose stage deadline expired before scoring
32
+ (`Trace.is_timeout`): it keeps no rewards, so its reward is 0."""
27
33
 
28
34
  @field_serializer("runtime")
29
35
  def serialize_runtime(
@@ -721,6 +721,14 @@ class Rollout:
721
721
  "agent_completed",
722
722
  )
723
723
 
724
+ def _scoring_skip_reason(self) -> str | None:
725
+ """Why the resolved scoring policy skips task scoring for this trace, if it does."""
726
+ if self._scoring_policy.skip_on_truncated and self.trace.is_truncated:
727
+ return "truncated"
728
+ if self._scoring_policy.skip_on_timeout and self.trace.is_timeout:
729
+ return "timeout"
730
+ return None
731
+
724
732
  def _metrics_deadline(self) -> float:
725
733
  """Best-effort metrics get at most 30 seconds, and a tenth of a finite scoring budget."""
726
734
  budget = (
@@ -848,7 +856,14 @@ class Rollout:
848
856
  boundary(TaskError, "scoring"),
849
857
  ):
850
858
  # Cross-trace judgement runs later, after the runtime is gone.
851
- if grader is not None:
859
+ if skip_reason := self._scoring_skip_reason():
860
+ logger.info(
861
+ "rollout %s: scoring skipped (%s)",
862
+ trace.id,
863
+ skip_reason,
864
+ )
865
+ trace.info["scoring_skipped"] = skip_reason
866
+ elif grader is not None:
852
867
  try:
853
868
  await grade_task(
854
869
  grader,
@@ -87,12 +87,15 @@ class RolloutLimits:
87
87
  a @stop — and becomes the trace's stop condition. Each caps a trace computed property:
88
88
  `max_turns` -> num_turns, `max_input_tokens` -> num_input_tokens, `max_output_tokens` ->
89
89
  num_output_tokens, `max_total_tokens` -> num_total_tokens. Token caps are soft by one turn:
90
- they're checked between turns, so the turn that crosses a cap still completes."""
90
+ they're checked between turns, so the turn that crosses a cap still completes.
91
+ `max_turn_tokens` caps each response (applied through sampling) and refuses the turn
92
+ after a response that hit it."""
91
93
 
92
94
  max_turns: int | None = None
93
95
  max_input_tokens: int | None = None
94
96
  max_output_tokens: int | None = None
95
97
  max_total_tokens: int | None = None
98
+ max_turn_tokens: int | None = None
96
99
 
97
100
  def reached(self, trace: Trace) -> str | None:
98
101
  """The name of the first limit `trace` has reached, or None if within all caps."""
@@ -113,6 +116,18 @@ class RolloutLimits:
113
116
  and trace.num_total_tokens >= self.max_total_tokens
114
117
  ):
115
118
  return "max_total_tokens"
119
+ if self.max_turn_tokens is not None:
120
+ last = next((c for c in reversed(trace.calls) if c.error is None), None)
121
+ # A length finish below the cap ran out of context, not turn tokens.
122
+ if (
123
+ last is not None
124
+ and last.finish_reason == "length"
125
+ and (
126
+ last.usage is None
127
+ or last.usage.completion_tokens >= self.max_turn_tokens
128
+ )
129
+ ):
130
+ return "max_turn_tokens"
116
131
  return None
117
132
 
118
133
 
@@ -648,6 +648,7 @@ class Trace(BaseModel, Generic[DataT, StateT, AgentConfigT]):
648
648
  "max_input_tokens",
649
649
  "max_output_tokens",
650
650
  "max_total_tokens",
651
+ "max_turn_tokens",
651
652
  "compaction_failed",
652
653
  ):
653
654
  return True
File without changes