verifiers 0.1.15.dev377__tar.gz → 0.1.15.dev380__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 (402) hide show
  1. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/PKG-INFO +1 -1
  2. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/dashboard/eval.py +6 -3
  3. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/clients/eval.py +2 -1
  4. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/dialects/__init__.py +2 -1
  5. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/dialects/anthropic.py +75 -58
  6. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/dialects/base.py +56 -22
  7. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/dialects/chat.py +99 -79
  8. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/dialects/responses.py +26 -10
  9. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/interception/server.py +18 -5
  10. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/runtimes/base.py +6 -3
  11. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/.gitignore +0 -0
  12. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/LICENSE +0 -0
  13. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/README.md +0 -0
  14. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/pyproject.toml +0 -0
  15. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/AGENTS.md +0 -0
  16. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/README.md +0 -0
  17. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/__init__.py +0 -0
  18. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/conftest.py +0 -0
  19. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_browser_env.py +0 -0
  20. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_build_script.py +0 -0
  21. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_cli_agent_env.py +0 -0
  22. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_client_auth_errors.py +0 -0
  23. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_client_config.py +0 -0
  24. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_client_multimodal_types.py +0 -0
  25. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_composable_env.py +0 -0
  26. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_context_token_metrics.py +0 -0
  27. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_decorator_ranks.py +0 -0
  28. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_endpoint_registry.py +0 -0
  29. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_env_group.py +0 -0
  30. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_env_server.py +0 -0
  31. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_environment.py +0 -0
  32. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_environment_extra.py +0 -0
  33. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_envs.py +0 -0
  34. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_error_chain.py +0 -0
  35. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_eval_display.py +0 -0
  36. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_eval_utils.py +0 -0
  37. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_gepa_cli.py +0 -0
  38. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_gepa_utils.py +0 -0
  39. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_gym_env.py +0 -0
  40. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_harbor_env_mcp.py +0 -0
  41. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_imports.py +0 -0
  42. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_init_script.py +0 -0
  43. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_install_utils.py +0 -0
  44. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_interception_utils.py +0 -0
  45. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_lean_task.py +0 -0
  46. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_logging.py +0 -0
  47. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_math_rubric.py +0 -0
  48. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_maybe_think_parser.py +0 -0
  49. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_message_utils.py +0 -0
  50. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_message_utils_multimodal.py +0 -0
  51. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_multiturn_env.py +0 -0
  52. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_nemorl_client.py +0 -0
  53. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_openai_chat_completions_token_client.py +0 -0
  54. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_openai_responses_client.py +0 -0
  55. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_opencode_rlm_env.py +0 -0
  56. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_openenv_client.py +0 -0
  57. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_parser.py +0 -0
  58. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_path_utils.py +0 -0
  59. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_per_turn_timing.py +0 -0
  60. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_pricing_utils.py +0 -0
  61. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_prime_plugin.py +0 -0
  62. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_renderer_client.py +0 -0
  63. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_renderer_e2e.py +0 -0
  64. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_rlm_composable_env.py +0 -0
  65. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_rubric.py +0 -0
  66. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_rubric_group.py +0 -0
  67. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_sandbox_debug_env.py +0 -0
  68. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_sandbox_env.py +0 -0
  69. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_sandbox_mixin.py +0 -0
  70. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_save_utils.py +0 -0
  71. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_setup_script.py +0 -0
  72. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_singleturn_env.py +0 -0
  73. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_stateful_tool_env.py +0 -0
  74. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_think_parser.py +0 -0
  75. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_tool_env.py +0 -0
  76. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_tool_utils.py +0 -0
  77. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_trajectory_processing.py +0 -0
  78. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_tui_info_formatting.py +0 -0
  79. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_types.py +0 -0
  80. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_wordle_env.py +0 -0
  81. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/test_xml_parser.py +0 -0
  82. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/conftest.py +0 -0
  83. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/fixtures/counter_tool_v1.py +0 -0
  84. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
  85. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/fixtures/echo_multi_v0.py +0 -0
  86. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/fixtures/echo_tool_v1.py +0 -0
  87. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
  88. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/fixtures/echo_v0.py +0 -0
  89. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/fixtures/echo_v1.py +0 -0
  90. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/fixtures/pyproject.toml +0 -0
  91. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
  92. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/test_color_codeword_tasks.py +0 -0
  93. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/test_configs.py +0 -0
  94. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/test_e2e.py +0 -0
  95. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/test_envs.py +0 -0
  96. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/test_graph.py +0 -0
  97. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/test_legacy.py +0 -0
  98. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/tests/v1/test_trace.py +0 -0
  99. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/AGENTS.md +0 -0
  100. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/__init__.py +0 -0
  101. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/__init__.py +0 -0
  102. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/commands/__init__.py +0 -0
  103. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/commands/build.py +0 -0
  104. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/commands/eval.py +0 -0
  105. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/commands/gepa.py +0 -0
  106. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/commands/init.py +0 -0
  107. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/commands/install.py +0 -0
  108. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/commands/setup.py +0 -0
  109. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/plugins/__init__.py +0 -0
  110. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/plugins/prime.py +0 -0
  111. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/cli/tui.py +0 -0
  112. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/clients/__init__.py +0 -0
  113. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/clients/anthropic_messages_client.py +0 -0
  114. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/clients/client.py +0 -0
  115. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
  116. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/clients/openai_chat_completions_client.py +0 -0
  117. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
  118. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/clients/openai_completions_client.py +0 -0
  119. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/clients/openai_responses_client.py +0 -0
  120. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/clients/renderer_client.py +0 -0
  121. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/decorators.py +0 -0
  122. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/AGENTS.md +0 -0
  123. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/__init__.py +0 -0
  124. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/env_group.py +0 -0
  125. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/environment.py +0 -0
  126. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/README.md +0 -0
  127. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/__init__.py +0 -0
  128. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/cli_agent_env.py +0 -0
  129. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/README.md +0 -0
  130. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/__init__.py +0 -0
  131. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/_filter.py +0 -0
  132. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/composable_env.py +0 -0
  133. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/harness.py +0 -0
  134. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
  135. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
  136. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
  137. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
  138. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
  139. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/sandbox_debug_env.py +0 -0
  140. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
  141. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/task.py +0 -0
  142. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
  143. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
  144. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
  145. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
  146. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
  147. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/harbor/cli_gym.py +0 -0
  148. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
  149. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/harbor/terminal_lego.py +0 -0
  150. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/lean/__init__.py +0 -0
  151. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/lean/lean_task.py +0 -0
  152. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
  153. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
  154. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/README.md +0 -0
  155. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/__init__.py +0 -0
  156. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/openseeker/README.md +0 -0
  157. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/openseeker/__init__.py +0 -0
  158. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/openseeker/taskset.py +0 -0
  159. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/README.md +0 -0
  160. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/__init__.py +0 -0
  161. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/__init__.py +0 -0
  162. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/api_tools/__init__.py +0 -0
  163. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/api_tools/tool_pdf.py +0 -0
  164. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/eval_toolkit.py +0 -0
  165. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/evaluator.py +0 -0
  166. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/llm_client/__init__.py +0 -0
  167. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/llm_client/base_client.py +0 -0
  168. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/prompts/__init__.py +0 -0
  169. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/prompts/cache_prompts.py +0 -0
  170. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/__init__.py +0 -0
  171. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/cache_filesys.py +0 -0
  172. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/load_eval_script.py +0 -0
  173. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/misc.py +0 -0
  174. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/tool_visit.py +0 -0
  175. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/url_tools.py +0 -0
  176. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/verification_tree.py +0 -0
  177. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/open_ended.py +0 -0
  178. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/quest/taskset.py +0 -0
  179. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/README.md +0 -0
  180. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/__init__.py +0 -0
  181. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/taskset.py +0 -0
  182. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/search/search_tasksets.py +0 -0
  183. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
  184. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
  185. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
  186. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
  187. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
  188. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
  189. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
  190. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
  191. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
  192. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
  193. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
  194. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
  195. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
  196. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
  197. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
  198. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
  199. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
  200. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
  201. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
  202. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
  203. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
  204. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
  205. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
  206. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
  207. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/gym_env.py +0 -0
  208. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
  209. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/harbor_env/env.py +0 -0
  210. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
  211. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/mcp_env.py +0 -0
  212. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/opencode_env.py +0 -0
  213. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
  214. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
  215. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
  216. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/utils/__init__.py +0 -0
  217. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/utils/file_locks.py +0 -0
  218. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
  219. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/README.md +0 -0
  220. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/__init__.py +0 -0
  221. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/browser_env/README.md +0 -0
  222. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
  223. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
  224. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
  225. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
  226. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
  227. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
  228. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/openenv_env.py +0 -0
  229. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
  230. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/integrations/textarena_env.py +0 -0
  231. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/multiturn_env.py +0 -0
  232. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/python_env.py +0 -0
  233. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/sandbox_env.py +0 -0
  234. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/singleturn_env.py +0 -0
  235. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/stateful_tool_env.py +0 -0
  236. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/envs/tool_env.py +0 -0
  237. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/errors.py +0 -0
  238. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/gepa/__init__.py +0 -0
  239. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/gepa/adapter.py +0 -0
  240. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/gepa/config.py +0 -0
  241. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/gepa/display.py +0 -0
  242. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/gepa/gepa_utils.py +0 -0
  243. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/parsers/__init__.py +0 -0
  244. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/parsers/maybe_think_parser.py +0 -0
  245. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/parsers/parser.py +0 -0
  246. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/parsers/think_parser.py +0 -0
  247. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/parsers/xml_parser.py +0 -0
  248. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rl/README.md +0 -0
  249. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rl/__init__.py +0 -0
  250. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rl/inference/__init__.py +0 -0
  251. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rl/inference/client.py +0 -0
  252. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rl/inference/server.py +0 -0
  253. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rl/trainer/__init__.py +0 -0
  254. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rl/trainer/config.py +0 -0
  255. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rl/trainer/orchestrator.py +0 -0
  256. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rl/trainer/trainer.py +0 -0
  257. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rl/trainer/utils.py +0 -0
  258. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rubrics/__init__.py +0 -0
  259. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
  260. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rubrics/judge_rubric.py +0 -0
  261. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rubrics/math_rubric.py +0 -0
  262. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rubrics/rubric.py +0 -0
  263. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/rubrics/rubric_group.py +0 -0
  264. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/__init__.py +0 -0
  265. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/build.py +0 -0
  266. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/eval.py +0 -0
  267. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/gepa.py +0 -0
  268. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/init.py +0 -0
  269. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/install.py +0 -0
  270. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/rl.py +0 -0
  271. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/setup.py +0 -0
  272. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/train.py +0 -0
  273. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/tui.py +0 -0
  274. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/scripts/vllm.py +0 -0
  275. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/serve/__init__.py +0 -0
  276. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/serve/client/env_client.py +0 -0
  277. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/serve/client/zmq_env_client.py +0 -0
  278. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/serve/server/__init__.py +0 -0
  279. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/serve/server/env_router.py +0 -0
  280. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/serve/server/env_server.py +0 -0
  281. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/serve/server/env_worker.py +0 -0
  282. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/serve/server/zmq_env_server.py +0 -0
  283. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/serve/types.py +0 -0
  284. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/types.py +0 -0
  285. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/__init__.py +0 -0
  286. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/async_utils.py +0 -0
  287. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/client_utils.py +0 -0
  288. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/config_utils.py +0 -0
  289. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/data_utils.py +0 -0
  290. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/display_utils.py +0 -0
  291. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/env_config_utils.py +0 -0
  292. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/env_utils.py +0 -0
  293. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/error_utils.py +0 -0
  294. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/eval_display.py +0 -0
  295. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/eval_utils.py +0 -0
  296. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/heartbeat.py +0 -0
  297. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/import_utils.py +0 -0
  298. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/install_utils.py +0 -0
  299. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/interception_utils.py +0 -0
  300. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/logging_utils.py +0 -0
  301. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/message_utils.py +0 -0
  302. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/metric_utils.py +0 -0
  303. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/path_utils.py +0 -0
  304. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/pricing_utils.py +0 -0
  305. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/process_utils.py +0 -0
  306. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/response_utils.py +0 -0
  307. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/save_utils.py +0 -0
  308. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/serve_utils.py +0 -0
  309. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/thread_utils.py +0 -0
  310. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/threaded_sandbox_client.py +0 -0
  311. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/tool_utils.py +0 -0
  312. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/usage_utils.py +0 -0
  313. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/utils/version_utils.py +0 -0
  314. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/ARCHITECTURE.md +0 -0
  315. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/GUIDE.md +0 -0
  316. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/README.md +0 -0
  317. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/__init__.py +0 -0
  318. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/__init__.py +0 -0
  319. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/dashboard/__init__.py +0 -0
  320. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/dashboard/base.py +0 -0
  321. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/dashboard/validate.py +0 -0
  322. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/eval/__init__.py +0 -0
  323. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/eval/main.py +0 -0
  324. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/eval/resume.py +0 -0
  325. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/eval/runner.py +0 -0
  326. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/init.py +0 -0
  327. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/output.py +0 -0
  328. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/resolve.py +0 -0
  329. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/serve.py +0 -0
  330. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/cli/validate.py +0 -0
  331. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/clients/__init__.py +0 -0
  332. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/clients/client.py +0 -0
  333. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/clients/config.py +0 -0
  334. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/clients/train.py +0 -0
  335. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/configs/__init__.py +0 -0
  336. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/configs/eval.py +0 -0
  337. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/configs/init.py +0 -0
  338. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/configs/serve.py +0 -0
  339. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/configs/validate.py +0 -0
  340. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/decorators.py +0 -0
  341. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/env.py +0 -0
  342. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/episode.py +0 -0
  343. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/errors.py +0 -0
  344. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/graph.py +0 -0
  345. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harness.py +0 -0
  346. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/__init__.py +0 -0
  347. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/bash/__init__.py +0 -0
  348. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/bash/harness.py +0 -0
  349. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/bash/program.py +0 -0
  350. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/codex/__init__.py +0 -0
  351. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/codex/harness.py +0 -0
  352. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/default/__init__.py +0 -0
  353. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/default/harness.py +0 -0
  354. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/default/program.py +0 -0
  355. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
  356. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
  357. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
  358. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
  359. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
  360. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
  361. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/rlm/harness.py +0 -0
  362. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
  363. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
  364. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
  365. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/interception/__init__.py +0 -0
  366. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/interception/pool.py +0 -0
  367. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/legacy.py +0 -0
  368. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/loaders.py +0 -0
  369. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/mcp/__init__.py +0 -0
  370. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/mcp/launch.py +0 -0
  371. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/mcp/multiplex.py +0 -0
  372. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/mcp/server.py +0 -0
  373. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/mcp/toolset.py +0 -0
  374. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/mcp/user.py +0 -0
  375. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/retries.py +0 -0
  376. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/rollout.py +0 -0
  377. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/runtimes/__init__.py +0 -0
  378. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/runtimes/docker.py +0 -0
  379. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/runtimes/limiters.py +0 -0
  380. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/runtimes/modal.py +0 -0
  381. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/runtimes/prime.py +0 -0
  382. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/runtimes/subprocess.py +0 -0
  383. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/serve/__init__.py +0 -0
  384. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/serve/client.py +0 -0
  385. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/serve/pool.py +0 -0
  386. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/serve/server.py +0 -0
  387. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/serve/types.py +0 -0
  388. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/state.py +0 -0
  389. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/task.py +0 -0
  390. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/taskset.py +0 -0
  391. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/tasksets/__init__.py +0 -0
  392. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/tasksets/harbor_v1/__init__.py +0 -0
  393. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/tasksets/harbor_v1/taskset.py +0 -0
  394. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/tasksets/textarena_v1/__init__.py +0 -0
  395. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/tasksets/textarena_v1/taskset.py +0 -0
  396. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/trace.py +0 -0
  397. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/types.py +0 -0
  398. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/utils/__init__.py +0 -0
  399. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/utils/format.py +0 -0
  400. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/utils/install.py +0 -0
  401. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/utils/logging.py +0 -0
  402. {verifiers-0.1.15.dev377 → verifiers-0.1.15.dev380}/verifiers/v1/utils/memory.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verifiers
