benchflow 0.5.3.dev957__tar.gz → 0.5.3.dev978__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.
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/PKG-INFO +1 -1
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/pyproject.toml +1 -1
- benchflow-0.5.3.dev978/src/benchflow/_utils/dataset_registry.py +216 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/task_authoring.py +33 -1
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/cli/main.py +128 -3
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/evaluation.py +23 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rollout.py +21 -0
- benchflow-0.5.3.dev978/tests/fixtures/digest/README.md +9 -0
- benchflow-0.5.3.dev978/tests/fixtures/digest/alpha-task/environment/Dockerfile +1 -0
- benchflow-0.5.3.dev978/tests/fixtures/digest/alpha-task/instruction.md +3 -0
- benchflow-0.5.3.dev978/tests/fixtures/digest/alpha-task/task.toml +4 -0
- benchflow-0.5.3.dev978/tests/fixtures/digest/alpha-task/tests/test.sh +2 -0
- benchflow-0.5.3.dev978/tests/fixtures/digest/beta-task/data/unicode.txt +1 -0
- benchflow-0.5.3.dev978/tests/fixtures/digest/beta-task/instruction.md +1 -0
- benchflow-0.5.3.dev978/tests/fixtures/digest/beta-task/task.toml +1 -0
- benchflow-0.5.3.dev978/tests/fixtures/digest/not-a-task/notes.txt +1 -0
- benchflow-0.5.3.dev978/tests/test_dataset_registry.py +453 -0
- benchflow-0.5.3.dev978/tests/test_task_digest.py +161 -0
- benchflow-0.5.3.dev978/tests/trajectories/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/.gitignore +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/CHANGELOG.md +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/LICENSE +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/README.md +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_dotenv.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_paths.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_run.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_types.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/benchmark_repos.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/config.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/evaluation_results.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/json_safe.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/learner_memory.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/result_metadata.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/reward_events.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/scoring.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/source_provenance.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/_utils/yaml_loader.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/acp/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/acp/client.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/acp/container_transport.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/acp/runtime.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/acp/session.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/acp/transport.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/acp/types.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/adapters/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/adapters/harbor.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/adapters/inbound.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/adapters/inspect_ai.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/adapters/ors.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/adapters/terminal_bench.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/codex_config.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/credentials.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/env.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/errors.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/harvey_lab_acp_shim.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/install.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/openclaw_acp_shim.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/pi_acp_launcher.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/protocol.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/providers.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/agents/registry.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/branch.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/cli/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/cli/continue_cmd.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/cli/trace_import.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/compat/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/compat/harbor_registry.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/continue_run/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/continue_run/batch.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/continue_run/orchestrator.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/continue_run/replay_proxy.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/continue_run/run_folder.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/continue_run/sandbox_proxy.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/contracts/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/contracts/planes.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/contracts/user.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/demo_task/environment/Dockerfile +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/demo_task/instruction.md +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/demo_task/task.toml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/demo_task/tests/test.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/diagnostics.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/environment/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/environment/manifest.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/environment/manifest_env.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/environment/protocol.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/environment/readiness.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/eval_sharding.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/eval_worker.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/experimental/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/experimental/mcp/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/experimental/mcp/hooks.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/experimental/mcp/reviewer_server.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/hosted_env.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/learner_skills.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/learner_store.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/metrics.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/models.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/monitor.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/providers/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/providers/litellm_bedrock_patch.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/providers/litellm_bedrock_preflight.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/providers/litellm_config.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/providers/litellm_logging.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/providers/litellm_runtime.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/providers/runtime.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/py.typed +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/README.md +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/builtins.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/events.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/file_readers.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/llm.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/memory_scorer.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/node.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/protocol.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/rubric.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/rubric_config.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rewards/validation.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rollout_branch.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/rollout_planes.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/runtime.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/_base.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/_cache_reclaim.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/_compose.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/_compose_files/docker-compose-base.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/_compose_files/docker-compose-build.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/_compose_files/docker-compose-no-network.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/_compose_files/docker-compose-prebuilt.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/_sdk_ops.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/daytona.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/docker.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/lockdown.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/metadata.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/modal_impl.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/process.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/protocol.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/services.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/setup.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/snapshot.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sandbox/user.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/scenes.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/sdk.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/self_gen.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/skill_eval/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/skill_eval/_core.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/skill_eval/gepa_export.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/skill_eval/schema.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/skill_policy.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/skills.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/task/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/task/config.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/task/env.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/task/paths.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/task/task.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/task/verifier.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/templates/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/templates/judge.py.tmpl +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/templates/test.sh.tmpl +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/traces/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/traces/huggingface.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/traces/local.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/traces/models.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/traces/parsers.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/traces/task_gen.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/trajectories/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/trajectories/_capture.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/trajectories/export.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/trajectories/metrics.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/trajectories/otel.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/trajectories/tree.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/trajectories/types.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/trajectories/viewer.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/src/benchflow/usage_tracking.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/agents/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/agents/test_protocol.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/README.md +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/acp_smoke/environment/Dockerfile +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/acp_smoke/environment/docker-compose.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/acp_smoke/environment/skills/conformance-writer/SKILL.md +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/acp_smoke/instruction.md +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/acp_smoke/solution/solve.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/acp_smoke/task.toml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/acp_smoke/tests/test.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/conformance-results.json +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/proof_multi_agent.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/proof_snapshot.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/run_conformance.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conformance/self_gen_smoke_skills/skill-creator/SKILL.md +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/conftest.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/continue_run/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/continue_run/_helpers.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/continue_run/test_batch.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/continue_run/test_orchestrator.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/continue_run/test_replay_proxy.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/continue_run/test_run_folder.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/environment/__init__.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/environment/test_chibench_manifest.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/environment/test_clawsbench_manifest.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/environment/test_manifest.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/environment/test_manifest_env.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/environment/test_protocol.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/environment/test_readiness.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/hello-world-task/environment/Dockerfile +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/hello-world-task/instruction.md +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/hello-world-task/solution/solve.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/hello-world-task/task.toml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/hello-world-task/tests/test.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/terminal-bench-smoke-task/environment/Dockerfile +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/terminal-bench-smoke-task/instruction.md +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/terminal-bench-smoke-task/solution/solve.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/terminal-bench-smoke-task/task.toml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/terminal-bench-smoke-task/tests/test.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/terminal-bench-smoke-task/tests/test_state.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/test_claude.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/test_codex.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/test_codex_custom_provider.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/test_gemini.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/test_openclaw.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/traces/minimal-claude.jsonl +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/examples/traces/minimal-opentraces.jsonl +0 -0
- /benchflow-0.5.3.dev957/tests/trajectories/__init__.py → /benchflow-0.5.3.dev978/tests/fixtures/digest/beta-task/data/empty.bin +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/fixtures/mock_acp_agent.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/fixtures/mock_acp_agent_interleaved.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/fixtures/mock_acp_agent_multi_turn.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/fixtures/mock_openai_responses_server.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/check_adapter_evidence.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/check_hosted_env_evidence.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/check_results.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/check_skillsbench_harbor_parity.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/check_trace_to_task_evidence.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/configs/claude-agent-acp.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/configs/codex-acp.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/configs/gemini.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/configs/harvey-lab-harness.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/configs/openclaw.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/configs/opencode.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/configs/openhands.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/configs/pi-acp.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/run.sh +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/run_suite.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/integration/suites/release.yaml +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_acp.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_acp_capability_advertising.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_acp_model_config_dispatch.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_acp_pinned_protocol_guard.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_acp_setup_failure_propagation.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_adapter_scripts.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_adapters.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_agent_cli.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_agent_env_resolution.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_agent_gemini_defaults.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_agent_idle_timeout_cli.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_agent_model_decouple.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_agent_registry.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_agent_setup.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_agent_spec.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_base_install_imports.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_bedrock_thinking.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_branch.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_capture_trajectory.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_clawsbench_slice.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_cli_daytona.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_cli_docs_drift.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_cli_misc.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_compat_harbor_registry.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_config_redaction.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_connect_as_env.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_continuallearningbench_adapter.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_dashboard_credential_env_scrub.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_dashboard_daytona_key.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_dashboard_no_host_paths.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_dashboard_release_evidence.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_dashboard_roadmap.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_dashboard_symlink_ingestion.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_dashboard_sync.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_daytona_command_polling.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_daytona_litellm_runtime.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_daytona_status.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_docker_prune_scoping.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_docker_uploads.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_docs_examples.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_eng50_capabilities.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_env_setup.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_environment_manifest_controls.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_eval_filters_applied.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_eval_sharding.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_eval_single_task_summary.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_eval_source_provenance.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_eval_worker_retry.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_eval_zero_task_guard.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_evaluation_environment_manifest.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_exclude_tasks.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_experiments_status.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_harvey_lab_shim.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_hf_scores.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_hilbench_adapter.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_hosted_env.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_hosted_env_rollout_contract.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_inbound_adapter_manifest.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_inbound_adapters.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_integration_check_results.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_integration_run_suite.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_internet_policy.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_job.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_job_sequential_shared.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_job_sequential_shared_resume.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_judge_symlink_ingestion.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_learner_skills.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_learner_skills_traversal.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_learner_store.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_learner_store_persistence.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_litellm_config.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_litellm_hardening.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_litellm_logging.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_litellm_runtime.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_litellm_smoke.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_llm_judge.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_llm_judge_event_tags.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_llm_judge_verifier.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_memory_scorer.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_metrics.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_mock_openai_responses_server.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_monitor_scaffold.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_native_acp_usage.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_no_cross_provider_fallback.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_notification_order_real.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_oracle.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_oracle_chokepoint.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_paths_safe.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_paths_symlink_helpers.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_pi_acp_launcher.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_process.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_provider_auth_detection.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_providers.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_reexport.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_registry_invariants.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_release_version.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_resolve_env_helpers.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_reward_node.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_reward_unified_contract.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rewards.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rewards_jsonl.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rollout_architecture.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rollout_branch.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rollout_config_path_coercion.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rollout_environment.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rollout_import_no_side_effects.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rollout_on_ask_user_wiring.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rollout_probe_sandbox_health.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rollout_upload.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_rubric_config.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_runtime.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_runtime_config_wired.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_runtime_live_sandbox.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sandbox.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sandbox_exec_secret_handling.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sandbox_hardening.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sandbox_isolation_copy_traversal.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sandbox_multi_service.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sandbox_protocol.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sandbox_setup.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sandbox_snapshot_contract.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sandbox_upload_symlink.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sandbox_verifier_workspace.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_scene.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_scene_outbox_trial.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_scene_parallel_group.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_scene_result_aggregation.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_scoring.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sdk_internals.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_sdk_lockdown.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_self_gen_cli.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_self_gen_export_error_channel.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_self_gen_export_failures.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_self_gen_orchestration.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_session_request_permission_dispatch.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skill_eval.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skill_eval_dryrun.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skill_eval_integration.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skill_eval_sweep.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skill_eval_traversal.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skill_invocation_artifacts.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skill_policy.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skills.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skills_dir_agent_home_link.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skillsbench_harbor_parity.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skillsbench_harbor_run_suite.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_skillsbench_publish_scrub.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_smoke.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_subscription_auth.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_task_check_eval_consistency.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_task_config.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_task_download.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_tasks.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_token_usage_normalization.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_trace_import_cli.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_trace_task_gen_traversal.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_trace_to_task_evidence.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_traces_huggingface.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_traces_parsers.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_traces_task_gen.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_train_mode_artifact_emission.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_trajectory_integration.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_trajectory_streaming.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_trial_agent_timeout_verify.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_trial_install_agent_timeout.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_trial_litellm_runtime.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_usage_litellm.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_usage_required.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_usage_tracking.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_user.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_verifier_multi_container.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_verifier_output.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_verifier_output_freshness.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_verify.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_workflow_action_pinning.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/test_yaml_config.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/trajectories/test_export.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/trajectories/test_export_nan_handling.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/trajectories/test_redaction.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/trajectories/test_step_granularity.py +0 -0
- {benchflow-0.5.3.dev957 → benchflow-0.5.3.dev978}/tests/trajectories/test_tree.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: benchflow
|
|
3
|
-
Version: 0.5.3.
|
|
3
|
+
Version: 0.5.3.dev978
|
|
4
4
|
Summary: Multi-turn agent benchmarking with ACP — run any agent, any model, any provider.
|
|
5
5
|
Project-URL: Homepage, https://github.com/benchflow-ai/benchflow
|
|
6
6
|
Project-URL: Repository, https://github.com/benchflow-ai/benchflow
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"""Dataset registry resolution — `bench eval create -d skillsbench@1.1`.
|
|
2
|
+
|
|
3
|
+
Resolves a published dataset version from the skillsbench registry
|
|
4
|
+
(``registry.json``, see ``docs/dataset-versioning.md`` in
|
|
5
|
+
benchflow-ai/skillsbench): clones the pinned snapshot, verifies every
|
|
6
|
+
task's content digest against the registry entry, and hands back the
|
|
7
|
+
task set plus source provenance for result stamping.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import posixpath
|
|
12
|
+
import re
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
from urllib.request import urlopen
|
|
17
|
+
|
|
18
|
+
from benchflow._utils import benchmark_repos
|
|
19
|
+
from benchflow._utils.task_authoring import task_digest
|
|
20
|
+
|
|
21
|
+
DEFAULT_REGISTRY_SOURCE = (
|
|
22
|
+
"https://raw.githubusercontent.com/benchflow-ai/skillsbench/main/registry.json"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
_GITHUB_URL_RE = re.compile(
|
|
26
|
+
r"^(?:https://|git@)github\.com[:/]([^/]+)/([^/]+?)(?:\.git)?/?$"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class DatasetResolutionError(ValueError):
|
|
31
|
+
"""A dataset spec could not be resolved against the registry."""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class DatasetDigestMismatchError(DatasetResolutionError):
|
|
35
|
+
"""Snapshot content does not match the registry's pinned digests."""
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass(frozen=True)
|
|
39
|
+
class ResolvedDataset:
|
|
40
|
+
"""A registry entry resolved to verified task directories on disk."""
|
|
41
|
+
|
|
42
|
+
name: str
|
|
43
|
+
version: str
|
|
44
|
+
bench_version: str | None
|
|
45
|
+
tasks_dir: Path
|
|
46
|
+
task_names: set[str]
|
|
47
|
+
task_digests: dict[str, str]
|
|
48
|
+
provenance: dict[str, Any]
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def spec(self) -> str:
|
|
52
|
+
return f"{self.name}@{self.version}"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def parse_dataset_spec(spec: str) -> tuple[str, str]:
|
|
56
|
+
"""Split ``<name>@<version>`` — the version is mandatory.
|
|
57
|
+
|
|
58
|
+
Published versions are immutable, so there is no "latest" default: a
|
|
59
|
+
run must name the exact version it pins.
|
|
60
|
+
"""
|
|
61
|
+
name, sep, version = spec.partition("@")
|
|
62
|
+
if not sep or not name or not version:
|
|
63
|
+
raise DatasetResolutionError(
|
|
64
|
+
f"Invalid dataset spec {spec!r} — expected <name>@<version> "
|
|
65
|
+
f"(e.g. skillsbench@1.1)"
|
|
66
|
+
)
|
|
67
|
+
return name, version
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def load_registry(source: str) -> list[dict[str, Any]]:
|
|
71
|
+
"""Load a dataset registry from an HTTP(S) URL or a local file path."""
|
|
72
|
+
if source.startswith(("http://", "https://")):
|
|
73
|
+
with urlopen(source, timeout=30) as response:
|
|
74
|
+
raw = response.read().decode("utf-8")
|
|
75
|
+
else:
|
|
76
|
+
raw = Path(source).read_text()
|
|
77
|
+
registry = json.loads(raw)
|
|
78
|
+
if not isinstance(registry, list):
|
|
79
|
+
raise DatasetResolutionError(
|
|
80
|
+
f"Registry at {source} is not a list of dataset entries"
|
|
81
|
+
)
|
|
82
|
+
return registry
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def bench_version_issue(declared_range: str | None) -> str | None:
|
|
86
|
+
"""Warning text when the running bench falls outside the dataset's
|
|
87
|
+
validated ``bench_version`` range, else None. Advisory only — the
|
|
88
|
+
range records what the version was validated against, it is not a
|
|
89
|
+
hard gate."""
|
|
90
|
+
if not declared_range:
|
|
91
|
+
return None
|
|
92
|
+
from packaging.specifiers import InvalidSpecifier, SpecifierSet
|
|
93
|
+
from packaging.version import InvalidVersion, Version
|
|
94
|
+
|
|
95
|
+
from benchflow import __version__
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
specifier = SpecifierSet(declared_range)
|
|
99
|
+
except InvalidSpecifier:
|
|
100
|
+
return f"registry declares an unparseable bench_version {declared_range!r}"
|
|
101
|
+
try:
|
|
102
|
+
current = Version(__version__)
|
|
103
|
+
except InvalidVersion:
|
|
104
|
+
return (
|
|
105
|
+
f"cannot compare bench version {__version__!r} against the "
|
|
106
|
+
f"dataset's validated range {declared_range!r}"
|
|
107
|
+
)
|
|
108
|
+
if specifier.contains(current, prereleases=True):
|
|
109
|
+
return None
|
|
110
|
+
return (
|
|
111
|
+
f"bench {__version__} is outside the range this dataset was "
|
|
112
|
+
f"validated against ({declared_range}) — results may not be "
|
|
113
|
+
f"comparable with published runs"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _github_org_repo(git_url: str) -> str:
|
|
118
|
+
match = _GITHUB_URL_RE.match(git_url)
|
|
119
|
+
if not match:
|
|
120
|
+
raise DatasetResolutionError(
|
|
121
|
+
f"Unsupported git_url {git_url!r} — expected a github.com repository"
|
|
122
|
+
)
|
|
123
|
+
return f"{match.group(1)}/{match.group(2)}"
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def resolve_dataset(
|
|
127
|
+
spec: str, registry: str = DEFAULT_REGISTRY_SOURCE
|
|
128
|
+
) -> ResolvedDataset:
|
|
129
|
+
"""Resolve ``<name>@<version>`` to digest-verified task dirs on disk.
|
|
130
|
+
|
|
131
|
+
Clones the snapshot pinned by the registry entry (by commit id, so a
|
|
132
|
+
moved git tag cannot change what runs), then recomputes every task's
|
|
133
|
+
content digest and fails hard on any mismatch — a dataset version is
|
|
134
|
+
an immutable artifact and must byte-match its registry entry.
|
|
135
|
+
"""
|
|
136
|
+
name, version = parse_dataset_spec(spec)
|
|
137
|
+
entries = load_registry(registry)
|
|
138
|
+
entry = next(
|
|
139
|
+
(
|
|
140
|
+
e
|
|
141
|
+
for e in entries
|
|
142
|
+
if e.get("name") == name and str(e.get("version")) == version
|
|
143
|
+
),
|
|
144
|
+
None,
|
|
145
|
+
)
|
|
146
|
+
if entry is None:
|
|
147
|
+
available = (
|
|
148
|
+
", ".join(f"{e.get('name')}@{e.get('version')}" for e in entries) or "none"
|
|
149
|
+
)
|
|
150
|
+
raise DatasetResolutionError(
|
|
151
|
+
f"Dataset {spec!r} not found in registry (available: {available})"
|
|
152
|
+
)
|
|
153
|
+
tasks = entry.get("tasks") or []
|
|
154
|
+
if not tasks:
|
|
155
|
+
raise DatasetResolutionError(f"Dataset {spec!r} has no tasks in the registry")
|
|
156
|
+
|
|
157
|
+
snapshots = {(t["git_url"], t["git_commit_id"]) for t in tasks}
|
|
158
|
+
if len(snapshots) != 1:
|
|
159
|
+
raise DatasetResolutionError(
|
|
160
|
+
f"Dataset {spec!r} spans {len(snapshots)} git snapshots — "
|
|
161
|
+
f"only single-snapshot datasets are supported"
|
|
162
|
+
)
|
|
163
|
+
git_url, commit = next(iter(snapshots))
|
|
164
|
+
|
|
165
|
+
parents = {posixpath.dirname(t["path"].rstrip("/")) for t in tasks}
|
|
166
|
+
if len(parents) != 1:
|
|
167
|
+
raise DatasetResolutionError(
|
|
168
|
+
f"Dataset {spec!r} tasks live under {len(parents)} parent "
|
|
169
|
+
f"directories — only a single tasks directory is supported"
|
|
170
|
+
)
|
|
171
|
+
parent = next(iter(parents))
|
|
172
|
+
|
|
173
|
+
task_digests: dict[str, str] = {}
|
|
174
|
+
for t in tasks:
|
|
175
|
+
base = posixpath.basename(t["path"].rstrip("/"))
|
|
176
|
+
if base in task_digests:
|
|
177
|
+
raise DatasetResolutionError(
|
|
178
|
+
f"Dataset {spec!r} has two tasks named {base!r}"
|
|
179
|
+
)
|
|
180
|
+
task_digests[base] = t["digest"]
|
|
181
|
+
|
|
182
|
+
repo = _github_org_repo(git_url)
|
|
183
|
+
resolved = benchmark_repos.resolve_source_with_metadata(
|
|
184
|
+
repo, path=parent or None, ref=commit
|
|
185
|
+
)
|
|
186
|
+
resolved_sha = resolved.provenance.get("resolved_sha")
|
|
187
|
+
if resolved_sha != commit:
|
|
188
|
+
raise DatasetResolutionError(
|
|
189
|
+
f"Snapshot for {spec!r} resolved to {resolved_sha} but the "
|
|
190
|
+
f"registry pins {commit}"
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
mismatches = []
|
|
194
|
+
for base, expected in sorted(task_digests.items()):
|
|
195
|
+
candidate = resolved.path / base
|
|
196
|
+
if not candidate.is_dir():
|
|
197
|
+
mismatches.append(f"{base}: missing from snapshot")
|
|
198
|
+
continue
|
|
199
|
+
actual = task_digest(candidate)
|
|
200
|
+
if actual != expected:
|
|
201
|
+
mismatches.append(f"{base}: computed {actual}, registry pins {expected}")
|
|
202
|
+
if mismatches:
|
|
203
|
+
raise DatasetDigestMismatchError(
|
|
204
|
+
f"Dataset {spec!r} content does not match its registry digests:\n "
|
|
205
|
+
+ "\n ".join(mismatches)
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
return ResolvedDataset(
|
|
209
|
+
name=name,
|
|
210
|
+
version=version,
|
|
211
|
+
bench_version=entry.get("bench_version"),
|
|
212
|
+
tasks_dir=resolved.path,
|
|
213
|
+
task_names=set(task_digests),
|
|
214
|
+
task_digests=task_digests,
|
|
215
|
+
provenance=resolved.provenance,
|
|
216
|
+
)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
"""Task authoring — init and
|
|
1
|
+
"""Task authoring — init, check, and digest benchmark tasks."""
|
|
2
2
|
|
|
3
|
+
import hashlib
|
|
3
4
|
import logging
|
|
5
|
+
import os
|
|
4
6
|
import re
|
|
5
7
|
import tomllib
|
|
6
8
|
from pathlib import Path
|
|
@@ -94,6 +96,36 @@ def check_task(task_dir: Path) -> list[str]:
|
|
|
94
96
|
return issues
|
|
95
97
|
|
|
96
98
|
|
|
99
|
+
def task_digest(task_dir: Path) -> str:
|
|
100
|
+
"""Content digest pinning a task's files, independent of git.
|
|
101
|
+
|
|
102
|
+
sha256 over every regular file under ``task_dir``, sorted by POSIX
|
|
103
|
+
relative path; each file contributes
|
|
104
|
+
``path_utf8 + b"\\x00" + sha256(file_bytes).digest()``. Symlinks and
|
|
105
|
+
file modes are excluded, so the digest is reproducible from a plain
|
|
106
|
+
checkout. Must byte-match the reference digests in the skillsbench
|
|
107
|
+
dataset registry (``registry.json`` / ``docs/dataset-versioning.md``,
|
|
108
|
+
skillsbench PR #922).
|
|
109
|
+
"""
|
|
110
|
+
if not task_dir.is_dir():
|
|
111
|
+
raise NotADirectoryError(f"Not a directory: {task_dir}")
|
|
112
|
+
files: list[tuple[str, Path]] = []
|
|
113
|
+
# os.walk never descends into symlinked directories (unlike pre-3.13
|
|
114
|
+
# Path.rglob), keeping "symlinks are excluded" true for whole subtrees.
|
|
115
|
+
for dirpath, _dirnames, filenames in os.walk(task_dir):
|
|
116
|
+
for filename in filenames:
|
|
117
|
+
path = Path(dirpath) / filename
|
|
118
|
+
if path.is_symlink() or not path.is_file():
|
|
119
|
+
continue
|
|
120
|
+
files.append((path.relative_to(task_dir).as_posix(), path))
|
|
121
|
+
digest = hashlib.sha256()
|
|
122
|
+
for rel, path in sorted(files):
|
|
123
|
+
digest.update(rel.encode("utf-8"))
|
|
124
|
+
digest.update(b"\x00")
|
|
125
|
+
digest.update(hashlib.sha256(path.read_bytes()).digest())
|
|
126
|
+
return f"sha256:{digest.hexdigest()}"
|
|
127
|
+
|
|
128
|
+
|
|
97
129
|
_CTRF_STANDARD_PATH = "/logs/verifier/ctrf.json"
|
|
98
130
|
|
|
99
131
|
|
|
@@ -674,6 +674,46 @@ def tasks_check(
|
|
|
674
674
|
raise typer.Exit(1)
|
|
675
675
|
|
|
676
676
|
|
|
677
|
+
@tasks_app.command("digest")
|
|
678
|
+
def tasks_digest(
|
|
679
|
+
path: Annotated[
|
|
680
|
+
Path,
|
|
681
|
+
typer.Argument(
|
|
682
|
+
help="Path to a task directory, or a directory of task directories"
|
|
683
|
+
),
|
|
684
|
+
],
|
|
685
|
+
) -> None:
|
|
686
|
+
"""Compute the content digest that pins a task's files, independent of git.
|
|
687
|
+
|
|
688
|
+
Matches the digests in the skillsbench dataset registry (registry.json).
|
|
689
|
+
Given a single task directory (contains task.toml), prints the digest;
|
|
690
|
+
given a directory of tasks, prints one "<name> <digest>" line per task.
|
|
691
|
+
"""
|
|
692
|
+
from benchflow._utils.task_authoring import task_digest
|
|
693
|
+
|
|
694
|
+
if not path.is_dir():
|
|
695
|
+
console.print(f"[red]Not a directory: {path}[/red]")
|
|
696
|
+
raise typer.Exit(1)
|
|
697
|
+
|
|
698
|
+
if (path / "task.toml").is_file():
|
|
699
|
+
# typer.echo, not console.print: Rich wraps lines at terminal width,
|
|
700
|
+
# which would corrupt piped machine-readable output.
|
|
701
|
+
typer.echo(task_digest(path))
|
|
702
|
+
return
|
|
703
|
+
|
|
704
|
+
task_dirs = sorted(
|
|
705
|
+
d for d in path.iterdir() if d.is_dir() and (d / "task.toml").is_file()
|
|
706
|
+
)
|
|
707
|
+
if not task_dirs:
|
|
708
|
+
console.print(
|
|
709
|
+
f"[red]No tasks under {path} — expected task.toml in it "
|
|
710
|
+
f"or in its immediate subdirectories[/red]"
|
|
711
|
+
)
|
|
712
|
+
raise typer.Exit(1)
|
|
713
|
+
for task_dir in task_dirs:
|
|
714
|
+
typer.echo(f"{task_dir.name} {task_digest(task_dir)}")
|
|
715
|
+
|
|
716
|
+
|
|
677
717
|
compat_app = typer.Typer(help="Third-party framework compatibility checks.")
|
|
678
718
|
app.add_typer(compat_app, name="compat")
|
|
679
719
|
|
|
@@ -1052,6 +1092,23 @@ def eval_create(
|
|
|
1052
1092
|
help="Skip these task names; repeatable (e.g. --exclude quantum-numerical-simulation)",
|
|
1053
1093
|
),
|
|
1054
1094
|
] = None,
|
|
1095
|
+
dataset: Annotated[
|
|
1096
|
+
str | None,
|
|
1097
|
+
typer.Option(
|
|
1098
|
+
"--dataset",
|
|
1099
|
+
"-d",
|
|
1100
|
+
help="Registry dataset to run, as <name>@<version> (e.g. skillsbench@1.1). "
|
|
1101
|
+
"Resolves the pinned snapshot and verifies task content digests.",
|
|
1102
|
+
),
|
|
1103
|
+
] = None,
|
|
1104
|
+
registry: Annotated[
|
|
1105
|
+
str | None,
|
|
1106
|
+
typer.Option(
|
|
1107
|
+
"--registry",
|
|
1108
|
+
help="Dataset registry JSON URL or local file "
|
|
1109
|
+
"(default: the skillsbench registry). Only valid with --dataset.",
|
|
1110
|
+
),
|
|
1111
|
+
] = None,
|
|
1055
1112
|
) -> None:
|
|
1056
1113
|
"""Run an evaluation — single task or batch.
|
|
1057
1114
|
|
|
@@ -1067,12 +1124,22 @@ def eval_create(
|
|
|
1067
1124
|
parsed_env = _parse_agent_env(agent_env)
|
|
1068
1125
|
include_tasks = set(include) if include else set()
|
|
1069
1126
|
exclude_tasks = set(exclude) if exclude else set()
|
|
1070
|
-
sources = [
|
|
1127
|
+
sources = [
|
|
1128
|
+
bool(config_file),
|
|
1129
|
+
bool(tasks_dir),
|
|
1130
|
+
bool(source_repo),
|
|
1131
|
+
bool(source_env),
|
|
1132
|
+
bool(dataset),
|
|
1133
|
+
]
|
|
1071
1134
|
if sum(sources) > 1:
|
|
1072
1135
|
console.print(
|
|
1073
|
-
"[red]Choose only one source: --config, --tasks-dir, --source-repo,
|
|
1136
|
+
"[red]Choose only one source: --config, --tasks-dir, --source-repo, "
|
|
1137
|
+
"--source-env, or --dataset[/red]"
|
|
1074
1138
|
)
|
|
1075
1139
|
raise typer.Exit(1)
|
|
1140
|
+
if registry and not dataset:
|
|
1141
|
+
console.print("[red]--registry requires --dataset[/red]")
|
|
1142
|
+
raise typer.Exit(1)
|
|
1076
1143
|
if worker_concurrency is not None and not (tasks_dir or source_repo):
|
|
1077
1144
|
console.print(
|
|
1078
1145
|
"[red]--worker-concurrency is supported for --tasks-dir and --source-repo batch runs[/red]"
|
|
@@ -1300,6 +1367,63 @@ def eval_create(
|
|
|
1300
1367
|
if run_result.error:
|
|
1301
1368
|
console.print(f"[red]Error:[/red] {run_result.error}")
|
|
1302
1369
|
raise typer.Exit(1)
|
|
1370
|
+
elif dataset:
|
|
1371
|
+
from benchflow._utils.dataset_registry import (
|
|
1372
|
+
DEFAULT_REGISTRY_SOURCE,
|
|
1373
|
+
DatasetResolutionError,
|
|
1374
|
+
bench_version_issue,
|
|
1375
|
+
resolve_dataset,
|
|
1376
|
+
)
|
|
1377
|
+
|
|
1378
|
+
registry_source = registry or DEFAULT_REGISTRY_SOURCE
|
|
1379
|
+
try:
|
|
1380
|
+
with console.status(f"Resolving dataset {dataset}…"):
|
|
1381
|
+
resolved_dataset = resolve_dataset(dataset, registry=registry_source)
|
|
1382
|
+
except DatasetResolutionError as e:
|
|
1383
|
+
console.print(f"[red]{e}[/red]")
|
|
1384
|
+
raise typer.Exit(1) from None
|
|
1385
|
+
version_issue = bench_version_issue(resolved_dataset.bench_version)
|
|
1386
|
+
if version_issue:
|
|
1387
|
+
console.print(f"[yellow]Warning:[/yellow] {version_issue}")
|
|
1388
|
+
console.print(
|
|
1389
|
+
f"[green]✓[/green] {resolved_dataset.spec}: "
|
|
1390
|
+
f"{len(resolved_dataset.task_names)} tasks, digests verified "
|
|
1391
|
+
f"({str(resolved_dataset.provenance.get('resolved_sha', ''))[:12]})"
|
|
1392
|
+
)
|
|
1393
|
+
dataset_include = (
|
|
1394
|
+
resolved_dataset.task_names & include_tasks
|
|
1395
|
+
if include_tasks
|
|
1396
|
+
else resolved_dataset.task_names
|
|
1397
|
+
)
|
|
1398
|
+
eff_model = effective_model(eval_agent, model)
|
|
1399
|
+
_run_batch_eval(
|
|
1400
|
+
resolved_dataset.tasks_dir,
|
|
1401
|
+
EvaluationConfig(
|
|
1402
|
+
agent=eval_agent,
|
|
1403
|
+
model=eff_model,
|
|
1404
|
+
reasoning_effort=eval_reasoning_effort,
|
|
1405
|
+
environment=eval_environment,
|
|
1406
|
+
concurrency=eval_concurrency,
|
|
1407
|
+
build_concurrency=build_concurrency,
|
|
1408
|
+
prompts=eval_prompts,
|
|
1409
|
+
agent_idle_timeout=eval_agent_idle_timeout,
|
|
1410
|
+
agent_env=parsed_env,
|
|
1411
|
+
sandbox_user=sandbox_user,
|
|
1412
|
+
sandbox_setup_timeout=sandbox_setup_timeout,
|
|
1413
|
+
skills_dir=str(skills_dir) if skills_dir else None,
|
|
1414
|
+
skill_mode=skill_mode,
|
|
1415
|
+
skill_creator_dir=str(skill_creator_dir) if skill_creator_dir else None,
|
|
1416
|
+
self_gen_no_internet=self_gen_no_internet,
|
|
1417
|
+
source_provenance=resolved_dataset.provenance,
|
|
1418
|
+
include_tasks=dataset_include,
|
|
1419
|
+
exclude_tasks=exclude_tasks,
|
|
1420
|
+
usage_tracking=eval_usage_tracking,
|
|
1421
|
+
environment_manifest=eval_env_manifest,
|
|
1422
|
+
dataset_name=resolved_dataset.name,
|
|
1423
|
+
dataset_version=resolved_dataset.version,
|
|
1424
|
+
dataset_task_digests=resolved_dataset.task_digests,
|
|
1425
|
+
),
|
|
1426
|
+
)
|
|
1303
1427
|
elif source_repo:
|
|
1304
1428
|
from benchflow._utils.benchmark_repos import resolve_source_with_metadata
|
|
1305
1429
|
|
|
@@ -1368,7 +1492,8 @@ def eval_create(
|
|
|
1368
1492
|
)
|
|
1369
1493
|
else:
|
|
1370
1494
|
console.print(
|
|
1371
|
-
"[red]Provide --config, --tasks-dir, --source-repo,
|
|
1495
|
+
"[red]Provide --config, --tasks-dir, --source-repo, --source-env, "
|
|
1496
|
+
"or --dataset[/red]"
|
|
1372
1497
|
)
|
|
1373
1498
|
raise typer.Exit(1)
|
|
1374
1499
|
|
|
@@ -267,6 +267,13 @@ class EvaluationConfig:
|
|
|
267
267
|
self_gen_no_internet: bool = False
|
|
268
268
|
job_mode: str = DEFAULT_JOB_MODE
|
|
269
269
|
source_provenance: dict[str, Any] | None = None
|
|
270
|
+
# Registry dataset identity (`bench eval create -d name@version`). When
|
|
271
|
+
# set, every result.json/config.json is stamped with dataset_name,
|
|
272
|
+
# dataset_version, and the task's registry content digest — see
|
|
273
|
+
# docs/dataset-versioning.md in benchflow-ai/skillsbench.
|
|
274
|
+
dataset_name: str | None = None
|
|
275
|
+
dataset_version: str | None = None
|
|
276
|
+
dataset_task_digests: dict[str, str] = field(default_factory=dict)
|
|
270
277
|
usage_tracking: UsageTrackingConfig = field(default_factory=UsageTrackingConfig)
|
|
271
278
|
# Environment-plane manifest applied to every rollout in the batch.
|
|
272
279
|
# When set, each task's RolloutConfig.environment_manifest is populated
|
|
@@ -817,6 +824,13 @@ class Evaluation:
|
|
|
817
824
|
from benchflow._utils.benchmark_repos import task_source_provenance
|
|
818
825
|
from benchflow.rollout import Rollout, RolloutConfig
|
|
819
826
|
|
|
827
|
+
dataset = None
|
|
828
|
+
if cfg.dataset_name:
|
|
829
|
+
dataset = {
|
|
830
|
+
"name": cfg.dataset_name,
|
|
831
|
+
"version": cfg.dataset_version,
|
|
832
|
+
"task_digest": cfg.dataset_task_digests.get(task_dir.name),
|
|
833
|
+
}
|
|
820
834
|
skills_dir = (
|
|
821
835
|
str(self._learner_skills_dir)
|
|
822
836
|
if self._learner_skills_dir is not None
|
|
@@ -855,6 +869,7 @@ class Evaluation:
|
|
|
855
869
|
self_gen_no_internet=cfg.self_gen_no_internet,
|
|
856
870
|
export_generated_skills_to=export_to,
|
|
857
871
|
source_provenance=task_source_provenance(cfg.source_provenance, task_dir),
|
|
872
|
+
dataset=dataset,
|
|
858
873
|
usage_tracking=cfg.usage_tracking,
|
|
859
874
|
)
|
|
860
875
|
if skill_mode == SKILL_MODE_SELF_GEN:
|
|
@@ -1383,6 +1398,14 @@ class Evaluation:
|
|
|
1383
1398
|
**trajectory_step_summary(all_results),
|
|
1384
1399
|
**phase_timing_summary(all_results),
|
|
1385
1400
|
**summary_source_fields(cfg.source_provenance, all_results),
|
|
1401
|
+
**(
|
|
1402
|
+
{
|
|
1403
|
+
"dataset_name": cfg.dataset_name,
|
|
1404
|
+
"dataset_version": cfg.dataset_version,
|
|
1405
|
+
}
|
|
1406
|
+
if cfg.dataset_name
|
|
1407
|
+
else {}
|
|
1408
|
+
),
|
|
1386
1409
|
}
|
|
1387
1410
|
# Surface continual-learning provenance — generation, curve — so a
|
|
1388
1411
|
# resumed run can be audited end-to-end (#394).
|
|
@@ -525,6 +525,7 @@ def _write_config(
|
|
|
525
525
|
agent_idle_timeout: int | None = None,
|
|
526
526
|
scenes: list[Scene] | None = None,
|
|
527
527
|
source_provenance: dict[str, Any] | None = None,
|
|
528
|
+
dataset: dict[str, Any] | None = None,
|
|
528
529
|
) -> None:
|
|
529
530
|
"""Write config.json to rollout_dir with secrets filtered out."""
|
|
530
531
|
recorded_env = {
|
|
@@ -552,6 +553,10 @@ def _write_config(
|
|
|
552
553
|
config_data["usage_tracking"] = usage_tracking.to_config_artifact()
|
|
553
554
|
if source_provenance is not None:
|
|
554
555
|
config_data["source"] = source_provenance
|
|
556
|
+
if dataset is not None:
|
|
557
|
+
config_data["dataset_name"] = dataset.get("name")
|
|
558
|
+
config_data["dataset_version"] = dataset.get("version")
|
|
559
|
+
config_data["task_digest"] = dataset.get("task_digest")
|
|
555
560
|
(rollout_dir / "config.json").write_text(json.dumps(config_data, indent=2))
|
|
556
561
|
|
|
557
562
|
|
|
@@ -616,6 +621,7 @@ def _build_rollout_result(
|
|
|
616
621
|
usage_tracking: dict[str, Any] | None = None,
|
|
617
622
|
evolved_skills: dict[str, str] | None = None,
|
|
618
623
|
source_provenance: dict[str, Any] | None = None,
|
|
624
|
+
dataset: dict[str, Any] | None = None,
|
|
619
625
|
diagnostics: RolloutDiagnostics | None = None,
|
|
620
626
|
skill_policy: TaskSkillPolicy | None = None,
|
|
621
627
|
sandbox_id: str | None = None,
|
|
@@ -743,6 +749,15 @@ def _build_rollout_result(
|
|
|
743
749
|
if source_provenance is not None
|
|
744
750
|
else {}
|
|
745
751
|
),
|
|
752
|
+
**(
|
|
753
|
+
{
|
|
754
|
+
"dataset_name": dataset.get("name"),
|
|
755
|
+
"dataset_version": dataset.get("version"),
|
|
756
|
+
"task_digest": dataset.get("task_digest"),
|
|
757
|
+
}
|
|
758
|
+
if dataset is not None
|
|
759
|
+
else {}
|
|
760
|
+
),
|
|
746
761
|
"sandbox_id": sandbox_id,
|
|
747
762
|
},
|
|
748
763
|
indent=2,
|
|
@@ -1092,6 +1107,10 @@ class RolloutConfig:
|
|
|
1092
1107
|
skip_verify: bool = False
|
|
1093
1108
|
export_generated_skills_to: str | Path | None = None
|
|
1094
1109
|
source_provenance: dict[str, Any] | None = None
|
|
1110
|
+
# Registry dataset identity for this task: {"name", "version",
|
|
1111
|
+
# "task_digest"} — stamped into config.json/result.json so published
|
|
1112
|
+
# runs declare the dataset version they ran (dataset-versioning plan).
|
|
1113
|
+
dataset: dict[str, Any] | None = None
|
|
1095
1114
|
planes: RolloutPlanes | None = field(default=None, repr=False, compare=False)
|
|
1096
1115
|
|
|
1097
1116
|
def __post_init__(self) -> None:
|
|
@@ -1540,6 +1559,7 @@ class Rollout:
|
|
|
1540
1559
|
agent_idle_timeout=cfg.agent_idle_timeout,
|
|
1541
1560
|
scenes=cfg.effective_scenes,
|
|
1542
1561
|
source_provenance=cfg.source_provenance,
|
|
1562
|
+
dataset=cfg.dataset,
|
|
1543
1563
|
)
|
|
1544
1564
|
|
|
1545
1565
|
self._phase = "setup"
|
|
@@ -2906,6 +2926,7 @@ class Rollout:
|
|
|
2906
2926
|
scenes=self._config.effective_scenes,
|
|
2907
2927
|
evolved_skills=self._evolved_skills,
|
|
2908
2928
|
source_provenance=self._config.source_provenance,
|
|
2929
|
+
dataset=self._config.dataset,
|
|
2909
2930
|
diagnostics=self._diagnostics,
|
|
2910
2931
|
usage_tracking=self._usage_tracking_metadata(),
|
|
2911
2932
|
skill_policy=getattr(self, "_task_skill_policy", None)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Digest test fixtures
|
|
2
|
+
|
|
3
|
+
Golden-test fixtures for `bench tasks digest`. The expected digests are
|
|
4
|
+
hardcoded in `tests/test_task_digest.py` — do not modify any file under the
|
|
5
|
+
task directories here without updating those golden values.
|
|
6
|
+
|
|
7
|
+
Filenames are ASCII on purpose: macOS checks out unicode filenames in NFD,
|
|
8
|
+
which would change the hashed path bytes across platforms. Unicode coverage
|
|
9
|
+
lives in file *content* (`beta-task/data/unicode.txt`).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
FROM ubuntu:24.04
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
naïve résumé — ünïcödé
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# beta-task
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "1.1"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Not a task — no task.toml. Multi-task digest mode must skip this directory.
|