agent-hitch 0.2.6 → 0.2.8
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.
- package/README.md +30 -3
- package/README.zh-CN.md +14 -2
- package/dist/bin/hitch.js +25 -3
- package/dist/bin/hitch.js.map +1 -1
- package/dist/scripts/canary-benchmark.js +54 -0
- package/dist/scripts/canary-benchmark.js.map +1 -0
- package/dist/scripts/canary-buildkit-secrets.js +166 -0
- package/dist/scripts/canary-buildkit-secrets.js.map +1 -0
- package/dist/scripts/canary-collision-domains.js +77 -0
- package/dist/scripts/canary-collision-domains.js.map +1 -0
- package/dist/scripts/canary-docker-image-observation.js +181 -0
- package/dist/scripts/canary-docker-image-observation.js.map +1 -0
- package/dist/scripts/canary-eval-scheduler-throughput.js +47 -0
- package/dist/scripts/canary-eval-scheduler-throughput.js.map +1 -0
- package/dist/scripts/canary-gpu-hardware.js +95 -0
- package/dist/scripts/canary-gpu-hardware.js.map +1 -0
- package/dist/scripts/canary-harbor-load.js +365 -0
- package/dist/scripts/canary-harbor-load.js.map +1 -0
- package/dist/scripts/canary-packaged-harness.js +75 -0
- package/dist/scripts/canary-packaged-harness.js.map +1 -0
- package/dist/scripts/canary-resource-load.js +188 -0
- package/dist/scripts/canary-resource-load.js.map +1 -0
- package/dist/scripts/check-architecture.js +10 -5
- package/dist/scripts/check-architecture.js.map +1 -1
- package/dist/scripts/docker-reaper-crash-child.js +21 -0
- package/dist/scripts/docker-reaper-crash-child.js.map +1 -0
- package/dist/src/adapters/catalog.js +3 -1
- package/dist/src/adapters/catalog.js.map +1 -1
- package/dist/src/adapters/discovery.js +1 -1
- package/dist/src/adapters/discovery.js.map +1 -1
- package/dist/src/adapters/providers/claude.js +6 -0
- package/dist/src/adapters/providers/claude.js.map +1 -1
- package/dist/src/adapters/providers/codex-auth.js +29 -0
- package/dist/src/adapters/providers/codex-auth.js.map +1 -0
- package/dist/src/adapters/providers/codex.js +29 -6
- package/dist/src/adapters/providers/codex.js.map +1 -1
- package/dist/src/adapters/providers/deepseek.js +6 -0
- package/dist/src/adapters/providers/deepseek.js.map +1 -1
- package/dist/src/adapters/providers/model-call.js +26 -0
- package/dist/src/adapters/providers/model-call.js.map +1 -0
- package/dist/src/adapters/providers/opencode.js +6 -0
- package/dist/src/adapters/providers/opencode.js.map +1 -1
- package/dist/src/adapters/providers/pi.js +6 -0
- package/dist/src/adapters/providers/pi.js.map +1 -1
- package/dist/src/artifacts/index.js +1 -0
- package/dist/src/artifacts/index.js.map +1 -1
- package/dist/src/artifacts/preparer.js +7 -2
- package/dist/src/artifacts/preparer.js.map +1 -1
- package/dist/src/backends/harbor/agent-budget.js +31 -0
- package/dist/src/backends/harbor/agent-budget.js.map +1 -0
- package/dist/src/backends/harbor/backend.js +59 -107
- package/dist/src/backends/harbor/backend.js.map +1 -1
- package/dist/src/backends/harbor/environment-config.js +92 -0
- package/dist/src/backends/harbor/environment-config.js.map +1 -0
- package/dist/src/backends/harbor/index.js +6 -1
- package/dist/src/backends/harbor/index.js.map +1 -1
- package/dist/src/backends/harbor/model-proxy-config.js +23 -0
- package/dist/src/backends/harbor/model-proxy-config.js.map +1 -0
- package/dist/src/backends/harbor/process.js +177 -0
- package/dist/src/backends/harbor/process.js.map +1 -0
- package/dist/src/backends/harbor/regrade.js +77 -0
- package/dist/src/backends/harbor/regrade.js.map +1 -0
- package/dist/src/backends/harbor/runtime-toolchain.js +30 -0
- package/dist/src/backends/harbor/runtime-toolchain.js.map +1 -0
- package/dist/src/backends/harbor/supervisor.js +74 -0
- package/dist/src/backends/harbor/supervisor.js.map +1 -0
- package/dist/src/backends/harbor/task-resources.js +206 -0
- package/dist/src/backends/harbor/task-resources.js.map +1 -0
- package/dist/src/backends/harbor/tools.js +6 -29
- package/dist/src/backends/harbor/tools.js.map +1 -1
- package/dist/src/backends/index.js +5 -1
- package/dist/src/backends/index.js.map +1 -1
- package/dist/src/benchmarks/index.js +3 -0
- package/dist/src/benchmarks/index.js.map +1 -0
- package/dist/src/benchmarks/loader.js +271 -0
- package/dist/src/benchmarks/loader.js.map +1 -0
- package/dist/src/benchmarks/metrics.js +16 -0
- package/dist/src/benchmarks/metrics.js.map +1 -0
- package/dist/src/benchmarks/toml.js +13 -0
- package/dist/src/benchmarks/toml.js.map +1 -0
- package/dist/src/benchmarks/validation.js +242 -0
- package/dist/src/benchmarks/validation.js.map +1 -0
- package/dist/src/cli/arguments.js +6 -4
- package/dist/src/cli/arguments.js.map +1 -1
- package/dist/src/cli/commands/benchmark.js +22 -0
- package/dist/src/cli/commands/benchmark.js.map +1 -0
- package/dist/src/cli/commands/capabilities.js +18 -0
- package/dist/src/cli/commands/capabilities.js.map +1 -0
- package/dist/src/cli/commands/daemon.js +135 -8
- package/dist/src/cli/commands/daemon.js.map +1 -1
- package/dist/src/cli/commands/eval.js +228 -6
- package/dist/src/cli/commands/eval.js.map +1 -1
- package/dist/src/cli/commands/images.js +40 -0
- package/dist/src/cli/commands/images.js.map +1 -0
- package/dist/src/cli/commands/run.js +42 -17
- package/dist/src/cli/commands/run.js.map +1 -1
- package/dist/src/cli/commands/runs.js +25 -3
- package/dist/src/cli/commands/runs.js.map +1 -1
- package/dist/src/cli/commands/trajectory.js +96 -5
- package/dist/src/cli/commands/trajectory.js.map +1 -1
- package/dist/src/cli/commands/verifier.js +36 -0
- package/dist/src/cli/commands/verifier.js.map +1 -0
- package/dist/src/cli/commands/worker.js +79 -0
- package/dist/src/cli/commands/worker.js.map +1 -0
- package/dist/src/cli/main.js +10 -0
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/output.js +84 -4
- package/dist/src/cli/output.js.map +1 -1
- package/dist/src/control-plane/build-admission.js +69 -0
- package/dist/src/control-plane/build-admission.js.map +1 -0
- package/dist/src/control-plane/build-records.js +6 -0
- package/dist/src/control-plane/build-records.js.map +1 -0
- package/dist/src/control-plane/collisions.js +40 -0
- package/dist/src/control-plane/collisions.js.map +1 -0
- package/dist/src/control-plane/eval-control-state.js +22 -0
- package/dist/src/control-plane/eval-control-state.js.map +1 -0
- package/dist/src/control-plane/eval-control-work.js +44 -0
- package/dist/src/control-plane/eval-control-work.js.map +1 -0
- package/dist/src/control-plane/eval-image-resolution.js +52 -0
- package/dist/src/control-plane/eval-image-resolution.js.map +1 -0
- package/dist/src/control-plane/eval-image-services.js +30 -0
- package/dist/src/control-plane/eval-image-services.js.map +1 -0
- package/dist/src/control-plane/eval-records.js +252 -0
- package/dist/src/control-plane/eval-records.js.map +1 -0
- package/dist/src/control-plane/eval-recovery.js +181 -0
- package/dist/src/control-plane/eval-recovery.js.map +1 -0
- package/dist/src/control-plane/eval-scheduler.js +450 -0
- package/dist/src/control-plane/eval-scheduler.js.map +1 -0
- package/dist/src/control-plane/index.js +20 -0
- package/dist/src/control-plane/index.js.map +1 -0
- package/dist/src/control-plane/local-worker.js +49 -0
- package/dist/src/control-plane/local-worker.js.map +1 -0
- package/dist/src/control-plane/model-capture-planning.js +12 -0
- package/dist/src/control-plane/model-capture-planning.js.map +1 -0
- package/dist/src/control-plane/remote-result-transport.js +175 -0
- package/dist/src/control-plane/remote-result-transport.js.map +1 -0
- package/dist/src/control-plane/remote-work-coordinator.js +333 -0
- package/dist/src/control-plane/remote-work-coordinator.js.map +1 -0
- package/dist/src/control-plane/remote-work-inputs.js +266 -0
- package/dist/src/control-plane/remote-work-inputs.js.map +1 -0
- package/dist/src/control-plane/remote-work-item.js +62 -0
- package/dist/src/control-plane/remote-work-item.js.map +1 -0
- package/dist/src/control-plane/remote-work-recovery.js +220 -0
- package/dist/src/control-plane/remote-work-recovery.js.map +1 -0
- package/dist/src/control-plane/remote-worker-artifacts.js +135 -0
- package/dist/src/control-plane/remote-worker-artifacts.js.map +1 -0
- package/dist/src/control-plane/remote-worker-client.js +202 -0
- package/dist/src/control-plane/remote-worker-client.js.map +1 -0
- package/dist/src/control-plane/remote-worker-configuration.js +34 -0
- package/dist/src/control-plane/remote-worker-configuration.js.map +1 -0
- package/dist/src/control-plane/remote-worker-credentials.js +58 -0
- package/dist/src/control-plane/remote-worker-credentials.js.map +1 -0
- package/dist/src/control-plane/remote-worker-protocol.js +489 -0
- package/dist/src/control-plane/remote-worker-protocol.js.map +1 -0
- package/dist/src/control-plane/remote-worker-runner.js +214 -0
- package/dist/src/control-plane/remote-worker-runner.js.map +1 -0
- package/dist/src/control-plane/remote-workers.js +377 -0
- package/dist/src/control-plane/remote-workers.js.map +1 -0
- package/dist/src/control-plane/rerun-scheduler.js +448 -0
- package/dist/src/control-plane/rerun-scheduler.js.map +1 -0
- package/dist/src/control-plane/rerun-submission.js +62 -0
- package/dist/src/control-plane/rerun-submission.js.map +1 -0
- package/dist/src/control-plane/resources.js +182 -0
- package/dist/src/control-plane/resources.js.map +1 -0
- package/dist/src/control-plane/scheduler-eval-entry.js +32 -0
- package/dist/src/control-plane/scheduler-eval-entry.js.map +1 -0
- package/dist/src/control-plane/synthetic-result.js +21 -0
- package/dist/src/control-plane/synthetic-result.js.map +1 -0
- package/dist/src/control-plane/work-admission.js +23 -0
- package/dist/src/control-plane/work-admission.js.map +1 -0
- package/dist/src/control-plane/work-dispatcher.js +237 -0
- package/dist/src/control-plane/work-dispatcher.js.map +1 -0
- package/dist/src/controller-runtime/hash.js +19 -3
- package/dist/src/controller-runtime/hash.js.map +1 -1
- package/dist/src/controller-runtime/index.js +1 -1
- package/dist/src/controller-runtime/index.js.map +1 -1
- package/dist/src/controller-runtime/store.js +15 -6
- package/dist/src/controller-runtime/store.js.map +1 -1
- package/dist/src/daemon/auth.js +5 -0
- package/dist/src/daemon/auth.js.map +1 -1
- package/dist/src/daemon/client.js.map +1 -1
- package/dist/src/daemon/event-stream.js +46 -0
- package/dist/src/daemon/event-stream.js.map +1 -0
- package/dist/src/daemon/health.js +66 -0
- package/dist/src/daemon/health.js.map +1 -0
- package/dist/src/daemon/launcher.js +28 -1
- package/dist/src/daemon/launcher.js.map +1 -1
- package/dist/src/daemon/logging.js +23 -0
- package/dist/src/daemon/logging.js.map +1 -0
- package/dist/src/daemon/scheduler.js +26 -5
- package/dist/src/daemon/scheduler.js.map +1 -1
- package/dist/src/daemon/server.js +255 -98
- package/dist/src/daemon/server.js.map +1 -1
- package/dist/src/daemon/telemetry.js +163 -0
- package/dist/src/daemon/telemetry.js.map +1 -0
- package/dist/src/daemon/worker-routes.js +219 -0
- package/dist/src/daemon/worker-routes.js.map +1 -0
- package/dist/src/domain/benchmarks.js +2 -0
- package/dist/src/domain/benchmarks.js.map +1 -0
- package/dist/src/domain/bundles.js +2 -0
- package/dist/src/domain/bundles.js.map +1 -0
- package/dist/src/domain/control-plane.js +2 -0
- package/dist/src/domain/control-plane.js.map +1 -0
- package/dist/src/domain/execution-evidence.js +2 -0
- package/dist/src/domain/execution-evidence.js.map +1 -0
- package/dist/src/domain/execution-plan.js +2 -0
- package/dist/src/domain/execution-plan.js.map +1 -0
- package/dist/src/domain/images.js +2 -0
- package/dist/src/domain/images.js.map +1 -0
- package/dist/src/domain/index.js +13 -0
- package/dist/src/domain/index.js.map +1 -1
- package/dist/src/domain/interactions.js +2 -0
- package/dist/src/domain/interactions.js.map +1 -0
- package/dist/src/domain/providers.js +2 -0
- package/dist/src/domain/providers.js.map +1 -0
- package/dist/src/domain/resources.js +2 -0
- package/dist/src/domain/resources.js.map +1 -0
- package/dist/src/domain/runs.js.map +1 -1
- package/dist/src/domain/validation.js +11 -4
- package/dist/src/domain/validation.js.map +1 -1
- package/dist/src/domain/verifier-evidence-validation.js +214 -0
- package/dist/src/domain/verifier-evidence-validation.js.map +1 -0
- package/dist/src/domain/verifier-evidence.js +3 -0
- package/dist/src/domain/verifier-evidence.js.map +1 -0
- package/dist/src/domain/verifier-score-contract.js +232 -0
- package/dist/src/domain/verifier-score-contract.js.map +1 -0
- package/dist/src/domain/workers.js +2 -0
- package/dist/src/domain/workers.js.map +1 -0
- package/dist/src/evals/benchmark-adapter-manifest.js +219 -0
- package/dist/src/evals/benchmark-adapter-manifest.js.map +1 -0
- package/dist/src/evals/benchmark-candidate.js +36 -0
- package/dist/src/evals/benchmark-candidate.js.map +1 -0
- package/dist/src/evals/benchmark-run.js +166 -0
- package/dist/src/evals/benchmark-run.js.map +1 -0
- package/dist/src/evals/collect-only-rerun.js +183 -0
- package/dist/src/evals/collect-only-rerun.js.map +1 -0
- package/dist/src/evals/directory.js +30 -0
- package/dist/src/evals/directory.js.map +1 -0
- package/dist/src/evals/docker-engine-stats.js +89 -0
- package/dist/src/evals/docker-engine-stats.js.map +1 -0
- package/dist/src/evals/docker-ownership.js +51 -0
- package/dist/src/evals/docker-ownership.js.map +1 -0
- package/dist/src/evals/docker-reaper.js +144 -0
- package/dist/src/evals/docker-reaper.js.map +1 -0
- package/dist/src/evals/docker-resource-observer.js +207 -0
- package/dist/src/evals/docker-resource-observer.js.map +1 -0
- package/dist/src/evals/duration-estimator.js +126 -0
- package/dist/src/evals/duration-estimator.js.map +1 -0
- package/dist/src/evals/environment-image-planning.js +164 -0
- package/dist/src/evals/environment-image-planning.js.map +1 -0
- package/dist/src/evals/eval-artifact-planning.js +56 -0
- package/dist/src/evals/eval-artifact-planning.js.map +1 -0
- package/dist/src/evals/eval-finalization.js +10 -0
- package/dist/src/evals/eval-finalization.js.map +1 -0
- package/dist/src/evals/eval-lifecycle-events.js +29 -0
- package/dist/src/evals/eval-lifecycle-events.js.map +1 -0
- package/dist/src/evals/eval-logical-plan.js +51 -0
- package/dist/src/evals/eval-logical-plan.js.map +1 -0
- package/dist/src/evals/eval-result-builder.js +81 -0
- package/dist/src/evals/eval-result-builder.js.map +1 -0
- package/dist/src/evals/events.js +53 -5
- package/dist/src/evals/events.js.map +1 -1
- package/dist/src/evals/evolution-baseline.js +191 -0
- package/dist/src/evals/evolution-baseline.js.map +1 -0
- package/dist/src/evals/execution-evidence.js +116 -0
- package/dist/src/evals/execution-evidence.js.map +1 -0
- package/dist/src/evals/execution-leases.js +342 -0
- package/dist/src/evals/execution-leases.js.map +1 -0
- package/dist/src/evals/execution-plan-artifacts.js +72 -0
- package/dist/src/evals/execution-plan-artifacts.js.map +1 -0
- package/dist/src/evals/execution-plan-images.js +69 -0
- package/dist/src/evals/execution-plan-images.js.map +1 -0
- package/dist/src/evals/execution-plan-resources.js +174 -0
- package/dist/src/evals/execution-plan-resources.js.map +1 -0
- package/dist/src/evals/execution-plan.js +451 -0
- package/dist/src/evals/execution-plan.js.map +1 -0
- package/dist/src/evals/failure-classifier.js +61 -0
- package/dist/src/evals/failure-classifier.js.map +1 -0
- package/dist/src/evals/harbor-artifact-builder-image.js +99 -0
- package/dist/src/evals/harbor-artifact-builder-image.js.map +1 -0
- package/dist/src/evals/harbor-artifact-builder.js +358 -0
- package/dist/src/evals/harbor-artifact-builder.js.map +1 -0
- package/dist/src/evals/harbor-bridge-error.js +58 -3
- package/dist/src/evals/harbor-bridge-error.js.map +1 -1
- package/dist/src/evals/harbor-node-runtime.js +146 -0
- package/dist/src/evals/harbor-node-runtime.js.map +1 -0
- package/dist/src/evals/harbor-phase-timings.js +60 -0
- package/dist/src/evals/harbor-phase-timings.js.map +1 -0
- package/dist/src/evals/index.js +40 -2
- package/dist/src/evals/index.js.map +1 -1
- package/dist/src/evals/infrastructure-retry.js +208 -84
- package/dist/src/evals/infrastructure-retry.js.map +1 -1
- package/dist/src/evals/interaction-capture-import.js +49 -0
- package/dist/src/evals/interaction-capture-import.js.map +1 -0
- package/dist/src/evals/local-docker-provider.js +372 -0
- package/dist/src/evals/local-docker-provider.js.map +1 -0
- package/dist/src/evals/local-eval-planning.js +80 -0
- package/dist/src/evals/local-eval-planning.js.map +1 -0
- package/dist/src/evals/model-capture-plan.js +22 -0
- package/dist/src/evals/model-capture-plan.js.map +1 -0
- package/dist/src/evals/model-capture-runtime.js +114 -0
- package/dist/src/evals/model-capture-runtime.js.map +1 -0
- package/dist/src/evals/model-proxy-runtime-state.js +53 -0
- package/dist/src/evals/model-proxy-runtime-state.js.map +1 -0
- package/dist/src/evals/native-phase-evidence.js +440 -0
- package/dist/src/evals/native-phase-evidence.js.map +1 -0
- package/dist/src/evals/physical-retry-work.js +31 -0
- package/dist/src/evals/physical-retry-work.js.map +1 -0
- package/dist/src/evals/planned-execution-support.js +66 -0
- package/dist/src/evals/planned-execution-support.js.map +1 -0
- package/dist/src/evals/planned-execution.js +469 -0
- package/dist/src/evals/planned-execution.js.map +1 -0
- package/dist/src/evals/planned-progress-publisher.js +62 -0
- package/dist/src/evals/planned-progress-publisher.js.map +1 -0
- package/dist/src/evals/planned-remote-execution.js +40 -0
- package/dist/src/evals/planned-remote-execution.js.map +1 -0
- package/dist/src/evals/planned-retry-execution.js +174 -0
- package/dist/src/evals/planned-retry-execution.js.map +1 -0
- package/dist/src/evals/planned-retry-lifecycle.js +188 -0
- package/dist/src/evals/planned-retry-lifecycle.js.map +1 -0
- package/dist/src/evals/preparation-rerun.js +225 -0
- package/dist/src/evals/preparation-rerun.js.map +1 -0
- package/dist/src/evals/prepared-harness.js +76 -0
- package/dist/src/evals/prepared-harness.js.map +1 -0
- package/dist/src/evals/progress.js +52 -12
- package/dist/src/evals/progress.js.map +1 -1
- package/dist/src/evals/records.js +20 -3
- package/dist/src/evals/records.js.map +1 -1
- package/dist/src/evals/recovery.js +242 -0
- package/dist/src/evals/recovery.js.map +1 -0
- package/dist/src/evals/regrade-evidence.js +77 -0
- package/dist/src/evals/regrade-evidence.js.map +1 -0
- package/dist/src/evals/remote-infrastructure-retry.js +165 -0
- package/dist/src/evals/remote-infrastructure-retry.js.map +1 -0
- package/dist/src/evals/request.js +21 -3
- package/dist/src/evals/request.js.map +1 -1
- package/dist/src/evals/rerun-inputs.js +108 -0
- package/dist/src/evals/rerun-inputs.js.map +1 -0
- package/dist/src/evals/rerun-slots.js +4 -3
- package/dist/src/evals/rerun-slots.js.map +1 -1
- package/dist/src/evals/rerun-types.js +45 -0
- package/dist/src/evals/rerun-types.js.map +1 -0
- package/dist/src/evals/rerun.js +133 -88
- package/dist/src/evals/rerun.js.map +1 -1
- package/dist/src/evals/result-helpers.js +78 -0
- package/dist/src/evals/result-helpers.js.map +1 -0
- package/dist/src/evals/resume-state.js +36 -0
- package/dist/src/evals/resume-state.js.map +1 -0
- package/dist/src/evals/retry-backoff.js +20 -0
- package/dist/src/evals/retry-backoff.js.map +1 -0
- package/dist/src/evals/retry-state.js +195 -0
- package/dist/src/evals/retry-state.js.map +1 -0
- package/dist/src/evals/scheduler-metrics.js +95 -0
- package/dist/src/evals/scheduler-metrics.js.map +1 -0
- package/dist/src/evals/scheduler-trace-replay.js +107 -0
- package/dist/src/evals/scheduler-trace-replay.js.map +1 -0
- package/dist/src/evals/service-types.js +2 -0
- package/dist/src/evals/service-types.js.map +1 -0
- package/dist/src/evals/service.js +331 -347
- package/dist/src/evals/service.js.map +1 -1
- package/dist/src/evals/task-resources.js +209 -0
- package/dist/src/evals/task-resources.js.map +1 -0
- package/dist/src/evals/trial-environment-evidence.js +87 -0
- package/dist/src/evals/trial-environment-evidence.js.map +1 -0
- package/dist/src/evals/trial-execution-evidence.js +13 -0
- package/dist/src/evals/trial-execution-evidence.js.map +1 -0
- package/dist/src/evals/trial-import-identity.js +31 -0
- package/dist/src/evals/trial-import-identity.js.map +1 -0
- package/dist/src/evals/trial-import.js +183 -188
- package/dist/src/evals/trial-import.js.map +1 -1
- package/dist/src/evals/trial-publication-recovery.js +144 -0
- package/dist/src/evals/trial-publication-recovery.js.map +1 -0
- package/dist/src/evals/trial-publication.js +25 -0
- package/dist/src/evals/trial-publication.js.map +1 -0
- package/dist/src/evals/trial-reference-validation.js +49 -0
- package/dist/src/evals/trial-reference-validation.js.map +1 -0
- package/dist/src/evals/verifier-artifacts.js +317 -0
- package/dist/src/evals/verifier-artifacts.js.map +1 -0
- package/dist/src/evals/verifier-eligibility.js +25 -0
- package/dist/src/evals/verifier-eligibility.js.map +1 -0
- package/dist/src/evals/verifier-only-rerun.js +210 -0
- package/dist/src/evals/verifier-only-rerun.js.map +1 -0
- package/dist/src/evals/verifier-runtime.js +61 -0
- package/dist/src/evals/verifier-runtime.js.map +1 -0
- package/dist/src/evals/verifier-score-artifacts.js +119 -0
- package/dist/src/evals/verifier-score-artifacts.js.map +1 -0
- package/dist/src/evals/work-item-artifacts.js +23 -0
- package/dist/src/evals/work-item-artifacts.js.map +1 -0
- package/dist/src/foundation/config.js +17 -0
- package/dist/src/foundation/config.js.map +1 -1
- package/dist/src/foundation/contained-file.js +85 -0
- package/dist/src/foundation/contained-file.js.map +1 -0
- package/dist/src/foundation/credential-redaction.js +162 -0
- package/dist/src/foundation/credential-redaction.js.map +1 -0
- package/dist/src/foundation/environment-image-references.js +59 -0
- package/dist/src/foundation/environment-image-references.js.map +1 -0
- package/dist/src/foundation/executable.js +45 -5
- package/dist/src/foundation/executable.js.map +1 -1
- package/dist/src/foundation/fs.js +2 -1
- package/dist/src/foundation/fs.js.map +1 -1
- package/dist/src/foundation/index.js +6 -2
- package/dist/src/foundation/index.js.map +1 -1
- package/dist/src/foundation/process-identity.js +69 -0
- package/dist/src/foundation/process-identity.js.map +1 -0
- package/dist/src/images/context.js +47 -0
- package/dist/src/images/context.js.map +1 -0
- package/dist/src/images/docker-buildkit.js +137 -0
- package/dist/src/images/docker-buildkit.js.map +1 -0
- package/dist/src/images/dockerfile.js +67 -0
- package/dist/src/images/dockerfile.js.map +1 -0
- package/dist/src/images/gc.js +261 -0
- package/dist/src/images/gc.js.map +1 -0
- package/dist/src/images/index.js +10 -0
- package/dist/src/images/index.js.map +1 -0
- package/dist/src/images/manifest.js +109 -0
- package/dist/src/images/manifest.js.map +1 -0
- package/dist/src/images/ownership.js +5 -0
- package/dist/src/images/ownership.js.map +1 -0
- package/dist/src/images/records.js +32 -0
- package/dist/src/images/records.js.map +1 -0
- package/dist/src/images/registry.js +154 -0
- package/dist/src/images/registry.js.map +1 -0
- package/dist/src/images/service.js +224 -0
- package/dist/src/images/service.js.map +1 -0
- package/dist/src/model-access/capture.js +255 -0
- package/dist/src/model-access/capture.js.map +1 -0
- package/dist/src/model-access/index.js +5 -0
- package/dist/src/model-access/index.js.map +1 -0
- package/dist/src/model-access/policy.js +49 -0
- package/dist/src/model-access/policy.js.map +1 -0
- package/dist/src/model-access/proxy.js +336 -0
- package/dist/src/model-access/proxy.js.map +1 -0
- package/dist/src/model-access/records.js +167 -0
- package/dist/src/model-access/records.js.map +1 -0
- package/dist/src/runs/adapter-process.js +12 -0
- package/dist/src/runs/adapter-process.js.map +1 -0
- package/dist/src/runs/bundle.js +450 -0
- package/dist/src/runs/bundle.js.map +1 -0
- package/dist/src/runs/events.js +12 -1
- package/dist/src/runs/events.js.map +1 -1
- package/dist/src/runs/executor.js +46 -45
- package/dist/src/runs/executor.js.map +1 -1
- package/dist/src/runs/finalizer.js +17 -0
- package/dist/src/runs/finalizer.js.map +1 -1
- package/dist/src/runs/index.js +8 -1
- package/dist/src/runs/index.js.map +1 -1
- package/dist/src/runs/manifest.js +5 -5
- package/dist/src/runs/manifest.js.map +1 -1
- package/dist/src/runs/phase-bundle.js +86 -0
- package/dist/src/runs/phase-bundle.js.map +1 -0
- package/dist/src/runs/phase-cancellation.js +107 -0
- package/dist/src/runs/phase-cancellation.js.map +1 -0
- package/dist/src/runs/phase-group.js +113 -0
- package/dist/src/runs/phase-group.js.map +1 -0
- package/dist/src/runs/query.js +1 -1
- package/dist/src/runs/query.js.map +1 -1
- package/dist/src/runs/records.js +3 -0
- package/dist/src/runs/records.js.map +1 -1
- package/dist/src/runs/request.js +10 -3
- package/dist/src/runs/request.js.map +1 -1
- package/dist/src/runs/training-candidate.js +161 -0
- package/dist/src/runs/training-candidate.js.map +1 -0
- package/dist/src/runs/verifier-evidence-redaction.js +61 -0
- package/dist/src/runs/verifier-evidence-redaction.js.map +1 -0
- package/dist/src/runs/verifier-evidence.js +459 -0
- package/dist/src/runs/verifier-evidence.js.map +1 -0
- package/dist/src/runs/verifier-structured-evidence.js +83 -0
- package/dist/src/runs/verifier-structured-evidence.js.map +1 -0
- package/dist/src/trajectories/analysis.js +288 -0
- package/dist/src/trajectories/analysis.js.map +1 -0
- package/dist/src/trajectories/chunk-projection.js +148 -0
- package/dist/src/trajectories/chunk-projection.js.map +1 -0
- package/dist/src/trajectories/content-projection.js +389 -0
- package/dist/src/trajectories/content-projection.js.map +1 -0
- package/dist/src/trajectories/dsh-chunk-contract.js +176 -0
- package/dist/src/trajectories/dsh-chunk-contract.js.map +1 -0
- package/dist/src/trajectories/dsh-contract.js +284 -0
- package/dist/src/trajectories/dsh-contract.js.map +1 -0
- package/dist/src/trajectories/events-chunk-drill.js +95 -0
- package/dist/src/trajectories/events-chunk-drill.js.map +1 -0
- package/dist/src/trajectories/events-page.js +367 -0
- package/dist/src/trajectories/events-page.js.map +1 -0
- package/dist/src/trajectories/index.js +3 -0
- package/dist/src/trajectories/index.js.map +1 -1
- package/dist/src/trajectories/provider-capture.js +15 -24
- package/dist/src/trajectories/provider-capture.js.map +1 -1
- package/dist/src/trajectories/providers/deepseek.js +3 -3
- package/dist/src/trajectories/providers/deepseek.js.map +1 -1
- package/dist/src/trajectories/request-attempt.js +47 -0
- package/dist/src/trajectories/request-attempt.js.map +1 -0
- package/dist/src/trajectories/stream-reader.js +311 -0
- package/dist/src/trajectories/stream-reader.js.map +1 -0
- package/dist/src/trajectories/surface-fold.js +126 -0
- package/dist/src/trajectories/surface-fold.js.map +1 -0
- package/dist/src/workers/index.js +3 -0
- package/dist/src/workers/index.js.map +1 -0
- package/dist/src/workers/remote-harbor-work-spec.js +97 -0
- package/dist/src/workers/remote-harbor-work-spec.js.map +1 -0
- package/dist/src/workers/remote-harbor-worker.js +223 -0
- package/dist/src/workers/remote-harbor-worker.js.map +1 -0
- package/docs/schemas/benchmark-hook-request-v1.schema.json +65 -0
- package/docs/schemas/benchmark-hook-response-v1.schema.json +75 -0
- package/docs/schemas/benchmark-hook-v1.schema.json +33 -0
- package/docs/schemas/benchmark-lock-v1.schema.json +351 -0
- package/docs/schemas/benchmark-metric-v1.schema.json +37 -0
- package/docs/schemas/benchmark-package-v1.schema.json +167 -0
- package/docs/schemas/benchmark-phase-group.schema.json +41 -0
- package/docs/schemas/benchmark-profile-v1.schema.json +141 -0
- package/docs/schemas/benchmark-task-v1.schema.json +384 -0
- package/docs/schemas/benchmark-tool-result-v1.schema.json +30 -0
- package/docs/schemas/environment-build-index.schema.json +13 -0
- package/docs/schemas/environment-build-record.schema.json +25 -0
- package/docs/schemas/environment-image-manifest.schema.json +62 -0
- package/docs/schemas/error.schema.json +22 -0
- package/docs/schemas/eval-control.schema.json +36 -0
- package/docs/schemas/eval-execution-plan.schema.json +216 -0
- package/docs/schemas/eval-progress.schema.json +1 -15
- package/docs/schemas/eval-rerun-result.schema.json +58 -0
- package/docs/schemas/eval-rerun-state.schema.json +61 -0
- package/docs/schemas/eval-rerun-submission.schema.json +60 -0
- package/docs/schemas/eval-result.schema.json +32 -13
- package/docs/schemas/eval-submission-input.schema.json +14 -0
- package/docs/schemas/eval-submission.schema.json +68 -0
- package/docs/schemas/eval-trial-publication.schema.json +15 -0
- package/docs/schemas/eval-trial-reference.schema.json +129 -0
- package/docs/schemas/execution-evidence.schema.json +96 -0
- package/docs/schemas/execution-lease.schema.json +50 -0
- package/docs/schemas/execution-provider-status.schema.json +65 -0
- package/docs/schemas/execution-worker.schema.json +53 -0
- package/docs/schemas/harbor-process-exit.schema.json +14 -0
- package/docs/schemas/interaction-capture-ref.schema.json +45 -0
- package/docs/schemas/local-provider-execution.schema.json +33 -0
- package/docs/schemas/model-interaction.schema.json +41 -0
- package/docs/schemas/regrade-assessment-reference.schema.json +11 -0
- package/docs/schemas/remote-result-envelope.schema.json +32 -0
- package/docs/schemas/remote-tree-envelope.schema.json +25 -0
- package/docs/schemas/remote-work-offer.schema.json +58 -0
- package/docs/schemas/remote-work-receipt.schema.json +50 -0
- package/docs/schemas/remote-worker-artifact.schema.json +17 -0
- package/docs/schemas/remote-worker-event.schema.json +18 -0
- package/docs/schemas/remote-worker-heartbeat.schema.json +37 -0
- package/docs/schemas/remote-worker-registration.schema.json +52 -0
- package/docs/schemas/result-bundle-index.schema.json +133 -0
- package/docs/schemas/run-context.schema.json +15 -0
- package/docs/schemas/run-environment-images.schema.json +39 -0
- package/docs/schemas/run-manifest.schema.json +4 -0
- package/docs/schemas/run-request.schema.json +4 -0
- package/docs/schemas/training-data-candidate.schema.json +46 -0
- package/docs/schemas/trajectory-analysis.schema.json +258 -0
- package/docs/schemas/trajectory-events-page.schema.json +40 -0
- package/docs/schemas/verifier-assessment.schema.json +77 -0
- package/docs/schemas/verifier-evidence.schema.json +276 -0
- package/integrations/harbor/hitch_benchmark.py +252 -0
- package/integrations/harbor/hitch_candidate_recycle.py +262 -0
- package/integrations/harbor/hitch_harbor_agent.py +698 -568
- package/integrations/harbor/hitch_harbor_environment.py +469 -0
- package/integrations/harbor/hitch_harbor_task_resources.py +275 -0
- package/integrations/harbor/hitch_harbor_verifier.py +83 -2
- package/integrations/harbor/hitch_phase_supervisor.py +452 -0
- package/integrations/harbor/hitch_tool_client.mjs +91 -0
- package/integrations/model-call/cli.js +57 -0
- package/package.json +30 -6
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"""Inspect Harbor task and Compose resource declarations without starting Docker."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import re
|
|
7
|
+
import sys
|
|
8
|
+
import tomllib
|
|
9
|
+
from decimal import Decimal, InvalidOperation
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
import yaml
|
|
14
|
+
from harbor.models.task.config import TaskConfig, VerifierEnvironmentMode
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def inspect_task(task_dir: Path) -> dict[str, Any]:
|
|
18
|
+
task_file = task_dir / "task.toml"
|
|
19
|
+
if not task_file.is_file():
|
|
20
|
+
raise ValueError(f"task.toml is missing: {task_file}")
|
|
21
|
+
with task_file.open("rb") as handle:
|
|
22
|
+
config = TaskConfig.model_validate(tomllib.load(handle))
|
|
23
|
+
services = _compose_services(task_dir / "environment" / "docker-compose.yaml")
|
|
24
|
+
runtime_platform = _compose_runtime_platform(
|
|
25
|
+
task_dir / "environment" / "docker-compose.yaml"
|
|
26
|
+
)
|
|
27
|
+
if "main" not in {service["name"] for service in services}:
|
|
28
|
+
services.append({"name": "main", "replicas": 1})
|
|
29
|
+
services.sort(key=lambda service: service["name"].encode("utf-8"))
|
|
30
|
+
|
|
31
|
+
verifier_mode = config.verifier.environment_mode
|
|
32
|
+
separate = verifier_mode == VerifierEnvironmentMode.SEPARATE or (
|
|
33
|
+
verifier_mode is None and config.verifier.environment is not None
|
|
34
|
+
)
|
|
35
|
+
verifier_environment = config.verifier.environment
|
|
36
|
+
if separate and verifier_environment is None:
|
|
37
|
+
verifier_environment = config.environment
|
|
38
|
+
main_egress = config.environment.os.value == "linux" and any(
|
|
39
|
+
mode is not None and mode.value != "public"
|
|
40
|
+
for mode in (
|
|
41
|
+
config.environment.network_mode,
|
|
42
|
+
config.agent.network_mode,
|
|
43
|
+
None if separate else config.verifier.network_mode,
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
verifier_egress = bool(
|
|
47
|
+
separate
|
|
48
|
+
and verifier_environment is not None
|
|
49
|
+
and verifier_environment.os.value == "linux"
|
|
50
|
+
and any(
|
|
51
|
+
mode is not None and mode.value != "public"
|
|
52
|
+
for mode in (verifier_environment.network_mode, config.verifier.network_mode)
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
images, fallbacks, builds = _environment_images(
|
|
56
|
+
config.environment, "task", task_dir / "environment"
|
|
57
|
+
)
|
|
58
|
+
if separate and verifier_environment is not None:
|
|
59
|
+
verifier_images, verifier_fallbacks, verifier_builds = _environment_images(
|
|
60
|
+
verifier_environment, "verifier", None
|
|
61
|
+
)
|
|
62
|
+
images.extend(verifier_images)
|
|
63
|
+
fallbacks.extend(verifier_fallbacks)
|
|
64
|
+
builds.extend(verifier_builds)
|
|
65
|
+
compose_images, compose_fallbacks = _compose_images(
|
|
66
|
+
task_dir / "environment" / "docker-compose.yaml"
|
|
67
|
+
)
|
|
68
|
+
images.extend(compose_images)
|
|
69
|
+
fallbacks.extend(compose_fallbacks)
|
|
70
|
+
return {
|
|
71
|
+
"schema_version": "1",
|
|
72
|
+
**({"runtime_platform": runtime_platform} if runtime_platform is not None else {}),
|
|
73
|
+
"task": _environment_resources(config.environment),
|
|
74
|
+
"verifier": {
|
|
75
|
+
"separate": separate,
|
|
76
|
+
**({"environment": _environment_resources(verifier_environment)} if verifier_environment is not None else {}),
|
|
77
|
+
},
|
|
78
|
+
"compose_services": services,
|
|
79
|
+
"provider_sidecars": {
|
|
80
|
+
"main_egress": main_egress,
|
|
81
|
+
"verifier_egress": verifier_egress,
|
|
82
|
+
},
|
|
83
|
+
"environment_images": sorted(
|
|
84
|
+
images, key=lambda entry: (entry["source"], entry["service"])
|
|
85
|
+
),
|
|
86
|
+
"environment_image_fallbacks": sorted(
|
|
87
|
+
fallbacks, key=lambda entry: (entry["source"], entry["service"])
|
|
88
|
+
),
|
|
89
|
+
"environment_builds": sorted(
|
|
90
|
+
builds, key=lambda entry: (entry["source"], entry["service"])
|
|
91
|
+
),
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _compose_runtime_platform(compose_file: Path) -> str | None:
|
|
96
|
+
if not compose_file.exists():
|
|
97
|
+
return None
|
|
98
|
+
document = yaml.safe_load(compose_file.read_text(encoding="utf-8"))
|
|
99
|
+
if not isinstance(document, dict):
|
|
100
|
+
return None
|
|
101
|
+
services = document.get("services")
|
|
102
|
+
main = services.get("main") if isinstance(services, dict) else None
|
|
103
|
+
raw = main.get("platform") if isinstance(main, dict) else None
|
|
104
|
+
if raw is None:
|
|
105
|
+
return None
|
|
106
|
+
if not isinstance(raw, str):
|
|
107
|
+
raise ValueError("Compose main platform must be a string")
|
|
108
|
+
normalized = {
|
|
109
|
+
"linux/x86_64": "linux/amd64",
|
|
110
|
+
"linux/aarch64": "linux/arm64",
|
|
111
|
+
}.get(raw.strip().lower(), raw.strip().lower())
|
|
112
|
+
if normalized not in {"linux/amd64", "linux/arm64"}:
|
|
113
|
+
raise ValueError(f"Compose main platform is unsupported: {raw}")
|
|
114
|
+
return normalized
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _environment_resources(environment: Any) -> dict[str, Any]:
|
|
118
|
+
return {
|
|
119
|
+
**({"cpu_millis": environment.cpus * 1000} if environment.cpus is not None else {}),
|
|
120
|
+
**({"memory_bytes": environment.memory_mb * 1024 * 1024} if environment.memory_mb is not None else {}),
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _environment_images(
|
|
125
|
+
environment: Any, source: str, context_dir: Path | None
|
|
126
|
+
) -> tuple[list[dict[str, str]], list[dict[str, str]], list[dict[str, str]]]:
|
|
127
|
+
reference = getattr(environment, "docker_image", None)
|
|
128
|
+
if reference is None:
|
|
129
|
+
if context_dir is not None and (context_dir / "Dockerfile").is_file():
|
|
130
|
+
return [], [], [{
|
|
131
|
+
"source": source,
|
|
132
|
+
"service": "main",
|
|
133
|
+
"context": "environment",
|
|
134
|
+
"dockerfile": "Dockerfile",
|
|
135
|
+
}]
|
|
136
|
+
return [], [{"source": source, "service": "main", "code": "backend-build"}], []
|
|
137
|
+
if not isinstance(reference, str) or not reference or "$" in reference:
|
|
138
|
+
return [], [{"source": source, "service": "main", "code": "dynamic-image"}], []
|
|
139
|
+
return [{"source": source, "service": "main", "reference": reference}], [], []
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _compose_images(
|
|
143
|
+
compose_file: Path,
|
|
144
|
+
) -> tuple[list[dict[str, str]], list[dict[str, str]]]:
|
|
145
|
+
if not compose_file.exists():
|
|
146
|
+
return [], []
|
|
147
|
+
document = yaml.safe_load(compose_file.read_text(encoding="utf-8"))
|
|
148
|
+
if document is None or not isinstance(document, dict):
|
|
149
|
+
return [], []
|
|
150
|
+
raw_services = document.get("services")
|
|
151
|
+
if not isinstance(raw_services, dict):
|
|
152
|
+
return [], []
|
|
153
|
+
images: list[dict[str, str]] = []
|
|
154
|
+
fallbacks: list[dict[str, str]] = []
|
|
155
|
+
for name, raw in raw_services.items():
|
|
156
|
+
if not isinstance(name, str) or not isinstance(raw, dict):
|
|
157
|
+
continue
|
|
158
|
+
reference = raw.get("image")
|
|
159
|
+
if raw.get("build") is not None:
|
|
160
|
+
fallbacks.append({"source": "compose", "service": name, "code": "backend-build"})
|
|
161
|
+
elif isinstance(reference, str) and reference and "$" not in reference:
|
|
162
|
+
images.append({"source": "compose", "service": name, "reference": reference})
|
|
163
|
+
elif reference is not None:
|
|
164
|
+
fallbacks.append({"source": "compose", "service": name, "code": "dynamic-image"})
|
|
165
|
+
return images, fallbacks
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _compose_services(compose_file: Path) -> list[dict[str, Any]]:
|
|
169
|
+
if not compose_file.exists():
|
|
170
|
+
return []
|
|
171
|
+
document = yaml.safe_load(compose_file.read_text(encoding="utf-8"))
|
|
172
|
+
if document is None:
|
|
173
|
+
return []
|
|
174
|
+
if not isinstance(document, dict) or "include" in document:
|
|
175
|
+
raise ValueError("Compose resource discovery requires one mapping without include")
|
|
176
|
+
raw_services = document.get("services")
|
|
177
|
+
if not isinstance(raw_services, dict):
|
|
178
|
+
raise ValueError("Compose services must be a mapping")
|
|
179
|
+
result: list[dict[str, Any]] = []
|
|
180
|
+
for name, raw in raw_services.items():
|
|
181
|
+
if not isinstance(name, str) or not name or not isinstance(raw, dict):
|
|
182
|
+
raise ValueError("Compose service declaration is invalid")
|
|
183
|
+
if raw.get("profiles") or raw.get("extends"):
|
|
184
|
+
raise ValueError(f"Compose resource discovery does not support profiles/extends: {name}")
|
|
185
|
+
deploy = raw.get("deploy") if isinstance(raw.get("deploy"), dict) else {}
|
|
186
|
+
deploy_resources = deploy.get("resources") if isinstance(deploy.get("resources"), dict) else {}
|
|
187
|
+
limits = deploy_resources.get("limits") if isinstance(deploy_resources.get("limits"), dict) else {}
|
|
188
|
+
reservations = deploy_resources.get("reservations") if isinstance(deploy_resources.get("reservations"), dict) else {}
|
|
189
|
+
cpu_values = [_cpu_millis(value, name) for value in (raw.get("cpus"), limits.get("cpus")) if value is not None]
|
|
190
|
+
memory_values = [_memory_bytes(value, name) for value in (raw.get("mem_limit"), limits.get("memory")) if value is not None]
|
|
191
|
+
gpu_values = [_gpu_count(value, name) for value in (raw.get("gpus"), reservations.get("devices")) if value is not None]
|
|
192
|
+
replicas = raw.get("scale", deploy.get("replicas", 1))
|
|
193
|
+
if isinstance(replicas, bool) or not isinstance(replicas, int) or replicas < 1:
|
|
194
|
+
raise ValueError(f"Compose service replicas must be a positive integer: {name}")
|
|
195
|
+
result.append({
|
|
196
|
+
"name": name,
|
|
197
|
+
"replicas": replicas,
|
|
198
|
+
**({"cpu_millis": max(cpu_values)} if cpu_values else {}),
|
|
199
|
+
**({"memory_bytes": max(memory_values)} if memory_values else {}),
|
|
200
|
+
**({"gpu_count": max(gpu_values)} if gpu_values else {}),
|
|
201
|
+
})
|
|
202
|
+
return result
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _gpu_count(value: Any, service: str) -> int:
|
|
206
|
+
if value == "all":
|
|
207
|
+
raise ValueError(f"Compose GPU request must use a fixed count: {service}")
|
|
208
|
+
if not isinstance(value, list) or not value:
|
|
209
|
+
raise ValueError(f"Compose GPU request is invalid: {service}")
|
|
210
|
+
total = 0
|
|
211
|
+
for request in value:
|
|
212
|
+
if not isinstance(request, dict):
|
|
213
|
+
raise ValueError(f"Compose GPU request is invalid: {service}")
|
|
214
|
+
capabilities = request.get("capabilities")
|
|
215
|
+
if not isinstance(capabilities, list) or "gpu" not in capabilities:
|
|
216
|
+
continue
|
|
217
|
+
count = request.get("count")
|
|
218
|
+
device_ids = request.get("device_ids")
|
|
219
|
+
if count is not None and device_ids is not None:
|
|
220
|
+
raise ValueError(f"Compose GPU request cannot set count and device_ids: {service}")
|
|
221
|
+
if device_ids is not None:
|
|
222
|
+
if not isinstance(device_ids, list) or not device_ids or any(not isinstance(item, str) or not item for item in device_ids):
|
|
223
|
+
raise ValueError(f"Compose GPU device_ids are invalid: {service}")
|
|
224
|
+
total += len(device_ids)
|
|
225
|
+
elif isinstance(count, int) and not isinstance(count, bool) and count > 0:
|
|
226
|
+
total += count
|
|
227
|
+
else:
|
|
228
|
+
raise ValueError(f"Compose GPU request must use a fixed count: {service}")
|
|
229
|
+
if total < 1:
|
|
230
|
+
raise ValueError(f"Compose GPU request has no gpu capability: {service}")
|
|
231
|
+
return total
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def _cpu_millis(value: Any, service: str) -> int:
|
|
235
|
+
if isinstance(value, bool) or not isinstance(value, (int, float, str)):
|
|
236
|
+
raise ValueError(f"Compose CPU limit is not numeric: {service}")
|
|
237
|
+
try:
|
|
238
|
+
decimal = Decimal(str(value).strip()) * 1000
|
|
239
|
+
except InvalidOperation as error:
|
|
240
|
+
raise ValueError(f"Compose CPU limit is not numeric: {service}") from error
|
|
241
|
+
if decimal != decimal.to_integral_value() or decimal <= 0:
|
|
242
|
+
raise ValueError(f"Compose CPU limit must be positive whole millicores: {service}")
|
|
243
|
+
return int(decimal)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def _memory_bytes(value: Any, service: str) -> int:
|
|
247
|
+
if isinstance(value, bool):
|
|
248
|
+
raise ValueError(f"Compose memory limit is invalid: {service}")
|
|
249
|
+
if isinstance(value, int):
|
|
250
|
+
if value <= 0:
|
|
251
|
+
raise ValueError(f"Compose memory limit must be positive: {service}")
|
|
252
|
+
return value
|
|
253
|
+
if not isinstance(value, str):
|
|
254
|
+
raise ValueError(f"Compose memory limit is invalid: {service}")
|
|
255
|
+
match = re.fullmatch(r"\s*([0-9]+(?:\.[0-9]+)?)\s*([kmgtpe]?i?b?)?\s*", value, re.IGNORECASE)
|
|
256
|
+
if not match:
|
|
257
|
+
raise ValueError(f"Compose memory limit is not a fixed size: {service}")
|
|
258
|
+
unit = (match.group(2) or "b").lower()
|
|
259
|
+
powers = {"b": 0, "k": 1, "kb": 1, "ki": 1, "kib": 1, "m": 2, "mb": 2, "mi": 2, "mib": 2,
|
|
260
|
+
"g": 3, "gb": 3, "gi": 3, "gib": 3, "t": 4, "tb": 4, "ti": 4, "tib": 4,
|
|
261
|
+
"p": 5, "pb": 5, "pi": 5, "pib": 5, "e": 6, "eb": 6, "ei": 6, "eib": 6}
|
|
262
|
+
bytes_value = Decimal(match.group(1)) * (1024 ** powers[unit])
|
|
263
|
+
if bytes_value != bytes_value.to_integral_value() or bytes_value <= 0:
|
|
264
|
+
raise ValueError(f"Compose memory limit is not a whole positive byte size: {service}")
|
|
265
|
+
return int(bytes_value)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def main() -> None:
|
|
269
|
+
if len(sys.argv) != 2:
|
|
270
|
+
raise SystemExit("usage: hitch_harbor_task_resources.py <task-directory>")
|
|
271
|
+
print(json.dumps(inspect_task(Path(sys.argv[1]).resolve()), separators=(",", ":"), sort_keys=True))
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
if __name__ == "__main__":
|
|
275
|
+
main()
|
|
@@ -11,7 +11,9 @@ import asyncio
|
|
|
11
11
|
import json
|
|
12
12
|
import re
|
|
13
13
|
import shutil
|
|
14
|
+
import time
|
|
14
15
|
from dataclasses import dataclass
|
|
16
|
+
from datetime import datetime, timezone
|
|
15
17
|
from pathlib import Path
|
|
16
18
|
from typing import Any
|
|
17
19
|
|
|
@@ -21,9 +23,15 @@ from harbor.verifier.verifier import Verifier
|
|
|
21
23
|
|
|
22
24
|
|
|
23
25
|
MAX_LOG_BYTES = 256 * 1024
|
|
26
|
+
HITCH_AGENT_OUTCOME_NAME = "hitch-agent-outcome.json"
|
|
24
27
|
LOG_NAMES = ("test-stdout.txt", "test-stderr.txt", "stdout.txt", "stderr.txt")
|
|
25
|
-
OUTPUT_NAMES = (*LOG_NAMES, "reward.txt", "reward.json", "ctrf.json")
|
|
26
|
-
CONTROL_NAMES = (
|
|
28
|
+
OUTPUT_NAMES = (*LOG_NAMES, "reward.txt", "reward.json", "process.json", "feedback.json", "ctrf.json")
|
|
29
|
+
CONTROL_NAMES = (
|
|
30
|
+
"infrastructure-error.json",
|
|
31
|
+
"infrastructure-retry-history.json",
|
|
32
|
+
"candidate-ineligible.json",
|
|
33
|
+
"eligibility-gate.json",
|
|
34
|
+
)
|
|
27
35
|
|
|
28
36
|
INFRASTRUCTURE_PATTERNS: tuple[tuple[str, tuple[re.Pattern[str], ...]], ...] = (
|
|
29
37
|
(
|
|
@@ -117,8 +125,35 @@ class HitchRetryingVerifier(Verifier):
|
|
|
117
125
|
self.infrastructure_retry_backoff_ms = infrastructure_retry_backoff_ms
|
|
118
126
|
|
|
119
127
|
async def verify(self) -> VerifierResult:
|
|
128
|
+
started_ns = time.monotonic_ns()
|
|
129
|
+
try:
|
|
130
|
+
return await self._verify_with_retries()
|
|
131
|
+
finally:
|
|
132
|
+
self._write_phase_timing(started_ns)
|
|
133
|
+
|
|
134
|
+
async def _verify_with_retries(self) -> VerifierResult:
|
|
135
|
+
directory = getattr(getattr(getattr(self, "task", None), "paths", None), "environment_dir", None)
|
|
136
|
+
if directory and (directory.parent / ".hitch-benchmark.json").is_file():
|
|
137
|
+
from hitch_benchmark import restore_final_response, validate_collected_submission
|
|
138
|
+
validate_collected_submission(self)
|
|
139
|
+
await restore_final_response(self)
|
|
120
140
|
# Do not trust a control file left by the candidate or a prior phase.
|
|
121
141
|
await self._remove_files(CONTROL_NAMES)
|
|
142
|
+
eligibility = self._read_trusted_agent_outcome()
|
|
143
|
+
if eligibility is None:
|
|
144
|
+
self._write_json("eligibility-gate.json", {
|
|
145
|
+
"schema_version": "1", "status": "unavailable", "verifier_executed": True,
|
|
146
|
+
})
|
|
147
|
+
elif eligibility["gradeability"] == "ungradeable":
|
|
148
|
+
self._write_json("candidate-ineligible.json", {
|
|
149
|
+
"schema_version": "1",
|
|
150
|
+
"code": "candidate_evidence_unavailable",
|
|
151
|
+
"run_id": eligibility["run_id"],
|
|
152
|
+
"candidate_bundle": eligibility["candidate_bundle"],
|
|
153
|
+
"reason_code": eligibility.get("reason_code", "candidate_evidence_unavailable"),
|
|
154
|
+
"verifier_executed": False,
|
|
155
|
+
})
|
|
156
|
+
return VerifierResult(rewards={"reward": 0})
|
|
122
157
|
attempts: list[dict[str, Any]] = []
|
|
123
158
|
for attempt in range(1, self.infrastructure_retries + 2):
|
|
124
159
|
result: VerifierResult | None = None
|
|
@@ -143,6 +178,10 @@ class HitchRetryingVerifier(Verifier):
|
|
|
143
178
|
if attempts:
|
|
144
179
|
self._write_history("recovered", attempts)
|
|
145
180
|
assert result is not None
|
|
181
|
+
directory = getattr(getattr(getattr(self, "task", None), "paths", None), "environment_dir", None)
|
|
182
|
+
if directory and (directory.parent / ".hitch-benchmark.json").is_file():
|
|
183
|
+
from hitch_benchmark import normalize_rewards
|
|
184
|
+
return normalize_rewards(self, result)
|
|
146
185
|
return result
|
|
147
186
|
|
|
148
187
|
attempts.append(
|
|
@@ -179,6 +218,48 @@ class HitchRetryingVerifier(Verifier):
|
|
|
179
218
|
|
|
180
219
|
raise AssertionError("unreachable verifier retry state")
|
|
181
220
|
|
|
221
|
+
def _read_trusted_agent_outcome(self) -> dict[str, Any] | None:
|
|
222
|
+
source = self.trial_paths.verifier_dir.parent / "agent" / HITCH_AGENT_OUTCOME_NAME
|
|
223
|
+
try:
|
|
224
|
+
if not source.is_file() or source.stat().st_size <= 0 or source.stat().st_size > 16 * 1024:
|
|
225
|
+
return None
|
|
226
|
+
value = json.loads(source.read_text(encoding="utf-8"))
|
|
227
|
+
except (OSError, UnicodeError, json.JSONDecodeError):
|
|
228
|
+
return None
|
|
229
|
+
if not isinstance(value, dict) or set(value) - {
|
|
230
|
+
"schema_version", "run_id", "status", "candidate_bundle", "submission_snapshot", "gradeability", "reason_code",
|
|
231
|
+
}:
|
|
232
|
+
return None
|
|
233
|
+
if value.get("schema_version") != "1" or re.fullmatch(r"run_[a-f0-9]{32}", str(value.get("run_id", ""))) is None:
|
|
234
|
+
return None
|
|
235
|
+
if value.get("status") not in {"succeeded", "failed", "timed_out", "cancelled"}:
|
|
236
|
+
return None
|
|
237
|
+
if value.get("candidate_bundle") not in {"complete", "missing", "invalid"}:
|
|
238
|
+
return None
|
|
239
|
+
if value.get("submission_snapshot") not in {"complete", "missing", "not-required"}:
|
|
240
|
+
return None
|
|
241
|
+
if value.get("gradeability") not in {"gradeable", "ungradeable"}:
|
|
242
|
+
return None
|
|
243
|
+
if value["gradeability"] == "gradeable" and value["candidate_bundle"] != "complete":
|
|
244
|
+
return None
|
|
245
|
+
if "reason_code" in value and (not isinstance(value["reason_code"], str) or not value["reason_code"]):
|
|
246
|
+
return None
|
|
247
|
+
return value
|
|
248
|
+
|
|
249
|
+
def _write_phase_timing(self, started_ns: int) -> None:
|
|
250
|
+
self._write_json(
|
|
251
|
+
"hitch-phase-timings.json",
|
|
252
|
+
{
|
|
253
|
+
"schema_version": "1",
|
|
254
|
+
"phases": {
|
|
255
|
+
"verifier": {
|
|
256
|
+
"duration_ms": max(0, (time.monotonic_ns() - started_ns) // 1_000_000),
|
|
257
|
+
"completed_at": datetime.now(timezone.utc).isoformat(),
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
)
|
|
262
|
+
|
|
182
263
|
async def _clear_outputs(self) -> None:
|
|
183
264
|
await self._remove_files(OUTPUT_NAMES)
|
|
184
265
|
|