3
- Version: 0.1.15.dev377
3
+ Version: 0.1.15.dev380
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
@@ -215,8 +215,8 @@ def _groups(rollouts: list[Rollout]) -> list[list[Rollout]]:
215
215
  by_task.setdefault(rollout.trace.task.idx, []).append(rollout)
216
216
  groups = list(by_task.values())
217
217
  for group in groups:
218
- group.sort(key=lambda r: r.trace.timing.generation.start)
219
- groups.sort(key=lambda g: g[0].trace.timing.generation.start)
218
+ group.sort(key=lambda r: r.trace.timing.setup.start)
219
+ groups.sort(key=lambda g: g[0].trace.timing.setup.start)
220
220
  return groups
221
221
 
222
222
 
@@ -253,11 +253,14 @@ def Rows(groups: list[list[Rollout]], now: float, runtime_type: str) -> Table:
253
253
  )
254
254
  runtime = f"{runtime_type}({descriptor})" if descriptor else runtime_type
255
255
  turns = t.num_turns
256
- start = t.timing.generation.start
256
+ start = t.timing.setup.start
257
257
  end = (
258
258
  t.timing.scoring.end
259
259
  or t.timing.finalize.end
260
260
  or t.timing.generation.end
261
+ # a rollout that errored in setup has only setup.end — freeze there once done,
262
+ # else (still running) the timer would grow off `now` forever
263
+ or (t.timing.setup.end if t.is_completed else 0)
261
264
  or now
262
265
  )
