verifiers 0.2.2.dev59__tar.gz → 0.2.2.dev61__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.dev59 → verifiers-0.2.2.dev61}/PKG-INFO +1 -1
  2. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/conftest.py +1 -0
  3. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/conftest.py +4 -3
  4. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/test_e2e.py +1 -0
  5. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/acp/__init__.py +2 -0
  6. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/acp/_runner.py +24 -3
  7. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/agent.py +18 -18
  8. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/__init__.py +3 -0
  9. verifiers-0.2.2.dev61/verifiers/v1/harnesses/openclaw/__init__.py +6 -0
  10. verifiers-0.2.2.dev61/verifiers/v1/harnesses/openclaw/harness.py +352 -0
  11. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/rollout.py +23 -15
  12. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/.gitignore +0 -0
  13. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/LICENSE +0 -0
  14. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/README.md +0 -0
  15. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/pyproject.toml +0 -0
  16. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/__init__.py +0 -0
  17. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_browser_env.py +0 -0
  18. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_build_script.py +0 -0
  19. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_cli_agent_env.py +0 -0
  20. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_client_auth_errors.py +0 -0
  21. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_client_config.py +0 -0
  22. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_client_multimodal_types.py +0 -0
  23. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_composable_env.py +0 -0
  24. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_context_token_metrics.py +0 -0
  25. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_decorator_ranks.py +0 -0
  26. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_endpoint_registry.py +0 -0
  27. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_env_group.py +0 -0
  28. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_env_server.py +0 -0
  29. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_environment.py +0 -0
  30. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_environment_extra.py +0 -0
  31. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_error_chain.py +0 -0
  32. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_eval_display.py +0 -0
  33. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_eval_utils.py +0 -0
  34. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_gepa_cli.py +0 -0
  35. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_gepa_utils.py +0 -0
  36. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_gym_env.py +0 -0
  37. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_harbor_env_mcp.py +0 -0
  38. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_imports.py +0 -0
  39. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_init_script.py +0 -0
  40. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_install_utils.py +0 -0
  41. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_interception_utils.py +0 -0
  42. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_logging.py +0 -0
  43. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_math_rubric.py +0 -0
  44. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_maybe_think_parser.py +0 -0
  45. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_message_utils.py +0 -0
  46. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_message_utils_multimodal.py +0 -0
  47. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_multiturn_env.py +0 -0
  48. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_nemorl_client.py +0 -0
  49. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_openai_chat_completions_token_client.py +0 -0
  50. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_openai_responses_client.py +0 -0
  51. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_opencode_rlm_env.py +0 -0
  52. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_openenv_client.py +0 -0
  53. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_parser.py +0 -0
  54. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_path_utils.py +0 -0
  55. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_per_turn_timing.py +0 -0
  56. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_pricing_utils.py +0 -0
  57. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_prime_plugin.py +0 -0
  58. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_renderer_client.py +0 -0
  59. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_renderer_e2e.py +0 -0
  60. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_rlm_composable_env.py +0 -0
  61. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_rubric.py +0 -0
  62. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_rubric_group.py +0 -0
  63. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_sandbox_debug_env.py +0 -0
  64. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_sandbox_env.py +0 -0
  65. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_sandbox_mixin.py +0 -0
  66. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_save_utils.py +0 -0
  67. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_setup_script.py +0 -0
  68. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_singleturn_env.py +0 -0
  69. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_stateful_tool_env.py +0 -0
  70. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_think_parser.py +0 -0
  71. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_tool_env.py +0 -0
  72. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_tool_utils.py +0 -0
  73. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_trajectory_processing.py +0 -0
  74. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_tui_info_formatting.py +0 -0
  75. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_types.py +0 -0
  76. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/test_xml_parser.py +0 -0
  77. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/counter_tool_v1.py +0 -0
  78. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/duet_v1.py +0 -0
  79. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/echo_acp_resume_v1.py +0 -0
  80. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
  81. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/echo_multi_v0.py +0 -0
  82. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/echo_tool_v1.py +0 -0
  83. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
  84. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/echo_v0.py +0 -0
  85. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/echo_v1.py +0 -0
  86. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/pyproject.toml +0 -0
  87. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
  88. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/test_color_codeword_tasks.py +0 -0
  89. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/test_configs.py +0 -0
  90. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/test_envs.py +0 -0
  91. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/test_graph.py +0 -0
  92. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/test_judges.py +0 -0
  93. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/test_legacy.py +0 -0
  94. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/test_scoring.py +0 -0
  95. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/test_taskset.py +0 -0
  96. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/tests/v1/test_trace.py +0 -0
  97. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/__init__.py +0 -0
  98. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/__init__.py +0 -0
  99. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/commands/__init__.py +0 -0
  100. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/commands/build.py +0 -0
  101. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/commands/eval.py +0 -0
  102. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/commands/gepa.py +0 -0
  103. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/commands/init.py +0 -0
  104. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/commands/install.py +0 -0
  105. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/commands/setup.py +0 -0
  106. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/plugins/__init__.py +0 -0
  107. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/plugins/prime.py +0 -0
  108. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/cli/tui.py +0 -0
  109. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/clients/__init__.py +0 -0
  110. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/clients/anthropic_messages_client.py +0 -0
  111. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/clients/client.py +0 -0
  112. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
  113. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/clients/openai_chat_completions_client.py +0 -0
  114. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
  115. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/clients/openai_completions_client.py +0 -0
  116. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/clients/openai_responses_client.py +0 -0
  117. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/clients/renderer_client.py +0 -0
  118. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/decorators.py +0 -0
  119. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/__init__.py +0 -0
  120. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/env_group.py +0 -0
  121. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/environment.py +0 -0
  122. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/README.md +0 -0
  123. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/__init__.py +0 -0
  124. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/cli_agent_env.py +0 -0
  125. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/README.md +0 -0
  126. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/__init__.py +0 -0
  127. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/_filter.py +0 -0
  128. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/composable_env.py +0 -0
  129. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/harness.py +0 -0
  130. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
  131. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
  132. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
  133. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
  134. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
  135. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/sandbox_debug_env.py +0 -0
  136. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
  137. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/task.py +0 -0
  138. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
  139. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
  140. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
  141. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
  142. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
  143. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/harbor/cli_gym.py +0 -0
  144. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
  145. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/harbor/terminal_lego.py +0 -0
  146. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
  147. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
  148. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
  149. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
  150. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
  151. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
  152. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
  153. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
  154. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
  155. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
  156. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
  157. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
  158. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
  159. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
  160. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
  161. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
  162. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
  163. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
  164. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
  165. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
  166. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
  167. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
  168. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
  169. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
  170. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
  171. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
  172. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/gym_env.py +0 -0
  173. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
  174. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/harbor_env/env.py +0 -0
  175. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
  176. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/mcp_env.py +0 -0
  177. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/opencode_env.py +0 -0
  178. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
  179. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
  180. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
  181. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/utils/__init__.py +0 -0
  182. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/utils/file_locks.py +0 -0
  183. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
  184. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/README.md +0 -0
  185. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/__init__.py +0 -0
  186. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/browser_env/README.md +0 -0
  187. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
  188. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
  189. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
  190. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
  191. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
  192. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
  193. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/openenv_env.py +0 -0
  194. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
  195. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/integrations/textarena_env.py +0 -0
  196. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/multiturn_env.py +0 -0
  197. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/python_env.py +0 -0
  198. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/sandbox_env.py +0 -0
  199. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/singleturn_env.py +0 -0
  200. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/stateful_tool_env.py +0 -0
  201. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/envs/tool_env.py +0 -0
  202. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/errors.py +0 -0
  203. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/gepa/__init__.py +0 -0
  204. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/gepa/adapter.py +0 -0
  205. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/gepa/config.py +0 -0
  206. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/gepa/display.py +0 -0
  207. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/gepa/gepa_utils.py +0 -0
  208. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/parsers/__init__.py +0 -0
  209. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/parsers/maybe_think_parser.py +0 -0
  210. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/parsers/parser.py +0 -0
  211. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/parsers/think_parser.py +0 -0
  212. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/parsers/xml_parser.py +0 -0
  213. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/rubrics/__init__.py +0 -0
  214. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
  215. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/rubrics/judge_rubric.py +0 -0
  216. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/rubrics/math_rubric.py +0 -0
  217. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/rubrics/rubric.py +0 -0
  218. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/rubrics/rubric_group.py +0 -0
  219. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/scripts/__init__.py +0 -0
  220. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/scripts/build.py +0 -0
  221. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/scripts/eval.py +0 -0
  222. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/scripts/gepa.py +0 -0
  223. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/scripts/init.py +0 -0
  224. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/scripts/install.py +0 -0
  225. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/scripts/setup.py +0 -0
  226. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/scripts/tui.py +0 -0
  227. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/serve/__init__.py +0 -0
  228. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/serve/client/env_client.py +0 -0
  229. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/serve/client/zmq_env_client.py +0 -0
  230. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/serve/server/__init__.py +0 -0
  231. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/serve/server/env_router.py +0 -0
  232. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/serve/server/env_server.py +0 -0
  233. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/serve/server/env_worker.py +0 -0
  234. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/serve/server/zmq_env_server.py +0 -0
  235. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/serve/types.py +0 -0
  236. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/types.py +0 -0
  237. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/__init__.py +0 -0
  238. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/async_utils.py +0 -0
  239. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/client_utils.py +0 -0
  240. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/config_utils.py +0 -0
  241. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/data_utils.py +0 -0
  242. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/display_utils.py +0 -0
  243. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/env_config_utils.py +0 -0
  244. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/env_utils.py +0 -0
  245. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/error_utils.py +0 -0
  246. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/eval_display.py +0 -0
  247. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/eval_utils.py +0 -0
  248. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/heartbeat.py +0 -0
  249. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/import_utils.py +0 -0
  250. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/install_utils.py +0 -0
  251. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/interception_utils.py +0 -0
  252. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/logging_utils.py +0 -0
  253. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/message_utils.py +0 -0
  254. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/metric_utils.py +0 -0
  255. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/path_utils.py +0 -0
  256. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/pricing_utils.py +0 -0
  257. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/process_utils.py +0 -0
  258. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/response_utils.py +0 -0
  259. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/save_utils.py +0 -0
  260. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/serve_utils.py +0 -0
  261. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/thread_utils.py +0 -0
  262. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/threaded_sandbox_client.py +0 -0
  263. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/tool_utils.py +0 -0
  264. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/usage_utils.py +0 -0
  265. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/utils/version_utils.py +0 -0
  266. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/__init__.py +0 -0
  267. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/artifacts.py +0 -0
  268. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/__init__.py +0 -0
  269. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/dashboard/__init__.py +0 -0
  270. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/dashboard/base.py +0 -0
  271. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/dashboard/eval.py +0 -0
  272. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/dashboard/replay.py +0 -0
  273. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/dashboard/validate.py +0 -0
  274. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/debug.py +0 -0
  275. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/eval/__init__.py +0 -0
  276. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/eval/main.py +0 -0
  277. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/eval/resume.py +0 -0
  278. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/eval/runner.py +0 -0
  279. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/gepa.py +0 -0
  280. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/init.py +0 -0
  281. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/output.py +0 -0
  282. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/replay.py +0 -0
  283. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/resolve.py +0 -0
  284. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/serve.py +0 -0
  285. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/cli/validate.py +0 -0
  286. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/clients/__init__.py +0 -0
  287. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/clients/client.py +0 -0
  288. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/clients/config.py +0 -0
  289. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/clients/eval.py +0 -0
  290. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/clients/train.py +0 -0
  291. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/__init__.py +0 -0
  292. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/agent.py +0 -0
  293. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/cli/__init__.py +0 -0
  294. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/cli/debug.py +0 -0
  295. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/cli/env.py +0 -0
  296. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/cli/eval.py +0 -0
  297. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/cli/init.py +0 -0
  298. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/cli/replay.py +0 -0
  299. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/cli/serve.py +0 -0
  300. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/cli/validate.py +0 -0
  301. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/env.py +0 -0
  302. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/harness.py +0 -0
  303. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/judge.py +0 -0
  304. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/legacy.py +0 -0
  305. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/retries.py +0 -0
  306. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/serve.py +0 -0
  307. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/task.py +0 -0
  308. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/configs/taskset.py +0 -0
  309. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/decorators.py +0 -0
  310. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/dialects/__init__.py +0 -0
  311. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/dialects/anthropic.py +0 -0
  312. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/dialects/base.py +0 -0
  313. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/dialects/chat.py +0 -0
  314. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/dialects/responses.py +0 -0
  315. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/env.py +0 -0
  316. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/envs/__init__.py +0 -0
  317. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/envs/agentic_judge/__init__.py +0 -0
  318. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/envs/agentic_judge/env.py +0 -0
  319. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
  320. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/envs/best_of_n/env.py +0 -0
  321. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/envs/single_agent/__init__.py +0 -0
  322. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/envs/single_agent/env.py +0 -0
  323. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/envs/user_sim/__init__.py +0 -0
  324. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/envs/user_sim/env.py +0 -0
  325. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/episode.py +0 -0
  326. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/errors.py +0 -0
  327. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/gepa/__init__.py +0 -0
  328. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/gepa/adapter.py +0 -0
  329. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/gepa/config.py +0 -0
  330. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/gepa/dataset.py +0 -0
  331. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/gepa/reflection.py +0 -0
  332. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/gepa/runner.py +0 -0
  333. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/graph.py +0 -0
  334. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harness.py +0 -0
  335. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/bash/__init__.py +0 -0
  336. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/bash/harness.py +0 -0
  337. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/bash/program.py +0 -0
  338. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/browser_use/__init__.py +0 -0
  339. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/browser_use/harness.py +0 -0
  340. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/browser_use/program.py +0 -0
  341. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
  342. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/claude_code/harness.py +0 -0
  343. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/codex/__init__.py +0 -0
  344. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/codex/harness.py +0 -0
  345. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/hermes_agent/__init__.py +0 -0
  346. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/hermes_agent/harness.py +0 -0
  347. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/hermes_agent/program.py +0 -0
  348. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
  349. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
  350. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
  351. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
  352. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
  353. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/null/__init__.py +0 -0
  354. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/null/harness.py +0 -0
  355. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/null/program.py +0 -0
  356. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/pi/__init__.py +0 -0
  357. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/pi/harness.py +0 -0
  358. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/pool/__init__.py +0 -0
  359. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/pool/harness.py +0 -0
  360. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
  361. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/rlm/harness.py +0 -0
  362. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
  363. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
  364. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
  365. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/interception/__init__.py +0 -0
  366. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/interception/base.py +0 -0
  367. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/interception/pool.py +0 -0
  368. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/interception/server.py +0 -0
  369. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/interception/tunnel/__init__.py +0 -0
  370. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/interception/tunnel/base.py +0 -0
  371. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/interception/tunnel/custom.py +0 -0
  372. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/interception/tunnel/prime.py +0 -0
  373. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/judge.py +0 -0
  374. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/judges/__init__.py +0 -0
  375. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/judges/reference.py +0 -0
  376. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/judges/reference.txt +0 -0
  377. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/judges/rubric.py +0 -0
  378. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/judges/rubric.txt +0 -0
  379. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/legacy.py +0 -0
  380. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/loaders.py +0 -0
  381. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/mcp/__init__.py +0 -0
  382. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/mcp/launch.py +0 -0
  383. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/mcp/server.py +0 -0
  384. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/mcp/toolset.py +0 -0
  385. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/push.py +0 -0
  386. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/retries.py +0 -0
  387. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/runtimes/__init__.py +0 -0
  388. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/runtimes/base.py +0 -0
  389. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/runtimes/docker/__init__.py +0 -0
  390. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/runtimes/docker/egress.py +0 -0
  391. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/runtimes/limiters.py +0 -0
  392. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/runtimes/modal.py +0 -0
  393. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/runtimes/prime.py +0 -0
  394. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/runtimes/subprocess.py +0 -0
  395. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/scoring.py +0 -0
  396. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/serve/__init__.py +0 -0
  397. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/serve/client.py +0 -0
  398. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/serve/pool.py +0 -0
  399. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/serve/server.py +0 -0
  400. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/serve/types.py +0 -0
  401. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/session.py +0 -0
  402. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/state.py +0 -0
  403. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/task.py +0 -0
  404. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/taskset.py +0 -0
  405. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/tasksets/__init__.py +0 -0
  406. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
  407. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
  408. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/tasksets/lean/__init__.py +0 -0
  409. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/tasksets/lean/scoring.py +0 -0
  410. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/tasksets/lean/taskset.py +0 -0
  411. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
  412. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
  413. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
  414. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
  415. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/trace.py +0 -0
  416. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/types.py +0 -0
  417. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/__init__.py +0 -0
  418. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/aio.py +0 -0
  419. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/compile.py +0 -0
  420. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/format.py +0 -0
  421. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/generic.py +0 -0
  422. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/git.py +0 -0
  423. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/image.py +0 -0
  424. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/install.py +0 -0
  425. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/interrupt.py +0 -0
  426. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/logging.py +0 -0
  427. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/memory.py +0 -0
  428. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/verifiers/v1/utils/sampling.py +0 -0
  429. {verifiers-0.2.2.dev59 → verifiers-0.2.2.dev61}/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.dev59
