modelrig 0.3.0 → 0.5.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 +269 -0
- package/README.md +79 -14
- package/dist/adapters/deepseek.d.ts.map +1 -1
- package/dist/adapters/deepseek.js +8 -1
- package/dist/adapters/gemini.d.ts +45 -0
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +67 -6
- package/dist/adapters/grok.d.ts +7 -0
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +23 -1
- package/dist/adapters/openai-compat.d.ts +7 -0
- package/dist/adapters/openai-compat.d.ts.map +1 -1
- package/dist/adapters/openai-compat.js +24 -1
- package/dist/adapters/openai.d.ts +7 -0
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +23 -1
- package/dist/artifacts/artifact.d.ts +3 -2
- package/dist/artifacts/artifact.d.ts.map +1 -1
- package/dist/artifacts/artifact.js +11 -4
- package/dist/artifacts/run-context.d.ts +21 -2
- package/dist/artifacts/run-context.d.ts.map +1 -1
- package/dist/artifacts/run-context.js +46 -1
- package/dist/bakeoff/replay.d.ts.map +1 -1
- package/dist/bakeoff/replay.js +17 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +26 -5
- package/dist/config.d.ts +7 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +21 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -26
- package/dist/init/init-cli.d.ts.map +1 -1
- package/dist/init/init-cli.js +2 -1
- package/dist/init/observe-cli.d.ts.map +1 -1
- package/dist/init/observe-cli.js +2 -1
- package/dist/registry/select.d.ts +59 -0
- package/dist/registry/select.d.ts.map +1 -1
- package/dist/registry/select.js +66 -0
- package/dist/routes/loader-warnings.d.ts +28 -0
- package/dist/routes/loader-warnings.d.ts.map +1 -0
- package/dist/routes/loader-warnings.js +56 -0
- package/dist/routes/loader.d.ts +1 -11
- package/dist/routes/loader.d.ts.map +1 -1
- package/dist/routes/loader.js +44 -26
- package/dist/routes/sampling-config.d.ts.map +1 -1
- package/dist/routes/sampling-config.js +11 -0
- package/dist/run/dispatch.d.ts +14 -2
- package/dist/run/dispatch.d.ts.map +1 -1
- package/dist/run/dispatch.js +31 -2
- package/dist/run/ladder-key.d.ts +40 -0
- package/dist/run/ladder-key.d.ts.map +1 -0
- package/dist/run/ladder-key.js +39 -0
- package/dist/run/raw-defaults.d.ts +52 -0
- package/dist/run/raw-defaults.d.ts.map +1 -0
- package/dist/run/raw-defaults.js +123 -0
- package/dist/run/raw-support.d.ts +123 -0
- package/dist/run/raw-support.d.ts.map +1 -0
- package/dist/run/raw-support.js +150 -0
- package/dist/run/raw.d.ts +53 -11
- package/dist/run/raw.d.ts.map +1 -1
- package/dist/run/raw.js +157 -31
- package/dist/run/rawonly.d.ts +60 -0
- package/dist/run/rawonly.d.ts.map +1 -0
- package/dist/run/rawonly.js +120 -0
- package/dist/run/record-attempt.d.ts +14 -1
- package/dist/run/record-attempt.d.ts.map +1 -1
- package/dist/run/record-attempt.js +43 -2
- package/dist/run/resolve.d.ts +21 -1
- package/dist/run/resolve.d.ts.map +1 -1
- package/dist/run/resolve.js +29 -6
- package/dist/run/routing-docs.d.ts +73 -0
- package/dist/run/routing-docs.d.ts.map +1 -0
- package/dist/run/routing-docs.js +222 -0
- package/dist/run/run.d.ts +7 -1
- package/dist/run/run.d.ts.map +1 -1
- package/dist/run/run.js +38 -55
- package/dist/run/variant.d.ts +43 -0
- package/dist/run/variant.d.ts.map +1 -0
- package/dist/run/variant.js +86 -0
- package/dist/savings/emit.d.ts +33 -0
- package/dist/savings/emit.d.ts.map +1 -1
- package/dist/savings/emit.js +75 -3
- package/dist/telemetry/exporter.d.ts.map +1 -1
- package/dist/telemetry/exporter.js +6 -0
- package/dist/telemetry/ingest-protocol.d.ts +7 -0
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
- package/dist/telemetry/load-error-report.d.ts.map +1 -1
- package/dist/telemetry/load-error-report.js +4 -1
- package/dist/telemetry/otel-map.d.ts.map +1 -1
- package/dist/telemetry/otel-map.js +8 -0
- package/dist/telemetry/store-migrations.d.ts +15 -0
- package/dist/telemetry/store-migrations.d.ts.map +1 -0
- package/dist/telemetry/store-migrations.js +119 -0
- package/dist/telemetry/store.d.ts.map +1 -1
- package/dist/telemetry/store.js +26 -93
- package/dist/types/failures-teaching.js +1 -1
- package/dist/types/provider.d.ts +13 -0
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/route.d.ts +37 -1
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +31 -0
- package/dist/types/telemetry.d.ts.map +1 -1
- package/dist/validate-cli.d.ts.map +1 -1
- package/dist/validate-cli.js +17 -4
- package/dist/watch/evaluate.d.ts +27 -1
- package/dist/watch/evaluate.d.ts.map +1 -1
- package/dist/watch/evaluate.js +13 -0
- package/dist/watch/proposals.d.ts +28 -0
- package/dist/watch/proposals.d.ts.map +1 -1
- package/dist/watch/proposals.js +51 -0
- package/package.json +1 -1
package/dist/run/resolve.d.ts
CHANGED
|
@@ -9,10 +9,30 @@ import type { RouteBundle, RunOptions } from "../types/route";
|
|
|
9
9
|
import type { CandidateRef, CapabilityFlag, ProviderId } from "../types/provider";
|
|
10
10
|
/** Static capability stub — replaced by the probed registry in Phase 2. */
|
|
11
11
|
export type CapabilityLookup = (provider: ProviderId, model: string) => ReadonlySet<CapabilityFlag>;
|
|
12
|
+
/**
|
|
13
|
+
* Resolution mode (routing-console spec §4.4, R3). `live` is every production
|
|
14
|
+
* path (`rig.run`, `runStream`, `runBundle`, the hosted gateway slug lane) and
|
|
15
|
+
* DROPS `trial` candidates before minting — a declared trial candidate is never
|
|
16
|
+
* served live. `trial` is the bake-off replay path ONLY (`replayVariant`), which
|
|
17
|
+
* keeps trial candidates so a customer can measure a new model on captured
|
|
18
|
+
* traffic before promoting it. Default `live` — every existing caller is
|
|
19
|
+
* byte-for-byte unchanged (no trial candidates ⇒ the filter is a no-op anyway).
|
|
20
|
+
*/
|
|
21
|
+
export type RunMode = "live" | "trial";
|
|
12
22
|
export interface CandidateIterator {
|
|
13
23
|
/** Next eligible candidate, or null when the set is exhausted. */
|
|
14
24
|
next(): CandidateRef | null;
|
|
25
|
+
/** Position in the EFFECTIVE eligible list of the candidate the most recent
|
|
26
|
+
* `next()` returned (0 = first eligible; ladder key, spec §2.1). `-1` before
|
|
27
|
+
* the first `next()`; unchanged by a `next()` that returns null. */
|
|
28
|
+
readonly index: number;
|
|
15
29
|
}
|
|
30
|
+
/** The live-resolver capability filter. Exported so the declare-first challenger
|
|
31
|
+
* eligibility (`registry/select.ts` `requirementPredicates` +
|
|
32
|
+
* `evaluateChallengerEligibility`) can pin itself in agreement with what would
|
|
33
|
+
* actually serve — an eligibility that drifted from the live filter would offer
|
|
34
|
+
* a challenger the route could never dispatch. */
|
|
35
|
+
export declare function satisfiesRequirements(route: RouteBundle, flags: ReadonlySet<CapabilityFlag>, searchAvailable: boolean): boolean;
|
|
16
36
|
/**
|
|
17
37
|
* Request-time candidate filters (G-2) — optional, applied by resolveCandidates
|
|
18
38
|
* BEFORE the prefer:[cost] sort. Distinct from route.require (capability + ZDR):
|
|
@@ -56,7 +76,7 @@ export interface WarmthShadowLog {
|
|
|
56
76
|
}[];
|
|
57
77
|
readonly diverged: boolean;
|
|
58
78
|
}
|
|
59
|
-
export declare function resolveCandidates(route: RouteBundle, capabilities: CapabilityLookup, costUsdPerMTok: (provider: ProviderId, model: string) => number | null, searchAvailable?: boolean, filter?: CandidateFilter, shadowWarmth?: WarmthShadowOptions): CandidateIterator;
|
|
79
|
+
export declare function resolveCandidates(route: RouteBundle, capabilities: CapabilityLookup, costUsdPerMTok: (provider: ProviderId, model: string) => number | null, searchAvailable?: boolean, filter?: CandidateFilter, shadowWarmth?: WarmthShadowOptions, mode?: RunMode): CandidateIterator;
|
|
60
80
|
/**
|
|
61
81
|
* Per-run requirement opt-ins (G-3). A caller can demand zero-retention routing
|
|
62
82
|
* for a single run without editing the route bundle: `zero_retention` is unioned
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/run/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAElF,2EAA2E;AAC3E,MAAM,MAAM,gBAAgB,GAAG,CAC7B,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,MAAM,KACV,WAAW,CAAC,cAAc,CAAC,CAAC;AAEjC,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/run/resolve.ts"],"names":[],"mappings":"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"}
|
package/dist/run/resolve.js
CHANGED
|
@@ -7,12 +7,18 @@
|
|
|
7
7
|
* retryable failure the run loop asks for the next candidate.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.satisfiesRequirements = satisfiesRequirements;
|
|
10
11
|
exports.resolveCandidates = resolveCandidates;
|
|
11
12
|
exports.applyRunRequirements = applyRunRequirements;
|
|
12
13
|
exports.candidateFilterFromOptions = candidateFilterFromOptions;
|
|
13
14
|
exports.filterSummary = filterSummary;
|
|
14
15
|
exports.mintRawCandidate = mintRawCandidate;
|
|
15
16
|
exports.resolveDeclaredCandidate = resolveDeclaredCandidate;
|
|
17
|
+
/** The live-resolver capability filter. Exported so the declare-first challenger
|
|
18
|
+
* eligibility (`registry/select.ts` `requirementPredicates` +
|
|
19
|
+
* `evaluateChallengerEligibility`) can pin itself in agreement with what would
|
|
20
|
+
* actually serve — an eligibility that drifted from the live filter would offer
|
|
21
|
+
* a challenger the route could never dispatch. */
|
|
16
22
|
function satisfiesRequirements(route, flags, searchAvailable) {
|
|
17
23
|
for (const requirement of route.require) {
|
|
18
24
|
switch (requirement) {
|
|
@@ -56,11 +62,21 @@ function satisfiesRequirements(route, flags, searchAvailable) {
|
|
|
56
62
|
}
|
|
57
63
|
return true;
|
|
58
64
|
}
|
|
59
|
-
function resolveCandidates(route, capabilities, costUsdPerMTok, searchAvailable = false, filter, shadowWarmth) {
|
|
60
|
-
// Filter order (spec §4.1): provider only → provider ignore →
|
|
61
|
-
// → maxPrice → prefer:[cost]. When `filter` is absent every
|
|
62
|
-
// so the path is byte-for-byte the pre-G-2 behavior
|
|
65
|
+
function resolveCandidates(route, capabilities, costUsdPerMTok, searchAvailable = false, filter, shadowWarmth, mode = "live") {
|
|
66
|
+
// Filter order (spec §4.1): trial-drop → provider only → provider ignore →
|
|
67
|
+
// capability+ZDR → maxPrice → prefer:[cost]. When `filter` is absent every
|
|
68
|
+
// step is a no-op, so the path is byte-for-byte the pre-G-2 behavior
|
|
69
|
+
// (back-compat).
|
|
63
70
|
let pool = route.candidates;
|
|
71
|
+
// Declare-first (spec §4.4): a `trial` candidate is declared but NEVER served
|
|
72
|
+
// live — drop it first, exactly as a `providers.ignore` entry is dropped, on
|
|
73
|
+
// every live path. Only bake-off replay (`mode: "trial"`) keeps it. The
|
|
74
|
+
// candidate-set invariant is untouched: `route.candidates` (the declared set
|
|
75
|
+
// the run loop's runtime guard checks against) still includes trial entries;
|
|
76
|
+
// they are simply never minted into a CandidateRef on a live path.
|
|
77
|
+
if (mode === "live") {
|
|
78
|
+
pool = pool.filter((c) => c.trial !== true);
|
|
79
|
+
}
|
|
64
80
|
if (filter?.only && filter.only.length > 0) {
|
|
65
81
|
const only = new Set(filter.only);
|
|
66
82
|
pool = pool.filter((c) => only.has(c.provider));
|
|
@@ -124,10 +140,17 @@ function resolveCandidates(route, capabilities, costUsdPerMTok, searchAvailable
|
|
|
124
140
|
// minted. The cast below is the single sanctioned exception to the
|
|
125
141
|
// "no `as CandidateRef`" grep (scoped to run/resolve.ts in CI).
|
|
126
142
|
const refs = ordered.map((c) => Object.freeze({ provider: c.provider, model: c.model }));
|
|
127
|
-
let
|
|
143
|
+
let cursor = 0;
|
|
144
|
+
let lastIndex = -1;
|
|
128
145
|
return {
|
|
129
146
|
next() {
|
|
130
|
-
|
|
147
|
+
if (cursor >= refs.length)
|
|
148
|
+
return null;
|
|
149
|
+
lastIndex = cursor;
|
|
150
|
+
return refs[cursor++];
|
|
151
|
+
},
|
|
152
|
+
get index() {
|
|
153
|
+
return lastIndex;
|
|
131
154
|
},
|
|
132
155
|
};
|
|
133
156
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routing & reliability — the code-anchored boundary and the failure-class
|
|
3
|
+
* section of https://modelrig.dev/routing-reliability.html.
|
|
4
|
+
*
|
|
5
|
+
* ONE table feeds the published page AND the tripwire test, the same way
|
|
6
|
+
* `RAW_KNOB_SUPPORT` (raw-support.ts) feeds the raw-lane matrix and its runtime
|
|
7
|
+
* guard. The docs builder (scripts/build-docs-site.ts) injects
|
|
8
|
+
* `renderRoutingBoundary()` at `<!-- ROUTING_BOUNDARY -->` and
|
|
9
|
+
* `renderFailureClasses()` at `<!-- FAILURE_CLASSES -->`, and inlines the
|
|
10
|
+
* boundary into llms.txt. Nothing here is exported from the package root.
|
|
11
|
+
*
|
|
12
|
+
* Spec: docs/ModelRig/routing-reliability-overview/spec.md §5–§6.
|
|
13
|
+
*/
|
|
14
|
+
import type { FailureClass } from "../types/failures";
|
|
15
|
+
export type BoundaryStatus = "not_built" | "deferred" | "shadow" | "by_design";
|
|
16
|
+
export interface BoundaryTripwire {
|
|
17
|
+
/** Path relative to packages/modelrig (the test reads it as text). */
|
|
18
|
+
readonly file: string;
|
|
19
|
+
/** Entry is STALE if this matches — the feature appeared. */
|
|
20
|
+
readonly mustNotMatch?: RegExp;
|
|
21
|
+
/** Entry is STALE if this stops matching — the no-op marker vanished. */
|
|
22
|
+
readonly mustMatch?: RegExp;
|
|
23
|
+
}
|
|
24
|
+
export interface BoundaryEntry {
|
|
25
|
+
/** Stable id (B1…) — becomes the first table column and a citable handle. */
|
|
26
|
+
readonly id: string;
|
|
27
|
+
readonly status: BoundaryStatus;
|
|
28
|
+
/** <= 8 words. */
|
|
29
|
+
readonly capability: string;
|
|
30
|
+
/** ONE sentence, present tense: what is true today. */
|
|
31
|
+
readonly statement: string;
|
|
32
|
+
/** Repo doc path (or issue) a reader can cite. */
|
|
33
|
+
readonly tracking: string;
|
|
34
|
+
readonly tripwire?: BoundaryTripwire | {
|
|
35
|
+
readonly noImportersOf: string;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Rendered group headings, in order. */
|
|
39
|
+
export declare const BOUNDARY_STATUS_LABEL: Readonly<Record<BoundaryStatus, string>>;
|
|
40
|
+
/**
|
|
41
|
+
* The ten boundary entries, transcribed verbatim from spec §5.3. Statuses,
|
|
42
|
+
* statements, and tripwires are BINDING content — do not add, drop, or reword
|
|
43
|
+
* an entry without an architect addendum to the spec. Shipping a capability
|
|
44
|
+
* listed here breaks `routing-docs.test.ts` until the entry is flipped or
|
|
45
|
+
* removed and the page updated.
|
|
46
|
+
*/
|
|
47
|
+
export declare const ROUTING_BOUNDARY: readonly BoundaryEntry[];
|
|
48
|
+
/**
|
|
49
|
+
* Markdown (renderer subset only): one `###` per non-empty status group, a pipe
|
|
50
|
+
* table per group with columns id | capability | what is true today | tracking.
|
|
51
|
+
* No nested lists, no HTML — the docs-site renderer supports neither.
|
|
52
|
+
*
|
|
53
|
+
* `published` (the site's page slugs) is passed by the docs builder so a tracking
|
|
54
|
+
* cell naming a published page renders as a link; a bare call (the shape/tripwire
|
|
55
|
+
* tests, which assert the plain table) leaves every cell as plain text.
|
|
56
|
+
*/
|
|
57
|
+
export declare function renderRoutingBoundary(published?: ReadonlySet<string>): string;
|
|
58
|
+
/** The failure classes in taxonomy order (types/failures.ts `FailureClass`
|
|
59
|
+
* union). FAILURE_TEACHING is keyed in that same order and its completeness is
|
|
60
|
+
* pinned by failures-teaching.test.ts, so its key order is the canonical walk.
|
|
61
|
+
* A test in routing-docs.test.ts asserts this equals the union order in
|
|
62
|
+
* failures.ts, so a taxonomy reorder cannot drift silently. */
|
|
63
|
+
export declare function failureClassOrder(): readonly FailureClass[];
|
|
64
|
+
/**
|
|
65
|
+
* Markdown: `### <class>` per FailureClass in taxonomy order, then the teaching
|
|
66
|
+
* `what`, the retry line, the backoff schedule (when any), and the `fixHint`.
|
|
67
|
+
* Heading text is the bare class name so the docs-site id equals the class
|
|
68
|
+
* (failures-teaching.ts docsUrl anchors depend on it — spec §6).
|
|
69
|
+
*/
|
|
70
|
+
export declare function renderFailureClasses(): string;
|
|
71
|
+
/** Exposed for the anchor-completeness test: the heading id each class gets. */
|
|
72
|
+
export declare function failureClassAnchor(cls: FailureClass): string;
|
|
73
|
+
//# sourceMappingURL=routing-docs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing-docs.d.ts","sourceRoot":"","sources":["../../src/run/routing-docs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE/E,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,kBAAkB;IAClB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uDAAuD;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,GAAG;QAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AAED,yCAAyC;AACzC,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,CAK1E,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,aAAa,EA0FpD,CAAC;AAwBF;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAoB7E;AAED;;;;+DAI+D;AAC/D,wBAAgB,iBAAiB,IAAI,SAAS,YAAY,EAAE,CAE3D;AA0BD;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAW7C;AAED,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAE5D"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Routing & reliability — the code-anchored boundary and the failure-class
|
|
4
|
+
* section of https://modelrig.dev/routing-reliability.html.
|
|
5
|
+
*
|
|
6
|
+
* ONE table feeds the published page AND the tripwire test, the same way
|
|
7
|
+
* `RAW_KNOB_SUPPORT` (raw-support.ts) feeds the raw-lane matrix and its runtime
|
|
8
|
+
* guard. The docs builder (scripts/build-docs-site.ts) injects
|
|
9
|
+
* `renderRoutingBoundary()` at `<!-- ROUTING_BOUNDARY -->` and
|
|
10
|
+
* `renderFailureClasses()` at `<!-- FAILURE_CLASSES -->`, and inlines the
|
|
11
|
+
* boundary into llms.txt. Nothing here is exported from the package root.
|
|
12
|
+
*
|
|
13
|
+
* Spec: docs/ModelRig/routing-reliability-overview/spec.md §5–§6.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.ROUTING_BOUNDARY = exports.BOUNDARY_STATUS_LABEL = void 0;
|
|
17
|
+
exports.renderRoutingBoundary = renderRoutingBoundary;
|
|
18
|
+
exports.failureClassOrder = failureClassOrder;
|
|
19
|
+
exports.renderFailureClasses = renderFailureClasses;
|
|
20
|
+
exports.failureClassAnchor = failureClassAnchor;
|
|
21
|
+
const failures_1 = require("../types/failures");
|
|
22
|
+
const failures_teaching_1 = require("../types/failures-teaching");
|
|
23
|
+
/** Rendered group headings, in order. */
|
|
24
|
+
exports.BOUNDARY_STATUS_LABEL = {
|
|
25
|
+
not_built: "Not built",
|
|
26
|
+
deferred: "Deferred",
|
|
27
|
+
shadow: "Built, not actuating",
|
|
28
|
+
by_design: "By design — will not do",
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The ten boundary entries, transcribed verbatim from spec §5.3. Statuses,
|
|
32
|
+
* statements, and tripwires are BINDING content — do not add, drop, or reword
|
|
33
|
+
* an entry without an architect addendum to the spec. Shipping a capability
|
|
34
|
+
* listed here breaks `routing-docs.test.ts` until the entry is flipped or
|
|
35
|
+
* removed and the page updated.
|
|
36
|
+
*/
|
|
37
|
+
exports.ROUTING_BOUNDARY = [
|
|
38
|
+
{
|
|
39
|
+
id: "B1",
|
|
40
|
+
status: "not_built",
|
|
41
|
+
capability: "Quality / value-accuracy gate in the ladder",
|
|
42
|
+
statement: "Fall-through is triggered by structure and infrastructure only; no builder-defined predicate or judge can reject a schema-valid output at run time — value accuracy exists offline, in bake-offs.",
|
|
43
|
+
tracking: "customer request on file (2026-08-21); not scheduled",
|
|
44
|
+
tripwire: { file: "src/types/route.ts", mustNotMatch: /qualityGate|"judged"/ },
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "B2",
|
|
48
|
+
status: "not_built",
|
|
49
|
+
capability: "Structure on the raw lane",
|
|
50
|
+
statement: '`runRaw` never validates or repairs; `responseFormat: "json_object"` shapes MIME, not schema, so `meta.validated` stays false — structure on the raw lane is ruled out by design, and the path is to graduate that step to a route.',
|
|
51
|
+
tracking: "ruled schema-free on the raw lane; re-request on file",
|
|
52
|
+
tripwire: { file: "src/run/raw.ts", mustNotMatch: /readonly outputSchema\??:/ },
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "B3",
|
|
56
|
+
status: "deferred",
|
|
57
|
+
capability: "`prefer: latency` / observed-health ordering",
|
|
58
|
+
statement: "`latency` is accepted and does nothing — declared order stands; observed p50/p90/p99 are aggregated but unused by routing.",
|
|
59
|
+
tracking: "deferred to the observed-health work (latency signal first)",
|
|
60
|
+
tripwire: { file: "src/run/resolve.ts", mustMatch: /declared order stands/ },
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: "B4",
|
|
64
|
+
status: "shadow",
|
|
65
|
+
capability: "Cache-aware (warmth) candidate ordering",
|
|
66
|
+
statement: "The cache-adjusted ranking is computed and logged beside the chosen order but never changes it.",
|
|
67
|
+
tracking: "cache-aware routing — shadow mode; see caching-lifecycle.md",
|
|
68
|
+
tripwire: { file: "src/run/resolve.ts", mustMatch: /returns the UNCHANGED list-cost order/ },
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: "B5",
|
|
72
|
+
status: "shadow",
|
|
73
|
+
capability: "Cache-miss streak alert",
|
|
74
|
+
statement: "A miss-streak detector exists; nothing consumes it yet, so no alert fires.",
|
|
75
|
+
tracking: "cache-aware routing — monitor wiring pending",
|
|
76
|
+
tripwire: { noImportersOf: "telemetry/cache-miss-streak" },
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "B6",
|
|
80
|
+
status: "not_built",
|
|
81
|
+
capability: "Run-level idempotency / dedupe key",
|
|
82
|
+
statement: "Two identical `rig.run` calls dispatch twice; the only idempotency is the exporter's watermark.",
|
|
83
|
+
// Spec §5.3 tracking reads "— (record here)": B6 has no external tracking
|
|
84
|
+
// doc; this generated boundary IS its record, so the rendered cell is "—".
|
|
85
|
+
tracking: "—",
|
|
86
|
+
tripwire: { file: "src/types/route.ts", mustNotMatch: /idempotencyKey/ },
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "B7",
|
|
90
|
+
status: "by_design",
|
|
91
|
+
capability: "Automatic model swap",
|
|
92
|
+
statement: "Nothing changes what serves a route without a bake-off and an explicit human approval (`modelrig swap execute <id> --approve`).",
|
|
93
|
+
tracking: "optimization-loop.md — human-approved swaps only",
|
|
94
|
+
// No file tripwire: the P6 never-silent-swap invariant is covered by its
|
|
95
|
+
// own dev-rule tests (spec §5.3).
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: "B8",
|
|
99
|
+
status: "by_design",
|
|
100
|
+
capability: "Provider cache resource lifecycle",
|
|
101
|
+
statement: "ModelRig passes your cache handle through and prices the hits; it never creates, refreshes, or deletes the resource — your heartbeat does.",
|
|
102
|
+
tracking: "caching-lifecycle.md — who owns what",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "B9",
|
|
106
|
+
status: "by_design",
|
|
107
|
+
capability: "Tool execution",
|
|
108
|
+
statement: "ModelRig normalizes the tool-call protocol and returns `meta.toolCalls`; the caller runs the tool.",
|
|
109
|
+
tracking: "route-bundles.md — tools are normalized, never executed",
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: "B10",
|
|
113
|
+
status: "by_design",
|
|
114
|
+
capability: "Raw-lane flex → standard degrade",
|
|
115
|
+
statement: "A flex capacity rejection on `runRaw` surfaces as `capacity_shed` for your own retry ladder; ModelRig does not degrade the tier for you.",
|
|
116
|
+
tracking: "route-bundles.md — raw-lane serviceTier (customer-side degrade)",
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
const STATUS_ORDER = ["not_built", "deferred", "shadow", "by_design"];
|
|
120
|
+
/** Escape a table cell so a literal `|` in content cannot break the pipe table.
|
|
121
|
+
* (None of the current statements contain one; this keeps a future edit safe.) */
|
|
122
|
+
function cell(text) {
|
|
123
|
+
return text.replace(/\|/g, "\\|");
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Turn a `<slug>.md` token in a tracking cell into a markdown link to that
|
|
127
|
+
* published page (S8) — but ONLY when the slug is one the site actually
|
|
128
|
+
* publishes, so a stray `.md` reference never becomes a dead link. The URL is
|
|
129
|
+
* absolute (`modelrig.dev/<slug>.html`) so the same rendered text works on the
|
|
130
|
+
* page (the docs renderer leaves an already-`.html` href alone) AND inline in
|
|
131
|
+
* llms.txt, which is plain text and never runs the `.md`→`.html` rewrite.
|
|
132
|
+
*/
|
|
133
|
+
function linkifyTracking(text, published) {
|
|
134
|
+
return text.replace(/\b([a-z0-9][a-z0-9-]*)\.md\b/gi, (whole, slug) => published.has(slug) ? `[${slug}](https://modelrig.dev/${slug}.html)` : whole);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Markdown (renderer subset only): one `###` per non-empty status group, a pipe
|
|
138
|
+
* table per group with columns id | capability | what is true today | tracking.
|
|
139
|
+
* No nested lists, no HTML — the docs-site renderer supports neither.
|
|
140
|
+
*
|
|
141
|
+
* `published` (the site's page slugs) is passed by the docs builder so a tracking
|
|
142
|
+
* cell naming a published page renders as a link; a bare call (the shape/tripwire
|
|
143
|
+
* tests, which assert the plain table) leaves every cell as plain text.
|
|
144
|
+
*/
|
|
145
|
+
function renderRoutingBoundary(published) {
|
|
146
|
+
const blocks = [];
|
|
147
|
+
for (const status of STATUS_ORDER) {
|
|
148
|
+
const entries = exports.ROUTING_BOUNDARY.filter((e) => e.status === status);
|
|
149
|
+
if (entries.length === 0)
|
|
150
|
+
continue;
|
|
151
|
+
const rows = entries.map((e) => {
|
|
152
|
+
const tracking = published ? linkifyTracking(e.tracking, published) : e.tracking;
|
|
153
|
+
return `| ${e.id} | ${cell(e.capability)} | ${cell(e.statement)} | ${cell(tracking)} |`;
|
|
154
|
+
});
|
|
155
|
+
blocks.push([
|
|
156
|
+
`### ${exports.BOUNDARY_STATUS_LABEL[status]}`,
|
|
157
|
+
"",
|
|
158
|
+
"| id | capability | what is true today | tracking |",
|
|
159
|
+
"|---|---|---|---|",
|
|
160
|
+
...rows,
|
|
161
|
+
].join("\n"));
|
|
162
|
+
}
|
|
163
|
+
return blocks.join("\n\n");
|
|
164
|
+
}
|
|
165
|
+
/** The failure classes in taxonomy order (types/failures.ts `FailureClass`
|
|
166
|
+
* union). FAILURE_TEACHING is keyed in that same order and its completeness is
|
|
167
|
+
* pinned by failures-teaching.test.ts, so its key order is the canonical walk.
|
|
168
|
+
* A test in routing-docs.test.ts asserts this equals the union order in
|
|
169
|
+
* failures.ts, so a taxonomy reorder cannot drift silently. */
|
|
170
|
+
function failureClassOrder() {
|
|
171
|
+
return Object.keys(failures_teaching_1.FAILURE_TEACHING);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Backoff schedule per class, in reader-facing words. The numbers mirror the
|
|
175
|
+
* (non-exported) constants in run/retry.ts — `CAPACITY_BACKOFF_MS` and the
|
|
176
|
+
* `NETWORK_BACKOFF_*` pair — and a test in routing-docs.test.ts reads retry.ts
|
|
177
|
+
* to pin them, so this string cannot drift from the engine (spec §6).
|
|
178
|
+
*/
|
|
179
|
+
function backoffLine(cls) {
|
|
180
|
+
if (cls === "capacity_shed")
|
|
181
|
+
return "Backoff between retries: 30 s -> 60 s -> 120 s -> 240 s.";
|
|
182
|
+
if (cls === "network")
|
|
183
|
+
return "Backoff between retries: 1 s, doubling each time, capped at 30 s.";
|
|
184
|
+
// A class that is never retried — terminal, or `config_auth` (straight to the
|
|
185
|
+
// next candidate) — has no backoff to describe. Every OTHER class is retryable
|
|
186
|
+
// with a zero delay, so say so: §2 promises "with backoff", and leaving the
|
|
187
|
+
// remaining classes silent read as "unspecified" rather than "none" (S7).
|
|
188
|
+
if (failures_1.TERMINAL_CLASSES.has(cls) || cls === "config_auth")
|
|
189
|
+
return null;
|
|
190
|
+
return "No backoff between retries (immediate retry).";
|
|
191
|
+
}
|
|
192
|
+
/** The retry disposition sentence for one class (spec §6). */
|
|
193
|
+
function retryLine(cls) {
|
|
194
|
+
if (failures_1.TERMINAL_CLASSES.has(cls))
|
|
195
|
+
return "Terminal — never retried; aborts the run.";
|
|
196
|
+
if (cls === "config_auth")
|
|
197
|
+
return "Never retried — the run loop advances to the next candidate.";
|
|
198
|
+
return "Retryable — default budget 0 (declare every budget you want under `policy.retries`).";
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Markdown: `### <class>` per FailureClass in taxonomy order, then the teaching
|
|
202
|
+
* `what`, the retry line, the backoff schedule (when any), and the `fixHint`.
|
|
203
|
+
* Heading text is the bare class name so the docs-site id equals the class
|
|
204
|
+
* (failures-teaching.ts docsUrl anchors depend on it — spec §6).
|
|
205
|
+
*/
|
|
206
|
+
function renderFailureClasses() {
|
|
207
|
+
const blocks = [];
|
|
208
|
+
for (const cls of failureClassOrder()) {
|
|
209
|
+
const teaching = failures_teaching_1.FAILURE_TEACHING[cls];
|
|
210
|
+
const parts = [`### ${cls}`, "", teaching.what, "", retryLine(cls)];
|
|
211
|
+
const backoff = backoffLine(cls);
|
|
212
|
+
if (backoff !== null)
|
|
213
|
+
parts.push("", backoff);
|
|
214
|
+
parts.push("", `Fix: ${teaching.fixHint}`);
|
|
215
|
+
blocks.push(parts.join("\n"));
|
|
216
|
+
}
|
|
217
|
+
return blocks.join("\n\n");
|
|
218
|
+
}
|
|
219
|
+
/** Exposed for the anchor-completeness test: the heading id each class gets. */
|
|
220
|
+
function failureClassAnchor(cls) {
|
|
221
|
+
return cls;
|
|
222
|
+
}
|
package/dist/run/run.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { RigManifest } from "../routes/manifest";
|
|
|
12
12
|
import type { RunOptions, RunResult } from "../types/route";
|
|
13
13
|
import type { TelemetryStore } from "../types/telemetry";
|
|
14
14
|
import type { CaptureStore } from "../telemetry/capture";
|
|
15
|
-
import type { CapabilityLookup } from "./resolve";
|
|
15
|
+
import type { CapabilityLookup, RunMode } from "./resolve";
|
|
16
16
|
import type { SearchProvider } from "./grounding";
|
|
17
17
|
import type { StreamDeltaSink } from "./dispatch";
|
|
18
18
|
import type { TaskSettingsResolver } from "../settings/task-settings";
|
|
@@ -50,6 +50,12 @@ export interface RunDeps {
|
|
|
50
50
|
* content before a capture row is written. null/omitted = local-only (the
|
|
51
51
|
* YAML flag governs, no per-task scrub policy). */
|
|
52
52
|
readonly settings?: TaskSettingsResolver | null;
|
|
53
|
+
/** Resolution mode (routing-console spec §4.4, R3) — `live` (default) on every
|
|
54
|
+
* production surface, `trial` ONLY on the bake-off replay path (`replayVariant`
|
|
55
|
+
* sets it). `trial` keeps declared `trial` candidates and permits selecting a
|
|
56
|
+
* trial variant; `live` drops trial candidates before minting and rejects a
|
|
57
|
+
* trial variant. Absent ⇒ live ⇒ byte-identical to the pre-R3 loop. */
|
|
58
|
+
readonly mode?: RunMode;
|
|
53
59
|
}
|
|
54
60
|
export declare function run(deps: RunDeps, routeName: string, opts: RunOptions): Promise<RunResult>;
|
|
55
61
|
//# sourceMappingURL=run.d.ts.map
|
package/dist/run/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/run/run.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAMrD,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,mBAAmB,CAAC;AAGvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/run/run.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAMrD,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,mBAAmB,CAAC;AAGvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAW,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAS3D,OAAO,KAAK,EAAE,cAAc,EAAoC,MAAM,aAAa,CAAC;AAUpF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAKlD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACxD,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;IACxC,+EAA+E;IAC/E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;gDAE4C;IAC5C,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACvC;2EACuE;IACvE,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IACxC;;0BAEsB;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACxC,qDAAqD;IACrD,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C;;;mFAG+E;IAC/E,QAAQ,CAAC,aAAa,CAAC,EAAE,eAAe,CAAC;IACzC;;;;;uDAKmD;IACnD,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAChD;;;;2EAIuE;IACvE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAsBD,wBAAsB,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAgkBhG"}
|