modelrig 0.1.0 → 0.2.0
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/CHANGELOG.md +94 -0
- package/README.md +41 -11
- package/data/PROVENANCE.md +19 -0
- package/data/pricing-manual.json +22 -0
- package/data/pricing-map.json +46362 -0
- package/data/pricing-overlay.json +419 -0
- package/dist/adapters/anthropic.d.ts +50 -6
- package/dist/adapters/anthropic.d.ts.map +1 -1
- package/dist/adapters/anthropic.js +123 -29
- package/dist/adapters/build-adapters.d.ts +11 -0
- package/dist/adapters/build-adapters.d.ts.map +1 -0
- package/dist/adapters/build-adapters.js +45 -0
- package/dist/adapters/deepseek.d.ts +6 -0
- package/dist/adapters/deepseek.d.ts.map +1 -1
- package/dist/adapters/deepseek.js +54 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +46 -6
- package/dist/adapters/grok.d.ts +9 -0
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +67 -3
- package/dist/adapters/openai-compat.d.ts +6 -0
- package/dist/adapters/openai-compat.d.ts.map +1 -1
- package/dist/adapters/openai-compat.js +58 -1
- package/dist/adapters/openai-stream.d.ts +58 -0
- package/dist/adapters/openai-stream.d.ts.map +1 -0
- package/dist/adapters/openai-stream.js +120 -0
- package/dist/adapters/openai.d.ts +6 -0
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +60 -1
- package/dist/adapters/sampling.d.ts +28 -0
- package/dist/adapters/sampling.d.ts.map +1 -0
- package/dist/adapters/sampling.js +34 -0
- package/dist/adapters/tool-mapping.d.ts +92 -0
- package/dist/adapters/tool-mapping.d.ts.map +1 -0
- package/dist/adapters/tool-mapping.js +143 -0
- package/dist/artifacts/artifact.d.ts +137 -0
- package/dist/artifacts/artifact.d.ts.map +1 -0
- package/dist/artifacts/artifact.js +377 -0
- package/dist/artifacts/content-uploader.d.ts +87 -0
- package/dist/artifacts/content-uploader.d.ts.map +1 -0
- package/dist/artifacts/content-uploader.js +124 -0
- package/dist/artifacts/index.d.ts +63 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +80 -0
- package/dist/artifacts/run-context.d.ts +129 -0
- package/dist/artifacts/run-context.d.ts.map +1 -0
- package/dist/artifacts/run-context.js +208 -0
- package/dist/artifacts/scrub.d.ts +60 -0
- package/dist/artifacts/scrub.d.ts.map +1 -0
- package/dist/artifacts/scrub.js +139 -0
- package/dist/artifacts/step.d.ts +26 -0
- package/dist/artifacts/step.d.ts.map +1 -0
- package/dist/artifacts/step.js +37 -0
- package/dist/artifacts/taint.d.ts +63 -0
- package/dist/artifacts/taint.d.ts.map +1 -0
- package/dist/artifacts/taint.js +76 -0
- package/dist/bakeoff/cache-sim.d.ts +99 -0
- package/dist/bakeoff/cache-sim.d.ts.map +1 -0
- package/dist/bakeoff/cache-sim.js +126 -0
- package/dist/bakeoff/eval-cases.d.ts +96 -0
- package/dist/bakeoff/eval-cases.d.ts.map +1 -0
- package/dist/bakeoff/eval-cases.js +105 -0
- package/dist/bakeoff/report.d.ts +41 -0
- package/dist/bakeoff/report.d.ts.map +1 -0
- package/dist/bakeoff/report.js +142 -0
- package/dist/bakeoff/samples.d.ts +15 -0
- package/dist/bakeoff/samples.d.ts.map +1 -1
- package/dist/bakeoff/samples.js +20 -0
- package/dist/cli.d.ts +1 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +134 -116
- package/dist/config.d.ts +100 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +104 -0
- package/dist/deprecations.d.ts +32 -0
- package/dist/deprecations.d.ts.map +1 -0
- package/dist/deprecations.js +59 -0
- package/dist/gateway/http-protocol.d.ts +175 -0
- package/dist/gateway/http-protocol.d.ts.map +1 -0
- package/dist/gateway/http-protocol.js +105 -0
- package/dist/index.d.ts +105 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +266 -138
- package/dist/init/finder.d.ts +15 -0
- package/dist/init/finder.d.ts.map +1 -1
- package/dist/init/finder.js +46 -0
- package/dist/init/init-cli.d.ts +10 -0
- package/dist/init/init-cli.d.ts.map +1 -0
- package/dist/init/init-cli.js +86 -0
- package/dist/init/observe-cli.d.ts +19 -0
- package/dist/init/observe-cli.d.ts.map +1 -0
- package/dist/init/observe-cli.js +73 -0
- package/dist/init/observe.d.ts +81 -0
- package/dist/init/observe.d.ts.map +1 -0
- package/dist/init/observe.js +245 -0
- package/dist/registry/build.d.ts +94 -1
- package/dist/registry/build.d.ts.map +1 -1
- package/dist/registry/build.js +125 -4
- package/dist/registry/cache-policy.d.ts +94 -0
- package/dist/registry/cache-policy.d.ts.map +1 -0
- package/dist/registry/cache-policy.js +238 -0
- package/dist/registry/call-notes.d.ts.map +1 -1
- package/dist/registry/call-notes.js +40 -2
- package/dist/registry/effective-rate.d.ts +151 -0
- package/dist/registry/effective-rate.d.ts.map +1 -0
- package/dist/registry/effective-rate.js +156 -0
- package/dist/registry/facts.d.ts.map +1 -1
- package/dist/registry/facts.js +16 -0
- package/dist/registry/parity.d.ts +26 -0
- package/dist/registry/parity.d.ts.map +1 -1
- package/dist/registry/parity.js +43 -2
- package/dist/registry/pricing-shape.d.ts +113 -0
- package/dist/registry/pricing-shape.d.ts.map +1 -0
- package/dist/registry/pricing-shape.js +123 -0
- package/dist/registry/pricing.d.ts +25 -1
- package/dist/registry/pricing.d.ts.map +1 -1
- package/dist/registry/pricing.js +64 -6
- package/dist/rigindex/bootstrap.d.ts +36 -0
- package/dist/rigindex/bootstrap.d.ts.map +1 -0
- package/dist/rigindex/bootstrap.js +97 -0
- package/dist/rigindex/fit.d.ts +24 -0
- package/dist/rigindex/fit.d.ts.map +1 -0
- package/dist/rigindex/fit.js +76 -0
- package/dist/rigindex/gates.d.ts +52 -0
- package/dist/rigindex/gates.d.ts.map +1 -0
- package/dist/rigindex/gates.js +109 -0
- package/dist/rigindex/graph.d.ts +31 -0
- package/dist/rigindex/graph.d.ts.map +1 -0
- package/dist/rigindex/graph.js +120 -0
- package/dist/rigindex/index.d.ts +23 -0
- package/dist/rigindex/index.d.ts.map +1 -0
- package/dist/rigindex/index.js +112 -0
- package/dist/rigindex/types.d.ts +76 -0
- package/dist/rigindex/types.d.ts.map +1 -0
- package/dist/rigindex/types.js +8 -0
- package/dist/routes/cache-lint.d.ts +41 -0
- package/dist/routes/cache-lint.d.ts.map +1 -0
- package/dist/routes/cache-lint.js +81 -0
- package/dist/routes/loader.d.ts +37 -0
- package/dist/routes/loader.d.ts.map +1 -1
- package/dist/routes/loader.js +138 -0
- package/dist/routes/resolved-bundle.d.ts +79 -0
- package/dist/routes/resolved-bundle.d.ts.map +1 -0
- package/dist/routes/resolved-bundle.js +148 -0
- package/dist/routes/sampling-config.d.ts +32 -0
- package/dist/routes/sampling-config.d.ts.map +1 -0
- package/dist/routes/sampling-config.js +91 -0
- package/dist/run/ajv.d.ts +22 -0
- package/dist/run/ajv.d.ts.map +1 -0
- package/dist/run/ajv.js +32 -0
- package/dist/run/cache-handle.d.ts +58 -0
- package/dist/run/cache-handle.d.ts.map +1 -0
- package/dist/run/cache-handle.js +54 -0
- package/dist/run/cache-stamp.d.ts +65 -0
- package/dist/run/cache-stamp.d.ts.map +1 -0
- package/dist/run/cache-stamp.js +0 -0
- package/dist/run/capture-write.d.ts +33 -0
- package/dist/run/capture-write.d.ts.map +1 -0
- package/dist/run/capture-write.js +55 -0
- package/dist/run/cost.d.ts.map +1 -1
- package/dist/run/cost.js +1 -1
- package/dist/run/dispatch.d.ts +99 -0
- package/dist/run/dispatch.d.ts.map +1 -0
- package/dist/run/dispatch.js +191 -0
- package/dist/run/raw.d.ts +88 -0
- package/dist/run/raw.d.ts.map +1 -0
- package/dist/run/raw.js +286 -0
- package/dist/run/record-attempt.d.ts +40 -0
- package/dist/run/record-attempt.d.ts.map +1 -0
- package/dist/run/record-attempt.js +99 -0
- package/dist/run/resolve.d.ts +75 -2
- package/dist/run/resolve.d.ts.map +1 -1
- package/dist/run/resolve.js +126 -4
- package/dist/run/run.d.ts +14 -0
- package/dist/run/run.d.ts.map +1 -1
- package/dist/run/run.js +0 -0
- package/dist/run/stream.d.ts +49 -0
- package/dist/run/stream.d.ts.map +1 -0
- package/dist/run/stream.js +87 -0
- package/dist/run/validate.d.ts.map +1 -1
- package/dist/run/validate.js +6 -7
- package/dist/savings/cache-ledger.d.ts +108 -0
- package/dist/savings/cache-ledger.d.ts.map +1 -0
- package/dist/savings/cache-ledger.js +174 -0
- package/dist/savings/cache-reconcile.d.ts +64 -0
- package/dist/savings/cache-reconcile.d.ts.map +1 -0
- package/dist/savings/cache-reconcile.js +59 -0
- package/dist/savings/cache-stats.d.ts +63 -0
- package/dist/savings/cache-stats.d.ts.map +1 -0
- package/dist/savings/cache-stats.js +108 -0
- package/dist/savings/emit.d.ts +13 -0
- package/dist/savings/emit.d.ts.map +1 -1
- package/dist/savings/emit.js +25 -0
- package/dist/savings/swap-execute.d.ts +14 -0
- package/dist/savings/swap-execute.d.ts.map +1 -1
- package/dist/savings/swap-execute.js +44 -1
- package/dist/savings/swaps-client.d.ts +14 -0
- package/dist/savings/swaps-client.d.ts.map +1 -1
- package/dist/savings/swaps-client.js +16 -2
- package/dist/settings/api-fetcher.d.ts +39 -0
- package/dist/settings/api-fetcher.d.ts.map +1 -0
- package/dist/settings/api-fetcher.js +92 -0
- package/dist/settings/index.d.ts +10 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +15 -0
- package/dist/settings/task-settings.d.ts +91 -0
- package/dist/settings/task-settings.d.ts.map +1 -0
- package/dist/settings/task-settings.js +116 -0
- package/dist/status.d.ts +77 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +113 -0
- package/dist/telemetry/artifact-store.d.ts +48 -0
- package/dist/telemetry/artifact-store.d.ts.map +1 -0
- package/dist/telemetry/artifact-store.js +189 -0
- package/dist/telemetry/cache-miss-streak.d.ts +79 -0
- package/dist/telemetry/cache-miss-streak.d.ts.map +1 -0
- package/dist/telemetry/cache-miss-streak.js +99 -0
- package/dist/telemetry/capture.d.ts +3 -0
- package/dist/telemetry/capture.d.ts.map +1 -1
- package/dist/telemetry/capture.js +15 -8
- package/dist/telemetry/exporter-setup.d.ts +28 -0
- package/dist/telemetry/exporter-setup.d.ts.map +1 -0
- package/dist/telemetry/exporter-setup.js +34 -0
- package/dist/telemetry/exporter.d.ts +75 -0
- package/dist/telemetry/exporter.d.ts.map +1 -1
- package/dist/telemetry/exporter.js +324 -47
- package/dist/telemetry/health.d.ts +76 -0
- package/dist/telemetry/health.d.ts.map +1 -0
- package/dist/telemetry/health.js +92 -0
- package/dist/telemetry/ingest-protocol.d.ts +152 -3
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
- package/dist/telemetry/ingest-protocol.js +204 -4
- package/dist/telemetry/load-error-report.d.ts +24 -0
- package/dist/telemetry/load-error-report.d.ts.map +1 -0
- package/dist/telemetry/load-error-report.js +50 -0
- package/dist/telemetry/otel-map.d.ts +121 -0
- package/dist/telemetry/otel-map.d.ts.map +1 -0
- package/dist/telemetry/otel-map.js +224 -0
- package/dist/telemetry/otel-normalize.d.ts +104 -0
- package/dist/telemetry/otel-normalize.d.ts.map +1 -0
- package/dist/telemetry/otel-normalize.js +530 -0
- package/dist/telemetry/otlp-emitter.d.ts +52 -0
- package/dist/telemetry/otlp-emitter.d.ts.map +1 -0
- package/dist/telemetry/otlp-emitter.js +144 -0
- package/dist/telemetry/otlp-proto.d.ts +29 -0
- package/dist/telemetry/otlp-proto.d.ts.map +1 -0
- package/dist/telemetry/otlp-proto.js +266 -0
- package/dist/telemetry/sinks.d.ts +37 -1
- package/dist/telemetry/sinks.d.ts.map +1 -1
- package/dist/telemetry/sinks.js +121 -30
- package/dist/telemetry/store.d.ts +28 -1
- package/dist/telemetry/store.d.ts.map +1 -1
- package/dist/telemetry/store.js +218 -3
- package/dist/tenancy/api-key-format.d.ts +15 -5
- package/dist/tenancy/api-key-format.d.ts.map +1 -1
- package/dist/tenancy/api-key-format.js +24 -5
- package/dist/types/config-teaching.d.ts +62 -0
- package/dist/types/config-teaching.d.ts.map +1 -0
- package/dist/types/config-teaching.js +183 -0
- package/dist/types/provider.d.ts +122 -1
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/provider.js +21 -1
- package/dist/types/route.d.ts +79 -1
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +117 -0
- package/dist/types/telemetry.d.ts.map +1 -1
- package/dist/validate-cli.d.ts +12 -0
- package/dist/validate-cli.d.ts.map +1 -0
- package/dist/validate-cli.js +57 -0
- package/dist/verify/capture.d.ts +66 -0
- package/dist/verify/capture.d.ts.map +1 -0
- package/dist/verify/capture.js +180 -0
- package/dist/verify/cli-run.d.ts +23 -0
- package/dist/verify/cli-run.d.ts.map +1 -0
- package/dist/verify/cli-run.js +57 -0
- package/dist/verify/diff.d.ts +48 -0
- package/dist/verify/diff.d.ts.map +1 -0
- package/dist/verify/diff.js +157 -0
- package/dist/verify/index.d.ts +17 -0
- package/dist/verify/index.d.ts.map +1 -0
- package/dist/verify/index.js +24 -0
- package/dist/verify/report.d.ts +14 -0
- package/dist/verify/report.d.ts.map +1 -0
- package/dist/verify/report.js +88 -0
- package/dist/verify/types.d.ts +101 -0
- package/dist/verify/types.d.ts.map +1 -0
- package/dist/verify/types.js +17 -0
- package/dist/verify/verify.d.ts +29 -0
- package/dist/verify/verify.d.ts.map +1 -0
- package/dist/verify/verify.js +148 -0
- package/dist/watch/evaluate.d.ts +162 -3
- package/dist/watch/evaluate.d.ts.map +1 -1
- package/dist/watch/evaluate.js +61 -0
- package/dist/watch/monitor.d.ts +116 -0
- package/dist/watch/monitor.d.ts.map +1 -0
- package/dist/watch/monitor.js +199 -0
- package/dist/watch/proposals.d.ts +20 -4
- package/dist/watch/proposals.d.ts.map +1 -1
- package/dist/watch/proposals.js +31 -3
- package/dist/watch/run.d.ts +33 -0
- package/dist/watch/run.d.ts.map +1 -1
- package/dist/watch/run.js +39 -0
- package/package.json +7 -1
- package/registry/LICENSE +20 -0
- package/registry/leaderboard.json +3639 -0
- package/registry/registry.json +7263 -0
- package/dist/telemetry/supabase-exporter.d.ts +0 -64
- package/dist/telemetry/supabase-exporter.d.ts.map +0 -1
- package/dist/telemetry/supabase-exporter.js +0 -211
|
@@ -15,8 +15,16 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import type { SwapChange } from "./emit";
|
|
17
17
|
import type { SwapEventRecord } from "./swaps-client";
|
|
18
|
+
import type { CacheContext } from "../watch/evaluate";
|
|
19
|
+
import type { CacheVerdict } from "../registry/effective-rate";
|
|
18
20
|
import type { ProposalRecord, ProposalStatus } from "../watch/proposals";
|
|
19
21
|
import type { RouteBundle } from "../types/route";
|
|
22
|
+
/** Narrow a proposal's `evidence.cache_context` jsonb (spec §5.5 — additive,
|
|
23
|
+
* present only on cache-aware proposals) to a typed `CacheContext`, or null when
|
|
24
|
+
* absent/malformed. Defensive: an older or non-cache proposal has no block, and
|
|
25
|
+
* a partial block must degrade to "no cache explanation", never throw on the
|
|
26
|
+
* safety-critical execute path. */
|
|
27
|
+
export declare function readCacheContext(evidence: Record<string, unknown> | null): CacheContext | null;
|
|
20
28
|
export interface SwapExecuteDeps {
|
|
21
29
|
readonly proposalId: string;
|
|
22
30
|
/** THE gate — false throws before any read or write. */
|
|
@@ -39,6 +47,12 @@ export interface SwapExecuteResult {
|
|
|
39
47
|
readonly change: SwapChange;
|
|
40
48
|
readonly approvedBy: string;
|
|
41
49
|
readonly executedAt: string;
|
|
50
|
+
/** Cache-aware verdict from the proposal's `cache_context` evidence (spec
|
|
51
|
+
* §5.5), or null on a non-cache proposal. Additive — never gates execution
|
|
52
|
+
* (the human already approved); surfaced so the CLI/console can show WHY. */
|
|
53
|
+
readonly cacheVerdict: CacheVerdict | null;
|
|
54
|
+
/** The [Briefing §30] one-line explanation for the approval prompt, or null. */
|
|
55
|
+
readonly cacheExplanation: string | null;
|
|
42
56
|
}
|
|
43
57
|
export declare function executeSwap(deps: SwapExecuteDeps): Promise<SwapExecuteResult>;
|
|
44
58
|
//# sourceMappingURL=swap-execute.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swap-execute.d.ts","sourceRoot":"","sources":["../../src/savings/swap-execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"swap-execute.d.ts","sourceRoot":"","sources":["../../src/savings/swap-execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;mCAImC;AACnC,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,YAAY,GAAG,IAAI,CAmB9F;AASD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE;QAClB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;QAChD,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;KAChF,CAAC;IACF,QAAQ,CAAC,KAAK,EAAE;QAAE,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,CAAC;IAClE,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;iFAE6E;IAC7E,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3C,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAwGnF"}
|
|
@@ -15,8 +15,36 @@
|
|
|
15
15
|
* executed. Applying the YAML stays a human/git action.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.readCacheContext = readCacheContext;
|
|
18
19
|
exports.executeSwap = executeSwap;
|
|
19
20
|
const emit_1 = require("./emit");
|
|
21
|
+
const evaluate_1 = require("../watch/evaluate");
|
|
22
|
+
/** Narrow a proposal's `evidence.cache_context` jsonb (spec §5.5 — additive,
|
|
23
|
+
* present only on cache-aware proposals) to a typed `CacheContext`, or null when
|
|
24
|
+
* absent/malformed. Defensive: an older or non-cache proposal has no block, and
|
|
25
|
+
* a partial block must degrade to "no cache explanation", never throw on the
|
|
26
|
+
* safety-critical execute path. */
|
|
27
|
+
function readCacheContext(evidence) {
|
|
28
|
+
const raw = evidence?.cache_context;
|
|
29
|
+
if (raw === null || typeof raw !== "object")
|
|
30
|
+
return null;
|
|
31
|
+
const c = raw;
|
|
32
|
+
const verdicts = ["cache_positive", "cache_marginal", "cache_negative", "no_cache_signal"];
|
|
33
|
+
if (typeof c.verdict !== "string" || !verdicts.includes(c.verdict))
|
|
34
|
+
return null;
|
|
35
|
+
const num = (v) => (typeof v === "number" ? v : 0);
|
|
36
|
+
return {
|
|
37
|
+
observed_hit_rate: num(c.observed_hit_rate),
|
|
38
|
+
observed_write_rate: num(c.observed_write_rate),
|
|
39
|
+
window_days: num(c.window_days),
|
|
40
|
+
incumbent_effective_in_per_mtok: num(c.incumbent_effective_in_per_mtok),
|
|
41
|
+
challenger_cold_in_per_mtok: num(c.challenger_cold_in_per_mtok),
|
|
42
|
+
switch_cost_usd: num(c.switch_cost_usd),
|
|
43
|
+
cache_option_value_usd: num(c.cache_option_value_usd),
|
|
44
|
+
breakeven_conformant_calls: typeof c.breakeven_conformant_calls === "number" ? c.breakeven_conformant_calls : Number.POSITIVE_INFINITY,
|
|
45
|
+
verdict: c.verdict,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
20
48
|
async function executeSwap(deps) {
|
|
21
49
|
// The gate first — before any client call, so a non-approved invocation
|
|
22
50
|
// has zero side effects (defense in depth with the CLI's fast-fail check).
|
|
@@ -83,5 +111,20 @@ async function executeSwap(deps) {
|
|
|
83
111
|
revertedAt: null,
|
|
84
112
|
});
|
|
85
113
|
await deps.proposals.setStatus(proposal.id, "approved", "executed");
|
|
86
|
-
|
|
114
|
+
// Cache-aware explainability (spec §5.5) — additive, read-only. The verdict +
|
|
115
|
+
// prose ride along for the approval prompt / audit trail; they NEVER gate the
|
|
116
|
+
// swap (the human decision above is the only gate). Absent on non-cache
|
|
117
|
+
// proposals, in which case both are null and behavior is byte-identical.
|
|
118
|
+
const cacheContext = readCacheContext(proposal.evidence);
|
|
119
|
+
const incumbentLabel = change.incumbentCandidates.map((c) => `${c.provider}/${c.model}`).join(", ") || "incumbent";
|
|
120
|
+
const cacheExplanation = cacheContext !== null ? (0, evaluate_1.explainCacheContext)(cacheContext, incumbentLabel, winner.variant) : null;
|
|
121
|
+
return {
|
|
122
|
+
swapId,
|
|
123
|
+
route: proposal.route,
|
|
124
|
+
change,
|
|
125
|
+
approvedBy: deps.approvedBy,
|
|
126
|
+
executedAt,
|
|
127
|
+
cacheVerdict: cacheContext?.verdict ?? null,
|
|
128
|
+
cacheExplanation,
|
|
129
|
+
};
|
|
87
130
|
}
|
|
@@ -29,12 +29,26 @@ export interface SwapEventRecord {
|
|
|
29
29
|
export interface SwapsClientConfig {
|
|
30
30
|
readonly supabaseUrl: string;
|
|
31
31
|
readonly serviceRoleKey: string;
|
|
32
|
+
/**
|
|
33
|
+
* The tenant this client writes/reads for. When set (the hosted managed-loop
|
|
34
|
+
* §1 swap surface + odometer): `record` STAMPS `org_id` on the row (else it
|
|
35
|
+
* falls to the house-org column default — filing a customer's swap under ours)
|
|
36
|
+
* and `list` scopes to this org (the odometer must never sum another tenant's
|
|
37
|
+
* swaps). When omitted, behaviour is unchanged for the CLI/self-host lane.
|
|
38
|
+
* `get`/`orgOf`/`markReverted` are keyed by id and org-agnostic.
|
|
39
|
+
*/
|
|
40
|
+
readonly orgId?: string;
|
|
32
41
|
readonly fetchFn?: typeof fetch;
|
|
33
42
|
}
|
|
34
43
|
export interface SwapsClient {
|
|
35
44
|
record(event: SwapEventRecord): Promise<void>;
|
|
45
|
+
/** All executed swaps for this client's org (when `orgId` set) or every org
|
|
46
|
+
* (unscoped) — newest first. The odometer reader's source. */
|
|
36
47
|
list(): Promise<SwapEventRecord[]>;
|
|
37
48
|
get(id: string): Promise<SwapEventRecord | null>;
|
|
49
|
+
/** The org that owns a swap, or null if no such swap — the tenant a revert
|
|
50
|
+
* must be authorized against (T11), mirroring `proposals.orgOf`. */
|
|
51
|
+
orgOf(id: string): Promise<string | null>;
|
|
38
52
|
markReverted(id: string, revertedAt: string): Promise<void>;
|
|
39
53
|
}
|
|
40
54
|
export declare function createSwapsClient(config: SwapsClientConfig): SwapsClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swaps-client.d.ts","sourceRoot":"","sources":["../../src/savings/swaps-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,+BAA+B,EAAE,MAAM,CAAC;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpF;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AA4BD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACnC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACjD,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"swaps-client.d.ts","sourceRoot":"","sources":["../../src/savings/swaps-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,+BAA+B,EAAE,MAAM,CAAC;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpF;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AA4BD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C;kEAC8D;IAC9D,IAAI,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACnC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACjD;wEACoE;IACpE,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CAiFxE"}
|
|
@@ -45,6 +45,9 @@ function createSwapsClient(config) {
|
|
|
45
45
|
headers: { prefer: "resolution=ignore-duplicates,return=minimal" },
|
|
46
46
|
body: JSON.stringify([
|
|
47
47
|
{
|
|
48
|
+
// Stamp the tenant when scoped; else the house-org column default
|
|
49
|
+
// applies (single-tenant self-host). A hosted swap MUST carry its org.
|
|
50
|
+
...(config.orgId !== undefined ? { org_id: config.orgId } : {}),
|
|
48
51
|
id: event.id,
|
|
49
52
|
proposal_id: event.proposalId,
|
|
50
53
|
route: event.route,
|
|
@@ -59,7 +62,8 @@ function createSwapsClient(config) {
|
|
|
59
62
|
});
|
|
60
63
|
},
|
|
61
64
|
async list() {
|
|
62
|
-
const
|
|
65
|
+
const scope = config.orgId !== undefined ? `&org_id=eq.${encodeURIComponent(config.orgId)}` : "";
|
|
66
|
+
const response = await request(`swap_events?select=*${scope}&order=executed_at.desc`, {
|
|
63
67
|
method: "GET",
|
|
64
68
|
});
|
|
65
69
|
return (await response.json()).map(toRecord);
|
|
@@ -71,8 +75,18 @@ function createSwapsClient(config) {
|
|
|
71
75
|
const rows = (await response.json());
|
|
72
76
|
return rows.length > 0 ? toRecord(rows[0]) : null;
|
|
73
77
|
},
|
|
78
|
+
async orgOf(id) {
|
|
79
|
+
const response = await request(`swap_events?select=org_id&id=eq.${encodeURIComponent(id)}`, {
|
|
80
|
+
method: "GET",
|
|
81
|
+
});
|
|
82
|
+
const rows = (await response.json());
|
|
83
|
+
return rows.length > 0 && typeof rows[0].org_id === "string" ? rows[0].org_id : null;
|
|
84
|
+
},
|
|
74
85
|
async markReverted(id, revertedAt) {
|
|
75
|
-
|
|
86
|
+
// `reverted_at=is.null` so a concurrent second revert matches zero rows
|
|
87
|
+
// rather than overwriting the first revert's timestamp (a benign TOCTOU,
|
|
88
|
+
// hardened: the odometer's stop-accruing point stays the first revert).
|
|
89
|
+
await request(`swap_events?id=eq.${encodeURIComponent(id)}&reverted_at=is.null`, {
|
|
76
90
|
method: "PATCH",
|
|
77
91
|
body: JSON.stringify({ reverted_at: revertedAt }),
|
|
78
92
|
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The api-mode task-settings fetcher (settings-plane §1.5): one authenticated
|
|
3
|
+
* GET to the hosted control plane per task, shaped into a `TaskSettings` for the
|
|
4
|
+
* resolver's cache. Kept apart from the pure resolver so the resolver stays
|
|
5
|
+
* network-free (unit-testable with a mock fetcher) and this file owns the one
|
|
6
|
+
* HTTP concern.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors the api SINK's posture (telemetry/sinks.ts): same `Bearer rig_sk_`
|
|
9
|
+
* header, same "status only, never the body, never the URL in an error" leak
|
|
10
|
+
* discipline (C2). NEVER throws for a network/HTTP failure — it resolves `null`
|
|
11
|
+
* so the resolver stays fail-open (a settings read must never take a run down).
|
|
12
|
+
*/
|
|
13
|
+
import type { RigConfig } from "../config";
|
|
14
|
+
import { type TaskSettingsFetcher, type TaskSettingsResolver } from "./task-settings";
|
|
15
|
+
export interface ApiTaskSettingsFetcherConfig {
|
|
16
|
+
/** Base URL of the hosted control plane, e.g. https://api.modelrig.ai — the
|
|
17
|
+
* SAME `ingestUrl` the api sink uses (the settings path hangs off the host). */
|
|
18
|
+
readonly ingestUrl: string;
|
|
19
|
+
/** `rig_sk_…` key. GET needs no special scope (settings ride the readable task
|
|
20
|
+
* row — see the server handler), so the ingest key suffices. Header only,
|
|
21
|
+
* never a URL (C2). */
|
|
22
|
+
readonly apiKey: string;
|
|
23
|
+
/** Injectable for tests; defaults to the global fetch. */
|
|
24
|
+
readonly fetchFn?: typeof fetch;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build the api-mode fetcher. `fetch(task)` GETs `/v1/tasks/:task/settings` and
|
|
28
|
+
* returns the parsed settings, or null on ANY non-200, network error, or
|
|
29
|
+
* malformed body — the resolver reads null as "leave the cache as it is".
|
|
30
|
+
*/
|
|
31
|
+
export declare function createApiTaskSettingsFetcher(config: ApiTaskSettingsFetcherConfig): TaskSettingsFetcher;
|
|
32
|
+
/**
|
|
33
|
+
* Construct AND start the api-mode settings resolver from a rig config, or null
|
|
34
|
+
* when the rig is not in api mode (local-only/direct keep env/YAML). Folds the
|
|
35
|
+
* fetcher + resolver + start into one call so the SDK entrypoint stays under the
|
|
36
|
+
* LOC cap. The resolver refreshes on `intervalMs` (the exporter interval).
|
|
37
|
+
*/
|
|
38
|
+
export declare function startApiSettings(config: RigConfig, defaultIntervalMs: number): TaskSettingsResolver | null;
|
|
39
|
+
//# sourceMappingURL=api-fetcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-fetcher.d.ts","sourceRoot":"","sources":["../../src/settings/api-fetcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAa,MAAM,WAAW,CAAC;AACtD,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EAC1B,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,4BAA4B;IAC3C;oFACgF;IAChF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;2BAEuB;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACjC;AAwBD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,4BAA4B,GACnC,mBAAmB,CAsBrB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,iBAAiB,EAAE,MAAM,GACxB,oBAAoB,GAAG,IAAI,CAW7B"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The api-mode task-settings fetcher (settings-plane §1.5): one authenticated
|
|
4
|
+
* GET to the hosted control plane per task, shaped into a `TaskSettings` for the
|
|
5
|
+
* resolver's cache. Kept apart from the pure resolver so the resolver stays
|
|
6
|
+
* network-free (unit-testable with a mock fetcher) and this file owns the one
|
|
7
|
+
* HTTP concern.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors the api SINK's posture (telemetry/sinks.ts): same `Bearer rig_sk_`
|
|
10
|
+
* header, same "status only, never the body, never the URL in an error" leak
|
|
11
|
+
* discipline (C2). NEVER throws for a network/HTTP failure — it resolves `null`
|
|
12
|
+
* so the resolver stays fail-open (a settings read must never take a run down).
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.createApiTaskSettingsFetcher = createApiTaskSettingsFetcher;
|
|
16
|
+
exports.startApiSettings = startApiSettings;
|
|
17
|
+
const task_settings_1 = require("./task-settings");
|
|
18
|
+
const SCRUB_MODES = ["off", "detect", "redact", "block"];
|
|
19
|
+
/** Narrow an unknown JSON body into a `TaskSettings`, or null when the shape is
|
|
20
|
+
* not what the endpoint promises. A malformed 200 is treated like a miss
|
|
21
|
+
* (fail-open) rather than trusted — we never fabricate a capture-on from junk. */
|
|
22
|
+
function parseSettings(body) {
|
|
23
|
+
if (typeof body !== "object" || body === null)
|
|
24
|
+
return null;
|
|
25
|
+
const settings = body.settings;
|
|
26
|
+
if (typeof settings !== "object" || settings === null)
|
|
27
|
+
return null;
|
|
28
|
+
const s = settings;
|
|
29
|
+
if (typeof s.capture !== "boolean")
|
|
30
|
+
return null;
|
|
31
|
+
if (!(s.artifacts_enabled === null || typeof s.artifacts_enabled === "boolean"))
|
|
32
|
+
return null;
|
|
33
|
+
if (typeof s.artifact_content !== "boolean")
|
|
34
|
+
return null;
|
|
35
|
+
if (!SCRUB_MODES.includes(s.scrub))
|
|
36
|
+
return null;
|
|
37
|
+
return {
|
|
38
|
+
capture: s.capture,
|
|
39
|
+
artifacts_enabled: s.artifacts_enabled,
|
|
40
|
+
artifact_content: s.artifact_content,
|
|
41
|
+
scrub: s.scrub,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build the api-mode fetcher. `fetch(task)` GETs `/v1/tasks/:task/settings` and
|
|
46
|
+
* returns the parsed settings, or null on ANY non-200, network error, or
|
|
47
|
+
* malformed body — the resolver reads null as "leave the cache as it is".
|
|
48
|
+
*/
|
|
49
|
+
function createApiTaskSettingsFetcher(config) {
|
|
50
|
+
const base = config.ingestUrl.replace(/\/$/, "");
|
|
51
|
+
const fetchFn = config.fetchFn ?? fetch;
|
|
52
|
+
return {
|
|
53
|
+
async fetch(task) {
|
|
54
|
+
const url = `${base}/v1/tasks/${encodeURIComponent(task)}/settings`;
|
|
55
|
+
let response;
|
|
56
|
+
try {
|
|
57
|
+
response = await fetchFn(url, {
|
|
58
|
+
method: "GET",
|
|
59
|
+
headers: { authorization: `Bearer ${config.apiKey}` },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Network throw — no status. Fail-open: the resolver keeps last-known.
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
// 404 (task not yet registered) and every other non-200 → null, no throw.
|
|
67
|
+
if (!response.ok)
|
|
68
|
+
return null;
|
|
69
|
+
const body = (await response.json().catch(() => null));
|
|
70
|
+
return parseSettings(body);
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Construct AND start the api-mode settings resolver from a rig config, or null
|
|
76
|
+
* when the rig is not in api mode (local-only/direct keep env/YAML). Folds the
|
|
77
|
+
* fetcher + resolver + start into one call so the SDK entrypoint stays under the
|
|
78
|
+
* LOC cap. The resolver refreshes on `intervalMs` (the exporter interval).
|
|
79
|
+
*/
|
|
80
|
+
function startApiSettings(config, defaultIntervalMs) {
|
|
81
|
+
if (config.export?.mode !== "api")
|
|
82
|
+
return null;
|
|
83
|
+
const resolver = (0, task_settings_1.createTaskSettingsResolver)({
|
|
84
|
+
fetcher: createApiTaskSettingsFetcher({
|
|
85
|
+
ingestUrl: config.export.ingestUrl,
|
|
86
|
+
apiKey: config.export.apiKey,
|
|
87
|
+
}),
|
|
88
|
+
intervalMs: config.export.intervalMs ?? defaultIntervalMs,
|
|
89
|
+
});
|
|
90
|
+
resolver.start();
|
|
91
|
+
return resolver;
|
|
92
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Control-plane settings resolution (settings-plane §1.5) — the barrel.
|
|
3
|
+
* Re-exported from the SDK entrypoint so `index.ts` stays under the LOC cap and
|
|
4
|
+
* the settings surface has one home.
|
|
5
|
+
*/
|
|
6
|
+
export { createTaskSettingsResolver, effectiveCapture, DEFAULT_TASK_SETTINGS, } from "./task-settings";
|
|
7
|
+
export type { TaskSettings, TaskSettingsResolver, TaskSettingsFetcher } from "./task-settings";
|
|
8
|
+
export { createApiTaskSettingsFetcher, startApiSettings } from "./api-fetcher";
|
|
9
|
+
export type { ApiTaskSettingsFetcherConfig } from "./api-fetcher";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/settings/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,4BAA4B,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC/E,YAAY,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Control-plane settings resolution (settings-plane §1.5) — the barrel.
|
|
4
|
+
* Re-exported from the SDK entrypoint so `index.ts` stays under the LOC cap and
|
|
5
|
+
* the settings surface has one home.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.startApiSettings = exports.createApiTaskSettingsFetcher = exports.DEFAULT_TASK_SETTINGS = exports.effectiveCapture = exports.createTaskSettingsResolver = void 0;
|
|
9
|
+
var task_settings_1 = require("./task-settings");
|
|
10
|
+
Object.defineProperty(exports, "createTaskSettingsResolver", { enumerable: true, get: function () { return task_settings_1.createTaskSettingsResolver; } });
|
|
11
|
+
Object.defineProperty(exports, "effectiveCapture", { enumerable: true, get: function () { return task_settings_1.effectiveCapture; } });
|
|
12
|
+
Object.defineProperty(exports, "DEFAULT_TASK_SETTINGS", { enumerable: true, get: function () { return task_settings_1.DEFAULT_TASK_SETTINGS; } });
|
|
13
|
+
var api_fetcher_1 = require("./api-fetcher");
|
|
14
|
+
Object.defineProperty(exports, "createApiTaskSettingsFetcher", { enumerable: true, get: function () { return api_fetcher_1.createApiTaskSettingsFetcher; } });
|
|
15
|
+
Object.defineProperty(exports, "startApiSettings", { enumerable: true, get: function () { return api_fetcher_1.startApiSettings; } });
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK-side control-plane settings resolution (settings-plane §1.5).
|
|
3
|
+
*
|
|
4
|
+
* In api mode a task's governance settings — capture / artifacts / content /
|
|
5
|
+
* scrub — live in the CONTROL PLANE, not in YAML. The console, the API, and the
|
|
6
|
+
* MCP tool set them (Phase 1); the SDK PULLS them: once at boot and again on the
|
|
7
|
+
* exporter interval, cached, keyed by the task identity a run carries
|
|
8
|
+
* (`opts.task` — the E4 landing note: rig.run auto-step is NOT wired, so there is
|
|
9
|
+
* no ambient route context to key on). The control-plane value WINS over any
|
|
10
|
+
* YAML flag wherever a control plane is configured (spec §1.5); YAML `capture:`
|
|
11
|
+
* is deprecated and honored only by local-only rigs (see routes/loader.ts).
|
|
12
|
+
*
|
|
13
|
+
* ── FAIL-OPEN, ALWAYS ─────────────────────────────────────────────────────
|
|
14
|
+
* The run loop must never block on, or fail because of, this network read —
|
|
15
|
+
* same doctrine as the telemetry exporter. So:
|
|
16
|
+
* • `get(task)` is SYNCHRONOUS and reads only the cache; it never awaits.
|
|
17
|
+
* • a fetch that errors leaves the LAST-KNOWN value untouched (fail-open to
|
|
18
|
+
* last-known).
|
|
19
|
+
* • a task never yet fetched resolves to DEFAULT_TASK_SETTINGS (capture off —
|
|
20
|
+
* the safe floor), never a block.
|
|
21
|
+
*
|
|
22
|
+
* local-only rigs (no control plane) never construct this at all — env/YAML stay
|
|
23
|
+
* their only mechanism, unchanged.
|
|
24
|
+
*/
|
|
25
|
+
import type { ScrubMode } from "../config";
|
|
26
|
+
/** The four governance settings, exactly as `GET /v1/tasks/:task/settings`
|
|
27
|
+
* returns them under `settings` (mirrors the server's `TaskSettings`). */
|
|
28
|
+
export interface TaskSettings {
|
|
29
|
+
readonly capture: boolean;
|
|
30
|
+
/** null = inherit the gateway/SDK default (§2). A boolean overrides it. */
|
|
31
|
+
readonly artifacts_enabled: boolean | null;
|
|
32
|
+
readonly artifact_content: boolean;
|
|
33
|
+
readonly scrub: ScrubMode;
|
|
34
|
+
}
|
|
35
|
+
/** The safe floor for a task the control plane has not answered for yet: capture
|
|
36
|
+
* OFF, artifacts inherit the default, content OFF, scrub the schema default. A
|
|
37
|
+
* run that reaches the cache before the first fetch lands sees this — never a
|
|
38
|
+
* block, never a silent capture-on. */
|
|
39
|
+
export declare const DEFAULT_TASK_SETTINGS: TaskSettings;
|
|
40
|
+
/** Pulls one task's settings from the control plane. Returns the settings, or
|
|
41
|
+
* `null` when the task is unknown (404) or the read is unreadable — the resolver
|
|
42
|
+
* treats null as "leave the cache as it is" (fail-open). NEVER throws for a
|
|
43
|
+
* network/HTTP failure; it resolves null so the caller stays fail-open. */
|
|
44
|
+
export interface TaskSettingsFetcher {
|
|
45
|
+
fetch(task: string): Promise<TaskSettings | null>;
|
|
46
|
+
}
|
|
47
|
+
export interface TaskSettingsResolver {
|
|
48
|
+
/** The effective settings for a task, from the cache only — synchronous,
|
|
49
|
+
* never throws, never awaits. Last-known if fetched before; DEFAULT otherwise. */
|
|
50
|
+
get(task: string): TaskSettings;
|
|
51
|
+
/** A copy of every tracked task's last-known settings — for `rig.status()` /
|
|
52
|
+
* the boot posture. Empty until the first run tracks a task. */
|
|
53
|
+
snapshot(): ReadonlyMap<string, TaskSettings>;
|
|
54
|
+
/** Register a task so the interval refresh keeps it fresh, and kick a
|
|
55
|
+
* one-shot fetch now if it has never been seen. Fire-and-forget; fail-open.
|
|
56
|
+
* Called on the first run that carries this `opts.task`. */
|
|
57
|
+
track(task: string): void;
|
|
58
|
+
/** Re-pull every tracked task once. The boot pull and each exporter-interval
|
|
59
|
+
* tick call this. Resolves after all fetches settle; never rejects. */
|
|
60
|
+
refresh(): Promise<void>;
|
|
61
|
+
/** Begin the interval loop (idempotent). */
|
|
62
|
+
start(): void;
|
|
63
|
+
/** Stop the interval loop (idempotent). */
|
|
64
|
+
stop(): void;
|
|
65
|
+
}
|
|
66
|
+
export interface TaskSettingsResolverConfig {
|
|
67
|
+
readonly fetcher: TaskSettingsFetcher;
|
|
68
|
+
/** Refresh cadence — the exporter interval, threaded from index.ts so the two
|
|
69
|
+
* loops beat together (spec §1.5: "refreshes on the exporter interval"). */
|
|
70
|
+
readonly intervalMs: number;
|
|
71
|
+
/** Injectable for tests; defaults to the real timers. */
|
|
72
|
+
readonly setInterval?: (fn: () => void, ms: number) => ReturnType<typeof setInterval>;
|
|
73
|
+
readonly clearInterval?: (handle: ReturnType<typeof setInterval>) => void;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build the api-mode task-settings resolver. Holds a per-task cache and an
|
|
77
|
+
* interval that re-pulls every tracked task, so a console flip is reflected
|
|
78
|
+
* within one interval WITHOUT a redeploy (spec acceptance d). Every fetch is
|
|
79
|
+
* fail-open: a rejection or a null leaves the last-known value in place.
|
|
80
|
+
*/
|
|
81
|
+
export declare function createTaskSettingsResolver(config: TaskSettingsResolverConfig): TaskSettingsResolver;
|
|
82
|
+
/**
|
|
83
|
+
* The EFFECTIVE capture flag for a run (spec §1.5 precedence). When a control
|
|
84
|
+
* plane is configured (resolver present) it WINS: the YAML flag is ignored
|
|
85
|
+
* entirely — deprecated, warned about at load (routes/loader.ts). Only a
|
|
86
|
+
* local-only rig (resolver null) lets the YAML flag govern. A run with no task
|
|
87
|
+
* identity to key on (`opts.task` absent) falls back to YAML even in api mode,
|
|
88
|
+
* because there is no control-plane row to resolve.
|
|
89
|
+
*/
|
|
90
|
+
export declare function effectiveCapture(resolver: TaskSettingsResolver | null, task: string | undefined, yamlCapture: boolean): boolean;
|
|
91
|
+
//# sourceMappingURL=task-settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-settings.d.ts","sourceRoot":"","sources":["../../src/settings/task-settings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;0EAC0E;AAC1E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AAED;;;uCAGuC;AACvC,eAAO,MAAM,qBAAqB,EAAE,YAKnC,CAAC;AAEF;;;2EAG2E;AAC3E,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,oBAAoB;IACnC;sFACkF;IAClF,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;IAChC;oEACgE;IAChE,QAAQ,IAAI,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC9C;;gEAE4D;IAC5D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;2EACuE;IACvE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,4CAA4C;IAC5C,KAAK,IAAI,IAAI,CAAC;IACd,2CAA2C;IAC3C,IAAI,IAAI,IAAI,CAAC;CACd;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC;gFAC4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACtF,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,KAAK,IAAI,CAAC;CAC3E;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,0BAA0B,GACjC,oBAAoB,CA4DtB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,oBAAoB,GAAG,IAAI,EACrC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,WAAW,EAAE,OAAO,GACnB,OAAO,CAGT"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SDK-side control-plane settings resolution (settings-plane §1.5).
|
|
4
|
+
*
|
|
5
|
+
* In api mode a task's governance settings — capture / artifacts / content /
|
|
6
|
+
* scrub — live in the CONTROL PLANE, not in YAML. The console, the API, and the
|
|
7
|
+
* MCP tool set them (Phase 1); the SDK PULLS them: once at boot and again on the
|
|
8
|
+
* exporter interval, cached, keyed by the task identity a run carries
|
|
9
|
+
* (`opts.task` — the E4 landing note: rig.run auto-step is NOT wired, so there is
|
|
10
|
+
* no ambient route context to key on). The control-plane value WINS over any
|
|
11
|
+
* YAML flag wherever a control plane is configured (spec §1.5); YAML `capture:`
|
|
12
|
+
* is deprecated and honored only by local-only rigs (see routes/loader.ts).
|
|
13
|
+
*
|
|
14
|
+
* ── FAIL-OPEN, ALWAYS ─────────────────────────────────────────────────────
|
|
15
|
+
* The run loop must never block on, or fail because of, this network read —
|
|
16
|
+
* same doctrine as the telemetry exporter. So:
|
|
17
|
+
* • `get(task)` is SYNCHRONOUS and reads only the cache; it never awaits.
|
|
18
|
+
* • a fetch that errors leaves the LAST-KNOWN value untouched (fail-open to
|
|
19
|
+
* last-known).
|
|
20
|
+
* • a task never yet fetched resolves to DEFAULT_TASK_SETTINGS (capture off —
|
|
21
|
+
* the safe floor), never a block.
|
|
22
|
+
*
|
|
23
|
+
* local-only rigs (no control plane) never construct this at all — env/YAML stay
|
|
24
|
+
* their only mechanism, unchanged.
|
|
25
|
+
*/
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.DEFAULT_TASK_SETTINGS = void 0;
|
|
28
|
+
exports.createTaskSettingsResolver = createTaskSettingsResolver;
|
|
29
|
+
exports.effectiveCapture = effectiveCapture;
|
|
30
|
+
/** The safe floor for a task the control plane has not answered for yet: capture
|
|
31
|
+
* OFF, artifacts inherit the default, content OFF, scrub the schema default. A
|
|
32
|
+
* run that reaches the cache before the first fetch lands sees this — never a
|
|
33
|
+
* block, never a silent capture-on. */
|
|
34
|
+
exports.DEFAULT_TASK_SETTINGS = {
|
|
35
|
+
capture: false,
|
|
36
|
+
artifacts_enabled: null,
|
|
37
|
+
artifact_content: false,
|
|
38
|
+
scrub: "detect",
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Build the api-mode task-settings resolver. Holds a per-task cache and an
|
|
42
|
+
* interval that re-pulls every tracked task, so a console flip is reflected
|
|
43
|
+
* within one interval WITHOUT a redeploy (spec acceptance d). Every fetch is
|
|
44
|
+
* fail-open: a rejection or a null leaves the last-known value in place.
|
|
45
|
+
*/
|
|
46
|
+
function createTaskSettingsResolver(config) {
|
|
47
|
+
const cache = new Map();
|
|
48
|
+
const tracked = new Set();
|
|
49
|
+
const setIntervalFn = config.setInterval ?? setInterval;
|
|
50
|
+
const clearIntervalFn = config.clearInterval ?? clearInterval;
|
|
51
|
+
let timer = null;
|
|
52
|
+
/** Pull one task and fold the result into the cache. Fail-open: a thrown
|
|
53
|
+
* error or a null result is swallowed and the cache is left untouched. */
|
|
54
|
+
async function pull(task) {
|
|
55
|
+
try {
|
|
56
|
+
const settings = await config.fetcher.fetch(task);
|
|
57
|
+
if (settings !== null)
|
|
58
|
+
cache.set(task, settings);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Fail-open: keep the last-known value. A settings read must never take a
|
|
62
|
+
// run down, and a warning here would fire once per interval per task —
|
|
63
|
+
// noise. The value simply does not advance until the plane answers again.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
get(task) {
|
|
68
|
+
return cache.get(task) ?? exports.DEFAULT_TASK_SETTINGS;
|
|
69
|
+
},
|
|
70
|
+
snapshot() {
|
|
71
|
+
return new Map(cache);
|
|
72
|
+
},
|
|
73
|
+
track(task) {
|
|
74
|
+
if (tracked.has(task))
|
|
75
|
+
return;
|
|
76
|
+
tracked.add(task);
|
|
77
|
+
// First sighting: pull now so the value is fresh as soon as possible,
|
|
78
|
+
// rather than waiting up to a full interval. Fire-and-forget.
|
|
79
|
+
void pull(task);
|
|
80
|
+
},
|
|
81
|
+
async refresh() {
|
|
82
|
+
// Settle all, never reject — one task's failure must not abort the others'
|
|
83
|
+
// refresh (Promise.allSettled, though each pull already swallows its own).
|
|
84
|
+
await Promise.all([...tracked].map((t) => pull(t)));
|
|
85
|
+
},
|
|
86
|
+
start() {
|
|
87
|
+
if (timer !== null)
|
|
88
|
+
return;
|
|
89
|
+
timer = setIntervalFn(() => {
|
|
90
|
+
void this.refresh();
|
|
91
|
+
}, config.intervalMs);
|
|
92
|
+
// Never keep the process alive for a settings refresh (mirrors the
|
|
93
|
+
// exporter timer's posture).
|
|
94
|
+
timer.unref?.();
|
|
95
|
+
},
|
|
96
|
+
stop() {
|
|
97
|
+
if (timer !== null) {
|
|
98
|
+
clearIntervalFn(timer);
|
|
99
|
+
timer = null;
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The EFFECTIVE capture flag for a run (spec §1.5 precedence). When a control
|
|
106
|
+
* plane is configured (resolver present) it WINS: the YAML flag is ignored
|
|
107
|
+
* entirely — deprecated, warned about at load (routes/loader.ts). Only a
|
|
108
|
+
* local-only rig (resolver null) lets the YAML flag govern. A run with no task
|
|
109
|
+
* identity to key on (`opts.task` absent) falls back to YAML even in api mode,
|
|
110
|
+
* because there is no control-plane row to resolve.
|
|
111
|
+
*/
|
|
112
|
+
function effectiveCapture(resolver, task, yamlCapture) {
|
|
113
|
+
if (resolver === null || task === undefined)
|
|
114
|
+
return yamlCapture;
|
|
115
|
+
return resolver.get(task).capture;
|
|
116
|
+
}
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rig posture — the boot banner + `/status` report (settings-plane §2).
|
|
3
|
+
*
|
|
4
|
+
* WS1's lesson, made a rule: "a default nobody can observe gets asked about
|
|
5
|
+
* instead of answered." The artifact namespace now defaults ON when a control
|
|
6
|
+
* plane is configured (§2 flip), so a user must be able to SEE whether it is on
|
|
7
|
+
* and WHY, without reading source. This module derives that posture from the
|
|
8
|
+
* resolved config (plus, for `/status`, the settings resolver's snapshot) and
|
|
9
|
+
* shapes it for a one-line boot banner and a fuller `/status` report.
|
|
10
|
+
*
|
|
11
|
+
* Pure formatters (no env, no network) except `emitBootBanner`, which writes the
|
|
12
|
+
* one banner line to stderr — kept here so index.ts calls it in a single line.
|
|
13
|
+
*/
|
|
14
|
+
import type { RigConfig } from "./config";
|
|
15
|
+
import type { TaskSettings } from "./settings/task-settings";
|
|
16
|
+
export type ExportMode = "api" | "direct" | "local-only";
|
|
17
|
+
export interface ArtifactsPosture {
|
|
18
|
+
readonly enabled: boolean;
|
|
19
|
+
/** A human sentence naming WHY — so a flipped default is observable. */
|
|
20
|
+
readonly reason: string;
|
|
21
|
+
}
|
|
22
|
+
export interface RigStatus {
|
|
23
|
+
readonly exportMode: ExportMode;
|
|
24
|
+
readonly artifacts: ArtifactsPosture;
|
|
25
|
+
/** Content custody (E2-C) — its own gate, unchanged by the §2 metadata flip. */
|
|
26
|
+
readonly contentCustody: boolean;
|
|
27
|
+
readonly otlp: "configured" | "disabled";
|
|
28
|
+
/** Cache accounting posture (cache-aware-routing WS-A/WS-D). Derived from the
|
|
29
|
+
* policy registry — config-only, so `status` shows it anywhere. Live per-route
|
|
30
|
+
* hit rate + effective input rate are a control-plane read, surfaced on the
|
|
31
|
+
* console route cache page (and GET /v1/routes/:route/cache-stats), not here. */
|
|
32
|
+
readonly cache: CachePosture;
|
|
33
|
+
/** Per-task control-plane settings the resolver has pulled (empty until a run
|
|
34
|
+
* tracks a task, and always empty for a local-only rig). */
|
|
35
|
+
readonly tasks: ReadonlyArray<{
|
|
36
|
+
readonly task: string;
|
|
37
|
+
} & TaskSettings>;
|
|
38
|
+
}
|
|
39
|
+
export interface CachePosture {
|
|
40
|
+
/** The versioned policy registry the accounting math reads (all providers
|
|
41
|
+
* share one `as_of`). */
|
|
42
|
+
readonly policyVersion: string;
|
|
43
|
+
/** Providers whose caching ModelRig accounts for on its path (first-party
|
|
44
|
+
* seeded, `cache_supported: true`); fail-closed providers are omitted. */
|
|
45
|
+
readonly eligibleProviders: readonly string[];
|
|
46
|
+
}
|
|
47
|
+
/** The cache posture from the policy registry alone (WS-A) — which providers
|
|
48
|
+
* ModelRig accounts caching for, and the policy version. No telemetry: live
|
|
49
|
+
* hit rates live behind the control-plane rollup (WS-B / the console). */
|
|
50
|
+
export declare function cachePosture(): CachePosture;
|
|
51
|
+
export declare function exportModeOf(config: RigConfig): ExportMode;
|
|
52
|
+
/**
|
|
53
|
+
* The artifact-namespace posture as a boolean + a reason, derivable from config
|
|
54
|
+
* ALONE (so both the banner and `/status` agree). The four cases the §2 flip
|
|
55
|
+
* creates, each named honestly:
|
|
56
|
+
* on + control plane → the default is now on (a sink exists to ship to)
|
|
57
|
+
* on + local-only → an explicit MODELRIG_ARTIFACTS opt-in
|
|
58
|
+
* off + control plane → an explicit MODELRIG_ARTIFACTS=0 opt-out
|
|
59
|
+
* off + local-only → nothing to ship to; off is the local-only default
|
|
60
|
+
*/
|
|
61
|
+
export declare function artifactsPosture(config: RigConfig): ArtifactsPosture;
|
|
62
|
+
/** Build the full status snapshot from config + the resolver's per-task cache. */
|
|
63
|
+
export declare function buildRigStatus(config: RigConfig, tasks?: ReadonlyMap<string, TaskSettings>): RigStatus;
|
|
64
|
+
/** The one-line boot banner (§2). Concise on purpose — mode, artifacts (+why),
|
|
65
|
+
* content, otlp. */
|
|
66
|
+
export declare function formatBootBanner(config: RigConfig): string;
|
|
67
|
+
/**
|
|
68
|
+
* Emit the boot banner to stderr — ONCE at rig construction, and ONLY when a
|
|
69
|
+
* control plane is configured (the case where the §2 default flip is in effect
|
|
70
|
+
* and the posture is non-obvious). A pure local-only rig with artifacts off is
|
|
71
|
+
* the boring, expected default and stays silent (no banner noise in tests or
|
|
72
|
+
* embedders). Stderr, so it never pollutes a command's stdout.
|
|
73
|
+
*/
|
|
74
|
+
export declare function emitBootBanner(config: RigConfig): void;
|
|
75
|
+
/** Render a `/status` report as multi-line text for the CLI. */
|
|
76
|
+
export declare function formatStatusReport(status: RigStatus): string;
|
|
77
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEzD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,gFAAgF;IAChF,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,UAAU,CAAC;IACzC;;;qFAGiF;IACjF,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B;gEAC4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,YAAY,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,YAAY;IAC3B;6BACyB;IACzB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;8EAC0E;IAC1E,QAAQ,CAAC,iBAAiB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAED;;0EAE0E;AAC1E,wBAAgB,YAAY,IAAI,YAAY,CAI3C;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAE1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB,CAapE;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,EACjB,KAAK,GAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAa,GACnD,SAAS,CASX;AAED;oBACoB;AACpB,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAS1D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAGtD;AAED,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAwB5D"}
|