verifiers 0.2.2.dev54__tar.gz → 0.2.2.dev56__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 (424) hide show
  1. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/PKG-INFO +1 -1
  2. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/pyproject.toml +1 -0
  3. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/test_e2e.py +20 -0
  4. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/replay.py +2 -2
  5. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/__init__.py +6 -0
  6. verifiers-0.2.2.dev56/verifiers/v1/harnesses/browser_use/__init__.py +6 -0
  7. verifiers-0.2.2.dev56/verifiers/v1/harnesses/browser_use/harness.py +125 -0
  8. verifiers-0.2.2.dev56/verifiers/v1/harnesses/browser_use/program.py +402 -0
  9. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/serve/server.py +2 -2
  10. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/task.py +51 -75
  11. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/taskset.py +0 -2
  12. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/.gitignore +0 -0
  13. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/LICENSE +0 -0
  14. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/README.md +0 -0
  15. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/__init__.py +0 -0
  16. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/conftest.py +0 -0
  17. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_browser_env.py +0 -0
  18. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_build_script.py +0 -0
  19. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_cli_agent_env.py +0 -0
  20. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_client_auth_errors.py +0 -0
  21. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_client_config.py +0 -0
  22. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_client_multimodal_types.py +0 -0
  23. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_composable_env.py +0 -0
  24. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_context_token_metrics.py +0 -0
  25. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_decorator_ranks.py +0 -0
  26. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_endpoint_registry.py +0 -0
  27. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_env_group.py +0 -0
  28. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_env_server.py +0 -0
  29. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_environment.py +0 -0
  30. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_environment_extra.py +0 -0
  31. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_error_chain.py +0 -0
  32. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_eval_display.py +0 -0
  33. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_eval_utils.py +0 -0
  34. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_gepa_cli.py +0 -0
  35. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_gepa_utils.py +0 -0
  36. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_gym_env.py +0 -0
  37. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_harbor_env_mcp.py +0 -0
  38. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_imports.py +0 -0
  39. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_init_script.py +0 -0
  40. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_install_utils.py +0 -0
  41. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_interception_utils.py +0 -0
  42. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_logging.py +0 -0
  43. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_math_rubric.py +0 -0
  44. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_maybe_think_parser.py +0 -0
  45. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_message_utils.py +0 -0
  46. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_message_utils_multimodal.py +0 -0
  47. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_multiturn_env.py +0 -0
  48. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_nemorl_client.py +0 -0
  49. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_openai_chat_completions_token_client.py +0 -0
  50. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_openai_responses_client.py +0 -0
  51. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_opencode_rlm_env.py +0 -0
  52. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_openenv_client.py +0 -0
  53. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_parser.py +0 -0
  54. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_path_utils.py +0 -0
  55. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_per_turn_timing.py +0 -0
  56. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_pricing_utils.py +0 -0
  57. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_prime_plugin.py +0 -0
  58. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_renderer_client.py +0 -0
  59. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_renderer_e2e.py +0 -0
  60. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_rlm_composable_env.py +0 -0
  61. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_rubric.py +0 -0
  62. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_rubric_group.py +0 -0
  63. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_sandbox_debug_env.py +0 -0
  64. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_sandbox_env.py +0 -0
  65. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_sandbox_mixin.py +0 -0
  66. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_save_utils.py +0 -0
  67. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_setup_script.py +0 -0
  68. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_singleturn_env.py +0 -0
  69. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_stateful_tool_env.py +0 -0
  70. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_think_parser.py +0 -0
  71. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_tool_env.py +0 -0
  72. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_tool_utils.py +0 -0
  73. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_trajectory_processing.py +0 -0
  74. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_tui_info_formatting.py +0 -0
  75. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_types.py +0 -0
  76. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/test_xml_parser.py +0 -0
  77. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/conftest.py +0 -0
  78. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/counter_tool_v1.py +0 -0
  79. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/duet_v1.py +0 -0
  80. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/echo_acp_resume_v1.py +0 -0
  81. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
  82. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/echo_multi_v0.py +0 -0
  83. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/echo_tool_v1.py +0 -0
  84. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
  85. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/echo_v0.py +0 -0
  86. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/echo_v1.py +0 -0
  87. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/pyproject.toml +0 -0
  88. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
  89. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/test_color_codeword_tasks.py +0 -0
  90. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/test_configs.py +0 -0
  91. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/test_envs.py +0 -0
  92. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/test_graph.py +0 -0
  93. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/test_judges.py +0 -0
  94. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/test_legacy.py +0 -0
  95. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/test_scoring.py +0 -0
  96. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/test_taskset.py +0 -0
  97. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/tests/v1/test_trace.py +0 -0
  98. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/__init__.py +0 -0
  99. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/__init__.py +0 -0
  100. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/commands/__init__.py +0 -0
  101. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/commands/build.py +0 -0
  102. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/commands/eval.py +0 -0
  103. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/commands/gepa.py +0 -0
  104. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/commands/init.py +0 -0
  105. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/commands/install.py +0 -0
  106. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/commands/setup.py +0 -0
  107. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/plugins/__init__.py +0 -0
  108. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/plugins/prime.py +0 -0
  109. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/cli/tui.py +0 -0
  110. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/clients/__init__.py +0 -0
  111. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/clients/anthropic_messages_client.py +0 -0
  112. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/clients/client.py +0 -0
  113. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
  114. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/clients/openai_chat_completions_client.py +0 -0
  115. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
  116. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/clients/openai_completions_client.py +0 -0
  117. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/clients/openai_responses_client.py +0 -0
  118. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/clients/renderer_client.py +0 -0
  119. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/decorators.py +0 -0
  120. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/__init__.py +0 -0
  121. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/env_group.py +0 -0
  122. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/environment.py +0 -0
  123. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/README.md +0 -0
  124. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/__init__.py +0 -0
  125. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/cli_agent_env.py +0 -0
  126. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/README.md +0 -0
  127. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/__init__.py +0 -0
  128. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/_filter.py +0 -0
  129. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/composable_env.py +0 -0
  130. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/harness.py +0 -0
  131. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
  132. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
  133. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
  134. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
  135. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
  136. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/sandbox_debug_env.py +0 -0
  137. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
  138. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/task.py +0 -0
  139. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
  140. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
  141. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
  142. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
  143. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
  144. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/harbor/cli_gym.py +0 -0
  145. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
  146. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/harbor/terminal_lego.py +0 -0
  147. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
  148. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
  149. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
  150. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
  151. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
  152. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
  153. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
  154. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
  155. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
  156. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
  157. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
  158. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
  159. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
  160. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
  161. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
  162. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
  163. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
  164. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
  165. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
  166. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
  167. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
  168. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
  169. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
  170. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
  171. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
  172. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
  173. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/gym_env.py +0 -0
  174. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
  175. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/harbor_env/env.py +0 -0
  176. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
  177. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/mcp_env.py +0 -0
  178. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/opencode_env.py +0 -0
  179. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
  180. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
  181. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
  182. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/utils/__init__.py +0 -0
  183. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/utils/file_locks.py +0 -0
  184. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
  185. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/README.md +0 -0
  186. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/__init__.py +0 -0
  187. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/browser_env/README.md +0 -0
  188. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
  189. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
  190. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
  191. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
  192. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
  193. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
  194. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/openenv_env.py +0 -0
  195. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
  196. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/integrations/textarena_env.py +0 -0
  197. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/multiturn_env.py +0 -0
  198. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/python_env.py +0 -0
  199. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/sandbox_env.py +0 -0
  200. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/singleturn_env.py +0 -0
  201. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/stateful_tool_env.py +0 -0
  202. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/envs/tool_env.py +0 -0
  203. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/errors.py +0 -0
  204. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/gepa/__init__.py +0 -0
  205. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/gepa/adapter.py +0 -0
  206. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/gepa/config.py +0 -0
  207. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/gepa/display.py +0 -0
  208. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/gepa/gepa_utils.py +0 -0
  209. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/parsers/__init__.py +0 -0
  210. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/parsers/maybe_think_parser.py +0 -0
  211. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/parsers/parser.py +0 -0
  212. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/parsers/think_parser.py +0 -0
  213. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/parsers/xml_parser.py +0 -0
  214. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/rubrics/__init__.py +0 -0
  215. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
  216. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/rubrics/judge_rubric.py +0 -0
  217. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/rubrics/math_rubric.py +0 -0
  218. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/rubrics/rubric.py +0 -0
  219. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/rubrics/rubric_group.py +0 -0
  220. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/scripts/__init__.py +0 -0
  221. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/scripts/build.py +0 -0
  222. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/scripts/eval.py +0 -0
  223. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/scripts/gepa.py +0 -0
  224. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/scripts/init.py +0 -0
  225. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/scripts/install.py +0 -0
  226. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/scripts/setup.py +0 -0
  227. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/scripts/tui.py +0 -0
  228. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/serve/__init__.py +0 -0
  229. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/serve/client/env_client.py +0 -0
  230. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/serve/client/zmq_env_client.py +0 -0
  231. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/serve/server/__init__.py +0 -0
  232. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/serve/server/env_router.py +0 -0
  233. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/serve/server/env_server.py +0 -0
  234. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/serve/server/env_worker.py +0 -0
  235. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/serve/server/zmq_env_server.py +0 -0
  236. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/serve/types.py +0 -0
  237. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/types.py +0 -0
  238. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/__init__.py +0 -0
  239. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/async_utils.py +0 -0
  240. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/client_utils.py +0 -0
  241. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/config_utils.py +0 -0
  242. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/data_utils.py +0 -0
  243. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/display_utils.py +0 -0
  244. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/env_config_utils.py +0 -0
  245. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/env_utils.py +0 -0
  246. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/error_utils.py +0 -0
  247. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/eval_display.py +0 -0
  248. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/eval_utils.py +0 -0
  249. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/heartbeat.py +0 -0
  250. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/import_utils.py +0 -0
  251. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/install_utils.py +0 -0
  252. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/interception_utils.py +0 -0
  253. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/logging_utils.py +0 -0
  254. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/message_utils.py +0 -0
  255. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/metric_utils.py +0 -0
  256. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/path_utils.py +0 -0
  257. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/pricing_utils.py +0 -0
  258. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/process_utils.py +0 -0
  259. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/response_utils.py +0 -0
  260. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/save_utils.py +0 -0
  261. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/serve_utils.py +0 -0
  262. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/thread_utils.py +0 -0
  263. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/threaded_sandbox_client.py +0 -0
  264. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/tool_utils.py +0 -0
  265. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/usage_utils.py +0 -0
  266. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/utils/version_utils.py +0 -0
  267. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/__init__.py +0 -0
  268. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/acp/__init__.py +0 -0
  269. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/acp/_runner.py +0 -0
  270. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/agent.py +0 -0
  271. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/artifacts.py +0 -0
  272. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/__init__.py +0 -0
  273. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/dashboard/__init__.py +0 -0
  274. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/dashboard/base.py +0 -0
  275. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/dashboard/eval.py +0 -0
  276. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/dashboard/replay.py +0 -0
  277. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/dashboard/validate.py +0 -0
  278. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/debug.py +0 -0
  279. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/eval/__init__.py +0 -0
  280. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/eval/main.py +0 -0
  281. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/eval/resume.py +0 -0
  282. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/eval/runner.py +0 -0
  283. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/gepa.py +0 -0
  284. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/init.py +0 -0
  285. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/output.py +0 -0
  286. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/resolve.py +0 -0
  287. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/serve.py +0 -0
  288. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/cli/validate.py +0 -0
  289. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/clients/__init__.py +0 -0
  290. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/clients/client.py +0 -0
  291. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/clients/config.py +0 -0
  292. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/clients/eval.py +0 -0
  293. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/clients/train.py +0 -0
  294. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/__init__.py +0 -0
  295. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/agent.py +0 -0
  296. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/cli/__init__.py +0 -0
  297. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/cli/debug.py +0 -0
  298. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/cli/env.py +0 -0
  299. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/cli/eval.py +0 -0
  300. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/cli/init.py +0 -0
  301. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/cli/replay.py +0 -0
  302. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/cli/serve.py +0 -0
  303. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/cli/validate.py +0 -0
  304. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/env.py +0 -0
  305. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/harness.py +0 -0
  306. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/judge.py +0 -0
  307. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/legacy.py +0 -0
  308. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/retries.py +0 -0
  309. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/serve.py +0 -0
  310. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/task.py +0 -0
  311. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/configs/taskset.py +0 -0
  312. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/decorators.py +0 -0
  313. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/dialects/__init__.py +0 -0
  314. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/dialects/anthropic.py +0 -0
  315. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/dialects/base.py +0 -0
  316. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/dialects/chat.py +0 -0
  317. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/dialects/responses.py +0 -0
  318. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/env.py +0 -0
  319. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/envs/__init__.py +0 -0
  320. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
  321. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/envs/agentic_judge/env.py +0 -0
  322. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
  323. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/envs/best_of_n/env.py +0 -0
  324. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/envs/single_agent/__init__.py +0 -0
  325. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/envs/single_agent/env.py +0 -0
  326. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/envs/user_sim/__init__.py +0 -0
  327. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/envs/user_sim/env.py +0 -0
  328. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/episode.py +0 -0
  329. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/errors.py +0 -0
  330. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/gepa/__init__.py +0 -0
  331. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/gepa/adapter.py +0 -0
  332. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/gepa/config.py +0 -0
  333. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/gepa/dataset.py +0 -0
  334. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/gepa/reflection.py +0 -0
  335. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/gepa/runner.py +0 -0
  336. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/graph.py +0 -0
  337. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harness.py +0 -0
  338. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/bash/__init__.py +0 -0
  339. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/bash/harness.py +0 -0
  340. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/bash/program.py +0 -0
  341. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
  342. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/claude_code/harness.py +0 -0
  343. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/codex/__init__.py +0 -0
  344. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/codex/harness.py +0 -0
  345. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
  346. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
  347. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
  348. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
  349. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
  350. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/null/__init__.py +0 -0
  351. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/null/harness.py +0 -0
  352. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/null/program.py +0 -0
  353. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/pi/__init__.py +0 -0
  354. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/pi/harness.py +0 -0
  355. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/pool/__init__.py +0 -0
  356. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/pool/harness.py +0 -0
  357. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
  358. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/rlm/harness.py +0 -0
  359. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
  360. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
  361. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
  362. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/interception/__init__.py +0 -0
  363. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/interception/base.py +0 -0
  364. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/interception/pool.py +0 -0
  365. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/interception/server.py +0 -0
  366. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/interception/tunnel/__init__.py +0 -0
  367. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/interception/tunnel/base.py +0 -0
  368. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/interception/tunnel/custom.py +0 -0
  369. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/interception/tunnel/prime.py +0 -0
  370. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/judge.py +0 -0
  371. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/judges/__init__.py +0 -0
  372. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/judges/reference.py +0 -0
  373. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/judges/reference.txt +0 -0
  374. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/judges/rubric.py +0 -0
  375. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/judges/rubric.txt +0 -0
  376. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/legacy.py +0 -0
  377. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/loaders.py +0 -0
  378. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/mcp/__init__.py +0 -0
  379. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/mcp/launch.py +0 -0
  380. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/mcp/server.py +0 -0
  381. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/mcp/toolset.py +0 -0
  382. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/push.py +0 -0
  383. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/retries.py +0 -0
  384. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/rollout.py +0 -0
  385. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/runtimes/__init__.py +0 -0
  386. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/runtimes/base.py +0 -0
  387. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/runtimes/docker/__init__.py +0 -0
  388. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/runtimes/docker/egress.py +0 -0
  389. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/runtimes/limiters.py +0 -0
  390. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/runtimes/modal.py +0 -0
  391. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/runtimes/prime.py +0 -0
  392. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/runtimes/subprocess.py +0 -0
  393. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/scoring.py +0 -0
  394. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/serve/__init__.py +0 -0
  395. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/serve/client.py +0 -0
  396. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/serve/pool.py +0 -0
  397. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/serve/types.py +0 -0
  398. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/session.py +0 -0
  399. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/state.py +0 -0
  400. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/tasksets/__init__.py +0 -0
  401. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
  402. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
  403. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/tasksets/lean/__init__.py +0 -0
  404. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/tasksets/lean/scoring.py +0 -0
  405. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/tasksets/lean/taskset.py +0 -0
  406. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
  407. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
  408. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
  409. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
  410. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/trace.py +0 -0
  411. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/types.py +0 -0
  412. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/__init__.py +0 -0
  413. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/aio.py +0 -0
  414. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/compile.py +0 -0
  415. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/format.py +0 -0
  416. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/generic.py +0 -0
  417. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/git.py +0 -0
  418. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/image.py +0 -0
  419. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/install.py +0 -0
  420. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/interrupt.py +0 -0
  421. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/logging.py +0 -0
  422. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/memory.py +0 -0
  423. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/sampling.py +0 -0
  424. {verifiers-0.2.2.dev54 → verifiers-0.2.2.dev56}/verifiers/v1/utils/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verifiers
