@miller-tech/uap 2.21.2 → 2.36.1
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 +22 -10
- package/config/model-profiles/qwen38-coder390.json +46 -0
- package/config/model-profiles/qwen38.json +3 -2
- package/config/model-registry.json +110 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/benchmarks/paired/types.d.ts +2 -2
- package/dist/bin/cli.js +315 -20
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/attention.d.ts +6 -0
- package/dist/cli/attention.d.ts.map +1 -0
- package/dist/cli/attention.js +115 -0
- package/dist/cli/attention.js.map +1 -0
- package/dist/cli/bench-report.d.ts +82 -0
- package/dist/cli/bench-report.d.ts.map +1 -0
- package/dist/cli/bench-report.js +237 -0
- package/dist/cli/bench-report.js.map +1 -0
- package/dist/cli/clients.d.ts +6 -0
- package/dist/cli/clients.d.ts.map +1 -0
- package/dist/cli/clients.js +142 -0
- package/dist/cli/clients.js.map +1 -0
- package/dist/cli/dashboard-grants.d.ts +26 -0
- package/dist/cli/dashboard-grants.d.ts.map +1 -0
- package/dist/cli/dashboard-grants.js +69 -0
- package/dist/cli/dashboard-grants.js.map +1 -0
- package/dist/cli/dashboard-pace.d.ts +31 -0
- package/dist/cli/dashboard-pace.d.ts.map +1 -0
- package/dist/cli/dashboard-pace.js +42 -0
- package/dist/cli/dashboard-pace.js.map +1 -0
- package/dist/cli/dashboard-session.d.ts +25 -0
- package/dist/cli/dashboard-session.d.ts.map +1 -0
- package/dist/cli/dashboard-session.js +814 -0
- package/dist/cli/dashboard-session.js.map +1 -0
- package/dist/cli/dashboard-types.d.ts +18 -0
- package/dist/cli/dashboard-types.d.ts.map +1 -0
- package/dist/cli/dashboard-types.js +9 -0
- package/dist/cli/dashboard-types.js.map +1 -0
- package/dist/cli/dashboard.d.ts +2 -18
- package/dist/cli/dashboard.d.ts.map +1 -1
- package/dist/cli/dashboard.js +43 -793
- package/dist/cli/dashboard.js.map +1 -1
- package/dist/cli/deliver.d.ts +35 -0
- package/dist/cli/deliver.d.ts.map +1 -1
- package/dist/cli/deliver.js +93 -9
- package/dist/cli/deliver.js.map +1 -1
- package/dist/cli/diff.d.ts +85 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +293 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/eta.d.ts +35 -0
- package/dist/cli/eta.d.ts.map +1 -0
- package/dist/cli/eta.js +101 -0
- package/dist/cli/eta.js.map +1 -0
- package/dist/cli/handsfree.d.ts +7 -0
- package/dist/cli/handsfree.d.ts.map +1 -1
- package/dist/cli/handsfree.js +27 -0
- package/dist/cli/handsfree.js.map +1 -1
- package/dist/cli/hooks.d.ts.map +1 -1
- package/dist/cli/hooks.js +126 -5
- package/dist/cli/hooks.js.map +1 -1
- package/dist/cli/loops.d.ts +24 -5
- package/dist/cli/loops.d.ts.map +1 -1
- package/dist/cli/loops.js +92 -12
- package/dist/cli/loops.js.map +1 -1
- package/dist/cli/models.d.ts +62 -0
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/cli/models.js +567 -0
- package/dist/cli/models.js.map +1 -0
- package/dist/cli/plan.d.ts +9 -0
- package/dist/cli/plan.d.ts.map +1 -1
- package/dist/cli/plan.js +57 -4
- package/dist/cli/plan.js.map +1 -1
- package/dist/cli/proxy-relay.d.ts +55 -0
- package/dist/cli/proxy-relay.d.ts.map +1 -0
- package/dist/cli/proxy-relay.js +116 -0
- package/dist/cli/proxy-relay.js.map +1 -0
- package/dist/cli/proxy.d.ts +4 -0
- package/dist/cli/proxy.d.ts.map +1 -1
- package/dist/cli/proxy.js +26 -1
- package/dist/cli/proxy.js.map +1 -1
- package/dist/cli/sandbox.d.ts +101 -4
- package/dist/cli/sandbox.d.ts.map +1 -1
- package/dist/cli/sandbox.js +393 -44
- package/dist/cli/sandbox.js.map +1 -1
- package/dist/cli/self.d.ts +13 -0
- package/dist/cli/self.d.ts.map +1 -0
- package/dist/cli/self.js +94 -0
- package/dist/cli/self.js.map +1 -0
- package/dist/cli/systemd-services.d.ts +2 -8
- package/dist/cli/systemd-services.d.ts.map +1 -1
- package/dist/cli/systemd-services.js +5 -20
- package/dist/cli/systemd-services.js.map +1 -1
- package/dist/cli/task.js +1 -1
- package/dist/cli/task.js.map +1 -1
- package/dist/cli/wizard-config.d.ts.map +1 -1
- package/dist/cli/wizard-config.js +31 -2
- package/dist/cli/wizard-config.js.map +1 -1
- package/dist/config/settings-registry.d.ts +1 -1
- package/dist/config/settings-registry.d.ts.map +1 -1
- package/dist/config/settings-registry.js +108 -0
- package/dist/config/settings-registry.js.map +1 -1
- package/dist/coordination/capability-router.js +2 -2
- package/dist/coordination/capability-router.js.map +1 -1
- package/dist/coordination/database.d.ts +13 -0
- package/dist/coordination/database.d.ts.map +1 -1
- package/dist/coordination/database.js +63 -7
- package/dist/coordination/database.js.map +1 -1
- package/dist/coordination/eta-inject.d.ts +32 -0
- package/dist/coordination/eta-inject.d.ts.map +1 -0
- package/dist/coordination/eta-inject.js +64 -0
- package/dist/coordination/eta-inject.js.map +1 -0
- package/dist/coordination/reactor.d.ts.map +1 -1
- package/dist/coordination/reactor.js +14 -0
- package/dist/coordination/reactor.js.map +1 -1
- package/dist/coordination/service.d.ts +18 -8
- package/dist/coordination/service.d.ts.map +1 -1
- package/dist/coordination/service.js +38 -28
- package/dist/coordination/service.js.map +1 -1
- package/dist/dashboard/client-registry.d.ts +163 -0
- package/dist/dashboard/client-registry.d.ts.map +1 -0
- package/dist/dashboard/client-registry.js +549 -0
- package/dist/dashboard/client-registry.js.map +1 -0
- package/dist/dashboard/controls.d.ts.map +1 -1
- package/dist/dashboard/controls.js +33 -4
- package/dist/dashboard/controls.js.map +1 -1
- package/dist/dashboard/data-seeder.d.ts +10 -7
- package/dist/dashboard/data-seeder.d.ts.map +1 -1
- package/dist/dashboard/data-seeder.js +31 -75
- package/dist/dashboard/data-seeder.js.map +1 -1
- package/dist/dashboard/data-service.d.ts +9 -0
- package/dist/dashboard/data-service.d.ts.map +1 -1
- package/dist/dashboard/data-service.js +32 -3
- package/dist/dashboard/data-service.js.map +1 -1
- package/dist/dashboard/placement-routes.d.ts +119 -0
- package/dist/dashboard/placement-routes.d.ts.map +1 -0
- package/dist/dashboard/placement-routes.js +331 -0
- package/dist/dashboard/placement-routes.js.map +1 -0
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +408 -2
- package/dist/dashboard/server.js.map +1 -1
- package/dist/delivery/attention.d.ts +130 -0
- package/dist/delivery/attention.d.ts.map +1 -0
- package/dist/delivery/attention.js +341 -0
- package/dist/delivery/attention.js.map +1 -0
- package/dist/delivery/decompose.d.ts +18 -0
- package/dist/delivery/decompose.d.ts.map +1 -1
- package/dist/delivery/decompose.js +22 -1
- package/dist/delivery/decompose.js.map +1 -1
- package/dist/delivery/eta-estimate.d.ts +111 -0
- package/dist/delivery/eta-estimate.d.ts.map +1 -0
- package/dist/delivery/eta-estimate.js +171 -0
- package/dist/delivery/eta-estimate.js.map +1 -0
- package/dist/delivery/eta.d.ts +23 -0
- package/dist/delivery/eta.d.ts.map +1 -0
- package/dist/delivery/eta.js +59 -0
- package/dist/delivery/eta.js.map +1 -0
- package/dist/delivery/orchestrated-mission.d.ts +10 -0
- package/dist/delivery/orchestrated-mission.d.ts.map +1 -1
- package/dist/delivery/orchestrated-mission.js +15 -1
- package/dist/delivery/orchestrated-mission.js.map +1 -1
- package/dist/delivery/plan-check.d.ts +7 -1
- package/dist/delivery/plan-check.d.ts.map +1 -1
- package/dist/delivery/plan-check.js +23 -2
- package/dist/delivery/plan-check.js.map +1 -1
- package/dist/delivery/run-state.d.ts +1 -1
- package/dist/delivery/run-state.d.ts.map +1 -1
- package/dist/delivery/run-state.js +8 -1
- package/dist/delivery/run-state.js.map +1 -1
- package/dist/delivery/task-orchestrator.d.ts +8 -3
- package/dist/delivery/task-orchestrator.d.ts.map +1 -1
- package/dist/delivery/task-orchestrator.js +75 -43
- package/dist/delivery/task-orchestrator.js.map +1 -1
- package/dist/delivery/task-sync.d.ts +21 -0
- package/dist/delivery/task-sync.d.ts.map +1 -1
- package/dist/delivery/task-sync.js +44 -8
- package/dist/delivery/task-sync.js.map +1 -1
- package/dist/delivery/task-workspace.d.ts +3 -3
- package/dist/delivery/task-workspace.js +3 -3
- package/dist/generators/self-card.d.ts +65 -0
- package/dist/generators/self-card.d.ts.map +1 -0
- package/dist/generators/self-card.js +256 -0
- package/dist/generators/self-card.js.map +1 -0
- package/dist/inference/probe.js +1 -1
- package/dist/inference/probe.js.map +1 -1
- package/dist/memory/prepopulate.d.ts.map +1 -1
- package/dist/memory/prepopulate.js +2 -0
- package/dist/memory/prepopulate.js.map +1 -1
- package/dist/models/analytics.d.ts +32 -0
- package/dist/models/analytics.d.ts.map +1 -1
- package/dist/models/analytics.js +68 -5
- package/dist/models/analytics.js.map +1 -1
- package/dist/models/plan-readability.d.ts +55 -0
- package/dist/models/plan-readability.d.ts.map +1 -0
- package/dist/models/plan-readability.js +339 -0
- package/dist/models/plan-readability.js.map +1 -0
- package/dist/placement/admission.d.ts +59 -0
- package/dist/placement/admission.d.ts.map +1 -0
- package/dist/placement/admission.js +197 -0
- package/dist/placement/admission.js.map +1 -0
- package/dist/placement/auto.d.ts +44 -0
- package/dist/placement/auto.d.ts.map +1 -0
- package/dist/placement/auto.js +212 -0
- package/dist/placement/auto.js.map +1 -0
- package/dist/placement/enforce.d.ts +128 -0
- package/dist/placement/enforce.d.ts.map +1 -0
- package/dist/placement/enforce.js +655 -0
- package/dist/placement/enforce.js.map +1 -0
- package/dist/placement/idle.d.ts +50 -0
- package/dist/placement/idle.d.ts.map +1 -0
- package/dist/placement/idle.js +213 -0
- package/dist/placement/idle.js.map +1 -0
- package/dist/placement/ledger.d.ts +323 -0
- package/dist/placement/ledger.d.ts.map +1 -0
- package/dist/placement/ledger.js +263 -0
- package/dist/placement/ledger.js.map +1 -0
- package/dist/placement/preview.d.ts +51 -0
- package/dist/placement/preview.d.ts.map +1 -0
- package/dist/placement/preview.js +61 -0
- package/dist/placement/preview.js.map +1 -0
- package/dist/placement/probes.d.ts +47 -0
- package/dist/placement/probes.d.ts.map +1 -0
- package/dist/placement/probes.js +207 -0
- package/dist/placement/probes.js.map +1 -0
- package/dist/placement/proxy-env.d.ts +21 -0
- package/dist/placement/proxy-env.d.ts.map +1 -0
- package/dist/placement/proxy-env.js +42 -0
- package/dist/placement/proxy-env.js.map +1 -0
- package/dist/placement/registry.d.ts +1038 -0
- package/dist/placement/registry.d.ts.map +1 -0
- package/dist/placement/registry.js +274 -0
- package/dist/placement/registry.js.map +1 -0
- package/dist/policies/liveness.d.ts +6 -8
- package/dist/policies/liveness.d.ts.map +1 -1
- package/dist/policies/liveness.js +6 -25
- package/dist/policies/liveness.js.map +1 -1
- package/dist/policies/sandbox-anchor.d.ts +91 -0
- package/dist/policies/sandbox-anchor.d.ts.map +1 -0
- package/dist/policies/sandbox-anchor.js +187 -0
- package/dist/policies/sandbox-anchor.js.map +1 -0
- package/dist/policies/sandbox-grants.d.ts +131 -0
- package/dist/policies/sandbox-grants.d.ts.map +1 -0
- package/dist/policies/sandbox-grants.js +562 -0
- package/dist/policies/sandbox-grants.js.map +1 -0
- package/dist/state/manifest.d.ts +4 -2
- package/dist/state/manifest.d.ts.map +1 -1
- package/dist/state/manifest.js +32 -16
- package/dist/state/manifest.js.map +1 -1
- package/dist/utils/checkout-root.d.ts +2 -0
- package/dist/utils/checkout-root.d.ts.map +1 -0
- package/dist/utils/checkout-root.js +43 -0
- package/dist/utils/checkout-root.js.map +1 -0
- package/dist/utils/resolve-uap-bin.d.ts +5 -0
- package/dist/utils/resolve-uap-bin.d.ts.map +1 -0
- package/dist/utils/resolve-uap-bin.js +33 -0
- package/dist/utils/resolve-uap-bin.js.map +1 -0
- package/dist/utils/terminal-safe.d.ts +12 -0
- package/dist/utils/terminal-safe.d.ts.map +1 -0
- package/dist/utils/terminal-safe.js +53 -0
- package/dist/utils/terminal-safe.js.map +1 -0
- package/docs/ATTRIBUTION.md +1 -0
- package/docs/DASHBOARD_UPLIFT_SPEC.md +8 -8
- package/docs/INDEX.md +6 -5
- package/docs/architecture/OVERVIEW.md +15 -3
- package/docs/architecture/PROTOCOL.md +7 -1
- package/docs/architecture/adr/0006-operator-directed-model-placement.md +86 -0
- package/docs/architecture/adr/0007-auto-displacement-allowlist-as-standing-consent.md +79 -0
- package/docs/architecture/adr/0008-fleet-clients-link-out.md +92 -0
- package/docs/architecture/adr/0009-completion-triggered-dispatch-and-per-leaf-model-dials.md +71 -0
- package/docs/architecture/adr/0010-attention-queue-and-afk-auto-decider.md +159 -0
- package/docs/architecture/adr/0011-sandbox-grants-and-network-egress-boundary.md +219 -0
- package/docs/architecture/adr/0012-operator-legibility-surfaces.md +175 -0
- package/docs/getting-started/INSTALLATION.md +1 -1
- package/docs/guides/AUTOMATIC_FEATURES.md +8 -0
- package/docs/guides/LOCAL_MODELS.md +1 -1
- package/docs/guides/PROXY.md +2 -1
- package/docs/guides/SANDBOX.md +91 -4
- package/docs/integrations/MCP_ROUTER.md +1 -1
- package/docs/plans/model-performance-proof-options.md +176 -0
- package/docs/reference/API.md +1 -1
- package/docs/reference/CLI.md +169 -4
- package/docs/reference/COMPARISON.md +1 -1
- package/docs/reference/CONFIGURATION.md +12 -3
- package/docs/reference/CONFIGURATION_REFERENCE.md +269 -14
- package/docs/reference/DATABASE_SCHEMA.md +1 -1
- package/docs/reference/FEATURES.md +15 -3
- package/docs/reference/PATTERNS.md +1 -1
- package/docs/reference/PLATFORMS.md +14 -1
- package/docs/specs/operator-model-placement.md +1314 -0
- package/docs/specs/operator-model-placement.review.md +339 -0
- package/package.json +2 -2
- package/scripts/maintenance/publish-npm.sh +23 -11
- package/scripts/version-bump.sh +6 -51
- package/src/policies/enforcers/__pycache__/_common.cpython-311.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-311.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-311.pyc +0 -0
- package/src/policies/schemas/policies/mandatory-testing-deployment.md +2 -5
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-311.pyc +0 -0
- package/templates/hooks/session-start.sh +44 -0
- package/tools/agents/UAP/cli.py +14 -3
- package/tools/agents/UAP/paths.py +50 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-311.pyc +0 -0
- package/tools/agents/scripts/anthropic_proxy.py +1386 -99
- package/tools/agents/scripts/toolcall_path_normalizer.py +46 -1
- package/tools/agents/tests/test_anthropic_proxy_streaming.py +29 -6
- package/tools/agents/tests/test_doubling_break.py +64 -5
- package/tools/agents/tests/test_error_loop_break.py +10 -4
- package/tools/agents/tests/test_error_loop_ignores_correctives.py +13 -2
- package/tools/agents/tests/test_lockstep_escalation.py +280 -9
- package/tools/agents/tests/test_path_containment.py +94 -0
- package/tools/agents/tests/test_proxy_unix_socket.py +162 -0
- package/tools/agents/tests/test_signature_quality.py +349 -0
- package/tools/agents/tests/test_uap_compliance.py +11 -1
- package/web/dash/core.js +1 -0
- package/web/dash/tab-clients.js +196 -0
- package/web/dash/tab-models.js +387 -8
- package/web/dash/tab-policies.js +87 -4
- package/web/dash/tabs.js +77 -73
- package/web/dashboard.html +6 -0
- package/src/policies/enforcers/__pycache__/_common.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/expert_review_required.cpython-312.pyc +0 -0
- package/src/policies/enforcers/__pycache__/quality_metrics_gate.cpython-312.pyc +0 -0
- package/templates/hooks/__pycache__/deliver_autoroute.cpython-312.pyc +0 -0
- package/tools/agents/scripts/__pycache__/toolcall_path_normalizer.cpython-312.pyc +0 -0
- package/web/dash/tab-agents.js +0 -21
- package/web/dash/tab-deliver.js +0 -12
- package/web/dash/tab-memory.js +0 -12
- package/web/dash/tab-orchestration.js +0 -21
- package/web/dash/tab-overview.js +0 -21
- package/web/dash/tab-tasks.js +0 -21
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Impact preview (spec §4.5): the victim list the operator sees BEFORE
|
|
3
|
+
* committing, and the re-derivation check enforcement uses AFTER the yes.
|
|
4
|
+
*
|
|
5
|
+
* Nothing in this view is advisory-only: enforcement re-derives the same
|
|
6
|
+
* victim set and refuses to proceed if it differs from what the operator
|
|
7
|
+
* approved. A preview that lies is worse than no preview.
|
|
8
|
+
*
|
|
9
|
+
* In-flight status is `unknown` in phase 1: the proxy exposes no live
|
|
10
|
+
* request state yet (the phase-2 in-flight-per-target endpoint supplies it).
|
|
11
|
+
* The preview must say unknown rather than guess "idle".
|
|
12
|
+
*/
|
|
13
|
+
import { isMeasuredConfig } from './registry.js';
|
|
14
|
+
/** Consequence table, spec §4.5. */
|
|
15
|
+
function consequenceFor(state, inflight) {
|
|
16
|
+
if (state === 'warming')
|
|
17
|
+
return 'load wasted; VRAM returns on stop';
|
|
18
|
+
if (state === 'paused')
|
|
19
|
+
return 'already offloaded; restore path lost';
|
|
20
|
+
if (inflight === true)
|
|
21
|
+
return 'active generation aborted; context lost';
|
|
22
|
+
if (inflight === false)
|
|
23
|
+
return 'session idle; context lost; reload needed';
|
|
24
|
+
// The proxy's /internal/placement/inflight endpoint shipped (phase 3);
|
|
25
|
+
// 'unknown' now means "the proxy did not answer", never "not wired yet".
|
|
26
|
+
return 'context lost; reload needed (in-flight view unavailable from the proxy)';
|
|
27
|
+
}
|
|
28
|
+
/** Build the victim preview for a displace option. */
|
|
29
|
+
export function buildVictimPreviews(registry, victims, inflightOf = () => 'unknown') {
|
|
30
|
+
return victims.map((v) => {
|
|
31
|
+
const cfg = registry.models[v.model]?.configs[v.config];
|
|
32
|
+
return {
|
|
33
|
+
model: v.model,
|
|
34
|
+
config: v.config,
|
|
35
|
+
device: v.device,
|
|
36
|
+
state: v.state,
|
|
37
|
+
holders: v.holders,
|
|
38
|
+
inflight: inflightOf(v),
|
|
39
|
+
frees_gpu_mib: v.gpu_mib ?? 0,
|
|
40
|
+
frees_host_mib: v.host_rss_mib,
|
|
41
|
+
reload_cost_mib: cfg && isMeasuredConfig(cfg) ? cfg.resident_gpu_mib : undefined,
|
|
42
|
+
consequence: consequenceFor(v.state, inflightOf(v)),
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/** Stable signature of a victim set — what the operator approved and what
|
|
47
|
+
* enforcement re-derives must produce the same string, or enforcement
|
|
48
|
+
* aborts. Order-insensitive; content-sensitive. */
|
|
49
|
+
export function victimSignature(victims) {
|
|
50
|
+
return victims
|
|
51
|
+
.map((v) => `${v.model}/${v.config}`)
|
|
52
|
+
.sort()
|
|
53
|
+
.join(',');
|
|
54
|
+
}
|
|
55
|
+
/** The enforcement-time check: re-derive the victims from live state and
|
|
56
|
+
* refuse when the set the operator approved no longer matches. A mismatch
|
|
57
|
+
* means the world moved between preview and commit — abort, re-ask. */
|
|
58
|
+
export function previewStillValid(approved, rederived) {
|
|
59
|
+
return victimSignature(approved) === victimSignature(rederived);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/placement/preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,gBAAgB,EAAsB,MAAM,eAAe,CAAC;AAsBrE,oCAAoC;AACpC,SAAS,cAAc,CAAC,KAA8B,EAAE,QAAkB;IACxE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,mCAAmC,CAAC;IACpE,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,sCAAsC,CAAC;IACtE,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,yCAAyC,CAAC;IACxE,IAAI,QAAQ,KAAK,KAAK;QAAE,OAAO,2CAA2C,CAAC;IAC3E,uEAAuE;IACvE,yEAAyE;IACzE,OAAO,yEAAyE,CAAC;AACnF,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,mBAAmB,CACjC,QAAuB,EACvB,OAAyB,EACzB,aAAmD,GAAG,EAAE,CAAC,SAAS;IAElE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACvB,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACxD,OAAO;YACL,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;YACvB,aAAa,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC;YAC7B,cAAc,EAAE,CAAC,CAAC,YAAY;YAC9B,eAAe,EAAE,GAAG,IAAI,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS;YAChF,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;SACpD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;mDAEmD;AACnD,MAAM,UAAU,eAAe,CAAC,OAAiD;IAC/E,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;SACpC,IAAI,EAAE;SACN,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED;;uEAEuE;AACvE,MAAM,UAAU,iBAAiB,CAC/B,QAAkD,EAClD,SAAmD;IAEnD,OAAO,eAAe,CAAC,QAAQ,CAAC,KAAK,eAAe,CAAC,SAAS,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** Is a user unit active? Fail-closed to false when systemctl is missing. */
|
|
2
|
+
export declare function isUnitActive(unit: string): boolean;
|
|
3
|
+
/** Main PID of a user unit; null when systemctl is missing or the unit is
|
|
4
|
+
* inactive. Never a guess. */
|
|
5
|
+
export declare function unitMainPid(unit: string): number | null;
|
|
6
|
+
/** All PIDs in a user unit's cgroup. A backend can be multi-process — the
|
|
7
|
+
* strata unit's MainPID is the serve wrapper while the ENGINE child holds
|
|
8
|
+
* the GPU — so the whole-config footprint must aggregate the cgroup, not
|
|
9
|
+
* trust MainPID. Null when the unit or its cgroup is not readable. */
|
|
10
|
+
export declare function unitCgroupPids(unit: string): number[] | null;
|
|
11
|
+
/** PID of whatever listens on the port, via `ss -ltnp`. Fallback for
|
|
12
|
+
* unit-less backends. Null when nothing is listening. */
|
|
13
|
+
export declare function listeningPortPid(port: number): number | null;
|
|
14
|
+
/** Established (in-use) TCP connections to a backend endpoint, via
|
|
15
|
+
* `ss -tn state established`. This is the idle sweep's port-level safety:
|
|
16
|
+
* clients that bypass the gate (curl straight at the port, another agent
|
|
17
|
+
* talking to the backend directly) are invisible to the gated usage
|
|
18
|
+
* clock — an ESTABLISHED connection means SOMETHING is talking to the
|
|
19
|
+
* resident right now and it must not be unloaded. Null when `ss` cannot
|
|
20
|
+
* answer: unknown is a refusal to unload, never a guess that it's idle.
|
|
21
|
+
* Scoped to SPORT only: every connection TO the backend has a server-side
|
|
22
|
+
* socket with local port = the backend port, while matching DPORT too
|
|
23
|
+
* would also count this machine's own outbound traffic to any remote host
|
|
24
|
+
* on that port number (false "busy" — safe, but it would defer the sweep
|
|
25
|
+
* forever). All same-device backends share one endpoint port (the
|
|
26
|
+
* Conflicts graph keeps exactly one live). */
|
|
27
|
+
export declare function endpointEstablishedConns(endpoint: string | undefined): number | null;
|
|
28
|
+
/** Whole-config GPU MiB: sum of nvidia-smi compute-apps memory across the
|
|
29
|
+
* given PIDs. Null when none of them hold GPU memory — a refusal, not zero. */
|
|
30
|
+
export declare function gpuComputeMiB(pids: number[]): number | null;
|
|
31
|
+
/** Per-GPU stats keyed by index — one nvidia-smi call for every card.
|
|
32
|
+
* (probeGpuFreeMiB() in src/capacity reads GPU 0 only; the multi-device
|
|
33
|
+
* abstraction needs per-index readings. Spec §5 item 4.) */
|
|
34
|
+
export interface GpuStats {
|
|
35
|
+
total_mib?: number;
|
|
36
|
+
free_mib?: number;
|
|
37
|
+
}
|
|
38
|
+
export declare function gpuStatsByIndex(): Map<number, GpuStats>;
|
|
39
|
+
/** Host total RAM (MiB) from /proc/meminfo MemTotal. Null when unreadable. */
|
|
40
|
+
export declare function hostTotalMiB(): number | null;
|
|
41
|
+
/** Host available RAM (MiB) from /proc/meminfo MemAvailable. Null when the
|
|
42
|
+
* file is unreadable (non-Linux). */
|
|
43
|
+
export declare function hostAvailableMiB(): number | null;
|
|
44
|
+
/** Whole-config host RSS (MiB): sum of VmRSS across the given PIDs.
|
|
45
|
+
* Processes that vanish mid-sum are skipped; null when none could be read. */
|
|
46
|
+
export declare function hostRssMiB(pids: number[]): number | null;
|
|
47
|
+
//# sourceMappingURL=probes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probes.d.ts","sourceRoot":"","sources":["../../src/placement/probes.ts"],"names":[],"mappings":"AAcA,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAWlD;AAED;8BAC8B;AAC9B,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYvD;AAED;;;sEAGsE;AACtE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAiB5D;AAED;yDACyD;AACzD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY5D;AAED;;;;;;;;;;;;8CAY8C;AAC9C,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAkBpF;AAED;+EAC+E;AAC/E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAqB3D;AAED;;4DAE4D;AAC5D,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAsBvD;AAED,8EAA8E;AAC9E,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAQ5C;AAED;qCACqC;AACrC,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAQhD;AAED;8EAC8E;AAC9E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAaxD"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host probes for the placement layer: unit liveness, whole-cgroup process
|
|
3
|
+
* discovery, GPU memory, host RSS, and device free memory.
|
|
4
|
+
*
|
|
5
|
+
* Same doctrine as src/capacity/probe.ts: execFileSync with argv arrays only
|
|
6
|
+
* (no shell), bounded timeouts, every probe fails soft to null — callers
|
|
7
|
+
* decide what null means, and for placement null always means REFUSE, never
|
|
8
|
+
* a guess.
|
|
9
|
+
*/
|
|
10
|
+
import { execFileSync } from 'child_process';
|
|
11
|
+
import { readFileSync } from 'fs';
|
|
12
|
+
const PROBE_TIMEOUT_MS = 5000;
|
|
13
|
+
/** Is a user unit active? Fail-closed to false when systemctl is missing. */
|
|
14
|
+
export function isUnitActive(unit) {
|
|
15
|
+
try {
|
|
16
|
+
const out = execFileSync('systemctl', ['--user', 'is-active', '--', unit], {
|
|
17
|
+
encoding: 'utf-8',
|
|
18
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
19
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
20
|
+
});
|
|
21
|
+
return out.trim() === 'active';
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/** Main PID of a user unit; null when systemctl is missing or the unit is
|
|
28
|
+
* inactive. Never a guess. */
|
|
29
|
+
export function unitMainPid(unit) {
|
|
30
|
+
try {
|
|
31
|
+
const out = execFileSync('systemctl', ['--user', 'show', '-p', 'MainPID', '--', unit], {
|
|
32
|
+
encoding: 'utf-8',
|
|
33
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
34
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
35
|
+
});
|
|
36
|
+
const pid = Number(out.trim().split('=')[1]);
|
|
37
|
+
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** All PIDs in a user unit's cgroup. A backend can be multi-process — the
|
|
44
|
+
* strata unit's MainPID is the serve wrapper while the ENGINE child holds
|
|
45
|
+
* the GPU — so the whole-config footprint must aggregate the cgroup, not
|
|
46
|
+
* trust MainPID. Null when the unit or its cgroup is not readable. */
|
|
47
|
+
export function unitCgroupPids(unit) {
|
|
48
|
+
try {
|
|
49
|
+
const out = execFileSync('systemctl', ['--user', 'show', '-p', 'ControlGroup', '--', unit], {
|
|
50
|
+
encoding: 'utf-8',
|
|
51
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
52
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
53
|
+
});
|
|
54
|
+
const cg = out.trim().split('=')[1];
|
|
55
|
+
if (!cg)
|
|
56
|
+
return null;
|
|
57
|
+
const procs = readFileSync(`/sys/fs/cgroup${cg}/cgroup.procs`, 'utf-8');
|
|
58
|
+
return procs
|
|
59
|
+
.split('\n')
|
|
60
|
+
.map((l) => Number(l.trim()))
|
|
61
|
+
.filter((p) => Number.isFinite(p) && p > 0);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** PID of whatever listens on the port, via `ss -ltnp`. Fallback for
|
|
68
|
+
* unit-less backends. Null when nothing is listening. */
|
|
69
|
+
export function listeningPortPid(port) {
|
|
70
|
+
try {
|
|
71
|
+
const out = execFileSync('ss', ['-ltnp', `sport = :${port}`], {
|
|
72
|
+
encoding: 'utf-8',
|
|
73
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
74
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
75
|
+
});
|
|
76
|
+
const m = out.match(/pid=(\d+)/);
|
|
77
|
+
return m ? Number(m[1]) : null;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** Established (in-use) TCP connections to a backend endpoint, via
|
|
84
|
+
* `ss -tn state established`. This is the idle sweep's port-level safety:
|
|
85
|
+
* clients that bypass the gate (curl straight at the port, another agent
|
|
86
|
+
* talking to the backend directly) are invisible to the gated usage
|
|
87
|
+
* clock — an ESTABLISHED connection means SOMETHING is talking to the
|
|
88
|
+
* resident right now and it must not be unloaded. Null when `ss` cannot
|
|
89
|
+
* answer: unknown is a refusal to unload, never a guess that it's idle.
|
|
90
|
+
* Scoped to SPORT only: every connection TO the backend has a server-side
|
|
91
|
+
* socket with local port = the backend port, while matching DPORT too
|
|
92
|
+
* would also count this machine's own outbound traffic to any remote host
|
|
93
|
+
* on that port number (false "busy" — safe, but it would defer the sweep
|
|
94
|
+
* forever). All same-device backends share one endpoint port (the
|
|
95
|
+
* Conflicts graph keeps exactly one live). */
|
|
96
|
+
export function endpointEstablishedConns(endpoint) {
|
|
97
|
+
const m = endpoint?.match(/:(\d+)(?:\/|$)/);
|
|
98
|
+
if (!m)
|
|
99
|
+
return null; // no port in the endpoint — unknown, fail closed
|
|
100
|
+
const port = Number(m[1]);
|
|
101
|
+
if (!Number.isInteger(port) || port <= 0)
|
|
102
|
+
return null;
|
|
103
|
+
try {
|
|
104
|
+
const out = execFileSync('ss', ['-tn', `state established`, `sport = :${port}`], {
|
|
105
|
+
encoding: 'utf-8',
|
|
106
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
107
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
108
|
+
});
|
|
109
|
+
return out
|
|
110
|
+
.split('\n')
|
|
111
|
+
.filter((l) => l.trim() && !l.startsWith('State'))
|
|
112
|
+
.length;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return null; // ss missing/unhappy — unknown, never "idle"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** Whole-config GPU MiB: sum of nvidia-smi compute-apps memory across the
|
|
119
|
+
* given PIDs. Null when none of them hold GPU memory — a refusal, not zero. */
|
|
120
|
+
export function gpuComputeMiB(pids) {
|
|
121
|
+
try {
|
|
122
|
+
const out = execFileSync('nvidia-smi', ['--query-compute-apps=pid,used_memory', '--format=csv,noheader,nounits'], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: PROBE_TIMEOUT_MS });
|
|
123
|
+
const want = new Set(pids);
|
|
124
|
+
let total = null;
|
|
125
|
+
for (const line of out.split('\n')) {
|
|
126
|
+
const [p, mem] = line.split(',').map((s) => s.trim());
|
|
127
|
+
if (!p)
|
|
128
|
+
continue; // trailing newline must not parse as pid 0
|
|
129
|
+
if (!want.has(Number(p)))
|
|
130
|
+
continue;
|
|
131
|
+
const mib = Number(mem);
|
|
132
|
+
if (!Number.isFinite(mib))
|
|
133
|
+
continue;
|
|
134
|
+
total = (total ?? 0) + Math.round(mib);
|
|
135
|
+
}
|
|
136
|
+
return total;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export function gpuStatsByIndex() {
|
|
143
|
+
const out = new Map();
|
|
144
|
+
try {
|
|
145
|
+
const text = execFileSync('nvidia-smi', ['--query-gpu=index,memory.total,memory.free', '--format=csv,noheader,nounits'], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: PROBE_TIMEOUT_MS });
|
|
146
|
+
for (const line of text.split('\n')) {
|
|
147
|
+
if (!line.trim())
|
|
148
|
+
continue; // trailing newline: Number('')===0 must not become GPU 0
|
|
149
|
+
const [idx, total, free] = line.split(',').map((s) => s.trim());
|
|
150
|
+
const i = Number(idx);
|
|
151
|
+
if (!Number.isFinite(i))
|
|
152
|
+
continue;
|
|
153
|
+
const stats = {};
|
|
154
|
+
if (Number.isFinite(Number(total)))
|
|
155
|
+
stats.total_mib = Math.round(Number(total));
|
|
156
|
+
if (Number.isFinite(Number(free)))
|
|
157
|
+
stats.free_mib = Math.round(Number(free));
|
|
158
|
+
out.set(i, stats);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// no nvidia-smi — empty map; every device reads as unprobed
|
|
163
|
+
}
|
|
164
|
+
return out;
|
|
165
|
+
}
|
|
166
|
+
/** Host total RAM (MiB) from /proc/meminfo MemTotal. Null when unreadable. */
|
|
167
|
+
export function hostTotalMiB() {
|
|
168
|
+
try {
|
|
169
|
+
const meminfo = readFileSync('/proc/meminfo', 'utf-8');
|
|
170
|
+
const m = meminfo.match(/^MemTotal:\s+(\d+)\s+kB$/m);
|
|
171
|
+
return m ? Math.round(Number(m[1]) / 1024) : null;
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/** Host available RAM (MiB) from /proc/meminfo MemAvailable. Null when the
|
|
178
|
+
* file is unreadable (non-Linux). */
|
|
179
|
+
export function hostAvailableMiB() {
|
|
180
|
+
try {
|
|
181
|
+
const meminfo = readFileSync('/proc/meminfo', 'utf-8');
|
|
182
|
+
const m = meminfo.match(/^MemAvailable:\s+(\d+)\s+kB$/m);
|
|
183
|
+
return m ? Math.round(Number(m[1]) / 1024) : null;
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/** Whole-config host RSS (MiB): sum of VmRSS across the given PIDs.
|
|
190
|
+
* Processes that vanish mid-sum are skipped; null when none could be read. */
|
|
191
|
+
export function hostRssMiB(pids) {
|
|
192
|
+
let total = null;
|
|
193
|
+
for (const pid of pids) {
|
|
194
|
+
try {
|
|
195
|
+
const status = readFileSync(`/proc/${pid}/status`, 'utf-8');
|
|
196
|
+
const m = status.match(/^VmRSS:\s+(\d+)\s+kB$/m);
|
|
197
|
+
if (!m)
|
|
198
|
+
continue;
|
|
199
|
+
total = (total ?? 0) + Math.round(Number(m[1]) / 1024);
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// process exited between cgroup read and proc read — skip it
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return total;
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=probes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probes.js","sourceRoot":"","sources":["../../src/placement/probes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Absolute path to the proxy's systemd EnvironmentFile. */
|
|
2
|
+
export declare function proxyEnvPath(homeDir?: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Read the last (last-wins) value of KEY in the proxy env file, or null if the
|
|
5
|
+
* file is missing or the key is unset. Used to honor an operator local-only pin
|
|
6
|
+
* before overwriting ANTHROPIC_PASSTHROUGH_MODELS.
|
|
7
|
+
*/
|
|
8
|
+
export declare function readProxyEnvVar(key: string, homeDir?: string): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* One resolution of the loopback proxy base URL + auth headers (process env
|
|
11
|
+
* wins, then the proxy env file, then the loopback default). Previously two
|
|
12
|
+
* copies in enforce.ts drifted silently; one composer now.
|
|
13
|
+
*/
|
|
14
|
+
export declare function proxyBaseAndHeaders(opts?: {
|
|
15
|
+
proxyBaseUrl?: string;
|
|
16
|
+
proxyToken?: string;
|
|
17
|
+
}): {
|
|
18
|
+
base: string;
|
|
19
|
+
headers: Record<string, string>;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=proxy-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-env.d.ts","sourceRoot":"","sources":["../../src/placement/proxy-env.ts"],"names":[],"mappings":"AAYA,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,OAAO,GAAE,MAAkB,GAAG,MAAM,CAEhE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,MAAkB,GAAG,MAAM,GAAG,IAAI,CAQvF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACxD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAInD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared proxy-env resolution for the placement domain (spec §4.3/§4.6).
|
|
3
|
+
*
|
|
4
|
+
* Lives in src/placement/ — NOT imported from src/cli/ — so the domain layer
|
|
5
|
+
* (consumed by both the CLI and the dashboard) never reaches into a surface
|
|
6
|
+
* layer. src/cli/systemd-services.ts re-exports readProxyEnvVar for its
|
|
7
|
+
* existing callers.
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync } from 'fs';
|
|
10
|
+
import { homedir } from 'os';
|
|
11
|
+
import { join } from 'path';
|
|
12
|
+
/** Absolute path to the proxy's systemd EnvironmentFile. */
|
|
13
|
+
export function proxyEnvPath(homeDir = homedir()) {
|
|
14
|
+
return join(homeDir, '.config', 'uap', 'anthropic-proxy.env');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Read the last (last-wins) value of KEY in the proxy env file, or null if the
|
|
18
|
+
* file is missing or the key is unset. Used to honor an operator local-only pin
|
|
19
|
+
* before overwriting ANTHROPIC_PASSTHROUGH_MODELS.
|
|
20
|
+
*/
|
|
21
|
+
export function readProxyEnvVar(key, homeDir = homedir()) {
|
|
22
|
+
const path = proxyEnvPath(homeDir);
|
|
23
|
+
if (!existsSync(path))
|
|
24
|
+
return null;
|
|
25
|
+
const lines = readFileSync(path, 'utf8').split('\n');
|
|
26
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
27
|
+
if (lines[i].startsWith(`${key}=`))
|
|
28
|
+
return lines[i].slice(key.length + 1);
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* One resolution of the loopback proxy base URL + auth headers (process env
|
|
34
|
+
* wins, then the proxy env file, then the loopback default). Previously two
|
|
35
|
+
* copies in enforce.ts drifted silently; one composer now.
|
|
36
|
+
*/
|
|
37
|
+
export function proxyBaseAndHeaders(opts = {}) {
|
|
38
|
+
const base = (opts.proxyBaseUrl ?? process.env.UAP_PROXY_URL ?? 'http://127.0.0.1:4000').replace(/\/$/, '');
|
|
39
|
+
const token = opts.proxyToken ?? process.env.PROXY_AUTH_TOKEN ?? readProxyEnvVar('PROXY_AUTH_TOKEN') ?? '';
|
|
40
|
+
return { base, headers: token ? { Authorization: `Bearer ${token}` } : {} };
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=proxy-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy-env.js","sourceRoot":"","sources":["../../src/placement/proxy-env.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,4DAA4D;AAC5D,MAAM,UAAU,YAAY,CAAC,UAAkB,OAAO,EAAE;IACtD,OAAO,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,UAAkB,OAAO,EAAE;IACtE,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrD,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAuD,EAAE;IAEzD,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,uBAAuB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC5G,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,eAAe,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;IAC3G,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAC9E,CAAC"}
|