263
266
  prompt, completion, cached, reasoning, nbranches = _tokens(t)
@@ -56,7 +56,8 @@ _BLOCKED_REQUEST_HEADERS = frozenset(
56
56
  "signature-input",
57
57
  }
58
58
  )
59
- _SSE_EVENT_END = re.compile(rb"(?:\r\n|\r|\n){2}")
59
+ # Atomic so one CRLF cannot backtrack into two line endings and split an event mid-field.
60
+ _SSE_EVENT_END = re.compile(rb"(?>\r\n|\r|\n){2}")
60
61
 
61
62
 
62
63
  class EvalClient(Client):
@@ -6,7 +6,7 @@ resolved from the endpoint the program's SDK posts to — no per-harness declara
6
6
  """
7
7
 
8
8
  from verifiers.v1.dialects.anthropic import AnthropicDialect
9
- from verifiers.v1.dialects.base import Dialect, iter_sse
9
+ from verifiers.v1.dialects.base import Dialect, StreamParser, iter_sse
10
10
  from verifiers.v1.dialects.chat import (
11
11
  FINISH_REASONS,
12
12
  ChatDialect,
@@ -27,6 +27,7 @@ __all__ = [
27
27
  "AnthropicDialect",
28
28
  "ChatDialect",
29
29
  "ResponsesDialect",
30
+ "StreamParser",
30
31
  "iter_sse",
31
32
  "parse_message",
32
33
  "parse_tools",
@@ -7,11 +7,12 @@ trace. `count_tokens` is relayed verbatim (an `aux_route`), never recorded.
7
7
  """
