verifiers 0.2.2.dev60__tar.gz → 0.2.2.dev62__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 (429) hide show
  1. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/PKG-INFO +1 -1
  2. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/conftest.py +1 -0
  3. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/conftest.py +4 -3
  4. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/test_e2e.py +1 -0
  5. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/acp/__init__.py +2 -0
  6. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/acp/_runner.py +24 -3
  7. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/__init__.py +3 -0
  8. verifiers-0.2.2.dev62/verifiers/v1/harnesses/openclaw/__init__.py +6 -0
  9. verifiers-0.2.2.dev62/verifiers/v1/harnesses/openclaw/harness.py +352 -0
  10. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/mcp/launch.py +22 -8
  11. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/.gitignore +0 -0
  12. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/LICENSE +0 -0
  13. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/README.md +0 -0
  14. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/pyproject.toml +0 -0
  15. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/__init__.py +0 -0
  16. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_browser_env.py +0 -0
  17. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_build_script.py +0 -0
  18. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_cli_agent_env.py +0 -0
  19. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_client_auth_errors.py +0 -0
  20. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_client_config.py +0 -0
  21. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_client_multimodal_types.py +0 -0
  22. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_composable_env.py +0 -0
  23. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_context_token_metrics.py +0 -0
  24. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_decorator_ranks.py +0 -0
  25. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_endpoint_registry.py +0 -0
  26. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_env_group.py +0 -0
  27. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_env_server.py +0 -0
  28. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_environment.py +0 -0
  29. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_environment_extra.py +0 -0
  30. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_error_chain.py +0 -0
  31. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_eval_display.py +0 -0
  32. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_eval_utils.py +0 -0
  33. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_gepa_cli.py +0 -0
  34. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_gepa_utils.py +0 -0
  35. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_gym_env.py +0 -0
  36. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_harbor_env_mcp.py +0 -0
  37. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_imports.py +0 -0
  38. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_init_script.py +0 -0
  39. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_install_utils.py +0 -0
  40. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_interception_utils.py +0 -0
  41. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_logging.py +0 -0
  42. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_math_rubric.py +0 -0
  43. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_maybe_think_parser.py +0 -0
  44. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_message_utils.py +0 -0
  45. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_message_utils_multimodal.py +0 -0
  46. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_multiturn_env.py +0 -0
  47. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_nemorl_client.py +0 -0
  48. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_openai_chat_completions_token_client.py +0 -0
  49. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_openai_responses_client.py +0 -0
  50. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_opencode_rlm_env.py +0 -0
  51. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_openenv_client.py +0 -0
  52. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_parser.py +0 -0
  53. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_path_utils.py +0 -0
  54. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_per_turn_timing.py +0 -0
  55. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_pricing_utils.py +0 -0
  56. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_prime_plugin.py +0 -0
  57. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_renderer_client.py +0 -0
  58. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_renderer_e2e.py +0 -0
  59. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_rlm_composable_env.py +0 -0
  60. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_rubric.py +0 -0
  61. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_rubric_group.py +0 -0
  62. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_sandbox_debug_env.py +0 -0
  63. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_sandbox_env.py +0 -0
  64. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_sandbox_mixin.py +0 -0
  65. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_save_utils.py +0 -0
  66. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_setup_script.py +0 -0
  67. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_singleturn_env.py +0 -0
  68. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_stateful_tool_env.py +0 -0
  69. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_think_parser.py +0 -0
  70. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_tool_env.py +0 -0
  71. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_tool_utils.py +0 -0
  72. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_trajectory_processing.py +0 -0
  73. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_tui_info_formatting.py +0 -0
  74. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_types.py +0 -0
  75. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/test_xml_parser.py +0 -0
  76. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/counter_tool_v1.py +0 -0
  77. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/duet_v1.py +0 -0
  78. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/echo_acp_resume_v1.py +0 -0
  79. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
  80. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/echo_multi_v0.py +0 -0
  81. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/echo_tool_v1.py +0 -0
  82. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
  83. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/echo_v0.py +0 -0
  84. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/echo_v1.py +0 -0
  85. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/pyproject.toml +0 -0
  86. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
  87. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/test_color_codeword_tasks.py +0 -0
  88. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/test_configs.py +0 -0
  89. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/test_envs.py +0 -0
  90. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/test_graph.py +0 -0
  91. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/test_judges.py +0 -0
  92. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/test_legacy.py +0 -0
  93. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/test_scoring.py +0 -0
  94. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/test_taskset.py +0 -0
  95. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/tests/v1/test_trace.py +0 -0
  96. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/__init__.py +0 -0
  97. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/__init__.py +0 -0
  98. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/commands/__init__.py +0 -0
  99. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/commands/build.py +0 -0
  100. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/commands/eval.py +0 -0
  101. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/commands/gepa.py +0 -0
  102. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/commands/init.py +0 -0
  103. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/commands/install.py +0 -0
  104. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/commands/setup.py +0 -0
  105. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/plugins/__init__.py +0 -0
  106. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/plugins/prime.py +0 -0
  107. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/cli/tui.py +0 -0
  108. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/clients/__init__.py +0 -0
  109. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/clients/anthropic_messages_client.py +0 -0
  110. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/clients/client.py +0 -0
  111. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
  112. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/clients/openai_chat_completions_client.py +0 -0
  113. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
  114. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/clients/openai_completions_client.py +0 -0
  115. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/clients/openai_responses_client.py +0 -0
  116. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/clients/renderer_client.py +0 -0
  117. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/decorators.py +0 -0
  118. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/__init__.py +0 -0
  119. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/env_group.py +0 -0
  120. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/environment.py +0 -0
  121. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/README.md +0 -0
  122. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/__init__.py +0 -0
  123. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/cli_agent_env.py +0 -0
  124. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/README.md +0 -0
  125. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/__init__.py +0 -0
  126. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/_filter.py +0 -0
  127. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/composable_env.py +0 -0
  128. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/harness.py +0 -0
  129. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
  130. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
  131. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
  132. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
  133. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
  134. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/sandbox_debug_env.py +0 -0
  135. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
  136. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/task.py +0 -0
  137. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
  138. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
  139. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
  140. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
  141. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
  142. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/harbor/cli_gym.py +0 -0
  143. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
  144. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/harbor/terminal_lego.py +0 -0
  145. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
  146. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
  147. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
  148. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
  149. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
  150. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
  151. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
  152. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
  153. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
  154. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
  155. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
  156. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
  157. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
  158. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
  159. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
  160. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
  161. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
  162. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
  163. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
  164. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
  165. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
  166. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
  167. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
  168. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
  169. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
  170. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
  171. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/gym_env.py +0 -0
  172. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
  173. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/harbor_env/env.py +0 -0
  174. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
  175. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/mcp_env.py +0 -0
  176. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/opencode_env.py +0 -0
  177. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
  178. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
  179. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
  180. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/utils/__init__.py +0 -0
  181. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/utils/file_locks.py +0 -0
  182. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
  183. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/README.md +0 -0
  184. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/__init__.py +0 -0
  185. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/browser_env/README.md +0 -0
  186. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
  187. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
  188. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
  189. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
  190. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
  191. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
  192. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/openenv_env.py +0 -0
  193. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
  194. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/integrations/textarena_env.py +0 -0
  195. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/multiturn_env.py +0 -0
  196. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/python_env.py +0 -0
  197. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/sandbox_env.py +0 -0
  198. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/singleturn_env.py +0 -0
  199. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/stateful_tool_env.py +0 -0
  200. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/envs/tool_env.py +0 -0
  201. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/errors.py +0 -0
  202. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/gepa/__init__.py +0 -0
  203. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/gepa/adapter.py +0 -0
  204. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/gepa/config.py +0 -0
  205. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/gepa/display.py +0 -0
  206. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/gepa/gepa_utils.py +0 -0
  207. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/parsers/__init__.py +0 -0
  208. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/parsers/maybe_think_parser.py +0 -0
  209. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/parsers/parser.py +0 -0
  210. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/parsers/think_parser.py +0 -0
  211. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/parsers/xml_parser.py +0 -0
  212. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/rubrics/__init__.py +0 -0
  213. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
  214. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/rubrics/judge_rubric.py +0 -0
  215. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/rubrics/math_rubric.py +0 -0
  216. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/rubrics/rubric.py +0 -0
  217. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/rubrics/rubric_group.py +0 -0
  218. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/scripts/__init__.py +0 -0
  219. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/scripts/build.py +0 -0
  220. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/scripts/eval.py +0 -0
  221. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/scripts/gepa.py +0 -0
  222. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/scripts/init.py +0 -0
  223. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/scripts/install.py +0 -0
  224. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/scripts/setup.py +0 -0
  225. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/scripts/tui.py +0 -0
  226. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/serve/__init__.py +0 -0
  227. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/serve/client/env_client.py +0 -0
  228. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/serve/client/zmq_env_client.py +0 -0
  229. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/serve/server/__init__.py +0 -0
  230. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/serve/server/env_router.py +0 -0
  231. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/serve/server/env_server.py +0 -0
  232. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/serve/server/env_worker.py +0 -0
  233. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/serve/server/zmq_env_server.py +0 -0
  234. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/serve/types.py +0 -0
  235. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/types.py +0 -0
  236. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/__init__.py +0 -0
  237. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/async_utils.py +0 -0
  238. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/client_utils.py +0 -0
  239. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/config_utils.py +0 -0
  240. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/data_utils.py +0 -0
  241. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/display_utils.py +0 -0
  242. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/env_config_utils.py +0 -0
  243. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/env_utils.py +0 -0
  244. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/error_utils.py +0 -0
  245. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/eval_display.py +0 -0
  246. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/eval_utils.py +0 -0
  247. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/heartbeat.py +0 -0
  248. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/import_utils.py +0 -0
  249. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/install_utils.py +0 -0
  250. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/interception_utils.py +0 -0
  251. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/logging_utils.py +0 -0
  252. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/message_utils.py +0 -0
  253. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/metric_utils.py +0 -0
  254. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/path_utils.py +0 -0
  255. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/pricing_utils.py +0 -0
  256. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/process_utils.py +0 -0
  257. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/response_utils.py +0 -0
  258. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/save_utils.py +0 -0
  259. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/serve_utils.py +0 -0
  260. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/thread_utils.py +0 -0
  261. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/threaded_sandbox_client.py +0 -0
  262. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/tool_utils.py +0 -0
  263. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/usage_utils.py +0 -0
  264. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/utils/version_utils.py +0 -0
  265. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/__init__.py +0 -0
  266. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/agent.py +0 -0
  267. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/artifacts.py +0 -0
  268. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/__init__.py +0 -0
  269. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/dashboard/__init__.py +0 -0
  270. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/dashboard/base.py +0 -0
  271. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/dashboard/eval.py +0 -0
  272. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/dashboard/replay.py +0 -0
  273. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/dashboard/validate.py +0 -0
  274. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/debug.py +0 -0
  275. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/eval/__init__.py +0 -0
  276. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/eval/main.py +0 -0
  277. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/eval/resume.py +0 -0
  278. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/eval/runner.py +0 -0
  279. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/gepa.py +0 -0
  280. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/init.py +0 -0
  281. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/output.py +0 -0
  282. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/replay.py +0 -0
  283. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/resolve.py +0 -0
  284. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/serve.py +0 -0
  285. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/cli/validate.py +0 -0
  286. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/clients/__init__.py +0 -0
  287. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/clients/client.py +0 -0
  288. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/clients/config.py +0 -0
  289. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/clients/eval.py +0 -0
  290. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/clients/train.py +0 -0
  291. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/__init__.py +0 -0
  292. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/agent.py +0 -0
  293. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/cli/__init__.py +0 -0
  294. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/cli/debug.py +0 -0
  295. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/cli/env.py +0 -0
  296. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/cli/eval.py +0 -0
  297. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/cli/init.py +0 -0
  298. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/cli/replay.py +0 -0
  299. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/cli/serve.py +0 -0
  300. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/cli/validate.py +0 -0
  301. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/env.py +0 -0
  302. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/harness.py +0 -0
  303. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/judge.py +0 -0
  304. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/legacy.py +0 -0
  305. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/retries.py +0 -0
  306. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/serve.py +0 -0
  307. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/task.py +0 -0
  308. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/configs/taskset.py +0 -0
  309. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/decorators.py +0 -0
  310. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/dialects/__init__.py +0 -0
  311. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/dialects/anthropic.py +0 -0
  312. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/dialects/base.py +0 -0
  313. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/dialects/chat.py +0 -0
  314. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/dialects/responses.py +0 -0
  315. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/env.py +0 -0
  316. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/envs/__init__.py +0 -0
  317. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
  318. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/envs/agentic_judge/env.py +0 -0
  319. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
  320. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/envs/best_of_n/env.py +0 -0
  321. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/envs/single_agent/__init__.py +0 -0
  322. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/envs/single_agent/env.py +0 -0
  323. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/envs/user_sim/__init__.py +0 -0
  324. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/envs/user_sim/env.py +0 -0
  325. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/episode.py +0 -0
  326. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/errors.py +0 -0
  327. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/gepa/__init__.py +0 -0
  328. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/gepa/adapter.py +0 -0
  329. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/gepa/config.py +0 -0
  330. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/gepa/dataset.py +0 -0
  331. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/gepa/reflection.py +0 -0
  332. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/gepa/runner.py +0 -0
  333. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/graph.py +0 -0
  334. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harness.py +0 -0
  335. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/bash/__init__.py +0 -0
  336. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/bash/harness.py +0 -0
  337. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/bash/program.py +0 -0
  338. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/browser_use/__init__.py +0 -0
  339. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/browser_use/harness.py +0 -0
  340. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/browser_use/program.py +0 -0
  341. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
  342. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/claude_code/harness.py +0 -0
  343. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/codex/__init__.py +0 -0
  344. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/codex/harness.py +0 -0
  345. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/hermes_agent/__init__.py +0 -0
  346. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/hermes_agent/harness.py +0 -0
  347. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/hermes_agent/program.py +0 -0
  348. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
  349. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
  350. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
  351. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
  352. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
  353. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/null/__init__.py +0 -0
  354. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/null/harness.py +0 -0
  355. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/null/program.py +0 -0
  356. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/pi/__init__.py +0 -0
  357. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/pi/harness.py +0 -0
  358. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/pool/__init__.py +0 -0
  359. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/pool/harness.py +0 -0
  360. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
  361. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/rlm/harness.py +0 -0
  362. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
  363. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
  364. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
  365. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/interception/__init__.py +0 -0
  366. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/interception/base.py +0 -0
  367. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/interception/pool.py +0 -0
  368. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/interception/server.py +0 -0
  369. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/interception/tunnel/__init__.py +0 -0
  370. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/interception/tunnel/base.py +0 -0
  371. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/interception/tunnel/custom.py +0 -0
  372. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/interception/tunnel/prime.py +0 -0
  373. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/judge.py +0 -0
  374. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/judges/__init__.py +0 -0
  375. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/judges/reference.py +0 -0
  376. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/judges/reference.txt +0 -0
  377. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/judges/rubric.py +0 -0
  378. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/judges/rubric.txt +0 -0
  379. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/legacy.py +0 -0
  380. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/loaders.py +0 -0
  381. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/mcp/__init__.py +0 -0
  382. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/mcp/server.py +0 -0
  383. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/mcp/toolset.py +0 -0
  384. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/push.py +0 -0
  385. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/retries.py +0 -0
  386. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/rollout.py +0 -0
  387. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/runtimes/__init__.py +0 -0
  388. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/runtimes/base.py +0 -0
  389. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/runtimes/docker/__init__.py +0 -0
  390. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/runtimes/docker/egress.py +0 -0
  391. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/runtimes/limiters.py +0 -0
  392. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/runtimes/modal.py +0 -0
  393. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/runtimes/prime.py +0 -0
  394. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/runtimes/subprocess.py +0 -0
  395. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/scoring.py +0 -0
  396. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/serve/__init__.py +0 -0
  397. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/serve/client.py +0 -0
  398. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/serve/pool.py +0 -0
  399. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/serve/server.py +0 -0
  400. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/serve/types.py +0 -0
  401. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/session.py +0 -0
  402. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/state.py +0 -0
  403. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/task.py +0 -0
  404. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/taskset.py +0 -0
  405. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/tasksets/__init__.py +0 -0
  406. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
  407. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
  408. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/tasksets/lean/__init__.py +0 -0
  409. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/tasksets/lean/scoring.py +0 -0
  410. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/tasksets/lean/taskset.py +0 -0
  411. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
  412. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
  413. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
  414. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
  415. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/trace.py +0 -0
  416. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/types.py +0 -0
  417. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/__init__.py +0 -0
  418. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/aio.py +0 -0
  419. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/compile.py +0 -0
  420. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/format.py +0 -0
  421. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/generic.py +0 -0
  422. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/git.py +0 -0
  423. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/image.py +0 -0
  424. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/install.py +0 -0
  425. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/interrupt.py +0 -0
  426. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/logging.py +0 -0
  427. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/memory.py +0 -0
  428. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/verifiers/v1/utils/sampling.py +0 -0
  429. {verifiers-0.2.2.dev60 → verifiers-0.2.2.dev62}/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.dev60
