verifiers 0.1.15.dev167__tar.gz → 0.1.15.dev168__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 (324) hide show
  1. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/PKG-INFO +1 -1
  2. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_environment.py +24 -0
  3. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_trajectory_processing.py +43 -0
  4. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_runtime_lifecycle.py +180 -3
  5. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/clients/anthropic_messages_client.py +6 -6
  6. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/clients/openai_responses_client.py +2 -2
  7. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/types.py +35 -1
  8. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/async_utils.py +14 -15
  9. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/interception_utils.py +38 -0
  10. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/harness.py +9 -2
  11. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/endpoint_utils.py +131 -25
  12. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/sandbox_program_utils.py +40 -240
  13. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/sandbox_utils.py +58 -17
  14. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/.gitignore +0 -0
  15. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/LICENSE +0 -0
  16. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/README.md +0 -0
  17. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/pyproject.toml +0 -0
  18. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/AGENTS.md +0 -0
  19. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/README.md +0 -0
  20. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/__init__.py +0 -0
  21. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/conftest.py +0 -0
  22. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_browser_env.py +0 -0
  23. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_build_script.py +0 -0
  24. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_cli_agent_env.py +0 -0
  25. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_client_auth_errors.py +0 -0
  26. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_client_config.py +0 -0
  27. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_client_multimodal_types.py +0 -0
  28. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_composable_env.py +0 -0
  29. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_context_token_metrics.py +0 -0
  30. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_decorator_ranks.py +0 -0
  31. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_endpoint_registry.py +0 -0
  32. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_env_group.py +0 -0
  33. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_env_server.py +0 -0
  34. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_environment_extra.py +0 -0
  35. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_envs.py +0 -0
  36. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_error_chain.py +0 -0
  37. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_eval_cli.py +0 -0
  38. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_eval_display.py +0 -0
  39. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_eval_utils.py +0 -0
  40. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_gepa_cli.py +0 -0
  41. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_gepa_utils.py +0 -0
  42. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_gym_env.py +0 -0
  43. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_harbor_env_mcp.py +0 -0
  44. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_imports.py +0 -0
  45. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_init_script.py +0 -0
  46. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_install_utils.py +0 -0
  47. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_interception_utils.py +0 -0
  48. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_langchain_deep_agents_wikispeedia.py +0 -0
  49. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_lean_task.py +0 -0
  50. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_logging.py +0 -0
  51. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_math_rubric.py +0 -0
  52. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_maybe_think_parser.py +0 -0
  53. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_mcp_search_env.py +0 -0
  54. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_message_utils.py +0 -0
  55. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_message_utils_multimodal.py +0 -0
  56. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_multiturn_env.py +0 -0
  57. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_nemorl_client.py +0 -0
  58. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_openai_chat_completions_token_client.py +0 -0
  59. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_openai_responses_client.py +0 -0
  60. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_opencode_harbor.py +0 -0
  61. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_opencode_rlm_env.py +0 -0
  62. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_openenv_client.py +0 -0
  63. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_parser.py +0 -0
  64. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_path_utils.py +0 -0
  65. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_per_turn_timing.py +0 -0
  66. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_pricing_utils.py +0 -0
  67. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_prime_plugin.py +0 -0
  68. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_renderer_client.py +0 -0
  69. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_renderer_e2e.py +0 -0
  70. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_rlm_composable_env.py +0 -0
  71. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_rubric.py +0 -0
  72. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_rubric_group.py +0 -0
  73. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_sandbox_env.py +0 -0
  74. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_sandbox_mixin.py +0 -0
  75. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_save_utils.py +0 -0
  76. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_setup_script.py +0 -0
  77. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_singleturn_env.py +0 -0
  78. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_stateful_tool_env.py +0 -0
  79. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_think_parser.py +0 -0
  80. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_tool_env.py +0 -0
  81. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_tool_utils.py +0 -0
  82. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_tui_info_formatting.py +0 -0
  83. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_types.py +0 -0
  84. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_bfcl.py +0 -0
  85. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_config_extension.py +0 -0
  86. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_empty_completions.py +0 -0
  87. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_endpoint_protocols.py +0 -0
  88. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_example_counts.py +0 -0
  89. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_group_reward_env.py +0 -0
  90. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_harbor_cli.py +0 -0
  91. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_mini_swe_agent.py +0 -0
  92. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_nemo_gym_harness.py +0 -0
  93. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_openenv_taskset.py +0 -0
  94. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_openreward_taskset.py +0 -0
  95. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_replay_harness.py +0 -0
  96. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_rlm_swe.py +0 -0
  97. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_scoring_functions.py +0 -0
  98. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_taskset_bindings.py +0 -0
  99. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_taskset_utils.py +0 -0
  100. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_v1_textarena_taskset.py +0 -0
  101. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_wiki_search_v1.py +0 -0
  102. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_wordle_env.py +0 -0
  103. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_wordle_v1_env.py +0 -0
  104. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/tests/test_xml_parser.py +0 -0
  105. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/AGENTS.md +0 -0
  106. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/__init__.py +0 -0
  107. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/__init__.py +0 -0
  108. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/commands/__init__.py +0 -0
  109. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/commands/build.py +0 -0
  110. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/commands/eval.py +0 -0
  111. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/commands/gepa.py +0 -0
  112. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/commands/init.py +0 -0
  113. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/commands/install.py +0 -0
  114. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/commands/setup.py +0 -0
  115. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/plugins/__init__.py +0 -0
  116. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/plugins/prime.py +0 -0
  117. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/cli/tui.py +0 -0
  118. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/clients/__init__.py +0 -0
  119. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/clients/client.py +0 -0
  120. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
  121. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/clients/openai_chat_completions_client.py +0 -0
  122. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
  123. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/clients/openai_completions_client.py +0 -0
  124. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/clients/renderer_client.py +0 -0
  125. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/decorators.py +0 -0
  126. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/AGENTS.md +0 -0
  127. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/__init__.py +0 -0
  128. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/env_group.py +0 -0
  129. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/environment.py +0 -0
  130. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/README.md +0 -0
  131. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/__init__.py +0 -0
  132. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/cli_agent_env.py +0 -0
  133. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/README.md +0 -0
  134. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/__init__.py +0 -0
  135. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/_filter.py +0 -0
  136. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/composable_env.py +0 -0
  137. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harness.py +0 -0
  138. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
  139. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
  140. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
  141. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
  142. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
  143. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
  144. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/task.py +0 -0
  145. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
  146. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
  147. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
  148. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
  149. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
  150. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
  151. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/lean/__init__.py +0 -0
  152. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/lean/lean_task.py +0 -0
  153. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
  154. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
  155. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
  156. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
  157. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
  158. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
  159. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
  160. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
  161. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
  162. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
  163. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
  164. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
  165. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
  166. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
  167. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
  168. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
  169. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
  170. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
  171. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
  172. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
  173. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
  174. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
  175. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
  176. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
  177. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
  178. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
  179. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/gym_env.py +0 -0
  180. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
  181. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/harbor_env/env.py +0 -0
  182. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
  183. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/mcp_env.py +0 -0
  184. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/opencode_env.py +0 -0
  185. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
  186. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
  187. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
  188. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/utils/__init__.py +0 -0
  189. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/utils/file_locks.py +0 -0
  190. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
  191. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/README.md +0 -0
  192. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/__init__.py +0 -0
  193. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/README.md +0 -0
  194. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
  195. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
  196. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
  197. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
  198. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
  199. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
  200. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/openenv_env.py +0 -0
  201. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
  202. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/textarena_env.py +0 -0
  203. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/multiturn_env.py +0 -0
  204. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/python_env.py +0 -0
  205. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/sandbox_env.py +0 -0
  206. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/singleturn_env.py +0 -0
  207. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/stateful_tool_env.py +0 -0
  208. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/envs/tool_env.py +0 -0
  209. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/errors.py +0 -0
  210. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/gepa/__init__.py +0 -0
  211. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/gepa/adapter.py +0 -0
  212. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/gepa/config.py +0 -0
  213. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/gepa/display.py +0 -0
  214. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/gepa/gepa_utils.py +0 -0
  215. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/parsers/__init__.py +0 -0
  216. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/parsers/maybe_think_parser.py +0 -0
  217. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/parsers/parser.py +0 -0
  218. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/parsers/think_parser.py +0 -0
  219. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/parsers/xml_parser.py +0 -0
  220. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rl/README.md +0 -0
  221. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rl/__init__.py +0 -0
  222. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rl/inference/__init__.py +0 -0
  223. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rl/inference/client.py +0 -0
  224. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rl/inference/server.py +0 -0
  225. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/__init__.py +0 -0
  226. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/config.py +0 -0
  227. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/orchestrator.py +0 -0
  228. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/trainer.py +0 -0
  229. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/utils.py +0 -0
  230. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rubrics/__init__.py +0 -0
  231. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
  232. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rubrics/judge_rubric.py +0 -0
  233. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rubrics/math_rubric.py +0 -0
  234. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rubrics/rubric.py +0 -0
  235. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/rubrics/rubric_group.py +0 -0
  236. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/__init__.py +0 -0
  237. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/build.py +0 -0
  238. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/eval.py +0 -0
  239. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/gepa.py +0 -0
  240. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/init.py +0 -0
  241. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/install.py +0 -0
  242. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/rl.py +0 -0
  243. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/setup.py +0 -0
  244. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/train.py +0 -0
  245. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/tui.py +0 -0
  246. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/scripts/vllm.py +0 -0
  247. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/serve/__init__.py +0 -0
  248. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/serve/client/env_client.py +0 -0
  249. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/serve/client/zmq_env_client.py +0 -0
  250. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/serve/server/__init__.py +0 -0
  251. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/serve/server/env_router.py +0 -0
  252. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/serve/server/env_server.py +0 -0
  253. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/serve/server/env_worker.py +0 -0
  254. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/serve/server/zmq_env_server.py +0 -0
  255. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/serve/types.py +0 -0
  256. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/__init__.py +0 -0
  257. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/client_utils.py +0 -0
  258. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/config_utils.py +0 -0
  259. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/data_utils.py +0 -0
  260. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/display_utils.py +0 -0
  261. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/env_config_utils.py +0 -0
  262. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/env_utils.py +0 -0
  263. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/error_utils.py +0 -0
  264. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/eval_display.py +0 -0
  265. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/eval_utils.py +0 -0
  266. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/heartbeat.py +0 -0
  267. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/import_utils.py +0 -0
  268. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/install_utils.py +0 -0
  269. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/logging_utils.py +0 -0
  270. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/message_utils.py +0 -0
  271. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/metric_utils.py +0 -0
  272. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/path_utils.py +0 -0
  273. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/pricing_utils.py +0 -0
  274. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/process_utils.py +0 -0
  275. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/response_utils.py +0 -0
  276. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/save_utils.py +0 -0
  277. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/serve_utils.py +0 -0
  278. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/thread_utils.py +0 -0
  279. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/threaded_sandbox_client.py +0 -0
  280. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/tool_utils.py +0 -0
  281. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/usage_utils.py +0 -0
  282. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/utils/version_utils.py +0 -0
  283. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/ENVIRONMENT_BEST_PRACTICES.md +0 -0
  284. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/README.md +0 -0
  285. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/RE_MIGRATION.md +0 -0
  286. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/__init__.py +0 -0
  287. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/artifact.py +0 -0
  288. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/config.py +0 -0
  289. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/env.py +0 -0
  290. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/model.py +0 -0
  291. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/program.py +0 -0
  292. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/runtime.py +0 -0
  293. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/runtime_handles.py +0 -0
  294. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/sandbox.py +0 -0
  295. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/state.py +0 -0
  296. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/task.py +0 -0
  297. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/taskset.py +0 -0
  298. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/toolset.py +0 -0
  299. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/types.py +0 -0
  300. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/user.py +0 -0
  301. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/__init__.py +0 -0
  302. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/binding_utils.py +0 -0
  303. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/config_callable_utils.py +0 -0
  304. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/config_utils.py +0 -0
  305. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/json_utils.py +0 -0
  306. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/judge_utils.py +0 -0
  307. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/lifecycle_utils.py +0 -0
  308. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/logging_utils.py +0 -0
  309. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/mcp_proxy_utils.py +0 -0
  310. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/mcp_utils.py +0 -0
  311. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/object_utils.py +0 -0
  312. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/program_utils.py +0 -0
  313. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/prompt_utils.py +0 -0
  314. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/runtime_owner_utils.py +0 -0
  315. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/runtime_registry.py +0 -0
  316. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/sandbox_python_utils.py +0 -0
  317. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/scoring_utils.py +0 -0
  318. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/serialization_utils.py +0 -0
  319. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/task_freeze_utils.py +0 -0
  320. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/taskset_utils.py +0 -0
  321. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/tool_utils.py +0 -0
  322. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/toolset_utils.py +0 -0
  323. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/trajectory_utils.py +0 -0
  324. {verifiers-0.1.15.dev167 → verifiers-0.1.15.dev168}/verifiers/v1/utils/usage_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verifiers