8
8
 
9
9
  import json
10
- from collections.abc import Mapping
10
+ from collections.abc import Callable, Mapping
11
+ from dataclasses import dataclass, field
11
12
 
12
13
  from anthropic.types import Message as AnthropicMessage
13
14
 
14
- from verifiers.v1.dialects.base import Dialect, iter_sse
15
+ from verifiers.v1.dialects.base import Dialect, StreamParser, parse_sse_event
15
16
  from verifiers.v1.types import (
16
17
  AssistantMessage,
17
18
  ContentPart,
@@ -171,6 +172,76 @@ def response_from_wire(message: AnthropicMessage) -> Response:
171
172
  )
172
173
 
173
174
 
175
+ @dataclass
176
+ class AnthropicStreamParser(StreamParser):
177
+ """Incrementally assemble Anthropic message events without retaining SSE bytes."""
178
+
179
+ validate_response: Callable[[dict], AnthropicMessage]
180
+ message: dict = field(default_factory=dict)
181
+ blocks: dict[int, dict] = field(default_factory=dict)
182
+ block_parts: dict[int, dict[str, list[str]]] = field(default_factory=dict)
183
+ partial_json: dict[int, list[str]] = field(default_factory=dict)
184
+
185
+ def feed(self, raw: bytes) -> None:
186
+ event = parse_sse_event(raw)
187
+ if event is None:
188
+ return
189
+ kind = event.get("type")
190
+ if kind == "message_start":
191
+ self.message = event.get("message") or {}
192
+ elif kind == "content_block_start":
193
+ index = event["index"]
194
+ self.blocks[index] = dict(event.get("content_block") or {})
195
+ self.block_parts.pop(index, None)
196
+ elif kind == "content_block_delta":
197
+ index = event["index"]
198
+ block = self.blocks.setdefault(index, {"type": "text", "text": ""})
199
+ delta = event.get("delta") or {}
200
+ delta_type = delta.get("type")
201
+ if delta_type in (
202
+ "text_delta",
203
+ "thinking_delta",
204
+ "signature_delta",
205
+ ):
206
+ field_name = delta_type.removesuffix("_delta")
207
+ fields = self.block_parts.get(index)
208
+ if fields is None:
209
+ fields = {}
210
+ self.block_parts[index] = fields
211
+ parts = fields.get(field_name)
212
+ if parts is None:
213
+ parts = [block.get(field_name, "")]
214
+ fields[field_name] = parts
215
+ parts.append(delta.get(field_name, ""))
216
+ elif delta_type == "input_json_delta":
217
+ parts = self.partial_json.get(index)
218
+ if parts is None:
219
+ parts = []
220
+ self.partial_json[index] = parts
221
+ parts.append(delta.get("partial_json", ""))
222
+ elif kind == "message_delta":
223
+ self.message.update(
224
+ {
225
+ key: value
226
+ for key, value in (event.get("delta") or {}).items()
227
+ if value is not None
228
+ }
229
+ )
230
+ self.message["usage"] = {
231
+ **(self.message.get("usage") or {}),
232
+ **(event.get("usage") or {}),
233
+ }
234
+
235
+ def finish(self) -> Response:
236
+ for index, fields in self.block_parts.items():
237
+ for field_name, parts in fields.items():
238
+ self.blocks[index][field_name] = "".join(parts)
239
+ for index, parts in self.partial_json.items():
240
+ self.blocks[index]["input"] = json.loads("".join(parts) or "{}")
241
+ self.message["content"] = [self.blocks[index] for index in sorted(self.blocks)]
242
+ return response_from_wire(self.validate_response(self.message))
243
+
244
+
174
245
  class AnthropicDialect(Dialect[dict, AnthropicMessage]):
175
246
  """The Anthropic Messages wire format."""
176
247
 
@@ -215,62 +286,8 @@ class AnthropicDialect(Dialect[dict, AnthropicMessage]):
215
286
  raw["usage"].pop("service_tier")