3
+ Version: 0.2.2.dev62
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
@@ -45,6 +45,7 @@ def pytest_configure(config) -> None:
45
45
  config.addinivalue_line(
46
46
  "markers", "claude_code: v1 e2e cases on the claude-code harness"
47
47
  )
48
+ config.addinivalue_line("markers", "openclaw: v1 e2e cases on the OpenClaw harness")
48
49
  config.addinivalue_line(
49
50
  "markers", "hermes_agent: v1 e2e cases on the hermes-agent harness"
50
51
  )
@@ -25,8 +25,8 @@ Every combination carries its axes' pytest marks, so subsets select with `-m`:
25
25
  uv run pytest tests/v1 -n auto -m modal # only modal (needs local setup)
26
26
 
27
27
  Marks: runtimes `subprocess` / `docker` / `prime` / `modal`, placement `colocated`,
28
- harnesses `null` / `bash` / `rlm` / `kimi_code` / `pi` / `pool` / `codex` / `claude_code` /
29
- `hermes_agent`.
28
+ harnesses `null` / `bash` / `rlm` / `kimi_code` / `pi` / `pool` / `openclaw` / `codex` /
29
+ `claude_code` / `hermes_agent`.
30
30
  A mark is applied per axis, so it selects every case touching that value on ANY axis; for one exact
