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
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { chmod, link, lstat, mkdir, rename, rm, stat } from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { HitchError, ensureDir, statePaths } from "../foundation/index.js";
|
|
4
|
-
import { verifyLocalModel } from "./model-store.js";
|
|
5
|
-
export async function materializeLocalModel(root, manifest) {
|
|
6
|
-
await verifyLocalModel(root, manifest);
|
|
7
|
-
const paths = statePaths(root);
|
|
8
|
-
const target = path.join(paths.inferenceCache, "models", manifest.model_id.slice("sha256:".length));
|
|
9
|
-
if (await validMaterialization(target, manifest, paths.modelFiles))
|
|
10
|
-
return target;
|
|
11
|
-
const temporary = `${target}.tmp-${process.pid}-${Date.now()}`;
|
|
12
|
-
await rm(temporary, { recursive: true, force: true });
|
|
13
|
-
await ensureDir(temporary);
|
|
14
|
-
try {
|
|
15
|
-
for (const file of manifest.files) {
|
|
16
|
-
const destination = path.join(temporary, ...file.path.split("/"));
|
|
17
|
-
await mkdir(path.dirname(destination), { recursive: true });
|
|
18
|
-
await link(path.join(paths.modelFiles, file.sha256.slice("sha256:".length)), destination);
|
|
19
|
-
await chmod(destination, 0o444);
|
|
20
|
-
}
|
|
21
|
-
await ensureDir(path.dirname(target));
|
|
22
|
-
try {
|
|
23
|
-
await rename(temporary, target);
|
|
24
|
-
await chmodDirectories(target);
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
27
|
-
if (error.code !== "EEXIST" && error.code !== "ENOTEMPTY")
|
|
28
|
-
throw error;
|
|
29
|
-
await rm(temporary, { recursive: true, force: true });
|
|
30
|
-
}
|
|
31
|
-
if (!await validMaterialization(target, manifest, paths.modelFiles)) {
|
|
32
|
-
throw new HitchError("materialized model failed integrity validation", { code: "local_model_integrity_failed", exitCode: 5 });
|
|
33
|
-
}
|
|
34
|
-
return target;
|
|
35
|
-
}
|
|
36
|
-
finally {
|
|
37
|
-
await rm(temporary, { recursive: true, force: true }).catch(() => { });
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
async function validMaterialization(directory, manifest, modelFiles) {
|
|
41
|
-
try {
|
|
42
|
-
const directoryStat = await stat(directory);
|
|
43
|
-
if (!directoryStat.isDirectory() || (directoryStat.mode & 0o222) !== 0)
|
|
44
|
-
return false;
|
|
45
|
-
for (const file of manifest.files) {
|
|
46
|
-
const candidate = path.join(directory, ...file.path.split("/"));
|
|
47
|
-
const observed = await lstat(candidate);
|
|
48
|
-
const stored = await lstat(path.join(modelFiles, file.sha256.slice("sha256:".length)));
|
|
49
|
-
if (!observed.isFile() || observed.isSymbolicLink() || observed.size !== file.size
|
|
50
|
-
|| observed.dev !== stored.dev || observed.ino !== stored.ino)
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
async function chmodDirectories(root) {
|
|
60
|
-
const entries = await import("node:fs/promises").then(({ readdir }) => readdir(root, { withFileTypes: true }));
|
|
61
|
-
for (const entry of entries)
|
|
62
|
-
if (entry.isDirectory())
|
|
63
|
-
await chmodDirectories(path.join(root, entry.name));
|
|
64
|
-
await chmod(root, 0o555);
|
|
65
|
-
}
|
|
66
|
-
//# sourceMappingURL=materialize.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"materialize.js","sourceRoot":"","sources":["../../../src/inference/materialize.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { atomicWriteJSON, readJSON, sha256JSON, statePaths } from "../foundation/index.js";
|
|
3
|
-
import { parseModelNodeBinding } from "./manifest.js";
|
|
4
|
-
export function parseModelSnapshotRef(value) {
|
|
5
|
-
const ref = value;
|
|
6
|
-
if (!ref || Object.keys(ref).sort().join(",") !== "digest,mediaType,uri" || !/^sha256:[a-f0-9]{64}$/.test(ref.digest)
|
|
7
|
-
|| ref.uri !== `cas:${ref.digest}` || ref.mediaType !== "application/json")
|
|
8
|
-
throw new TypeError("model node requires a portable HF snapshot reference");
|
|
9
|
-
return ref;
|
|
10
|
-
}
|
|
11
|
-
function locationPath(root, model, binding) {
|
|
12
|
-
return path.join(statePaths(root).models, model.model_id.slice(7), "node-locations", sha256JSON(binding).slice(7) + ".json");
|
|
13
|
-
}
|
|
14
|
-
export async function rememberModelNodeSnapshot(root, model, binding, snapshotRef) {
|
|
15
|
-
parseModelNodeBinding(binding);
|
|
16
|
-
parseModelSnapshotRef(snapshotRef);
|
|
17
|
-
await atomicWriteJSON(locationPath(root, model, binding), { schema_version: "1", model_id: model.model_id, binding, snapshotRef });
|
|
18
|
-
}
|
|
19
|
-
export async function modelNodeSnapshot(root, model, binding) {
|
|
20
|
-
parseModelNodeBinding(binding);
|
|
21
|
-
let value;
|
|
22
|
-
try {
|
|
23
|
-
value = await readJSON(locationPath(root, model, binding));
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
if (error.code === "ENOENT")
|
|
27
|
-
return null;
|
|
28
|
-
throw error;
|
|
29
|
-
}
|
|
30
|
-
if (value.schema_version !== "1" || value.model_id !== model.model_id || sha256JSON(value.binding) !== sha256JSON(binding))
|
|
31
|
-
throw new TypeError("stored model-node location changed identity");
|
|
32
|
-
return parseModelSnapshotRef(value.snapshotRef);
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=model-location.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model-location.js","sourceRoot":"","sources":["../../../src/inference/model-location.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAC3F,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGtD,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAClD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,sBAAsB,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC;WAChH,GAAG,CAAC,GAAG,KAAK,OAAO,GAAG,CAAC,MAAM,EAAE,IAAI,GAAG,CAAC,SAAS,KAAK,kBAAkB;QAAE,MAAM,IAAI,SAAS,CAAC,sDAAsD,CAAC,CAAC;IAC1J,OAAO,GAAG,CAAC;AACb,CAAC;AACD,SAAS,YAAY,CAAC,IAAY,EAAE,KAA2B,EAAE,OAA2B;IAC1F,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC;AAC/H,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,IAAY,EAAE,KAA2B,EAAE,OAA2B,EAAE,WAA6B;IACnJ,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;IACnE,MAAM,eAAe,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;AACrI,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY,EAAE,KAA2B,EAAE,OAA2B;IAC5G,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,IAAI,KAAsG,CAAC;IAC3G,IAAI,CAAC;QAAC,KAAK,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAAC,CAAC;IACnE,OAAO,KAAK,EAAE,CAAC;QAAC,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;IACnG,IAAI,KAAK,CAAC,cAAc,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,UAAU,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,6CAA6C,CAAC,CAAC;IAC/L,OAAO,qBAAqB,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { randomUUID } from "node:crypto";
|
|
3
|
-
import { createReadStream } from "node:fs";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { lstat, mkdir } from "node:fs/promises";
|
|
6
|
-
import { Readable } from "node:stream";
|
|
7
|
-
import { pipeline } from "node:stream/promises";
|
|
8
|
-
import { HitchError, atomicWriteJSON, hitchRootId, readJSON, runCommand, sha256JSON, statePaths, withFileLock } from "../foundation/index.js";
|
|
9
|
-
import { verifyLocalModel } from "./model-store.js";
|
|
10
|
-
import { modelNodeSnapshot } from "./model-location.js";
|
|
11
|
-
import { parseLocalModelManifest } from "./manifest.js";
|
|
12
|
-
const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
13
|
-
/** Gear node protocol v2. Model bytes use separate bounded-header binary CAS. */
|
|
14
|
-
export class PythonInferenceNodeClient {
|
|
15
|
-
connection;
|
|
16
|
-
node;
|
|
17
|
-
env;
|
|
18
|
-
constructor(connection, node, env = process.env) {
|
|
19
|
-
this.connection = connection;
|
|
20
|
-
this.node = node;
|
|
21
|
-
this.env = env;
|
|
22
|
-
if (!connection.python.length || connection.python.some(arg => typeof arg !== "string" || !arg || arg.includes("\0"))
|
|
23
|
-
|| !path.posix.isAbsolute(connection.configPath) || !node.nodeId || !node.generation
|
|
24
|
-
|| [connection.gateway.localPort, connection.gateway.nodePort].some(port => !Number.isInteger(port) || port < 1 || port > 65535)
|
|
25
|
-
|| (connection.transport.type === "ssh" && !/^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/.test(connection.transport.host))) {
|
|
26
|
-
throw new TypeError("invalid explicit model-node connection");
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
command(action) {
|
|
30
|
-
const command = [...this.connection.python, "-m", "gear_training.node", action, "--config", this.connection.configPath];
|
|
31
|
-
return this.connection.transport.type === "local" ? command
|
|
32
|
-
: ["ssh", "-T", "-o", "BatchMode=yes", "-o", "ConnectTimeout=15", "--", this.connection.transport.host, command.map(quote).join(" ")];
|
|
33
|
-
}
|
|
34
|
-
envelope(operation, payload) {
|
|
35
|
-
return { schemaVersion: 2, requestId: randomUUID(), node: this.node, operation, inputDigest: sha256JSON(payload), payload };
|
|
36
|
-
}
|
|
37
|
-
response(value, envelope) {
|
|
38
|
-
const data = value;
|
|
39
|
-
if (!data || data.schemaVersion !== 2 || data.requestId !== envelope.requestId || data.inputDigest !== envelope.inputDigest
|
|
40
|
-
|| sha256JSON(data.node ?? null) !== sha256JSON(this.node) || !("result" in data)) {
|
|
41
|
-
throw new HitchError("model-node reply identity or generation changed", { code: "inference_runtime_mismatch", exitCode: 12 });
|
|
42
|
-
}
|
|
43
|
-
return data.result;
|
|
44
|
-
}
|
|
45
|
-
async exchange(action, envelope, file) {
|
|
46
|
-
const command = this.command(action);
|
|
47
|
-
const child = spawn(command[0], command.slice(1), { env: this.env, stdio: ["pipe", "pipe", "pipe"] });
|
|
48
|
-
child.stderr.resume();
|
|
49
|
-
child.stdin.on("error", () => { });
|
|
50
|
-
const timer = setTimeout(() => child.kill("SIGKILL"), file ? 3_600_000 : 120_000);
|
|
51
|
-
const completed = new Promise((resolve, reject) => {
|
|
52
|
-
child.once("error", reject);
|
|
53
|
-
child.once("close", resolve);
|
|
54
|
-
});
|
|
55
|
-
void completed.catch(() => { });
|
|
56
|
-
let output = "";
|
|
57
|
-
let length = 0;
|
|
58
|
-
const read = async () => {
|
|
59
|
-
for await (const chunk of child.stdout) {
|
|
60
|
-
length += chunk.byteLength;
|
|
61
|
-
if (length > 4 * 1024 * 1024)
|
|
62
|
-
throw new TypeError("model-node response exceeds control protocol limit");
|
|
63
|
-
output += chunk.toString();
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
async function* input() { yield Buffer.from(JSON.stringify(envelope) + "\n"); if (file)
|
|
67
|
-
yield* createReadStream(file); }
|
|
68
|
-
try {
|
|
69
|
-
const [, , code] = await Promise.all([pipeline(Readable.from(input()), child.stdin), read(), completed]);
|
|
70
|
-
if (code !== 0) {
|
|
71
|
-
let reason = "transport-failed";
|
|
72
|
-
try {
|
|
73
|
-
const parsed = JSON.parse(output);
|
|
74
|
-
if (/^[a-z][a-z0-9_-]{0,100}$/.test(parsed.error?.code))
|
|
75
|
-
reason = parsed.error.code;
|
|
76
|
-
}
|
|
77
|
-
catch { }
|
|
78
|
-
throw new HitchError(`model-node ${envelope.operation} failed (${reason}); resource ownership remains unresolved`, { code: "inference_route_unavailable", exitCode: 12 });
|
|
79
|
-
}
|
|
80
|
-
return this.response(JSON.parse(output), envelope);
|
|
81
|
-
}
|
|
82
|
-
finally {
|
|
83
|
-
clearTimeout(timer);
|
|
84
|
-
if (child.exitCode === null)
|
|
85
|
-
child.kill("SIGKILL");
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
async call(operation, payload) { return this.exchange("rpc", this.envelope(operation, payload)); }
|
|
89
|
-
payload(input) {
|
|
90
|
-
return { serviceId: input.serviceId, ownerId: hitchRootId(input.root), model: input.model, runtime: input.runtime, lock: input.lock };
|
|
91
|
-
}
|
|
92
|
-
async prepare(input) {
|
|
93
|
-
const snapshotRef = input.lock.model_node ? await modelNodeSnapshot(input.root, input.model, input.lock.model_node) : null;
|
|
94
|
-
if (snapshotRef) {
|
|
95
|
-
const observed = parseLocalModelManifest(await this.call("cas.hfManifest", { snapshotRef }));
|
|
96
|
-
if (observed.model_id !== input.model.model_id)
|
|
97
|
-
throw new TypeError("model-node content differs from its registered model");
|
|
98
|
-
await this.call("inference.prepare", this.payload(input));
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
await verifyLocalModel(input.root, input.model);
|
|
102
|
-
for (const file of input.model.files) {
|
|
103
|
-
const state = await this.call("cas.stat", { digest: file.sha256 });
|
|
104
|
-
if (state.present && state.size === file.size)
|
|
105
|
-
continue;
|
|
106
|
-
if (state.present)
|
|
107
|
-
throw new TypeError("model-node object size differs from the model manifest");
|
|
108
|
-
const result = await this.exchange("cas-import", this.envelope("cas.import", { digest: file.sha256, size: file.size }), path.join(statePaths(input.root).modelFiles, file.sha256.slice(7)));
|
|
109
|
-
if (!result.present || result.size !== file.size)
|
|
110
|
-
throw new TypeError("node did not acknowledge durable model import");
|
|
111
|
-
}
|
|
112
|
-
await this.call("inference.prepare", this.payload(input));
|
|
113
|
-
}
|
|
114
|
-
start(input) { return this.call("inference.start", this.payload(input)); }
|
|
115
|
-
inspect(owner) { return this.call("inference.inspect", owner); }
|
|
116
|
-
attach(input) {
|
|
117
|
-
const original = { serviceId: input.record.service_id, ownerId: hitchRootId(input.root), model: input.model, runtime: input.runtime, lock: input.lock };
|
|
118
|
-
return this.call("inference.attach", { serviceId: original.serviceId, ownerId: original.ownerId,
|
|
119
|
-
inferenceId: input.lock.inference_id, inputDigest: sha256JSON(original), expectedHandle: input.record.service_handle });
|
|
120
|
-
}
|
|
121
|
-
stop(owner) { return this.call("inference.stop", owner); }
|
|
122
|
-
async route(root, nodePort) {
|
|
123
|
-
const { gateway, transport } = this.connection;
|
|
124
|
-
if (nodePort !== gateway.nodePort || (transport.type === "local" && gateway.localPort !== gateway.nodePort)) {
|
|
125
|
-
throw new TypeError("model-node service port differs from its configured route");
|
|
126
|
-
}
|
|
127
|
-
if (transport.type === "ssh") {
|
|
128
|
-
const directory = statePaths(root).inferenceOperationLocks;
|
|
129
|
-
const identity = sha256JSON({ node: this.node, connection: this.connection });
|
|
130
|
-
// Short absolute socket paths fit the Unix-domain limit on macOS/Linux.
|
|
131
|
-
const socketDirectory = path.join("/tmp", `hitch-node-${process.getuid?.() ?? "user"}-${hitchRootId(root).slice(-12)}`);
|
|
132
|
-
await mkdir(socketDirectory, { mode: 0o700, recursive: true });
|
|
133
|
-
const permissions = await lstat(socketDirectory);
|
|
134
|
-
if (!permissions.isDirectory() || permissions.isSymbolicLink() || (permissions.mode & 0o077) !== 0
|
|
135
|
-
|| (process.getuid && permissions.uid !== process.getuid()))
|
|
136
|
-
throw new TypeError("model-node SSH socket directory is not private");
|
|
137
|
-
const socket = path.join(socketDirectory, `${identity.slice(-20)}.sock`);
|
|
138
|
-
const recordPath = path.join(directory, identity.slice(7) + ".tunnel.json");
|
|
139
|
-
await withFileLock(directory, identity.slice(7), async () => {
|
|
140
|
-
let prior;
|
|
141
|
-
try {
|
|
142
|
-
prior = await readJSON(recordPath);
|
|
143
|
-
}
|
|
144
|
-
catch (error) {
|
|
145
|
-
if (error.code !== "ENOENT")
|
|
146
|
-
throw error;
|
|
147
|
-
}
|
|
148
|
-
if (prior && prior.identity !== identity)
|
|
149
|
-
throw new TypeError("model-node tunnel ownership changed");
|
|
150
|
-
const invoke = (args) => runCommand("ssh", args, { env: this.env, timeoutMs: 30_000, failureCode: "inference_route_unavailable", failureExitCode: 12 });
|
|
151
|
-
const common = ["-S", socket, "-o", "BatchMode=yes", "-o", "ConnectTimeout=15"];
|
|
152
|
-
if (prior) {
|
|
153
|
-
try {
|
|
154
|
-
await invoke([...common, "-O", "check", "--", transport.host]);
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
catch { }
|
|
158
|
-
}
|
|
159
|
-
await atomicWriteJSON(recordPath, { identity, node: this.node, connection: this.connection });
|
|
160
|
-
await invoke([...common, "-M", "-fNT", "-o", "ExitOnForwardFailure=yes", "-o", "ServerAliveInterval=15", "-o", "ServerAliveCountMax=3",
|
|
161
|
-
"-L", `127.0.0.1:${gateway.localPort}:127.0.0.1:${gateway.nodePort}`, "--", transport.host]);
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
return `http://127.0.0.1:${gateway.localPort}`;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
//# sourceMappingURL=node-client.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"node-client.js","sourceRoot":"","sources":["../../../src/inference/node-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { HitchError, atomicWriteJSON, readJSON, sha256JSON, statePaths, withFileLock } from "../foundation/index.js";
|
|
3
|
-
import { parseInferenceRuntimeManifest, parseModelNodeBinding } from "./manifest.js";
|
|
4
|
-
import { PythonInferenceNodeClient } from "./node-client.js";
|
|
5
|
-
export function parseModelNodeRegistration(value) {
|
|
6
|
-
const record = exact(value, ["schema_version", "binding", "connection"]);
|
|
7
|
-
if (record.schema_version !== "2")
|
|
8
|
-
throw new TypeError("model node registration requires schema version 2");
|
|
9
|
-
const binding = parseModelNodeBinding(record.binding);
|
|
10
|
-
const connection = exact(record.connection, ["transport", "python", "configPath", "gateway"]);
|
|
11
|
-
const transport = exact(connection.transport, ["type", "host"]);
|
|
12
|
-
if (transport.type !== "local" && transport.type !== "ssh" || transport.type === "local" && transport.host !== undefined)
|
|
13
|
-
throw new TypeError("invalid model node transport");
|
|
14
|
-
const gateway = exact(connection.gateway, ["localPort", "nodePort"]);
|
|
15
|
-
if (!Array.isArray(connection.python) || typeof connection.configPath !== "string")
|
|
16
|
-
throw new TypeError("invalid model node connection");
|
|
17
|
-
const result = { schema_version: "2", binding, connection: { transport, python: connection.python, configPath: connection.configPath, gateway } };
|
|
18
|
-
// Shared command/port/SSH validation, without launching a process.
|
|
19
|
-
new PythonInferenceNodeClient(result.connection, { nodeId: binding.node_id, generation: binding.generation });
|
|
20
|
-
if (transport.type === "local" && gateway.localPort !== gateway.nodePort)
|
|
21
|
-
throw new TypeError("local model node route ports must match");
|
|
22
|
-
return result;
|
|
23
|
-
}
|
|
24
|
-
export async function observeModelNode(client, binding) {
|
|
25
|
-
const value = await client.call("probe", {});
|
|
26
|
-
if (!value || value.nodeId !== binding.node_id || value.generation !== binding.generation
|
|
27
|
-
|| value.runtimeDigest !== binding.runtime_digest || sha256JSON(value.runtime) !== binding.runtime_digest
|
|
28
|
-
|| !Array.isArray(value.gpuUuids) || value.gpuUuids.some(uuid => typeof uuid !== "string")
|
|
29
|
-
|| !Array.isArray(value.launchers) || !value.launchers.includes("process")
|
|
30
|
-
|| value.capabilities?.binaryCas !== true || value.capabilities?.durableInferenceProcesses !== true) {
|
|
31
|
-
throw new HitchError("model-node generation, Python runtime or process capability changed", { code: "inference_runtime_mismatch", exitCode: 12 });
|
|
32
|
-
}
|
|
33
|
-
return value;
|
|
34
|
-
}
|
|
35
|
-
export function runtimeFromModelNode(observation) {
|
|
36
|
-
const packages = observation.runtime.packages.filter(item => item.name === "sglang");
|
|
37
|
-
if (packages.length !== 1)
|
|
38
|
-
throw new TypeError("model node must observe exactly one SGLang distribution");
|
|
39
|
-
const packageInfo = packages[0];
|
|
40
|
-
const body = { schema_version: "2", engine: "sglang", sglang_version: packageInfo.version, sglang_commit: packageInfo.commit,
|
|
41
|
-
backend: "cuda", package: { kind: "python-env", environment_digest: observation.runtimeDigest,
|
|
42
|
-
python_version: observation.runtime.pythonVersion, packages_digest: observation.runtime.packagesDigest }, compatibility_profile: "gear-model-node-v2" };
|
|
43
|
-
return parseInferenceRuntimeManifest({ ...body, runtime_id: sha256JSON(body) });
|
|
44
|
-
}
|
|
45
|
-
export async function registerModelNode(root, value, env = process.env) {
|
|
46
|
-
const registration = parseModelNodeRegistration(value);
|
|
47
|
-
const { binding, connection } = registration;
|
|
48
|
-
const client = new PythonInferenceNodeClient(connection, { nodeId: binding.node_id, generation: binding.generation }, env);
|
|
49
|
-
const observation = await observeModelNode(client, binding);
|
|
50
|
-
const runtime = runtimeFromModelNode(observation);
|
|
51
|
-
await withFileLock(statePaths(root).inferenceOperationLocks, sha256JSON(binding), async () => {
|
|
52
|
-
// Explicit re-registration may repair connection coordinates after probing
|
|
53
|
-
// the same frozen identity. Old generation records remain recoverable.
|
|
54
|
-
await atomicWriteJSON(registrationPath(root, binding), registration);
|
|
55
|
-
await atomicWriteJSON(path.join(statePaths(root).inferenceRuntimes, runtime.runtime_id.slice(7), "manifest.json"), runtime);
|
|
56
|
-
});
|
|
57
|
-
return { schema_version: "2", binding, runtime, gpu_uuids: observation.gpuUuids };
|
|
58
|
-
}
|
|
59
|
-
export async function loadModelNodeClient(root, binding, env = process.env) {
|
|
60
|
-
const record = parseModelNodeRegistration(await readJSON(registrationPath(root, parseModelNodeBinding(binding))));
|
|
61
|
-
if (sha256JSON(record.binding) !== sha256JSON(binding))
|
|
62
|
-
throw new TypeError("model node registration identity changed");
|
|
63
|
-
return new PythonInferenceNodeClient(record.connection, { nodeId: binding.node_id, generation: binding.generation }, env);
|
|
64
|
-
}
|
|
65
|
-
function registrationPath(root, binding) {
|
|
66
|
-
return path.join(statePaths(root).inferenceNodes, sha256JSON(binding).slice(7) + ".json");
|
|
67
|
-
}
|
|
68
|
-
function exact(value, keys) {
|
|
69
|
-
if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).some(key => !keys.includes(key)))
|
|
70
|
-
throw new TypeError("invalid model node registration fields");
|
|
71
|
-
return value;
|
|
72
|
-
}
|
|
73
|
-
export async function readModelNodeRegistration(file) {
|
|
74
|
-
return parseModelNodeRegistration(await readJSON(file));
|
|
75
|
-
}
|
|
76
|
-
export async function readModelNodeBinding(file) {
|
|
77
|
-
return parseModelNodeBinding(await readJSON(file));
|
|
78
|
-
}
|
|
79
|
-
//# sourceMappingURL=node-registry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"node-registry.js","sourceRoot":"","sources":["../../../src/inference/node-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { HitchError } from "../foundation/index.js";
|
|
2
|
-
/** /server_info contains credentials. Persist only this explicit projection. */
|
|
3
|
-
export function validateRuntimeObservation(value, imageId, gpuUuid, lock, runtime) {
|
|
4
|
-
const { info, tokens } = validateEngineInfo(value, gpuUuid, lock, runtime);
|
|
5
|
-
if (runtime.package.kind !== "oci" || !/^sha256:[a-f0-9]{64}$/.test(imageId))
|
|
6
|
-
throw mismatch("container image ID is missing or runtime is not OCI");
|
|
7
|
-
return {
|
|
8
|
-
schema_version: "1", ...observationFields(info, tokens, gpuUuid, lock), container_image_id: imageId,
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
/** Process observations record the node environment; no fictitious inner OCI image. */
|
|
12
|
-
export function validateProcessRuntimeObservation(value, observed, gpuUuid, lock, runtime, expectedNode) {
|
|
13
|
-
if (runtime.schema_version !== "2" || runtime.package.kind !== "python-env" || observed.kind !== "python-env"
|
|
14
|
-
|| observed.node_id !== expectedNode.node_id || observed.generation !== expectedNode.generation
|
|
15
|
-
|| observed.environment_digest !== runtime.package.environment_digest || observed.python_version !== runtime.package.python_version
|
|
16
|
-
|| observed.packages_digest !== runtime.package.packages_digest
|
|
17
|
-
|| (observed.outer_image_digest !== null && !/^sha256:[a-f0-9]{64}$/.test(observed.outer_image_digest)))
|
|
18
|
-
throw mismatch("model-node Python environment or generation changed");
|
|
19
|
-
const { info, tokens } = validateEngineInfo(value, gpuUuid, lock, runtime);
|
|
20
|
-
return { schema_version: "2", ...observationFields(info, tokens, gpuUuid, lock), runtime: {
|
|
21
|
-
kind: "python-env", node_id: observed.node_id, generation: observed.generation,
|
|
22
|
-
environment_digest: observed.environment_digest, python_version: observed.python_version,
|
|
23
|
-
packages_digest: observed.packages_digest, outer_image_digest: observed.outer_image_digest,
|
|
24
|
-
} };
|
|
25
|
-
}
|
|
26
|
-
function validateEngineInfo(value, gpuUuid, lock, runtime) {
|
|
27
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
28
|
-
throw mismatch("invalid /server_info response");
|
|
29
|
-
const info = value;
|
|
30
|
-
const expected = {
|
|
31
|
-
version: runtime.sglang_version, device: lock.execution.platform.backend,
|
|
32
|
-
dtype: lock.execution.dtype, kv_cache_dtype: lock.execution.kv_cache_dtype,
|
|
33
|
-
attention_backend: lock.execution.attention_backend, sampling_backend: lock.execution.sampling_backend,
|
|
34
|
-
context_length: lock.execution.context_tokens_per_request, max_running_requests: lock.execution.max_running_requests,
|
|
35
|
-
tp_size: 1, dp_size: 1, pp_size: 1,
|
|
36
|
-
disable_radix_cache: lock.execution.prefix_cache.mode === "disabled",
|
|
37
|
-
disable_overlap_schedule: !lock.execution.platform.overlap_schedule,
|
|
38
|
-
};
|
|
39
|
-
for (const [field, wanted] of Object.entries(expected)) {
|
|
40
|
-
const actual = info[field];
|
|
41
|
-
if (field === "dtype" || field === "kv_cache_dtype") {
|
|
42
|
-
if (normalizeDtype(actual) === normalizeDtype(wanted))
|
|
43
|
-
continue;
|
|
44
|
-
}
|
|
45
|
-
if (actual !== wanted)
|
|
46
|
-
throw mismatch(`${field}: expected ${String(wanted)}, engine reported ${String(actual)}`);
|
|
47
|
-
}
|
|
48
|
-
const tokens = info.max_total_num_tokens;
|
|
49
|
-
if (!Number.isSafeInteger(tokens) || tokens < lock.execution.max_total_tokens) {
|
|
50
|
-
throw mismatch(`engine token pool ${String(tokens)} is smaller than locked budget ${lock.execution.max_total_tokens}`);
|
|
51
|
-
}
|
|
52
|
-
if (lock.execution.platform.backend === "cuda") {
|
|
53
|
-
if (info.mem_fraction_static !== lock.execution.platform.mem_fraction_static)
|
|
54
|
-
throw mismatch("CUDA memory fraction changed");
|
|
55
|
-
if (!gpuUuid || gpuUuid !== lock.execution.platform.device_constraint)
|
|
56
|
-
throw mismatch("container GPU UUID differs from the lock");
|
|
57
|
-
}
|
|
58
|
-
else if (gpuUuid !== null)
|
|
59
|
-
throw mismatch("CPU service unexpectedly exposes a GPU");
|
|
60
|
-
return { info, tokens: tokens };
|
|
61
|
-
}
|
|
62
|
-
function observationFields(info, tokens, gpuUuid, lock) {
|
|
63
|
-
return {
|
|
64
|
-
observed_at: new Date().toISOString(), version: String(info.version),
|
|
65
|
-
device: lock.execution.platform.backend, dtype: String(info.dtype),
|
|
66
|
-
kv_cache_dtype: String(info.kv_cache_dtype), attention_backend: String(info.attention_backend),
|
|
67
|
-
sampling_backend: String(info.sampling_backend), context_length: info.context_length,
|
|
68
|
-
max_total_num_tokens: tokens, max_running_requests: info.max_running_requests,
|
|
69
|
-
gpu_uuid: gpuUuid,
|
|
70
|
-
probe: { api: lock.protocol.api, max_output_tokens: 8, streaming: true },
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
function normalizeDtype(value) {
|
|
74
|
-
return { bf16: "bfloat16", half: "float16", fp16: "float16", float: "float32" }[String(value)] ?? value;
|
|
75
|
-
}
|
|
76
|
-
function mismatch(message) {
|
|
77
|
-
return new HitchError(`SGLang runtime observation mismatch: ${message}`, { code: "inference_runtime_mismatch", exitCode: 12 });
|
|
78
|
-
}
|
|
79
|
-
//# sourceMappingURL=observation.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"observation.js","sourceRoot":"","sources":["../../../src/inference/observation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { HitchError } from "../foundation/index.js";
|
|
2
|
-
import { resolveLocalInferenceDevice } from "./doctor.js";
|
|
3
|
-
import { reservedInferenceDevices } from "./device-reservation.js";
|
|
4
|
-
import { buildInferenceLock, loadInferenceLock, persistInferenceLock } from "./lock.js";
|
|
5
|
-
import { resolveLocalModel, verifyLocalModel } from "./model-store.js";
|
|
6
|
-
import { loadInferenceRuntime, prepareInferenceRuntime } from "./runtime-store.js";
|
|
7
|
-
import { loadModelNodeClient, observeModelNode, runtimeFromModelNode } from "./node-registry.js";
|
|
8
|
-
import { parseModelNodeBinding } from "./manifest.js";
|
|
9
|
-
import { sha256JSON } from "../foundation/index.js";
|
|
10
|
-
export async function prepareLocalInference(options) {
|
|
11
|
-
const model = await resolveLocalModel(options.root, options.selection.model);
|
|
12
|
-
if (options.selection.model_node) {
|
|
13
|
-
const { verifyModelOnNode } = await import("./remote-model-store.js");
|
|
14
|
-
await verifyModelOnNode(options.root, model, options.selection.model_node);
|
|
15
|
-
return prepareModelNodeInference(options, model);
|
|
16
|
-
}
|
|
17
|
-
await verifyLocalModel(options.root, model);
|
|
18
|
-
const reusable = options.reusableLocks?.find((lock) => lock.model_id === model.model_id
|
|
19
|
-
&& !lock.model_node
|
|
20
|
-
&& lock.protocol.api === (options.harnessRef?.startsWith("training-tool@") ? "chat-completions" : "responses")
|
|
21
|
-
&& lock.profile === options.selection.profile
|
|
22
|
-
&& (options.selection.device === "auto" || options.selection.device === lock.execution.platform.backend));
|
|
23
|
-
const inferenceId = options.selection.inference_id ?? reusable?.inference_id;
|
|
24
|
-
if (inferenceId) {
|
|
25
|
-
const lock = await loadInferenceLock(options.root, inferenceId);
|
|
26
|
-
if (lock.model_node)
|
|
27
|
-
throw new HitchError("a v2 inference lock requires its explicit model-node selection", { code: "inference_lock_mismatch", exitCode: 2 });
|
|
28
|
-
if (lock.model_id !== model.model_id) {
|
|
29
|
-
throw new HitchError("prepared inference identity refers to a different model", { code: "inference_lock_mismatch", exitCode: 2 });
|
|
30
|
-
}
|
|
31
|
-
const resolved = await resolveLocalInferenceDevice(lock.execution.platform.backend, {
|
|
32
|
-
...options.doctor,
|
|
33
|
-
...(lock.execution.platform.backend === "cuda" && lock.execution.platform.device_constraint
|
|
34
|
-
? { deviceConstraint: lock.execution.platform.device_constraint } : {}),
|
|
35
|
-
});
|
|
36
|
-
assertHarnessCompatibility(options.harnessRef, lock);
|
|
37
|
-
return {
|
|
38
|
-
doctor: resolved.doctor,
|
|
39
|
-
model,
|
|
40
|
-
runtime: await loadInferenceRuntime(options.root, lock.runtime_id),
|
|
41
|
-
lock,
|
|
42
|
-
runtime_cache_hit: true,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
const weights = model.files.filter((file) => file.path.endsWith(".safetensors")).reduce((sum, file) => sum + file.size, 0);
|
|
46
|
-
const resolved = await resolveLocalInferenceDevice(options.selection.device, {
|
|
47
|
-
...options.doctor, requiredMemoryMiB: Math.ceil((weights * 1.25 + 1024 ** 3) / 1024 ** 2),
|
|
48
|
-
excludedDeviceUuids: [...await reservedInferenceDevices(), ...(options.doctor?.excludedDeviceUuids ?? [])],
|
|
49
|
-
});
|
|
50
|
-
if (resolved.backend === "metal") {
|
|
51
|
-
throw new HitchError("Metal local inference is not available in P0", { code: "inference_device_unsupported", exitCode: 3 });
|
|
52
|
-
}
|
|
53
|
-
const prepared = await prepareInferenceRuntime({
|
|
54
|
-
...options.runtime,
|
|
55
|
-
root: options.root,
|
|
56
|
-
backend: resolved.backend,
|
|
57
|
-
offline: options.selection.offline,
|
|
58
|
-
...(options.onProgress ? { onProgress: options.onProgress } : {}),
|
|
59
|
-
});
|
|
60
|
-
const lock = buildInferenceLock(model, prepared.manifest, {
|
|
61
|
-
backend: resolved.backend,
|
|
62
|
-
profile: options.selection.profile,
|
|
63
|
-
...(options.harnessRef?.startsWith("training-tool@") ? { api: "chat-completions" } : {}),
|
|
64
|
-
...(resolved.doctor.gpu?.uuid ? { deviceConstraint: resolved.doctor.gpu.uuid } : {}),
|
|
65
|
-
});
|
|
66
|
-
assertHarnessCompatibility(options.harnessRef, lock);
|
|
67
|
-
await persistInferenceLock(options.root, lock);
|
|
68
|
-
return {
|
|
69
|
-
model,
|
|
70
|
-
runtime: prepared.manifest,
|
|
71
|
-
lock,
|
|
72
|
-
doctor: resolved.doctor,
|
|
73
|
-
runtime_cache_hit: prepared.cache_hit,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
async function prepareModelNodeInference(options, model) {
|
|
77
|
-
const binding = parseModelNodeBinding(options.selection.model_node);
|
|
78
|
-
if (!["auto", "cuda"].includes(options.selection.device))
|
|
79
|
-
throw new HitchError("model-node inference requires CUDA", { code: "inference_device_unsupported", exitCode: 3 });
|
|
80
|
-
const observation = await observeModelNode(await loadModelNodeClient(options.root, binding), binding);
|
|
81
|
-
const runtime = runtimeFromModelNode(observation);
|
|
82
|
-
const persistedRuntime = await loadInferenceRuntime(options.root, runtime.runtime_id);
|
|
83
|
-
if (sha256JSON(persistedRuntime) !== sha256JSON(runtime))
|
|
84
|
-
throw new HitchError("registered model-node runtime changed", { code: "inference_runtime_mismatch", exitCode: 12 });
|
|
85
|
-
const reusable = options.reusableLocks?.find(lock => lock.model_id === model.model_id && lock.profile === options.selection.profile
|
|
86
|
-
&& sha256JSON(lock.model_node ?? null) === sha256JSON(binding)
|
|
87
|
-
&& lock.protocol.api === (options.harnessRef?.startsWith("training-tool@") ? "chat-completions" : "responses"));
|
|
88
|
-
const inferenceId = options.selection.inference_id ?? reusable?.inference_id;
|
|
89
|
-
const device = options.doctor?.deviceConstraint;
|
|
90
|
-
let lock;
|
|
91
|
-
if (inferenceId) {
|
|
92
|
-
lock = await loadInferenceLock(options.root, inferenceId);
|
|
93
|
-
if (sha256JSON(lock.model_node ?? null) !== sha256JSON(binding) || lock.model_id !== model.model_id || lock.runtime_id !== runtime.runtime_id) {
|
|
94
|
-
throw new HitchError("inference lock differs from the frozen model node, runtime or model", { code: "inference_lock_mismatch", exitCode: 2 });
|
|
95
|
-
}
|
|
96
|
-
if (device && (lock.execution.platform.backend !== "cuda" || lock.execution.platform.device_constraint !== device))
|
|
97
|
-
throw new HitchError("inference device changed", { code: "inference_lock_mismatch", exitCode: 2 });
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
if (!device)
|
|
101
|
-
throw new HitchError("plan model-node inference with an explicit --gpu before submitting it", { code: "inference_device_unavailable", exitCode: 3 });
|
|
102
|
-
lock = buildInferenceLock(model, runtime, { backend: "cuda", profile: options.selection.profile, modelNode: binding, deviceConstraint: device,
|
|
103
|
-
...(options.harnessRef?.startsWith("training-tool@") ? { api: "chat-completions" } : {}) });
|
|
104
|
-
}
|
|
105
|
-
if (lock.execution.platform.backend !== "cuda" || !observation.gpuUuids.includes(lock.execution.platform.device_constraint ?? "")) {
|
|
106
|
-
throw new HitchError("locked physical GPU is absent on the model node", { code: "inference_device_unavailable", exitCode: 3 });
|
|
107
|
-
}
|
|
108
|
-
assertHarnessCompatibility(options.harnessRef, lock);
|
|
109
|
-
await persistInferenceLock(options.root, lock);
|
|
110
|
-
return { model, runtime, lock, runtime_cache_hit: true, node_observation: observation };
|
|
111
|
-
}
|
|
112
|
-
function assertHarnessCompatibility(harnessRef, lock) {
|
|
113
|
-
if (!harnessRef)
|
|
114
|
-
return;
|
|
115
|
-
const harness = harnessRef.split("@", 1)[0];
|
|
116
|
-
if (harness !== "codex" && harness !== "model-call" && harness !== "training-tool") {
|
|
117
|
-
throw new HitchError(`local inference is not supported in the preview for ${harness}`, { code: "inference_harness_unsupported", exitCode: 2 });
|
|
118
|
-
}
|
|
119
|
-
if (harness === "training-tool" && lock.protocol.api !== "chat-completions")
|
|
120
|
-
throw new HitchError("training-tool requires an explicit Chat Completions inference lock", { code: "inference_protocol_unsupported", exitCode: 2 });
|
|
121
|
-
if ((harness === "codex" || harness === "training-tool") && !lock.protocol.tool_calls) {
|
|
122
|
-
throw new HitchError("this model type has no configured SGLang tool-call parser for Codex", {
|
|
123
|
-
code: "inference_protocol_unsupported", exitCode: 2,
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
if (harness === "codex" && harnessRef !== "codex@version:0.145.0") {
|
|
127
|
-
throw new HitchError("local inference supports only codex@version:0.145.0", {
|
|
128
|
-
code: "inference_harness_unsupported", exitCode: 2,
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
//# sourceMappingURL=preflight.js.map
|