216
287
  return super().validate_response(raw)
217
288
 
218
- def parse_stream(self, raw: bytes) -> Response:
219
- """Assemble message_start / content_block_* / message_delta events into the complete
220
- message, then parse it."""
221
- message: dict = {}
222
- blocks: dict[int, dict] = {}
223
- block_parts: dict[int, dict[str, list[str]]] = {}
224
- partial_json: dict[int, list[str]] = {}
225
- for event in iter_sse(raw):
226
- kind = event.get("type")
227
- if kind == "message_start":
228
- message = event.get("message") or {}
229
- elif kind == "content_block_start":
230
- index = event["index"]
231
- blocks[index] = dict(event.get("content_block") or {})
232
- block_parts.pop(index, None)
233
- elif kind == "content_block_delta":
234
- index = event["index"]
235
- block = blocks.setdefault(index, {"type": "text", "text": ""})
236
- delta = event.get("delta") or {}
237
- delta_type = delta.get("type")
238
- if delta_type in ("text_delta", "thinking_delta", "signature_delta"):
239
- field = delta_type.removesuffix("_delta")
240
- fields = block_parts.get(index)
241
- if fields is None:
242
- fields = {}
243
- block_parts[index] = fields
244
- parts = fields.get(field)
245
- if parts is None:
246
- parts = [block.get(field, "")]
247
- fields[field] = parts
248
- parts.append(delta.get(field, ""))
249
- elif delta_type == "input_json_delta":
250
- parts = partial_json.get(index)
251
- if parts is None:
252
- parts = []
253
- partial_json[index] = parts
254
- parts.append(delta.get("partial_json", ""))
255
- elif kind == "message_delta":
256
- message.update(
257
- {
258
- k: v
259
- for k, v in (event.get("delta") or {}).items()
260
- if v is not None
261
- }
262
- )
263
- message["usage"] = {
264
- **(message.get("usage") or {}),
265
- **(event.get("usage") or {}),
266
- }
267
- for index, fields in block_parts.items():
268
- for field, parts in fields.items():
269
- blocks[index][field] = "".join(parts)
270
- for index, parts in partial_json.items():
271
- blocks[index]["input"] = json.loads("".join(parts) or "{}")
272
- message["content"] = [blocks[i] for i in sorted(blocks)]
273
- return response_from_wire(self.validate_response(message))
289
+ def stream_parser(self) -> StreamParser:
290
+ return AnthropicStreamParser(self.validate_response)
274
291
 
275
292
  def apply_overrides(self, body: dict, model: str, sampling: SamplingConfig) -> dict:
276
293
  # Forward verbatim except the eval's model + sampling. `temperature`/`top_p` are
@@ -5,17 +5,17 @@ trace from the program's native request + the provider's native response. The se
5
5
  every registered dialect's `routes` (see `dialects.DIALECTS`), so a request's format is resolved
6
6
  from the endpoint the program's SDK posts to — the harness declares nothing.
7
7
 
8
- The eval client relays a request's bytes verbatim to a matching endpoint, so the dialect only
9
- parses a *copy* for the trace (incl. assembling a relayed SSE stream via `parse_stream`); the
10
- renderer is chat-only. A dialect is therefore mostly wire -> vf
11
- (`parse_request`/`parse_response`/`parse_stream`); the exceptions are `apply_overrides` (impose
12
- the eval's model + sampling in this format's shape) and `extend` (chat-only user-sim injection).
8
+ The eval client relays a request's bytes verbatim to a matching endpoint, while a dialect-owned
9
+ `StreamParser` incrementally assembles a response copy for the trace; the renderer is chat-only.
10
+ A dialect is therefore mostly wire -> vf (`parse_request`/`parse_response`/`stream_parser`); the
11
+ exceptions are `apply_overrides` (impose the eval's model + sampling in this format's shape) and
12
+ `extend` (chat-only user-sim injection).
13
13
  """
14
14
 
15
15
  import json
16
16
  import logging
17
17
  from abc import ABC, abstractmethod
18
- from collections.abc import Iterator, Mapping
18
+ from collections.abc import Callable, Iterator, Mapping
19
19
  from typing import ClassVar, Generic, TypeVar
20
20
 
21
21
  from pydantic import BaseModel
@@ -29,6 +29,37 @@ RespT = TypeVar("RespT", bound=BaseModel)
29
29
  logger = logging.getLogger(__name__)
30
30
 
31
31
 
32
+ def is_sse_done_event(raw: bytes) -> bool:
33
+ """Whether one complete SSE event carries the DONE sentinel."""
34
+ # Ordinary OpenAI events carry JSON objects; reject their hot path before splitting lines.
35
+ if raw.startswith((b"data: {", b"data:{")):
36
+ return False
37
+ data = b"\n".join(
38
+ line.removeprefix(b"data:").strip()
39
+ for line in raw.splitlines()
40
+ if line.startswith(b"data:")
41
+ )
42
+ return data == b"[DONE]"
43
+
44
+
45
+ def parse_sse_event(raw: bytes) -> dict | None:
46
+ """Parse one complete SSE event's JSON data payload, ignoring comments and sentinels."""
47
+ data = b"\n".join(
48
+ line.removeprefix(b"data:").strip()
49
+ for line in raw.splitlines()
50
+ if line.startswith(b"data:")
51
+ )
52
+ if not data or data == b"[DONE]":
53
+ return None
54
+ try:
55
+ return from_json(data)
56
+ except ValueError:
57
+ logger.warning(
58
+ "SSE JSON fast-path failed; falling back to stdlib with invalid UTF-8 replacement"
59
+ )
60
+ return json.loads(data.decode("utf-8", errors="replace"))
61
+
62
+
32
63
  def iter_sse(raw: bytes) -> Iterator[dict]:
33
64
  """Yield JSON SSE payloads in order without retaining prior events."""