31
31
  combination use `-k` on the test id (e.g. `-k "harness-in-docker-with-tool-in-subprocess"`).
32
32
  prime/modal provision real remote sandboxes (slow, infra-flaky, need setup), so they're local-only.
@@ -70,7 +70,8 @@ def tool_runtime(request) -> dict:
70
70
 
71
71
 
72
72
  # Built-in harnesses are bundled in the `harnesses` package; the agent CLIs (`rlm` /
73
- # `kimi-code` / `codex` / `claude-code` / `hermes-agent`) install their dependencies at rollout.
73
+ # `kimi-code` / `openclaw` / `codex` / `claude-code` / `hermes-agent`) install their
74
+ # dependencies at rollout.
74
75
  # `compact` (an example harness) and `terminus-2` (drives the host tmux) are excluded from e2e.
75
76
  @pytest.fixture
76
77
  def harness(request) -> str:
@@ -59,6 +59,7 @@ ACP_RESUME_PLACEMENTS = [
59
59
  _pair("kimi-code", "docker", "kimi-code-acp-in-docker"),
60
60
  _pair("pi", "docker", "pi-acp-in-docker"),
61
61
  _pair("pool", "docker", "pool-acp-in-docker"),
62
+ _pair("openclaw", "docker", "openclaw-acp-in-docker"),
62
63
  _pair("pool", "prime", "pool-acp-in-prime"),
63
64
  ]