3
- Version: 0.1.15.dev167
3
+ Version: 0.1.15.dev168
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
@@ -697,6 +697,30 @@ class TestMaybeRetry:
697
697
  error_data = rollout_outputs[0]["error"]
698
698
  assert "InfraError" == error_data["error"]
699
699
 
700
+ @pytest.mark.asyncio
701
+ async def test_retries_serialized_infra_error_subclass(self):
702
+ """A serialized InfraError subclass (e.g. SandboxError) in returned state
703
+ must trigger retry.
704
+
705
+ The v1 harness serializes state["error"] to ErrorData before maybe_retry
706
+ inspects it, so matching must be subclass-aware (rebuild concrete error +
707
+ isinstance) — base-name substring matching missed SandboxError, which is
708
+ an InfraError and should be retried.
709
+ """
710
+ from verifiers.utils.async_utils import maybe_retry
711
+ from verifiers.utils.error_utils import error_data
712
+
713
+ serialized = error_data(vf.SandboxError("Program file upload failed"))
714
+ calls = {"n": 0}
715
+
716
+ async def attempt():
717
+ calls["n"] += 1
718
+ return {"error": serialized}
719
+
720
+ result = await maybe_retry(attempt, max_retries=2, initial=0.0, max_wait=0.0)()
721
+ assert calls["n"] == 3 # 1 initial + 2 retries (InfraError is retryable)
722
+ assert result["error"] == serialized # last result returned after exhaustion
723
+
700
724
 
