verifiers 0.1.15.dev396__tar.gz → 0.1.15.dev397__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 (406) hide show
  1. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/PKG-INFO +1 -1
  2. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/GUIDE.md +54 -0
  3. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/__init__.py +6 -0
  4. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/dashboard/eval.py +28 -4
  5. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/clients/config.py +21 -9
  6. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/dialects/chat.py +1 -19
  7. verifiers-0.1.15.dev397/verifiers/v1/judge.py +180 -0
  8. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/trace.py +19 -1
  9. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/types.py +29 -9
  10. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/.gitignore +0 -0
  11. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/LICENSE +0 -0
  12. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/README.md +0 -0
  13. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/pyproject.toml +0 -0
  14. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/AGENTS.md +0 -0
  15. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/README.md +0 -0
  16. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/__init__.py +0 -0
  17. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/conftest.py +0 -0
  18. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_browser_env.py +0 -0
  19. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_build_script.py +0 -0
  20. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_cli_agent_env.py +0 -0
  21. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_client_auth_errors.py +0 -0
  22. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_client_config.py +0 -0
  23. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_client_multimodal_types.py +0 -0
  24. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_composable_env.py +0 -0
  25. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_context_token_metrics.py +0 -0
  26. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_decorator_ranks.py +0 -0
  27. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_endpoint_registry.py +0 -0
  28. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_env_group.py +0 -0
  29. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_env_server.py +0 -0
  30. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_environment.py +0 -0
  31. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_environment_extra.py +0 -0
  32. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_envs.py +0 -0
  33. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_error_chain.py +0 -0
  34. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_eval_display.py +0 -0
  35. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_eval_utils.py +0 -0
  36. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_gepa_cli.py +0 -0
  37. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_gepa_utils.py +0 -0
  38. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_gym_env.py +0 -0
  39. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_harbor_env_mcp.py +0 -0
  40. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_imports.py +0 -0
  41. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_init_script.py +0 -0
  42. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_install_utils.py +0 -0
  43. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_interception_utils.py +0 -0
  44. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_lean_task.py +0 -0
  45. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_logging.py +0 -0
  46. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_math_rubric.py +0 -0
  47. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_maybe_think_parser.py +0 -0
  48. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_message_utils.py +0 -0
  49. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_message_utils_multimodal.py +0 -0
  50. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_multiturn_env.py +0 -0
  51. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_nemorl_client.py +0 -0
  52. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_openai_chat_completions_token_client.py +0 -0
  53. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_openai_responses_client.py +0 -0
  54. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_opencode_rlm_env.py +0 -0
  55. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_openenv_client.py +0 -0
  56. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_parser.py +0 -0
  57. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_path_utils.py +0 -0
  58. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_per_turn_timing.py +0 -0
  59. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_pricing_utils.py +0 -0
  60. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_prime_plugin.py +0 -0
  61. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_renderer_client.py +0 -0
  62. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_renderer_e2e.py +0 -0
  63. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_rlm_composable_env.py +0 -0
  64. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_rubric.py +0 -0
  65. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_rubric_group.py +0 -0
  66. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_sandbox_debug_env.py +0 -0
  67. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_sandbox_env.py +0 -0
  68. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_sandbox_mixin.py +0 -0
  69. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_save_utils.py +0 -0
  70. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_setup_script.py +0 -0
  71. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_singleturn_env.py +0 -0
  72. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_stateful_tool_env.py +0 -0
  73. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_think_parser.py +0 -0
  74. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_tool_env.py +0 -0
  75. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_tool_utils.py +0 -0
  76. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_trajectory_processing.py +0 -0
  77. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_tui_info_formatting.py +0 -0
  78. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_types.py +0 -0
  79. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_wordle_env.py +0 -0
  80. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/test_xml_parser.py +0 -0
  81. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/conftest.py +0 -0
  82. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/fixtures/counter_tool_v1.py +0 -0
  83. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
  84. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/fixtures/echo_multi_v0.py +0 -0
  85. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/fixtures/echo_tool_v1.py +0 -0
  86. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
  87. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/fixtures/echo_v0.py +0 -0
  88. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/fixtures/echo_v1.py +0 -0
  89. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/fixtures/pyproject.toml +0 -0
  90. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
  91. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/test_color_codeword_tasks.py +0 -0
  92. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/test_configs.py +0 -0
  93. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/test_e2e.py +0 -0
  94. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/test_envs.py +0 -0
  95. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/test_graph.py +0 -0
  96. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/test_legacy.py +0 -0
  97. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/tests/v1/test_trace.py +0 -0
  98. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/AGENTS.md +0 -0
  99. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/__init__.py +0 -0
  100. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/__init__.py +0 -0
  101. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/commands/__init__.py +0 -0
  102. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/commands/build.py +0 -0
  103. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/commands/eval.py +0 -0
  104. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/commands/gepa.py +0 -0
  105. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/commands/init.py +0 -0
  106. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/commands/install.py +0 -0
  107. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/commands/setup.py +0 -0
  108. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/plugins/__init__.py +0 -0
  109. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/plugins/prime.py +0 -0
  110. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/cli/tui.py +0 -0
  111. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/clients/__init__.py +0 -0
  112. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/clients/anthropic_messages_client.py +0 -0
  113. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/clients/client.py +0 -0
  114. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
  115. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/clients/openai_chat_completions_client.py +0 -0
  116. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
  117. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/clients/openai_completions_client.py +0 -0
  118. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/clients/openai_responses_client.py +0 -0
  119. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/clients/renderer_client.py +0 -0
  120. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/decorators.py +0 -0
  121. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/AGENTS.md +0 -0
  122. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/__init__.py +0 -0
  123. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/env_group.py +0 -0
  124. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/environment.py +0 -0
  125. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/README.md +0 -0
  126. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/__init__.py +0 -0
  127. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/cli_agent_env.py +0 -0
  128. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/README.md +0 -0
  129. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/__init__.py +0 -0
  130. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/_filter.py +0 -0
  131. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/composable_env.py +0 -0
  132. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/harness.py +0 -0
  133. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
  134. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
  135. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
  136. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
  137. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
  138. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/sandbox_debug_env.py +0 -0
  139. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
  140. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/task.py +0 -0
  141. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
  142. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
  143. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
  144. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
  145. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
  146. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/harbor/cli_gym.py +0 -0
  147. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
  148. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/harbor/terminal_lego.py +0 -0
  149. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/lean/__init__.py +0 -0
  150. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/lean/lean_task.py +0 -0
  151. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
  152. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
  153. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/README.md +0 -0
  154. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/__init__.py +0 -0
  155. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/openseeker/README.md +0 -0
  156. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/openseeker/__init__.py +0 -0
  157. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/openseeker/taskset.py +0 -0
  158. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/README.md +0 -0
  159. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/__init__.py +0 -0
  160. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/__init__.py +0 -0
  161. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/api_tools/__init__.py +0 -0
  162. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/api_tools/tool_pdf.py +0 -0
  163. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/eval_toolkit.py +0 -0
  164. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/evaluator.py +0 -0
  165. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/llm_client/__init__.py +0 -0
  166. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/llm_client/base_client.py +0 -0
  167. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/prompts/__init__.py +0 -0
  168. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/prompts/cache_prompts.py +0 -0
  169. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/__init__.py +0 -0
  170. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/cache_filesys.py +0 -0
  171. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/load_eval_script.py +0 -0
  172. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/misc.py +0 -0
  173. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/tool_visit.py +0 -0
  174. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/url_tools.py +0 -0
  175. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/verification_tree.py +0 -0
  176. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/open_ended.py +0 -0
  177. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/quest/taskset.py +0 -0
  178. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/README.md +0 -0
  179. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/__init__.py +0 -0
  180. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/taskset.py +0 -0
  181. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/search/search_tasksets.py +0 -0
  182. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
  183. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
  184. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
  185. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
  186. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
  187. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
  188. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
  189. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
  190. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
  191. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
  192. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
  193. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
  194. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
  195. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
  196. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
  197. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
  198. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
  199. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
  200. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
  201. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
  202. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
  203. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
  204. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
  205. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
  206. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/gym_env.py +0 -0
  207. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
  208. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/harbor_env/env.py +0 -0
  209. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
  210. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/mcp_env.py +0 -0
  211. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/opencode_env.py +0 -0
  212. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
  213. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
  214. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
  215. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/utils/__init__.py +0 -0
  216. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/utils/file_locks.py +0 -0
  217. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
  218. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/README.md +0 -0
  219. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/__init__.py +0 -0
  220. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/browser_env/README.md +0 -0
  221. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
  222. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
  223. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
  224. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
  225. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
  226. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
  227. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/openenv_env.py +0 -0
  228. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
  229. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/integrations/textarena_env.py +0 -0
  230. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/multiturn_env.py +0 -0
  231. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/python_env.py +0 -0
  232. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/sandbox_env.py +0 -0
  233. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/singleturn_env.py +0 -0
  234. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/stateful_tool_env.py +0 -0
  235. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/envs/tool_env.py +0 -0
  236. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/errors.py +0 -0
  237. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/gepa/__init__.py +0 -0
  238. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/gepa/adapter.py +0 -0
  239. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/gepa/config.py +0 -0
  240. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/gepa/display.py +0 -0
  241. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/gepa/gepa_utils.py +0 -0
  242. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/parsers/__init__.py +0 -0
  243. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/parsers/maybe_think_parser.py +0 -0
  244. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/parsers/parser.py +0 -0
  245. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/parsers/think_parser.py +0 -0
  246. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/parsers/xml_parser.py +0 -0
  247. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rl/README.md +0 -0
  248. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rl/__init__.py +0 -0
  249. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rl/inference/__init__.py +0 -0
  250. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rl/inference/client.py +0 -0
  251. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rl/inference/server.py +0 -0
  252. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rl/trainer/__init__.py +0 -0
  253. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rl/trainer/config.py +0 -0
  254. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rl/trainer/orchestrator.py +0 -0
  255. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rl/trainer/trainer.py +0 -0
  256. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rl/trainer/utils.py +0 -0
  257. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rubrics/__init__.py +0 -0
  258. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
  259. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rubrics/judge_rubric.py +0 -0
  260. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rubrics/math_rubric.py +0 -0
  261. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rubrics/rubric.py +0 -0
  262. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/rubrics/rubric_group.py +0 -0
  263. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/__init__.py +0 -0
  264. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/build.py +0 -0
  265. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/eval.py +0 -0
  266. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/gepa.py +0 -0
  267. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/init.py +0 -0
  268. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/install.py +0 -0
  269. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/rl.py +0 -0
  270. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/setup.py +0 -0
  271. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/train.py +0 -0
  272. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/tui.py +0 -0
  273. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/scripts/vllm.py +0 -0
  274. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/serve/__init__.py +0 -0
  275. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/serve/client/env_client.py +0 -0
  276. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/serve/client/zmq_env_client.py +0 -0
  277. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/serve/server/__init__.py +0 -0
  278. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/serve/server/env_router.py +0 -0
  279. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/serve/server/env_server.py +0 -0
  280. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/serve/server/env_worker.py +0 -0
  281. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/serve/server/zmq_env_server.py +0 -0
  282. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/serve/types.py +0 -0
  283. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/types.py +0 -0
  284. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/__init__.py +0 -0
  285. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/async_utils.py +0 -0
  286. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/client_utils.py +0 -0
  287. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/config_utils.py +0 -0
  288. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/data_utils.py +0 -0
  289. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/display_utils.py +0 -0
  290. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/env_config_utils.py +0 -0
  291. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/env_utils.py +0 -0
  292. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/error_utils.py +0 -0
  293. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/eval_display.py +0 -0
  294. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/eval_utils.py +0 -0
  295. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/heartbeat.py +0 -0
  296. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/import_utils.py +0 -0
  297. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/install_utils.py +0 -0
  298. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/interception_utils.py +0 -0
  299. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/logging_utils.py +0 -0
  300. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/message_utils.py +0 -0
  301. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/metric_utils.py +0 -0
  302. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/path_utils.py +0 -0
  303. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/pricing_utils.py +0 -0
  304. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/process_utils.py +0 -0
  305. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/response_utils.py +0 -0
  306. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/save_utils.py +0 -0
  307. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/serve_utils.py +0 -0
  308. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/thread_utils.py +0 -0
  309. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/threaded_sandbox_client.py +0 -0
  310. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/tool_utils.py +0 -0
  311. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/usage_utils.py +0 -0
  312. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/utils/version_utils.py +0 -0
  313. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/ARCHITECTURE.md +0 -0
  314. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/README.md +0 -0
  315. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/__init__.py +0 -0
  316. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/dashboard/__init__.py +0 -0
  317. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/dashboard/base.py +0 -0
  318. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/dashboard/validate.py +0 -0
  319. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/eval/__init__.py +0 -0
  320. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/eval/main.py +0 -0
  321. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/eval/resume.py +0 -0
  322. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/eval/runner.py +0 -0
  323. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/init.py +0 -0
  324. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/output.py +0 -0
  325. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/resolve.py +0 -0
  326. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/serve.py +0 -0
  327. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/cli/validate.py +0 -0
  328. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/clients/__init__.py +0 -0
  329. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/clients/client.py +0 -0
  330. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/clients/eval.py +0 -0
  331. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/clients/train.py +0 -0
  332. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/configs/__init__.py +0 -0
  333. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/configs/eval.py +0 -0
  334. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/configs/init.py +0 -0
  335. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/configs/serve.py +0 -0
  336. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/configs/validate.py +0 -0
  337. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/decorators.py +0 -0
  338. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/dialects/__init__.py +0 -0
  339. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/dialects/anthropic.py +0 -0
  340. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/dialects/base.py +0 -0
  341. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/dialects/responses.py +0 -0
  342. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/env.py +0 -0
  343. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/episode.py +0 -0
  344. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/errors.py +0 -0
  345. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/graph.py +0 -0
  346. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harness.py +0 -0
  347. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/__init__.py +0 -0
  348. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/bash/__init__.py +0 -0
  349. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/bash/harness.py +0 -0
  350. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/bash/program.py +0 -0
  351. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/bash_edit/__init__.py +0 -0
  352. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/bash_edit/harness.py +0 -0
  353. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/bash_edit/program.py +0 -0
  354. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/codex/__init__.py +0 -0
  355. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/codex/harness.py +0 -0
  356. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/default/__init__.py +0 -0
  357. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/default/harness.py +0 -0
  358. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/default/program.py +0 -0
  359. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
  360. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
  361. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
  362. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
  363. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
  364. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
  365. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/rlm/harness.py +0 -0
  366. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
  367. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
  368. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
  369. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/interception/__init__.py +0 -0
  370. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/interception/pool.py +0 -0
  371. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/interception/server.py +0 -0
  372. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/legacy.py +0 -0
  373. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/loaders.py +0 -0
  374. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/mcp/__init__.py +0 -0
  375. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/mcp/launch.py +0 -0
  376. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/mcp/multiplex.py +0 -0
  377. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/mcp/server.py +0 -0
  378. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/mcp/toolset.py +0 -0
  379. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/mcp/user.py +0 -0
  380. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/retries.py +0 -0
  381. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/rollout.py +0 -0
  382. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/runtimes/__init__.py +0 -0
  383. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/runtimes/base.py +0 -0
  384. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/runtimes/docker.py +0 -0
  385. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/runtimes/limiters.py +0 -0
  386. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/runtimes/modal.py +0 -0
  387. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/runtimes/prime.py +0 -0
  388. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/runtimes/subprocess.py +0 -0
  389. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/serve/__init__.py +0 -0
  390. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/serve/client.py +0 -0
  391. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/serve/pool.py +0 -0
  392. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/serve/server.py +0 -0
  393. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/serve/types.py +0 -0
  394. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/state.py +0 -0
  395. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/task.py +0 -0
  396. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/taskset.py +0 -0
  397. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/tasksets/__init__.py +0 -0
  398. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
  399. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
  400. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
  401. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
  402. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/utils/__init__.py +0 -0
  403. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/utils/format.py +0 -0
  404. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/utils/install.py +0 -0
  405. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/verifiers/v1/utils/logging.py +0 -0
  406. {verifiers-0.1.15.dev396 → verifiers-0.1.15.dev397}/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.dev396