64
65
 
@@ -33,6 +33,7 @@ class ACP:
33
33
  mcp_urls: dict[str, str] | None = None,
34
34
  system_prompt: str | None = None,
35
35
  session_path: str | None = None,
36
+ allow_empty_tool_reply: bool = False,
36
37
  ) -> ProgramResult:
37
38
  if prompt is None:
38
39
  raise ValueError("ACP requires a prompt")
@@ -47,6 +48,7 @@ class ACP:
47
48
  "mcp_urls": mcp_urls or {},
48
49
  "system_prompt": system_prompt or "",
49
50
  "session_path": session_path,
51
+ "allow_empty_tool_reply": allow_empty_tool_reply,
50
52
  }
51
53
  program = await runtime.prepare_uv_script(
52
54
  ACP_SOURCE, {**env, "UV_FROZEN": "false"}
@@ -28,6 +28,8 @@ from acp.schema import (
28
28
  PermissionOption,
29
29
  RequestPermissionResponse,
30
30
  TextContentBlock,
31
+ ToolCall,
32
+ ToolCallUpdate,
31
33
  )
32
34
 
33
35
 
@@ -35,8 +37,16 @@ class VerifiersClient(Client):
35
37
  def __init__(self) -> None:
36
38
  self.visible_reply = ""
37
39
  self.message_id: str | None = None
40
+ self.tool_calls: dict[str, str] = {}
38
41
 
39
42
  async def session_update(self, session_id: str, update: Any, **kwargs: Any) -> None:
43
+ if isinstance(update, ToolCall):
44
+ self.tool_calls[update.tool_call_id] = update.status or "pending"
45
+ return
46
+ if isinstance(update, ToolCallUpdate):
47
+ if update.status:
48
+ self.tool_calls[update.tool_call_id] = update.status
49
+ return
40
50
  if not isinstance(update, AgentMessageChunk) or not isinstance(
41
51
  update.content, TextContentBlock
42
52
  ):
@@ -168,13 +178,24 @@ async def run_client(config: dict) -> None:
168
178
  raise ValueError("ACP prompt has no content")
169
179
  client.visible_reply = ""
170
180
  client.message_id = None
181
+ client.tool_calls = {}
171
182
  try:
172
- await connection.prompt(session_id=session_id, prompt=prompt)
183
+ response = await connection.prompt(session_id=session_id, prompt=prompt)
173
184
  except RequestError as error:
174
185
  detail = error.data.get("details") if isinstance(error.data, dict) else None
175
186
  raise RuntimeError(detail or str(error)) from error
176
- if not client.visible_reply.strip():
177
- raise RuntimeError("ACP agent produced no visible reply")
187
+ tool_statuses = list(client.tool_calls.values())
188
+ completed_tool_turn = (
189
+ config["allow_empty_tool_reply"]
190
+ and response.stop_reason == "end_turn"
191
+ and bool(tool_statuses)
192
+ and all(status in ("completed", "failed") for status in tool_statuses)
193
+ )
194
+ if not client.visible_reply.strip() and not completed_tool_turn:
195
+ raise RuntimeError(
196
+ "ACP agent produced no visible reply "
197
+ f"(stop_reason={response.stop_reason}, tool_statuses={tool_statuses})"
198
+ )
178
199
  sys.stdout.write(client.visible_reply)
179
200
  if session_path and is_new:
180
201
  session_path.parent.mkdir(parents=True, exist_ok=True)
@@ -18,6 +18,7 @@ from verifiers.v1.harnesses.mini_swe_agent import (
18
18
  MiniSWEAgentHarnessConfig,
19
19
  )
20
20
  from verifiers.v1.harnesses.null import NullHarness, NullHarnessConfig
21
+ from verifiers.v1.harnesses.openclaw import OpenClawHarness, OpenClawHarnessConfig
21
22
  from verifiers.v1.harnesses.pi import PiHarness, PiHarnessConfig
22
23
  from verifiers.v1.harnesses.pool import PoolHarness, PoolHarnessConfig
23
24
  from verifiers.v1.harnesses.rlm import RLMHarness, RLMHarnessConfig
@@ -40,6 +41,8 @@ __all__ = [
40
41
  "MiniSWEAgentHarnessConfig",
41
42
  "NullHarness",
42
43
  "NullHarnessConfig",
44
+ "OpenClawHarness",
45
+ "OpenClawHarnessConfig",
43
46
  "PiHarness",
44
47
  "PiHarnessConfig",
45
48
  "PoolHarness",
@@ -0,0 +1,6 @@
1
+ from verifiers.v1.harnesses.openclaw.harness import (
2
+ OpenClawHarness,
3
+ OpenClawHarnessConfig,
4
+ )
5
+
6
+ __all__ = ["OpenClawHarness", "OpenClawHarnessConfig"]
@@ -0,0 +1,352 @@
1
+ """Run OpenClaw's Gateway-backed ACP agent against interception."""
2
+
3
+ import asyncio
4
+ import fcntl
5
+ import json
6
+ import logging
7
+ import secrets
8
+ import shlex
9
+ from collections.abc import AsyncIterator
10
+ from contextlib import asynccontextmanager
11
+ from pathlib import Path
12
+
13
+ from pydantic import Field
14
+
15
+ from verifiers.v1.acp import ACP
16
+ from verifiers.v1.clients import ModelContext
17
+ from verifiers.v1.configs.harness import HarnessConfig
18
+ from verifiers.v1.harness import Harness
19
+ from verifiers.v1.runtimes import DockerRuntime, ProgramResult, Runtime
20
+ from verifiers.v1.task import TaskData
21
+ from verifiers.v1.trace import Trace
22
+
23
+ logger = logging.getLogger(__name__)
24
+
25
+ # OpenClaw and its bundled Node runtime exceed the small /tmp tmpfs in some VMs.
26
+ OPENCLAW_DIR = "/var/tmp/vf-openclaw-{version}"
27
+ OPENCLAW_BIN = f"{OPENCLAW_DIR}/bin/openclaw"
28
+ INSTALL = r"""
29
+ set -e
30
+ command -v curl >/dev/null || (apt-get update -qq && apt-get install -y -qq curl ca-certificates >/dev/null)
31
+ curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install-cli.sh | bash -s -- --prefix {dir} --version {version} --no-onboard
32
+ """
33
+
34
+ OPENCLAW_ACP = ACP()
35
+
36
+
37
+ @asynccontextmanager
38
+ async def _gateway_start_lock(runtime: Runtime) -> AsyncIterator[None]:
39
+ if not isinstance(runtime, DockerRuntime) or runtime.network_restricted:
40
+ yield
41
+ return
42
+ # Unrestricted Docker containers share the host network across server workers.
43
+ with Path("/tmp/vf-openclaw-gateway.lock").open("a") as lock: # noqa: ASYNC230
44
+ while True:
45
+ try:
46
+ fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
47
+ break
48
+ except BlockingIOError:
49
+ await asyncio.sleep(0.1)
50
+ try:
51
+ yield
52
+ finally:
53
+ fcntl.flock(lock, fcntl.LOCK_UN)
54
+
55
+
56
+ class OpenClawHarnessConfig(HarnessConfig):
57
+ version: str = Field(default="2026.7.1-2", pattern=r"^[A-Za-z0-9._+-]+$")
58
+ """OpenClaw release to install, pinned for reproducibility."""
59
+ use_bundled_skill: bool = True
60
+ """Enable OpenClaw's bundled skill catalog in addition to uploaded harness skills."""
61
+
62
+
63
+ class OpenClawHarness(Harness[OpenClawHarnessConfig]):
64
+ APPENDS_SYSTEM_PROMPT = True
65
+ SUPPORTS_MCP = True
66
+ SUPPORTS_RESUME = True
67
+ SUPPORTS_SKILLS = True
68
+
69
+ async def setup(self, runtime: Runtime) -> None:
70
+ if not hasattr(self, "_staged_skills_dir"):
71
+ self._staged_skills_dir = (
72
+ f".vf-openclaw/staged-skills-{secrets.token_hex(8)}"
73
+ )
74
+ self._skills_setup_lock = asyncio.Lock()
75
+ if self.config.skills:
76
+ async with self._skills_setup_lock:
77
+ # A complete tree is immutable, so concurrent setups can safely reuse it.
78
+ ready_path = f"{self._staged_skills_dir}/.ready"
79
+ ready = await runtime.run(["test", "-f", ready_path], {})
80
+ if ready.exit_code != 0:
81
+ cleared = await runtime.run(
82
+ ["rm", "-rf", self._staged_skills_dir], {}
83
+ )
84
+ if cleared.exit_code != 0:
85
+ raise RuntimeError(
86
+ "failed to clear OpenClaw skills: "
87
+ f"{cleared.stderr.strip()[-500:]}"
88
+ )
89
+ await self.install_skills(runtime, self._staged_skills_dir)
90
+ await runtime.write(ready_path, b"")
91
+ directory = OPENCLAW_DIR.format(version=self.config.version)
92
+ binary = OPENCLAW_BIN.format(version=self.config.version)
93
+ script = INSTALL.replace("{version}", self.config.version).replace(
94
+ "{dir}", directory
95
+ )
96
+ ensure = shlex.quote(f"[ -x {binary} ] || ({script})")
97
+ guarded = (
98
+ f"mkdir -p {directory} && "
99
+ f'"$(command -v flock || command -v lockf)" {directory}/install.lock '
100
+ f"bash -o pipefail -c {ensure}"
101
+ )
102
+ logger.info("openclaw: ensuring OpenClaw %s is installed", self.config.version)
103
+ result = await runtime.run(["sh", "-c", guarded], self.config.resolved_env)
104
+ if result.exit_code != 0:
105
+ detail = (result.stderr or result.stdout).strip()[-500:]
106
+ raise RuntimeError(f"OpenClaw install failed: {detail}")
107
+ await OPENCLAW_ACP.setup(self, runtime)
108
+
109
+ async def launch(
110
+ self,
111
+ ctx: ModelContext,
112
+ trace: Trace,
113
+ runtime: Runtime,
114
+ endpoint: str,
115
+ secret: str,
116
+ mcp_urls: dict[str, str],
117
+ data: TaskData,
118
+ ) -> ProgramResult:
119
+ system_prompt, prompt = self.resolve_prompt(data)
120
+ reasoning = ctx.sampling.reasoning_effort not in (
121
+ None,
122
+ "none",
123
+ ) or ctx.model.rsplit("/", 1)[-1].startswith(("gpt-5", "o1", "o3", "o4"))
124
+ directory = OPENCLAW_DIR.format(version=self.config.version)
125
+ state_dir = f".vf-openclaw/{trace.id}"
126
+ config_path = f"{state_dir}/openclaw.json"
127
+ skills_dir = f"{state_dir}/skills"
128
+ config = {
129
+ "gateway": {"mode": "local"},
130
+ "agents": {
131
+ "defaults": {
132
+ "workspace": ".",
133
+ "skipBootstrap": True,
134
+ "sandbox": {"mode": "off"},
135
+ "model": {"primary": f"intercept/{ctx.model}"},
136
+ }
137
+ },
138
+ "tools": {
139
+ "profile": "coding",
140
+ "fs": {"workspaceOnly": True},
141
+ "exec": {"host": "gateway", "mode": "full"},
142
+ "deny": self.config.disabled_tools or [],
143
+ },
144
+ "models": {
145
+ "mode": "replace",
146
+ "providers": {
147
+ "intercept": {
148
+ "baseUrl": endpoint,
149
+ "apiKey": "${OPENCLAW_INTERCEPT_KEY}",
150
+ "api": "openai-responses",
151
+ "authHeader": True,
152
+ "models": [
153
+ {
154
+ "id": ctx.model,
155
+ "name": ctx.model,
156
+ "reasoning": reasoning,
157
+ "input": ["text", "image"],
158
+ }
159
+ ],
160
+ }
161
+ },
162
+ },
163
+ "mcp": {
164
+ "servers": {
165
+ name: {
166
+ "url": url,
167
+ "transport": "streamable-http",
168
+ "connectionTimeoutMs": 60_000,
169
+ "requestTimeoutMs": 600_000,
170
+ }
171
+ for name, url in mcp_urls.items()
172
+ }
173
+ },
174
+ }
175
+ created = await runtime.run(["mkdir", "-p", state_dir], {})
176
+ if created.exit_code != 0:
177
+ raise RuntimeError(
178
+ f"OpenClaw state directory failed: {created.stderr.strip()[-500:]}"
179
+ )
180
+ if self.config.skills:
181
+ exists = await runtime.run(["test", "-d", skills_dir], {})
182
+ if exists.exit_code != 0:
183
+ copied = await runtime.run(
184
+ ["cp", "-R", self._staged_skills_dir, skills_dir], {}
185
+ )
186
+ if copied.exit_code != 0:
187
+ raise RuntimeError(
188
+ f"failed to stage OpenClaw skills: {copied.stderr.strip()[-500:]}"
189
+ )
190
+ config["skills"] = {"load": {"extraDirs": [skills_dir]}}
191
+ if not self.config.use_bundled_skill:
192
+ # OpenClaw treats an empty allowlist as all; a no-match key disables the catalog.
193
+ config.setdefault("skills", {})["allowBundled"] = ["__none__"]
194
+ await runtime.write(config_path, json.dumps(config).encode())
195
+
196
+ binary = OPENCLAW_BIN.format(version=self.config.version)
197
+ node = f"{directory}/tools/node/bin/node"
198
+ allocate_port = shlex.join(
199
+ [
200
+ node,
201
+ "-e",
202
+ (
203
+ 'const net=require("node:net");const server=net.createServer();'
204
+ 'server.listen(0,"127.0.0.1",()=>{'
205
+ "process.stdout.write(String(server.address().port));server.close();});"
206
+ ),
207
+ ]
208
+ )
209
+ log_path = f"{state_dir}/gateway.log"
210
+ pid_path = f"{state_dir}/gateway.pid"
211
+ env = {
212
+ **self.config.resolved_env,
213
+ "OPENCLAW_CONFIG_PATH": config_path,
214
+ "OPENCLAW_STATE_DIR": state_dir,
215
+ "OPENCLAW_INTERCEPT_KEY": secret,
216
+ "OPENCLAW_HIDE_BANNER": "1",
217
+ "OPENCLAW_SUPPRESS_NOTES": "1",
218
+ "NO_COLOR": "1",
219
+ }
220
+ async with _gateway_start_lock(runtime):
221
+ allocated = await runtime.run(["sh", "-c", allocate_port], {})
222
+ if allocated.exit_code != 0:
223
+ raise RuntimeError(
224
+ f"OpenClaw port allocation failed: {allocated.stderr.strip()[-500:]}"
225
+ )
226
+ gateway_port = allocated.stdout.strip()
227
+ port_probe = shlex.join(
228
+ [
229
+ node,
230
+ "-e",
231
+ (
232
+ 'const net=require("node:net");'
233
+ f'const socket=net.connect({{host:"127.0.0.1",port:{gateway_port}}});'
234
+ 'socket.on("connect",()=>socket.end());'
235
+ 'socket.on("error",()=>process.exit(1));'
236
+ ),
237
+ ]
238
+ )
239
+ await runtime.run_background(
240
+ [
241
+ "sh",
242
+ "-c",
243
+ (
244
+ f"echo $$ >{shlex.quote(pid_path)}; "
245
+ f"exec {shlex.quote(binary)} gateway run "
246
+ f"--port {shlex.quote(gateway_port)} --bind loopback "
247
+ f"--auth token --token {shlex.quote(trace.id)} "
248
+ "--allow-unconfigured"
249
+ ),
250
+ ],
251
+ env,
252
+ log_path,
253
+ )
254
+ bound = await runtime.run(
255
+ [
256
+ "sh",
257
+ "-c",
258
+ (
259
+ "attempt=0; "
260
+ f"until [ -s {shlex.quote(pid_path)} ] && "
261
+ f'kill -0 "$(cat {shlex.quote(pid_path)})" 2>/dev/null && '
262
+ f"{port_probe} >/dev/null 2>&1; do "
263
+ f"if [ -s {shlex.quote(pid_path)} ] && "
264
+ f'! kill -0 "$(cat {shlex.quote(pid_path)})" 2>/dev/null; then '
265
+ f"tail -100 {shlex.quote(log_path)} >&2; exit 1; fi; "
266
+ "attempt=$((attempt + 1)); "
267
+ f'[ "$attempt" -lt 1200 ] || {{ tail -100 {shlex.quote(log_path)} >&2; exit 1; }}; '
268
+ "sleep 0.1; done"
269
+ ),
270
+ ],
271
+ {},
272
+ )
273
+ if bound.exit_code != 0:
274
+ detail = (bound.stderr or bound.stdout).strip()[-2000:]
275
+ raise RuntimeError(f"OpenClaw gateway failed to bind: {detail}")
276
+ readiness = await runtime.run(
277
+ [
278
+ "sh",
279
+ "-c",
280
+ (
281
+ "attempt=0; "
282
+ f"until [ -s {shlex.quote(pid_path)} ] && "
283
+ f'kill -0 "$(cat {shlex.quote(pid_path)})" 2>/dev/null && '
284
+ f'curl -fsS "http://127.0.0.1:{gateway_port}/healthz" '
285
+ ">/dev/null 2>&1; do "
286
+ f"if [ -s {shlex.quote(pid_path)} ] && "
287
+ f'! kill -0 "$(cat {shlex.quote(pid_path)})" 2>/dev/null; then '
288
+ f"tail -100 {shlex.quote(log_path)} >&2; exit 1; fi; "
289
+ "attempt=$((attempt + 1)); "
290
+ f'[ "$attempt" -lt 120 ] || {{ tail -100 {shlex.quote(log_path)} >&2; exit 1; }}; '
291
+ "sleep 1; done"
292
+ ),
293
+ ],
294
+ {},
295
+ )
296
+ if readiness.exit_code != 0:
297
+ detail = (readiness.stderr or readiness.stdout).strip()[-2000:]
298
+ raise RuntimeError(f"OpenClaw gateway failed to start: {detail}")
299
+ command = [
300
+ "sh",
301
+ "-c",
302
+ (
303
+ "set -eu; "
304
+ f"gateway_pid=$(cat {shlex.quote(pid_path)}); "
305
+ f'trap \'kill "$gateway_pid" 2>/dev/null || true; '
306
+ 'attempt=0; while kill -0 "$gateway_pid" 2>/dev/null && '
307
+ ' [ "$attempt" -lt 50 ]; do attempt=$((attempt + 1)); sleep 0.1; done; '
308
+ 'kill -9 "$gateway_pid" 2>/dev/null || true; '
309
+ 'while kill -0 "$gateway_pid" 2>/dev/null; do sleep 0.1; done; '
310
+ f"rm -f {shlex.quote(pid_path)}' EXIT; "
311
+ f'{shlex.quote(binary)} acp --url "ws://127.0.0.1:{gateway_port}" '
312
+ f"--token {shlex.quote(trace.id)} --no-prefix-cwd"
313
+ ),
314
+ ]
315
+ # OpenClaw rejects ACP per-session MCP declarations; the isolated Gateway
316
+ # config above owns the equivalent task-scoped server definitions.
317
+ return await OPENCLAW_ACP.run(
318
+ runtime,
319
+ env,
320
+ command,
321
+ prompt,
322
+ mcp_urls={},
323
+ system_prompt=system_prompt,
324
+ session_path=f"{state_dir}/acp-session",
325
+ # OpenClaw can end after its final tool completes without a text message.
326
+ allow_empty_tool_reply=True,
327
+ )
328
+
329
+ async def cleanup(self, trace: Trace, runtime: Runtime) -> None:
330
+ state_dir = f".vf-openclaw/{trace.id}"
331
+ pid_path = f"{state_dir}/gateway.pid"
332
+ result = await runtime.run(
333
+ [
334
+ "sh",
335
+ "-c",
336
+ (
337
+ f"if [ -s {shlex.quote(pid_path)} ]; then "
338
+ f"gateway_pid=$(cat {shlex.quote(pid_path)}); "
339
+ 'kill "$gateway_pid" 2>/dev/null || true; '
340
+ 'attempt=0; while kill -0 "$gateway_pid" 2>/dev/null && '
341
+ ' [ "$attempt" -lt 50 ]; do attempt=$((attempt + 1)); sleep 0.1; done; '
342
+ 'kill -9 "$gateway_pid" 2>/dev/null || true; '
343
+ 'while kill -0 "$gateway_pid" 2>/dev/null; do sleep 0.1; done; fi; '
344
+ f"rm -rf {shlex.quote(state_dir)}"
345
+ ),
346
+ ],
347
+ {},
348
+ )
349
+ if result.exit_code != 0:
350
+ raise RuntimeError(
351
+ f"failed to clean up OpenClaw state: {result.stderr.strip()[-500:]}"
352
+ )
@@ -23,7 +23,6 @@ from verifiers.v1.runtimes import (
23
23
  NetworkPolicyConfig,
24
24
  Runtime,
25
25
  make_runtime,
26
- runtime_is_local,
27
26
  )
28
27
  from verifiers.v1.runtimes.base import _ENSURE_UV
29
28
 
@@ -248,6 +247,7 @@ async def serve(
248
247
  *,
249
248
  state_secret: str = "",
250
249
  state_base: str | None = None,
250
+ runtime: Runtime | None = None,
251
251
  ):
252
252
  cfg = server.config
253
253
  colocated = getattr(cfg, "colocated", False)
@@ -268,7 +268,7 @@ async def serve(
268
268
  if colocated and harness_runtime is not None:
269
269
  runtime = harness_runtime
270
270
  else:
271
- runtime = make_runtime(cfg.runtime)
271
+ runtime = runtime or make_runtime(cfg.runtime)
272
272
  await runtime.start()
273
273
  stack.push_async_callback(runtime.stop)
274
274
  # Only consumers outside the server runtime need its fixed published port. Colocated tools
@@ -315,7 +315,8 @@ class SharedToolServer:
315
315
  """One live taskset-scoped (shared) server, as the rollouts see it: its eval-level
316
316
  `url` plus whether its runtime is `local` (host-reachable) — a remote one is an
317
317
  interception consumer, so the interception must be exposed for it to reach the
318
- `/state` channel (see `Env._requires_tunnel`). An `external` server (a
318
+ `/state` channel (see `Env._requires_tunnel`). `runtime` is retained for translating
319
+ that channel into the server's network. An `external` server (a
319
320
  config-`url` endpoint) was not launched by the framework and sits outside its state
320
321
  machinery entirely: rollouts get its URL bare — no state tag (and no per-rollout
321
322
  secret sent to a third party)."""
@@ -323,6 +324,7 @@ class SharedToolServer:
323
324
  url: str
324
325
  local: bool
325
326
  external: bool = False
327
+ runtime: Runtime | None = None
326
328
 
327
329
 
328
330
  @contextlib.asynccontextmanager
@@ -359,11 +361,18 @@ async def serve_shared(toolsets: list[Toolset], harness_is_local: bool = True):
359
361
  url=cfg.url, local=False, external=True
360
362
  )
361
363
  else:
364
+ runtime = make_runtime(cfg.runtime)
362
365
  url = await stack.enter_async_context(
363
- serve(toolset, harness_is_local=harness_is_local)
366
+ serve(
367
+ toolset,
368
+ harness_is_local=harness_is_local,
369
+ runtime=runtime,
370
+ )
364
371
  )
365
372
  servers[name] = SharedToolServer(
366
- url=url, local=runtime_is_local(cfg.runtime)
373
+ url=url,
374
+ local=runtime.is_local,
375
+ runtime=runtime,
367
376
  )
368
377
  logger.info("shared tool server '%s': %s", name, servers[name].url)
369
378
  yield servers
@@ -395,8 +404,8 @@ async def serve_tools(
395
404
  taskset-scoped `shared` servers — already
396
405
  running eval-level (see `serve_shared`) — join under their per-rollout state tag.
397
406
  `state_base`/`state_secret` wire each server to the interception server's shared-state
398
- channel `state_base` is universally reachable, so every server (per-rollout or
399
- `shared`, any runtime) uses it directly."""
407
+ channel. Each launched server translates the host-local base for its own runtime;
408
+ external servers stay untagged."""
400
409
  urls: dict[str, str] = {}
401
410
  async with contextlib.AsyncExitStack() as stack:
402
411
  for name, server in (shared or {}).items():
@@ -408,7 +417,12 @@ async def serve_tools(
408
417
  logger.info("tool server '%s' (shared, external): %s", name, server.url)
409
418
  continue
410
419
  url = harness_runtime.host_url(server.url) if server.local else server.url
411
- urls[name] = _shared_url_for_rollout(url, state_base, state_secret)
420
+ shared_state_base = (
421
+ server.runtime.host_url(state_base.rstrip("/"))
422
+ if server.runtime is not None and state_base
423
+ else state_base
424
+ )
425
+ urls[name] = _shared_url_for_rollout(url, shared_state_base, state_secret)
412
426
  # The tagged URL contains the bearer secret; log only the untagged base URL.
413
427
  logger.info("tool server '%s' (shared): %s", name, server.url)
414
428
  for toolset in toolsets:
File without changes