verifiers 0.1.15.dev166__tar.gz → 0.1.15.dev167__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.dev167}/PKG-INFO +1 -1
  2. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_composable_env.py +22 -0
  3. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_environment_extra.py +24 -0
  4. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_eval_cli.py +25 -0
  5. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_path_utils.py +47 -0
  6. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_save_utils.py +61 -0
  7. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_taskset_utils.py +23 -1
  8. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/environment.py +52 -12
  9. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/eval.py +22 -0
  10. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/types.py +4 -0
  11. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/eval_utils.py +5 -1
  12. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/path_utils.py +8 -0
  13. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/save_utils.py +21 -0
  14. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/.gitignore +0 -0
  15. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/LICENSE +0 -0
  16. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/README.md +0 -0
  17. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/pyproject.toml +0 -0
  18. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/AGENTS.md +0 -0
  19. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/README.md +0 -0
  20. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/__init__.py +0 -0
  21. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/conftest.py +0 -0
  22. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_browser_env.py +0 -0
  23. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_build_script.py +0 -0
  24. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_cli_agent_env.py +0 -0
  25. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_client_auth_errors.py +0 -0
  26. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_client_config.py +0 -0
  27. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_client_multimodal_types.py +0 -0
  28. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_context_token_metrics.py +0 -0
  29. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_decorator_ranks.py +0 -0
  30. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_endpoint_registry.py +0 -0
  31. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_env_group.py +0 -0
  32. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_env_server.py +0 -0
  33. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_environment.py +0 -0
  34. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_envs.py +0 -0
  35. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_error_chain.py +0 -0
  36. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_eval_display.py +0 -0
  37. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_eval_utils.py +0 -0
  38. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_gepa_cli.py +0 -0
  39. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_gepa_utils.py +0 -0
  40. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_gym_env.py +0 -0
  41. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_harbor_env_mcp.py +0 -0
  42. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_imports.py +0 -0
  43. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_init_script.py +0 -0
  44. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_install_utils.py +0 -0
  45. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_interception_utils.py +0 -0
  46. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_langchain_deep_agents_wikispeedia.py +0 -0
  47. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_lean_task.py +0 -0
  48. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_logging.py +0 -0
  49. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_math_rubric.py +0 -0
  50. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_maybe_think_parser.py +0 -0
  51. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_mcp_search_env.py +0 -0
  52. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_message_utils.py +0 -0
  53. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_message_utils_multimodal.py +0 -0
  54. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_multiturn_env.py +0 -0
  55. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_nemorl_client.py +0 -0
  56. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_openai_chat_completions_token_client.py +0 -0
  57. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_openai_responses_client.py +0 -0
  58. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_opencode_harbor.py +0 -0
  59. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_opencode_rlm_env.py +0 -0
  60. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_openenv_client.py +0 -0
  61. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_parser.py +0 -0
  62. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_per_turn_timing.py +0 -0
  63. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_pricing_utils.py +0 -0
  64. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_prime_plugin.py +0 -0
  65. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_renderer_client.py +0 -0
  66. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_renderer_e2e.py +0 -0
  67. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_rlm_composable_env.py +0 -0
  68. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_rubric.py +0 -0
  69. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_rubric_group.py +0 -0
  70. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_sandbox_env.py +0 -0
  71. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_sandbox_mixin.py +0 -0
  72. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_setup_script.py +0 -0
  73. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_singleturn_env.py +0 -0
  74. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_stateful_tool_env.py +0 -0
  75. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_think_parser.py +0 -0
  76. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_tool_env.py +0 -0
  77. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_tool_utils.py +0 -0
  78. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_trajectory_processing.py +0 -0
  79. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_tui_info_formatting.py +0 -0
  80. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_types.py +0 -0
  81. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_bfcl.py +0 -0
  82. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_config_extension.py +0 -0
  83. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_empty_completions.py +0 -0
  84. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_endpoint_protocols.py +0 -0
  85. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_example_counts.py +0 -0
  86. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_group_reward_env.py +0 -0
  87. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_harbor_cli.py +0 -0
  88. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_mini_swe_agent.py +0 -0
  89. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_nemo_gym_harness.py +0 -0
  90. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_openenv_taskset.py +0 -0
  91. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_openreward_taskset.py +0 -0
  92. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_replay_harness.py +0 -0
  93. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_rlm_swe.py +0 -0
  94. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_runtime_lifecycle.py +0 -0
  95. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_scoring_functions.py +0 -0
  96. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_taskset_bindings.py +0 -0
  97. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_v1_textarena_taskset.py +0 -0
  98. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_wiki_search_v1.py +0 -0
  99. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_wordle_env.py +0 -0
  100. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_wordle_v1_env.py +0 -0
  101. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/tests/test_xml_parser.py +0 -0
  102. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/AGENTS.md +0 -0
  103. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/__init__.py +0 -0
  104. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/__init__.py +0 -0
  105. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/commands/__init__.py +0 -0
  106. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/commands/build.py +0 -0
  107. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/commands/eval.py +0 -0
  108. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/commands/gepa.py +0 -0
  109. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/commands/init.py +0 -0
  110. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/commands/install.py +0 -0
  111. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/commands/setup.py +0 -0
  112. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/plugins/__init__.py +0 -0
  113. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/plugins/prime.py +0 -0
  114. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/cli/tui.py +0 -0
  115. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/clients/__init__.py +0 -0
  116. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/clients/anthropic_messages_client.py +0 -0
  117. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/clients/client.py +0 -0
  118. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
  119. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/clients/openai_chat_completions_client.py +0 -0
  120. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
  121. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/clients/openai_completions_client.py +0 -0
  122. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/clients/openai_responses_client.py +0 -0
  123. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/clients/renderer_client.py +0 -0
  124. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/decorators.py +0 -0
  125. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/AGENTS.md +0 -0
  126. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/__init__.py +0 -0
  127. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/env_group.py +0 -0
  128. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/README.md +0 -0
  129. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/__init__.py +0 -0
  130. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/cli_agent_env.py +0 -0
  131. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/README.md +0 -0
  132. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/__init__.py +0 -0
  133. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/_filter.py +0 -0
  134. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/composable_env.py +0 -0
  135. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/harness.py +0 -0
  136. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
  137. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
  138. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
  139. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
  140. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
  141. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
  142. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/task.py +0 -0
  143. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
  144. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
  145. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
  146. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
  147. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
  148. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
  149. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/lean/__init__.py +0 -0
  150. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/lean/lean_task.py +0 -0
  151. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
  152. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
  153. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
  154. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
  155. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
  156. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
  157. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
  158. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
  159. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
  160. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
  161. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
  162. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
  163. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
  164. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
  165. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
  166. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
  167. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
  168. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
  169. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
  170. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
  171. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
  172. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
  173. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
  174. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
  175. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
  176. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
  177. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/gym_env.py +0 -0
  178. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
  179. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/harbor_env/env.py +0 -0
  180. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
  181. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/mcp_env.py +0 -0
  182. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/opencode_env.py +0 -0
  183. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
  184. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
  185. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
  186. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/utils/__init__.py +0 -0
  187. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/utils/file_locks.py +0 -0
  188. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
  189. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/README.md +0 -0
  190. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/__init__.py +0 -0
  191. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/browser_env/README.md +0 -0
  192. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
  193. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
  194. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
  195. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
  196. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
  197. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
  198. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/openenv_env.py +0 -0
  199. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
  200. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/integrations/textarena_env.py +0 -0
  201. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/multiturn_env.py +0 -0
  202. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/python_env.py +0 -0
  203. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/sandbox_env.py +0 -0
  204. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/singleturn_env.py +0 -0
  205. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/stateful_tool_env.py +0 -0
  206. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/envs/tool_env.py +0 -0
  207. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/errors.py +0 -0
  208. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/gepa/__init__.py +0 -0
  209. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/gepa/adapter.py +0 -0
  210. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/gepa/config.py +0 -0
  211. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/gepa/display.py +0 -0
  212. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/gepa/gepa_utils.py +0 -0
  213. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/parsers/__init__.py +0 -0
  214. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/parsers/maybe_think_parser.py +0 -0
  215. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/parsers/parser.py +0 -0
  216. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/parsers/think_parser.py +0 -0
  217. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/parsers/xml_parser.py +0 -0
  218. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rl/README.md +0 -0
  219. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rl/__init__.py +0 -0
  220. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rl/inference/__init__.py +0 -0
  221. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rl/inference/client.py +0 -0
  222. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rl/inference/server.py +0 -0
  223. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rl/trainer/__init__.py +0 -0
  224. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rl/trainer/config.py +0 -0
  225. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rl/trainer/orchestrator.py +0 -0
  226. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rl/trainer/trainer.py +0 -0
  227. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rl/trainer/utils.py +0 -0
  228. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rubrics/__init__.py +0 -0
  229. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
  230. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rubrics/judge_rubric.py +0 -0
  231. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rubrics/math_rubric.py +0 -0
  232. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rubrics/rubric.py +0 -0
  233. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/rubrics/rubric_group.py +0 -0
  234. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/__init__.py +0 -0
  235. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/build.py +0 -0
  236. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/gepa.py +0 -0
  237. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/init.py +0 -0
  238. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/install.py +0 -0
  239. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/rl.py +0 -0
  240. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/setup.py +0 -0
  241. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/train.py +0 -0
  242. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/tui.py +0 -0
  243. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/scripts/vllm.py +0 -0
  244. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/serve/__init__.py +0 -0
  245. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/serve/client/env_client.py +0 -0
  246. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/serve/client/zmq_env_client.py +0 -0
  247. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/serve/server/__init__.py +0 -0
  248. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/serve/server/env_router.py +0 -0
  249. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/serve/server/env_server.py +0 -0
  250. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/serve/server/env_worker.py +0 -0
  251. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/serve/server/zmq_env_server.py +0 -0
  252. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/serve/types.py +0 -0
  253. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/__init__.py +0 -0
  254. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/async_utils.py +0 -0
  255. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/client_utils.py +0 -0
  256. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/config_utils.py +0 -0
  257. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/data_utils.py +0 -0
  258. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/display_utils.py +0 -0
  259. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/env_config_utils.py +0 -0
  260. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/env_utils.py +0 -0
  261. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/error_utils.py +0 -0
  262. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/eval_display.py +0 -0
  263. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/heartbeat.py +0 -0
  264. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/import_utils.py +0 -0
  265. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/install_utils.py +0 -0
  266. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/interception_utils.py +0 -0
  267. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/logging_utils.py +0 -0
  268. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/message_utils.py +0 -0
  269. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/metric_utils.py +0 -0
  270. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/pricing_utils.py +0 -0
  271. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/process_utils.py +0 -0
  272. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/response_utils.py +0 -0
  273. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/serve_utils.py +0 -0
  274. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/thread_utils.py +0 -0
  275. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/threaded_sandbox_client.py +0 -0
  276. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/tool_utils.py +0 -0
  277. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/usage_utils.py +0 -0
  278. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/utils/version_utils.py +0 -0
  279. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/ENVIRONMENT_BEST_PRACTICES.md +0 -0
  280. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/README.md +0 -0
  281. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/RE_MIGRATION.md +0 -0
  282. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/__init__.py +0 -0
  283. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/artifact.py +0 -0
  284. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/config.py +0 -0
  285. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/env.py +0 -0
  286. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/harness.py +0 -0
  287. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/model.py +0 -0
  288. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/program.py +0 -0
  289. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/runtime.py +0 -0
  290. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/runtime_handles.py +0 -0
  291. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/sandbox.py +0 -0
  292. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/state.py +0 -0
  293. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/task.py +0 -0
  294. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/taskset.py +0 -0
  295. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/toolset.py +0 -0
  296. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/types.py +0 -0
  297. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/user.py +0 -0
  298. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/__init__.py +0 -0
  299. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/binding_utils.py +0 -0
  300. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/config_callable_utils.py +0 -0
  301. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/config_utils.py +0 -0
  302. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/endpoint_utils.py +0 -0
  303. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/json_utils.py +0 -0
  304. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/judge_utils.py +0 -0
  305. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/lifecycle_utils.py +0 -0
  306. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/logging_utils.py +0 -0
  307. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/mcp_proxy_utils.py +0 -0
  308. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/mcp_utils.py +0 -0
  309. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/object_utils.py +0 -0
  310. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/program_utils.py +0 -0
  311. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/prompt_utils.py +0 -0
  312. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/runtime_owner_utils.py +0 -0
  313. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/runtime_registry.py +0 -0
  314. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/sandbox_program_utils.py +0 -0
  315. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/sandbox_python_utils.py +0 -0
  316. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/sandbox_utils.py +0 -0
  317. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/scoring_utils.py +0 -0
  318. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/serialization_utils.py +0 -0
  319. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/task_freeze_utils.py +0 -0
  320. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/taskset_utils.py +0 -0
  321. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/tool_utils.py +0 -0
  322. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/toolset_utils.py +0 -0
  323. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/verifiers/v1/utils/trajectory_utils.py +0 -0
  324. {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev167}/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.dev167
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)
@@ -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."""
@@ -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
+ ]
@@ -400,12 +400,13 @@ class Environment(ABC):
400
400
  self.build_dataset()
401
401
  if self.dataset is None:
402
402
  raise ValueError("dataset is not set")
403
+ dataset = self.dataset
403
404
  if seed is not None:
404
- self.dataset = self.dataset.shuffle(seed=seed)
405
+ dataset = dataset.shuffle(seed=seed)
405
406
  if n > 0:
406
- n = min(n, len(self.dataset))
407
- return self.dataset.select(range(n))
408
- return self.dataset
407
+ n = min(n, len(dataset))
408
+ return dataset.select(range(n))
409
+ return dataset
409
410
 
410
411
  @final
411
412
  def get_eval_dataset(self, n: int = -1, seed: int | None = None) -> "Dataset":
@@ -415,12 +416,13 @@ class Environment(ABC):
415
416
  "eval_dataset is not set, falling back to train dataset"
416
417
  )
417
418
  return self.get_dataset(n, seed)
419
+ eval_dataset = self.eval_dataset
418
420
  if seed is not None:
419
- self.eval_dataset = self.eval_dataset.shuffle(seed=seed)
421
+ eval_dataset = eval_dataset.shuffle(seed=seed)
420
422
  if n > 0:
421
- n = min(n, len(self.eval_dataset))
422
- return self.eval_dataset.select(range(n))
423
- return self.eval_dataset
423
+ n = min(n, len(eval_dataset))
424
+ return eval_dataset.select(range(n))
425
+ return eval_dataset
424
426
 
425
427
  @final
426
428
  def _get_usage_tracker(
@@ -831,6 +833,8 @@ class Environment(ABC):
831
833
  hf_hub_dataset_name: str | None = None,
832
834
  independent_scoring: bool = False,
833
835
  max_retries: int = 0,
836
+ shuffle: bool = False,
837
+ shuffle_seed: int | None = None,
834
838
  on_start: StartCallback | None = None,
835
839
  on_progress: ProgressCallback | list[ProgressCallback] | None = None,
836
840
  on_log: LogCallback | None = None,
@@ -934,6 +938,9 @@ class Environment(ABC):
934
938
  total_rollouts = len(raw_inputs)
935
939
  num_examples = len(set([i["example_id"] for i in raw_inputs]))
936
940
  rollouts_per_example = total_rollouts // num_examples if num_examples > 0 else 0
941
+ resolved_shuffle_seed = (
942
+ (0 if shuffle_seed is None else shuffle_seed) if shuffle else None
943
+ )
937
944
  builder = GenerateOutputsBuilder(
938
945
  env_id=self.env_id,
939
946
  env_args=self.env_args,
@@ -945,6 +952,8 @@ class Environment(ABC):
945
952
  sampling_args=sampling_args,
946
953
  results_path=results_path,
947
954
  pass_threshold=self.pass_threshold,
955
+ shuffle=shuffle,
956
+ shuffle_seed=resolved_shuffle_seed,
948
957
  )
949
958
 
950
959
  single_client: Client | None = None
@@ -989,6 +998,8 @@ class Environment(ABC):
989
998
  model=model,
990
999
  num_examples=num_examples,
991
1000
  rollouts_per_example=rollouts_per_example,
1001
+ shuffle=shuffle,
1002
+ shuffle_seed=resolved_shuffle_seed,
992
1003
  )
993
1004
  on_log(f"Resuming evaluation from {results_path}")
994
1005
  outputs = load_outputs(results_path)
@@ -1152,11 +1163,20 @@ class Environment(ABC):
1152
1163
 
1153
1164
  # evaluation
1154
1165
  def _get_eval_inputs(
1155
- self, num_examples: int = -1, rollouts_per_example: int = 1
1166
+ self,
1167
+ num_examples: int = -1,
1168
+ rollouts_per_example: int = 1,
1169
+ shuffle: bool = False,
1170
+ shuffle_seed: int | None = None,
1156
1171
  ) -> List[RolloutInput]:
1157
1172
  # get_eval_dataset handles fallback to train dataset if no eval source exists
1158
- inputs = self.get_eval_dataset(n=num_examples)
1173
+ inputs = self.get_eval_dataset()
1159
1174
  assert inputs is not None, "No dataset found"
1175
+ if shuffle:
1176
+ inputs = inputs.shuffle(seed=0 if shuffle_seed is None else shuffle_seed)
1177
+ if num_examples > 0:
1178
+ num_examples = min(num_examples, len(inputs))
1179
+ inputs = inputs.select(range(num_examples))
1160
1180
  if rollouts_per_example > 1:
1161
1181
  inputs = inputs.repeat(rollouts_per_example)
1162
1182
  return inputs.to_list()
@@ -1176,6 +1196,8 @@ class Environment(ABC):
1176
1196
  hf_hub_dataset_name: str | None = None,
1177
1197
  independent_scoring: bool = False,
1178
1198
  max_retries: int = 0,
1199
+ shuffle: bool = False,
1200
+ shuffle_seed: int | None = None,
1179
1201
  on_start: StartCallback | None = None,
1180
1202
  on_progress: ProgressCallback | list[ProgressCallback] | None = None,
1181
1203
  on_log: LogCallback | None = None,
@@ -1189,7 +1211,13 @@ class Environment(ABC):
1189
1211
  A single callback replaces the default. A list of callbacks runs
1190
1212
  alongside the default.
1191
1213
  """