3
+ Version: 0.2.2.dev61
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)
@@ -25,7 +25,7 @@ from verifiers.v1.harness import Harness
25
25
  from verifiers.v1.interception import Interception, InterceptionServer
26
26
  from verifiers.v1.mcp import SharedToolServer
27
27
  from verifiers.v1.retries import backoff, trace_should_retry
28
- from verifiers.v1.rollout import RolloutRun, _as_messages
28
+ from verifiers.v1.rollout import RolloutRun, RolloutTimeouts, _as_messages
29
29
  from verifiers.v1.runtimes import (
30
30
  NetworkPolicyConfig,
31
31
  Runtime,
@@ -533,23 +533,23 @@ class Agent:
533
533
  "harness": self.harness,
534
534
  "ctx": self.ctx,
535
535
  "runtime_config": runtime_config,
536
- "setup_timeout": (
537
- self.timeout.setup
538
- if self.timeout.setup is not None
539
- else task.data.timeout.setup
540
- ),
541
- "agent_timeout": cap_remote_agent_timeout(
542
- agent_timeout, runtime_config, task
543
- ),
544
- "finalize_timeout": (
545
- self.timeout.finalize
546
- if self.timeout.finalize is not None
547
- else task.data.timeout.finalize
548
- ),
549
- "scoring_timeout": (
550
- self.timeout.scoring
551
- if self.timeout.scoring is not None
552
- else task.data.timeout.scoring
536
+ "timeouts": RolloutTimeouts(
537
+ setup=(
538
+ self.timeout.setup
539
+ if self.timeout.setup is not None
540
+ else task.data.timeout.setup
541
+ ),
542
+ agent=cap_remote_agent_timeout(agent_timeout, runtime_config, task),
543
+ finalize=(
544
+ self.timeout.finalize
545
+ if self.timeout.finalize is not None
546
+ else task.data.timeout.finalize
547
+ ),
548
+ scoring=(
549
+ self.timeout.scoring
550
+ if self.timeout.scoring is not None
551
+ else task.data.timeout.scoring
552
+ ),
553
553
  ),
554
554
  "limits": self.limits,
555
555
  "shared_tools": shared_tools,
@@ -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,6 +23,7 @@ import logging
23
23
  import time
24
24
  from collections.abc import AsyncIterator, Callable
25
25
  from contextlib import AsyncExitStack, asynccontextmanager
26
+ from dataclasses import dataclass
26
27
 
27
28
  from verifiers.v1.clients import ModelContext
28
29
  from verifiers.v1.configs.agent import AgentConfig
@@ -57,6 +58,19 @@ from verifiers.v1.types import Messages
57
58
  logger = logging.getLogger(__name__)
58
59
 
59
60
 
61
+ @dataclass(frozen=True)
62
+ class RolloutTimeouts:
63
+ """Per-stage rollout timeouts in seconds (None = unlimited), each bounding one
64
+ lifecycle stage: `setup` covers task + harness setup in `open()`, `agent` is the
65
+ cumulative budget the run's segments draw down across `step()`s, `finalize` and
66
+ `scoring` bound their `close()` stages."""
67
+
68
+ setup: float | None = None
69
+ agent: float | None = None
70
+ finalize: float | None = None
71
+ scoring: float | None = None
72
+
73
+
60
74
  def _as_messages(raw: Messages) -> Messages:
61
75
  """A turn's messages may arrive typed or as wire dicts (env code naturally
62
76
  writes `{"role": "user", ...}`); the trace speaks typed, so normalize here."""
@@ -115,10 +129,7 @@ class RolloutRun:
115
129
  runtime_config: RuntimeConfig,
116
130
  wire_data: TaskData | None = None,
117
131
  has_user: bool = False,
118
- setup_timeout: float | None = None,
119
- agent_timeout: float | None = None,
120
- finalize_timeout: float | None = None,
121
- scoring_timeout: float | None = None,
132
+ timeouts: RolloutTimeouts | None = None,
122
133
  limits: RolloutLimits | None = None,
123
134
  shared_tools: dict[str, SharedToolServer] | None = None,
124
135
  interception: Interception | None = None,
@@ -130,11 +141,8 @@ class RolloutRun:
130
141
  self.ctx = ctx
131
142
  self.runtime_config = runtime_config
132
143
  self._has_user = has_user
133
- self._setup_timeout = setup_timeout
134
- self._agent_timeout = agent_timeout
135
- self._agent_time_remaining = agent_timeout
136
- self._finalize_timeout = finalize_timeout
137
- self._scoring_timeout = scoring_timeout
144
+ self._timeouts = timeouts or RolloutTimeouts()
145
+ self._agent_time_remaining = self._timeouts.agent
138
146
  self._shared_tools = shared_tools or {}
139
147
  self._interception = interception
140
148
  self.runtime = runtime
@@ -164,7 +172,7 @@ class RolloutRun:
164
172
  self.deadline_at: float | None = None
165
173
  """The active harness segment's absolute deadline (event-loop clock), or
166
174
  None between segments / when unbounded. An interaction spends one cumulative
167
- `agent_timeout` budget only while its own segments run, so time awaiting
175
+ `timeouts.agent` budget only while its own segments run, so time awaiting
168
176
  the caller (including another interleaved agent) cannot starve it."""
169
177
 
170
178
  @property
@@ -244,8 +252,8 @@ class RolloutRun:
244
252
  # Task setup and harness provisioning share one setup-stage deadline.
245
253
  setup_deadline = (
246
254
  None
247
- if self._setup_timeout is None
248
- else asyncio.get_running_loop().time() + self._setup_timeout
255
+ if self._timeouts.setup is None
256
+ else asyncio.get_running_loop().time() + self._timeouts.setup
249
257
  )
250
258
  async with (
251
259
  boundary(TaskError, "task setup"),
@@ -340,7 +348,7 @@ class RolloutRun:
340
348
  self.fail(
341
349
  HarnessError(
342
350
  f"agent timeout: rollout exceeded its "
343
- f"{self._agent_timeout:g}s budget"
351
+ f"{self._timeouts.agent:g}s budget"
344
352
  )
345
353
  )
346
354
  else:
@@ -406,7 +414,7 @@ class RolloutRun:
406
414
  invoke(
407
415
  self.task.finalize, {"trace": trace, "runtime": runtime}
408
416
  ),
409
- self._finalize_timeout,
417
+ self._timeouts.finalize,
410
418
  )
411
419
  now = time.time()
412
420
  trace.timing.finalize.end = now
@@ -418,7 +426,7 @@ class RolloutRun:
418
426
  self.task.score(trace, runtime),
419
427
  self.harness.score(trace, runtime),
420
428
  ),
421
- self._scoring_timeout,
429
+ self._timeouts.scoring,
422
430
  )
423
431
  trace.timing.scoring.end = time.time()
424
432
  except Exception as e: # noqa: BLE001 - finalize boundary records every rollout failure
File without changes