verifiers 0.1.15.dev426__tar.gz → 0.1.15.dev428__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 (417) hide show
  1. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/PKG-INFO +1 -1
  2. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/test_judges.py +78 -13
  3. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/dashboard/eval.py +35 -10
  4. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/eval/resume.py +13 -0
  5. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/eval/runner.py +7 -1
  6. verifiers-0.1.15.dev428/verifiers/v1/judges/rubric.py +330 -0
  7. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/judges/rubric.txt +2 -2
  8. verifiers-0.1.15.dev426/verifiers/v1/judges/rubric.py +0 -165
  9. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/.gitignore +0 -0
  10. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/LICENSE +0 -0
  11. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/README.md +0 -0
  12. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/pyproject.toml +0 -0
  13. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/AGENTS.md +0 -0
  14. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/README.md +0 -0
  15. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/__init__.py +0 -0
  16. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/conftest.py +0 -0
  17. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_browser_env.py +0 -0
  18. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_build_script.py +0 -0
  19. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_cli_agent_env.py +0 -0
  20. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_client_auth_errors.py +0 -0
  21. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_client_config.py +0 -0
  22. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_client_multimodal_types.py +0 -0
  23. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_composable_env.py +0 -0
  24. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_context_token_metrics.py +0 -0
  25. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_decorator_ranks.py +0 -0
  26. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_endpoint_registry.py +0 -0
  27. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_env_group.py +0 -0
  28. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_env_server.py +0 -0
  29. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_environment.py +0 -0
  30. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_environment_extra.py +0 -0
  31. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_envs.py +0 -0
  32. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_error_chain.py +0 -0
  33. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_eval_display.py +0 -0
  34. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_eval_utils.py +0 -0
  35. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_gepa_cli.py +0 -0
  36. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_gepa_utils.py +0 -0
  37. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_gym_env.py +0 -0
  38. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_harbor_env_mcp.py +0 -0
  39. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_imports.py +0 -0
  40. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_init_script.py +0 -0
  41. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_install_utils.py +0 -0
  42. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_interception_utils.py +0 -0
  43. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_logging.py +0 -0
  44. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_math_rubric.py +0 -0
  45. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_maybe_think_parser.py +0 -0
  46. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_message_utils.py +0 -0
  47. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_message_utils_multimodal.py +0 -0
  48. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_multiturn_env.py +0 -0
  49. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_nemorl_client.py +0 -0
  50. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_openai_chat_completions_token_client.py +0 -0
  51. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_openai_responses_client.py +0 -0
  52. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_opencode_rlm_env.py +0 -0
  53. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_openenv_client.py +0 -0
  54. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_parser.py +0 -0
  55. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_path_utils.py +0 -0
  56. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_per_turn_timing.py +0 -0
  57. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_pricing_utils.py +0 -0
  58. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_prime_plugin.py +0 -0
  59. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_renderer_client.py +0 -0
  60. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_renderer_e2e.py +0 -0
  61. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_rlm_composable_env.py +0 -0
  62. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_rubric.py +0 -0
  63. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_rubric_group.py +0 -0
  64. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_sandbox_debug_env.py +0 -0
  65. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_sandbox_env.py +0 -0
  66. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_sandbox_mixin.py +0 -0
  67. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_save_utils.py +0 -0
  68. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_setup_script.py +0 -0
  69. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_singleturn_env.py +0 -0
  70. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_stateful_tool_env.py +0 -0
  71. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_think_parser.py +0 -0
  72. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_tool_env.py +0 -0
  73. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_tool_utils.py +0 -0
  74. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_trajectory_processing.py +0 -0
  75. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_tui_info_formatting.py +0 -0
  76. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_types.py +0 -0
  77. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_wordle_env.py +0 -0
  78. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/test_xml_parser.py +0 -0
  79. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/conftest.py +0 -0
  80. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/fixtures/counter_tool_v1.py +0 -0
  81. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
  82. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/fixtures/echo_multi_v0.py +0 -0
  83. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/fixtures/echo_tool_v1.py +0 -0
  84. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
  85. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/fixtures/echo_v0.py +0 -0
  86. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/fixtures/echo_v1.py +0 -0
  87. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/fixtures/pyproject.toml +0 -0
  88. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
  89. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/test_color_codeword_tasks.py +0 -0
  90. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/test_configs.py +0 -0
  91. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/test_e2e.py +0 -0
  92. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/test_envs.py +0 -0
  93. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/test_graph.py +0 -0
  94. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/test_legacy.py +0 -0
  95. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/test_scoring.py +0 -0
  96. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/tests/v1/test_trace.py +0 -0
  97. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/AGENTS.md +0 -0
  98. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/__init__.py +0 -0
  99. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/__init__.py +0 -0
  100. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/commands/__init__.py +0 -0
  101. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/commands/build.py +0 -0
  102. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/commands/eval.py +0 -0
  103. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/commands/gepa.py +0 -0
  104. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/commands/init.py +0 -0
  105. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/commands/install.py +0 -0
  106. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/commands/setup.py +0 -0
  107. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/plugins/__init__.py +0 -0
  108. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/plugins/prime.py +0 -0
  109. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/cli/tui.py +0 -0
  110. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/clients/__init__.py +0 -0
  111. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/clients/anthropic_messages_client.py +0 -0
  112. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/clients/client.py +0 -0
  113. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
  114. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/clients/openai_chat_completions_client.py +0 -0
  115. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
  116. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/clients/openai_completions_client.py +0 -0
  117. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/clients/openai_responses_client.py +0 -0
  118. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/clients/renderer_client.py +0 -0
  119. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/decorators.py +0 -0
  120. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/AGENTS.md +0 -0
  121. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/__init__.py +0 -0
  122. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/env_group.py +0 -0
  123. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/environment.py +0 -0
  124. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/README.md +0 -0
  125. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/__init__.py +0 -0
  126. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/cli_agent_env.py +0 -0
  127. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/README.md +0 -0
  128. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/__init__.py +0 -0
  129. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/_filter.py +0 -0
  130. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/composable_env.py +0 -0
  131. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/harness.py +0 -0
  132. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
  133. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
  134. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
  135. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
  136. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
  137. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/sandbox_debug_env.py +0 -0
  138. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
  139. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/task.py +0 -0
  140. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
  141. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
  142. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
  143. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
  144. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
  145. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/harbor/cli_gym.py +0 -0
  146. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
  147. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/harbor/terminal_lego.py +0 -0
  148. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
  149. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
  150. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/README.md +0 -0
  151. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/__init__.py +0 -0
  152. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/openseeker/README.md +0 -0
  153. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/openseeker/__init__.py +0 -0
  154. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/openseeker/taskset.py +0 -0
  155. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/README.md +0 -0
  156. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/__init__.py +0 -0
  157. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/__init__.py +0 -0
  158. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/api_tools/__init__.py +0 -0
  159. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/api_tools/tool_pdf.py +0 -0
  160. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/eval_toolkit.py +0 -0
  161. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/evaluator.py +0 -0
  162. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/llm_client/__init__.py +0 -0
  163. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/llm_client/base_client.py +0 -0
  164. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/prompts/__init__.py +0 -0
  165. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/prompts/cache_prompts.py +0 -0
  166. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/__init__.py +0 -0
  167. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/cache_filesys.py +0 -0
  168. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/load_eval_script.py +0 -0
  169. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/misc.py +0 -0
  170. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/tool_visit.py +0 -0
  171. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/url_tools.py +0 -0
  172. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/verification_tree.py +0 -0
  173. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/open_ended.py +0 -0
  174. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/quest/taskset.py +0 -0
  175. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/README.md +0 -0
  176. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/__init__.py +0 -0
  177. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/taskset.py +0 -0
  178. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/search/search_tasksets.py +0 -0
  179. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
  180. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
  181. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
  182. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
  183. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
  184. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
  185. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
  186. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
  187. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
  188. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
  189. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
  190. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
  191. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
  192. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
  193. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
  194. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
  195. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
  196. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
  197. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
  198. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
  199. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
  200. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
  201. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
  202. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
  203. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/gym_env.py +0 -0
  204. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
  205. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/harbor_env/env.py +0 -0
  206. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
  207. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/mcp_env.py +0 -0
  208. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/opencode_env.py +0 -0
  209. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
  210. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
  211. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
  212. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/utils/__init__.py +0 -0
  213. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/utils/file_locks.py +0 -0
  214. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
  215. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/README.md +0 -0
  216. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/__init__.py +0 -0
  217. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/browser_env/README.md +0 -0
  218. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
  219. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
  220. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
  221. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
  222. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
  223. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
  224. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/openenv_env.py +0 -0
  225. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
  226. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/integrations/textarena_env.py +0 -0
  227. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/multiturn_env.py +0 -0
  228. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/python_env.py +0 -0
  229. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/sandbox_env.py +0 -0
  230. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/singleturn_env.py +0 -0
  231. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/stateful_tool_env.py +0 -0
  232. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/envs/tool_env.py +0 -0
  233. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/errors.py +0 -0
  234. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/gepa/__init__.py +0 -0
  235. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/gepa/adapter.py +0 -0
  236. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/gepa/config.py +0 -0
  237. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/gepa/display.py +0 -0
  238. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/gepa/gepa_utils.py +0 -0
  239. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/parsers/__init__.py +0 -0
  240. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/parsers/maybe_think_parser.py +0 -0
  241. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/parsers/parser.py +0 -0
  242. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/parsers/think_parser.py +0 -0
  243. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/parsers/xml_parser.py +0 -0
  244. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rl/README.md +0 -0
  245. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rl/__init__.py +0 -0
  246. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rl/inference/__init__.py +0 -0
  247. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rl/inference/client.py +0 -0
  248. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rl/inference/server.py +0 -0
  249. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rl/trainer/__init__.py +0 -0
  250. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rl/trainer/config.py +0 -0
  251. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rl/trainer/orchestrator.py +0 -0
  252. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rl/trainer/trainer.py +0 -0
  253. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rl/trainer/utils.py +0 -0
  254. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rubrics/__init__.py +0 -0
  255. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
  256. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rubrics/judge_rubric.py +0 -0
  257. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rubrics/math_rubric.py +0 -0
  258. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rubrics/rubric.py +0 -0
  259. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/rubrics/rubric_group.py +0 -0
  260. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/__init__.py +0 -0
  261. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/build.py +0 -0
  262. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/eval.py +0 -0
  263. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/gepa.py +0 -0
  264. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/init.py +0 -0
  265. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/install.py +0 -0
  266. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/rl.py +0 -0
  267. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/setup.py +0 -0
  268. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/train.py +0 -0
  269. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/tui.py +0 -0
  270. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/scripts/vllm.py +0 -0
  271. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/serve/__init__.py +0 -0
  272. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/serve/client/env_client.py +0 -0
  273. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/serve/client/zmq_env_client.py +0 -0
  274. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/serve/server/__init__.py +0 -0
  275. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/serve/server/env_router.py +0 -0
  276. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/serve/server/env_server.py +0 -0
  277. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/serve/server/env_worker.py +0 -0
  278. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/serve/server/zmq_env_server.py +0 -0
  279. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/serve/types.py +0 -0
  280. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/types.py +0 -0
  281. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/__init__.py +0 -0
  282. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/async_utils.py +0 -0
  283. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/client_utils.py +0 -0
  284. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/config_utils.py +0 -0
  285. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/data_utils.py +0 -0
  286. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/display_utils.py +0 -0
  287. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/env_config_utils.py +0 -0
  288. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/env_utils.py +0 -0
  289. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/error_utils.py +0 -0
  290. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/eval_display.py +0 -0
  291. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/eval_utils.py +0 -0
  292. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/heartbeat.py +0 -0
  293. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/import_utils.py +0 -0
  294. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/install_utils.py +0 -0
  295. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/interception_utils.py +0 -0
  296. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/logging_utils.py +0 -0
  297. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/message_utils.py +0 -0
  298. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/metric_utils.py +0 -0
  299. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/path_utils.py +0 -0
  300. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/pricing_utils.py +0 -0
  301. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/process_utils.py +0 -0
  302. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/response_utils.py +0 -0
  303. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/save_utils.py +0 -0
  304. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/serve_utils.py +0 -0
  305. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/thread_utils.py +0 -0
  306. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/threaded_sandbox_client.py +0 -0
  307. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/tool_utils.py +0 -0
  308. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/usage_utils.py +0 -0
  309. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/utils/version_utils.py +0 -0
  310. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/ARCHITECTURE.md +0 -0
  311. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/GUIDE.md +0 -0
  312. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/README.md +0 -0
  313. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/__init__.py +0 -0
  314. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/__init__.py +0 -0
  315. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/dashboard/__init__.py +0 -0
  316. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/dashboard/base.py +0 -0
  317. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/dashboard/replay.py +0 -0
  318. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/dashboard/validate.py +0 -0
  319. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/debug.py +0 -0
  320. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/eval/__init__.py +0 -0
  321. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/eval/main.py +0 -0
  322. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/init.py +0 -0
  323. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/output.py +0 -0
  324. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/replay.py +0 -0
  325. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/resolve.py +0 -0
  326. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/serve.py +0 -0
  327. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/cli/validate.py +0 -0
  328. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/clients/__init__.py +0 -0
  329. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/clients/client.py +0 -0
  330. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/clients/config.py +0 -0
  331. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/clients/eval.py +0 -0
  332. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/clients/train.py +0 -0
  333. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/configs/__init__.py +0 -0
  334. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/configs/debug.py +0 -0
  335. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/configs/eval.py +0 -0
  336. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/configs/init.py +0 -0
  337. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/configs/replay.py +0 -0
  338. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/configs/serve.py +0 -0
  339. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/configs/validate.py +0 -0
  340. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/decorators.py +0 -0
  341. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/dialects/__init__.py +0 -0
  342. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/dialects/anthropic.py +0 -0
  343. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/dialects/base.py +0 -0
  344. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/dialects/chat.py +0 -0
  345. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/dialects/responses.py +0 -0
  346. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/env.py +0 -0
  347. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/episode.py +0 -0
  348. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/errors.py +0 -0
  349. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/graph.py +0 -0
  350. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harness.py +0 -0
  351. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/__init__.py +0 -0
  352. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/codex/__init__.py +0 -0
  353. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/codex/harness.py +0 -0
  354. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/default/__init__.py +0 -0
  355. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/default/harness.py +0 -0
  356. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/default/program.py +0 -0
  357. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
  358. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
  359. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
  360. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
  361. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
  362. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/null/__init__.py +0 -0
  363. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/null/harness.py +0 -0
  364. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/null/program.py +0 -0
  365. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
  366. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/rlm/harness.py +0 -0
  367. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
  368. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
  369. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
  370. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/interception/__init__.py +0 -0
  371. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/interception/pool.py +0 -0
  372. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/interception/server.py +0 -0
  373. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/judge.py +0 -0
  374. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/judges/__init__.py +0 -0
  375. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/judges/reference.py +0 -0
  376. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/judges/reference.txt +0 -0
  377. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/legacy.py +0 -0
  378. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/loaders.py +0 -0
  379. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/mcp/__init__.py +0 -0
  380. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/mcp/launch.py +0 -0
  381. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/mcp/server.py +0 -0
  382. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/mcp/toolset.py +0 -0
  383. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/mcp/user.py +0 -0
  384. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/retries.py +0 -0
  385. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/rollout.py +0 -0
  386. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/runtimes/__init__.py +0 -0
  387. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/runtimes/base.py +0 -0
  388. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/runtimes/docker.py +0 -0
  389. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/runtimes/limiters.py +0 -0
  390. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/runtimes/modal.py +0 -0
  391. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/runtimes/prime.py +0 -0
  392. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/runtimes/subprocess.py +0 -0
  393. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/scoring.py +0 -0
  394. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/serve/__init__.py +0 -0
  395. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/serve/client.py +0 -0
  396. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/serve/pool.py +0 -0
  397. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/serve/server.py +0 -0
  398. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/serve/types.py +0 -0
  399. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/state.py +0 -0
  400. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/task.py +0 -0
  401. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/taskset.py +0 -0
  402. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/tasksets/__init__.py +0 -0
  403. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
  404. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
  405. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/tasksets/lean/__init__.py +0 -0
  406. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/tasksets/lean/scoring.py +0 -0
  407. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/tasksets/lean/taskset.py +0 -0
  408. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
  409. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
  410. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/trace.py +0 -0
  411. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/types.py +0 -0
  412. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/utils/__init__.py +0 -0
  413. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/utils/aio.py +0 -0
  414. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/utils/format.py +0 -0
  415. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/utils/install.py +0 -0
  416. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/verifiers/v1/utils/logging.py +0 -0
  417. {verifiers-0.1.15.dev426 → verifiers-0.1.15.dev428}/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.dev426
