agent-hitch 0.2.16 → 0.2.17
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 +7 -28
- package/README.zh-CN.md +6 -26
- package/dist/scripts/benchmark-dataset-verification.js +118 -0
- package/dist/scripts/benchmark-dataset-verification.js.map +1 -0
- package/dist/scripts/canary-external-endpoint.js +56 -0
- package/dist/scripts/canary-external-endpoint.js.map +1 -0
- package/dist/scripts/canary-native-training.js +8 -6
- package/dist/scripts/canary-native-training.js.map +1 -1
- package/dist/scripts/canary-remote-training.js +8 -6
- package/dist/scripts/canary-remote-training.js.map +1 -1
- package/dist/scripts/check-architecture.js +1 -1
- package/dist/scripts/check-architecture.js.map +1 -1
- package/dist/src/adapters/providers/codex.js +5 -2
- package/dist/src/adapters/providers/codex.js.map +1 -1
- package/dist/src/adapters/providers/model-call.js +1 -2
- package/dist/src/adapters/providers/model-call.js.map +1 -1
- package/dist/src/adapters/providers/training-tool.js +2 -0
- package/dist/src/adapters/providers/training-tool.js.map +1 -1
- package/dist/src/backends/harbor/artifact-pins.js +42 -0
- package/dist/src/backends/harbor/artifact-pins.js.map +1 -0
- package/dist/src/backends/harbor/backend.js +16 -8
- package/dist/src/backends/harbor/backend.js.map +1 -1
- package/dist/src/backends/harbor/bound-credential-helper.js +24 -0
- package/dist/src/backends/harbor/bound-credential-helper.js.map +1 -0
- package/dist/src/backends/harbor/credential-snapshot.js +71 -0
- package/dist/src/backends/harbor/credential-snapshot.js.map +1 -0
- package/dist/src/backends/harbor/environment-config.js +25 -2
- package/dist/src/backends/harbor/environment-config.js.map +1 -1
- package/dist/src/backends/harbor/environment-files.js +143 -0
- package/dist/src/backends/harbor/environment-files.js.map +1 -0
- package/dist/src/backends/harbor/evaluation-binding.js +160 -0
- package/dist/src/backends/harbor/evaluation-binding.js.map +1 -0
- package/dist/src/backends/harbor/host-credential-helper.js +5 -0
- package/dist/src/backends/harbor/host-credential-helper.js.map +1 -1
- package/dist/src/backends/harbor/index.js +2 -0
- package/dist/src/backends/harbor/index.js.map +1 -1
- package/dist/src/backends/harbor/model-proxy-config.js +3 -18
- package/dist/src/backends/harbor/model-proxy-config.js.map +1 -1
- package/dist/src/backends/harbor/portable-regrade.js +15 -3
- package/dist/src/backends/harbor/portable-regrade.js.map +1 -1
- package/dist/src/backends/harbor/python-runtime.js +71 -0
- package/dist/src/backends/harbor/python-runtime.js.map +1 -0
- package/dist/src/backends/harbor/tools.js +6 -4
- package/dist/src/backends/harbor/tools.js.map +1 -1
- package/dist/src/backends/index.js +3 -0
- package/dist/src/backends/index.js.map +1 -1
- package/dist/src/cli/arguments.js +30 -30
- package/dist/src/cli/arguments.js.map +1 -1
- package/dist/src/cli/commands/capabilities.js +7 -3
- package/dist/src/cli/commands/capabilities.js.map +1 -1
- package/dist/src/cli/commands/daemon.js +0 -17
- package/dist/src/cli/commands/daemon.js.map +1 -1
- package/dist/src/cli/commands/eval-binding.js +32 -0
- package/dist/src/cli/commands/eval-binding.js.map +1 -0
- package/dist/src/cli/commands/eval.js +21 -15
- package/dist/src/cli/commands/eval.js.map +1 -1
- package/dist/src/cli/commands/models.js +32 -45
- package/dist/src/cli/commands/models.js.map +1 -1
- package/dist/src/cli/commands/run.js +0 -35
- package/dist/src/cli/commands/run.js.map +1 -1
- package/dist/src/cli/main.js +0 -4
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/output.js +5 -16
- package/dist/src/cli/output.js.map +1 -1
- package/dist/src/control-plane/eval-records.js +3 -1
- package/dist/src/control-plane/eval-records.js.map +1 -1
- package/dist/src/control-plane/eval-recovery.js +4 -1
- package/dist/src/control-plane/eval-recovery.js.map +1 -1
- package/dist/src/control-plane/eval-scheduler.js +16 -8
- package/dist/src/control-plane/eval-scheduler.js.map +1 -1
- package/dist/src/control-plane/index.js +0 -2
- package/dist/src/control-plane/index.js.map +1 -1
- package/dist/src/control-plane/model-capture-planning.js +3 -4
- package/dist/src/control-plane/model-capture-planning.js.map +1 -1
- package/dist/src/control-plane/remote-model-routes.js +4 -24
- package/dist/src/control-plane/remote-model-routes.js.map +1 -1
- package/dist/src/control-plane/remote-offer-contract.js +2 -2
- package/dist/src/control-plane/remote-offer-contract.js.map +1 -1
- package/dist/src/control-plane/remote-result-transport.js +7 -8
- package/dist/src/control-plane/remote-result-transport.js.map +1 -1
- package/dist/src/control-plane/remote-work-coordinator.js +2 -2
- package/dist/src/control-plane/remote-work-coordinator.js.map +1 -1
- package/dist/src/control-plane/remote-work-recovery.js +2 -2
- package/dist/src/control-plane/remote-work-recovery.js.map +1 -1
- package/dist/src/control-plane/remote-worker-protocol.js +1 -1
- package/dist/src/control-plane/remote-worker-protocol.js.map +1 -1
- package/dist/src/control-plane/remote-worker-runner.js +21 -6
- package/dist/src/control-plane/remote-worker-runner.js.map +1 -1
- package/dist/src/control-plane/remote-workers.js +2 -2
- package/dist/src/control-plane/remote-workers.js.map +1 -1
- package/dist/src/control-plane/rerun-recovery.js +1 -1
- package/dist/src/control-plane/rerun-recovery.js.map +1 -1
- package/dist/src/control-plane/rerun-scheduler.js +21 -14
- package/dist/src/control-plane/rerun-scheduler.js.map +1 -1
- package/dist/src/control-plane/rerun-source.js +5 -2
- package/dist/src/control-plane/rerun-source.js.map +1 -1
- package/dist/src/control-plane/rerun-submission.js +7 -5
- package/dist/src/control-plane/rerun-submission.js.map +1 -1
- package/dist/src/control-plane/synthetic-result.js +3 -2
- package/dist/src/control-plane/synthetic-result.js.map +1 -1
- package/dist/src/control-plane/worker-model-relay.js +1 -1
- package/dist/src/control-plane/worker-model-relay.js.map +1 -1
- package/dist/src/controller-runtime/hash.js +6 -0
- package/dist/src/controller-runtime/hash.js.map +1 -1
- package/dist/src/daemon/client.js +12 -35
- package/dist/src/daemon/client.js.map +1 -1
- package/dist/src/daemon/evaluation-binding.js +33 -0
- package/dist/src/daemon/evaluation-binding.js.map +1 -0
- package/dist/src/daemon/evaluation-submission.js +27 -0
- package/dist/src/daemon/evaluation-submission.js.map +1 -0
- package/dist/src/daemon/index.js +1 -0
- package/dist/src/daemon/index.js.map +1 -1
- package/dist/src/daemon/json-stream.js +98 -0
- package/dist/src/daemon/json-stream.js.map +1 -0
- package/dist/src/daemon/scheduler.js +1 -4
- package/dist/src/daemon/scheduler.js.map +1 -1
- package/dist/src/daemon/server.js +14 -54
- package/dist/src/daemon/server.js.map +1 -1
- package/dist/src/domain/endpoints.js +2 -0
- package/dist/src/domain/endpoints.js.map +1 -0
- package/dist/src/domain/evaluation-binding.js +5 -0
- package/dist/src/domain/evaluation-binding.js.map +1 -0
- package/dist/src/domain/index.js +2 -0
- package/dist/src/domain/index.js.map +1 -1
- package/dist/src/domain/runs.js.map +1 -1
- package/dist/src/evals/benchmark-adapter-manifest.js +95 -32
- package/dist/src/evals/benchmark-adapter-manifest.js.map +1 -1
- package/dist/src/evals/benchmark-verification.js +106 -0
- package/dist/src/evals/benchmark-verification.js.map +1 -0
- package/dist/src/evals/collect-only-rerun.js +3 -2
- package/dist/src/evals/collect-only-rerun.js.map +1 -1
- package/dist/src/evals/directory.js +9 -1
- package/dist/src/evals/directory.js.map +1 -1
- package/dist/src/evals/endpoint-attempts.js +112 -0
- package/dist/src/evals/endpoint-attempts.js.map +1 -0
- package/dist/src/evals/endpoint-usage.js +8 -0
- package/dist/src/evals/endpoint-usage.js.map +1 -0
- package/dist/src/evals/environment-binding.js +9 -0
- package/dist/src/evals/environment-binding.js.map +1 -0
- package/dist/src/evals/eval-artifact-planning.js +10 -1
- package/dist/src/evals/eval-artifact-planning.js.map +1 -1
- package/dist/src/evals/eval-finalization.js +2 -3
- package/dist/src/evals/eval-finalization.js.map +1 -1
- package/dist/src/evals/eval-logical-plan.js +2 -0
- package/dist/src/evals/eval-logical-plan.js.map +1 -1
- package/dist/src/evals/eval-result-builder.js +4 -0
- package/dist/src/evals/eval-result-builder.js.map +1 -1
- package/dist/src/evals/eval-state.js +22 -0
- package/dist/src/evals/eval-state.js.map +1 -0
- package/dist/src/evals/execution-plan.js +6 -2
- package/dist/src/evals/execution-plan.js.map +1 -1
- package/dist/src/evals/index.js +5 -1
- package/dist/src/evals/index.js.map +1 -1
- package/dist/src/evals/infrastructure-retry.js +2 -0
- package/dist/src/evals/infrastructure-retry.js.map +1 -1
- package/dist/src/evals/model-capture-runtime.js +9 -13
- package/dist/src/evals/model-capture-runtime.js.map +1 -1
- package/dist/src/evals/native-phase-evidence.js +8 -2
- package/dist/src/evals/native-phase-evidence.js.map +1 -1
- package/dist/src/evals/planned-execution.js +7 -2
- package/dist/src/evals/planned-execution.js.map +1 -1
- package/dist/src/evals/planned-progress-publisher.js +18 -5
- package/dist/src/evals/planned-progress-publisher.js.map +1 -1
- package/dist/src/evals/planned-retry-execution.js +1 -0
- package/dist/src/evals/planned-retry-execution.js.map +1 -1
- package/dist/src/evals/preparation-rerun.js +0 -1
- package/dist/src/evals/preparation-rerun.js.map +1 -1
- package/dist/src/evals/progress.js +92 -7
- package/dist/src/evals/progress.js.map +1 -1
- package/dist/src/evals/records.js +12 -2
- package/dist/src/evals/records.js.map +1 -1
- package/dist/src/evals/recovery.js +2 -0
- package/dist/src/evals/recovery.js.map +1 -1
- package/dist/src/evals/remote-rerun-execution.js +1 -3
- package/dist/src/evals/remote-rerun-execution.js.map +1 -1
- package/dist/src/evals/remote-verifier-rerun.js +1 -1
- package/dist/src/evals/remote-verifier-rerun.js.map +1 -1
- package/dist/src/evals/request.js +14 -45
- package/dist/src/evals/request.js.map +1 -1
- package/dist/src/evals/rerun-observation.js +31 -0
- package/dist/src/evals/rerun-observation.js.map +1 -0
- package/dist/src/evals/rerun.js +23 -28
- package/dist/src/evals/rerun.js.map +1 -1
- package/dist/src/evals/service.js +45 -42
- package/dist/src/evals/service.js.map +1 -1
- package/dist/src/evals/shared-runtime.js +125 -0
- package/dist/src/evals/shared-runtime.js.map +1 -0
- package/dist/src/evals/trial-import.js +10 -2
- package/dist/src/evals/trial-import.js.map +1 -1
- package/dist/src/evals/trial-publication-recovery.js +1 -1
- package/dist/src/evals/trial-publication-recovery.js.map +1 -1
- package/dist/src/evals/verifier-artifacts.js +1 -0
- package/dist/src/evals/verifier-artifacts.js.map +1 -1
- package/dist/src/evals/verifier-only-rerun.js +1 -1
- package/dist/src/evals/verifier-only-rerun.js.map +1 -1
- package/dist/src/evals/verifier-rerun-result.js +3 -2
- package/dist/src/evals/verifier-rerun-result.js.map +1 -1
- package/dist/src/evals/verifier-score-artifacts.js +9 -1
- package/dist/src/evals/verifier-score-artifacts.js.map +1 -1
- package/dist/src/foundation/config.js +0 -5
- package/dist/src/foundation/config.js.map +1 -1
- package/dist/src/inference/index.js +3 -22
- package/dist/src/inference/index.js.map +1 -1
- package/dist/src/inference/lock.js +44 -130
- package/dist/src/inference/lock.js.map +1 -1
- package/dist/src/model-access/endpoint-contract.js +127 -0
- package/dist/src/model-access/endpoint-contract.js.map +1 -0
- package/dist/src/model-access/endpoint-credentials.js +54 -0
- package/dist/src/model-access/endpoint-credentials.js.map +1 -0
- package/dist/src/model-access/endpoint-probe-stream.js +66 -0
- package/dist/src/model-access/endpoint-probe-stream.js.map +1 -0
- package/dist/src/model-access/endpoint-verification.js +76 -0
- package/dist/src/model-access/endpoint-verification.js.map +1 -0
- package/dist/src/model-access/endpoints.js +105 -0
- package/dist/src/model-access/endpoints.js.map +1 -0
- package/dist/src/model-access/index.js +5 -1
- package/dist/src/model-access/index.js.map +1 -1
- package/dist/src/model-access/proxy.js +57 -14
- package/dist/src/model-access/proxy.js.map +1 -1
- package/dist/src/model-access/remote-model.js +21 -29
- package/dist/src/model-access/remote-model.js.map +1 -1
- package/dist/src/model-access/usage.js +30 -0
- package/dist/src/model-access/usage.js.map +1 -0
- package/dist/src/runs/endpoint-runtime.js +40 -0
- package/dist/src/runs/endpoint-runtime.js.map +1 -0
- package/dist/src/runs/executor.js +28 -42
- package/dist/src/runs/executor.js.map +1 -1
- package/dist/src/runs/local-inference-environment.js +5 -53
- package/dist/src/runs/local-inference-environment.js.map +1 -1
- package/dist/src/runs/manifest.js +1 -0
- package/dist/src/runs/manifest.js.map +1 -1
- package/dist/src/runs/outcome.js +3 -10
- package/dist/src/runs/outcome.js.map +1 -1
- package/dist/src/runs/queued.js +3 -2
- package/dist/src/runs/queued.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 -38
- package/dist/src/runs/request.js.map +1 -1
- package/dist/src/workers/remote-harbor-work-spec.js +8 -10
- package/dist/src/workers/remote-harbor-work-spec.js.map +1 -1
- package/dist/src/workers/remote-harbor-worker.js +3 -0
- package/dist/src/workers/remote-harbor-worker.js.map +1 -1
- package/docs/evidence/eval-preparation-2026-10-09.json +393 -0
- package/docs/evidence/eval-preparation-2026-10-09.md +178 -0
- package/docs/local-model-inference-spec.zh-CN.md +4 -663
- package/docs/resource-storage.zh-CN.md +116 -0
- package/docs/schemas/endpoint-evaluation-attempt.schema.json +29 -0
- package/docs/schemas/eval-artifact-pin.schema.json +14 -0
- package/docs/schemas/eval-execution-plan.schema.json +486 -105
- package/docs/schemas/eval-progress.schema.json +1 -1
- package/docs/schemas/eval-request.schema.json +149 -18
- package/docs/schemas/eval-rerun-submission.schema.json +8 -1
- package/docs/schemas/eval-result.schema.json +310 -56
- package/docs/schemas/evaluation-binding.schema.json +15 -0
- package/docs/schemas/external-endpoint-binding.schema.json +153 -0
- package/docs/schemas/external-endpoint-config.schema.json +93 -0
- package/docs/schemas/inference-execution-evidence.schema.json +253 -3
- package/docs/schemas/inference-lock-v3.schema.json +6 -0
- package/docs/schemas/inference-lock.schema.json +842 -341
- package/docs/schemas/ordered-eval-control.schema.json +7 -1
- package/docs/schemas/ready-endpoint-binding.schema.json +201 -0
- package/docs/schemas/run-manifest.schema.json +6 -0
- package/docs/schemas/run-request.schema.json +122 -20
- package/examples/external-inference/.env.example +16 -0
- package/examples/external-inference/README.md +203 -0
- package/examples/external-inference/accept.mjs +297 -0
- package/examples/external-inference/compose.gateway.yaml +119 -0
- package/examples/external-inference/compose.single.yaml +64 -0
- package/examples/external-inference/compose.tp2.yaml +15 -0
- package/examples/external-inference/deployment.example.json +58 -0
- package/examples/external-inference/endpoint.chat-completions.example.json +13 -0
- package/examples/external-inference/endpoint.responses.example.json +13 -0
- package/integrations/harbor/hitch_build_inputs.py +213 -0
- package/integrations/harbor/hitch_build_process.py +126 -0
- package/integrations/harbor/hitch_compose_preparation.py +274 -0
- package/integrations/harbor/hitch_harbor_agent.py +25 -39
- package/integrations/harbor/hitch_harbor_environment.py +96 -3
- package/integrations/harbor/hitch_image_cache.py +357 -0
- package/integrations/harbor/hitch_python_runtime.py +303 -0
- package/integrations/harbor/hitch_shared_runtime.py +123 -0
- package/integrations/model-call/cli.js +11 -10
- package/integrations/training-tool/cli.js +5 -3
- package/node_modules/smol-toml/LICENSE +24 -0
- package/node_modules/smol-toml/README.md +418 -0
- package/node_modules/smol-toml/dist/date.d.ts +41 -0
- package/node_modules/smol-toml/dist/date.js +127 -0
- package/node_modules/smol-toml/dist/error.d.ts +38 -0
- package/node_modules/smol-toml/dist/error.js +63 -0
- package/node_modules/smol-toml/dist/extract.js +69 -0
- package/node_modules/smol-toml/dist/index.cjs +734 -0
- package/node_modules/smol-toml/dist/index.d.ts +43 -0
- package/node_modules/smol-toml/dist/index.js +33 -0
- package/node_modules/smol-toml/dist/parse.d.ts +36 -0
- package/node_modules/smol-toml/dist/parse.js +149 -0
- package/node_modules/smol-toml/dist/primitive.js +238 -0
- package/node_modules/smol-toml/dist/stringify.d.ts +31 -0
- package/node_modules/smol-toml/dist/stringify.js +181 -0
- package/node_modules/smol-toml/dist/struct.js +179 -0
- package/node_modules/smol-toml/dist/util.d.ts +38 -0
- package/node_modules/smol-toml/dist/util.js +89 -0
- package/node_modules/smol-toml/package.json +68 -0
- package/package.json +15 -4
- package/dist/src/cli/commands/local.js +0 -130
- package/dist/src/cli/commands/local.js.map +0 -1
- package/dist/src/cli/commands/model-node.js +0 -26
- package/dist/src/cli/commands/model-node.js.map +0 -1
- package/dist/src/control-plane/inference-manager.js +0 -357
- package/dist/src/control-plane/inference-manager.js.map +0 -1
- package/dist/src/control-plane/managed-gateway-receipt.js +0 -26
- package/dist/src/control-plane/managed-gateway-receipt.js.map +0 -1
- package/dist/src/control-plane/managed-service-recovery.js +0 -158
- package/dist/src/control-plane/managed-service-recovery.js.map +0 -1
- package/dist/src/daemon/inference-prepare.js +0 -47
- package/dist/src/daemon/inference-prepare.js.map +0 -1
- package/dist/src/inference/daemon-capacity.js +0 -41
- package/dist/src/inference/daemon-capacity.js.map +0 -1
- package/dist/src/inference/device-reservation.js +0 -58
- package/dist/src/inference/device-reservation.js.map +0 -1
- package/dist/src/inference/doctor.js +0 -95
- package/dist/src/inference/doctor.js.map +0 -1
- package/dist/src/inference/generation-recovery.js +0 -83
- package/dist/src/inference/generation-recovery.js.map +0 -1
- package/dist/src/inference/managed-launcher.js +0 -35
- package/dist/src/inference/managed-launcher.js.map +0 -1
- package/dist/src/inference/materialize.js +0 -66
- package/dist/src/inference/materialize.js.map +0 -1
- package/dist/src/inference/model-location.js +0 -34
- package/dist/src/inference/model-location.js.map +0 -1
- package/dist/src/inference/node-client.js +0 -167
- package/dist/src/inference/node-client.js.map +0 -1
- package/dist/src/inference/node-registry.js +0 -79
- package/dist/src/inference/node-registry.js.map +0 -1
- package/dist/src/inference/observation.js +0 -79
- package/dist/src/inference/observation.js.map +0 -1
- package/dist/src/inference/preflight.js +0 -132
- package/dist/src/inference/preflight.js.map +0 -1
- package/dist/src/inference/process-sglang.js +0 -169
- package/dist/src/inference/process-sglang.js.map +0 -1
- package/dist/src/inference/protocol-probe.js +0 -29
- package/dist/src/inference/protocol-probe.js.map +0 -1
- package/dist/src/inference/remote-model-store.js +0 -24
- package/dist/src/inference/remote-model-store.js.map +0 -1
- package/dist/src/inference/runtime-catalog.js +0 -41
- package/dist/src/inference/runtime-catalog.js.map +0 -1
- package/dist/src/inference/runtime-store.js +0 -93
- package/dist/src/inference/runtime-store.js.map +0 -1
- package/dist/src/inference/service-attachment.js +0 -46
- package/dist/src/inference/service-attachment.js.map +0 -1
- package/dist/src/inference/service-inspection.js +0 -38
- package/dist/src/inference/service-inspection.js.map +0 -1
- package/dist/src/inference/sglang.js +0 -279
- package/dist/src/inference/sglang.js.map +0 -1
- package/dist/src/inference/supervisor.js +0 -460
- package/dist/src/inference/supervisor.js.map +0 -1
- package/dist/src/model-access/local-gateway-request.js +0 -139
- package/dist/src/model-access/local-gateway-request.js.map +0 -1
- package/dist/src/model-access/local-gateway.js +0 -323
- package/dist/src/model-access/local-gateway.js.map +0 -1
- package/dist/src/runs/local-inference-run.js +0 -53
- package/dist/src/runs/local-inference-run.js.map +0 -1
|
@@ -128,7 +128,6 @@ class HitchHarborAgent(BaseAgent):
|
|
|
128
128
|
verifier_identity: str | None = None,
|
|
129
129
|
logical_attempt: int | None = None,
|
|
130
130
|
model_capture: dict[str, Any] | None = None,
|
|
131
|
-
managed_local_inference: dict[str, Any] | None = None,
|
|
132
131
|
**kwargs: Any,
|
|
133
132
|
) -> None:
|
|
134
133
|
super().__init__(logs_dir=logs_dir, **kwargs)
|
|
@@ -167,14 +166,6 @@ class HitchHarborAgent(BaseAgent):
|
|
|
167
166
|
raise ValueError("logical_attempt must be a positive integer")
|
|
168
167
|
self.logical_attempt = logical_attempt
|
|
169
168
|
self.model_capture = _validate_model_capture(model_capture)
|
|
170
|
-
if managed_local_inference is not None and not _valid_managed_model_identity(managed_local_inference):
|
|
171
|
-
raise ValueError("managed_local_inference identity is invalid")
|
|
172
|
-
if managed_local_inference is not None and self.model_capture is None:
|
|
173
|
-
raise ValueError("managed_local_inference requires model_capture")
|
|
174
|
-
self.managed_local_inference = dict(managed_local_inference) if managed_local_inference else None
|
|
175
|
-
capture_inference = self.model_capture.get("managed_inference") if self.model_capture else None
|
|
176
|
-
if capture_inference != self.managed_local_inference:
|
|
177
|
-
raise ValueError("managed_local_inference must match model_capture identity")
|
|
178
169
|
self._hitch_version: str | None = None
|
|
179
170
|
self._entrypoint: str | None = None
|
|
180
171
|
self._artifact_manifest: dict[str, Any] | None = None
|
|
@@ -249,7 +240,10 @@ class HitchHarborAgent(BaseAgent):
|
|
|
249
240
|
# Upload the cached bundle's payload (package.json + dist/) as the
|
|
250
241
|
# package root under /opt/hitch; the local cache path is host-side
|
|
251
242
|
# bookkeeping and is not identity (spec §4.2).
|
|
252
|
-
|
|
243
|
+
shared = getattr(environment, "hitch_verify_shared_runtime", None)
|
|
244
|
+
shared_ready = await shared(payload_dir, self._artifact_host_directory) if shared else False
|
|
245
|
+
if not shared_ready:
|
|
246
|
+
await environment.upload_dir(payload_dir, "/opt/hitch")
|
|
253
247
|
await self._ensure_node(environment)
|
|
254
248
|
platform, node_version = await self._container_node_identity(environment)
|
|
255
249
|
if self._artifact_manifest is None or not self._artifact_compatible(
|
|
@@ -259,8 +253,12 @@ class HitchHarborAgent(BaseAgent):
|
|
|
259
253
|
"hitch-artifact-platform: dedicated-builder artifact is incompatible with "
|
|
260
254
|
f"trial runtime {platform}/{node_version}"
|
|
261
255
|
)
|
|
262
|
-
|
|
263
|
-
|
|
256
|
+
if shared_ready:
|
|
257
|
+
self._artifact_uploaded = True
|
|
258
|
+
self._artifact_transport_status = "shared_readonly_bind"
|
|
259
|
+
else:
|
|
260
|
+
await self._upload_harness_artifact(environment, self._artifact_host_directory)
|
|
261
|
+
self._artifact_transport_status = "dedicated_builder_upload"
|
|
264
262
|
entry = self._remote_entry(entrypoint)
|
|
265
263
|
version = await self._exec(environment, f"{self._node_prefix()} node {entry} --version")
|
|
266
264
|
self._hitch_version = (version.stdout or "").strip() or None
|
|
@@ -1417,6 +1415,7 @@ mv "$stage_dir" "$target_dir"
|
|
|
1417
1415
|
return [], "degraded-unreachable"
|
|
1418
1416
|
base = self.model_capture["base_url_template"].replace("{run_id}", run_id)
|
|
1419
1417
|
training = self.model_capture.get("training_external")
|
|
1418
|
+
external = self.model_capture.get("external_endpoint")
|
|
1420
1419
|
return [
|
|
1421
1420
|
f"OPENAI_BASE_URL={shlex.quote(base.replace('{provider}', 'openai'))}",
|
|
1422
1421
|
f"ANTHROPIC_BASE_URL={shlex.quote(base.replace('{provider}', 'anthropic'))}",
|
|
@@ -1427,14 +1426,10 @@ mv "$stage_dir" "$target_dir"
|
|
|
1427
1426
|
"OPENAI_API_KEY=hitch-training-external",
|
|
1428
1427
|
] if training else []),
|
|
1429
1428
|
*([
|
|
1430
|
-
"
|
|
1431
|
-
f"
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
"OPENAI_API_KEY=hitch-managed-local",
|
|
1435
|
-
*([f"HITCH_MANAGED_NODE_BINDING={shlex.quote(json.dumps(self.managed_local_inference['model_node'], separators=(',', ':')))}"]
|
|
1436
|
-
if self.managed_local_inference.get("model_node") else []),
|
|
1437
|
-
] if self.managed_local_inference else []),
|
|
1429
|
+
f"HITCH_EXTERNAL_RUN_ID={run_id}",
|
|
1430
|
+
f"HITCH_EXTERNAL_ENDPOINT_BINDING={shlex.quote(json.dumps(external, separators=(',', ':')))}",
|
|
1431
|
+
"OPENAI_API_KEY=hitch-external-endpoint",
|
|
1432
|
+
] if external else []),
|
|
1438
1433
|
], "healthy"
|
|
1439
1434
|
|
|
1440
1435
|
@staticmethod
|
|
@@ -1899,7 +1894,7 @@ def _validate_model_capture(value: dict[str, Any] | None) -> dict[str, Any] | No
|
|
|
1899
1894
|
required_fields = {
|
|
1900
1895
|
"schema_version", "mode", "required", "topology", "base_url_template", "health_url_template"
|
|
1901
1896
|
}
|
|
1902
|
-
if not isinstance(value, dict) or not required_fields.issubset(value) or set(value) - required_fields - {"
|
|
1897
|
+
if not isinstance(value, dict) or not required_fields.issubset(value) or set(value) - required_fields - {"external_endpoint", "training_external"}:
|
|
1903
1898
|
raise ValueError("model_capture fields are invalid")
|
|
1904
1899
|
if (
|
|
1905
1900
|
value.get("schema_version") != "1"
|
|
@@ -1924,35 +1919,26 @@ def _validate_model_capture(value: dict[str, Any] | None) -> dict[str, Any] | No
|
|
|
1924
1919
|
)
|
|
1925
1920
|
if parsed.scheme not in {"http", "https"} or not parsed.hostname or parsed.username or parsed.password:
|
|
1926
1921
|
raise ValueError(f"model_capture {field} URL is invalid")
|
|
1927
|
-
|
|
1922
|
+
external = value.get("external_endpoint")
|
|
1928
1923
|
training = value.get("training_external")
|
|
1929
1924
|
if training is not None:
|
|
1930
|
-
if (
|
|
1925
|
+
if (external is not None or not isinstance(training, dict)
|
|
1931
1926
|
or set(training) != {"binding_id", "training_run_id", "policy_version", "generation_contract_digest", "api", "max_output_tokens", "max_episode_steps"}
|
|
1932
1927
|
or training.get("api") != "chat-completions" or value.get("required") is not True
|
|
1933
1928
|
or any(not isinstance(training.get(k), str) or not training[k] for k in ("binding_id", "training_run_id", "policy_version"))
|
|
1934
1929
|
or re.fullmatch(r"sha256:[a-f0-9]{64}", str(training.get("generation_contract_digest"))) is None
|
|
1935
1930
|
or any(type(training.get(k)) is not int or training[k] <= 0 for k in ("max_output_tokens", "max_episode_steps"))):
|
|
1936
1931
|
raise ValueError("model_capture training identity is invalid")
|
|
1937
|
-
if
|
|
1938
|
-
|
|
1932
|
+
if external is not None:
|
|
1933
|
+
if (not isinstance(external, dict) or external.get("kind") != "external-endpoint"
|
|
1934
|
+
or external.get("schema_version") != "1" or "connection" in external
|
|
1935
|
+
or external.get("api") not in {"responses", "chat-completions"}
|
|
1936
|
+
or re.fullmatch(r"sha256:[a-f0-9]{64}", str(external.get("endpoint_revision"))) is None
|
|
1937
|
+
or value.get("required") is not True):
|
|
1938
|
+
raise ValueError("model_capture external endpoint binding is invalid")
|
|
1939
1939
|
return dict(value)
|
|
1940
1940
|
|
|
1941
1941
|
|
|
1942
|
-
def _valid_managed_model_identity(value: Any) -> bool:
|
|
1943
|
-
if (not isinstance(value, dict) or not {"inference_id", "model_id"}.issubset(value)
|
|
1944
|
-
or set(value) - {"inference_id", "model_id", "model_node"}
|
|
1945
|
-
or any(not isinstance(value[k], str) or re.fullmatch(r"sha256:[a-f0-9]{64}", value[k]) is None for k in ("inference_id", "model_id"))):
|
|
1946
|
-
return False
|
|
1947
|
-
if "model_node" not in value:
|
|
1948
|
-
return True
|
|
1949
|
-
node = value["model_node"]
|
|
1950
|
-
return (isinstance(node, dict) and set(node) == {"schema_version", "node_id", "generation", "runtime_digest", "launcher"}
|
|
1951
|
-
and node["schema_version"] == "2" and node["launcher"] == "process"
|
|
1952
|
-
and all(isinstance(node[k], str) and re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9_.-]{0,127}", node[k]) is not None for k in ("node_id", "generation"))
|
|
1953
|
-
and isinstance(node["runtime_digest"], str) and re.fullmatch(r"sha256:[a-f0-9]{64}", node["runtime_digest"]) is not None)
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
1942
|
def canonical_manifest_json(manifest: dict[str, Any]) -> str:
|
|
1957
1943
|
"""Canonically encode the runtime identity `{ schema_version, node_range,
|
|
1958
1944
|
entrypoints, files }` with sorted object keys and no insignificant
|
|
@@ -34,10 +34,24 @@ _GPU_OVERRIDE_PREFIX = "__HITCH_GPU_OVERRIDE_"
|
|
|
34
34
|
_HOST_CREDENTIAL_HELPER_ENV = "HITCH_HOST_CREDENTIAL_HELPER_JSON"
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
class _SharedRuntimeConfigurationError(ValueError):
|
|
38
|
+
"""No candidate was started; cleanup must preserve existing images."""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _candidate_session(session_id: str, trial_name: str | None) -> bool:
|
|
42
|
+
# Keep role selection self-contained: historical verifier repairs replace
|
|
43
|
+
# only this provider and retain the original runtime's module membership.
|
|
44
|
+
# Verifier sessions may truncate their role marker or use a step named env.
|
|
45
|
+
if trial_name is not None:
|
|
46
|
+
return session_id == f"{trial_name}__env"
|
|
47
|
+
return session_id.endswith("__env") and "__verifier__" not in session_id
|
|
48
|
+
|
|
49
|
+
|
|
37
50
|
class HitchHarborDockerEnvironment(DockerEnvironment):
|
|
38
51
|
"""Use Harbor's Docker semantics with a final ownership-label overlay."""
|
|
39
52
|
|
|
40
53
|
_hitch_static_no_network = False
|
|
54
|
+
_hitch_preparation = None
|
|
41
55
|
|
|
42
56
|
def __init__(
|
|
43
57
|
self,
|
|
@@ -48,6 +62,10 @@ class HitchHarborDockerEnvironment(DockerEnvironment):
|
|
|
48
62
|
hitch_prebuilt_task_image: str | None = None,
|
|
49
63
|
hitch_model_proxy_host_gateway: bool = False,
|
|
50
64
|
hitch_main_gpu_count: int = 0,
|
|
65
|
+
hitch_shared_runtime: Mapping[str, str] | None = None,
|
|
66
|
+
hitch_image_cache_dir: str | None = None,
|
|
67
|
+
hitch_image_build_slots: int = 2,
|
|
68
|
+
hitch_managed_keepalive: bool = False,
|
|
51
69
|
**kwargs: Any,
|
|
52
70
|
) -> None:
|
|
53
71
|
self._hitch_ownership_labels = _validate_labels(hitch_ownership_labels)
|
|
@@ -58,12 +76,32 @@ class HitchHarborDockerEnvironment(DockerEnvironment):
|
|
|
58
76
|
self._hitch_prebuilt_task_image = _validate_prebuilt_task_image(
|
|
59
77
|
hitch_prebuilt_task_image
|
|
60
78
|
)
|
|
79
|
+
# Harbor passes environment kwargs to separate verifiers too. A planned
|
|
80
|
+
# candidate image must never replace a verifier's independent context.
|
|
81
|
+
session_id = kwargs.get("session_id", args[2] if len(args) > 2 else "")
|
|
82
|
+
trial_paths = kwargs.get("trial_paths", args[3] if len(args) > 3 else None)
|
|
83
|
+
trial_name = trial_paths.trial_dir.name if trial_paths is not None else None
|
|
84
|
+
candidate = _candidate_session(session_id, trial_name)
|
|
85
|
+
if session_id and not candidate:
|
|
86
|
+
self._hitch_prebuilt_task_image = None
|
|
87
|
+
if hitch_image_cache_dir is not None and (not isinstance(hitch_image_cache_dir, str) or not Path(hitch_image_cache_dir).is_absolute()):
|
|
88
|
+
raise ValueError("Hitch image cache directory must be absolute")
|
|
89
|
+
if not isinstance(hitch_managed_keepalive, bool):
|
|
90
|
+
raise ValueError("Hitch managed keepalive flag is invalid")
|
|
91
|
+
self._hitch_preparation = None
|
|
92
|
+
if hitch_image_cache_dir or hitch_managed_keepalive:
|
|
93
|
+
from hitch_compose_preparation import ComposePreparation
|
|
94
|
+
self._hitch_preparation = ComposePreparation(self, hitch_image_cache_dir, hitch_image_build_slots, hitch_managed_keepalive)
|
|
61
95
|
if not isinstance(hitch_model_proxy_host_gateway, bool):
|
|
62
96
|
raise ValueError("Hitch model proxy host gateway flag is invalid")
|
|
63
97
|
self._hitch_model_proxy_host_gateway = hitch_model_proxy_host_gateway
|
|
64
98
|
if isinstance(hitch_main_gpu_count, bool) or not isinstance(hitch_main_gpu_count, int) or hitch_main_gpu_count < 0:
|
|
65
99
|
raise ValueError("Hitch main GPU count is invalid")
|
|
66
100
|
self._hitch_main_gpu_count = hitch_main_gpu_count
|
|
101
|
+
self._hitch_shared_runtime = None
|
|
102
|
+
if hitch_shared_runtime is not None:
|
|
103
|
+
import hitch_shared_runtime as shared_runtime
|
|
104
|
+
self._hitch_shared_runtime = shared_runtime.configure(hitch_shared_runtime, candidate)
|
|
67
105
|
self._hitch_ownership_temp_dir: tempfile.TemporaryDirectory[str] | None = None
|
|
68
106
|
self._hitch_ownership_compose_path: Path | None = None
|
|
69
107
|
self._hitch_phase_compose_path: Path | None = None
|
|
@@ -103,6 +141,7 @@ class HitchHarborDockerEnvironment(DockerEnvironment):
|
|
|
103
141
|
or self._hitch_main_gpu_count > 0
|
|
104
142
|
or self._hitch_benchmark_platform
|
|
105
143
|
or self._hitch_static_no_network
|
|
144
|
+
or self._hitch_shared_runtime
|
|
106
145
|
):
|
|
107
146
|
self._hitch_ownership_compose_path = self._write_ownership_overlay()
|
|
108
147
|
|
|
@@ -113,10 +152,52 @@ class HitchHarborDockerEnvironment(DockerEnvironment):
|
|
|
113
152
|
paths = list(super()._docker_compose_paths)
|
|
114
153
|
if self._hitch_ownership_compose_path is not None:
|
|
115
154
|
paths.append(self._hitch_ownership_compose_path)
|
|
155
|
+
if self._hitch_preparation and self._hitch_preparation.path is not None:
|
|
156
|
+
paths.append(self._hitch_preparation.path)
|
|
116
157
|
if self._hitch_phase_compose_path is not None:
|
|
117
158
|
paths.append(self._hitch_phase_compose_path)
|
|
118
159
|
return paths
|
|
119
160
|
|
|
161
|
+
@property
|
|
162
|
+
def _main_image_name(self):
|
|
163
|
+
preparation = getattr(self, "_hitch_preparation", None)
|
|
164
|
+
return preparation.images.get(MAIN_SERVICE_NAME, super()._main_image_name) if preparation else super()._main_image_name
|
|
165
|
+
|
|
166
|
+
async def _run_docker_compose_command(self, command, *args, **kwargs):
|
|
167
|
+
run = super()._run_docker_compose_command
|
|
168
|
+
if command[:1] == ["up"] and self._hitch_shared_runtime:
|
|
169
|
+
import hitch_shared_runtime as shared_runtime
|
|
170
|
+
from hitch_compose_preparation import compose_services
|
|
171
|
+
# Resolve the task's merged/interpolated configuration before our
|
|
172
|
+
# bind mounts can hide a conflicting task mount. Revalidate on every
|
|
173
|
+
# start, and never expose host snapshots to a privileged candidate.
|
|
174
|
+
try:
|
|
175
|
+
self._hitch_ownership_compose_path = self._write_ownership_overlay()
|
|
176
|
+
resolved = await run(["config", "--format", "json"])
|
|
177
|
+
shared_runtime.reject_conflicts(compose_services(resolved.stdout))
|
|
178
|
+
self._hitch_ownership_compose_path = self._write_ownership_overlay(include_shared_runtime=True)
|
|
179
|
+
except Exception as error:
|
|
180
|
+
raise _SharedRuntimeConfigurationError(str(error)) from error
|
|
181
|
+
preparation = self._hitch_preparation
|
|
182
|
+
if preparation:
|
|
183
|
+
if command == ["build"]:
|
|
184
|
+
cached = await preparation.build(run)
|
|
185
|
+
if cached is not None:
|
|
186
|
+
return cached
|
|
187
|
+
elif command[:1] == ["up"]:
|
|
188
|
+
# If Harbor selected a prebuilt image and skipped build, retain
|
|
189
|
+
# Compose's original image/pull-policy choices, including any
|
|
190
|
+
# sidecars. An implicit up is not an explicit build request.
|
|
191
|
+
await preparation.runtime(run)
|
|
192
|
+
elif command[:1] == ["down"] and preparation.images and "--rmi" in command:
|
|
193
|
+
index = command.index("--rmi")
|
|
194
|
+
if command[index + 1:index + 2] == ["local"]:
|
|
195
|
+
# Compose treats an immutable image ID as an untagged local
|
|
196
|
+
# image even though our persistent cache also owns a tag.
|
|
197
|
+
# Keep prepared images; retain all container/volume cleanup.
|
|
198
|
+
command = command[:index] + command[index + 2:]
|
|
199
|
+
return await run(command, *args, **kwargs)
|
|
200
|
+
|
|
120
201
|
def _requires_egress_control(self, *, startup_network_policy, phase_network_policies):
|
|
121
202
|
if self._hitch_static_no_network:
|
|
122
203
|
return False
|
|
@@ -148,6 +229,12 @@ class HitchHarborDockerEnvironment(DockerEnvironment):
|
|
|
148
229
|
user=user,
|
|
149
230
|
)
|
|
150
231
|
|
|
232
|
+
async def hitch_verify_shared_runtime(self, controller_payload, artifact_directory):
|
|
233
|
+
if self._hitch_shared_runtime is None:
|
|
234
|
+
return False
|
|
235
|
+
import hitch_shared_runtime as shared_runtime
|
|
236
|
+
return await shared_runtime.verify_environment(self, controller_payload, artifact_directory)
|
|
237
|
+
|
|
151
238
|
async def _apply_network_policy(self, network_policy):
|
|
152
239
|
if self._hitch_static_no_network:
|
|
153
240
|
if network_policy != self.network_policy:
|
|
@@ -188,15 +275,17 @@ class HitchHarborDockerEnvironment(DockerEnvironment):
|
|
|
188
275
|
|
|
189
276
|
async def start(self, force_build: bool):
|
|
190
277
|
try:
|
|
278
|
+
if self._hitch_preparation:
|
|
279
|
+
self._hitch_preparation.reset(force_build)
|
|
191
280
|
await super().start(force_build)
|
|
192
281
|
if self._hitch_static_no_network:
|
|
193
282
|
await self._verify_static_network()
|
|
194
283
|
if self._hitch_benchmark:
|
|
195
284
|
await self._hitch_benchmark.prepare()
|
|
196
|
-
except BaseException:
|
|
285
|
+
except BaseException as error:
|
|
197
286
|
# Harbor may abort setup before entering its normal teardown path.
|
|
198
287
|
try:
|
|
199
|
-
await self.stop(delete=
|
|
288
|
+
await self.stop(delete=not isinstance(error, _SharedRuntimeConfigurationError))
|
|
200
289
|
except BaseException:
|
|
201
290
|
pass
|
|
202
291
|
raise
|
|
@@ -222,7 +311,9 @@ class HitchHarborDockerEnvironment(DockerEnvironment):
|
|
|
222
311
|
finally:
|
|
223
312
|
await super().stop(delete)
|
|
224
313
|
|
|
225
|
-
def _write_ownership_overlay(self) -> Path:
|
|
314
|
+
def _write_ownership_overlay(self, *, include_shared_runtime=False) -> Path:
|
|
315
|
+
if include_shared_runtime and self._hitch_shared_runtime:
|
|
316
|
+
import hitch_shared_runtime as shared_runtime
|
|
226
317
|
services = {MAIN_SERVICE_NAME}
|
|
227
318
|
if self._enable_egress_control:
|
|
228
319
|
services.add(self._EGRESS_CONTROL_SERVICE_NAME)
|
|
@@ -265,6 +356,8 @@ class HitchHarborDockerEnvironment(DockerEnvironment):
|
|
|
265
356
|
service_overlays: dict[str, dict[str, Any]] = {}
|
|
266
357
|
for name in sorted(services):
|
|
267
358
|
config: dict[str, Any] = {}
|
|
359
|
+
if name == MAIN_SERVICE_NAME and include_shared_runtime and self._hitch_shared_runtime:
|
|
360
|
+
config["volumes"] = shared_runtime.compose_mounts(self._hitch_shared_runtime)
|
|
268
361
|
# The benchmark default must not replace explicit per-service
|
|
269
362
|
# architecture, e.g. an ARM QEMU sidecar beside an AMD64 candidate.
|
|
270
363
|
if getattr(self, "_hitch_benchmark_platform", None) and name not in declared_platforms:
|