701
725
  class TestEmptyModelResponseErrors:
702
726
  """Test cases for empty and invalid model response error handling."""
@@ -282,6 +282,49 @@ async def test_parsed_prompt_attribution_survives_v1_assert_serializable():
282
282
  State({"trajectory": [step]}).assert_serializable()
283
283
 
284
284
 
285
+ def test_assert_serializable_accepts_msgpack_sidecars_rejects_unknown():
286
+ """The ``assert_serializable`` json.dumps gate must accept exactly what the
287
+ trainer transport (msgpack) accepts, while staying strict otherwise.
288
+
289
+ Trajectory token steps carry sidecars that are non-JSON by design and reach
290
+ the trainer via msgpack, not JSON: the renderer ``MultiModalData`` (a
291
+ dataclass holding numpy pixel arrays) and ``routed_experts`` (a raw
292
+ ``memoryview`` buffer). Both must clear the gate; any other
293
+ non-serializable object must still raise.
294
+ """
295
+ import dataclasses
296
+
297
+ import numpy as np
298
+
299
+ @dataclasses.dataclass
300
+ class _FakeMultiModalData:
301
+ mm_hashes: dict
302
+ mm_items: dict
303
+ mm_placeholders: dict
304
+
305
+ mm = _FakeMultiModalData(
306
+ mm_hashes={"image": ["h1"]},
307
+ mm_items={"image": [np.zeros((2, 2), dtype=np.uint8)]},
308
+ mm_placeholders={"image": [{"offset": 0, "length": 4}]},
309
+ )
310
+ step = {
311
+ "tokens": {
312
+ "prompt_ids": [1, 2],
313
+ "multi_modal_data": mm,
314
+ "routed_experts": {"data": memoryview(b"abc"), "shape": [3], "start": 0},
315
+ }
316
+ }
317
+ # Must not raise: both sidecars are msgpack-transported, not JSON.
318
+ State({"trajectory": [step]}).assert_serializable()
319
+
320
+ # A genuinely non-serializable object must still be rejected.
321
+ class _Unknown:
322
+ pass
323
+
324
+ with pytest.raises(TypeError):
325
+ State({"trajectory": [{"tokens": _Unknown()}]}).assert_serializable()
326
+
327
+
285
328
  def test_process_trajectory_steps_for_training(make_input):
