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.
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/PKG-INFO +1 -1
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_composable_env.py +22 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_environment.py +24 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_environment_extra.py +24 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_eval_cli.py +25 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_path_utils.py +47 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_save_utils.py +61 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_trajectory_processing.py +43 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_runtime_lifecycle.py +180 -3
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_taskset_utils.py +23 -1
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/anthropic_messages_client.py +6 -6
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/openai_responses_client.py +2 -2
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/environment.py +52 -12
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/eval.py +22 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/types.py +39 -1
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/async_utils.py +14 -15
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/eval_utils.py +5 -1
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/interception_utils.py +38 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/path_utils.py +8 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/save_utils.py +21 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/harness.py +9 -2
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/endpoint_utils.py +131 -25
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/sandbox_program_utils.py +40 -240
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/sandbox_utils.py +58 -17
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/.gitignore +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/LICENSE +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/README.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/pyproject.toml +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/AGENTS.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/README.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/conftest.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_browser_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_build_script.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_cli_agent_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_client_auth_errors.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_client_config.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_client_multimodal_types.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_context_token_metrics.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_decorator_ranks.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_endpoint_registry.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_env_group.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_env_server.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_envs.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_error_chain.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_eval_display.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_eval_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_gepa_cli.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_gepa_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_gym_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_harbor_env_mcp.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_imports.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_init_script.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_install_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_interception_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_langchain_deep_agents_wikispeedia.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_lean_task.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_logging.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_math_rubric.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_maybe_think_parser.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_mcp_search_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_message_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_message_utils_multimodal.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_multiturn_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_nemorl_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_openai_chat_completions_token_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_openai_responses_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_opencode_harbor.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_opencode_rlm_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_openenv_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_parser.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_per_turn_timing.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_pricing_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_prime_plugin.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_renderer_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_renderer_e2e.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_rlm_composable_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_rubric.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_rubric_group.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_sandbox_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_sandbox_mixin.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_setup_script.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_singleturn_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_stateful_tool_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_think_parser.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_tool_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_tool_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_tui_info_formatting.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_types.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_bfcl.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_config_extension.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_empty_completions.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_endpoint_protocols.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_example_counts.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_group_reward_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_harbor_cli.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_mini_swe_agent.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_nemo_gym_harness.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_openenv_taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_openreward_taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_replay_harness.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_rlm_swe.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_scoring_functions.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_taskset_bindings.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_v1_textarena_taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_wiki_search_v1.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_wordle_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_wordle_v1_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/tests/test_xml_parser.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/AGENTS.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/build.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/eval.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/gepa.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/init.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/install.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/commands/setup.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/plugins/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/plugins/prime.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/cli/tui.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/openai_chat_completions_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/openai_completions_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/renderer_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/decorators.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/AGENTS.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/env_group.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/README.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/cli_agent_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/README.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/_filter.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/composable_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harness.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/task.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/lean/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/lean/lean_task.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/gym_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/harbor_env/env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/mcp_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/opencode_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/utils/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/utils/file_locks.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/README.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/README.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/openenv_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/integrations/textarena_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/multiturn_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/python_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/sandbox_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/singleturn_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/stateful_tool_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/envs/tool_env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/errors.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/gepa/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/gepa/adapter.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/gepa/config.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/gepa/display.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/gepa/gepa_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/parsers/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/parsers/maybe_think_parser.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/parsers/parser.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/parsers/think_parser.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/parsers/xml_parser.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/README.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/inference/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/inference/client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/inference/server.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/config.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/orchestrator.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/trainer.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rl/trainer/utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/judge_rubric.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/math_rubric.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/rubric.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/rubrics/rubric_group.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/build.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/gepa.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/init.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/install.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/rl.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/setup.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/train.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/tui.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/scripts/vllm.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/client/env_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/client/zmq_env_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/server/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/server/env_router.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/server/env_server.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/server/env_worker.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/server/zmq_env_server.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/serve/types.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/client_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/config_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/data_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/display_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/env_config_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/env_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/error_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/eval_display.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/heartbeat.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/import_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/install_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/logging_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/message_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/metric_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/pricing_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/process_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/response_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/serve_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/thread_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/threaded_sandbox_client.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/tool_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/usage_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/utils/version_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/ENVIRONMENT_BEST_PRACTICES.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/README.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/RE_MIGRATION.md +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/artifact.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/config.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/env.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/model.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/program.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/runtime.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/runtime_handles.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/sandbox.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/state.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/task.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/taskset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/toolset.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/types.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/user.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/__init__.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/binding_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/config_callable_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/config_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/json_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/judge_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/lifecycle_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/logging_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/mcp_proxy_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/mcp_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/object_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/program_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/prompt_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/runtime_owner_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/runtime_registry.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/sandbox_python_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/scoring_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/serialization_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/task_freeze_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/taskset_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/tool_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/toolset_utils.py +0 -0
- {verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/v1/utils/trajectory_utils.py +0 -0
- {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.
|
|
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
|
|
1607
|
-
_ = state, messages
|
|
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
|
|
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
|
+
]
|
{verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/anthropic_messages_client.py
RENAMED
|
@@ -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:
|
{verifiers-0.1.15.dev166 → verifiers-0.1.15.dev168}/verifiers/clients/openai_responses_client.py
RENAMED
|
@@ -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
|
-
|
|
160
|
-
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",
|