1192
- inputs = self._get_eval_inputs(num_examples, rollouts_per_example)
1214
+ resolved_shuffle_seed = 0 if shuffle and shuffle_seed is None else shuffle_seed
1215
+ inputs = self._get_eval_inputs(
1216
+ num_examples,
1217
+ rollouts_per_example,
1218
+ shuffle=shuffle,
1219
+ shuffle_seed=resolved_shuffle_seed,
1220
+ )
1193
1221
  return await self.generate(
1194
1222
  inputs,
1195
1223
  client=client,
@@ -1203,6 +1231,8 @@ class Environment(ABC):
1203
1231
  hf_hub_dataset_name=hf_hub_dataset_name,
1204
1232
  independent_scoring=independent_scoring,
1205
1233
  max_retries=max_retries,
1234
+ shuffle=shuffle,
1235
+ shuffle_seed=resolved_shuffle_seed,
1206
1236
  on_start=on_start,
1207
1237
  on_progress=on_progress,
1208
1238
  on_log=on_log,
@@ -1224,11 +1254,19 @@ class Environment(ABC):
1224
1254
  hf_hub_dataset_name: str | None = None,
1225
1255
  independent_scoring: bool = False,
1226
1256
  max_retries: int = 0,
1257
+ shuffle: bool = False,
1258
+ shuffle_seed: int | None = None,
1227
1259
  ) -> GenerateOutputs:
1228
1260
  """
1229
1261
  Evaluate model on the Environment evaluation dataset synchronously.
1230
1262
  """
1231
- inputs = self._get_eval_inputs(num_examples, rollouts_per_example)
1263
+ resolved_shuffle_seed = 0 if shuffle and shuffle_seed is None else shuffle_seed
1264
+ inputs = self._get_eval_inputs(
1265
+ num_examples,
1266
+ rollouts_per_example,
1267
+ shuffle=shuffle,
1268
+ shuffle_seed=resolved_shuffle_seed,
1269
+ )
1232
1270
  return self.generate_sync(
1233
1271
  inputs,
1234
1272
  client=client,
@@ -1242,6 +1280,8 @@ class Environment(ABC):
1242
1280
  hf_hub_dataset_name=hf_hub_dataset_name,
1243
1281
  independent_scoring=independent_scoring,
1244
1282
  max_retries=max_retries,
1283
+ shuffle=shuffle,
1284
+ shuffle_seed=resolved_shuffle_seed,
1245
1285
  )
1246
1286
 
1247
1287
  # setters for use by trainers
@@ -473,6 +473,18 @@ def build_parser() -> argparse.ArgumentParser:
473
473
  default=None,
474
474
  help="Number of rollouts per example",
475
475
  )