286
329
  """Test processing trajectory steps into training examples."""
287
330
  state1 = State(
@@ -110,6 +110,15 @@ class BlockingModelClient(CapturingModelClient):
110
110
  return await super().get_response(**kwargs)
111
111
 
112
112
 
113
+ class RaisingModelClient:
114
+ def __init__(self, error: vf.Error):
115
+ self.error = error
116
+
117
+ async def get_response(self, **kwargs: object) -> Response:
118
+ _ = kwargs
119
+ raise self.error
120
+
121
+
113
122
  class FakeCreateSandboxRequest:
114
123
  def __init__(self, **kwargs: object):
115
124
  self.kwargs = kwargs
@@ -517,6 +526,31 @@ async def endpoint_program(task, state):
517
526
  }
518
527
 
519
528
 
529
+ async def endpoint_model_error_program(task, state):
530
+ _ = task
531
+ root = state["endpoint_root_url"].rstrip("/")
532
+ endpoint_client = cast(OpenAI, state.get_client(api="chat", sync=True))
533
+ auth_headers = {"Authorization": f"Bearer {endpoint_client.api_key}"}
534
+ endpoint_client.close()
535
+
536
+ def post_model() -> None:
537
+ request = urllib.request.Request(
538
+ f"{root}/vf/model",
539
+ data=json.dumps(
540
+ {"messages": [{"role": "user", "content": "too long"}]}
541
+ ).encode(),
542
+ headers={"content-type": "application/json", **auth_headers},
543
+ )
544
+ with urllib.request.urlopen(request):
545
+ pass
546
+
547
+ try:
548
+ await asyncio.to_thread(post_model)
549
+ except Exception as exc:
550
+ raise vf.SandboxError("Sandbox command failed") from exc
551
+ raise AssertionError("Expected /vf/model to fail")
552
+
553
+
520
554
  async def endpoint_trajectory_program(task, state):
521
555
  _ = task
522
556
  root = state["endpoint_root_url"].rstrip("/")
