verifiers 0.1.15.dev418__tar.gz → 0.1.15.dev419__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.dev418 → verifiers-0.1.15.dev419}/PKG-INFO +1 -1
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/test_e2e.py +27 -0
- verifiers-0.1.15.dev419/tests/v1/test_judges.py +570 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/ARCHITECTURE.md +11 -8
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/GUIDE.md +89 -1
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/__init__.py +30 -3
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/env.py +2 -2
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harness.py +3 -3
- verifiers-0.1.15.dev419/verifiers/v1/judge.py +316 -0
- verifiers-0.1.15.dev419/verifiers/v1/judges/__init__.py +18 -0
- verifiers-0.1.15.dev419/verifiers/v1/judges/reference.py +112 -0
- verifiers-0.1.15.dev419/verifiers/v1/judges/reference.txt +18 -0
- verifiers-0.1.15.dev419/verifiers/v1/judges/rubric.py +165 -0
- verifiers-0.1.15.dev419/verifiers/v1/judges/rubric.txt +16 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/loaders.py +31 -10
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/task.py +12 -1
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/taskset.py +85 -9
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/trace.py +27 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/types.py +19 -8
- verifiers-0.1.15.dev418/verifiers/v1/judge.py +0 -180
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/.gitignore +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/LICENSE +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/pyproject.toml +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/AGENTS.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/conftest.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_browser_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_build_script.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_cli_agent_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_client_auth_errors.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_client_config.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_client_multimodal_types.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_composable_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_context_token_metrics.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_decorator_ranks.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_endpoint_registry.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_env_group.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_env_server.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_environment.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_environment_extra.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_envs.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_error_chain.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_eval_display.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_eval_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_gepa_cli.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_gepa_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_gym_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_harbor_env_mcp.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_imports.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_init_script.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_install_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_interception_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_logging.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_math_rubric.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_maybe_think_parser.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_message_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_message_utils_multimodal.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_multiturn_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_nemorl_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_openai_chat_completions_token_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_openai_responses_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_opencode_rlm_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_openenv_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_parser.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_path_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_per_turn_timing.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_pricing_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_prime_plugin.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_renderer_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_renderer_e2e.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_rlm_composable_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_rubric.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_rubric_group.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_sandbox_debug_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_sandbox_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_sandbox_mixin.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_save_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_setup_script.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_singleturn_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_stateful_tool_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_think_parser.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_tool_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_tool_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_trajectory_processing.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_tui_info_formatting.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_types.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_wordle_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/test_xml_parser.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/conftest.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/fixtures/counter_tool_v1.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/fixtures/echo_multi_v0.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/fixtures/echo_tool_v1.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/fixtures/echo_v0.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/fixtures/echo_v1.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/fixtures/pyproject.toml +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/test_color_codeword_tasks.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/test_configs.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/test_envs.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/test_graph.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/test_legacy.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/test_scoring.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/tests/v1/test_trace.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/AGENTS.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/commands/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/commands/build.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/commands/eval.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/commands/gepa.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/commands/init.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/commands/install.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/commands/setup.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/plugins/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/plugins/prime.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/cli/tui.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/clients/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/clients/anthropic_messages_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/clients/client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/clients/openai_chat_completions_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/clients/openai_completions_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/clients/openai_responses_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/clients/renderer_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/decorators.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/AGENTS.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/env_group.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/environment.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/cli_agent_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/_filter.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/composable_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/harness.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/sandbox_debug_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/task.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/harbor/cli_gym.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/harbor/terminal_lego.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/openseeker/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/openseeker/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/openseeker/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/api_tools/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/api_tools/tool_pdf.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/eval_toolkit.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/evaluator.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/llm_client/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/llm_client/base_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/prompts/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/prompts/cache_prompts.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/cache_filesys.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/load_eval_script.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/misc.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/tool_visit.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/utils/url_tools.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/obj_task_eval/verification_tree.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/open_ended.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/quest/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/redsearcher/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/search/search_tasksets.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/gym_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/harbor_env/env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/mcp_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/opencode_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/utils/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/utils/file_locks.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/browser_env/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/openenv_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/integrations/textarena_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/multiturn_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/python_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/sandbox_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/singleturn_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/stateful_tool_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/envs/tool_env.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/errors.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/gepa/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/gepa/adapter.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/gepa/config.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/gepa/display.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/gepa/gepa_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/parsers/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/parsers/maybe_think_parser.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/parsers/parser.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/parsers/think_parser.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/parsers/xml_parser.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rl/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rl/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rl/inference/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rl/inference/client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rl/inference/server.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rl/trainer/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rl/trainer/config.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rl/trainer/orchestrator.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rl/trainer/trainer.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rl/trainer/utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rubrics/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rubrics/judge_rubric.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rubrics/math_rubric.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rubrics/rubric.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/rubrics/rubric_group.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/build.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/eval.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/gepa.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/init.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/install.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/rl.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/setup.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/train.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/tui.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/scripts/vllm.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/serve/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/serve/client/env_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/serve/client/zmq_env_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/serve/server/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/serve/server/env_router.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/serve/server/env_server.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/serve/server/env_worker.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/serve/server/zmq_env_server.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/serve/types.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/types.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/async_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/client_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/config_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/data_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/display_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/env_config_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/env_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/error_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/eval_display.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/eval_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/heartbeat.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/import_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/install_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/interception_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/logging_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/message_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/metric_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/path_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/pricing_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/process_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/response_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/save_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/serve_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/thread_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/threaded_sandbox_client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/tool_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/usage_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/utils/version_utils.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/README.md +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/dashboard/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/dashboard/base.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/dashboard/eval.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/dashboard/validate.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/eval/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/eval/main.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/eval/resume.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/eval/runner.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/init.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/output.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/resolve.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/serve.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/cli/validate.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/clients/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/clients/client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/clients/config.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/clients/eval.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/clients/train.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/configs/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/configs/eval.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/configs/init.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/configs/serve.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/configs/validate.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/decorators.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/dialects/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/dialects/anthropic.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/dialects/base.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/dialects/chat.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/dialects/responses.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/episode.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/errors.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/graph.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/codex/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/codex/harness.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/default/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/default/harness.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/default/program.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/null/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/null/harness.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/null/program.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/rlm/harness.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/interception/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/interception/pool.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/interception/server.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/legacy.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/mcp/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/mcp/launch.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/mcp/server.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/mcp/toolset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/mcp/user.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/retries.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/rollout.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/runtimes/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/runtimes/base.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/runtimes/docker.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/runtimes/limiters.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/runtimes/modal.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/runtimes/prime.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/runtimes/subprocess.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/scoring.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/serve/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/serve/client.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/serve/pool.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/serve/server.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/serve/types.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/state.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/tasksets/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/tasksets/lean/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/tasksets/lean/scoring.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/tasksets/lean/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/utils/__init__.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/utils/format.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/utils/install.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/utils/logging.py +0 -0
- {verifiers-0.1.15.dev418 → verifiers-0.1.15.dev419}/verifiers/v1/utils/memory.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.dev419
|
|
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
|
|
@@ -190,6 +190,33 @@ async def test_tool_response_image(run_v1, tmp_path):
|
|
|
190
190
|
assert trace.reward == 1.0
|
|
191
191
|
|
|
192
192
|
|
|
193
|
+
@pytest.mark.e2e
|
|
194
|
+
async def test_rubric_judge(run_v1, tmp_path):
|
|
195
|
+
"""A config-plugged rubric judge scores the rollout on top of the taskset's own reward.
|
|
196
|
+
|
|
197
|
+
The single criterion is trivially satisfiable ("answer yes"), so any live judge model
|
|
198
|
+
scores it 1.0 — the test asserts the plumbing (config narrowing -> judge call -> reward +
|
|
199
|
+
per-criterion metric on the trace), not judge quality."""
|
|
200
|
+
rubric = tmp_path / "rubric.toml"
|
|
201
|
+
rubric.write_text(
|
|
202
|
+
"[[criteria]]\n"
|
|
203
|
+
'name = "always_yes"\n'
|
|
204
|
+
'text = "Always satisfied — answer yes regardless of the response."\n'
|
|
205
|
+
)
|
|
206
|
+
(trace,) = await run_v1(
|
|
207
|
+
"echo-v1",
|
|
208
|
+
harness="null",
|
|
209
|
+
harness_overrides={"runtime": {"type": "subprocess"}},
|
|
210
|
+
output_dir=tmp_path,
|
|
211
|
+
taskset_overrides={"judges": [{"id": "rubric", "path": str(rubric)}]},
|
|
212
|
+
max_turns=2,
|
|
213
|
+
)
|
|
214
|
+
assert trace.errors == []
|
|
215
|
+
assert trace.rewards["rubric"] > 0 # the judge's verdict landed in the reward
|
|
216
|
+
assert trace.metrics["rubric/always_yes"] == 1.0
|
|
217
|
+
assert trace.info["judge"] # the call was recorded onto the trace
|
|
218
|
+
|
|
219
|
+
|
|
193
220
|
@pytest.mark.e2e
|
|
194
221
|
async def test_agentic(run_v1, harness, harness_runtime, tmp_path):
|
|
195
222
|
"""Agentic: write a phrase to a file with the agent's shell, checked in the runtime."""
|
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
"""Pluggable judges: plugin resolution, base-`TasksetConfig.judges` narrowing, the built-in
|
|
2
|
+
`reference` / `rubric` judges, and `Taskset.score` running plugged judges after the decorated
|
|
3
|
+
rewards. Judge model calls are faked at `Judge.complete` — no network."""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
import verifiers.v1 as vf
|
|
11
|
+
from verifiers.v1.graph import MessageNode
|
|
12
|
+
from verifiers.v1.judge import Judge, JudgeResponse
|
|
13
|
+
from verifiers.v1.loaders import judge_class, judge_config_type, load_judge
|
|
14
|
+
from verifiers.v1.types import AssistantMessage, UserMessage
|
|
15
|
+
|
|
16
|
+
RUBRIC_TOML = """
|
|
17
|
+
[[criteria]]
|
|
18
|
+
name = "mentions_paris"
|
|
19
|
+
text = "The response mentions Paris."
|
|
20
|
+
weight = 3.0
|
|
21
|
+
|
|
22
|
+
[[criteria]]
|
|
23
|
+
name = "is_polite"
|
|
24
|
+
text = "The response is polite."
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class QATask(vf.Task):
|
|
29
|
+
answer: str = ""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def make_trace(reply: str = "It is Paris.") -> vf.Trace:
|
|
33
|
+
return vf.Trace(
|
|
34
|
+
task=QATask(idx=0, prompt="Capital of France?", answer="Paris"),
|
|
35
|
+
nodes=[
|
|
36
|
+
MessageNode(
|
|
37
|
+
parent=None,
|
|
38
|
+
message=UserMessage(content="Capital of France?"),
|
|
39
|
+
sampled=False,
|
|
40
|
+
),
|
|
41
|
+
MessageNode(
|
|
42
|
+
parent=0, message=AssistantMessage(content=reply), sampled=True
|
|
43
|
+
),
|
|
44
|
+
],
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@pytest.fixture
|
|
49
|
+
def fake_judge_model(monkeypatch):
|
|
50
|
+
"""Fake the judge's model call, recording each prompt for assertions. Text calls reply
|
|
51
|
+
"yes" iff "Paris" appears in the response block of the rendered prompt; structured
|
|
52
|
+
(`schema`) calls verdict each `- name: text` criteria line "yes" iff it mentions Paris."""
|
|
53
|
+
prompts: list[str] = []
|
|
54
|
+
|
|
55
|
+
async def fake_complete(
|
|
56
|
+
self, messages, *, trace=None, schema=None, parse=None, **sampling
|
|
57
|
+
):
|
|
58
|
+
prompts.append(messages)
|
|
59
|
+
if schema is not None:
|
|
60
|
+
verdicts = [
|
|
61
|
+
{"name": name, "verdict": "yes" if "Paris" in text else "no"}
|
|
62
|
+
for name, text in re.findall(r"^- ([^:]+): (.+)$", messages, re.M)
|
|
63
|
+
]
|
|
64
|
+
response = JudgeResponse(
|
|
65
|
+
text=json.dumps(verdicts),
|
|
66
|
+
parsed=schema.model_validate({"verdicts": verdicts}),
|
|
67
|
+
)
|
|
68
|
+
else:
|
|
69
|
+
response = JudgeResponse(
|
|
70
|
+
text="yes" if "Paris" in messages.split("Response:")[-1] else "no"
|
|
71
|
+
)
|
|
72
|
+
if parse is not None:
|
|
73
|
+
response.parsed = parse(response)
|
|
74
|
+
if trace is not None:
|
|
75
|
+
trace.record_judge(response)
|
|
76
|
+
return response
|
|
77
|
+
|
|
78
|
+
monkeypatch.setattr(Judge, "complete", fake_complete)
|
|
79
|
+
return prompts
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
# --- plugin resolution + config narrowing --------------------------------------------------
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_judge_plugin_resolution():
|
|
86
|
+
assert judge_class("reference") is vf.ReferenceJudge
|
|
87
|
+
assert judge_class("rubric") is vf.RubricJudge
|
|
88
|
+
assert judge_config_type("reference") is vf.ReferenceJudgeConfig
|
|
89
|
+
assert judge_config_type("rubric") is vf.RubricJudgeConfig
|
|
90
|
+
assert isinstance(load_judge(vf.ReferenceJudgeConfig()), vf.ReferenceJudge)
|
|
91
|
+
# built-ins pin their id, so a code-level default entry needs no explicit id
|
|
92
|
+
assert vf.ReferenceJudgeConfig().id == "reference"
|
|
93
|
+
assert vf.RubricJudgeConfig(path="x.toml").id == "rubric"
|
|
94
|
+
|
|
95
|
+
# a judge without the config generic falls back to the base JudgeConfig
|
|
96
|
+
class PlainJudge(vf.Judge[bool]):
|
|
97
|
+
prompt = "{x}"
|
|
98
|
+
|
|
99
|
+
assert type(PlainJudge().config) is vf.JudgeConfig
|
|
100
|
+
assert type(vf.ReferenceJudge().config) is vf.ReferenceJudgeConfig
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_taskset_config_narrows_judges(tmp_path):
|
|
104
|
+
# `judges` entries narrow to the config type their id resolves to (like taskset/harness
|
|
105
|
+
# narrowing in EnvConfig), so judge-specific fields validate against the real config —
|
|
106
|
+
# and survive model_dump (SerializeAsAny), which the env-server wire depends on.
|
|
107
|
+
rubric = tmp_path / "rubric.toml"
|
|
108
|
+
rubric.write_text(RUBRIC_TOML)
|
|
109
|
+
cfg = vf.TasksetConfig.model_validate(
|
|
110
|
+
{
|
|
111
|
+
"judges": [
|
|
112
|
+
{"id": "reference", "answer_field": "gold", "weight": 0.5},
|
|
113
|
+
{"id": "rubric", "path": str(rubric), "name": "quality"},
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
reference, rubric_cfg = cfg.judges
|
|
118
|
+
assert (
|
|
119
|
+
isinstance(reference, vf.ReferenceJudgeConfig)
|
|
120
|
+
and reference.answer_field == "gold"
|
|
121
|
+
)
|
|
122
|
+
assert isinstance(rubric_cfg, vf.RubricJudgeConfig) and rubric_cfg.name == "quality"
|
|
123
|
+
assert cfg.model_dump()["judges"][0]["answer_field"] == "gold"
|
|
124
|
+
# a round-trip through the dump re-narrows to the same types
|
|
125
|
+
again = vf.TasksetConfig.model_validate(cfg.model_dump())
|
|
126
|
+
assert isinstance(again.judges[0], vf.ReferenceJudgeConfig)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def test_judges_entry_requires_id():
|
|
130
|
+
with pytest.raises(ValueError, match="needs an `id`"):
|
|
131
|
+
vf.TasksetConfig.model_validate({"judges": [{"weight": 1.0}]})
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def test_rubric_config_requires_path():
|
|
135
|
+
# `path` is a required Path field: a plugged rubric judge without one fails at config time.
|
|
136
|
+
with pytest.raises(ValueError, match="path"):
|
|
137
|
+
vf.TasksetConfig.model_validate({"judges": [{"id": "rubric"}]})
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def test_judges_reject_shared_reward_keys():
|
|
141
|
+
# Ids may repeat (same plugin, two configs) — what must be unique is the derived reward
|
|
142
|
+
# key (`name`, else the id's package name), checked at config time.
|
|
143
|
+
with pytest.raises(ValueError, match="share a reward key"):
|
|
144
|
+
vf.TasksetConfig.model_validate(
|
|
145
|
+
{"judges": [{"id": "reference"}, {"id": "reference"}]}
|
|
146
|
+
)
|
|
147
|
+
cfg = vf.TasksetConfig.model_validate(
|
|
148
|
+
{
|
|
149
|
+
"judges": [
|
|
150
|
+
{"id": "reference", "name": "strict"},
|
|
151
|
+
{"id": "reference", "name": "lenient"},
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
)
|
|
155
|
+
assert [judge.name for judge in cfg.judges] == ["strict", "lenient"]
|
|
156
|
+
|
|
157
|
+
# class-level DEFAULTS are held to the same rule (they bypass the before-hook)
|
|
158
|
+
class TwoDefaults(vf.TasksetConfig):
|
|
159
|
+
judges: vf.Judges = [vf.ReferenceJudgeConfig(), vf.ReferenceJudgeConfig()]
|
|
160
|
+
|
|
161
|
+
with pytest.raises(ValueError, match="share a reward key"):
|
|
162
|
+
TwoDefaults()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def test_reward_name_fallback():
|
|
166
|
+
# name > id's package name > snake-cased class name (code-level judge with neither).
|
|
167
|
+
class MyQualityJudge(vf.Judge[float]):
|
|
168
|
+
prompt = "{x}"
|
|
169
|
+
|
|
170
|
+
assert (
|
|
171
|
+
vf.ReferenceJudge().reward_name == "reference"
|
|
172
|
+
) # class-name fallback (no id set)
|
|
173
|
+
assert (
|
|
174
|
+
vf.ReferenceJudge(vf.ReferenceJudgeConfig(id="org/my-judge@1.0.0")).reward_name
|
|
175
|
+
== "my-judge"
|
|
176
|
+
)
|
|
177
|
+
assert vf.ReferenceJudge(vf.ReferenceJudgeConfig(name="gold")).reward_name == "gold"
|
|
178
|
+
assert MyQualityJudge().reward_name == "my_quality"
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
async def test_base_judge_score_raises():
|
|
182
|
+
with pytest.raises(NotImplementedError, match="implements no `score`"):
|
|
183
|
+
await vf.Judge().score(task=QATask(idx=0, prompt="q"), trace=make_trace())
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# --- reference --------------------------------------------------------------------------------
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def test_reference_parse():
|
|
190
|
+
judge = vf.ReferenceJudge()
|
|
191
|
+
assert judge.parse(JudgeResponse(text="yes")) == 1.0
|
|
192
|
+
assert judge.parse(JudgeResponse(text="Final answer: NO")) == 0.0
|
|
193
|
+
# an unparseable verdict is a judge failure: raise (-> rollout error), don't score 0
|
|
194
|
+
with pytest.raises(ValueError, match="no yes/no verdict"):
|
|
195
|
+
judge.parse(JudgeResponse(text="gibberish"))
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
async def test_reference_score(fake_judge_model):
|
|
199
|
+
trace = make_trace()
|
|
200
|
+
verdict = await vf.ReferenceJudge(vf.ReferenceJudgeConfig(id="reference")).score(
|
|
201
|
+
trace.task, trace
|
|
202
|
+
)
|
|
203
|
+
assert verdict == 1.0
|
|
204
|
+
assert (
|
|
205
|
+
"Capital of France?" in fake_judge_model[0]
|
|
206
|
+
) # the task prompt is in the judge prompt
|
|
207
|
+
assert len(trace.info["judge"]) == 1 # the call is recorded onto the trace
|
|
208
|
+
|
|
209
|
+
trace = make_trace(reply="It is Rome.")
|
|
210
|
+
assert await vf.ReferenceJudge().score(trace.task, trace) == 0.0
|
|
211
|
+
|
|
212
|
+
judge = vf.ReferenceJudge(vf.ReferenceJudgeConfig(answer_field="gold"))
|
|
213
|
+
with pytest.raises(ValueError, match="no 'gold' field"): # misconfig raises, not 0
|
|
214
|
+
await judge.score(trace.task, trace)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
async def test_reference_score_messages_prompt(fake_judge_model):
|
|
218
|
+
# A Messages-form prompt still reaches the judge as text (via Task.prompt_text).
|
|
219
|
+
from verifiers.v1.types import TextContentPart, UserMessage as UM
|
|
220
|
+
|
|
221
|
+
task = QATask(
|
|
222
|
+
idx=0,
|
|
223
|
+
prompt=[UM(content=[TextContentPart(text="Capital of France?")])],
|
|
224
|
+
answer="Paris",
|
|
225
|
+
)
|
|
226
|
+
trace = vf.Trace(
|
|
227
|
+
task=task,
|
|
228
|
+
nodes=[
|
|
229
|
+
MessageNode(parent=None, message=UserMessage(content="q"), sampled=False),
|
|
230
|
+
MessageNode(
|
|
231
|
+
parent=0, message=AssistantMessage(content="It is Paris."), sampled=True
|
|
232
|
+
),
|
|
233
|
+
],
|
|
234
|
+
)
|
|
235
|
+
assert await vf.ReferenceJudge().score(task, trace) == 1.0
|
|
236
|
+
assert "Capital of France?" in fake_judge_model[0]
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
async def test_reference_question_field(fake_judge_model):
|
|
240
|
+
# question_field points {question} at a dedicated task field instead of the full prompt.
|
|
241
|
+
class FieldTask(vf.Task):
|
|
242
|
+
question: str = ""
|
|
243
|
+
answer: str = ""
|
|
244
|
+
|
|
245
|
+
task = FieldTask(
|
|
246
|
+
idx=0,
|
|
247
|
+
prompt="SYSTEM INSTRUCTIONS\n\nQuestion: Capital of France?",
|
|
248
|
+
question="Capital of France?",
|
|
249
|
+
answer="Paris",
|
|
250
|
+
)
|
|
251
|
+
trace = vf.Trace(
|
|
252
|
+
task=task,
|
|
253
|
+
nodes=[
|
|
254
|
+
MessageNode(parent=None, message=UserMessage(content="q"), sampled=False),
|
|
255
|
+
MessageNode(
|
|
256
|
+
parent=0, message=AssistantMessage(content="It is Paris."), sampled=True
|
|
257
|
+
),
|
|
258
|
+
],
|
|
259
|
+
)
|
|
260
|
+
await vf.ReferenceJudge(vf.ReferenceJudgeConfig(question_field="question")).score(
|
|
261
|
+
task, trace
|
|
262
|
+
)
|
|
263
|
+
assert "Capital of France?" in fake_judge_model[0]
|
|
264
|
+
assert "SYSTEM INSTRUCTIONS" not in fake_judge_model[0]
|
|
265
|
+
|
|
266
|
+
judge = vf.ReferenceJudge(vf.ReferenceJudgeConfig(question_field="typo"))
|
|
267
|
+
with pytest.raises(ValueError, match="no 'typo' field"):
|
|
268
|
+
await judge.score(task, trace)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def full_trace_fixture() -> vf.Trace:
|
|
272
|
+
"""A multi-turn trace: user -> assistant (reasoning + tool call) -> tool -> final reply."""
|
|
273
|
+
from verifiers.v1.types import ToolCall, ToolMessage
|
|
274
|
+
|
|
275
|
+
return vf.Trace(
|
|
276
|
+
task=QATask(idx=0, prompt="Capital of France?", answer="Paris"),
|
|
277
|
+
nodes=[
|
|
278
|
+
MessageNode(
|
|
279
|
+
parent=None,
|
|
280
|
+
message=UserMessage(content="Capital of France?"),
|
|
281
|
+
sampled=False,
|
|
282
|
+
),
|
|
283
|
+
MessageNode(
|
|
284
|
+
parent=0,
|
|
285
|
+
message=AssistantMessage(
|
|
286
|
+
content="Let me look it up.",
|
|
287
|
+
reasoning_content="SECRET REASONING",
|
|
288
|
+
tool_calls=[
|
|
289
|
+
ToolCall(id="1", name="search", arguments='{"q": "france"}')
|
|
290
|
+
],
|
|
291
|
+
),
|
|
292
|
+
sampled=True,
|
|
293
|
+
),
|
|
294
|
+
MessageNode(
|
|
295
|
+
parent=1,
|
|
296
|
+
message=ToolMessage(
|
|
297
|
+
tool_call_id="1",
|
|
298
|
+
name="search",
|
|
299
|
+
content="TOOL RESULT: Paris is the capital.",
|
|
300
|
+
),
|
|
301
|
+
sampled=False,
|
|
302
|
+
),
|
|
303
|
+
MessageNode(
|
|
304
|
+
parent=2, message=AssistantMessage(content="It is Paris."), sampled=True
|
|
305
|
+
),
|
|
306
|
+
],
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def test_transcript():
|
|
311
|
+
transcript = full_trace_fixture().transcript
|
|
312
|
+
assert "[user]\nCapital of France?" in transcript
|
|
313
|
+
assert '[tool_call search({"q": "france"})]' in transcript
|
|
314
|
+
assert "[tool search]\nTOOL RESULT: Paris is the capital." in transcript
|
|
315
|
+
assert "It is Paris." in transcript
|
|
316
|
+
assert "SECRET REASONING" not in transcript # reasoning is excluded
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
async def test_view_modes(fake_judge_model):
|
|
320
|
+
# last_reply (default): the judge sees only the final reply.
|
|
321
|
+
trace = full_trace_fixture()
|
|
322
|
+
await vf.ReferenceJudge().score(trace.task, trace)
|
|
323
|
+
assert "TOOL RESULT" not in fake_judge_model[0]
|
|
324
|
+
# full_trace: the whole transcript (minus reasoning) fills {response}.
|
|
325
|
+
trace = full_trace_fixture()
|
|
326
|
+
await vf.ReferenceJudge(vf.ReferenceJudgeConfig(view="full_trace")).score(
|
|
327
|
+
trace.task, trace
|
|
328
|
+
)
|
|
329
|
+
assert "TOOL RESULT: Paris is the capital." in fake_judge_model[1]
|
|
330
|
+
assert "SECRET REASONING" not in fake_judge_model[1]
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def test_view_defaults():
|
|
334
|
+
# reference grades the final answer; rubric grades the process by default.
|
|
335
|
+
assert vf.ReferenceJudgeConfig().view == "last_reply"
|
|
336
|
+
assert vf.RubricJudgeConfig(path="x.toml").view == "full_trace"
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
async def test_rubric_view_full_trace(tmp_path, fake_judge_model):
|
|
340
|
+
# The rubric judge's default view: criteria are judged against the whole transcript.
|
|
341
|
+
judge = rubric_judge(tmp_path)
|
|
342
|
+
trace = full_trace_fixture()
|
|
343
|
+
await judge.score(trace.task, trace)
|
|
344
|
+
assert all("TOOL RESULT" in prompt for prompt in fake_judge_model)
|
|
345
|
+
assert all("SECRET REASONING" not in prompt for prompt in fake_judge_model)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
async def test_config_prompt_overrides_class_template(fake_judge_model):
|
|
349
|
+
judge = vf.ReferenceJudge(
|
|
350
|
+
vf.ReferenceJudgeConfig(prompt="Q:{question} A:{answer} R:{response}")
|
|
351
|
+
)
|
|
352
|
+
assert judge.build_messages(question="q", answer="a", response="r") == "Q:q A:a R:r"
|
|
353
|
+
# A template needn't use every evaluate field: score also passes {positive}/{negative},
|
|
354
|
+
# which str.format ignores when the (custom) prompt doesn't reference them.
|
|
355
|
+
trace = make_trace()
|
|
356
|
+
assert await judge.score(trace.task, trace) == 1.0
|
|
357
|
+
assert fake_judge_model[0] == "Q:Capital of France? A:Paris R:It is Paris."
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
async def test_prompt_file(tmp_path, fake_judge_model):
|
|
361
|
+
# The prompt template can come from a file; the same {field} placeholders work.
|
|
362
|
+
file = tmp_path / "judge.txt"
|
|
363
|
+
file.write_text("Q:{question} A:{answer} R:{response}")
|
|
364
|
+
trace = make_trace()
|
|
365
|
+
judge = vf.ReferenceJudge(vf.ReferenceJudgeConfig(prompt_file=file))
|
|
366
|
+
assert await judge.score(trace.task, trace) == 1.0
|
|
367
|
+
assert fake_judge_model[0] == "Q:Capital of France? A:Paris R:It is Paris."
|
|
368
|
+
# a bad path fails at judge construction, not mid-eval at score time
|
|
369
|
+
with pytest.raises(FileNotFoundError):
|
|
370
|
+
vf.ReferenceJudge(vf.ReferenceJudgeConfig(prompt_file=tmp_path / "missing.txt"))
|
|
371
|
+
# inline and file prompts are mutually exclusive
|
|
372
|
+
with pytest.raises(ValueError, match="not both"):
|
|
373
|
+
vf.ReferenceJudgeConfig(prompt="inline", prompt_file=file)
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
# --- reference input/verdict knobs ------------------------------------------------------------
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
async def test_reference_empty_response_short_circuits(fake_judge_model):
|
|
380
|
+
# An empty reply scores 0 without paying for the (foregone) judge call.
|
|
381
|
+
trace = make_trace(reply="")
|
|
382
|
+
assert await vf.ReferenceJudge().score(trace.task, trace) == 0.0
|
|
383
|
+
assert fake_judge_model == []
|
|
384
|
+
assert "judge" not in trace.info
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
async def test_reference_list_answer(fake_judge_model):
|
|
388
|
+
# A list-valued answer field is judged as multiple acceptable answers, one per line.
|
|
389
|
+
class MultiTask(vf.Task):
|
|
390
|
+
aliases: list[str] = []
|
|
391
|
+
|
|
392
|
+
task = MultiTask(idx=0, prompt="q?", aliases=["Paris", "Lutetia"])
|
|
393
|
+
trace = make_trace()
|
|
394
|
+
await vf.ReferenceJudge(vf.ReferenceJudgeConfig(answer_field="aliases")).score(
|
|
395
|
+
task, trace
|
|
396
|
+
)
|
|
397
|
+
assert "Paris\nLutetia" in fake_judge_model[0]
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
async def test_reference_choices(fake_judge_model):
|
|
401
|
+
# Verdict labels are configurable; the positive (first) label scores 1.0 and the
|
|
402
|
+
# default prompt asks for the configured labels (not a hardcoded yes/no).
|
|
403
|
+
judge = vf.ReferenceJudge(vf.ReferenceJudgeConfig(choices=("A", "B")))
|
|
404
|
+
assert judge.parse(JudgeResponse(text="A")) == 1.0
|
|
405
|
+
assert judge.parse(JudgeResponse(text="Final verdict: B")) == 0.0
|
|
406
|
+
with pytest.raises(ValueError, match="no A/B verdict"):
|
|
407
|
+
judge.parse(JudgeResponse(text="gibberish"))
|
|
408
|
+
trace = make_trace()
|
|
409
|
+
with pytest.raises(
|
|
410
|
+
ValueError
|
|
411
|
+
): # the yes-replying fake is now an unparseable verdict
|
|
412
|
+
await judge.score(trace.task, trace)
|
|
413
|
+
assert 'Respond either "A" or "B"' in fake_judge_model[0]
|
|
414
|
+
# degenerate labels are a config error (duplicates would score every verdict 1.0)
|
|
415
|
+
for choices in (("yes", "yes"), ("A", "a"), ("", "no")):
|
|
416
|
+
with pytest.raises(ValueError, match="two distinct, non-empty"):
|
|
417
|
+
vf.ReferenceJudgeConfig(choices=choices)
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
async def test_error_attribution(monkeypatch, tmp_path):
|
|
421
|
+
# The policy: a MODEL failure scores 0.0; a JUDGE failure errors the rollout (raises
|
|
422
|
+
# out of Taskset.score as a TasksetError) so training skips the sample instead of
|
|
423
|
+
# punishing the model for a broken judge.
|
|
424
|
+
async def gibberish_judge(
|
|
425
|
+
self, messages, *, trace=None, schema=None, parse=None, **s
|
|
426
|
+
):
|
|
427
|
+
response = JudgeResponse(text="as an AI language model I cannot grade this")
|
|
428
|
+
try:
|
|
429
|
+
if parse is not None:
|
|
430
|
+
response.parsed = parse(response)
|
|
431
|
+
return response
|
|
432
|
+
finally:
|
|
433
|
+
if trace is not None:
|
|
434
|
+
trace.record_judge(response)
|
|
435
|
+
|
|
436
|
+
monkeypatch.setattr(Judge, "complete", gibberish_judge)
|
|
437
|
+
taskset = JudgedTaskset(
|
|
438
|
+
JudgedConfig.model_validate({"judges": [{"id": "reference"}]})
|
|
439
|
+
)
|
|
440
|
+
# model failure: empty reply -> judge skipped, reward 0.0, NO error
|
|
441
|
+
trace = make_trace(reply="")
|
|
442
|
+
await taskset.score(trace, runtime=None)
|
|
443
|
+
assert trace.rewards["reference"] == 0.0
|
|
444
|
+
# judge failure: unparseable verdict -> the rollout errors, no reward recorded
|
|
445
|
+
trace = make_trace()
|
|
446
|
+
with pytest.raises(vf.TasksetError, match="no yes/no verdict"):
|
|
447
|
+
await taskset.score(trace, runtime=None)
|
|
448
|
+
assert "reference" not in trace.rewards
|
|
449
|
+
assert len(trace.info["judge"]) == 1 # the billed call is still recorded
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
# --- rubric --------------------------------------------------------------------------------
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
def rubric_judge(
|
|
456
|
+
tmp_path, body: str = RUBRIC_TOML, suffix: str = ".toml", **kwargs
|
|
457
|
+
) -> vf.RubricJudge:
|
|
458
|
+
path = tmp_path / f"rubric{suffix}"
|
|
459
|
+
path.write_text(body)
|
|
460
|
+
return vf.RubricJudge(vf.RubricJudgeConfig(path=str(path), **kwargs))
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
def test_rubric_criteria_toml_and_json(tmp_path):
|
|
464
|
+
toml = rubric_judge(tmp_path).criteria
|
|
465
|
+
assert [c.name for c in toml] == ["mentions_paris", "is_polite"]
|
|
466
|
+
assert [c.weight for c in toml] == [3.0, 1.0]
|
|
467
|
+
# JSON: both the {"criteria": [...]} object and a bare list parse to the same rubric
|
|
468
|
+
items = [c.model_dump() for c in toml]
|
|
469
|
+
assert (
|
|
470
|
+
rubric_judge(tmp_path, json.dumps({"criteria": items}), ".json").criteria
|
|
471
|
+
== toml
|
|
472
|
+
)
|
|
473
|
+
assert rubric_judge(tmp_path, json.dumps(items), ".json").criteria == toml
|
|
474
|
+
# the suffix check is case-insensitive: QUALITY.TOML is TOML, not JSON
|
|
475
|
+
assert rubric_judge(tmp_path, suffix=".TOML").criteria == toml
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
def test_rubric_config_weight_overrides_file(tmp_path):
|
|
479
|
+
judge = rubric_judge(tmp_path, weights={"mentions_paris": 1.0})
|
|
480
|
+
assert [c.weight for c in judge.criteria] == [1.0, 1.0]
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def test_rubric_rejects_bad_files(tmp_path):
|
|
484
|
+
with pytest.raises(ValueError, match="no criteria"):
|
|
485
|
+
_ = rubric_judge(tmp_path, "").criteria
|
|
486
|
+
duplicate = RUBRIC_TOML.replace("is_polite", "mentions_paris")
|
|
487
|
+
with pytest.raises(ValueError, match="duplicate"):
|
|
488
|
+
_ = rubric_judge(tmp_path, duplicate).criteria
|
|
489
|
+
with pytest.raises(ValueError, match="name no criterion"):
|
|
490
|
+
_ = rubric_judge(tmp_path, weights={"typo": 2.0}).criteria
|
|
491
|
+
# all-zero weights fail while loading the rubric — before any judge call is paid for
|
|
492
|
+
with pytest.raises(ValueError, match="no positive criterion weight"):
|
|
493
|
+
_ = rubric_judge(
|
|
494
|
+
tmp_path, weights={"mentions_paris": 0.0, "is_polite": 0.0}
|
|
495
|
+
).criteria
|
|
496
|
+
# negative/NaN/inf weights would invert a criterion or corrupt the weighted mean
|
|
497
|
+
for weight in (-1.0, float("nan"), float("inf")):
|
|
498
|
+
with pytest.raises(ValueError, match="negative or non-finite"):
|
|
499
|
+
_ = rubric_judge(tmp_path, weights={"mentions_paris": weight}).criteria
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
async def test_rubric_score(tmp_path, fake_judge_model):
|
|
503
|
+
# verdicts: mentions_paris=1 (w=3), is_polite=0 (w=1) -> weighted mean 0.75, from ONE
|
|
504
|
+
# structured judge call; each verdict lands as a `<name>/<criterion>` metric.
|
|
505
|
+
judge = rubric_judge(tmp_path)
|
|
506
|
+
trace = make_trace()
|
|
507
|
+
assert await judge.score(trace.task, trace) == 0.75
|
|
508
|
+
assert trace.metrics == {"rubric/mentions_paris": 1.0, "rubric/is_polite": 0.0}
|
|
509
|
+
assert len(trace.info["judge"]) == 1 # one call for the whole rubric
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
async def test_rubric_verdict_mismatch_raises(tmp_path, monkeypatch):
|
|
513
|
+
# A reply that doesn't verdict exactly the rubric's criteria is a judge failure: raise
|
|
514
|
+
# (-> rollout error), don't guess or silently score 0.
|
|
515
|
+
async def wrong_names(self, messages, *, trace=None, schema=None, parse=None, **s):
|
|
516
|
+
verdicts = {"verdicts": [{"name": "typo", "verdict": "yes"}]}
|
|
517
|
+
return JudgeResponse(text="", parsed=schema.model_validate(verdicts))
|
|
518
|
+
|
|
519
|
+
monkeypatch.setattr(Judge, "complete", wrong_names)
|
|
520
|
+
judge = rubric_judge(tmp_path)
|
|
521
|
+
trace = make_trace()
|
|
522
|
+
with pytest.raises(ValueError, match="expected the rubric"):
|
|
523
|
+
await judge.score(trace.task, trace)
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
# --- Taskset.score integration -------------------------------------------------------------
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
class JudgedConfig(vf.TasksetConfig):
|
|
530
|
+
pass
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
class JudgedTaskset(vf.Taskset[QATask, JudgedConfig]):
|
|
534
|
+
def load_tasks(self) -> list[QATask]:
|
|
535
|
+
return []
|
|
536
|
+
|
|
537
|
+
@vf.reward
|
|
538
|
+
async def own(self, trace) -> float:
|
|
539
|
+
return 0.25
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
async def test_taskset_score_runs_plugged_judges(tmp_path, fake_judge_model):
|
|
543
|
+
rubric = tmp_path / "rubric.toml"
|
|
544
|
+
rubric.write_text(RUBRIC_TOML)
|
|
545
|
+
cfg = JudgedConfig.model_validate(
|
|
546
|
+
{
|
|
547
|
+
"judges": [
|
|
548
|
+
{"id": "reference", "weight": 0.5},
|
|
549
|
+
{"id": "rubric", "path": str(rubric), "name": "quality"},
|
|
550
|
+
]
|
|
551
|
+
}
|
|
552
|
+
)
|
|
553
|
+
taskset = JudgedTaskset(cfg)
|
|
554
|
+
trace = make_trace()
|
|
555
|
+
await taskset.score(trace, runtime=None)
|
|
556
|
+
assert trace.rewards["own"] == 0.25 # decorated rewards still run
|
|
557
|
+
assert (
|
|
558
|
+
trace.rewards["reference"] == 0.5
|
|
559
|
+
) # 1.0 * weight 0.5, under the id-derived name
|
|
560
|
+
assert trace.rewards["quality"] == 0.75 # the rubric's aggregate, under its `name`
|
|
561
|
+
assert (
|
|
562
|
+
len(trace.info["judge"]) == 2
|
|
563
|
+
) # every judge call recorded (rubric = one call)
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
async def test_taskset_without_judges_scores_as_before():
|
|
567
|
+
taskset = JudgedTaskset(JudgedConfig())
|
|
568
|
+
trace = make_trace()
|
|
569
|
+
await taskset.score(trace, runtime=None)
|
|
570
|
+
assert trace.rewards == {"own": 0.25}
|
|
@@ -237,11 +237,14 @@ from a native v1 one; both are an `EnvClient` away.
|
|
|
237
237
|
|
|
238
238
|
## Plugins & ids
|
|
239
239
|
|
|
240
|
-
Tasksets and
|
|
241
|
-
`name` (a local, importable package), `org/name`, or `org/name@version`;
|
|
242
|
-
installs the latter two from the Environments Hub on demand. A plugin module
|
|
243
|
-
`Taskset` / `Harness` subclass via `__all__`; `load_taskset` /
|
|
244
|
-
find that single subclass, and instantiate it,
|
|
245
|
-
config dict into the plugin's concrete config
|
|
246
|
-
ConfigT]` / `Harness[ConfigT]`
|
|
247
|
-
|
|
240
|
+
Tasksets, harnesses, and judges are packages resolved by `id` (`ids.py`, `loaders.py`). An
|
|
241
|
+
`ID` is `name` (a local, importable package), `org/name`, or `org/name@version`;
|
|
242
|
+
`ensure_installed` installs the latter two from the Environments Hub on demand. A plugin module
|
|
243
|
+
exports its `Taskset` / `Harness` / `Judge` subclass via `__all__`; `load_taskset` /
|
|
244
|
+
`load_harness` / `load_judge` import the module, find that single subclass, and instantiate it,
|
|
245
|
+
while `narrow_plugin_field` validates a generic config dict into the plugin's concrete config
|
|
246
|
+
type (read off the class's `Taskset[TaskT, ConfigT]` / `Harness[ConfigT]` / `Judge[ParsedT,
|
|
247
|
+
ConfigT]` generic) — so the typed CLI/TOML surfaces each plugin's own fields without the core
|
|
248
|
+
knowing them ahead of time. Judges are the lightweight third kind: attached to any eval via the
|
|
249
|
+
base `TasksetConfig.judges` (built-ins under `verifiers/v1/judges`) and run by `Taskset.score`
|
|
250
|
+
after the taskset's own rewards.
|