476
+ parser.add_argument(
477
+ "--shuffle",
478
+ default=False,
479
+ action="store_true",
480
+ help="Shuffle the evaluation dataset before selecting examples",
481
+ )
482
+ parser.add_argument(
483
+ "--shuffle-seed",
484
+ type=int,
485
+ default=None,
486
+ help="Seed for --shuffle. Defaults to 0 when --shuffle is enabled.",
487
+ )
476
488
  parser.add_argument(
477
489
  "--max-concurrent",
478
490
  "-c",
@@ -712,6 +724,12 @@ def main(argv: list[str] | None = None):
712
724
  logger.debug(
713
725
  f"Using rollouts_per_example={rollouts_per_example} from {source}"
714
726
  )
727
+ shuffle = bool(raw.get("shuffle", False))
728
+ shuffle_seed = raw.get("shuffle_seed")
729
+ if shuffle and shuffle_seed is None:
730
+ shuffle_seed = 0
731
+ if not shuffle:
732
+ shuffle_seed = None
715
733
 
716
734
  raw_endpoint_id = raw.get("endpoint_id")
717
735
  raw_model_field = raw.get("model")
@@ -918,6 +936,8 @@ def main(argv: list[str] | None = None):
918
936
  model=model,
919
937
  num_examples=num_examples,
920
938
  rollouts_per_example=rollouts_per_example,
939
+ shuffle=shuffle,
940
+ shuffle_seed=shuffle_seed,
921
941
  env_dir_path=raw.get("env_dir_path", DEFAULT_ENV_DIR_PATH),
922
942
  output_dir=raw.get("output_dir"),
923
943
  name=name,
@@ -957,6 +977,8 @@ def main(argv: list[str] | None = None):
957
977
  sampling_args=merged_sampling_args,
958
978
  num_examples=num_examples,
959
979
  rollouts_per_example=rollouts_per_example,
980
+ shuffle=shuffle,
981
+ shuffle_seed=shuffle_seed,
960
982
  max_concurrent=raw.get("max_concurrent", DEFAULT_MAX_CONCURRENT),
961
983
  max_retries=raw.get("max_retries", 3),
962
984
  num_workers=raw.get("num_workers", "auto"),
@@ -1152,6 +1152,8 @@ class GenerateMetadata(TypedDict):
1152
1152
  base_url: str
1153
1153
  num_examples: int
1154
1154
  rollouts_per_example: int
1155
+ shuffle: NotRequired[bool]
1156
+ shuffle_seed: NotRequired[int | None]
1155
1157
  sampling_args: SamplingArgs
1156
1158
  date: str
1157
1159
  time: float # whole-eval wall-clock seconds
@@ -1340,6 +1342,8 @@ class EvalConfig(BaseModel):
1340
1342
  sampling_args: SamplingArgs
1341
1343
  num_examples: int
1342
1344
  rollouts_per_example: int
1345
+ shuffle: bool = False
1346
+ shuffle_seed: int | None = None
1343
1347
  max_concurrent: int
1344
1348
  num_workers: int | str = "auto"
1345
1349
  independent_scoring: bool = False
@@ -658,6 +658,8 @@ def load_toml_config(
658
658
  # evaluation
659
659
  "num_examples",
660
660
  "rollouts_per_example",
661
+ "shuffle",
662
+ "shuffle_seed",
661
663
  "max_concurrent",
662
664
  "independent_scoring",
663
665
  "max_retries",
@@ -1102,7 +1104,7 @@ async def run_evaluation(
1102
1104
 
1103
1105
  logger.debug(f"Starting evaluation with model: {config.model}")
1104
1106
  logger.debug(
1105
- f"Configuration: num_examples={config.num_examples}, rollouts_per_example={config.rollouts_per_example}, max_concurrent={config.max_concurrent}"
1107
+ f"Configuration: num_examples={config.num_examples}, rollouts_per_example={config.rollouts_per_example}, shuffle={config.shuffle}, shuffle_seed={config.shuffle_seed}, max_concurrent={config.max_concurrent}"
1106
1108
  )
1107
1109
 
1108
1110
  effective_group_max_concurrent = config.max_concurrent
@@ -1127,6 +1129,8 @@ async def run_evaluation(
1127
1129
  sampling_args=config.sampling_args,
1128
1130
  num_examples=config.num_examples,
1129
1131
  rollouts_per_example=config.rollouts_per_example,
1132
+ shuffle=config.shuffle,
1133
+ shuffle_seed=config.shuffle_seed,
1130
1134
  max_concurrent=effective_group_max_concurrent,
1131
1135
  results_path=results_path,
1132
1136
  state_columns=config.state_columns,
@@ -107,6 +107,8 @@ def find_latest_incomplete_eval_results_path(
107
107
  model: str,
108
108
  num_examples: int,
109
109
  rollouts_per_example: int,
110
+ shuffle: bool = False,
111
+ shuffle_seed: int | None = None,
110
112
  env_dir_path: str = "./environments",
111
113
  output_dir: str | None = None,
112
114
  name: str | None = None,
@@ -147,6 +149,12 @@ def find_latest_incomplete_eval_results_path(
147
149
  continue
148
150
  if metadata.get("rollouts_per_example") != rollouts_per_example:
149
151
  continue
152
+ if bool(metadata.get("shuffle", False)) != shuffle:
153
+ continue
154
+ if shuffle:
155
+ expected_shuffle_seed = 0 if shuffle_seed is None else shuffle_seed
156
+ if metadata.get("shuffle_seed") != expected_shuffle_seed:
157
+ continue
150
158
 
151
159
  saved_num_examples = metadata.get("num_examples")
152
160
  if not isinstance(saved_num_examples, int) or saved_num_examples > num_examples:
@@ -550,6 +550,8 @@ class GenerateOutputsBuilder:
550
550
  sampling_args: SamplingArgs,
551
551
  results_path: Path | None,
552
552
  pass_threshold: float = 0.5,
553
+ shuffle: bool = False,
554
+ shuffle_seed: int | None = None,
553
555
  ):
554
556
  self.env_id = env_id
555
557
  self.env_args = env_args
@@ -557,6 +559,10 @@ class GenerateOutputsBuilder:
557
559
  self.client = client
558
560
  self.num_examples = num_examples
559
561
  self.rollouts_per_example = rollouts_per_example
562
+ self.shuffle = shuffle
563
+ self.shuffle_seed = (
564
+ (0 if shuffle_seed is None else shuffle_seed) if shuffle else None
565
+ )
560
566
  self.state_columns = state_columns or []
561
567
  self.sampling_args = sampling_args
562
568
  self.results_path = results_path or get_results_path(env_id, model)
@@ -659,6 +665,8 @@ class GenerateOutputsBuilder:
659
665
  base_url=self.base_url,
660
666
  num_examples=self.num_examples,
661
667
  rollouts_per_example=self.rollouts_per_example,
668
+ shuffle=self.shuffle,
669
+ shuffle_seed=self.shuffle_seed,
662
670
  sampling_args=self.sampling_args,
663
671
  date=datetime.now().isoformat(),
664
672
  time=time.time() - self.start_time,
@@ -733,6 +741,8 @@ def validate_resume_metadata(
733
741
  model: str,
734
742
  num_examples: int,
735
743
  rollouts_per_example: int,
744
+ shuffle: bool = False,
745
+ shuffle_seed: int | None = None,
736
746
  ) -> None:
737
747
  """Validate saved metadata matches the current resume configuration.
738
748
 
@@ -778,6 +788,17 @@ def validate_resume_metadata(
778
788
  f"num_examples: saved={saved_num_examples!r}, current={num_examples!r} (current must be >= saved)"
779
789
  )
780
790
 
791
+ saved_shuffle = bool(saved_metadata.get("shuffle", False))
792
+ if saved_shuffle != shuffle:
793
+ mismatches.append(f"shuffle: saved={saved_shuffle!r}, current={shuffle!r}")
794
+ if shuffle:
795
+ expected_shuffle_seed = 0 if shuffle_seed is None else shuffle_seed
796
+ saved_shuffle_seed = saved_metadata.get("shuffle_seed", "<missing>")
797
+ if saved_shuffle_seed != expected_shuffle_seed:
798
+ mismatches.append(
799
+ f"shuffle_seed: saved={saved_shuffle_seed!r}, current={expected_shuffle_seed!r}"
800
+ )
801
+
781
802
  if mismatches:
782
803
  mismatch_text = "; ".join(mismatches)
783
804
  raise ValueError(