@@ -725,6 +759,7 @@ for _name, _value in {
725
759
  "initialize_from_taskset": initialize_from_taskset,
726
760
  "child_reads_program_sandbox": child_reads_program_sandbox,
727
761
  "endpoint_program": endpoint_program,
762
+ "endpoint_model_error_program": endpoint_model_error_program,
728
763
  "endpoint_trajectory_program": endpoint_trajectory_program,
729
764
  "concurrent_endpoint_program": concurrent_endpoint_program,
730
765
  "mcp_proxy_program": mcp_proxy_program,
@@ -827,6 +862,41 @@ async def test_endpoint_exposes_tool_user_and_stop_surfaces() -> None:
827
862
  assert "endpoint_root_url" not in state
828
863
 
829
864
 
865
+ @pytest.mark.asyncio
866
+ async def test_vf_model_bridge_preserves_overlong_prompt_error() -> None:
867
+ harness = make_harness(
868
+ program={"fn": program_ref("endpoint_model_error_program")},
869
+ model="test-model",
870
+ client=RaisingModelClient(vf.OverlongPromptError("too long")),
871
+ )
872
+ task = vf.Task({"prompt": [{"role": "user", "content": "hi"}]}).freeze()
873
+
874
+ state = await harness.run(task)
875
+ await harness.teardown()
876
+
877
+ assert state["prompt_too_long"] is True
878
+ assert state["is_truncated"] is True
879
+ assert state["stop_condition"] == "prompt_too_long"
880
+ assert state.get("error") is None
881
+
882
+
883
+ @pytest.mark.asyncio
884
+ async def test_vf_model_bridge_preserves_model_error() -> None:
885
+ harness = make_harness(
886
+ program={"fn": program_ref("endpoint_model_error_program")},
887
+ model="test-model",
888
+ client=RaisingModelClient(vf.ModelError("model failed")),
889
+ )
890
+ task = vf.Task({"prompt": [{"role": "user", "content": "hi"}]}).freeze()
891
+
892
+ state = await harness.run(task)
893
+ await harness.teardown()
894
+
895
+ assert state["stop_condition"] == "has_error"
896
+ assert state["error"]["error"] == "ModelError"
897
+ assert "SandboxError" not in state["error"]["error_chain_str"]
898
+
899
+
830
900
  @pytest.mark.asyncio
831
901
  async def test_endpoint_request_can_hide_internal_model_call_from_trajectory() -> None:
832
902
  client = FakeModelClient([fake_response("hidden"), fake_response("shown")])
@@ -1462,6 +1532,70 @@ async def test_create_sandbox_cleans_up_wait_failure_with_retry(
1462
1532
  assert client.delete_calls == 2
1463
1533
 
1464
1534
 
1535
+ @pytest.mark.asyncio
1536
+ async def test_upload_program_files_retries_transient_transfer_error(
1537
+ monkeypatch: pytest.MonkeyPatch,
1538
+ ) -> None:
1539
+ install_fake_sandboxes(monkeypatch)
1540
+ disable_sandbox_retry_sleep(monkeypatch)
1541
+
1542
+ class FlakyUploadClient:
1543
+ calls = 0
1544
+
1545
+ async def upload_bytes(self, *args: object, **kwargs: object) -> None:
1546
+ _ = args, kwargs
1547
+ self.calls += 1
1548
+ if self.calls == 1:
1549
+ raise FakeAPIError("Upload failed: ")
1550
+
1551
+ client = FlakyUploadClient()
1552
+ task = vf.Task({"prompt": [{"role": "user", "content": "hi"}]}).freeze()
1553
+ state = vf.State.for_task(task)
1554
+
1555
+ await sandbox_utils.upload_program_files(
1556
+ cast(sandbox_utils.SandboxClient, client),
1557
+ "sbx-upload",
1558
+ {"files": {"/tmp/file.txt": "content"}},
1559
+ task,
1560
+ state,
1561
+ Runtime(),
1562
+ )
1563
+
1564
+ assert client.calls == 2
1565
+
1566
+
1567
+ @pytest.mark.asyncio
1568
+ async def test_upload_program_files_does_not_retry_non_transient_api_error(
1569
+ monkeypatch: pytest.MonkeyPatch,
1570
+ ) -> None:
1571
+ install_fake_sandboxes(monkeypatch)
1572
+ disable_sandbox_retry_sleep(monkeypatch)
1573
+
1574
+ class FailingUploadClient:
1575
+ calls = 0
1576
+
1577
+ async def upload_bytes(self, *args: object, **kwargs: object) -> None:
1578
+ _ = args, kwargs
1579
+ self.calls += 1
1580
+ raise FakeAPIError("Upload failed: HTTP 400: bad request")
1581
+
1582
+ client = FailingUploadClient()
1583
+ task = vf.Task({"prompt": [{"role": "user", "content": "hi"}]}).freeze()
1584
+ state = vf.State.for_task(task)
1585
+
1586
+ with pytest.raises(vf.SandboxError, match="HTTP 400"):
1587
+ await sandbox_utils.upload_program_files(
1588
+ cast(sandbox_utils.SandboxClient, client),
1589
+ "sbx-upload",
1590
+ {"files": {"/tmp/file.txt": "content"}},
1591
+ task,
1592
+ state,
1593
+ Runtime(),
1594
+ )
1595
+
1596
+ assert client.calls == 1
1597
+
1598
+
1465
1599
  @pytest.mark.asyncio
1466
1600
  async def test_create_sandbox_cancellation_deletes_late_provider_result(
1467
1601
  monkeypatch: pytest.MonkeyPatch,
@@ -1603,8 +1737,8 @@ async def test_sandbox_base_program_max_turns_zero_is_unbounded(
1603
1737
  config_path.write_text(json.dumps({"max_turns": 0}))
1604
1738
  namespace["RUNNER_CONFIG_PATH"] = str(config_path)
1605
1739
 
1606
- async def create_model_message(state, messages, client):
1607
- _ = state, messages, client
1740
+ async def create_model_message(state, messages):
1741
+ _ = state, messages
1608
1742
  return {"role": "assistant", "content": "done"}
1609
1743
 
1610
1744
  async def call_user(state, messages):
@@ -1621,12 +1755,55 @@ async def test_sandbox_base_program_max_turns_zero_is_unbounded(
1621
1755
 
1622
1756
  state = {"prompt": [{"role": "user", "content": "hi"}], "runtime": {}}
1623
1757
  run_base = cast(Any, namespace["run_base"])
1624
- result = await run_base({}, state, object())
1758
+ result = await run_base({}, state)
1625
1759
 
1626
1760
  assert result["completion"] == [{"role": "assistant", "content": "done"}]
1627
1761
  assert result["stop_condition"] == "no_tools"
1628
1762
 
1629
1763
 
1764
+ @pytest.mark.asyncio
1765
+ async def test_sandbox_base_program_model_call_uses_vf_model_bridge() -> None:
1766
+ namespace: dict[str, object] = {}
1767
+ source = runner_source().rsplit("asyncio.run(main())", 1)[0]
1768
+ exec(source, namespace)
1769
+
1770
+ posted: list[tuple[str, Any, object]] = []
1771
+
1772
+ async def vf_post(state, path, payload, timeout=None):
1773
+ _ = state
1774
+ posted.append((path, payload, timeout))
1775
+ return {"message": {"role": "assistant", "content": "ok"}}
1776
+
1777
+ namespace["vf_post"] = vf_post
1778
+ create_model_message = cast(Any, namespace["create_model_message"])
1779
+
1780
+ # Canonical Messages (incl. an image content part) are sent unchanged over the
1781
+ # /vf/model bridge; the host owns client resolution + tokenization and returns
1782
+ # the assistant message.
1783
+ messages = [
1784
+ {"role": "user", "content": "hi"},
1785
+ {
1786
+ "role": "tool",
1787
+ "tool_call_id": "call_1",
1788
+ "content": [
1789
+ {"type": "text", "text": "shot"},
1790
+ {
1791
+ "type": "image_url",
1792
+ "image_url": {"url": "data:image/png;base64,AAA"},
1793
+ },
1794
+ ],
1795
+ },
1796
+ ]
1797
+ message = await create_model_message({"runtime": {}}, messages)
1798
+
1799
+ assert message == {"role": "assistant", "content": "ok"}
1800
+ assert len(posted) == 1
1801
+ path, payload, timeout = posted[0]
1802
+ assert path == "model"
1803
+ assert payload["messages"] == messages # image part preserved verbatim
1804
+ assert timeout is None
1805
+
1806
+
1630
1807
  def test_sandbox_program_patch_cannot_set_lifecycle_fields() -> None:
1631
1808
  state = vf.State.for_task(vf.Task({"prompt": []}).freeze())
1632
1809
 
@@ -214,15 +214,15 @@ class AnthropicMessagesClient(
214
214
  return {}
215
215
 
216
216
  def build_tool_result_block(message: ToolMessage) -> ToolResultBlockParam:
217
+ if isinstance(message.content, str):
218
+ result_content: Any = message.content
219
+ else:
220
+ # Keep images: image_url parts -> Anthropic image blocks (not "[image]" text).
221
+ result_content = normalize_anthropic_content(message.content)
217
222
  return ToolResultBlockParam(
218
223
  type="tool_result",
219
224
  tool_use_id=message.tool_call_id,
220
- content=cast(
221
- Any,
222
- message.content
223
- if isinstance(message.content, str)
224
- else " ".join(content_to_text_chunks(message.content)),
225
- ),
225
+ content=cast(Any, result_content),
226
226
  )
227
227
 
228
228
  def from_chat_message(message: Message) -> AnthropicMessageParam | None:
@@ -156,8 +156,8 @@ class OpenAIResponsesClient(
156
156
  if isinstance(message, ToolMessage):
157
157
  output = message.content
158
158
  if not isinstance(output, str):
159
- text = content_to_text(output)
160
- output = text if text else str(output)
159
+ # Keep images: image_url parts -> Responses input_image (not text).
160
+ output = normalize_message_content(output)
161
161
  return [
162
162
  {
163
163
  "type": "function_call_output",
@@ -1081,9 +1081,43 @@ def _strip_runtime_handles(value: object) -> None:
1081
1081
  _strip_runtime_handles(item)
1082
1082
 
1083
1083
 
1084
+ def _json_gate_default(obj: object) -> object:
1085
+ # Gate parity with the trainer transport (serve_utils.msgpack_encoder):
1086
+ # accept what msgpack ships (it reaches the trainer via msgpack, not JSON),
1087
+ # as cheap stand-ins; json re-invokes this on nested values. Unknown raises.
1088
+ import dataclasses
1089
+ from datetime import date, datetime
1090
+ from enum import Enum
1091
+
1092
+ if isinstance(obj, (Path, uuid.UUID)):
1093
+ return str(obj) # filesystem path / uuid
1094
+ if isinstance(obj, Enum):
1095
+ return obj.value # enum member
1096
+ if isinstance(obj, (datetime, date)):
1097
+ return obj.isoformat() # timestamps
1098
+ if isinstance(obj, (bytes, bytearray, memoryview)):
1099
+ return f"<{type(obj).__name__}>" # raw buffers (e.g. routed_experts data)
1100
+ np = sys.modules.get("numpy")
1101
+ if np is not None and isinstance(obj, (np.integer, np.floating)):
1102
+ return obj.item() # numpy scalar -> python scalar
1103
+ if np is not None and isinstance(obj, np.ndarray):
1104
+ return {"dtype": str(obj.dtype), "shape": list(obj.shape)} # array: shape only
1105
+ torch = sys.modules.get("torch")
1106
+ if torch is not None and isinstance(obj, torch.Tensor):
1107
+ return {"dtype": str(obj.dtype), "shape": list(obj.shape)} # tensor: shape only
1108
+ model_dump = getattr(obj, "model_dump", None)
1109
+ if callable(model_dump):
1110
+ return model_dump(exclude_none=True) # pydantic model
1111
+ if dataclasses.is_dataclass(obj) and not isinstance(obj, type):
1112
+ # renderer sidecars (MultiModalData / PlaceholderRange); shallow so json
1113
+ # recurses into fields without deep-copying pixel arrays.
1114
+ return {f.name: getattr(obj, f.name) for f in dataclasses.fields(obj)}
1115
+ raise TypeError(f"{type(obj).__name__} is not JSON-serializable")
1116
+
1117
+
1084
1118
  def assert_json_serializable(value: object) -> None:
1085
1119
  try:
1086
- json.dumps(value)
1120
+ json.dumps(value, default=_json_gate_default)
1087
1121
  except TypeError as e:
1088
1122
  raise TypeError("Task and State values must be JSON-serializable.") from e
1089
1123
 
@@ -13,7 +13,7 @@ from pydantic import BaseModel
13
13
 
14
14
  import verifiers as vf
15
15
  from verifiers.utils.error_utils import ErrorChain
16
- from verifiers.utils.error_utils import error_data_to_exception
16
+ from verifiers.utils.error_utils import error_from_data, is_error_data
17
17
  from verifiers.utils.logging_utils import print_time
18
18
 
19
19
  logger = logging.getLogger(__name__)
@@ -161,25 +161,24 @@ def maybe_retry(
161
161
  if max_retries <= 0:
162
162
  return func
163
163
 
164
+ def reraise_one(err, error_types: tuple[type[Exception], ...]):
165
+ if not err:
166
+ return
167
+ if any(isinstance(err, err_type) for err_type in error_types):
168
+ raise err
169
+ # Rebuild serialized ErrorData so base types match (SandboxError -> InfraError).
170
+ if isinstance(err, Mapping) and is_error_data(err):
171
+ rebuilt = error_from_data(err)
172
+ if isinstance(rebuilt, error_types):
173
+ raise rebuilt
174
+
164
175
  def reraise_error_from_state(result, error_types: tuple[type[Exception], ...]):
165
176
  """Re-raise specified errors from state(s) to trigger tenacity retry."""
166
177
  if isinstance(result, dict):
167
- err = result.get("error")
168
- if err and any(isinstance(err, err_type) for err_type in error_types):
169
- raise err
170
- if isinstance(err, Mapping):
171
- retry_error = error_data_to_exception(err, error_types)
172
- if retry_error is not None:
173
- raise retry_error
178
+ reraise_one(result.get("error"), error_types)
174
179
  elif isinstance(result, list):
175
180
  for state in result:
176
- err = state.get("error")
177
- if err and any(isinstance(err, err_type) for err_type in error_types):
178
- raise err
179
- if isinstance(err, Mapping):
180
- retry_error = error_data_to_exception(err, error_types)
181
- if retry_error is not None:
182
- raise retry_error
181
+ reraise_one(state.get("error"), error_types)
183
182
 
184
183
  def log_retry(retry_state: tc.RetryCallState) -> None:
185
184
  """Log a warning with the exception and the number of attempts."""
@@ -120,6 +120,10 @@ class InterceptionServer:
120
120
  "/rollout/{rollout_id}/vf/stop",
121
121
  self._handle_stop_request,
122
122
  )
123
+ app.router.add_post(
124
+ "/rollout/{rollout_id}/vf/model",
125
+ self._handle_model_request,
126
+ )
123
127
  app.router.add_get(
124
128
  "/health",
125
129
  lambda _: web.json_response({"status": "ok"}),
@@ -192,6 +196,7 @@ class InterceptionServer:
192
196
  tool_defs: Any | None = None,
193
197
  user_handler: Any | None = None,
194
198
  stop_handler: Any | None = None,
199
+ model_handler: Any | None = None,
195
200
  ) -> asyncio.Queue:
196
201
  request_queue: asyncio.Queue = asyncio.Queue()
197
202
  self.active_rollouts[rollout_id] = {
@@ -201,6 +206,7 @@ class InterceptionServer:
201
206
  "tool_defs": tool_defs,
202
207
  "user_handler": user_handler,
203
208
  "stop_handler": stop_handler,
209
+ "model_handler": model_handler,
204
210
  }
205
211
  return request_queue
206
212
 
@@ -415,6 +421,38 @@ class InterceptionServer:
415
421
  return web.json_response({"error": str(e)}, status=500)
416
422
  return web.json_response(result)
417
423
 
424
+ async def _handle_model_request(self, request: Any) -> Any:
425
+ if not self._authorized(request):
426
+ return web.json_response({"error": "Unauthorized"}, status=401)
427
+
428
+ rollout_id = request.match_info["rollout_id"]
429
+ context = self.active_rollouts.get(rollout_id)
430
+ if not context:
431
+ return web.json_response({"error": "Rollout not found"}, status=404)
432
+ model_handler = context.get("model_handler")
433
+ if model_handler is None:
434
+ return web.json_response({"error": "Model proxy unavailable"}, status=404)
435
+
436
+ try:
437
+ request_body = await request.json()
438
+ except Exception as e:
439
+ return web.json_response({"error": f"Invalid JSON: {e}"}, status=400)
440
+ messages = request_body.get("messages")
441
+ if not isinstance(messages, list):
442
+ return web.json_response(
443
+ {"error": "Model request messages must be a list"}, status=400
444
+ )
445
+ tools = request_body.get("tools")
446
+
447
+ try:
448
+ result = model_handler(messages, tools)
449
+ if inspect.isawaitable(result):
450
+ result = await result
451
+ message = jsonable(result)
452
+ except Exception as e:
453
+ return web.json_response({"error": str(e)}, status=500)
454
+ return web.json_response({"message": message})
455
+
418
456
  async def _handle_streaming_response(
419
457
  self, http_request: Any, rollout_id: str, intercept: dict
420
458
  ) -> Any:
@@ -6,7 +6,7 @@ from pydantic import AliasChoices, Field
6
6
 
7
7
  import verifiers as vf
8
8
  from verifiers.clients.client import Client
9
- from verifiers.errors import Error, OverlongPromptError
9
+ from verifiers.errors import Error, OverlongPromptError, SandboxError
10
10
  from verifiers.types import (
11
11
  ClientConfig,
12
12
  MessageContent,
@@ -93,7 +93,7 @@ from .types import (
93
93
  if TYPE_CHECKING:
94
94
  from .taskset import Taskset
95
95
 
96
- ProgramResult: TypeAlias = State | ConfigData | None
96
+ ProgramResult: TypeAlias = State | JsonData | None
97
97
  ProgramRunner: TypeAlias = Callable[[Task, State], Awaitable[ProgramResult]]
98
98
 
99
99
 
@@ -282,6 +282,13 @@ class Harness(RuntimeOwnerMixin[ConfigT], Generic[ConfigT]):
282
282
  return state
283
283
 
284
284
  def record_error(self, state: State, error: Error) -> None:
285
+ if state.get("prompt_too_long"):
286
+ state._set_truncated(True)
287
+ state._set_stop_condition("prompt_too_long", overwrite=True)
288
+ return
289
+ if isinstance(error, SandboxError) and isinstance(state.get("error"), Error):
290
+ state._set_stop_condition("has_error", overwrite=True)
291
+ return
285
292
  if isinstance(error, OverlongPromptError):
286
293
  state["prompt_too_long"] = True
287
294
  state._set_truncated(True)