verifiers 0.2.2.dev25__tar.gz → 0.2.2.dev27__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.2.2.dev25 → verifiers-0.2.2.dev27}/PKG-INFO +1 -1
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/test_e2e.py +25 -14
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/test_judges.py +8 -6
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/__init__.py +2 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/dashboard/eval.py +9 -3
- verifiers-0.2.2.dev27/verifiers/v1/envs/agentic_judge/__init__.py +15 -0
- verifiers-0.2.2.dev27/verifiers/v1/envs/agentic_judge/env.py +347 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/legacy.py +2 -1
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/push.py +6 -4
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/trace.py +23 -7
- verifiers-0.2.2.dev25/verifiers/v1/envs/agentic_judge/__init__.py +0 -3
- verifiers-0.2.2.dev25/verifiers/v1/envs/agentic_judge/env.py +0 -174
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/.gitignore +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/LICENSE +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/README.md +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/pyproject.toml +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/conftest.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_browser_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_build_script.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_cli_agent_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_client_auth_errors.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_client_config.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_client_multimodal_types.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_composable_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_context_token_metrics.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_decorator_ranks.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_endpoint_registry.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_env_group.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_env_server.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_environment.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_environment_extra.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_error_chain.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_eval_display.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_eval_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_gepa_cli.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_gepa_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_gym_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_harbor_env_mcp.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_imports.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_init_script.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_install_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_interception_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_logging.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_math_rubric.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_maybe_think_parser.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_message_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_message_utils_multimodal.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_multiturn_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_nemorl_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_openai_chat_completions_token_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_openai_responses_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_opencode_rlm_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_openenv_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_parser.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_path_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_per_turn_timing.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_pricing_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_prime_plugin.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_renderer_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_renderer_e2e.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_rlm_composable_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_rubric.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_rubric_group.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_sandbox_debug_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_sandbox_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_sandbox_mixin.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_save_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_setup_script.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_singleturn_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_stateful_tool_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_think_parser.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_tool_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_tool_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_trajectory_processing.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_tui_info_formatting.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_types.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/test_xml_parser.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/conftest.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/counter_tool_v1.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/duet_v1.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/echo_acp_resume_v1.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/echo_agentic_v1.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/echo_multi_v0.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/echo_tool_v1.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/echo_user_sim_v1.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/echo_v0.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/echo_v1.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/pyproject.toml +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/fixtures/tool_response_image_v1.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/test_color_codeword_tasks.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/test_configs.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/test_envs.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/test_graph.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/test_legacy.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/test_scoring.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/test_taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/tests/v1/test_trace.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/commands/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/commands/build.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/commands/eval.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/commands/gepa.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/commands/init.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/commands/install.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/commands/setup.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/plugins/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/plugins/prime.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/cli/tui.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/clients/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/clients/anthropic_messages_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/clients/client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/clients/nemorl_chat_completions_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/clients/openai_chat_completions_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/clients/openai_chat_completions_token_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/clients/openai_completions_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/clients/openai_responses_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/clients/renderer_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/decorators.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/env_group.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/environment.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/README.md +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/cli_agent_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/README.md +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/_filter.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/composable_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/harnesses/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/harnesses/mini_swe_agent.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/harnesses/opencode.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/harnesses/prompt.txt +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/harnesses/rlm.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/sandbox_debug_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/swe_debug_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/task.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/cp/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/cp/cp_task.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/cp/test_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/harbor/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/harbor/cli_gym.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/harbor/harbor.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/harbor/terminal_lego.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/math/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/math/math_task.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/README.md +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/extract_fix_patch.sh +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/multi_swe/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/openswe/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/openswe/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/log_parser.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/r2e_gym/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/scale_swe/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/shared/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/shared/test_patch.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/swe_bench/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/swe_lego/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/log_parsers.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/swe_rebench_v2/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/swe_smith/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/composable/tasksets/swe/swe_tasksets.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/gym_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/harbor_env/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/harbor_env/env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/harbor_env/mcp.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/mcp_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/opencode_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/opencode_qa_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/opencode_rlm_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/sandbox_mixin.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/utils/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/utils/file_locks.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/experimental/utils/git_checkout_cache.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/README.md +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/browser_env/README.md +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/browser_env/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/browser_env/browser_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/browser_env/modes/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/browser_env/modes/base.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/browser_env/modes/cua_mode.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/browser_env/modes/dom_mode.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/openenv_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/reasoninggym_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/integrations/textarena_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/multiturn_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/python_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/sandbox_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/singleturn_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/stateful_tool_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/envs/tool_env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/errors.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/gepa/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/gepa/adapter.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/gepa/config.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/gepa/display.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/gepa/gepa_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/parsers/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/parsers/maybe_think_parser.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/parsers/parser.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/parsers/think_parser.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/parsers/xml_parser.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/rubrics/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/rubrics/experimental/hybrid_math_rubric.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/rubrics/judge_rubric.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/rubrics/math_rubric.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/rubrics/rubric.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/rubrics/rubric_group.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/scripts/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/scripts/build.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/scripts/eval.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/scripts/gepa.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/scripts/init.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/scripts/install.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/scripts/setup.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/scripts/tui.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/serve/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/serve/client/env_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/serve/client/zmq_env_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/serve/server/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/serve/server/env_router.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/serve/server/env_server.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/serve/server/env_worker.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/serve/server/zmq_env_server.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/serve/types.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/types.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/async_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/client_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/config_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/data_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/display_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/env_config_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/env_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/error_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/eval_display.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/eval_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/heartbeat.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/import_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/install_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/interception_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/logging_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/message_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/metric_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/path_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/pricing_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/process_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/response_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/save_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/serve_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/thread_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/threaded_sandbox_client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/tool_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/usage_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/utils/version_utils.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/acp/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/acp/_runner.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/agent.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/dashboard/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/dashboard/base.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/dashboard/replay.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/dashboard/validate.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/debug.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/eval/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/eval/main.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/eval/resume.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/eval/runner.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/gepa.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/init.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/output.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/replay.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/resolve.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/serve.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/cli/validate.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/clients/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/clients/client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/clients/config.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/clients/eval.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/clients/train.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/agent.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/cli/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/cli/debug.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/cli/env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/cli/eval.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/cli/init.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/cli/replay.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/cli/serve.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/cli/validate.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/judge.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/retries.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/task.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/configs/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/decorators.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/dialects/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/dialects/anthropic.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/dialects/base.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/dialects/chat.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/dialects/responses.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/envs/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/envs/best_of_n/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/envs/best_of_n/env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/envs/single_agent/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/envs/single_agent/env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/envs/user_sim/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/envs/user_sim/env.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/episode.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/errors.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/gepa/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/gepa/adapter.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/gepa/config.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/gepa/dataset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/gepa/reflection.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/gepa/runner.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/graph.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/bash/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/bash/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/bash/program.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/claude_code/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/claude_code/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/codex/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/codex/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/kimi_code/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/kimi_code/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/mini_swe_agent/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/mini_swe_agent/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/mini_swe_agent/program.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/null/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/null/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/null/program.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/pi/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/pi/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/pool/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/pool/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/rlm/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/rlm/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/terminus_2/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/terminus_2/harness.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/harnesses/terminus_2/program.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/interception/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/interception/base.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/interception/pool.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/interception/server.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/interception/tunnel/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/interception/tunnel/base.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/interception/tunnel/custom.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/interception/tunnel/prime.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/judge.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/judges/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/judges/reference.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/judges/reference.txt +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/judges/rubric.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/judges/rubric.txt +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/loaders.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/mcp/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/mcp/launch.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/mcp/server.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/mcp/toolset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/retries.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/rollout.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/runtimes/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/runtimes/base.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/runtimes/docker/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/runtimes/docker/egress.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/runtimes/limiters.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/runtimes/modal.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/runtimes/prime.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/runtimes/subprocess.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/scoring.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/serve/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/serve/client.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/serve/pool.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/serve/server.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/serve/types.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/session.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/state.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/task.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/tasksets/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/tasksets/harbor/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/tasksets/harbor/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/tasksets/lean/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/tasksets/lean/scoring.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/tasksets/lean/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/tasksets/openenv/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/tasksets/openenv/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/tasksets/textarena/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/tasksets/textarena/taskset.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/types.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/__init__.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/aio.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/compile.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/format.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/generic.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/git.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/image.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/install.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/interrupt.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/logging.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/memory.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/sampling.py +0 -0
- {verifiers-0.2.2.dev25 → verifiers-0.2.2.dev27}/verifiers/v1/utils/version.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: verifiers
|
|
3
|
-
Version: 0.2.2.
|
|
3
|
+
Version: 0.2.2.dev27
|
|
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
|
|
@@ -197,7 +197,7 @@ async def test_acp_resume_with_tool(run_v1, harness, harness_runtime, tmp_path):
|
|
|
197
197
|
)
|
|
198
198
|
assert trace.ok, trace.errors
|
|
199
199
|
assert trace.stop_condition == "user_closed"
|
|
200
|
-
assert trace.rewards["resumed"] == 1.0
|
|
200
|
+
assert trace.rewards["resumed"].score == 1.0
|
|
201
201
|
assert trace.tools # ACP-native tools, or Pi's MCP adapter meta-tool
|
|
202
202
|
segments = trace.info["acp_segments"]
|
|
203
203
|
assert len(segments) == 2
|
|
@@ -320,7 +320,7 @@ async def test_rubric_judge(run_v1, tmp_path):
|
|
|
320
320
|
max_turns=2,
|
|
321
321
|
)
|
|
322
322
|
assert trace.ok
|
|
323
|
-
assert trace.rewards["rubric"] > 0 # the judge's verdict landed in the reward
|
|
323
|
+
assert trace.rewards["rubric"].score > 0 # the judge's verdict landed in the reward
|
|
324
324
|
assert trace.metrics["rubric/always_yes"] == 1.0
|
|
325
325
|
assert trace.info["judge"] # the call was recorded onto the trace
|
|
326
326
|
|
|
@@ -392,23 +392,32 @@ async def test_env_id_best_of_n(run_v1, tmp_path):
|
|
|
392
392
|
|
|
393
393
|
@pytest.mark.e2e
|
|
394
394
|
async def test_env_id_agentic_judge(run_v1, tmp_path):
|
|
395
|
-
"""The agentic judge over the echo taskset (needs docker): the
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
395
|
+
"""The agentic judge over the echo taskset (needs docker): the box is
|
|
396
|
+
provisioned once from the solver's runtime policy, the solver plays in it,
|
|
397
|
+
the judge lands in the SAME box with the graded trace uploaded,
|
|
398
|
+
investigates with real execution, and its parsed verdict
|
|
399
|
+
lands on the solver's trace under the spec's reward key. Wiring, not taste:
|
|
400
|
+
the judge followed the verdict-file contract — the grade itself is the
|
|
401
|
+
model's call. Exercises the config surface too: a policy-only prompt
|
|
402
|
+
override (the verdict contract is appended regardless) and
|
|
403
|
+
reward-composition weights."""
|
|
400
404
|
traces = await run_v1(
|
|
401
405
|
"echo-v1",
|
|
402
406
|
harness=None, # seats pin their own harness; there is no run-level one
|
|
403
407
|
env={
|
|
404
408
|
"id": "agentic-judge",
|
|
405
|
-
|
|
406
|
-
|
|
409
|
+
# The solver owns the shared box, so the container is pinned here.
|
|
410
|
+
"solver": {"harness": {"id": "bash"}, "runtime": {"type": "docker"}},
|
|
411
|
+
# The judge reads the trace and reasons before it writes the
|
|
407
412
|
# verdict file; the shared 2048-token run cap truncates it mid-audit.
|
|
408
413
|
"judge": {
|
|
409
|
-
"
|
|
414
|
+
"harness": {"id": "bash"},
|
|
410
415
|
"max_output_tokens": 8192,
|
|
411
416
|
},
|
|
417
|
+
"task": {
|
|
418
|
+
"prompt": "Check EMPIRICALLY that the agent echoed the word back.",
|
|
419
|
+
},
|
|
420
|
+
"score": {"task_weight": 0.5},
|
|
412
421
|
},
|
|
413
422
|
output_dir=tmp_path,
|
|
414
423
|
max_turns=10,
|
|
@@ -419,9 +428,11 @@ async def test_env_id_agentic_judge(run_v1, tmp_path):
|
|
|
419
428
|
(judge,) = [t for t in traces if t.agent_name == "judge"]
|
|
420
429
|
assert solver.ok and judge.ok
|
|
421
430
|
assert judge.trainable is False
|
|
422
|
-
|
|
431
|
+
# The task's own reward keeps its raw score; the rescale lands on the weight.
|
|
432
|
+
assert solver.rewards["echoed"].score == 1.0
|
|
433
|
+
assert solver.rewards["echoed"].weight == 0.5
|
|
423
434
|
assert isinstance(judge.info.get("verdict"), dict) # scraped off the box
|
|
424
|
-
assert 0.0 <= solver.rewards["judge"] <= 1.0
|
|
435
|
+
assert 0.0 <= solver.rewards["judge"].score <= 1.0
|
|
425
436
|
|
|
426
437
|
|
|
427
438
|
@pytest.mark.e2e
|
|
@@ -482,7 +493,7 @@ async def test_env_id_user_sim_with_tools(run_v1, tmp_path):
|
|
|
482
493
|
assert assistant.ok and user.ok
|
|
483
494
|
assert assistant.task.data.prompt is None # the scenario stayed off the wire
|
|
484
495
|
assert user.num_turns >= 1 # the modeled user actually drove the exchange
|
|
485
|
-
assert assistant.rewards["echoed"] == 1.0 # the tool ran, mid-conversation
|
|
496
|
+
assert assistant.rewards["echoed"].score == 1.0 # the tool ran, mid-conversation
|
|
486
497
|
# The tool was advertised to the masked chat exactly as to any run.
|
|
487
498
|
assert assistant.tools is not None
|
|
488
499
|
assert any(tool.name == "echo_back" for tool in assistant.tools)
|
|
@@ -504,7 +515,7 @@ async def test_kuhn_poker_self_play(run_v1, tmp_path):
|
|
|
504
515
|
rollout_timeout=300,
|
|
505
516
|
)
|
|
506
517
|
assert sorted(t.agent_name for t in traces) == ["player0", "player1"]
|
|
507
|
-
payoffs = {t.agent_name: t.rewards["payoff"] for t in traces}
|
|
518
|
+
payoffs = {t.agent_name: t.rewards["payoff"].score for t in traces}
|
|
508
519
|
assert payoffs["player0"] + payoffs["player1"] == 0 # zero-sum
|
|
509
520
|
assert abs(payoffs["player0"]) in (1.0, 2.0)
|
|
510
521
|
for trace in traces:
|
|
@@ -453,7 +453,7 @@ async def test_error_attribution(monkeypatch, tmp_path):
|
|
|
453
453
|
# model failure: empty reply -> judge skipped, reward 0.0, NO error
|
|
454
454
|
trace = make_trace(reply="")
|
|
455
455
|
await JudgedTask(trace.task.data, taskset.config.task).score(trace, runtime=None)
|
|
456
|
-
assert trace.rewards["reference"] == 0.0
|
|
456
|
+
assert trace.rewards["reference"].score == 0.0
|
|
457
457
|
# judge failure: unparseable verdict -> the rollout errors, no reward recorded
|
|
458
458
|
trace = make_trace()
|
|
459
459
|
with pytest.raises(vf.TaskError, match="no yes/no verdict"):
|
|
@@ -623,11 +623,13 @@ async def test_task_score_runs_plugged_judges(tmp_path, fake_judge_model):
|
|
|
623
623
|
taskset = JudgedTaskset(cfg)
|
|
624
624
|
trace = make_trace()
|
|
625
625
|
await JudgedTask(trace.task.data, taskset.config.task).score(trace, runtime=None)
|
|
626
|
-
assert trace.rewards["own"] == 0.25 # decorated rewards still run
|
|
626
|
+
assert trace.rewards["own"].score == 0.25 # decorated rewards still run
|
|
627
|
+
assert trace.rewards["reference"] == vf.Reward(
|
|
628
|
+
score=1.0, weight=0.5
|
|
629
|
+
) # raw score + weight, under the id-derived name
|
|
627
630
|
assert (
|
|
628
|
-
trace.rewards["
|
|
629
|
-
) #
|
|
630
|
-
assert trace.rewards["quality"] == 0.75 # the rubric's aggregate, under its `name`
|
|
631
|
+
trace.rewards["quality"].score == 0.75
|
|
632
|
+
) # the rubric's aggregate, under its `name`
|
|
631
633
|
assert (
|
|
632
634
|
len(trace.info["judge"]) == 2
|
|
633
635
|
) # every judge call recorded (rubric = one call)
|
|
@@ -636,4 +638,4 @@ async def test_task_score_runs_plugged_judges(tmp_path, fake_judge_model):
|
|
|
636
638
|
async def test_task_without_judges_scores_as_before():
|
|
637
639
|
trace = make_trace()
|
|
638
640
|
await JudgedTask(trace.task.data).score(trace, runtime=None)
|
|
639
|
-
assert trace.rewards == {"own": 0.25}
|
|
641
|
+
assert trace.rewards == {"own": vf.Reward(score=0.25)}
|
|
@@ -107,6 +107,7 @@ from verifiers.v1.trace import (
|
|
|
107
107
|
EvalRunInfo,
|
|
108
108
|
GenerationSpan,
|
|
109
109
|
ModelCall,
|
|
110
|
+
Reward,
|
|
110
111
|
RunInfo,
|
|
111
112
|
TimeSpan,
|
|
112
113
|
TimeSplit,
|
|
@@ -171,6 +172,7 @@ __all__ = [
|
|
|
171
172
|
"Trace",
|
|
172
173
|
"TraceTask",
|
|
173
174
|
"WireTrace",
|
|
175
|
+
"Reward",
|
|
174
176
|
"Episode",
|
|
175
177
|
"WireEpisode",
|
|
176
178
|
"TRACE_VERSION",
|
|
@@ -341,13 +341,19 @@ def _score_segments(traces: list[Trace], source: str) -> str | None:
|
|
|
341
341
|
return None
|
|
342
342
|
segments = []
|
|
343
343
|
for name in names:
|
|
344
|
-
mean = format_mean(
|
|
345
|
-
traces, lambda t, n=name, s=source: getattr(t, s).get(n, 0.0)
|
|
346
|
-
)
|
|
344
|
+
mean = format_mean(traces, lambda t, n=name, s=source: _score(t, s, n))
|
|
347
345
|
segments.append(f"{name} {mean}")
|
|
348
346
|
return " · ".join(segments)
|
|
349
347
|
|
|
350
348
|
|
|
349
|
+
def _score(trace: Trace, source: str, name: str) -> float:
|
|
350
|
+
"""Rewards carry raw score + weight; the breakdown shows the raw score."""
|
|
351
|
+
if source == "rewards":
|
|
352
|
+
reward = trace.rewards.get(name)
|
|
353
|
+
return reward.score if reward is not None else 0.0
|
|
354
|
+
return trace.metrics.get(name, 0.0)
|
|
355
|
+
|
|
356
|
+
|
|
351
357
|
def _breakdown(scored: list[Trace], done: list[Trace]) -> Table | None:
|
|
352
358
|
"""Score rows read the policy view (`scored` — trainable traces); with several
|
|
353
359
|
roles in play they split per role, each role averaging over its OWN traces (no
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from verifiers.v1.envs.agentic_judge.env import (
|
|
2
|
+
AgenticJudgeEnv,
|
|
3
|
+
AgenticJudgeEnvConfig,
|
|
4
|
+
Criterion,
|
|
5
|
+
JudgeTaskConfig,
|
|
6
|
+
ScoreConfig,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"AgenticJudgeEnv",
|
|
11
|
+
"AgenticJudgeEnvConfig",
|
|
12
|
+
"Criterion",
|
|
13
|
+
"JudgeTaskConfig",
|
|
14
|
+
"ScoreConfig",
|
|
15
|
+
]
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
"""agentic-judge: a solver plays the task, a judge verifies it in the same box.
|
|
2
|
+
|
|
3
|
+
A reusable env (`--env.id agentic-judge` over any taskset): the box is
|
|
4
|
+
provisioned from the solver's runtime policy, the solver plays the task in it,
|
|
5
|
+
and a code-executing judge then inspects the work as the agent left it, with
|
|
6
|
+
the solver's full trace record uploaded at `/tmp/trace.json`. The judge grades
|
|
7
|
+
rubric criteria (`[env.task]`: policy prompt, criteria file) and writes its
|
|
8
|
+
verdicts to `/tmp/verdict.json`; `finalize()` validates them strictly onto the
|
|
9
|
+
solver's trace — `judge/<name>` metrics plus a weighted-mean `judge` reward,
|
|
10
|
+
composed with the taskset's own rewards via `[env.score]` (judge-only by
|
|
11
|
+
default).
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
import math
|
|
16
|
+
import re
|
|
17
|
+
import tomllib
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
from pydantic import field_validator
|
|
21
|
+
|
|
22
|
+
import verifiers.v1 as vf
|
|
23
|
+
from verifiers.v1.types import StrictBaseModel
|
|
24
|
+
|
|
25
|
+
VERDICT_FILE = "/tmp/verdict.json"
|
|
26
|
+
TRACE_FILE = "/tmp/trace.json"
|
|
27
|
+
|
|
28
|
+
GRADE_PROMPT = """\
|
|
29
|
+
You are grading another agent's attempt at a task. Verify the work EMPIRICALLY:
|
|
30
|
+
reconstruct what the agent did from its trace and test it with real execution
|
|
31
|
+
in your sandbox — never take the trace's word for an outcome you can check."""
|
|
32
|
+
|
|
33
|
+
TASK_SECTION = """\
|
|
34
|
+
## The task the agent was given
|
|
35
|
+
|
|
36
|
+
{prompt}"""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class Criterion(StrictBaseModel):
|
|
40
|
+
"""One rubric criterion — the plugged rubric judge's format, mirrored so the
|
|
41
|
+
same `criteria` files grade both judges."""
|
|
42
|
+
|
|
43
|
+
name: str
|
|
44
|
+
"""Key for the criterion's metric (`judge/<name>`)."""
|
|
45
|
+
text: str
|
|
46
|
+
weight: float = 1.0
|
|
47
|
+
"""The criterion's share of the reward."""
|
|
48
|
+
choices: list[str] = ["no", "yes"]
|
|
49
|
+
"""Allowed answers, ordered **worst → best**: the first scores 0.0, the last 1.0, the rest
|
|
50
|
+
evenly spaced by rank. Default `["no", "yes"]` is a binary check. Needs >= 2, no duplicates."""
|
|
51
|
+
|
|
52
|
+
@field_validator("choices")
|
|
53
|
+
@classmethod
|
|
54
|
+
def _check_choices(cls, v: list[str]) -> list[str]:
|
|
55
|
+
if len(v) < 2:
|
|
56
|
+
raise ValueError(f"`choices` needs at least two options, got {v}")
|
|
57
|
+
if len(set(v)) != len(v):
|
|
58
|
+
raise ValueError(f"`choices` has duplicate options: {v}")
|
|
59
|
+
return v
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
SOLVED = Criterion(
|
|
63
|
+
name="solved",
|
|
64
|
+
text="The task is fully solved: what the task asked for is achieved, and "
|
|
65
|
+
"you verified it with real execution.",
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _verdict_section(criteria: list[Criterion]) -> str:
|
|
70
|
+
listing = "\n".join(
|
|
71
|
+
f"- {c.name}: {c.text} (answer one of, worst to best: {', '.join(c.choices)})"
|
|
72
|
+
for c in criteria
|
|
73
|
+
)
|
|
74
|
+
return f"""\
|
|
75
|
+
## Your verdict
|
|
76
|
+
|
|
77
|
+
Grade the attempt on these criteria:
|
|
78
|
+
|
|
79
|
+
{listing}
|
|
80
|
+
|
|
81
|
+
When you are done verifying, write your verdict as JSON to `{VERDICT_FILE}`:
|
|
82
|
+
|
|
83
|
+
{{"verdicts": [{{"name": "<criterion name>", "reason": "<one sentence citing \
|
|
84
|
+
what you verified>", "verdict": "<answer>"}}, ...]}}
|
|
85
|
+
|
|
86
|
+
with one entry per criterion, using each criterion's exact name. For each, first
|
|
87
|
+
write the one-sentence reason grounded in what you actually verified, then set
|
|
88
|
+
verdict to exactly one of the options listed in parentheses after that
|
|
89
|
+
criterion."""
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _render(template: str, **fields: str) -> str:
|
|
93
|
+
"""Substitute documented placeholders in one pass over the original template —
|
|
94
|
+
str.format would crash on any literal brace in a custom prompt, and sequential
|
|
95
|
+
replaces would re-scan substituted values. An unknown placeholder stays as written."""
|
|
96
|
+
pattern = re.compile(r"\{(" + "|".join(map(re.escape, fields)) + r")\}")
|
|
97
|
+
return pattern.sub(lambda m: fields[m.group(1)], template)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
SANDBOX_NOTE = f"""\
|
|
101
|
+
## Your workspace
|
|
102
|
+
|
|
103
|
+
Your sandbox is the SAME box the graded agent worked in, in the state the agent
|
|
104
|
+
left it — its edits (and any scoring side effects) are applied. The agent's raw
|
|
105
|
+
trace record (JSON: messages, tool calls, and its `info` artifacts) is uploaded
|
|
106
|
+
at `{TRACE_FILE}`. The record can be very large — never dump it whole; peek
|
|
107
|
+
selectively (list its keys, then slice out specific fields with python or jq)
|
|
108
|
+
and pull only what you need. It is complete — it may also carry the task's own
|
|
109
|
+
scores/metrics and reference material (a gold answer, a reference solution,
|
|
110
|
+
held-out tests). Those are context, not your standard: recorded scores can be
|
|
111
|
+
wrong and references can be narrower than the task; do not over-index on how a
|
|
112
|
+
reference solves it. Your verdict is what YOU verified by execution."""
|
|
113
|
+
|
|
114
|
+
HINT_SECTION = """\
|
|
115
|
+
## Hints
|
|
116
|
+
|
|
117
|
+
{hint}"""
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class JudgeTask(vf.Task):
|
|
121
|
+
"""The judge's verdict task: the solver task's world mirrored onto the minted
|
|
122
|
+
row, the trace record written (and any stale verdict removed) before the
|
|
123
|
+
judge starts, verdict scraped off the live box after it exits. `NEEDS_CONTAINER`
|
|
124
|
+
keeps `Agent.run`'s per-task backstop aligned with the judge's declared need."""
|
|
125
|
+
|
|
126
|
+
NEEDS_CONTAINER = True
|
|
127
|
+
|
|
128
|
+
def __init__(self, data: vf.TaskData, files: dict[str, bytes]) -> None:
|
|
129
|
+
super().__init__(data)
|
|
130
|
+
self.files = files
|
|
131
|
+
|
|
132
|
+
@classmethod
|
|
133
|
+
def from_trace(cls, solution: vf.Trace, config: "JudgeTaskConfig") -> "JudgeTask":
|
|
134
|
+
"""Mint the judge's task from the solver's finished trace."""
|
|
135
|
+
solved = solution.task.data
|
|
136
|
+
files = {TRACE_FILE: json.dumps(solution.to_record()).encode()}
|
|
137
|
+
template = config.build_prompt()
|
|
138
|
+
body = _render(template, prompt=solved.prompt_text)
|
|
139
|
+
if "{prompt}" not in template:
|
|
140
|
+
# A policy that doesn't place the task statement itself still needs it.
|
|
141
|
+
body += "\n\n" + _render(TASK_SECTION, prompt=solved.prompt_text)
|
|
142
|
+
sections = [body, _verdict_section(config.criteria()), SANDBOX_NOTE]
|
|
143
|
+
if (hint := config.build_hint()) is not None:
|
|
144
|
+
sections.insert(1, _render(HINT_SECTION, hint=hint))
|
|
145
|
+
prompt = "\n\n".join(sections)
|
|
146
|
+
return cls(
|
|
147
|
+
vf.TaskData(
|
|
148
|
+
idx=solved.idx,
|
|
149
|
+
prompt=prompt,
|
|
150
|
+
image=solved.image,
|
|
151
|
+
workdir=solved.workdir,
|
|
152
|
+
resources=solved.resources,
|
|
153
|
+
),
|
|
154
|
+
files=files,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
async def setup(self, trace: vf.Trace, runtime: vf.Runtime) -> None:
|
|
158
|
+
# The solver had this box first: a pre-seeded verdict must never read as
|
|
159
|
+
# the judge's own, and a file (or planted symlink) at an upload path must
|
|
160
|
+
# never survive it — a symlinked TRACE_FILE would redirect the write onto
|
|
161
|
+
# any file the solver chose.
|
|
162
|
+
await runtime.run(["rm", "-f", VERDICT_FILE, *self.files], env={})
|
|
163
|
+
for path, content in self.files.items():
|
|
164
|
+
await runtime.write(path, content)
|
|
165
|
+
|
|
166
|
+
async def finalize(self, trace: vf.Trace, runtime: vf.Runtime) -> None:
|
|
167
|
+
"""Scrape the verdict off the box while it's alive. A judge that wrote no
|
|
168
|
+
file (or garbage) fails HERE — on the judge's own trace, the retryable
|
|
169
|
+
unit — never silently."""
|
|
170
|
+
try:
|
|
171
|
+
raw = await runtime.read(VERDICT_FILE)
|
|
172
|
+
except Exception as e:
|
|
173
|
+
raise ValueError(
|
|
174
|
+
f"the judge wrote no verdict to {VERDICT_FILE}; its final act must "
|
|
175
|
+
'be writing {"verdicts": [{"name", "reason", "verdict"}, ...]} there'
|
|
176
|
+
) from e
|
|
177
|
+
trace.info["verdict"] = json.loads(raw)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
class JudgeTaskConfig(vf.BaseConfig):
|
|
181
|
+
"""The judge's minted task: the grading policy and what lands in its box."""
|
|
182
|
+
|
|
183
|
+
prompt: Path | str | None = None
|
|
184
|
+
"""Grading-policy override: inline text, or a policy file (a value ending in
|
|
185
|
+
`.md`/`.txt` is read from disk). Replaces only the policy body — the verdict
|
|
186
|
+
contract and workspace note are always appended, so a custom policy cannot
|
|
187
|
+
break verdict scraping. May reference `{prompt}` (the solver task's prompt);
|
|
188
|
+
if it doesn't, the task statement is appended after the policy."""
|
|
189
|
+
hint: Path | str | None = None
|
|
190
|
+
"""Optional hints injected as their own section (inline text or a `.md`/
|
|
191
|
+
`.txt` file): task-family pointers into the trace or box — e.g. for math,
|
|
192
|
+
where the reference answer lives in the record; for SWE, to diff the repo
|
|
193
|
+
or read `info.patch`."""
|
|
194
|
+
rubric: Path | None = None
|
|
195
|
+
"""Criteria the judge grades against: a `.toml`/`.json` file with a
|
|
196
|
+
`criteria` list — the plugged rubric judge's format, so the same rubric
|
|
197
|
+
files work for both. None grades the single built-in `solved` criterion."""
|
|
198
|
+
|
|
199
|
+
@staticmethod
|
|
200
|
+
def _resolve(value: Path | str) -> str:
|
|
201
|
+
path = Path(value)
|
|
202
|
+
if isinstance(value, Path) or path.suffix in (".md", ".txt"):
|
|
203
|
+
return path.read_text(encoding="utf-8")
|
|
204
|
+
return str(value)
|
|
205
|
+
|
|
206
|
+
def build_prompt(self) -> str:
|
|
207
|
+
if self.prompt is None:
|
|
208
|
+
return GRADE_PROMPT + "\n\n" + TASK_SECTION
|
|
209
|
+
return self._resolve(self.prompt)
|
|
210
|
+
|
|
211
|
+
def build_hint(self) -> str | None:
|
|
212
|
+
return self._resolve(self.hint) if self.hint is not None else None
|
|
213
|
+
|
|
214
|
+
def criteria(self) -> list[Criterion]:
|
|
215
|
+
if self.rubric is None:
|
|
216
|
+
return [SOLVED]
|
|
217
|
+
text = self.rubric.read_text(encoding="utf-8")
|
|
218
|
+
data = (
|
|
219
|
+
tomllib.loads(text)
|
|
220
|
+
if self.rubric.suffix.lower() == ".toml"
|
|
221
|
+
else json.loads(text)
|
|
222
|
+
)
|
|
223
|
+
items = data.get("criteria", []) if isinstance(data, dict) else data
|
|
224
|
+
criteria = [Criterion.model_validate(item) for item in items]
|
|
225
|
+
if not criteria:
|
|
226
|
+
raise ValueError(f"rubric file '{self.rubric}' lists no criteria")
|
|
227
|
+
names = [criterion.name for criterion in criteria]
|
|
228
|
+
if len(set(names)) != len(names):
|
|
229
|
+
raise ValueError(
|
|
230
|
+
f"rubric file '{self.rubric}' has duplicate criterion names"
|
|
231
|
+
)
|
|
232
|
+
if bad := [c.name for c in criteria if not 0 <= c.weight < math.inf]:
|
|
233
|
+
raise ValueError(
|
|
234
|
+
f"rubric '{self.rubric}' has negative or non-finite criterion "
|
|
235
|
+
f"weights: {bad}"
|
|
236
|
+
)
|
|
237
|
+
if sum(criterion.weight for criterion in criteria) <= 0:
|
|
238
|
+
raise ValueError(f"rubric '{self.rubric}' has no positive criterion weight")
|
|
239
|
+
return criteria
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class ScoreConfig(vf.BaseConfig):
|
|
243
|
+
"""How the judge's verdict composes with the taskset's own rewards on the
|
|
244
|
+
solver's trace. Judge-only by default."""
|
|
245
|
+
|
|
246
|
+
task_weight: float = 0.0
|
|
247
|
+
"""Scale applied to the taskset's own rewards; 1 keeps them next to the verdict."""
|
|
248
|
+
judge_weight: float = 1.0
|
|
249
|
+
"""Weight of the judge's verdict in the solver's reward."""
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
class AgenticJudgeEnvConfig(vf.EnvConfig):
|
|
253
|
+
solver: vf.AgentConfig = vf.AgentConfig()
|
|
254
|
+
"""The solver agent. It owns the shared box, so its runtime must be a
|
|
255
|
+
container: `--env.solver.runtime.type docker|prime`."""
|
|
256
|
+
judge: vf.AgentConfig = vf.AgentConfig()
|
|
257
|
+
"""The judge agent. It plays in the solver's box; its own runtime policy is
|
|
258
|
+
ignored (overwritten with the solver's)."""
|
|
259
|
+
task: JudgeTaskConfig = JudgeTaskConfig()
|
|
260
|
+
score: ScoreConfig = ScoreConfig()
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
class AgenticJudgeEnv(vf.Env[AgenticJudgeEnvConfig]):
|
|
264
|
+
def __init__(self, config: AgenticJudgeEnvConfig) -> None:
|
|
265
|
+
# The judge plays in the solver's box, so its effective runtime IS the
|
|
266
|
+
# solver's policy — aligning the config keeps the base env's subprocess
|
|
267
|
+
# warning and the runtime stamped on the judge's trace truthful.
|
|
268
|
+
config.judge = config.judge.model_copy(
|
|
269
|
+
update={"runtime": config.solver.runtime}
|
|
270
|
+
)
|
|
271
|
+
super().__init__(config)
|
|
272
|
+
self._check_agents()
|
|
273
|
+
# A missing policy file or a malformed rubric fails here, not mid-episode.
|
|
274
|
+
config.task.build_prompt()
|
|
275
|
+
config.task.build_hint()
|
|
276
|
+
config.task.criteria()
|
|
277
|
+
|
|
278
|
+
def _check_agents(self) -> None:
|
|
279
|
+
"""The judge executes real code, never on the host — refuse an impossible
|
|
280
|
+
pairing at construction, not after burning a full solver run."""
|
|
281
|
+
judge = self._harnesses["judge"]
|
|
282
|
+
if not judge.EXECUTES_CODE:
|
|
283
|
+
raise ValueError(
|
|
284
|
+
"agentic-judge plays a code-executing judge in its own sandbox, but "
|
|
285
|
+
f"harness {judge.config.id!r} is a tool-less chat loop — a verdict "
|
|
286
|
+
"that needs no execution is a plugged judge "
|
|
287
|
+
"(--env.taskset.task.judges), not an agent."
|
|
288
|
+
)
|
|
289
|
+
if isinstance(self.config.solver.runtime, vf.SubprocessConfig):
|
|
290
|
+
raise ValueError(
|
|
291
|
+
"agentic-judge plays its judge in the solver's box, but the solver "
|
|
292
|
+
"(which provisions it) resolves to the subprocess runtime; use "
|
|
293
|
+
"--env.solver.runtime.type docker or prime"
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
async def setup(self, agents: vf.Agents) -> None:
|
|
297
|
+
# The judge grades the policy; its tokens are never training data.
|
|
298
|
+
agents.judge.trainable = False
|
|
299
|
+
|
|
300
|
+
async def run(self, task: vf.Task, agents: vf.Agents) -> None:
|
|
301
|
+
async with agents.solver.provision(task) as box:
|
|
302
|
+
solution = await agents.solver.run(task, runtime=box)
|
|
303
|
+
judge_task = JudgeTask.from_trace(solution, self.config.task)
|
|
304
|
+
await agents.judge.run(judge_task, runtime=box)
|
|
305
|
+
|
|
306
|
+
async def finalize(self, task: vf.Task, episode: vf.Episode) -> None:
|
|
307
|
+
by_agent = {t.agent_name: t for t in episode.traces}
|
|
308
|
+
solution, verdict = by_agent["solver"], by_agent["judge"]
|
|
309
|
+
data = verdict.info.get("verdict")
|
|
310
|
+
if not isinstance(data, dict) or not isinstance(data.get("verdicts"), list):
|
|
311
|
+
raise ValueError(
|
|
312
|
+
f"no verdicts on the judge's trace (expected {VERDICT_FILE} with a "
|
|
313
|
+
'"verdicts" list)'
|
|
314
|
+
)
|
|
315
|
+
criteria = self.config.task.criteria()
|
|
316
|
+
by_criterion = {c.name: c for c in criteria}
|
|
317
|
+
answers: dict[str, str] = {}
|
|
318
|
+
for entry in data["verdicts"]:
|
|
319
|
+
if not isinstance(entry, dict):
|
|
320
|
+
raise ValueError(f"verdict entry {entry!r} is not an object")
|
|
321
|
+
name = str(entry.get("name"))
|
|
322
|
+
if name in answers:
|
|
323
|
+
# Contradictory duplicates must not collapse to whichever came last.
|
|
324
|
+
raise ValueError(f"judge answered criterion {name!r} more than once")
|
|
325
|
+
answers[name] = str(entry.get("verdict"))
|
|
326
|
+
if sorted(answers) != sorted(by_criterion):
|
|
327
|
+
raise ValueError(
|
|
328
|
+
f"judge verdicts name {sorted(answers)}, expected the rubric's "
|
|
329
|
+
f"{sorted(by_criterion)}"
|
|
330
|
+
)
|
|
331
|
+
scores: dict[str, float] = {}
|
|
332
|
+
for name, answer in answers.items():
|
|
333
|
+
choices = by_criterion[name].choices
|
|
334
|
+
# An off-menu answer is a judge failure, not a zero score.
|
|
335
|
+
if answer not in choices:
|
|
336
|
+
raise ValueError(
|
|
337
|
+
f"judge answered {answer!r} for '{name}', expected one of {choices}"
|
|
338
|
+
)
|
|
339
|
+
scores[name] = choices.index(answer) / (len(choices) - 1)
|
|
340
|
+
for criterion in criteria:
|
|
341
|
+
solution.record_metric(f"judge/{criterion.name}", scores[criterion.name])
|
|
342
|
+
if self.config.score.task_weight != 1.0:
|
|
343
|
+
for reward in solution.rewards.values():
|
|
344
|
+
reward.weight *= self.config.score.task_weight
|
|
345
|
+
total = sum(criterion.weight for criterion in criteria)
|
|
346
|
+
reward = sum(c.weight * scores[c.name] for c in criteria) / total
|
|
347
|
+
solution.record_reward("judge", reward, weight=self.config.score.judge_weight)
|
|
@@ -37,6 +37,7 @@ from verifiers.v1.trace import (
|
|
|
37
37
|
Error,
|
|
38
38
|
GenerationSpan,
|
|
39
39
|
ModelCall,
|
|
40
|
+
Reward,
|
|
40
41
|
TimeSpan,
|
|
41
42
|
TimeSplit,
|
|
42
43
|
Timing,
|
|
@@ -270,7 +271,7 @@ def rollout_output_to_trace(out: dict, task_idx: int) -> Trace:
|
|
|
270
271
|
data=_to_wire_task(task_idx, out.get("prompt"), out.get("answer")),
|
|
271
272
|
),
|
|
272
273
|
tools=_to_v1_tools(out.get("tool_defs")),
|
|
273
|
-
rewards={"reward": float(out.get("reward") or 0.0)},
|
|
274
|
+
rewards={"reward": Reward(score=float(out.get("reward") or 0.0))},
|
|
274
275
|
metrics={k: float(v) for k, v in (out.get("metrics") or {}).items()},
|
|
275
276
|
info=dict(out.get("info") or {}),
|
|
276
277
|
is_completed=bool(out.get("is_completed", True)),
|
|
@@ -90,9 +90,10 @@ def trace_to_sample(
|
|
|
90
90
|
else None,
|
|
91
91
|
"info": dict(trace.info) or None,
|
|
92
92
|
}
|
|
93
|
-
# Flatten sub-rewards to top-level keys the way v0 does
|
|
94
|
-
|
|
95
|
-
|
|
93
|
+
# Flatten sub-rewards to top-level keys the way v0 does (raw scores, as v0's
|
|
94
|
+
# per-function outputs were); env metrics stay nested.
|
|
95
|
+
for name, reward in trace.rewards.items():
|
|
96
|
+
sample.setdefault(name, reward.score)
|
|
96
97
|
return sample
|
|
97
98
|
|
|
98
99
|
|
|
@@ -127,7 +128,8 @@ def _run_metrics(episodes: list[Episode], traces: list[Trace]) -> dict[str, Any]
|
|
|
127
128
|
sums: dict[str, float] = {}
|
|
128
129
|
counts: dict[str, int] = {}
|
|
129
130
|
for trace in scored:
|
|
130
|
-
for name,
|
|
131
|
+
scores = {name: reward.score for name, reward in trace.rewards.items()}
|
|
132
|
+
for name, value in {**scores, **trace.metrics}.items():
|
|
131
133
|
sums[name] = sums.get(name, 0.0) + value
|
|
132
134
|
counts[name] = counts.get(name, 0) + 1
|
|
133
135
|
n = len(scored)
|
|
@@ -266,7 +266,7 @@ _NODE_DUMP_EXCLUDE: dict = {
|
|
|
266
266
|
"""Raw tensor fields kept on the msgpack wire but excluded from JSON records."""
|
|
267
267
|
|
|
268
268
|
|
|
269
|
-
TRACE_VERSION =
|
|
269
|
+
TRACE_VERSION = 4
|
|
270
270
|
"""Version of the trace record schema (see `Trace.model_json_schema()`). Bumped on
|
|
271
271
|
breaking shape changes; optional-with-default fields are additive and don't bump it."""
|
|
272
272
|
|
|
@@ -343,6 +343,21 @@ class TraceTask(StrictBaseModel, Generic[DataT]):
|
|
|
343
343
|
"""The (immutable) row being solved."""
|
|
344
344
|
|
|
345
345
|
|
|
346
|
+
class Reward(StrictBaseModel):
|
|
347
|
+
"""One named reward as recorded on the trace: the raw score next to its weight,
|
|
348
|
+
so records keep both readable and the weighted sum stays a derived view."""
|
|
349
|
+
|
|
350
|
+
score: float
|
|
351
|
+
"""The raw value the reward function returned, unweighted."""
|
|
352
|
+
weight: float = 1.0
|
|
353
|
+
"""The multiplier `score` carries in the trace-level `reward` sum."""
|
|
354
|
+
|
|
355
|
+
@property
|
|
356
|
+
def value(self) -> float:
|
|
357
|
+
"""This reward's weighted contribution to the trace-level `reward`."""
|
|
358
|
+
return self.score * self.weight
|
|
359
|
+
|
|
360
|
+
|
|
346
361
|
class Trace(StrictBaseModel, Generic[DataT, StateT, AgentConfigT]):
|
|
347
362
|
id: str = Field(default_factory=lambda: uuid.uuid4().hex)
|
|
348
363
|
"""Unique id for this rollout, auto-generated per trace."""
|
|
@@ -369,8 +384,9 @@ class Trace(StrictBaseModel, Generic[DataT, StateT, AgentConfigT]):
|
|
|
369
384
|
"""Every provider exchange behind the sampled turns, in order: raw wire request/response
|
|
370
385
|
plus per-call timing and errors, linked into `nodes` via `ModelCall.node`."""
|
|
371
386
|
|
|
372
|
-
rewards: dict[str,
|
|
373
|
-
"""
|
|
387
|
+
rewards: dict[str, Reward] = Field(default_factory=dict)
|
|
388
|
+
"""Named rewards from tasks, judges, and the env's `score()` — each keeps its
|
|
389
|
+
raw `score` and `weight`; the trace-level `reward` is their weighted sum."""
|
|
374
390
|
metrics: dict[str, float] = Field(default_factory=dict)
|
|
375
391
|
"""Unweighted metrics from tasks, harnesses, and judges."""
|
|
376
392
|
info: dict[str, Any] = Field(default_factory=dict)
|
|
@@ -400,7 +416,7 @@ class Trace(StrictBaseModel, Generic[DataT, StateT, AgentConfigT]):
|
|
|
400
416
|
|
|
401
417
|
@property
|
|
402
418
|
def reward(self) -> float:
|
|
403
|
-
return sum(self.rewards.values())
|
|
419
|
+
return sum(r.value for r in self.rewards.values())
|
|
404
420
|
|
|
405
421
|
@property
|
|
406
422
|
def error(self) -> Error | None:
|
|
@@ -559,12 +575,12 @@ class Trace(StrictBaseModel, Generic[DataT, StateT, AgentConfigT]):
|
|
|
559
575
|
self.extra_usage.append(response.usage)
|
|
560
576
|
|
|
561
577
|
def record_reward(self, name: str, value: float, weight: float = 1.0) -> None:
|
|
562
|
-
|
|
578
|
+
reward = Reward(score=float(value), weight=float(weight))
|
|
563
579
|
if name in self.rewards:
|
|
564
580
|
logger.warning(
|
|
565
|
-
"reward %r overridden: %s -> %s", name, self.rewards[name],
|
|
581
|
+
"reward %r overridden: %s -> %s", name, self.rewards[name], reward
|
|
566
582
|
)
|
|
567
|
-
self.rewards[name] =
|
|
583
|
+
self.rewards[name] = reward
|
|
568
584
|
|
|
569
585
|
def stamp(self, run: RunInfo | None = None, **info: Any) -> None:
|
|
570
586
|
"""Stamp identity only the consumer knows (the eval CLI / a trainer) onto the
|