3
+ Version: 0.1.15.dev428
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
@@ -29,9 +29,9 @@ class QATask(vf.Task):
29
29
  answer: str = ""
30
30
 
31
31
 
32
- def make_trace(reply: str = "It is Paris.") -> vf.Trace:
32
+ def make_trace(reply: str = "It is Paris.", answer: str = "Paris") -> vf.Trace:
33
33
  return vf.Trace(
34
- task=QATask(idx=0, prompt="Capital of France?", answer="Paris"),
34
+ task=QATask(idx=0, prompt="Capital of France?", answer=answer),
35
35
  nodes=[
36
36
  MessageNode(
37
37
  parent=None,
@@ -47,23 +47,31 @@ def make_trace(reply: str = "It is Paris.") -> vf.Trace:
47
47
 
48
48
  @pytest.fixture
49
49
  def fake_judge_model(monkeypatch):
50
- """Fake the judge's model call, recording each prompt for assertions. Text calls reply
51
- "yes" iff "Paris" appears in the response block of the rendered prompt; structured
52
- (`schema`) calls verdict each `- name: text` criteria line "yes" iff it mentions Paris."""
50
+ """Fake the judge's model call, recording each prompt for assertions. Rubric calls (a JSON
51
+ `verdicts` instruction or a `schema`) reply one reasoned verdict per `- name: text` criterion,
52
+ "yes" iff it mentions Paris; other judges reply plain "yes"/"no" by the response block."""
53
53
  prompts: list[str] = []
54
54
 
55
55
  async def fake_complete(
56
56
  self, messages, *, trace=None, schema=None, parse=None, **sampling
57
57
  ):
58
58
  prompts.append(messages)
59
- if schema is not None:
59
+ # Rubric calls carry criteria lines + a JSON `verdicts` instruction; reply one verdict per
60
+ # criterion (yes iff its text mentions Paris) with a reason. Other judges get plain yes/no.
61
+ if schema is not None or '"verdicts"' in messages:
60
62
  verdicts = [
61
- {"name": name, "verdict": "yes" if "Paris" in text else "no"}
63
+ {
64
+ "name": name,
65
+ "reason": "cites Paris" if "Paris" in text else "no Paris",
66
+ "verdict": "yes" if "Paris" in text else "no",
67
+ }
62
68
  for name, text in re.findall(r"^- ([^:]+): (.+)$", messages, re.M)
63
69
  ]
64
70
  response = JudgeResponse(
65
- text=json.dumps(verdicts),
66
- parsed=schema.model_validate({"verdicts": verdicts}),
71
+ text=json.dumps({"verdicts": verdicts}),
72
+ parsed=schema.model_validate({"verdicts": verdicts})
73
+ if schema
74
+ else None,
67
75
  )
68
76
  else:
69
77
  response = JudgeResponse(
@@ -501,7 +509,7 @@ def test_rubric_rejects_bad_files(tmp_path):
501
509
 
502
510
  async def test_rubric_score(tmp_path, fake_judge_model):
503
511
  # verdicts: mentions_paris=1 (w=3), is_polite=0 (w=1) -> weighted mean 0.75, from ONE
504
- # structured judge call; each verdict lands as a `<name>/<criterion>` metric.
512
+ # judge call; each verdict lands as a `<name>/<criterion>` metric.
505
513
  judge = rubric_judge(tmp_path)
506
514
  trace = make_trace()
507
515
  assert await judge.score(trace.task, trace) == 0.75
@@ -513,16 +521,73 @@ async def test_rubric_verdict_mismatch_raises(tmp_path, monkeypatch):
513
521
  # A reply that doesn't verdict exactly the rubric's criteria is a judge failure: raise
514
522
  # (-> rollout error), don't guess or silently score 0.
515
523
  async def wrong_names(self, messages, *, trace=None, schema=None, parse=None, **s):
516
- verdicts = {"verdicts": [{"name": "typo", "verdict": "yes"}]}
517
- return JudgeResponse(text="", parsed=schema.model_validate(verdicts))
524
+ verdicts = {"verdicts": [{"name": "typo", "reason": "x", "verdict": "yes"}]}
525
+ return JudgeResponse(text=json.dumps(verdicts), parsed=None)
518
526
 
519
527
  monkeypatch.setattr(Judge, "complete", wrong_names)
520
528
  judge = rubric_judge(tmp_path)
521
529
  trace = make_trace()
522
- with pytest.raises(ValueError, match="expected the rubric"):
530
+ with pytest.raises(ValueError, match="expected the batch"):
523
531
  await judge.score(trace.task, trace)
524
532
 
525
533
 
534
+ CHOICES_TOML = (
535
+ '[[criteria]]\nname = "depth"\ntext = "How thorough?"\n'
536
+ 'choices = ["none", "partial", "good"]\n'
537
+ )
538
+
539
+
540
+ async def test_rubric_choices_normalize(tmp_path, monkeypatch):
541
+ # Ordered choices (worst→best) score by rank: "partial" of ["none","partial","good"] -> 0.5.
542
+ async def graded(self, messages, *, trace=None, schema=None, parse=None, **s):
543
+ v = {"verdicts": [{"name": "depth", "reason": "r", "verdict": "partial"}]}
544
+ return JudgeResponse(text=json.dumps(v), parsed=None)
545
+
546
+ monkeypatch.setattr(Judge, "complete", graded)
547
+ judge = rubric_judge(tmp_path, body=CHOICES_TOML, name="q")
548
+ trace = make_trace()
549
+ assert await judge.score(trace.task, trace) == 0.5
550
+ assert trace.metrics == {"q/depth": 0.5}
551
+
552
+
553
+ async def test_rubric_off_menu_answer_raises(tmp_path, monkeypatch):
554
+ # A verdict that isn't one of the criterion's choices is a judge failure, not a 0.
555
+ async def off_menu(self, messages, *, trace=None, schema=None, parse=None, **s):
556
+ v = {"verdicts": [{"name": "depth", "reason": "r", "verdict": "maybe"}]}
557
+ return JudgeResponse(text=json.dumps(v), parsed=None)
558
+
559
+ monkeypatch.setattr(Judge, "complete", off_menu)
560
+ judge = rubric_judge(tmp_path, body=CHOICES_TOML)
561
+ trace = make_trace()
562
+ with pytest.raises(ValueError, match="expected one of"):
563
+ await judge.score(trace.task, trace)
564
+
565
+
566
+ def test_rubric_choices_validation(tmp_path):
567
+ with pytest.raises(ValueError, match="at least two"):
568
+ rubric_judge(
569
+ tmp_path, body='[[criteria]]\nname = "x"\ntext = "t"\nchoices = ["only"]\n'
570
+ ).criteria
571
+ with pytest.raises(ValueError, match="duplicate options"):
572
+ rubric_judge(
573
+ tmp_path,
574
+ body='[[criteria]]\nname = "x"\ntext = "t"\nchoices = ["a", "a"]\n',
575
+ ).criteria
576
+
577
+
578
+ async def test_rubric_reference_answer_optional(tmp_path, fake_judge_model):
579
+ # off by default: no reference block in the prompt.
580
+ t = make_trace()
581
+ await rubric_judge(tmp_path).score(t.task, t)
582
+ assert "Reference solution" not in fake_judge_model[-1]
583
+
584
+ # answer_field set: the task's gold answer is shown to the judge.
585
+ t = make_trace(answer="ZEBRA-GOLD")
586
+ await rubric_judge(tmp_path, answer_field="answer").score(t.task, t)
587
+ assert "Reference solution" in fake_judge_model[-1]
588
+ assert "ZEBRA-GOLD" in fake_judge_model[-1]
589
+
590
+
526
591
  # --- Taskset.score integration -------------------------------------------------------------
527
592
 
528
593
 
@@ -209,15 +209,24 @@ def Overview(config: EvalConfig) -> Table:
209
209
 
210
210
 
211
211
  def Progress(
212
- rollouts: list[Rollout], start: float, page: tuple[int, int] | None = None
212
+ rollouts: list[Rollout],
213
+ start: float,
214
+ page: tuple[int, int] | None = None,
215
+ finished: list[Trace] | None = None,
213
216
  ) -> Group:
214
- done = [r.trace for r in rollouts if r.phase == Phase.DONE] # fully scored
217
+ # On resume, `finished` holds the kept on-disk rollouts (reloaded as finished traces); count
218
+ # them alongside this session's so progress, reward, err, and the breakdown cover the whole
219
+ # run. `rollouts` is only this session's (owed) work, so the total adds the kept ones back.
220
+ done = (finished or []) + [
221
+ r.trace for r in rollouts if r.phase == Phase.DONE
222
+ ] # fully scored
223
+ total = len(finished or []) + len(rollouts)
215
224
  # Headline reward = mean over non-errored; when any errored, `format_mean` appends the
216
225
  # global avg (errored count as 0) in parens. `err` is the share that errored.
217
226
  reward = format_mean(done, lambda t: t.reward)
218
227
  err = f"{sum(t.has_error for t in done) / len(done):.2f}" if done else "—"
219
228
  stats = (
220
- f"{len(done)}/{len(rollouts)} · {format_time(time.time() - start)} · "
229
+ f"{len(done)}/{total} · {format_time(time.time() - start)} · "
221
230
  f"reward {reward} · err {err}"
222
231
  )
223
232
  if page is not None: # overflowing — show which page, and that the arrows page
@@ -226,7 +235,7 @@ def Progress(
226
235
  row.add_column(ratio=1) # bar stretches to fill the width left of the stats
227
236
  row.add_column(justify="right", no_wrap=True)
228
237
  row.add_row(
229
- ProgressBar(total=len(rollouts) or 1, completed=len(done)),
238
+ ProgressBar(total=total or 1, completed=len(done)),
230
239
  Text(stats),
231
240
  )
232
241
  breakdown = _breakdown(done)
@@ -561,7 +570,11 @@ def _paginate(
561
570
 
562
571
 
563
572
  def _render(
564
- rollouts: list[Rollout], config: EvalConfig, start: float, pager: Pager
573
+ rollouts: list[Rollout],
574
+ config: EvalConfig,
575
+ start: float,
576
+ pager: Pager,
577
+ finished: list[Trace] | None = None,
565
578
  ) -> Group:
566
579
  now = time.time()
567
580
  warning = _warning(config)
@@ -570,10 +583,15 @@ def _render(
570
583
  # Measure the fixed top (header + progress + rule) so the rollout rows fill the rest of the
571
584
  # screen; page through them (timer, or the left/right arrows) when they'd overflow (rich would
572
585
  # otherwise truncate).
573
- top = Group(header, Progress(rollouts, start), Rule(style="dim"))
586
+ top = Group(header, Progress(rollouts, start, finished=finished), Rule(style="dim"))
574
587
  rows_per_page = max(1, _CONSOLE.size.height - len(_CONSOLE.render_lines(top)) - 1)
575
588
  page_groups, index, count = _paginate(_groups(rollouts), rows_per_page, pager, now)
576
- progress = Progress(rollouts, start, page=(index + 1, count) if count > 1 else None)
589
+ progress = Progress(
590
+ rollouts,
591
+ start,
592
+ page=(index + 1, count) if count > 1 else None,
593
+ finished=finished,
594
+ )
577
595
  return Group(
578
596
  header,
579
597
  progress,
@@ -583,11 +601,18 @@ def _render(
583
601
 
584
602
 
585
603
  @contextlib.asynccontextmanager
586
- async def dashboard(rollouts: list[Rollout], config: EvalConfig, start: float):
604
+ async def dashboard(
605
+ rollouts: list[Rollout],
606
+ config: EvalConfig,
607
+ start: float,
608
+ finished: list[Trace] | None = None,
609
+ ):
587
610
  """Refresh the live eval view until the `with` block exits, then a final frame. Left/right
588
- arrows page through rollout rows when they overflow the screen."""
611
+ arrows page through rollout rows when they overflow the screen. On resume, `finished` carries
612
+ the kept on-disk rollouts (reloaded as finished traces) so the counts and scores cover the
613
+ whole run, not just this session's re-run rollouts."""
589
614
  pager = Pager()
590
615
  async with live_view(
591
- lambda: _render(rollouts, config, start, pager), on_key=pager.on_key
616
+ lambda: _render(rollouts, config, start, pager, finished), on_key=pager.on_key
592
617
  ):
593
618
  yield
@@ -16,7 +16,12 @@ from pathlib import Path
16
16
 
17
17
  from pydantic_core import from_json
18
18
 
19
+ from verifiers.v1.cli.output import read_traces
19
20
  from verifiers.v1.configs.eval import EvalConfig
21
+ from verifiers.v1.state import state_cls
22
+ from verifiers.v1.task import WireTask
23
+ from verifiers.v1.taskset import Taskset
24
+ from verifiers.v1.trace import Trace
20
25
 
21
26
 
22
27
  def split_resume(argv: list[str]) -> tuple[Path | None, list[str]]:
@@ -116,6 +121,14 @@ def rewrite_results(resume_dir: Path, keep: list[int]) -> None:
116
121
  tmp.replace(path)
117
122
 
118
123
 
124
+ def load_kept(resume_dir: Path, taskset: Taskset) -> list[Trace]:
125
+ """Reload the kept (good) traces as finished `Trace`s, so a resumed run's live dashboard counts
126
+ them toward the whole run (progress, reward, err, and the usage/time breakdown). Call *after*
127
+ `rewrite_results`, which leaves only the kept rows on disk. `WireTask` reads any taskset's saved
128
+ task without a runtime or its `Task` type (mirrors `replay`)."""
129
+ return read_traces(resume_dir, Trace[WireTask, state_cls(type(taskset))])
130
+
131
+
119
132
  def nothing_to_resume_msg(resume_dir: Path, num_tasks: int, num_rollouts: int) -> str:
120
133
  """The message shown (and then exit 0 - the run is already complete) when every selected
121
134
  rollout already completed without error."""
@@ -41,6 +41,10 @@ async def run_eval(env: Environment, config: EvalConfig) -> list[Trace]:
41
41
  # run only the owed rollouts. One lock serializes worker-thread appends from concurrent
42
42
  # rollouts while keeping large trace serialization off the event loop.
43
43
  owed: dict[str, int] | None = None
44
+ # On resume, the kept (good) on-disk rollouts, reloaded as finished traces so the live
45
+ # dashboard counts the whole run (progress, reward, err, usage/time) rather than only this
46
+ # session's re-run rollouts. Only the --rich dashboard reads them, so skip the load otherwise.
47
+ finished: list[Trace] = []
44
48
  if config.resume is not None:
45
49
  group = bool(discover_decorated(env.taskset, "group_reward"))
46
50
  keep, owed = resume.plan(
@@ -51,6 +55,8 @@ async def run_eval(env: Environment, config: EvalConfig) -> list[Trace]:
51
55
  raise SystemExit(0)
52
56
  tasks = [task for task in tasks if owed.get(task.idx)]
53
57
  resume.rewrite_results(out, keep)
58
+ if config.rich:
59
+ finished = resume.load_kept(out, env.taskset)
54
60
  logger.info(
55
61
  "resuming %s: %d task(s), %d rollout(s) owed",
56
62
  out,
@@ -84,7 +90,7 @@ async def run_eval(env: Environment, config: EvalConfig) -> list[Trace]:
84
90
  ]
85
91
  rollouts = [rollout for episode in episodes for rollout in episode.rollouts]
86
92
  display = (
87
- dashboard(rollouts, config, start)
93
+ dashboard(rollouts, config, start, finished=finished)
88
94
  if config.rich
89
95
  else contextlib.nullcontext()
90
96
  )
@@ -0,0 +1,330 @@
1
+ """rubric — an off-the-shelf rubric judge, plugged from config alone.
2
+
3
+ Reads a rubric — a list of criteria — from a JSON or TOML file and asks the judge model to grade
4
+ each by picking one of its ordered `choices` (default `["no", "yes"]`, a binary check), scored to
5
+ [0, 1] by rank — worst → best, so the first choice is 0.0 and the last 1.0 (all in one call by
6
+ default, or batched `max_criteria`-at-a-time). Grading uses plain-text JSON by default, or
7
+ structured output when `structured_output=true` (see `RubricJudgeConfig`). The reward is the
8
+ weighted mean of the per-criterion scores (`sum(w*v) / sum(w)`, so it stays in [0, 1]); each score
9
+ is also recorded as a `<name>/<criterion>` metric. Criterion weights come from the rubric file and
10
+ are overridable from config (`weights`); the aggregate weighs into `trace.reward` via the judge's
11
+ `weight`:
12
+
13
+ [[env.taskset.judges]]
14
+ id = "rubric"
15
+ path = "rubrics/quality.toml"
16
+ weight = 0.5
17
+ weights = { cites_sources = 2.0 } # override the file's per-criterion weight
18
+
19
+ with `rubrics/quality.toml` listing the criteria (JSON takes `{"criteria": [...]}` or a bare list):
20
+
21
+ [[criteria]]
22
+ name = "cites_sources"
23
+ text = "The response cites at least one specific source."
24
+ weight = 1.0
25
+ # choices default to ["no", "yes"]; give an ordered worst→best list for a graded criterion:
26
+ # choices = ["none", "partial", "thorough"] # -> 0.0, 0.5, 1.0
27
+ """
28
+
29
+ import asyncio
30
+ import json
31
+ import math
32
+ import re
33
+ import tomllib
34
+ from functools import cached_property
35
+ from pathlib import Path
36
+ from typing import cast
37
+
38
+ from pydantic import field_validator
39
+
40
+ from verifiers.v1.judge import (
41
+ Judge,
42
+ JudgeConfig,
43
+ JudgeView,
44
+ judge_question,
45
+ judge_response,
46
+ )
47
+ from verifiers.v1.task import Task
48
+ from verifiers.v1.trace import Trace
49
+ from verifiers.v1.types import ID, StrictBaseModel
50
+
51
+ # A sibling text file so it doubles as a starting point for a config `prompt_file`.
52
+ RUBRIC_PROMPT = (Path(__file__).resolve().parent / "rubric.txt").read_text(
53
+ encoding="utf-8"
54
+ )
55
+
56
+ # Appended to the prompt when `structured_output` is off, so the reply is JSON we can parse. Each
57
+ # criterion carries a one-sentence `reason` written *before* the verdict (chain-of-thought), so the
58
+ # verdict follows from it and the reasoning is auditable in `trace.info["judge"]`.
59
+ JSON_SUFFIX = (
60
+ "\n\nRespond with ONLY a JSON object and nothing else, in exactly this shape:\n"
61
+ '{"verdicts": [{"name": "<criterion name>", "reason": "<one sentence citing specific '
62
+ 'evidence from the response>", "verdict": "<answer>"}, ...]}\n'
63
+ "with one entry per criterion, using each criterion's exact name. For each, first write the "
64
+ "one-sentence reason grounded in the response, then set verdict to exactly one of the options "
65
+ "listed in parentheses after that criterion."
66
+ )
67
+
68
+
69
+ def normalize_choice(choice: str, choices: list[str]) -> float:
70
+ """Score a chosen option to [0, 1] by rank. `choices` are ordered worst → best, so the first
71
+ scores 0.0, the last 1.0, and the rest evenly spaced (`choices` always has >= 2 entries)."""
72
+ return choices.index(choice) / (len(choices) - 1)
73
+
74
+
75
+ def first_verdicts_object(text: str) -> dict | None:
76
+ """The first balanced JSON object in `text` that carries a `verdicts` key. Scanning for the
77
+ key (not just the first `{`) skips prose and, crucially, an echoed format example — the one
78
+ in `JSON_SUFFIX` fails to parse (its trailing `...` isn't JSON) and is passed over rather
79
+ than mistaken for the answer. Returns `None` if no such object is found."""
80
+ decoder = json.JSONDecoder()
81
+ idx = text.find("{")
82
+ while idx != -1:
83
+ try:
84
+ obj, _ = decoder.raw_decode(text[idx:])
85
+ except json.JSONDecodeError:
86
+ obj = None
87
+ if isinstance(obj, dict) and "verdicts" in obj:
88
+ return obj
89
+ idx = text.find("{", idx + 1)
90
+ return None
91
+
92
+
93
+ class Criterion(StrictBaseModel):
94
+ """One rubric entry the judge grades by picking one of `choices`, scored to [0, 1] by rank.
95
+ Defaults to a binary yes/no check (1/0)."""
96
+
97
+ name: str
98
+ """Key for the criterion's metric (`<judge name>/<name>`) and its `weights` override."""
99
+ text: str
100
+ """The check itself, phrased so the first (best) choice means satisfied."""
101
+ weight: float = 1.0
102
+ """The criterion's share of the reward (overridable per name via `weights` in config)."""
103
+ choices: list[str] = ["no", "yes"]
104
+ """Allowed answers, ordered **worst → best**: the first scores 0.0, the last 1.0, the rest
105
+ evenly spaced by rank. Default `["no", "yes"]` is a binary check. Needs >= 2, no duplicates."""
106
+
107
+ @field_validator("choices")
108
+ @classmethod
109
+ def _check_choices(cls, v: list[str]) -> list[str]:
110
+ if len(v) < 2:
111
+ raise ValueError(f"`choices` needs at least two options, got {v}")
112
+ if len(set(v)) != len(v):
113
+ raise ValueError(f"`choices` has duplicate options: {v}")
114
+ return v
115
+
116
+
117
+ class RubricJudgeConfig(JudgeConfig):
118
+ id: ID = "rubric"
119
+ """Pinned to the built-in, so a code-level default entry needs no explicit id."""
120
+ path: Path
121
+ """The rubric file (`.toml` or `.json`) listing the criteria — see the module docstring
122
+ for the shape. A relative path resolves against the eval's working directory."""
123
+ weights: dict[str, float] = {}
124
+ """Per-criterion weight overrides by criterion name (config wins over the file)."""
125
+ question_field: str = ""
126
+ """Task field to fill the prompt's `{question}`; empty = the task's prompt rendered as
127
+ text (`Task.prompt_text`)."""
128
+ answer_field: str = ""
129
+ """Optional task field holding a reference answer (e.g. a gold patch) to show the judge, like
130
+ the reference judge. Empty (default) shows none — `{reference}` renders blank. A list-valued
131
+ field is joined one item per line. Needs `{reference}` in the prompt (the built-in `rubric.txt`
132
+ has it)."""
133
+ view: JudgeView = "full_trace"
134
+ """How much of the rollout fills `{response}` (see `JudgeView`). Defaults to the whole
135
+ transcript — rubric criteria typically grade the process (tool use, citations,
136
+ intermediate steps), not just the final answer."""
137
+ max_criteria: int | None = None
138
+ """How many criteria to grade per judge call. `None` (default) grades all criteria in one
139
+ call. `1` sends one call per criterion (n independent judges); `k` batches them k-at-a-time.
140
+ Batches are graded concurrently and merged. Smaller batches trade more calls for focus/
141
+ robustness. Must be >= 1."""
142
+ structured_output: bool = False
143
+ """Grade via JSON-schema structured output (`response_format`) when `True`; grade via plain-text
144
+ output parsed as JSON when `False` (the default). Plain text is far more reliable on endpoints
145
+ whose structured decoding is flaky (e.g. GLM-5.2 and other non-OpenAI models on some providers
146
+ return empty completions for structured calls, especially over long transcripts); OpenAI models
147
+ handle either. Transient HTTP failures are already retried by the OpenAI client."""
148
+
149
+
150
+ class CriterionVerdict(StrictBaseModel):
151
+ """One criterion's reply, matched back to the rubric by `name`: a short `reason`
152
+ (chain-of-thought, always recorded for auditability in `trace.info["judge"]`) written *before*
153
+ the `verdict`, so the verdict follows from it. `verdict` is one of the criterion's `choices`
154
+ (validated per criterion in `grade_batch`, since choices vary by criterion)."""
155
+
156
+ name: str
157
+ reason: str
158
+ verdict: str
159
+
160
+
161
+ class RubricVerdicts(StrictBaseModel):
162
+ """The judge's reply: one reasoned verdict per rubric criterion."""
163
+
164
+ verdicts: list[CriterionVerdict]
165
+
166
+
167
+ class RubricJudge(Judge[RubricVerdicts, RubricJudgeConfig]):
168
+ """Scores every rubric criterion 1/0 (in one judge call, or batched `max_criteria` at a
169
+ time) and rewards their weighted mean."""
170
+
171
+ prompt = RUBRIC_PROMPT
172
+ schema = RubricVerdicts
173
+
174
+ @cached_property
175
+ def criteria(self) -> list[Criterion]:
176
+ """The rubric, parsed once from `config.path` (TOML by suffix, else JSON) with the
177
+ config's `weights` overrides applied. Fails loudly on a missing/empty file, duplicate
178
+ criterion names, or an override naming no criterion."""
179
+ path = self.config.path
180
+ text = path.read_text(encoding="utf-8")
181
+ data = (
182
+ tomllib.loads(text) if path.suffix.lower() == ".toml" else json.loads(text)
183
+ )
184
+ items = data.get("criteria", []) if isinstance(data, dict) else data
185
+ criteria = [Criterion.model_validate(item) for item in items]
186
+ if not criteria:
187
+ raise ValueError(f"rubric file '{path}' lists no criteria")
188
+ names = [criterion.name for criterion in criteria]
189
+ if len(set(names)) != len(names):
190
+ raise ValueError(f"rubric file '{path}' has duplicate criterion names")
191
+ if unknown := set(self.config.weights) - set(names):
192
+ raise ValueError(
193
+ f"`weights` overrides name no criterion in '{path}': {sorted(unknown)}"
194
+ )
195
+ criteria = [
196
+ criterion.model_copy(
197
+ update={
198
+ "weight": self.config.weights.get(criterion.name, criterion.weight)
199
+ }
200
+ )
201
+ for criterion in criteria
202
+ ]
203
+ if bad := [c.name for c in criteria if not 0 <= c.weight < math.inf]:
204
+ # A negative weight would invert a criterion (pushing the reward out of [0, 1]);
205
+ # NaN/inf (which json.loads accepts) would corrupt the weighted mean.
206
+ raise ValueError(
207
+ f"rubric '{path}' has negative or non-finite criterion weights: {bad}"
208
+ )
209
+ if sum(criterion.weight for criterion in criteria) <= 0:
210
+ raise ValueError(f"rubric '{path}' has no positive criterion weight")
211
+ return criteria
212
+
213
+ async def grade_batch(
214
+ self, task: Task, trace: Trace, batch: list[Criterion]
215
+ ) -> dict[str, float]:
216
+ """Grade one batch of criteria in a single judge call — structured output, or plain-text
217
+ JSON when `structured_output` is off (which avoids flaky structured decoding). Returns
218
+ `{name: score}`, each the chosen option normalized to [0, 1] by rank (best → worst),
219
+ matched back to the batch by name. `score` fans this out per batch."""
220
+
221
+ def render(
222
+ c: Criterion,
223
+ ) -> str: # every criterion states its own allowed answers inline
224
+ return f"- {c.name}: {c.text} (answer one of, worst to best: {', '.join(c.choices)})"
225
+
226
+ reference = "" # optional gold answer shown to the judge; blank unless `answer_field` set
227
+ if self.config.answer_field:
228
+ answer = getattr(task, self.config.answer_field, None)
229
+ if answer is None:
230
+ raise ValueError(
231
+ f"rubric judge found no {self.config.answer_field!r} field on the task; "
232
+ "point `answer_field` at the task's reference-answer field or leave it empty"
233
+ )
234
+ if isinstance(answer, (list, tuple)):
235
+ answer = "\n".join(str(item) for item in answer)
236
+ # A clearly-announced section (leading blank separates it from the Task block; the
237
+ # template's newline before Response closes it). Absent when `answer_field` is unset.
238
+ # Fence longer than any backtick run in the answer, so a patch/markdown containing ```
239
+ # can't close it early and spill into the prompt as instructions.
240
+ fence = "`" * (
241
+ max((len(m) for m in re.findall(r"`+", answer)), default=2) + 1
242
+ )
243
+ reference = (
244
+ "\nReference solution (a correct implementation of this task, for comparison):\n"
245
+ f"{fence}\n{answer}\n{fence}\n"
246
+ )
247
+
248
+ fields = dict(
249
+ question=judge_question(task, self.config.question_field),
250
+ response=judge_response(trace, self.config.view),
251
+ criteria="\n".join(render(c) for c in batch),
252
+ reference=reference,
253
+ )
254
+ if self.config.structured_output:
255
+ result = await self.evaluate(trace=trace, **fields)
256
+ verdicts = cast(RubricVerdicts, result.parsed).verdicts
257
+ else:
258
+ messages = cast(str, self.build_messages(**fields)) + JSON_SUFFIX
259
+ result = await self.complete(
260
+ messages, trace=trace
261
+ ) # no schema -> plain text
262
+ obj = first_verdicts_object(result.text)
263
+ if obj is None:
264
+ raise ValueError(
265
+ f"judge returned no verdicts JSON object: {result.text!r}"
266
+ )
267
+ verdicts = RubricVerdicts.model_validate(obj).verdicts
268
+ # Exactly one verdict per criterion in the batch, matched by name — anything else is a
269
+ # judge failure and must error the rollout, not score the model (see `judge_verdict`).
270
+ by_criterion = {c.name: c for c in batch}
271
+ if sorted(v.name for v in verdicts) != sorted(by_criterion):
272
+ raise ValueError(
273
+ f"judge verdicts name {sorted(v.name for v in verdicts)}, expected the "
274
+ f"batch's {sorted(by_criterion)}"
275
+ )
276
+ scores: dict[str, float] = {}
277
+ for v in verdicts:
278
+ choices = by_criterion[v.name].choices
279
+ if (
280
+ v.verdict not in choices
281
+ ): # an off-menu answer is a judge failure, not a 0
282
+ raise ValueError(
283
+ f"judge answered {v.verdict!r} for '{v.name}', expected one of {choices}"
284
+ )
285
+ scores[v.name] = normalize_choice(v.verdict, choices)
286
+ return scores
287
+
288
+ async def score(self, task: Task, trace: Trace) -> float:
289
+ criteria = self.criteria
290
+ # Split into batches of `max_criteria` (None = one batch of all), then grade the batches
291
+ # concurrently (one judge call each) and merge.
292
+ k = self.config.max_criteria
293
+ if k is not None and k < 1:
294
+ raise ValueError(f"`max_criteria` must be >= 1 or None, got {k}")
295
+ batches = (
296
+ [criteria]
297
+ if k is None
298
+ else [criteria[i : i + k] for i in range(0, len(criteria), k)]
299
+ )
300
+ # Fan out one call per batch; if any fails, cancel the siblings so a judge failure
301
+ # doesn't keep billing the remaining batches.
302
+ tasks = [
303
+ asyncio.ensure_future(self.grade_batch(task, trace, batch))
304
+ for batch in batches
305
+ ]
306
+ try:
307
+ results = await asyncio.gather(*tasks)
308
+ except BaseException:
309
+ for t in tasks:
310
+ t.cancel()
311
+ await asyncio.gather(*tasks, return_exceptions=True)
312
+ raise
313
+ by_name: dict[str, float] = {}
314
+ for batch_verdicts in results:
315
+ by_name.update(batch_verdicts)
316
+ for criterion in criteria:
317
+ trace.record_metric(
318
+ f"{self.reward_name}/{criterion.name}", by_name[criterion.name]
319
+ )
320
+ total = sum(criterion.weight for criterion in criteria)
321
+ return sum(c.weight * by_name[c.name] for c in criteria) / total
322
+
323
+
324
+ __all__ = [
325
+ "Criterion",
326
+ "CriterionVerdict",
327
+ "RubricJudge",
328
+ "RubricJudgeConfig",
329
+ "RubricVerdicts",
330
+ ]
@@ -4,7 +4,7 @@ Task:
4
4
  ```
5
5
  {question}
6
6
  ```
7
-
7
+ {reference}
8
8
  Response:
9
9
  ```
10
10
  {response}
@@ -13,4 +13,4 @@ Response:
13
13
  Criteria:
14
14
  {criteria}
15
15
 
16
- For each criterion, give a "yes" or "no" verdict under its exact name.
16
+ For each criterion, answer under its exact name with exactly one of the options given in parentheses after it.