3
- Version: 0.2.2.dev54
3
+ Version: 0.2.2.dev56
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
@@ -234,6 +234,7 @@ markers = [
234
234
  "colocated: v1 e2e cases with a user/tool server colocated in the harness runtime",
235
235
  "null: v1 e2e cases on the null harness",
236
236
  "bash: v1 e2e cases on the bash harness",
237
+ "browser_use: v1 e2e cases on the browser_use harness",
237
238
  "rlm: v1 e2e cases on the rlm harness",
238
239
  "kimi_code: v1 e2e cases on the kimi-code harness",
239
240
  "pi: v1 e2e cases on the pi harness",
@@ -118,6 +118,26 @@ async def test_single_turn(run_v1, harness, harness_runtime, tmp_path):
118
118
  assert call.time.duration > 0
119
119
 
120
120
 
121
+ @pytest.mark.e2e
122
+ @pytest.mark.browser_use
123
+ @pytest.mark.docker
124
+ async def test_browser_use(run_v1, tmp_path):
125
+ """The browser_use harness runs in an explicitly browser-capable runtime."""
126
+ image = (
127
+ "mcr.microsoft.com/playwright/python:v1.61.0-noble@"
128
+ "sha256:a9731514f24121d1dcd25d58d0a38146646d290a5998fd80d3e533e7b5e21c69"
129
+ )
130
+ (trace,) = await run_v1(
131
+ "echo-v1",
132
+ harness="browser_use",
133
+ runtime={"type": "docker", "image": image},
134
+ output_dir=tmp_path,
135
+ max_turns=2,
136
+ )
137
+ assert trace.ok
138
+ assert trace.reward == 1.0
139
+
140
+
121
141
  @pytest.mark.e2e
122
142
  @pytest.mark.parametrize("harness_runtime", USER_RUNTIMES, indirect=True)
123
143
  async def test_user(run_v1, harness_runtime, tmp_path):
@@ -31,7 +31,7 @@ from verifiers.v1.cli.resolve import narrow_taskset_config
31
31
  from verifiers.v1.configs.agent import WireAgentConfig
32
32
  from verifiers.v1.configs.cli.replay import ReplayConfig
33
33
  from verifiers.v1.state import state_cls
34
- from verifiers.v1.task import Task, WireTaskData, task_data_cls
34
+ from verifiers.v1.task import Task, WireTaskData
35
35
  from verifiers.v1.trace import Trace
36
36
  from verifiers.v1.utils.interrupt import install_interrupt
37
37
  from verifiers.v1.utils.logging import setup_logging
@@ -76,7 +76,7 @@ async def run_replay(config: ReplayConfig, source: Path, out: Path) -> list[Trac
76
76
  "score() — multi-agent runs don't support replay"
77
77
  )
78
78
  task_cls = vf.task_type(config.taskset.id)
79
- data_cls = task_data_cls(task_cls)
79
+ data_cls = task_cls.data_type()
80
80
  # `WireTaskData` reads any taskset's saved task without importing its Task type.
81
81
  # An episode may hold no traces (its env hooks failed before any agent ran);
82
82
  # there's nothing to re-score, so it drops out in the flatten. Each kept trace
@@ -1,4 +1,8 @@
1
1
  from verifiers.v1.harnesses.bash import BashHarness, BashHarnessConfig
2
+ from verifiers.v1.harnesses.browser_use import (
3
+ BrowserUseHarness,
4
+ BrowserUseHarnessConfig,
5
+ )
2
6
  from verifiers.v1.harnesses.claude_code import (
3
7
  ClaudeCodeHarness,
4
8
  ClaudeCodeHarnessConfig,
@@ -18,6 +22,8 @@ from verifiers.v1.harnesses.terminus_2 import Terminus2Harness, Terminus2Harness
18
22
  __all__ = [
19
23
  "BashHarness",
20
24
  "BashHarnessConfig",
25
+ "BrowserUseHarness",
26
+ "BrowserUseHarnessConfig",
21
27
  "ClaudeCodeHarness",
22
28
  "ClaudeCodeHarnessConfig",
23
29
  "CodexHarness",
@@ -0,0 +1,6 @@
1
+ from verifiers.v1.harnesses.browser_use.harness import (
2
+ BrowserUseHarness,
3
+ BrowserUseHarnessConfig,
4
+ )
5
+
6
+ __all__ = ["BrowserUseHarness", "BrowserUseHarnessConfig"]
@@ -0,0 +1,125 @@
1
+ import json
2
+ from pathlib import Path
3
+ from typing import Literal
4
+
5
+ from pydantic import model_validator
6
+
7
+ from verifiers.v1.clients import ModelContext
8
+ from verifiers.v1.configs.harness import HarnessConfig
9
+ from verifiers.v1.dialects.chat import message_to_wire
10
+ from verifiers.v1.harness import Harness
11
+ from verifiers.v1.runtimes import ProgramResult, Runtime
12
+ from verifiers.v1.task import TaskData
13
+ from verifiers.v1.trace import Trace
14
+
15
+ PROGRAM_SOURCE = (Path(__file__).resolve().parent / "program.py").read_text()
16
+
17
+ # The helper names and persistence rules the model needs to use the local tool.
18
+ BROWSER_SYSTEM_PROMPT = """You are a browser automation agent. Your `browser` tool executes Python code that controls a real Chromium over CDP through browser-harness; its helpers are pre-imported.
19
+
20
+ Rules of the tool:
21
+ - Each call runs in a fresh Python process: variables do NOT persist between calls. The browser does persist — tabs, cookies, and page state carry over.
22
+ - Use print() for anything you want to see. Filter in Python before printing; a raw AX tree or DOM dump is huge.
23
+ - The first navigation is new_tab(url), not goto_url(url). After navigating, call wait_for_load().
24
+
25
+ Core helpers: new_tab(url), goto_url(url), page_info(), js(expression), click_at_xy(x, y), type_text(text), press_key(key), fill_input(selector, text), scroll(x, y, dy), wait_for_load(), wait_for_element(selector), wait_for_network_idle(), list_tabs(), switch_tab(target), close_tab(), ensure_real_tab(), capture_screenshot(path), upload_file(selector, path), and raw cdp("Domain.method", ...).
26
+
27
+ Finding elements: prefer the accessibility tree over screenshots. cdp("Accessibility.getFullAXTree")["nodes"] has every element's role, name, and backendDOMNodeId — filter in Python before printing. For coordinates: q = cdp("DOM.getBoxModel", backendNodeId=n)["model"]["content"]; x, y = sum(q[0::2])/4, sum(q[1::2])/4, then click_at_xy(x, y) and verify with a targeted js(...) or page_info() check. Fall back to js(...) over the DOM when the AX tree lacks the element."""
28
+
29
+
30
+ class BrowserUseHarnessConfig(HarnessConfig):
31
+ browser: Literal["chromium", "cdp"] = "chromium"
32
+ """`chromium` launches locally; `cdp` attaches to `cdp_url` without owning it."""
33
+
34
+ cdp_url: str | None = None
35
+ """Rollout-scoped HTTP or WebSocket endpoint used with `browser = "cdp"`."""
36
+
37
+ @model_validator(mode="after")
38
+ def _require_cdp_url_iff_cdp(self) -> "BrowserUseHarnessConfig":
39
+ if self.browser == "cdp" and not self.cdp_url:
40
+ raise ValueError(
41
+ "browser='cdp' needs cdp_url set to a CDP endpoint to attach to"
42
+ )
43
+ if self.browser != "cdp" and self.cdp_url:
44
+ raise ValueError(
45
+ f"cdp_url is only valid with browser='cdp', not browser={self.browser!r}"
46
+ )
47
+ return self
48
+
49
+
50
+ class BrowserUseHarness(Harness[BrowserUseHarnessConfig]):
51
+ APPENDS_SYSTEM_PROMPT = True
52
+ SUPPORTS_MCP = True
53
+ SUPPORTS_RESUME = True
54
+ # The browser tool executes model-authored Python through a third-party daemon.
55
+ NEEDS_CONTAINER = True
56
+
57
+ async def setup(self, runtime: Runtime) -> None:
58
+ await runtime.prepare_uv_script(PROGRAM_SOURCE, self.config.resolved_env)
59
+
60
+ async def launch(
61
+ self,
62
+ ctx: ModelContext,
63
+ trace: Trace,
64
+ runtime: Runtime,
65
+ endpoint: str,
66
+ secret: str,
67
+ mcp_urls: dict[str, str],
68
+ data: TaskData,
69
+ ) -> ProgramResult:
70
+ system_prompt, prompt = self.resolve_prompt(data)
71
+ system_prompt = "\n\n".join(
72
+ p for p in (BROWSER_SYSTEM_PROMPT, system_prompt) if p
73
+ )
74
+ # Default resume replays the transcript. If there was no task system
75
+ # prompt, that transcript already contains this harness prompt.
76
+ replaying_browser_prompt = (
77
+ data.system_prompt is None
78
+ and prompt is not None
79
+ and not isinstance(prompt, str)
80
+ and any(
81
+ message.role == "system" and message.content == BROWSER_SYSTEM_PROMPT
82
+ for message in prompt
83
+ )
84
+ )
85
+ env = {**self.config.resolved_env}
86
+ state = f".vf-browser-{trace.id}"
87
+ args = [
88
+ f"--base-url={endpoint}",
89
+ f"--api-key={secret}",
90
+ f"--model={ctx.model}",
91
+ f"--browser={self.config.browser}",
92
+ # A resumed segment reuses this trace's browser and profile.
93
+ f"--state-dir={state}",
94
+ ]
95
+ if not replaying_browser_prompt:
96
+ args.append(f"--system-prompt={system_prompt}")
97
+ if self.config.cdp_url:
98
+ args.append(f"--cdp-url={self.config.cdp_url}")
99
+ if mcp_urls:
100
+ # The program connects to the tool servers over HTTP; hand it a standard
101
+ # `mcpServers` URL config (the `mcp` client itself comes from the uv deps).
102
+ args.append(
103
+ "--mcp-config="
104
+ + json.dumps(
105
+ {
106
+ "mcpServers": {
107
+ name: {"url": url} for name, url in mcp_urls.items()
108
+ }
109
+ }
110
+ )
111
+ )
112
+ if isinstance(prompt, str):
113
+ args.append(f"--prompt={prompt}")
114
+ elif prompt is not None:
115
+ # Base64 images can exceed exec limits, so hand Messages off through a file.
116
+ path = f".vf-initial-messages-{trace.id}.json"
117
+ await runtime.write(
118
+ path,
119
+ json.dumps([message_to_wire(m) for m in prompt]).encode(),
120
+ )
121
+ args.append(f"--initial-messages-file={path}")
122
+ program = await runtime.prepare_uv_script(
123
+ PROGRAM_SOURCE, self.config.resolved_env
124
+ )
125
+ return await runtime.run_program([*program, *args], env)
@@ -0,0 +1,402 @@
1
+ # /// script
2
+ # requires-python = ">=3.10"
3
+ # dependencies = [
4
+ # "browser-harness==0.1.8",
5
+ # "openai",
6
+ # "mcp>=1.24.0,<2",
7
+ # "httpx",
8
+ # "tenacity",
9
+ # ]
10
+ # ///
11
+ """A chat loop whose one local tool drives a real Chromium over CDP.
12
+
13
+ Each tool call pipes the model's code to browser-harness, whose daemon holds the
14
+ CDP connection and pre-imports its page helpers. `chromium` launches and owns a
15
+ local browser; `cdp` attaches to an HTTP or WebSocket endpoint it does not own.
16
+ Trace-scoped state preserves tabs across resume and records owned process IDs.
17
+ """
18
+
19
+ import argparse
20
+ import asyncio
21
+ import json
22
+ import os
23
+ import re
24
+ import shutil
25
+ import subprocess
26
+ import sys
27
+ import time
28
+ import urllib.request
29
+ from contextlib import AsyncExitStack, asynccontextmanager, suppress
30
+ from pathlib import Path
31
+ from typing import Any, cast
32
+ from urllib.parse import urlsplit
33
+
34
+ import httpx
35
+ from openai import AsyncOpenAI
36
+ from tenacity import AsyncRetrying, stop_after_attempt, wait_exponential_jitter
37
+
38
+ MCP_CALL_ATTEMPTS = 6
39
+ MCP_TIMEOUT = httpx.Timeout(600.0, connect=5.0) # the OpenAI SDK client defaults
40
+
41
+ BROWSER_TOOL_TIMEOUT = 3600
42
+ """Matches the bash harness's command timeout."""
43
+
44
+ BROWSER_READY_TIMEOUT = 60
45
+ """The documented Playwright image announced CDP in under one second from a
46
+ cold container; one minute leaves ample runtime startup headroom."""
47
+
48
+ _DEVTOOLS_LINE = re.compile(r"DevTools listening on ws://127\.0\.0\.1:(\d+)/")
49
+
50
+ BROWSER_TOOL = {
51
+ "type": "function",
52
+ "function": {
53
+ "name": "browser",
54
+ "description": (
55
+ "Execute Python code that drives the browser through browser-harness. "
56
+ "Helpers are pre-imported; use print() to see values. Each call runs in "
57
+ "a fresh process: Python variables do not persist between calls, but the "
58
+ "browser (tabs, cookies, page state) does."
59
+ ),
60
+ "parameters": {
61
+ "type": "object",
62
+ "properties": {
63
+ "code": {
64
+ "type": "string",
65
+ "description": "The Python code to execute.",
66
+ }
67
+ },
68
+ "required": ["code"],
69
+ },
70
+ },
71
+ }
72
+
73
+
74
+ def find_browser() -> str:
75
+ """The Chromium binary to launch, where a machine keeps one.
76
+
77
+ `PLAYWRIGHT_BROWSERS_PATH` before PATH: an image that installs browsers
78
+ through Playwright puts nothing on PATH.
79
+ """
80
+ for key in ("BH_CHROME_PATH", "CHROME_PATH"):
81
+ candidate = os.environ.get(key)
82
+ if candidate and os.access(candidate, os.X_OK):
83
+ return candidate
84
+ registry = os.environ.get("PLAYWRIGHT_BROWSERS_PATH")
85
+ if registry:
86
+ builds = sorted(Path(registry).glob("chromium-*/chrome-linux*/chrome"))
87
+ if builds:
88
+ return str(builds[-1])
89
+ for name in (
90
+ "google-chrome-stable",
91
+ "google-chrome",
92
+ "chromium",
93
+ "chromium-browser",
94
+ ):
95
+ found = shutil.which(name)
96
+ if found:
97
+ return found
98
+ raise SystemExit(
99
+ "no Chromium/Chrome found; run on a browser-capable image "
100
+ "(e.g. mcr.microsoft.com/playwright/python) or set BH_CHROME_PATH"
101
+ )
102
+
103
+
104
+ def _endpoint_alive(endpoint: str) -> bool:
105
+ try:
106
+ # browser-harness uses five seconds for this same DevTools HTTP probe.
107
+ urllib.request.urlopen(f"{endpoint}/json/version", timeout=5).close()
108
+ return True
109
+ except OSError:
110
+ return False
111
+
112
+
113
+ def ensure_chromium(state_dir: Path) -> str:
114
+ """Reuse this trace's live Chromium or launch it."""
115
+ endpoint_file = state_dir / "cdp-endpoint"
116
+ if endpoint_file.exists():
117
+ endpoint = endpoint_file.read_text().strip()
118
+ if endpoint and _endpoint_alive(endpoint):
119
+ return endpoint
120
+
121
+ profile = state_dir / "profile"
122
+ profile.mkdir(parents=True, exist_ok=True)
123
+ log = state_dir / "browser.log"
124
+ with open(log, "wb") as stderr:
125
+ browser = subprocess.Popen(
126
+ [
127
+ find_browser(),
128
+ "--remote-debugging-port=0",
129
+ f"--user-data-dir={profile}",
130
+ "--headless",
131
+ "--no-first-run",
132
+ "--no-default-browser-check",
133
+ "--disable-dev-shm-usage",
134
+ "--no-sandbox",
135
+ ],
136
+ stdout=subprocess.DEVNULL,
137
+ stderr=stderr,
138
+ stdin=subprocess.DEVNULL,
139
+ start_new_session=True,
140
+ )
141
+ deadline = time.monotonic() + BROWSER_READY_TIMEOUT
142
+ while time.monotonic() < deadline and browser.poll() is None:
143
+ output = log.read_text(errors="replace")
144
+ if match := _DEVTOOLS_LINE.search(output):
145
+ endpoint = f"http://127.0.0.1:{match.group(1)}"
146
+ endpoint_file.write_text(endpoint)
147
+ return endpoint
148
+ time.sleep(0.1)
149
+ if browser.poll() is None:
150
+ browser.kill()
151
+ browser.wait()
152
+ tail = log.read_text(errors="replace")[-2000:]
153
+ raise SystemExit(
154
+ f"browser did not announce a DevTools port within {BROWSER_READY_TIMEOUT}s: "
155
+ f"{tail or '<no browser output>'}"
156
+ )
157
+
158
+
159
+ def run_browser(code: str, env: dict[str, str]) -> str:
160
+ """Run model code through the pinned browser-harness CLI."""
161
+ try:
162
+ result = subprocess.run(
163
+ [sys.executable, "-m", "browser_harness.run"],
164
+ input=code,
165
+ capture_output=True,
166
+ text=True,
167
+ timeout=BROWSER_TOOL_TIMEOUT,
168
+ env=env,
169
+ check=False,
170
+ )
171
+ return (result.stdout + result.stderr) or "(no output)"
172
+ except Exception as e: # noqa: BLE001 - tool failures are returned to the model
173
+ return f"error: {e}"
174
+
175
+
176
+ async def chat(
177
+ client: AsyncOpenAI,
178
+ model: str,
179
+ messages: list[dict[str, Any]],
180
+ tools: list[dict[str, Any]],
181
+ ):
182
+ completion = await client.chat.completions.create(
183
+ model=model,
184
+ messages=cast(Any, messages),
185
+ tools=cast(Any, tools or None),
186
+ )
187
+ return completion.choices[0].message
188
+
189
+
190
+ @asynccontextmanager
191
+ async def mcp_session(spec: dict):
192
+ """One fresh streamable-HTTP session to an MCP server, opened and closed within the caller's
193
+ task so AnyIO cancellation scopes stay correctly nested. A teardown failure after the body
194
+ completed is swallowed — the result is already in hand, and closing noise must not fail (or
195
+ replay) an already-answered call."""
196
+ from mcp import ClientSession
197
+ from mcp.client.streamable_http import (
198
+ create_mcp_http_client,
199
+ streamable_http_client,
200
+ )
201
+
202
+ stack = AsyncExitStack()
203
+ try:
204
+ http_client = await stack.enter_async_context(
205
+ create_mcp_http_client(
206
+ headers=spec.get("headers") or None, timeout=MCP_TIMEOUT
207
+ )
208
+ )
209
+ read, write, *_ = await stack.enter_async_context(
210
+ streamable_http_client(spec["url"], http_client=http_client)
211
+ )
212
+ session = await stack.enter_async_context(ClientSession(read, write))
213
+ await session.initialize()
214
+ yield session
215
+ finally:
216
+ with suppress(Exception):
217
+ await stack.aclose()
218
+
219
+
220
+ async def with_retry(call):
221
+ """Run one session-scoped operation, retrying transient failures with backoff. A call whose
222
+ response was lost may be replayed — MCP has no idempotency key, so tools should tolerate
223
+ at-least-once delivery (a tool that fails reports through its result, not an exception)."""
224
+ async for attempt in AsyncRetrying(
225
+ stop=stop_after_attempt(MCP_CALL_ATTEMPTS),
226
+ wait=wait_exponential_jitter(initial=0.5, max=30),
227
+ reraise=True,
228
+ ):
229
+ with attempt:
230
+ return await call()
231
+
232
+
233
+ async def connect_mcp(
234
+ config: dict, reserved: set[str]
235
+ ) -> tuple[list[dict], dict, dict]:
236
+ """Enumerate each configured MCP server's tools (a streamable-HTTP `url`); return (tool schemas,
237
+ dispatch mapping `<server>_<tool>` -> (server name, raw tool name), servers mapping name -> spec).
238
+ No session is held — a stateless-HTTP server is reconnected per call."""
239
+ tool_schemas: list[dict] = []
240
+ dispatch: dict[str, tuple] = {}
241
+ servers: dict[str, dict] = {}
242
+ for name, spec in config.get("mcpServers", {}).items():
243
+ servers[name] = spec
244
+
245
+ async def list_tools(spec: dict = spec):
246
+ async with mcp_session(spec) as session:
247
+ return (await session.list_tools()).tools
248
+
249
+ for tool in await with_retry(list_tools):
250
+ # A server named "" (TOOL_PREFIX = None) advertises its tools bare.
251
+ full = f"{name}_{tool.name}" if name else tool.name
252
+ if full in reserved or full in dispatch:
253
+ raise ValueError(
254
+ f"duplicate tool name {full!r}; keep MCP tool names qualified"
255
+ )
256
+ tool_schemas.append(
257
+ {
258
+ "type": "function",
259
+ "function": {
260
+ "name": full,
261
+ "description": tool.description or "",
262
+ "parameters": tool.inputSchema,
263
+ },
264
+ }
265
+ )
266
+ dispatch[full] = (name, tool.name)
267
+ return tool_schemas, dispatch, servers
268
+
269
+
270
+ def mcp_content_to_chat_content(blocks) -> str | list[dict]:
271
+ parts = []
272
+ for block in blocks:
273
+ if block.type == "text":
274
+ parts.append({"type": "text", "text": block.text})
275
+ elif block.type == "image":
276
+ url = f"data:{block.mimeType};base64,{block.data}"
277
+ parts.append({"type": "image_url", "image_url": {"url": url}})
278
+ else:
279
+ parts.append({"type": "text", "text": str(block)})
280
+ if not parts:
281
+ return str(blocks)
282
+ if all(part["type"] == "text" for part in parts):
283
+ return "\n".join(str(part["text"]) for part in parts)
284
+ return parts
285
+
286
+
287
+ async def call_mcp(
288
+ servers: dict, dispatch: dict, name: str, arguments: dict
289
+ ) -> str | list[dict]:
290
+ """Call a tool on a fresh session per attempt — see `with_retry` for the replay semantics.
291
+ The result is converted outside the retry so a conversion failure fails once."""
292
+ server_name, raw = dispatch[name]
293
+
294
+ async def call():
295
+ async with mcp_session(servers[server_name]) as session:
296
+ return await session.call_tool(raw, arguments)
297
+
298
+ result = await with_retry(call)
299
+ return mcp_content_to_chat_content(result.content)
300
+
301
+
302
+ def parse_args() -> argparse.Namespace:
303
+ parser = argparse.ArgumentParser()
304
+ parser.add_argument("--base-url", required=True)
305
+ parser.add_argument("--api-key", required=True)
306
+ parser.add_argument("--model", required=True)
307
+ parser.add_argument("--state-dir", required=True)
308
+ parser.add_argument("--browser", default="chromium")
309
+ parser.add_argument("--cdp-url", default="")
310
+ parser.add_argument("--system-prompt", default="")
311
+ parser.add_argument("--prompt", default="")
312
+ parser.add_argument("--initial-messages-file", default="")
313
+ parser.add_argument("--mcp-config", default="")
314
+ return parser.parse_args()
315
+
316
+
317
+ async def main() -> None:
318
+ args = parse_args()
319
+ initial = []
320
+ if args.initial_messages_file:
321
+ path = Path(args.initial_messages_file)
322
+ payload = path.read_bytes()
323
+ path.unlink()
324
+ initial = json.loads(payload)
325
+ state_dir = Path(args.state_dir)
326
+ state_dir.mkdir(parents=True, exist_ok=True)
327
+ endpoint = (
328
+ ensure_chromium(state_dir) if args.browser == "chromium" else args.cdp_url
329
+ )
330
+ browser_env = {
331
+ **os.environ,
332
+ "BH_HOME": str(state_dir / "bh-home"),
333
+ "BH_TELEMETRY": "0",
334
+ (
335
+ "BU_CDP_WS" if urlsplit(endpoint).scheme in {"ws", "wss"} else "BU_CDP_URL"
336
+ ): endpoint,
337
+ }
338
+ client = AsyncOpenAI(base_url=args.base_url, api_key=args.api_key)
339
+ config = json.loads(args.mcp_config or "{}")
340
+ tools = [BROWSER_TOOL]
341
+ reserved = {"browser"}
342
+ mcp_tools, dispatch, servers = (
343
+ await connect_mcp(config, reserved)
344
+ if config.get("mcpServers")
345
+ else ([], {}, {})
346
+ )
347
+ tools += mcp_tools
348
+ messages = (
349
+ [{"role": "system", "content": args.system_prompt}]
350
+ if args.system_prompt
351
+ else []
352
+ )
353
+ if initial:
354
+ messages.extend(initial)
355
+ elif args.prompt:
356
+ messages.append({"role": "user", "content": args.prompt})
357
+ while True:
358
+ message = await chat(client, args.model, messages, tools)
359
+ messages.append(message.model_dump(exclude_none=True))
360
+ if not message.tool_calls:
361
+ break
362
+ for call in message.tool_calls:
363
+ name = call.function.name
364
+ try:
365
+ tool_args = json.loads(call.function.arguments or "{}")
366
+ except json.JSONDecodeError as e:
367
+ messages.append(
368
+ {
369
+ "role": "tool",
370
+ "tool_call_id": call.id,
371
+ "content": f"error: invalid JSON in tool arguments ({e}); resend the call with valid JSON",
372
+ }
373
+ )
374
+ continue
375
+ # Valid JSON can still be a non-object (`[]`, `42`, `null`); the `.get(...)` calls
376
+ # below assume a dict, so reject anything else as a tool error rather than crashing.
377
+ if not isinstance(tool_args, dict):
378
+ messages.append(
379
+ {
380
+ "role": "tool",
381
+ "tool_call_id": call.id,
382
+ "content": f"error: tool arguments must be a JSON object, got {type(tool_args).__name__}; resend as an object",
383
+ }
384
+ )
385
+ continue
386
+ if name in dispatch:
387
+ content = await call_mcp(servers, dispatch, name, tool_args)
388
+ elif name == "browser":
389
+ content = await asyncio.to_thread(
390
+ run_browser,
391
+ tool_args.get("code", ""),
392
+ browser_env,
393
+ )
394
+ else:
395
+ content = f"error: unknown tool {name!r}"
396
+ messages.append(
397
+ {"role": "tool", "tool_call_id": call.id, "content": content}
398
+ )
399
+
400
+
401
+ if __name__ == "__main__":
402
+ asyncio.run(main())
@@ -22,7 +22,7 @@ from verifiers.v1.serve.types import (
22
22
  RunRequest,
23
23
  RunResponse,
24
24
  )
25
- from verifiers.v1.task import Task, task_data_cls
25
+ from verifiers.v1.task import Task
26
26
  from verifiers.v1.types import SamplingConfig
27
27
 
28
28
  logger = logging.getLogger(__name__)
@@ -39,7 +39,7 @@ class EnvServer:
39
39
  self.taskset_id = config.taskset.id
40
40
  self.env = load_environment(config)
41
41
  self.task_cls = type(self.env.taskset).task_type()
42
- self.data_cls = task_data_cls(self.task_cls)
42
+ self.data_cls = self.task_cls.data_type()
43
43
  # A dispatched task is its client-side model_dump(): a field excluded from
44
44
  # serialization would vanish on the wire and rebuild silently defaulted, so
45
45
  # refuse to serve such a taskset.