34
65
  # Detect the wire line ending once, then scan without retaining prior payloads.
@@ -44,19 +75,9 @@ def iter_sse(raw: bytes) -> Iterator[dict]:
44
75
  if end == -1:
45
76
  end = len(raw)
46
77
  block = raw[start:end]
47
- data = b"\n".join(
48
- line.removeprefix(b"data:").strip()
49
- for line in block.splitlines()
50
- if line.startswith(b"data:")
51
- )
52
- if data and data != b"[DONE]":
53
- try:
54
- yield from_json(data)
55
- except ValueError:
56
- logger.warning(
57
- "SSE JSON fast-path failed; falling back to stdlib with invalid UTF-8 replacement"
58
- )
59
- yield json.loads(data.decode("utf-8", errors="replace"))
78
+ event = parse_sse_event(block)
79
+ if event is not None:
80
+ yield event
60
81
  start = end + len(separator)
61
82
 
62
83
 
@@ -80,6 +101,20 @@ def iter_sse_reverse(raw: bytes) -> Iterator[dict]:
80
101
  yield json.loads(data)
81
102
 
82
103
 
104
+ class StreamParser(ABC):
105
+ """Incrementally assemble one native SSE stream into a vf response."""
106
+
107
+ feed: Callable[[bytes], None]
108
+ """Consume one complete SSE event without retaining its raw bytes."""
109
+
110
+ on_done: Callable[[], None] | None = None
111
+ """Preserve terminal state before events following the DONE sentinel."""
112
+
113
+ @abstractmethod
114
+ def finish(self) -> Response:
115
+ """Finalize and return the assembled response after the stream ends."""
116
+
117
+
83
118
  class Dialect(ABC, Generic[ReqT, RespT]):