3
+ Version: 0.1.15.dev397
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
@@ -254,6 +254,60 @@ async def verify(self, task, trace, runtime) -> float:
254
254
  return float(r.stdout.strip() == "1.0")
255
255
  ```
256
256
 
257
+ ### Judges
258
+
259
+ When grading can't be deterministic, `vf.Judge` is a reusable LLM judge: it owns the OpenAI client
260
+ (with the Prime key/team fallback), the call, and usage/cost capture, and leaves the two things that
261
+ differ as hooks — `build_messages` (prompt) and `parse` (verdict). Subclass it, build it once in the
262
+ taskset `__init__`, and call it from a `@reward`:
263
+
264
+ ```python
265
+ import verifiers.v1 as vf
266
+
267
+ class CorrectnessJudge(vf.Judge[bool]): # Judge[ParsedT] — ParsedT is your verdict type
268
+ prompt = "Question: {question}\nAnswer: {answer}\nResponse: {response}\nCorrect? Reply yes or no."
269
+
270
+ def parse(self, response: vf.JudgeResponse[bool]) -> bool:
271
+ return response.text.strip().lower().startswith("yes")
272
+
273
+ class MyConfig(vf.TasksetConfig):
274
+ judge: vf.JudgeConfig = vf.JudgeConfig(model="openai/gpt-5-mini")
275
+
276
+ class MyTaskset(vf.Taskset[MyTask, MyConfig]):
277
+ def __init__(self, config: MyConfig) -> None:
278
+ super().__init__(config)
279
+ self.judge = CorrectnessJudge(config.judge)
280
+
281
+ @vf.reward()
282
+ async def correct(self, task, trace) -> float:
283
+ result = await self.judge.evaluate(trace=trace, question=task.question, answer=task.answer, response=...)
284
+ return 1.0 if result.parsed else 0.0
285
+ ```
286
+
287
+ `evaluate(*, trace=None, **fields)` renders the prompt (`build_messages`), calls the model, and
288
+ parses the verdict (`parse`), returning a `JudgeResponse{text, parsed, usage}`. Passing `trace=`
289
+ **records the call onto it** — a typed record appended to `trace.info["judge"]` (for debugging) and
290
+ the call's tokens + cost added to `trace.extra_usage`, kept separate from the agent's `trace.usage`
291
+ and off the message graph (so the trainer's token math is unaffected); the eval dashboard shows the
292
+ agent's usage and `+judge` separately. The record lands even if the judge refuses, returns an empty
293
+ structured output, or `parse` raises (the request was already billed). Omit `trace` for a pure call
294
+ (e.g. in tests).
295
+
296
+ The two hooks:
297
+
298
+ | hook | default | override for |
299
+ | --- | --- | --- |
300
+ | `build_messages(**fields) -> str \| Messages` | formats the `prompt` template with the fields into one user message | a system+user / non-template prompt (return a `vf.Messages` list) |
301
+ | `parse(response) -> ParsedT` | the structured object if `schema` is set, else `response.text` | your verdict (`bool`, a grade `str`, a pydantic model, a `list[float]`, …) |
302
+
303
+ Good to know:
304
+
305
+ - **Per-task rubric** is just a field — `prompt = "{task.rubric}\n…"` with `evaluate(trace=trace, task=task, …)` (`str.format` does attribute access on a passed-in `task`). For per-task *parsing*, parse in the reward, where the task is in scope.
306
+ - **Structured outputs**: set `schema` to a pydantic model to use OpenAI structured outputs (where the provider supports it — most do); `JudgeResponse.parsed` is then the validated object. For an unsupported model, prompt for JSON and call `Model.model_validate_json(response.text)` in `parse`.
307
+ - **Multiple / dynamic calls per rollout** (e.g. one per table column): call the low-level `complete(messages, *, trace=, schema=, parse=)` directly with `vf.Messages` you build — it records each call when passed `trace`.
308
+ - **Config**: `JudgeConfig` adds `model` + `sampling` (a `JudgeSamplingConfig`) to `BaseClientConfig` (`base_url`/`api_key_var`/`headers`, Prime auto-config). CLI-overridable: `--taskset.judge.model …`, `--taskset.judge.sampling.max-tokens …`.
309
+ - **Errors propagate**: a judge API failure errors the rollout (recorded as a `TasksetError` on the trace); the OpenAI SDK already retries transient 429/5xx/connection errors.
310
+
257
311
  ## Stop conditions
258
312
 
259
313
  A rollout ends when the harness finishes, a framework budget trips (`--max-turns`, token caps), or
@@ -38,6 +38,7 @@ from verifiers.v1.errors import (
38
38
  UserError,
39
39
  )
40
40
  from verifiers.v1.harness import Harness, HarnessConfig
41
+ from verifiers.v1.judge import Judge, JudgeConfig, JudgeResponse, JudgeSamplingConfig
41
42
  from verifiers.v1.loaders import (
42
43
  default_harness_id,
43
44
  harness_config_type,
@@ -189,6 +190,11 @@ __all__ = [
189
190
  "taskset_config_type",
190
191
  "harness_config_type",
191
192
  "default_harness_id",
193
+ # judge
194
+ "Judge",
195
+ "JudgeConfig",
196
+ "JudgeSamplingConfig",
197
+ "JudgeResponse",
192
198
  # mcp
193
199
  "Toolset",
194
200
  "ToolsetConfig",
@@ -25,6 +25,7 @@ from verifiers.v1.cli.output import output_path
25
25
  from verifiers.v1.configs.eval import EvalConfig
26
26
  from verifiers.v1.rollout import Phase, Rollout
27
27
  from verifiers.v1.trace import Trace
28
+ from verifiers.v1.types import Usage
28
29
  from verifiers.v1.utils.format import format_count, format_mean, format_time
29
30
  from verifiers.utils.pricing_utils import format_cost_usd
30
31
 
@@ -199,8 +200,9 @@ def _breakdown(done: list[Trace]) -> Table | None:
199
200
  # cost are summed; each timing phase is averaged over the rollouts that have it timed (averaged
200
201
  # per phase rather than summed, since phases run concurrently across rollouts).
201
202
  total_in = total_out = total_cached = total_reasoning = 0
202
- total_cost = 0.0
203
- have_cost = have_cached = have_reasoning = False
203
+ total_judge_in = total_judge_out = 0
204
+ total_cost = total_judge_cost = 0.0
205
+ have_cost = have_cached = have_reasoning = have_judge = False
204
206
  phase_secs: dict[str, float] = {}
205
207
  phase_count: dict[str, int] = {}
206
208
  for trace in done:
@@ -216,12 +218,27 @@ def _breakdown(done: list[Trace]) -> Table | None:
216
218
  if trace.usage is not None and trace.usage.cost is not None:
217
219
  total_cost += trace.usage.cost
218
220
  have_cost = True
221
+ # Judge / auxiliary scoring calls (off the message graph) shown separately from the agent's.
222
+ judge = Usage.aggregate(trace.extra_usage)
223
+ if judge is not None:
224
+ total_judge_in += judge.input_tokens
225
+ total_judge_out += judge.completion_tokens
226
+ if judge.cost is not None:
227
+ total_judge_cost += judge.cost
228
+ have_judge = True
219
229
  for phase in ("setup", "generation", "finalize", "scoring"):
220
230
  span = getattr(trace.timing, phase)
221
231
  if span.end: # phase was timed for this rollout
222
232
  phase_secs[phase] = phase_secs.get(phase, 0.0) + span.duration
223
233
  phase_count[phase] = phase_count.get(phase, 0) + 1
224
- if total_in or total_out or have_cost or have_cached or have_reasoning:
234
+ if (
235
+ total_in
236
+ or total_out
237
+ or have_cost
238
+ or have_cached
239
+ or have_reasoning
240
+ or have_judge
241
+ ):
225
242
  tokens = f"{format_count(total_in)}/{format_count(total_out)} tokens"
226
243
  details = []
227
244
  if have_cached:
@@ -231,8 +248,15 @@ def _breakdown(done: list[Trace]) -> Table | None:
231
248
  if details:
232
249
  tokens += f" ({', '.join(details)})"
233
250
  usage = [tokens]
251
+ if have_judge:
252
+ usage.append(
253
+ f"+ {format_count(total_judge_in)}/{format_count(total_judge_out)} judge"
254
+ )
234
255
  if have_cost:
235
- usage.append(f"total {format_cost_usd(total_cost)}")
256
+ cost = format_cost_usd(total_cost)
257
+ if total_judge_cost:
258
+ cost += f" + {format_cost_usd(total_judge_cost)} judge"
259
+ usage.append(cost)
236
260
  grid.add_row("usage", " · ".join(usage))
237
261
  time_segments = [
238
262
  f"{phase} {format_time(phase_secs[phase] / phase_count[phase])}"
@@ -88,7 +88,9 @@ ClientConfig = Annotated[
88
88
  ]
89
89
 
90
90
 
91
- def resolve_client(config: BaseClientConfig) -> Client:
91
+ def resolve_api_key(config: BaseClientConfig) -> str:
92
+ """The API key for `config`: its env var, falling back to the Prime CLI config for a
93
+ `PRIME_API_KEY`-keyed pinference endpoint. `"EMPTY"` when unset."""
92
94
  api_key = os.environ.get(config.api_key_var)
93
95
  host = urlparse(config.base_url).hostname or ""
94
96
  if (
@@ -97,19 +99,29 @@ def resolve_client(config: BaseClientConfig) -> Client:
97
99
  and (host == PRIME_INFERENCE_HOST or host.endswith(f".{PRIME_INFERENCE_HOST}"))
98
100
  ):
99
101
  api_key = load_prime_config().get("api_key")
100
- api_key = api_key or "EMPTY"
102
+ return api_key or "EMPTY"
103
+
104
+
105
+ def build_async_openai(config: BaseClientConfig) -> AsyncOpenAI:
106
+ """An `AsyncOpenAI` for `config` (resolved key + extra headers) — for in-env model calls
107
+ (e.g. a judge) and the training client's engine connection."""
108
+ return AsyncOpenAI(
109
+ base_url=config.base_url,
110
+ api_key=resolve_api_key(config),
111
+ default_headers=config.headers or None,
112
+ )
113
+
114
+
115
+ def resolve_client(config: BaseClientConfig) -> Client:
101
116
  if isinstance(config, TrainClientConfig):
102
117
  # The renderer calls a vLLM `/inference/v1/generate` engine through the OpenAI SDK.
103
- openai = AsyncOpenAI(
104
- base_url=config.base_url,
105
- api_key=api_key,
106
- default_headers=config.headers or None,
107
- )
108
118
  return TrainClient(
109
- openai,
119
+ build_async_openai(config),
110
120
  pool_size=config.pool_size,
111
121
  config=config.renderer,
112
122
  renderer_model_name=config.renderer_model_name,
113
123
  )
114
124
  # The proxy is a raw httpx forwarder; the dialect supplies the auth scheme + upstream path.
115
- return EvalClient(config.base_url, api_key, headers=config.headers or None)
125
+ return EvalClient(
126
+ config.base_url, resolve_api_key(config), headers=config.headers or None
127
+ )
@@ -169,25 +169,7 @@ def response_from_wire(completion: ChatCompletion) -> Response:
169
169
  finish: FinishReason = (
170
170
  choice.finish_reason if choice.finish_reason in FINISH_REASONS else None
171
171
  )
172
- usage = None
173
- if completion.usage:
174
- cached = (
175
- completion.usage.prompt_tokens_details.cached_tokens
176
- if completion.usage.prompt_tokens_details
177
- else None
178
- )
179
- reasoning = (
180
- completion.usage.completion_tokens_details.reasoning_tokens
181
- if completion.usage.completion_tokens_details
182
- else None
183
- )
184
- usage = Usage(
185
- prompt_tokens=completion.usage.prompt_tokens - (cached or 0),
186
- completion_tokens=completion.usage.completion_tokens,
187
- cached_input_tokens=cached,
188
- reasoning_tokens=reasoning,
189
- cost=getattr(completion.usage, "cost", None),
190
- )
172
+ usage = Usage.from_openai(completion.usage)
191
173
  return Response(
192
174
  id=completion.id,
193
175
  created=completion.created,
@@ -0,0 +1,180 @@
1
+ """A reusable per-task LLM judge for v1 tasksets.
2
+
3
+ Most tasksets that can't grade deterministically reach for the same shape: an OpenAI-compatible
4
+ endpoint, a prompt built from `(question, answer, response)`, one chat call, and a verdict parsed
5
+ out of the reply. `Judge` centralizes that — the client construction (incl. the Prime key/team
6
+ fallback), the call, and usage/cost capture — and leaves the two things that actually differ as
7
+ hooks: `build_messages` (prompt setup) and `parse`
8
+ (verdict parsing). Set `schema` to use OpenAI structured outputs (where the provider supports it),
9
+ in which case `JudgeResponse.parsed` is the validated pydantic object.
10
+
11
+ class CorrectnessJudge(vf.Judge[bool]):
12
+ prompt = "Question: {question}\\nAnswer: {answer}\\nResponse: {response}\\nCorrect? yes/no"
13
+
14
+ def parse(self, response: vf.JudgeResponse[bool]) -> bool:
15
+ return response.text.strip().lower().startswith("yes")
16
+
17
+ self.judge = CorrectnessJudge(self.config.judge) # self.config.judge: vf.JudgeConfig
18
+
19
+ @vf.reward
20
+ async def correct(self, task, trace) -> float:
21
+ result = await self.judge.evaluate(
22
+ trace=trace, question=task.question, answer=task.answer, response=...
23
+ )
24
+ return float(result.parsed)
25
+
26
+ Passing `trace=` records the call onto it — a typed record appended to `trace.info["judge"]` and
27
+ the call's tokens + cost added to `trace.extra_usage` (kept separate from the agent's `trace.usage`),
28
+ so judge behaviour and spend are no longer invisible. The record lands even if the judge refuses, an
29
+ empty structured output comes back, or `parse` raises (the request was already billed). Omit `trace`
30
+ for a pure call (e.g. in tests).
31
+ """
32
+
33
+ from __future__ import annotations
34
+
35
+ from typing import TYPE_CHECKING, Any, Callable, Generic, TypeVar, cast
36
+
37
+ from openai import AsyncOpenAI
38
+ from pydantic import BaseModel
39
+
40
+ from verifiers.v1.clients.config import BaseClientConfig, build_async_openai
41
+ from verifiers.v1.dialects.chat import message_to_wire
42
+ from verifiers.v1.types import Messages, SamplingConfig, StrictBaseModel, Usage
43
+
44
+ if TYPE_CHECKING:
45
+ from verifiers.v1.trace import Trace
46
+
47
+ ParsedT = TypeVar("ParsedT")
48
+
49
+
50
+ class JudgeSamplingConfig(SamplingConfig):
51
+ """Sampling knobs for a judge call (`temperature` / `top_p` / `reasoning_effort` /
52
+ `max_tokens`, plus provider-specific keys via `extra='allow'`). Same shape as the rollout's
53
+ `SamplingConfig` — set e.g. `judge.sampling.max_tokens`."""
54
+
55
+
56
+ class JudgeConfig(BaseClientConfig):
57
+ """An LLM-judge endpoint. Inherits `base_url` / `api_key_var` / `headers` (with the Prime
58
+ auto-config) from `BaseClientConfig`; adds the model and sampling. Subclass to add
59
+ taskset-specific fields."""
60
+
61
+ model: str = "openai/gpt-5-mini"
62
+ sampling: JudgeSamplingConfig = JudgeSamplingConfig()
63
+
64
+
65
+ class JudgeResponse(StrictBaseModel, Generic[ParsedT]):
66
+ """One judge call's result — returned to the caller and (JSON-serialized) appended to
67
+ `trace.info["judge"]` for debugging, including the provider-reported `usage` (tokens + cost)."""
68
+
69
+ text: str
70
+ """The judge's raw reply."""
71
+ parsed: ParsedT | None = None
72
+ """The verdict the taskset acts on (`parse`'s output, or the structured object for `schema`)."""
73
+ usage: Usage | None = None
74
+
75
+
76
+ class Judge(Generic[ParsedT]):
77
+ """A per-task LLM judge over an OpenAI-compatible endpoint.
78
+
79
+ Override `build_messages` (prompt setup) and `parse` (verdict parsing) — or just set the
80
+ `prompt` template and use the defaults — then call `evaluate(**fields)`. Set `schema` to opt
81
+ into structured outputs.
82
+ """
83
+
84
+ prompt: str | None = None
85
+ """Default template for `build_messages`, formatted with the `evaluate` kwargs and sent as a
86
+ single user message. Override `build_messages` for system+user or non-template prompts."""
87
+ schema: type[BaseModel] | None = None
88
+ """Pydantic schema for OpenAI structured outputs. When set, the call uses
89
+ `response_format=schema` and `JudgeResponse.parsed` is the validated object (provider must
90
+ support structured outputs)."""
91
+
92
+ def __init__(self, config: JudgeConfig | None = None) -> None:
93
+ self.config = config or JudgeConfig()
94
+ self.client: AsyncOpenAI = build_async_openai(self.config)
95
+
96
+ def build_messages(self, **fields: Any) -> str | Messages:
97
+ """Prompt-setup hook: turn the `evaluate` fields into the messages to send (a single user
98
+ message as a plain `str`, or a `vf.Messages` list). The default formats the `prompt`
99
+ template with the fields; override it for a system+user / non-template prompt."""
100
+ if self.prompt is None:
101
+ raise ValueError(
102
+ f"{type(self).__name__} has no `prompt`; set it or override build_messages"
103
+ )
104
+ return self.prompt.format(**fields)
105
+
106
+ def parse(self, response: JudgeResponse[ParsedT]) -> ParsedT:
107
+ """Parsing hook: turn a `JudgeResponse` into the verdict. The default returns the
108
+ structured object when `schema` is set, otherwise the raw reply text."""
109
+ if self.schema is not None:
110
+ return cast(ParsedT, response.parsed)
111
+ return cast(ParsedT, response.text)
112
+
113
+ async def complete(
114
+ self,
115
+ messages: str | Messages,
116
+ *,
117
+ trace: "Trace | None" = None,
118
+ schema: type[BaseModel] | None = None,
119
+ parse: Callable[[JudgeResponse[Any]], Any] | None = None,
120
+ **sampling: Any,
121
+ ) -> JudgeResponse[Any]:
122
+ """Call the judge once: send `messages`, build the `JudgeResponse`, and — when a `trace` is
123
+ given — record it (`Trace.record_judge`) in a `finally`, so the call's tokens + cost are
124
+ captured even when a refusal / empty structured output / `parse` hook raises after the
125
+ billed request. `schema` opts into structured outputs; `parse` sets `JudgeResponse.parsed`."""
126
+ wire = (
127
+ [{"role": "user", "content": messages}]
128
+ if isinstance(messages, str)
129
+ else [message_to_wire(m) for m in messages]
130
+ )
131
+ kwargs: dict[str, Any] = {"model": self.config.model, "messages": wire}
132
+ kwargs.update(self.config.sampling.model_dump(exclude_none=True))
133
+ kwargs.update(sampling)
134
+
135
+ response: JudgeResponse[Any] | None = None
136
+ try:
137
+ if schema is not None:
138
+ completion = await self.client.beta.chat.completions.parse(
139
+ response_format=schema, **kwargs
140
+ )
141
+ choice = completion.choices[0]
142
+ response = JudgeResponse(
143
+ text=choice.message.content or "",
144
+ parsed=choice.message.parsed,
145
+ usage=Usage.from_openai(completion.usage),
146
+ )
147
+ if choice.message.refusal is not None:
148
+ raise RuntimeError(
149
+ f"judge refused structured output: {choice.message.refusal}"
150
+ )
151
+ if response.parsed is None:
152
+ # No refusal but no object either — e.g. a truncated/malformed reply. Surface it
153
+ # rather than returning a None verdict callers read as a (falsy) failure.
154
+ raise RuntimeError(
155
+ f"judge returned no parseable structured output "
156
+ f"(finish_reason={choice.finish_reason})"
157
+ )
158
+ else:
159
+ completion = await self.client.chat.completions.create(**kwargs)
160
+ response = JudgeResponse(
161
+ text=completion.choices[0].message.content or "",
162
+ usage=Usage.from_openai(completion.usage),
163
+ )
164
+ if parse is not None:
165
+ response.parsed = parse(response)
166
+ return response
167
+ finally:
168
+ if trace is not None and response is not None:
169
+ trace.record_judge(response)
170
+
171
+ async def evaluate(
172
+ self, *, trace: "Trace | None" = None, **fields: Any
173
+ ) -> JudgeResponse[ParsedT]:
174
+ """Render the prompt (`build_messages(**fields)`), call the judge, and parse the verdict
175
+ (`parse`). When a `trace` is given the call is recorded onto it (`trace.info["judge"]` +
176
+ usage on `trace.extra_usage`), even if a refusal / empty output / parse raises."""
177
+ messages = self.build_messages(**fields)
178
+ return await self.complete(
179
+ messages, trace=trace, schema=self.schema, parse=self.parse
180
+ )
@@ -13,12 +13,15 @@ import time
13
13
  import traceback
14
14
  import uuid
15
15
  from collections.abc import Mapping
16
- from typing import Any, Generic, TypeVar
16
+ from typing import TYPE_CHECKING, Any, Generic, TypeVar
17
17
 
18
18
  import numpy as np
19
19
  from pydantic import Field, PrivateAttr
20
20
  from renderers.base import MultiModalData
21
21
 
22
+ if TYPE_CHECKING:
23
+ from verifiers.v1.judge import JudgeResponse
24
+
22
25
  from verifiers.v1 import graph
23
26
  from verifiers.v1.errors import ProviderError
24
27
  from verifiers.v1.graph import MessageNode
@@ -258,6 +261,13 @@ class Trace(StrictBaseModel, Generic[TaskT, StateT]):
258
261
  / `to_record`), unlike `info` which persists. Type it via `Taskset[Task, Config, MyState]`; defaults
259
262
  to the base `State`."""
260
263
 
264
+ extra_usage: list[Usage] = Field(default_factory=list)
265
+ """Token usage from model calls that aren't part of the message graph — LLM judges and other
266
+ auxiliary scoring calls (see `verifiers.v1.judge`). Kept separate from `usage` (the agent's own
267
+ spend) and off the graph, so branch/turn counts and the trainer's token math (`total_tokens`,
268
+ `branches`) see only sampled nodes; consumers that want a grand total add the two (e.g. the eval
269
+ dashboard shows the agent's usage and `+judge` separately)."""
270
+
261
271
  is_completed: bool = False
262
272
  stop_condition: str | None = None
263
273
  errors: list[Error] = Field(default_factory=list)
@@ -396,6 +406,14 @@ class Trace(StrictBaseModel, Generic[TaskT, StateT]):
396
406
  for name, value in values.items():
397
407
  self.record_metric(name, value)
398
408
 
409
+ def record_judge(self, response: "JudgeResponse") -> None:
410
+ """Persist a judge call (`Judge.evaluate` / `Judge.complete` is pure): append the typed
411
+ response to `info["judge"]` for debugging and fold its tokens + cost into `extra_usage`
412
+ (→ `usage`)."""
413
+ self.info.setdefault("judge", []).append(response.model_dump())
414
+ if response.usage is not None:
415
+ self.extra_usage.append(response.usage)
416
+
399
417
  def record_reward(self, name: str, value: float, weight: float = 1.0) -> None:
400
418
  """Record a `@reward`/`@group_reward` contribution under `name` (weight
401
419
  applied; summed into `reward`). Warns on override — a per-rollout reward and
@@ -160,27 +160,47 @@ class Usage(StrictBaseModel):
160
160
  reasoning_tokens: int | None = None
161
161
  cost: float | None = None
162
162
 
163
+ @classmethod
164
+ def from_openai(cls, usage: Any | None) -> "Usage | None":
165
+ """Build from an OpenAI chat-completion `usage` object (the `.usage` on a
166
+ `ChatCompletion`), or `None` when the provider reported none. Splits cache-read tokens
167
+ out of `prompt_tokens` and carries the reasoning subset + provider-reported `cost`."""
168
+ if usage is None:
169
+ return None
170
+ prompt_details = getattr(usage, "prompt_tokens_details", None)
171
+ cached = prompt_details.cached_tokens if prompt_details else None
172
+ completion_details = getattr(usage, "completion_tokens_details", None)
173
+ reasoning = completion_details.reasoning_tokens if completion_details else None
174
+ return cls(
175
+ prompt_tokens=usage.prompt_tokens - (cached or 0),
176
+ completion_tokens=usage.completion_tokens,
177
+ cached_input_tokens=cached,
178
+ reasoning_tokens=reasoning,
179
+ cost=getattr(usage, "cost", None),
180
+ )
181
+
163
182
  @classmethod
164
183
  def aggregate(cls, usages: Iterable["Usage"]) -> "Usage | None":
165
184
  """Sum per-response usage while preserving whether cache usage was reported."""
166
185
  values = list(usages)
167
186
  if not values:
168
187
  return None
188
+ # For the optional fields (cached / reasoning / cost), sum the responses that report them
189
+ # and yield None only when *no* response does — so one response omitting a field (e.g. a
190
+ # judge whose provider doesn't report reasoning or cost) doesn't null out the whole total.
169
191
  cached = [
170
- usage.cached_input_tokens
171
- for usage in values
172
- if usage.cached_input_tokens is not None
192
+ u.cached_input_tokens for u in values if u.cached_input_tokens is not None
193
+ ]
194
+ reasoning = [
195
+ u.reasoning_tokens for u in values if u.reasoning_tokens is not None
173
196
  ]
174
- reasoning = [usage.reasoning_tokens for usage in values]
175
- costs = [usage.cost for usage in values]
197
+ costs = [u.cost for u in values if u.cost is not None]
176
198
  return cls(
177
199
  prompt_tokens=sum(usage.prompt_tokens for usage in values),
178
200
  completion_tokens=sum(usage.completion_tokens for usage in values),
179
201
  cached_input_tokens=sum(cached) if cached else None,
180
- reasoning_tokens=sum(reasoning)
181
- if all(v is not None for v in reasoning)
182
- else None,
183
- cost=sum(costs) if all(v is not None for v in costs) else None,
202
+ reasoning_tokens=sum(reasoning) if reasoning else None,
203
+ cost=sum(costs) if costs else None,
184
204
  )
185
205
 
186
206
  @property