verifiers 0.1.15.dev166__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.dev166 → verifiers-0.1.15.dev168}/PKG-INFO +1 -1
  2. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_composable_env.py +22 -0
  3. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_environment.py +24 -0
  4. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_environment_extra.py +24 -0
  5. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_eval_cli.py +25 -0
  6. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_path_utils.py +47 -0
  7. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_save_utils.py +61 -0
  8. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_trajectory_processing.py +43 -0
  9. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_runtime_lifecycle.py +180 -3
  10. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_taskset_utils.py +23 -1
  11. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/anthropic_messages_client.py +6 -6
  12. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/openai_responses_client.py +2 -2
  13. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/environment.py +52 -12
  14. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/eval.py +22 -0
  15. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/types.py +39 -1
  16. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/async_utils.py +14 -15
  17. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/eval_utils.py +5 -1
  18. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/interception_utils.py +38 -0
  19. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/path_utils.py +8 -0
  20. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/save_utils.py +21 -0
  21. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/harness.py +9 -2
  22. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/endpoint_utils.py +131 -25
  23. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/sandbox_program_utils.py +40 -240
  24. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/sandbox_utils.py +58 -17
  25. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/.gitignore +0 -0
  26. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/LICENSE +0 -0
  27. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/README.md +0 -0
  28. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/pyproject.toml +0 -0
  29. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/AGENTS.md +0 -0
  30. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/README.md +0 -0
  31. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/__init__.py +0 -0
  32. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/conftest.py +0 -0
  33. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_browser_env.py +0 -0
  34. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_build_script.py +0 -0
  35. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_cli_agent_env.py +0 -0
  36. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_client_auth_errors.py +0 -0
  37. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_client_config.py +0 -0
  38. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_client_multimodal_types.py +0 -0
  39. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_context_token_metrics.py +0 -0
  40. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_decorator_ranks.py +0 -0
  41. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_endpoint_registry.py +0 -0
  42. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_env_group.py +0 -0
  43. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_env_server.py +0 -0
  44. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_envs.py +0 -0
  45. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_error_chain.py +0 -0
  46. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_eval_display.py +0 -0
  47. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_eval_utils.py +0 -0
  48. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_gepa_cli.py +0 -0
  49. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_gepa_utils.py +0 -0
  50. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_gym_env.py +0 -0
  51. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_harbor_env_mcp.py +0 -0
  52. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_imports.py +0 -0
  53. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_init_script.py +0 -0
  54. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_install_utils.py +0 -0
  55. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_interception_utils.py +0 -0
  56. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_langchain_deep_agents_wikispeedia.py +0 -0
  57. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_lean_task.py +0 -0
  58. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_logging.py +0 -0
  59. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_math_rubric.py +0 -0
  60. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_maybe_think_parser.py +0 -0
  61. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_mcp_search_env.py +0 -0
  62. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_message_utils.py +0 -0
  63. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_message_utils_multimodal.py +0 -0
  64. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_multiturn_env.py +0 -0
  65. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_nemorl_client.py +0 -0
  66. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_openai_chat_completions_token_client.py +0 -0
  67. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_openai_responses_client.py +0 -0
  68. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_opencode_harbor.py +0 -0
  69. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_opencode_rlm_env.py +0 -0
  70. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_openenv_client.py +0 -0
  71. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_parser.py +0 -0
  72. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_per_turn_timing.py +0 -0
  73. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_pricing_utils.py +0 -0
  74. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_prime_plugin.py +0 -0
  75. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_renderer_client.py +0 -0
  76. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_renderer_e2e.py +0 -0
  77. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_rlm_composable_env.py +0 -0
  78. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_rubric.py +0 -0
  79. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_rubric_group.py +0 -0
  80. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_sandbox_env.py +0 -0
  81. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_sandbox_mixin.py +0 -0
  82. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_setup_script.py +0 -0
  83. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_singleturn_env.py +0 -0
  84. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_stateful_tool_env.py +0 -0
  85. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_think_parser.py +0 -0
  86. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_tool_env.py +0 -0
  87. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_tool_utils.py +0 -0
  88. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_tui_info_formatting.py +0 -0
  89. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_types.py +0 -0
  90. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_bfcl.py +0 -0
  91. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_config_extension.py +0 -0
  92. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_empty_completions.py +0 -0
  93. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_endpoint_protocols.py +0 -0
  94. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_example_counts.py +0 -0
  95. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_group_reward_env.py +0 -0
  96. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_harbor_cli.py +0 -0
  97. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_mini_swe_agent.py +0 -0
  98. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_nemo_gym_harness.py +0 -0
  99. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_openenv_taskset.py +0 -0
  100. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_openreward_taskset.py +0 -0
  101. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_replay_harness.py +0 -0
  102. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_rlm_swe.py +0 -0
  103. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_scoring_functions.py +0 -0
  104. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_taskset_bindings.py +0 -0
  105. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_textarena_taskset.py +0 -0
  106. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_wiki_search_v1.py +0 -0
  107. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_wordle_env.py +0 -0
  108. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_wordle_v1_env.py +0 -0
  109. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_xml_parser.py +0 -0
  110. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/AGENTS.md +0 -0
  111. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/__init__.py +0 -0
  112. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/__init__.py +0 -0
  113. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/__init__.py +0 -0
  114. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/build.py +0 -0
  115. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/eval.py +0 -0
  116. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/gepa.py +0 -0
  117. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/init.py +0 -0
  118. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/install.py +0 -0
  119. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/setup.py +0 -0
  120. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/plugins/__init__.py +0 -0
  121. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/plugins/prime.py +0 -0
  122. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/tui.py +0 -0
  123. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/__init__.py +0 -0
  124. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/client.py +0 -0
  125. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
  126. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/openai_chat_completions_client.py +0 -0
  127. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
  128. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/openai_completions_client.py +0 -0
  129. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/renderer_client.py +0 -0
  130. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/decorators.py +0 -0
  131. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/AGENTS.md +0 -0
  132. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/__init__.py +0 -0
  133. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/env_group.py +0 -0
  134. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/README.md +0 -0
  135. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/__init__.py +0 -0
  136. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/cli_agent_env.py +0 -0
  137. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/README.md +0 -0
  138. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/__init__.py +0 -0
  139. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/_filter.py +0 -0
  140. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/composable_env.py +0 -0
  141. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harness.py +0 -0
  142. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
  143. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
  144. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
  145. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
  146. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
  147. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
  148. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/task.py +0 -0
  149. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
  150. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
  151. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
  152. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
  153. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
  154. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
  155. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/lean/__init__.py +0 -0
  156. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/lean/lean_task.py +0 -0
  157. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
  158. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
  159. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
  160. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
  161. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
  162. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
  163. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
  164. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
  165. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
  166. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
  167. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
  168. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
  169. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
  170. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
  171. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
  172. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
  173. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
  174. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
  175. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
  176. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
  177. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
  178. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
  179. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
  180. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
  181. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
  182. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
  183. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/gym_env.py +0 -0
  184. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
  185. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/harbor_env/env.py +0 -0
  186. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
  187. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/mcp_env.py +0 -0
  188. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/opencode_env.py +0 -0
  189. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
  190. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
  191. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
  192. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/utils/__init__.py +0 -0
  193. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/utils/file_locks.py +0 -0
  194. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
  195. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/README.md +0 -0
  196. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/__init__.py +0 -0
  197. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/README.md +0 -0
  198. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
  199. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
  200. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
  201. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
  202. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
  203. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
  204. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/openenv_env.py +0 -0
  205. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
  206. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/textarena_env.py +0 -0
  207. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/multiturn_env.py +0 -0
  208. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/python_env.py +0 -0
  209. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/sandbox_env.py +0 -0
  210. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/singleturn_env.py +0 -0
  211. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/stateful_tool_env.py +0 -0
  212. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/tool_env.py +0 -0
  213. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/errors.py +0 -0
  214. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/gepa/__init__.py +0 -0
  215. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/gepa/adapter.py +0 -0
  216. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/gepa/config.py +0 -0
  217. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/gepa/display.py +0 -0
  218. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/gepa/gepa_utils.py +0 -0
  219. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/parsers/__init__.py +0 -0
  220. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/parsers/maybe_think_parser.py +0 -0
  221. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/parsers/parser.py +0 -0
  222. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/parsers/think_parser.py +0 -0
  223. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/parsers/xml_parser.py +0 -0
  224. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/README.md +0 -0
  225. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/__init__.py +0 -0
  226. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/inference/__init__.py +0 -0
  227. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/inference/client.py +0 -0
  228. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/inference/server.py +0 -0
  229. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/__init__.py +0 -0
  230. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/config.py +0 -0
  231. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/orchestrator.py +0 -0
  232. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/trainer.py +0 -0
  233. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/utils.py +0 -0
  234. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/__init__.py +0 -0
  235. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
  236. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/judge_rubric.py +0 -0
  237. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/math_rubric.py +0 -0
  238. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/rubric.py +0 -0
  239. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/rubric_group.py +0 -0
  240. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/__init__.py +0 -0
  241. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/build.py +0 -0
  242. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/gepa.py +0 -0
  243. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/init.py +0 -0
  244. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/install.py +0 -0
  245. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/rl.py +0 -0
  246. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/setup.py +0 -0
  247. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/train.py +0 -0
  248. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/tui.py +0 -0
  249. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/vllm.py +0 -0
  250. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/__init__.py +0 -0
  251. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/client/env_client.py +0 -0
  252. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/client/zmq_env_client.py +0 -0
  253. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/server/__init__.py +0 -0
  254. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/server/env_router.py +0 -0
  255. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/server/env_server.py +0 -0
  256. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/server/env_worker.py +0 -0
  257. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/server/zmq_env_server.py +0 -0
  258. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/types.py +0 -0
  259. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/__init__.py +0 -0
  260. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/client_utils.py +0 -0
  261. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/config_utils.py +0 -0
  262. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/data_utils.py +0 -0
  263. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/display_utils.py +0 -0
  264. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/env_config_utils.py +0 -0
  265. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/env_utils.py +0 -0
  266. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/error_utils.py +0 -0
  267. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/eval_display.py +0 -0
  268. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/heartbeat.py +0 -0
  269. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/import_utils.py +0 -0
  270. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/install_utils.py +0 -0
  271. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/logging_utils.py +0 -0
  272. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/message_utils.py +0 -0
  273. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/metric_utils.py +0 -0
  274. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/pricing_utils.py +0 -0
  275. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/process_utils.py +0 -0
  276. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/response_utils.py +0 -0
  277. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/serve_utils.py +0 -0
  278. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/thread_utils.py +0 -0
  279. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/threaded_sandbox_client.py +0 -0
  280. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/tool_utils.py +0 -0
  281. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/usage_utils.py +0 -0
  282. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/version_utils.py +0 -0
  283. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/ENVIRONMENT_BEST_PRACTICES.md +0 -0
  284. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/README.md +0 -0
  285. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/RE_MIGRATION.md +0 -0
  286. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/__init__.py +0 -0
  287. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/artifact.py +0 -0
  288. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/config.py +0 -0
  289. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/env.py +0 -0
  290. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/model.py +0 -0
  291. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/program.py +0 -0
  292. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/runtime.py +0 -0
  293. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/runtime_handles.py +0 -0
  294. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/sandbox.py +0 -0
  295. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/state.py +0 -0
  296. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/task.py +0 -0
  297. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/taskset.py +0 -0
  298. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/toolset.py +0 -0
  299. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/types.py +0 -0
  300. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/user.py +0 -0
  301. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/__init__.py +0 -0
  302. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/binding_utils.py +0 -0
  303. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/config_callable_utils.py +0 -0
  304. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/config_utils.py +0 -0
  305. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/json_utils.py +0 -0
  306. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/judge_utils.py +0 -0
  307. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/lifecycle_utils.py +0 -0
  308. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/logging_utils.py +0 -0
  309. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/mcp_proxy_utils.py +0 -0
  310. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/mcp_utils.py +0 -0
  311. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/object_utils.py +0 -0
  312. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/program_utils.py +0 -0
  313. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/prompt_utils.py +0 -0
  314. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/runtime_owner_utils.py +0 -0
  315. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/runtime_registry.py +0 -0
  316. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/sandbox_python_utils.py +0 -0
  317. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/scoring_utils.py +0 -0
  318. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/serialization_utils.py +0 -0
  319. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/task_freeze_utils.py +0 -0
  320. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/taskset_utils.py +0 -0
  321. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/tool_utils.py +0 -0
  322. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/toolset_utils.py +0 -0
  323. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/trajectory_utils.py +0 -0
  324. {verifiers-0.1.15.dev166 → 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.dev166
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
@@ -187,6 +187,28 @@ def test_taskset_take():
187
187
  assert isinstance(taken, MockSandboxTaskSet)
188
188
 
189
189
 
190
+ def test_composable_env_eval_inputs_can_shuffle_taskset_dataset():
191
+ taskset = MockTaskSet(dataset=_make_dataset(6), name="math")
192
+ env = ComposableEnv(
193
+ taskset=taskset,
194
+ harness=Harness(run_command="true"),
195
+ )
196
+
197
+ inputs = env._get_eval_inputs(
198
+ num_examples=3,
199
+ rollouts_per_example=2,
200
+ shuffle=True,
201
+ shuffle_seed=11,
202
+ )
203
+ expected = (
204
+ env.get_eval_dataset().shuffle(seed=11).select(range(3)).repeat(2).to_list()
205
+ )
206
+
207
+ assert [row["example_id"] for row in inputs] == [
208
+ row["example_id"] for row in expected
209
+ ]
210
+
211
+
190
212
  def test_taskset_repr():
191
213
  ts = MockTaskSet(dataset=_make_dataset(), name="mytest")
192
214
  assert "mytest" in repr(ts)
@@ -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."""
@@ -302,6 +302,30 @@ def test_evaluate_fallback_and_repeat(mock_client, make_dummy_env, make_input):
302
302
  assert len(states) == 2 * 2
303
303
 
304
304
 
305
+ def test_get_eval_inputs_shuffles_before_take_and_repeat(mock_client, make_dummy_env):
306
+ ds = Dataset.from_dict(
307
+ {
308
+ "question": [f"q{i}" for i in range(6)],
309
+ "answer": [f"a{i}" for i in range(6)],
310
+ }
311
+ )
312
+ env = make_dummy_env(mock_client, dataset=ds)
313
+
314
+ inputs = env._get_eval_inputs(
315
+ num_examples=3,
316
+ rollouts_per_example=2,
317
+ shuffle=True,
318
+ shuffle_seed=123,
319
+ )
320
+ expected = (
321
+ env.get_eval_dataset().shuffle(seed=123).select(range(3)).repeat(2).to_list()
322
+ )
323
+
324
+ assert [row["example_id"] for row in inputs] == [
325
+ row["example_id"] for row in expected
326
+ ]
327
+
328
+
305
329
  @pytest.mark.asyncio
306
330
  async def test_generate_inside_running_loop(mock_client, make_dummy_env, make_input):
307
331
  env = make_dummy_env(mock_client)
@@ -72,6 +72,8 @@ def run_cli(make_metadata, make_state, make_input):
72
72
  "headers_from_state": None,
73
73
  "num_examples": 1,
74
74
  "rollouts_per_example": 1,
75
+ "shuffle": False,
76
+ "shuffle_seed": None,
75
77
  "max_concurrent": 1,
76
78
  "independent_scoring": False,
77
79
  "max_tokens": 42,
@@ -177,6 +179,20 @@ def test_parse_args_rejects_unknown_eval_flags():
177
179
  vf_eval.parse_args(["env1", "--unknown-flag", "value"])
178
180
 
179
181
 
182
+ def test_cli_shuffle_defaults_seed_when_enabled(monkeypatch, run_cli):
183
+ captured = run_cli(
184
+ monkeypatch,
185
+ {
186
+ "shuffle": True,
187
+ "shuffle_seed": None,
188
+ },
189
+ )
190
+
191
+ config = captured["configs"][0]
192
+ assert config.shuffle is True
193
+ assert config.shuffle_seed == 0
194
+
195
+
180
196
  def test_cli_v1_env_config_overrides_preserve_env_args_config(
181
197
  tmp_path: Path, monkeypatch, run_cli
182
198
  ):
@@ -1188,6 +1204,15 @@ def test_cli_toml_per_env_rollouts_per_example(monkeypatch, run_cli):
1188
1204
  assert configs[1].rollouts_per_example == 5
1189
1205
 
1190
1206
 
1207
+ def test_cli_toml_per_env_shuffle(monkeypatch, run_cli):
1208
+ with tempfile.NamedTemporaryFile(suffix=".toml", delete=False, mode="w") as f:
1209
+ f.write('[[eval]]\nenv_id = "env1"\nshuffle = true\nshuffle_seed = 321\n')
1210
+ f.flush()
1211
+ captured = run_cli(monkeypatch, {"env_id_or_config": f.name})
1212
+
1213
+ assert captured["configs"][0].shuffle_seed == 321
1214
+
1215
+
1191
1216
  def test_cli_toml_per_eval_settings_used(monkeypatch, run_cli):
1192
1217
  """TOML per-eval settings are used (CLI args ignored when using config)."""
1193
1218
  with tempfile.NamedTemporaryFile(suffix=".toml", delete=False, mode="w") as f:
@@ -70,6 +70,53 @@ def test_find_latest_incomplete_eval_results_path_returns_none_when_no_match(
70
70
  assert result is None
71
71
 
72
72
 
73
+ def test_find_latest_incomplete_eval_results_path_matches_shuffle_metadata(
74
+ tmp_path: Path, monkeypatch
75
+ ):
76
+ env_id = "dummy-env"
77
+ model = "openai/gpt-4.1-mini"
78
+ runs_dir = tmp_path / "outputs" / "evals" / f"{env_id}--{model.replace('/', '--')}"
79
+
80
+ matching_run = runs_dir / "matching"
81
+ wrong_seed_run = runs_dir / "wrong-seed"
82
+ for run in [matching_run, wrong_seed_run]:
83
+ run.mkdir(parents=True)
84
+ (run / "results.jsonl").write_text('{"example_id":0}\n', encoding="utf-8")
85
+
86
+ matching_run.joinpath("metadata.json").write_text(
87
+ (
88
+ '{"env_id":"dummy-env","model":"openai/gpt-4.1-mini",'
89
+ '"num_examples":4,"rollouts_per_example":1,'
90
+ '"shuffle":true,"shuffle_seed":123}'
91
+ ),
92
+ encoding="utf-8",
93
+ )
94
+ wrong_seed_run.joinpath("metadata.json").write_text(
95
+ (
96
+ '{"env_id":"dummy-env","model":"openai/gpt-4.1-mini",'
97
+ '"num_examples":4,"rollouts_per_example":1,'
98
+ '"shuffle":true,"shuffle_seed":456}'
99
+ ),
100
+ encoding="utf-8",
101
+ )
102
+
103
+ os.utime(matching_run, (1, 1))
104
+ os.utime(wrong_seed_run, (2, 2))
105
+ monkeypatch.chdir(tmp_path)
106
+
107
+ result = find_latest_incomplete_eval_results_path(
108
+ env_id=env_id,
109
+ model=model,
110
+ num_examples=4,
111
+ rollouts_per_example=1,
112
+ shuffle=True,
113
+ shuffle_seed=123,
114
+ env_dir_path=str(tmp_path / "environments"),
115
+ )
116
+
117
+ assert result.resolve() == matching_run
118
+
119
+
73
120
  def test_get_eval_runs_dir_uses_name_as_result_label(tmp_path: Path):
74
121
  runs_dir = get_eval_runs_dir(
75
122
  env_id="dummy-env",
@@ -31,6 +31,7 @@ from verifiers.utils.save_utils import (
31
31
  load_outputs,
32
32
  make_serializable,
33
33
  save_new_outputs,
34
+ save_metadata,
34
35
  states_to_outputs,
35
36
  truncate_malformed_trailing_line,
36
37
  validate_resume_metadata,
@@ -199,6 +200,37 @@ class TestSavingMetadata:
199
200
  metadata["base_url"] == "http://localhost:8000/v1,http://localhost:8001/v1"
200
201
  )
201
202
 
203
+ def test_save_metadata_records_default_shuffle_seed_for_resume(
204
+ self, tmp_path: Path
205
+ ):
206
+ results_path = tmp_path / "results"
207
+ builder = GenerateOutputsBuilder(
208
+ env_id="math-env",
209
+ env_args={},
210
+ model="test-model",
211
+ client=ClientConfig(api_base_url="http://localhost:8000/v1"),
212
+ num_examples=3,
213
+ rollouts_per_example=2,
214
+ state_columns=[],
215
+ sampling_args={},
216
+ results_path=results_path,
217
+ shuffle=True,
218
+ )
219
+ save_metadata(builder.build_metadata(), results_path)
220
+
221
+ assert (
222
+ json.loads((results_path / "metadata.json").read_text())["shuffle_seed"]
223
+ == 0
224
+ )
225
+ validate_resume_metadata(
226
+ results_path=results_path,
227
+ env_id="math-env",
228
+ model="test-model",
229
+ num_examples=3,
230
+ rollouts_per_example=2,
231
+ shuffle=True,
232
+ )
233
+
202
234
 
203
235
  class TestSavingResults:
204
236
  def test_response_usage_tokens_prompt_completion(self):
@@ -595,6 +627,35 @@ class TestResumeMetadataValidation:
595
627
  rollouts_per_example=2,
596
628
  )
597
629
 
630
+ def test_validate_resume_metadata_rejects_shuffle_mismatch(self, tmp_path: Path):
631
+ results_path = tmp_path / "results"
632
+ results_path.mkdir()
633
+ metadata_path = results_path / "metadata.json"
634
+ metadata_path.write_text(
635
+ json.dumps(
636
+ {
637
+ "env_id": "math-env",
638
+ "model": "test-model",
639
+ "num_examples": 3,
640
+ "rollouts_per_example": 2,
641
+ "shuffle": True,
642
+ "shuffle_seed": 123,
643
+ }
644
+ ),
645
+ encoding="utf-8",
646
+ )
647
+
648
+ with pytest.raises(ValueError, match="shuffle_seed"):
649
+ validate_resume_metadata(
650
+ results_path=results_path,
651
+ env_id="math-env",
652
+ model="test-model",
653
+ num_examples=3,
654
+ rollouts_per_example=2,
655
+ shuffle=True,
656
+ shuffle_seed=456,
657
+ )
658
+
598
659
 
599
660
  class TestBuilderPassAtK:
600
661
  """Tests for pass@k integration in GenerateOutputsBuilder."""
@@ -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
 
@@ -4,7 +4,7 @@ import types
4
4
 
5
5
  from datasets import Dataset
6
6
 
7
- from verifiers.v1 import Taskset
7
+ from verifiers.v1 import Env, Taskset
8
8
  from verifiers.v1.utils.taskset_utils import dataset_from_result, discover_sibling_dir
9
9
 
10
10
 
@@ -118,3 +118,25 @@ def test_taskset_skips_empty_skills_dir(tmp_path, monkeypatch) -> None:
118
118
 
119
119
  assert taskset.get_skills_dir() == skills_dir
120
120
  assert taskset.get_upload_dirs() == {"skills": skills_dir}
121
+
122
+
123
+ def test_v1_env_eval_inputs_can_shuffle_taskset_dataset() -> None:
124
+ class DemoTaskset(Taskset):
125
+ def load_tasks(self, split: str = "train"):
126
+ return [{"question": f"Reverse {i}.", "answer": str(i)} for i in range(6)]
127
+
128
+ env = Env(taskset=DemoTaskset())
129
+
130
+ inputs = env._get_eval_inputs(
131
+ num_examples=3,
132
+ rollouts_per_example=2,
133
+ shuffle=True,
134
+ shuffle_seed=7,
135
+ )
136
+ expected = (
137
+ env.get_eval_dataset().shuffle(seed=7).select(range(3)).repeat(2).to_list()
138
+ )
139
+
140
+ assert [row["example_id"] for row in inputs] == [
141
+ row["example_id"] for row in expected
142
+ ]
@@ -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",