84
119
  """One native API's wire format, fully typed over its request (`ReqT`) and response
85
120
  (`RespT`). The single place a protocol lives: implement a `Dialect` + register it in
@@ -133,9 +168,8 @@ class Dialect(ABC, Generic[ReqT, RespT]):
133
168
  return self.response_type.model_validate(raw)
134
169
 
135
170
  @abstractmethod
136
- def parse_stream(self, raw: bytes) -> Response:
137
- """A complete native SSE byte stream -> the vf `Response` (assembling the final message
138
- from the events), to record a relayed stream on the trace."""
171
+ def stream_parser(self) -> StreamParser:
172
+ """Create the per-request incremental parser for a native SSE response."""
139
173
 
140
174
  @abstractmethod
141
175
  def apply_overrides(self, body: ReqT, model: str, sampling: SamplingConfig) -> ReqT:
@@ -8,11 +8,12 @@ read them in the same precedence (`reasoning` / `reasoning_content` / `reasoning
8
8
 
9
9
  import time
10
10
  from collections.abc import Mapping
11
+ from dataclasses import dataclass, field as dataclass_field
11
12
  from typing import Any
12
13
 
13
14
  from openai.types.chat import ChatCompletion
14
15
 
15
- from verifiers.v1.dialects.base import Dialect, iter_sse
16
+ from verifiers.v1.dialects.base import Dialect, StreamParser, parse_sse_event
16
17
  from verifiers.v1.types import (
17
18
  AssistantMessage,
18
19
  FinishReason,
@@ -202,6 +203,101 @@ def response_from_wire(completion: ChatCompletion) -> Response:
202
203
  )
203
204
 
204
205
 
206
+ @dataclass
207
+ class ChatStreamParser(StreamParser):
208
+ """Incrementally assemble Chat Completions deltas without retaining SSE bytes."""
209
+
210
+ message: dict = dataclass_field(
211
+ default_factory=lambda: {"role": "assistant", "content": None}
212
+ )
213
+ message_parts: dict[str, list[str]] = dataclass_field(
214
+ default_factory=lambda: {key: [] for key in REASONING_FIELDS[:2] + ("content",)}
215
+ )
216
+ tool_calls: dict[int, dict] = dataclass_field(default_factory=dict)
217
+ tool_arguments: dict[int, list[str]] = dataclass_field(default_factory=dict)
218
+ reasoning_details: list[dict] = dataclass_field(default_factory=list)
219
+ reasoning_detail_parts: dict[int, list[str]] = dataclass_field(default_factory=dict)
220
+ finish_reason: str | None = None
221
+ usage: dict | None = None
222
+ head: dict | None = None
223
+
224
+ def feed(self, raw: bytes) -> None:
225
+ chunk = parse_sse_event(raw)
226
+ if chunk is None:
227
+ return
228
+ if self.head is None:
229
+ self.head = chunk
230
+ self.usage = chunk.get("usage") or self.usage
231
+ for choice in chunk.get("choices") or []:
232
+ if choice.get("index", 0) != 0:
233
+ continue
234
+ self.finish_reason = choice.get("finish_reason") or self.finish_reason
235
+ delta = choice.get("delta") or {}
236
+ for key in ("content", "reasoning_content", "reasoning"):
237
+ if delta.get(key) is not None:
238
+ self.message_parts[key].append(delta[key])
239
+ for detail in delta.get("reasoning_details") or []:
240
+ previous = self.reasoning_details[-1] if self.reasoning_details else {}
241
+ if detail.get("type") == previous.get("type") == "reasoning.text":
242
+ self.reasoning_detail_parts.setdefault(
243
+ len(self.reasoning_details) - 1,
244
+ [previous.get("text") or ""],
245
+ ).append(detail.get("text") or "")
246
+ for field_name in ("signature", "format"):
247
+ previous[field_name] = previous.get(field_name) or detail.get(
248
+ field_name
249
+ )
250
+ else:
251
+ self.reasoning_details.append(detail)
252
+ for tool_call in delta.get("tool_calls") or []:
253
+ index = tool_call.get("index", 0)
254
+ slot = self.tool_calls.setdefault(
255
+ index,
256
+ {"type": "function", "function": {"name": "", "arguments": ""}},
257
+ )
258
+ slot["id"] = tool_call.get("id") or slot.get("id", "")
259
+ function = tool_call.get("function") or {}
260
+ if function.get("name"):
261
+ slot["function"]["name"] = function["name"]
262
+ self.tool_arguments.setdefault(index, []).append(
263
+ function.get("arguments") or ""
264
+ )
265
+
266
+ def finish(self) -> Response:
267
+ for key, parts in self.message_parts.items():
268
+ if parts:
269
+ self.message[key] = "".join(parts)
270
+ for index, parts in self.reasoning_detail_parts.items():
271
+ self.reasoning_details[index]["text"] = "".join(parts)
272
+ for index, parts in self.tool_arguments.items():
273
+ self.tool_calls[index]["function"]["arguments"] = "".join(parts)
274
+ if self.tool_calls:
275
+ self.message["tool_calls"] = [
276
+ self.tool_calls[index] for index in sorted(self.tool_calls)
277
+ ]
278
+ if self.reasoning_details:
279
+ self.message["reasoning_details"] = self.reasoning_details
280
+ head = self.head or {}
281
+ return response_from_wire(
282
+ ChatCompletion.model_validate(
283
+ {
284
+ "id": head.get("id", "vf-intercept"),
285
+ "object": "chat.completion",
286
+ "created": head.get("created", int(time.time())),
287
+ "model": head.get("model", ""),
288
+ "choices": [
289
+ {
290
+ "index": 0,
291
+ "message": self.message,
292
+ "finish_reason": self.finish_reason or "stop",
293
+ }
294
+ ],
295
+ "usage": self.usage,
296
+ }
297
+ )
298
+ )
299
+
300
+
205
301
  class ChatDialect(Dialect[dict, ChatCompletion]):
206
302
  """The OpenAI chat-completions wire format."""
207
303
 
@@ -227,84 +323,8 @@ class ChatDialect(Dialect[dict, ChatCompletion]):
227
323
  def parse_response(self, response: ChatCompletion) -> Response:
228
324
  return response_from_wire(response)
229
325
 
230
- def parse_stream(self, raw: bytes) -> Response:
231
- """Assemble `chat.completion.chunk` deltas into one completion, then parse it."""
232
- message: dict = {"role": "assistant", "content": None}
233
- # Join streamed fields once; repeated concatenation recopies the growing response.
234
- message_parts = {key: [] for key in REASONING_FIELDS[:2] + ("content",)}
235
- tool_calls: dict[int, dict] = {}
236
- tool_arguments: dict[int, list[str]] = {}
237
- reasoning_details: list[dict] = []
238
- reasoning_detail_parts: dict[int, list[str]] = {}
239
- finish_reason = None
240
- usage = None
241
- head = None
242
- for chunk in iter_sse(raw):
243
- if head is None:
244
- head = chunk
245
- usage = chunk.get("usage") or usage
246
- for choice in chunk.get("choices") or []:
247
- if choice.get("index", 0) != 0:
248
- continue
249
- finish_reason = choice.get("finish_reason") or finish_reason
250
- delta = choice.get("delta") or {}
251
- for key in ("content", "reasoning_content", "reasoning"):
252
- if delta.get(key) is not None:
253
- message_parts[key].append(delta[key])
254
- for detail in delta.get("reasoning_details") or []:
255
- previous = reasoning_details[-1] if reasoning_details else {}
256
- if detail.get("type") == previous.get("type") == "reasoning.text":
257
- reasoning_detail_parts.setdefault(
258
- len(reasoning_details) - 1, [previous.get("text") or ""]
259
- ).append(detail.get("text") or "")
260
- for field in ("signature", "format"):
261
- previous[field] = previous.get(field) or detail.get(field)
262
- else:
263
- reasoning_details.append(detail)
264
- for tc in delta.get("tool_calls") or []:
265
- index = tc.get("index", 0)
266
- slot = tool_calls.setdefault(
267
- index,
268
- {"type": "function", "function": {"name": "", "arguments": ""}},
269
- )
270
- slot["id"] = tc.get("id") or slot.get("id", "")
271
- fn = tc.get("function") or {}
272
- if fn.get("name"):
273
- slot["function"]["name"] = fn["name"]
274
- tool_arguments.setdefault(index, []).append(
275
- fn.get("arguments") or ""
276
- )
277
- for key, parts in message_parts.items():
278
- if parts:
279
- message[key] = "".join(parts)
280
- for index, parts in reasoning_detail_parts.items():
281
- reasoning_details[index]["text"] = "".join(parts)
282
- for index, parts in tool_arguments.items():
283
- tool_calls[index]["function"]["arguments"] = "".join(parts)
284
- if tool_calls:
285
- message["tool_calls"] = [tool_calls[i] for i in sorted(tool_calls)]
286
- if reasoning_details:
287
- message["reasoning_details"] = reasoning_details
288
- if head is None:
289
- head = {}
290
- return response_from_wire(
291
- ChatCompletion.model_validate(
292
- {
293
- "id": head.get("id", "vf-intercept"),
294
- "object": "chat.completion",
295
- "created": head.get("created", int(time.time())),
296
- "model": head.get("model", ""),
297
- "choices": [
298
- {
299
- "index": 0,
300
- "message": message,
301
- "finish_reason": finish_reason or "stop",
302
- }
303
- ],
304
- "usage": usage,
305
- }
306
- )
307
- )
326
+ def stream_parser(self) -> StreamParser:
327
+ return ChatStreamParser()
308
328
 
309
329
  def apply_overrides(self, body: dict, model: str, sampling: SamplingConfig) -> dict:
310
330
  # Forward the program's body verbatim, overlaying only what the eval owns: the model and
@@ -8,6 +8,7 @@ endpoint and this dialect parses a copy for the trace. Server-side statefulness
8
8
  """
9
9
 
10
10
  import json
11
+ from collections import deque
11
12
  from typing import Any, cast
12
13
 
13
14
  from openai.types.responses import (
@@ -26,7 +27,7 @@ from openai.types.responses.response_usage import (
26
27
  )
27
28
  from pydantic import BaseModel, ConfigDict
28
29
 
29
- from verifiers.v1.dialects.base import Dialect, iter_sse_reverse
30
+ from verifiers.v1.dialects.base import Dialect, StreamParser, iter_sse_reverse
30
31
  from verifiers.v1.types import (
31
32
  AssistantMessage,
32
33
  ContentPart,
@@ -233,6 +234,28 @@ def response_from_wire(response: OpenAIResponse) -> Response:
233
234
  )
234
235
 
235
236
 
237
+ class ResponsesStreamParser(StreamParser):
238
+ """Retain only the complete terminal response event and trailing DONE event."""
239
+
240
+ def __init__(self) -> None:
241
+ self.events: deque[bytes] = deque(maxlen=2)
242
+ self.feed = self.events.append
243
+ self.terminal_events: tuple[bytes, ...] | None = None
244
+
245
+ def on_done(self) -> None:
246
+ # Freeze the terminal tail before later relay chunks can evict it.
247
+ self.terminal_events = tuple(self.events)
248
+
249
+ def finish(self) -> Response:
250
+ events = self.terminal_events or self.events
251
+ for event in iter_sse_reverse(b"".join(events)):
252
+ if event.get("type") in FINAL_EVENTS:
253
+ return response_from_wire(
254
+ OpenAIResponse.model_validate(event["response"])
255
+ )
256
+ raise ValueError("Responses stream ended without a terminal event")
257
+
258
+
236
259
  class ResponsesDialect(Dialect[dict, OpenAIResponse]):
237
260
  """The OpenAI Responses wire format."""
238
261
 
@@ -295,15 +318,8 @@ class ResponsesDialect(Dialect[dict, OpenAIResponse]):
295
318
  def parse_response(self, response: OpenAIResponse) -> Response:
296
319
  return response_from_wire(response)
297
320
 
298
- def parse_stream(self, raw: bytes) -> Response:
299
- """The terminal event (`response.completed` / `.incomplete` / `.failed`) carries the
300
- full response object — parse that."""
301
- for event in iter_sse_reverse(raw):
302
- if event.get("type") in FINAL_EVENTS:
303
- return response_from_wire(
304
- OpenAIResponse.model_validate(event["response"])
305
- )
306
- raise ValueError("Responses stream ended without a terminal event")
321
+ def stream_parser(self) -> StreamParser:
322
+ return ResponsesStreamParser()
307
323
 
308
324
  def apply_overrides(self, body: dict, model: str, sampling: SamplingConfig) -> dict:
309
325
  # Forward verbatim except the eval's model + sampling, mapped to the Responses shape
@@ -34,6 +34,7 @@ from pydantic_core import PydanticSerializationError, from_json, to_json
34
34
 
35
35
  from verifiers.v1.clients import RolloutContext
36
36
  from verifiers.v1.dialects import DIALECTS, Dialect
37
+ from verifiers.v1.dialects.base import is_sse_done_event
37
38
  from verifiers.v1 import graph
38
39
  from verifiers.v1.errors import (
39
40
  OverlongPromptError,
@@ -411,8 +412,8 @@ class InterceptionServer:
411
412
  prompt: Messages,
412
413
  ) -> web.StreamResponse:
413
414
  """A streamed (SSE) model turn: relay the provider's stream through to the program,
414
- accumulating the bytes to record the turn on the trace. Single-shot — a streamed turn
415
- never drives a user simulator (the only client that streams is the eval relay)."""
415
+ incrementally assembling the response to record on the trace. Single-shot — a streamed
416
+ turn never drives a user simulator (the only client that streams is the eval relay)."""
416
417
  try:
417
418
  refused = await session.refused()
418
419
  except RolloutError as e:
@@ -460,13 +461,17 @@ class InterceptionServer:
460
461
  headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}
461
462
  )
462
463
  resp.content_type = reply.content_type.split(";")[0].strip()
463
- buffer = bytearray()
464
+ # Parse complete events as they relay, avoiding a full-stream byte copy.
465
+ parser = dialect.stream_parser()
466
+ feed_event = parser.feed
467
+ on_done = parser.on_done
464
468
  # One bounded producer avoids per-event tasks; keepalive timeouts only cancel readiness waits.
465
469
  queue: asyncio.Queue[bytes | None] = asyncio.Queue(
466
470
  maxsize=_STREAM_QUEUE_MAXSIZE
467
471
  )
468
472
  ready = asyncio.Event()
469
473
  producer = asyncio.create_task(_queue_chunks(reply.chunks, queue, ready))
474
+ parser_error: Exception | None = None
470
475
  try:
471
476
  await resp.prepare(request)
472
477
  while True:
@@ -482,8 +487,14 @@ class InterceptionServer:
482
487
  if chunk is None:
483
488
  await producer
484
489
  break
485
- buffer += chunk
486
490
  await resp.write(chunk)
491
+ if parser_error is None:
492
+ try:
493
+ if on_done is not None and is_sse_done_event(chunk):
494
+ on_done()
495
+ feed_event(chunk)
496
+ except Exception as e:
497
+ parser_error = e
487
498
  except ConnectionResetError:
488
499
  return resp
489
500
  finally:
@@ -495,7 +506,9 @@ class InterceptionServer:
495
506
  await reply.close()
496
507
 
497
508
  try:
498
- turn.commit(dialect.parse_stream(bytes(buffer)))
509
+ if parser_error is not None:
510
+ raise parser_error
511
+ turn.commit(parser.finish())
499
512
  logger.debug("intercept stream turn: id=%s", session.trace.id)
500
513
  finally:
501
514
  with contextlib.suppress(ConnectionResetError):