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
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Non-fatal loader advisories — extracted from loader.ts (kept it under the
|
|
4
|
+
* 700-LOC cap). Each is a pure function returning a warning line or null; the
|
|
5
|
+
* loader console.warns them after a bundle loads. Unit-tested directly.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.arrayRootSchemaWarning = arrayRootSchemaWarning;
|
|
9
|
+
exports.unreferencedTrialCandidatesWarning = unreferencedTrialCandidatesWarning;
|
|
10
|
+
/**
|
|
11
|
+
* CE-2 A5 co-item: warn (non-fatal) when a route's output schema has an ARRAY
|
|
12
|
+
* root. OpenAI strict structured output (`response_format: json_schema`, strict)
|
|
13
|
+
* requires a top-level OBJECT — an array-root schema cannot use strict
|
|
14
|
+
* enforcement on OpenAI candidates and silently falls back to non-strict there
|
|
15
|
+
* (the walkthrough §10 provider-matrix gap). The route still LOADS and serves as
|
|
16
|
+
* declared; the fix is to wrap the array in an object property so strict
|
|
17
|
+
* enforcement holds across every provider. Returns the warning line, or null.
|
|
18
|
+
*/
|
|
19
|
+
function arrayRootSchemaWarning(route, outputSchema) {
|
|
20
|
+
if (outputSchema === null)
|
|
21
|
+
return null;
|
|
22
|
+
const rootType = outputSchema.type;
|
|
23
|
+
if (rootType !== "array")
|
|
24
|
+
return null;
|
|
25
|
+
return (`route "${route}" declares an output schema whose ROOT is type: "array". OpenAI strict ` +
|
|
26
|
+
`structured output requires a top-level object, so strict enforcement cannot apply on OpenAI ` +
|
|
27
|
+
`candidates (they fall back to non-strict there). Wrap the array in an object property ` +
|
|
28
|
+
`(e.g. { "type": "object", "properties": { "items": <your array> } }) to keep strict ` +
|
|
29
|
+
`enforcement across providers. The route loads and serves as declared.`);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Declare-first dead-declaration warning (routing-console spec §4.4): a `trial`
|
|
33
|
+
* candidate that no variant references can never be reached — not live (trial
|
|
34
|
+
* candidates are dropped on every live path) and not in a bake-off (a bake-off
|
|
35
|
+
* replays a NAMED variant, and no variant narrows to it). Warn so the author
|
|
36
|
+
* either adds the `trial-<provider>-<model>` variant the declare flow emits or
|
|
37
|
+
* removes the dangling candidate. Non-fatal (the route still loads and serves
|
|
38
|
+
* its live candidates as declared). Pure — unit-tested directly. Returns the
|
|
39
|
+
* warning line, or null when every trial candidate is referenced.
|
|
40
|
+
*/
|
|
41
|
+
function unreferencedTrialCandidatesWarning(route, candidates, variants) {
|
|
42
|
+
const referenced = new Set();
|
|
43
|
+
for (const v of variants) {
|
|
44
|
+
for (const c of v.candidates ?? [])
|
|
45
|
+
referenced.add(`${c.provider}/${c.model}`);
|
|
46
|
+
}
|
|
47
|
+
const dangling = candidates
|
|
48
|
+
.filter((c) => c.trial === true && !referenced.has(`${c.provider}/${c.model}`))
|
|
49
|
+
.map((c) => `${c.provider}/${c.model}`);
|
|
50
|
+
if (dangling.length === 0)
|
|
51
|
+
return null;
|
|
52
|
+
return (`route "${route}" declares trial candidate(s) [${dangling.join(", ")}] that no variant references. ` +
|
|
53
|
+
`A trial candidate is declared but never served live; it is only reachable through a bake-off of a ` +
|
|
54
|
+
`variant that narrows to it. Add a variant (e.g. { name: "trial-${dangling[0].replace("/", "-")}", ` +
|
|
55
|
+
`candidates: [<that candidate>] }) to bake it off, or remove the dangling declaration.`);
|
|
56
|
+
}
|
package/dist/routes/loader.d.ts
CHANGED
|
@@ -4,17 +4,7 @@
|
|
|
4
4
|
* resolves schema/prompt paths relative to the bundle file, freezes.
|
|
5
5
|
*/
|
|
6
6
|
import type { RouteBundle } from "../types/route";
|
|
7
|
-
|
|
8
|
-
* CE-2 A5 co-item: warn (non-fatal) when a route's output schema has an ARRAY
|
|
9
|
-
* root. OpenAI strict structured output (`response_format: json_schema`, strict)
|
|
10
|
-
* requires a top-level OBJECT — an array-root schema cannot use strict
|
|
11
|
-
* enforcement on OpenAI candidates and silently falls back to non-strict there
|
|
12
|
-
* (the walkthrough §10 provider-matrix gap). The route still LOADS and serves as
|
|
13
|
-
* declared; the fix is to wrap the array in an object property so strict
|
|
14
|
-
* enforcement holds across every provider. Returns the warning line, or null.
|
|
15
|
-
* Pure — unit-tested directly.
|
|
16
|
-
*/
|
|
17
|
-
export declare function arrayRootSchemaWarning(route: string, outputSchema: object | null): string | null;
|
|
7
|
+
export { arrayRootSchemaWarning, unreferencedTrialCandidatesWarning } from "./loader-warnings";
|
|
18
8
|
/**
|
|
19
9
|
* Structured config error thrown for any invalid bundle (never a raw Error).
|
|
20
10
|
* Load-time problems are deliberately NOT RigFailures — the failure taxonomy
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/routes/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAKV,WAAW,EAGZ,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/routes/loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAKV,WAAW,EAGZ,MAAM,gBAAgB,CAAC;AAUxB,OAAO,EAAE,sBAAsB,EAAE,kCAAkC,EAAE,MAAM,mBAAmB,CAAC;AAE/F;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;gBAEzB,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAO;CAOxF;AAiCD,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;IAChC,IAAI,IAAI,SAAS,WAAW,EAAE,CAAC;CAChC;AAucD;;;;;;;GAOG;AACH;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,CAItF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,YAAY,CAyB1F;AAED;;yBAEyB;AACzB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,EAAE,CA6CtE;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CA2C1D"}
|
package/dist/routes/loader.js
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* resolves schema/prompt paths relative to the bundle file, freezes.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.RouteConfigError = void 0;
|
|
9
|
-
exports.arrayRootSchemaWarning = arrayRootSchemaWarning;
|
|
8
|
+
exports.RouteConfigError = exports.unreferencedTrialCandidatesWarning = exports.arrayRootSchemaWarning = void 0;
|
|
10
9
|
exports.loadRoutesWithExtra = loadRoutesWithExtra;
|
|
11
10
|
exports.mergeLoadedRoutes = mergeLoadedRoutes;
|
|
12
11
|
exports.validateRoutesDir = validateRoutesDir;
|
|
@@ -19,28 +18,13 @@ const fingerprint_1 = require("../registry/fingerprint");
|
|
|
19
18
|
const template_1 = require("./template");
|
|
20
19
|
const cache_lint_1 = require("./cache-lint");
|
|
21
20
|
const sampling_config_1 = require("./sampling-config");
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* enforcement holds across every provider. Returns the warning line, or null.
|
|
30
|
-
* Pure — unit-tested directly.
|
|
31
|
-
*/
|
|
32
|
-
function arrayRootSchemaWarning(route, outputSchema) {
|
|
33
|
-
if (outputSchema === null)
|
|
34
|
-
return null;
|
|
35
|
-
const rootType = outputSchema.type;
|
|
36
|
-
if (rootType !== "array")
|
|
37
|
-
return null;
|
|
38
|
-
return (`route "${route}" declares an output schema whose ROOT is type: "array". OpenAI strict ` +
|
|
39
|
-
`structured output requires a top-level object, so strict enforcement cannot apply on OpenAI ` +
|
|
40
|
-
`candidates (they fall back to non-strict there). Wrap the array in an object property ` +
|
|
41
|
-
`(e.g. { "type": "object", "properties": { "items": <your array> } }) to keep strict ` +
|
|
42
|
-
`enforcement across providers. The route loads and serves as declared.`);
|
|
43
|
-
}
|
|
21
|
+
const loader_warnings_1 = require("./loader-warnings");
|
|
22
|
+
// Re-exported so existing importers of "./loader" keep resolving these pure
|
|
23
|
+
// advisories (they now live in ./loader-warnings to hold loader.ts under the
|
|
24
|
+
// 700-LOC cap).
|
|
25
|
+
var loader_warnings_2 = require("./loader-warnings");
|
|
26
|
+
Object.defineProperty(exports, "arrayRootSchemaWarning", { enumerable: true, get: function () { return loader_warnings_2.arrayRootSchemaWarning; } });
|
|
27
|
+
Object.defineProperty(exports, "unreferencedTrialCandidatesWarning", { enumerable: true, get: function () { return loader_warnings_2.unreferencedTrialCandidatesWarning; } });
|
|
44
28
|
/**
|
|
45
29
|
* Structured config error thrown for any invalid bundle (never a raw Error).
|
|
46
30
|
* Load-time problems are deliberately NOT RigFailures — the failure taxonomy
|
|
@@ -101,7 +85,18 @@ function parseCandidates(raw, problems) {
|
|
|
101
85
|
problems.push(`candidates[${i}].provider "${c.provider}" is not a known provider`);
|
|
102
86
|
continue;
|
|
103
87
|
}
|
|
104
|
-
|
|
88
|
+
// Declare-first `trial` flag (routing-console spec §4.4): declared, never
|
|
89
|
+
// live-served. Optional; only `true` is carried so an absent/false flag
|
|
90
|
+
// leaves the candidate byte-identical to a pre-R3 candidate.
|
|
91
|
+
if (c.trial !== undefined && typeof c.trial !== "boolean") {
|
|
92
|
+
problems.push(`candidates[${i}].trial must be a boolean`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
out.push(Object.freeze({
|
|
96
|
+
provider: c.provider,
|
|
97
|
+
model: c.model,
|
|
98
|
+
...(c.trial === true ? { trial: true } : {}),
|
|
99
|
+
}));
|
|
105
100
|
}
|
|
106
101
|
return out;
|
|
107
102
|
}
|
|
@@ -223,6 +218,13 @@ function parseRepair(raw, field, candidates, problems) {
|
|
|
223
218
|
problems.push(`${field}.repair_model (${repairModel.provider}/${repairModel.model}) is not in the route's declared candidates`);
|
|
224
219
|
repairModel = null;
|
|
225
220
|
}
|
|
221
|
+
// Declare-first (spec §4.4): the repair model dispatches LIVE, so a `trial`
|
|
222
|
+
// candidate (declared, never live-served) must not be one — reject at load.
|
|
223
|
+
const rm = repairModel;
|
|
224
|
+
if (rm !== null && candidates.some((c) => c.provider === rm.provider && c.model === rm.model && c.trial === true)) {
|
|
225
|
+
problems.push(`${field}.repair_model (${rm.provider}/${rm.model}) is a trial candidate and cannot be a live repair model`);
|
|
226
|
+
repairModel = null;
|
|
227
|
+
}
|
|
226
228
|
}
|
|
227
229
|
if (maxRepairs === 2 && repairModel === null) {
|
|
228
230
|
problems.push(`${field}.max_repairs=2 requires repair_model (attempt 2 is the designated repair model)`);
|
|
@@ -271,6 +273,14 @@ function parseVariants(raw, routeCandidates, problems) {
|
|
|
271
273
|
}
|
|
272
274
|
}
|
|
273
275
|
}
|
|
276
|
+
// trialOnly (routing-console spec §4.4): a variant whose candidates ALL map
|
|
277
|
+
// to declared `trial` candidates is a trial variant — valid for a bake-off,
|
|
278
|
+
// a live config error. Computed from the route-level trial flags (a variant
|
|
279
|
+
// narrows a subset; the flag lives on the declared candidate), so an empty
|
|
280
|
+
// or inherited candidate list is never trial-only.
|
|
281
|
+
const trialOnly = candidates !== undefined &&
|
|
282
|
+
candidates.length > 0 &&
|
|
283
|
+
candidates.every((vc) => routeCandidates.some((rc) => rc.provider === vc.provider && rc.model === vc.model && rc.trial === true));
|
|
274
284
|
if (v.prompt_override !== undefined && v.prompt_append !== undefined) {
|
|
275
285
|
problems.push(`${field} sets both prompt_override and prompt_append — they are mutually exclusive`);
|
|
276
286
|
}
|
|
@@ -293,6 +303,7 @@ function parseVariants(raw, routeCandidates, problems) {
|
|
|
293
303
|
? { json: v.json }
|
|
294
304
|
: {}),
|
|
295
305
|
...(repair !== undefined ? { repair } : {}),
|
|
306
|
+
...(trialOnly ? { trialOnly: true } : {}),
|
|
296
307
|
}));
|
|
297
308
|
}
|
|
298
309
|
return out;
|
|
@@ -440,10 +451,17 @@ function loadBundleFile(filePath) {
|
|
|
440
451
|
}
|
|
441
452
|
// CE-2 A5 co-item: an array-root schema cannot use OpenAI strict enforcement —
|
|
442
453
|
// warn once at load so the incompatibility is deliberate, never silent.
|
|
443
|
-
const arrayRootWarning = arrayRootSchemaWarning(route, outputSchema);
|
|
454
|
+
const arrayRootWarning = (0, loader_warnings_1.arrayRootSchemaWarning)(route, outputSchema);
|
|
444
455
|
if (arrayRootWarning !== null) {
|
|
445
456
|
console.warn(`modelrig: ${arrayRootWarning}`);
|
|
446
457
|
}
|
|
458
|
+
// Declare-first dead-declaration warning (spec §4.4): a trial candidate no
|
|
459
|
+
// variant references is unreachable — warn so the dangling declaration is
|
|
460
|
+
// deliberate, never silent.
|
|
461
|
+
const trialWarning = (0, loader_warnings_1.unreferencedTrialCandidatesWarning)(route, candidates, variants);
|
|
462
|
+
if (trialWarning !== null) {
|
|
463
|
+
console.warn(`modelrig: ${trialWarning}`);
|
|
464
|
+
}
|
|
447
465
|
return Object.freeze({
|
|
448
466
|
route: route,
|
|
449
467
|
version: version,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sampling-config.d.ts","sourceRoot":"","sources":["../../src/routes/sampling-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMjE;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,GACjB,cAAc,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"sampling-config.d.ts","sourceRoot":"","sources":["../../src/routes/sampling-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMjE;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,GACjB,cAAc,GAAG,SAAS,CAgD5B;AAED;yEACyE;AACzE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,WAAW,EACnB,UAAU,EAAE,SAAS,aAAa,EAAE,GACnC,MAAM,GAAG,IAAI,CAaf"}
|
|
@@ -27,6 +27,17 @@ function parseSampling(raw, field, problems) {
|
|
|
27
27
|
problems.push(`${field} must be an object {temperature?, top_p?, max_output_tokens?}`);
|
|
28
28
|
return undefined;
|
|
29
29
|
}
|
|
30
|
+
// Reject unknown keys — the sampling block is a closed 3-key set, and its whole
|
|
31
|
+
// reason to exist is that sampling params must never vanish SILENTLY. A typo
|
|
32
|
+
// (`temperatur`, `maxOutputTokens` camelCase, `top-p`) would otherwise leave the
|
|
33
|
+
// block empty and run at the adapter default — the exact silent-drop CE-6 kills.
|
|
34
|
+
// So here (unlike the lenient rest of `policy`) an unknown key is a config error.
|
|
35
|
+
const KNOWN = new Set(["temperature", "top_p", "max_output_tokens"]);
|
|
36
|
+
for (const key of Object.keys(raw)) {
|
|
37
|
+
if (!KNOWN.has(key)) {
|
|
38
|
+
problems.push(`${field} has unknown key "${key}" — allowed: temperature, top_p, max_output_tokens (snake_case)`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
30
41
|
const out = {};
|
|
31
42
|
const t = raw.temperature;
|
|
32
43
|
if (t !== undefined) {
|
package/dist/run/dispatch.d.ts
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
import type { AdapterRequest, AdapterResult, CandidateRef, ProviderAdapter } from "../types/provider";
|
|
12
12
|
import type { RigFailure } from "../types/failures";
|
|
13
13
|
import type { RouteBundle, RunMeta, RunOptions, RunResult, RunTags } from "../types/route";
|
|
14
|
-
import type { TelemetryStore } from "../types/telemetry";
|
|
14
|
+
import type { TelemetryRung, TelemetryStore } from "../types/telemetry";
|
|
15
|
+
import type { LadderKeyMinter } from "./ladder-key";
|
|
15
16
|
/** One telemetry attempt row's inputs — shared with run.ts's recordAttempt so
|
|
16
17
|
* the tool-call helper here can record through the same closure. */
|
|
17
18
|
export interface AttemptTelemetry {
|
|
@@ -34,6 +35,10 @@ export interface AttemptTelemetry {
|
|
|
34
35
|
readonly repairedBy?: string;
|
|
35
36
|
/** Addendum A1: model had no pricing entry (cost recorded as honest 0). */
|
|
36
37
|
readonly pricingMissing?: boolean;
|
|
38
|
+
/** Explicit ladder-rung hint (R1 review, F1). Only the tool-call path sets it
|
|
39
|
+
* (`tool_call`); every other rung is derived in the recorder from the
|
|
40
|
+
* repaired_by / pre-dispatch / primary-vs-retry signals. */
|
|
41
|
+
readonly rung?: TelemetryRung;
|
|
37
42
|
}
|
|
38
43
|
/** run.ts's recordAttempt, threaded in so the tool-call path records through
|
|
39
44
|
* the same ledger/tenancy closure the rest of the loop uses. */
|
|
@@ -41,7 +46,11 @@ export type RecordAttempt = (attempt: AttemptTelemetry) => string;
|
|
|
41
46
|
/** Record the grounding-inject search's own telemetry row (WS3): a $-only line
|
|
42
47
|
* under the synthetic "search" provider. Extracted from run.ts to keep it under
|
|
43
48
|
* the LOC cap; behaviour is byte-identical to the prior inline recorder. */
|
|
44
|
-
export declare function recordSearchCostRow(telemetry: TelemetryStore, route: RouteBundle, effectiveTags: RunTags, servedVariant: string | null, searchProviderId: string, costUsd: number): void;
|
|
49
|
+
export declare function recordSearchCostRow(telemetry: TelemetryStore, route: RouteBundle, effectiveTags: RunTags, servedVariant: string | null, searchProviderId: string, costUsd: number, ladder: LadderKeyMinter): void;
|
|
50
|
+
/** Schema coaching for the json_mode rung — ported from the production DeepSeek
|
|
51
|
+
* provider's schema-in-prompt guidance (minLength-is-a-FLOOR etc.). Lives here
|
|
52
|
+
* with the other request-shaping helpers to keep run.ts under the LOC cap. */
|
|
53
|
+
export declare function jsonModeCoaching(schema: object): string;
|
|
45
54
|
/** Side-channel for streaming: the run loop hands raw text deltas here as the
|
|
46
55
|
* serving adapter streams. Absent => buffered dispatch via `adapter.call()`
|
|
47
56
|
* (identical to pre-Phase-A behavior). */
|
|
@@ -86,6 +95,9 @@ export interface ToolCallResultParts {
|
|
|
86
95
|
readonly attemptsByClass: RunMeta["attemptsByClass"];
|
|
87
96
|
readonly servedVariant: string | null;
|
|
88
97
|
readonly pricingMissing: boolean;
|
|
98
|
+
/** The call's ladder-key id (spec §2.1 R0) — surfaced on the tool-call meta so
|
|
99
|
+
* it matches the recorded row's `call_id`. */
|
|
100
|
+
readonly callId: string;
|
|
89
101
|
}
|
|
90
102
|
/**
|
|
91
103
|
* Record a tool-call turn and build its RunResult (spec §4.4). A tool call is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/run/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,YAAY,EACZ,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/run/dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,YAAY,EACZ,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD;oEACoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;6DACyD;IACzD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;0BACsB;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC;;gEAE4D;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED;gEACgE;AAChE,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,gBAAgB,KAAK,MAAM,CAAC;AAElE;;4EAE4E;AAC5E,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,OAAO,EACtB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,eAAe,GACtB,IAAI,CAoCN;AAED;;8EAE8E;AAC9E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAYvD;AAED;;0CAE0C;AAC1C,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC;AAEzE,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B;;oEAEgE;IAChE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAC1C;AAED;uDACuD;AACvD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,mBAAmB,GAAG,cAAc,CAgC9E;AAED;4CAC4C;AAC5C,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,YAAY,EACvB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GACtB,cAAc,CAmBhB;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,eAAe,EACxB,GAAG,EAAE,cAAc,EACnB,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,aAAa,CAAC,CAuBxB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,EAAE;QAAE,EAAE,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACrD,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC;kDAC8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,mBAAmB,GAAG,SAAS,CAgD/F"}
|
package/dist/run/dispatch.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
exports.recordSearchCostRow = recordSearchCostRow;
|
|
14
|
+
exports.jsonModeCoaching = jsonModeCoaching;
|
|
14
15
|
exports.buildAdapterRequest = buildAdapterRequest;
|
|
15
16
|
exports.buildRepairAdapterRequest = buildRepairAdapterRequest;
|
|
16
17
|
exports.dispatchCandidate = dispatchCandidate;
|
|
@@ -21,7 +22,11 @@ const cache_handle_1 = require("./cache-handle");
|
|
|
21
22
|
/** Record the grounding-inject search's own telemetry row (WS3): a $-only line
|
|
22
23
|
* under the synthetic "search" provider. Extracted from run.ts to keep it under
|
|
23
24
|
* the LOC cap; behaviour is byte-identical to the prior inline recorder. */
|
|
24
|
-
function recordSearchCostRow(telemetry, route, effectiveTags, servedVariant, searchProviderId, costUsd) {
|
|
25
|
+
function recordSearchCostRow(telemetry, route, effectiveTags, servedVariant, searchProviderId, costUsd, ladder) {
|
|
26
|
+
// Ladder key (spec §2.1 R0): the search-cost row belongs to the same call and
|
|
27
|
+
// rides the same monotonic seq; candidate_index is the candidate this search
|
|
28
|
+
// grounds for (the current one — the run loop set it before the search).
|
|
29
|
+
const ladderKey = ladder.stamp();
|
|
25
30
|
telemetry.record({
|
|
26
31
|
id: (0, node_crypto_1.randomUUID)(),
|
|
27
32
|
ts: new Date().toISOString(),
|
|
@@ -41,15 +46,33 @@ function recordSearchCostRow(telemetry, route, effectiveTags, servedVariant, sea
|
|
|
41
46
|
ttfbMs: null,
|
|
42
47
|
failureClass: null,
|
|
43
48
|
attemptsJson: "{}",
|
|
44
|
-
|
|
49
|
+
// Rung tag (R1 review, F1): the grounding-inject search-cost row.
|
|
50
|
+
tagsJson: JSON.stringify({ ...effectiveTags, rung: "search" }),
|
|
45
51
|
fingerprintCell: route.fingerprintCell,
|
|
46
52
|
servedVariant,
|
|
47
53
|
repairedBy: null,
|
|
48
54
|
pricingMissing: false,
|
|
49
55
|
cacheKey: null,
|
|
50
56
|
prefixFingerprint: null,
|
|
57
|
+
callId: ladderKey.callId,
|
|
58
|
+
attemptSeq: ladderKey.attemptSeq,
|
|
59
|
+
candidateIndex: ladderKey.candidateIndex,
|
|
51
60
|
});
|
|
52
61
|
}
|
|
62
|
+
/** Schema coaching for the json_mode rung — ported from the production DeepSeek
|
|
63
|
+
* provider's schema-in-prompt guidance (minLength-is-a-FLOOR etc.). Lives here
|
|
64
|
+
* with the other request-shaping helpers to keep run.ts under the LOC cap. */
|
|
65
|
+
function jsonModeCoaching(schema) {
|
|
66
|
+
return ("\n\n---\nOUTPUT FORMAT (STRICT): Respond with a SINGLE valid JSON object and nothing else — " +
|
|
67
|
+
'no markdown fences, no introductory text, no sign-off. Your response MUST start with "{" and ' +
|
|
68
|
+
'end with "}". Sanitize every nested string so embedded quotes/brackets do not break the root ' +
|
|
69
|
+
"JSON escaping. The object MUST conform to this JSON Schema — match key names and types " +
|
|
70
|
+
"EXACTLY, include ALL required fields, and do not add commentary fields. CRITICAL: where the " +
|
|
71
|
+
"schema sets a minLength on a narrative/prose field, that is a FLOOR, not a target — write " +
|
|
72
|
+
"thorough, non-repetitive analysis that comfortably EXCEEDS the minimum (do not pad with " +
|
|
73
|
+
"repetition; add real substance). When unsure how long to make a prose field, write more, " +
|
|
74
|
+
`not less:\n\n${JSON.stringify(schema)}`);
|
|
75
|
+
}
|
|
53
76
|
/** Build the primary-attempt AdapterRequest — adds the grounding hint and the
|
|
54
77
|
* unified tools/toolChoice passthrough (spec §4.4). */
|
|
55
78
|
function buildAdapterRequest(parts) {
|
|
@@ -165,6 +188,11 @@ function emitToolCallResult(record, parts) {
|
|
|
165
188
|
...(result.usage.ttfbMs !== undefined ? { ttfbMs: result.usage.ttfbMs } : {}),
|
|
166
189
|
failure: null,
|
|
167
190
|
pricingMissing: parts.pricingMissing,
|
|
191
|
+
// Rung tag (R1 review, F1): a tool-call turn is a real model call but NOT a
|
|
192
|
+
// schema-validated serve — the recorder cannot tell it from a primary, so it
|
|
193
|
+
// is stamped explicitly. The rollup counts it as a tool-call turn, never a
|
|
194
|
+
// dispatch or a serve (its cost still counts).
|
|
195
|
+
rung: "tool_call",
|
|
168
196
|
});
|
|
169
197
|
return {
|
|
170
198
|
output: null,
|
|
@@ -185,6 +213,7 @@ function emitToolCallResult(record, parts) {
|
|
|
185
213
|
attemptsByClass,
|
|
186
214
|
servedVariant,
|
|
187
215
|
repairedBy: null,
|
|
216
|
+
callId: parts.callId,
|
|
188
217
|
toolCalls: result.toolCalls,
|
|
189
218
|
},
|
|
190
219
|
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-call telemetry ladder key — routing-console spec §2.1 / §4.1 (R0).
|
|
3
|
+
*
|
|
4
|
+
* One `callId` is minted per `rig.run` / `runStream` / `runBundle` / `runRaw`
|
|
5
|
+
* invocation and shared by EVERY telemetry row that call writes (primary, retry,
|
|
6
|
+
* repair, grounding-search, tool-call). `attemptSeq` is a 1-based counter that
|
|
7
|
+
* is monotonic across all of those rows, and `candidateIndex` is the position of
|
|
8
|
+
* the candidate the row is about within the call's effective declared list.
|
|
9
|
+
*
|
|
10
|
+
* The minter owns the seq counter and the current candidate index so the run
|
|
11
|
+
* loop does not have to thread them through every `recordAttempt` call site
|
|
12
|
+
* (run.ts sits at its LOC cap). The loop calls `setCandidateIndex` as the
|
|
13
|
+
* candidate iterator advances; the recorder (and the search-cost recorder) call
|
|
14
|
+
* `stamp()` once per row. A repair row is stamped DURING the current candidate's
|
|
15
|
+
* turn — before the iterator advances — so it inherits that candidate's index,
|
|
16
|
+
* which IS "the candidate being repaired" per spec §2.1.
|
|
17
|
+
*/
|
|
18
|
+
/** One stamped ladder key — the three fields persisted onto a telemetry row. */
|
|
19
|
+
export interface LadderKey {
|
|
20
|
+
readonly callId: string;
|
|
21
|
+
readonly attemptSeq: number;
|
|
22
|
+
readonly candidateIndex: number | null;
|
|
23
|
+
}
|
|
24
|
+
/** Hands out ladder keys for a single call. Created once per invocation. */
|
|
25
|
+
export interface LadderKeyMinter {
|
|
26
|
+
/** The `call_id` shared by every row of this invocation. */
|
|
27
|
+
readonly callId: string;
|
|
28
|
+
/** Record the candidate the run loop is currently attempting. Every later
|
|
29
|
+
* `stamp()` reads this value; a null clears it (no active candidate). */
|
|
30
|
+
setCandidateIndex(index: number | null): void;
|
|
31
|
+
/** Stamp the next row: bump `attempt_seq` (1-based, monotonic) and read the
|
|
32
|
+
* current `candidate_index`. */
|
|
33
|
+
stamp(): LadderKey;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build a ladder-key minter. `callId` defaults to a fresh uuid; the raw lane and
|
|
37
|
+
* tests may pass one in. Pure but for the uuid — no I/O, no shared state.
|
|
38
|
+
*/
|
|
39
|
+
export declare function createLadderKeyMinter(callId?: string): LadderKeyMinter;
|
|
40
|
+
//# sourceMappingURL=ladder-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ladder-key.d.ts","sourceRoot":"","sources":["../../src/run/ladder-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,gFAAgF;AAChF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CACxC;AAED,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;6EACyE;IACzE,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IAC9C;oCACgC;IAChC,KAAK,IAAI,SAAS,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,MAAqB,GAAG,eAAe,CAapF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The per-call telemetry ladder key — routing-console spec §2.1 / §4.1 (R0).
|
|
4
|
+
*
|
|
5
|
+
* One `callId` is minted per `rig.run` / `runStream` / `runBundle` / `runRaw`
|
|
6
|
+
* invocation and shared by EVERY telemetry row that call writes (primary, retry,
|
|
7
|
+
* repair, grounding-search, tool-call). `attemptSeq` is a 1-based counter that
|
|
8
|
+
* is monotonic across all of those rows, and `candidateIndex` is the position of
|
|
9
|
+
* the candidate the row is about within the call's effective declared list.
|
|
10
|
+
*
|
|
11
|
+
* The minter owns the seq counter and the current candidate index so the run
|
|
12
|
+
* loop does not have to thread them through every `recordAttempt` call site
|
|
13
|
+
* (run.ts sits at its LOC cap). The loop calls `setCandidateIndex` as the
|
|
14
|
+
* candidate iterator advances; the recorder (and the search-cost recorder) call
|
|
15
|
+
* `stamp()` once per row. A repair row is stamped DURING the current candidate's
|
|
16
|
+
* turn — before the iterator advances — so it inherits that candidate's index,
|
|
17
|
+
* which IS "the candidate being repaired" per spec §2.1.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.createLadderKeyMinter = createLadderKeyMinter;
|
|
21
|
+
const node_crypto_1 = require("node:crypto");
|
|
22
|
+
/**
|
|
23
|
+
* Build a ladder-key minter. `callId` defaults to a fresh uuid; the raw lane and
|
|
24
|
+
* tests may pass one in. Pure but for the uuid — no I/O, no shared state.
|
|
25
|
+
*/
|
|
26
|
+
function createLadderKeyMinter(callId = (0, node_crypto_1.randomUUID)()) {
|
|
27
|
+
let attemptSeq = 0;
|
|
28
|
+
let candidateIndex = null;
|
|
29
|
+
return {
|
|
30
|
+
callId,
|
|
31
|
+
setCandidateIndex(index) {
|
|
32
|
+
candidateIndex = index;
|
|
33
|
+
},
|
|
34
|
+
stamp() {
|
|
35
|
+
attemptSeq += 1;
|
|
36
|
+
return { callId, attemptSeq, candidateIndex };
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw-lane defaults (#245, spec R1–R3) — the SINGLE source of truth for what
|
|
3
|
+
* `rig.runRaw` sends when the caller omits a knob, and the generator behind the
|
|
4
|
+
* published defaults table.
|
|
5
|
+
*
|
|
6
|
+
* WHY ITS OWN FILE: `raw.ts` sits near the 700-LOC invariant cap, and this table
|
|
7
|
+
* is the CE-9/`raw-support.ts` pattern — a code constant the runtime reads AND
|
|
8
|
+
* the docs generator renders, so the published table can never drift from the
|
|
9
|
+
* behaviour. `raw.ts` imports `RAW_TIMEOUT_DEFAULT_MS` and resolves the effective
|
|
10
|
+
* timeout from it; the docs builder injects `renderRawDefaults()` at the
|
|
11
|
+
* `<!-- RAW_DEFAULTS -->` marker in `route-bundles.md` and into llms.txt. The
|
|
12
|
+
* drift test asserts the rendered `timeoutMs` default is read from THIS constant
|
|
13
|
+
* (never retyped), so the table and the dispatch agree by construction.
|
|
14
|
+
*/
|
|
15
|
+
import type { ServiceTier } from "../types/provider";
|
|
16
|
+
/**
|
|
17
|
+
* R1 — the tier-aware raw-lane timeout default (ms). A raw passthrough should not
|
|
18
|
+
* be shorter-fused than the tier it advertises: `standard`/`priority` target up
|
|
19
|
+
* to 5 min (grounded + large prompts routinely exceed the old 120 s even at
|
|
20
|
+
* standard), `flex` targets the 15-minute budget ModelRig advertises. An explicit
|
|
21
|
+
* `RawRunInput.timeoutMs` always wins; this is only the fallback, and a `timeout`
|
|
22
|
+
* failure on the raw lane teaches the tier + budget in its `fixHint`.
|
|
23
|
+
*/
|
|
24
|
+
export declare const RAW_TIMEOUT_DEFAULT_MS: Record<ServiceTier, number>;
|
|
25
|
+
/** One row of the generated defaults table (R2/R3). */
|
|
26
|
+
export interface RawDefaultRow {
|
|
27
|
+
/** The `RawRunInput` field this row documents. */
|
|
28
|
+
readonly knob: string;
|
|
29
|
+
/** The value sent when the caller omits the knob — DERIVED from the constant
|
|
30
|
+
* the runtime uses where one exists (timeoutMs), so it cannot drift. */
|
|
31
|
+
readonly default: string;
|
|
32
|
+
/** The teaching note rendered in the table cell. */
|
|
33
|
+
readonly note: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The defaults table (R2/R3) — every behavioural `RawRunInput` knob and what the
|
|
37
|
+
* raw lane does when the caller omits it. `provider`/`model`/`apiKey`/
|
|
38
|
+
* `systemPrompt`/`userPrompt` are the call itself, not defaultable knobs, so they
|
|
39
|
+
* are not listed. Exhaustive over the optional knobs the raw lane exposes; a new
|
|
40
|
+
* knob added to `RawRunInput` should gain a row here (and the `route-bundles`
|
|
41
|
+
* coverage test guards the important ones).
|
|
42
|
+
*/
|
|
43
|
+
export declare const RAW_DEFAULTS: readonly RawDefaultRow[];
|
|
44
|
+
/**
|
|
45
|
+
* Render the defaults table as a Markdown table, FROM `RAW_DEFAULTS` (never a
|
|
46
|
+
* hand-written twin — R2/R3). Consumed by the docs generator
|
|
47
|
+
* (scripts/build-docs-site.ts) at the `<!-- RAW_DEFAULTS -->` marker and in
|
|
48
|
+
* llms.txt, so the published table and the runtime defaults derive from one
|
|
49
|
+
* source.
|
|
50
|
+
*/
|
|
51
|
+
export declare function renderRawDefaults(): string;
|
|
52
|
+
//# sourceMappingURL=raw-defaults.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-defaults.d.ts","sourceRoot":"","sources":["../../src/run/raw-defaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAI9D,CAAC;AAEF,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;4EACwE;IACxE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAeD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,aAAa,EA6DhD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAK1C"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Raw-lane defaults (#245, spec R1–R3) — the SINGLE source of truth for what
|
|
4
|
+
* `rig.runRaw` sends when the caller omits a knob, and the generator behind the
|
|
5
|
+
* published defaults table.
|
|
6
|
+
*
|
|
7
|
+
* WHY ITS OWN FILE: `raw.ts` sits near the 700-LOC invariant cap, and this table
|
|
8
|
+
* is the CE-9/`raw-support.ts` pattern — a code constant the runtime reads AND
|
|
9
|
+
* the docs generator renders, so the published table can never drift from the
|
|
10
|
+
* behaviour. `raw.ts` imports `RAW_TIMEOUT_DEFAULT_MS` and resolves the effective
|
|
11
|
+
* timeout from it; the docs builder injects `renderRawDefaults()` at the
|
|
12
|
+
* `<!-- RAW_DEFAULTS -->` marker in `route-bundles.md` and into llms.txt. The
|
|
13
|
+
* drift test asserts the rendered `timeoutMs` default is read from THIS constant
|
|
14
|
+
* (never retyped), so the table and the dispatch agree by construction.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.RAW_DEFAULTS = exports.RAW_TIMEOUT_DEFAULT_MS = void 0;
|
|
18
|
+
exports.renderRawDefaults = renderRawDefaults;
|
|
19
|
+
/**
|
|
20
|
+
* R1 — the tier-aware raw-lane timeout default (ms). A raw passthrough should not
|
|
21
|
+
* be shorter-fused than the tier it advertises: `standard`/`priority` target up
|
|
22
|
+
* to 5 min (grounded + large prompts routinely exceed the old 120 s even at
|
|
23
|
+
* standard), `flex` targets the 15-minute budget ModelRig advertises. An explicit
|
|
24
|
+
* `RawRunInput.timeoutMs` always wins; this is only the fallback, and a `timeout`
|
|
25
|
+
* failure on the raw lane teaches the tier + budget in its `fixHint`.
|
|
26
|
+
*/
|
|
27
|
+
exports.RAW_TIMEOUT_DEFAULT_MS = {
|
|
28
|
+
standard: 300000,
|
|
29
|
+
priority: 300000,
|
|
30
|
+
flex: 900000,
|
|
31
|
+
};
|
|
32
|
+
/** Render `${ms} ms` as whole seconds (both defaults are whole-second values). */
|
|
33
|
+
function secs(ms) {
|
|
34
|
+
return `${ms / 1000} s`;
|
|
35
|
+
}
|
|
36
|
+
/** The tier-aware `timeoutMs` default, rendered FROM `RAW_TIMEOUT_DEFAULT_MS`
|
|
37
|
+
* (never a retyped literal — the drift test locks this to the constant). */
|
|
38
|
+
function timeoutDefaultCell() {
|
|
39
|
+
return `${secs(exports.RAW_TIMEOUT_DEFAULT_MS.standard)} (standard, priority) · ${secs(exports.RAW_TIMEOUT_DEFAULT_MS.flex)} (flex)`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The defaults table (R2/R3) — every behavioural `RawRunInput` knob and what the
|
|
43
|
+
* raw lane does when the caller omits it. `provider`/`model`/`apiKey`/
|
|
44
|
+
* `systemPrompt`/`userPrompt` are the call itself, not defaultable knobs, so they
|
|
45
|
+
* are not listed. Exhaustive over the optional knobs the raw lane exposes; a new
|
|
46
|
+
* knob added to `RawRunInput` should gain a row here (and the `route-bundles`
|
|
47
|
+
* coverage test guards the important ones).
|
|
48
|
+
*/
|
|
49
|
+
exports.RAW_DEFAULTS = [
|
|
50
|
+
{
|
|
51
|
+
knob: "timeoutMs",
|
|
52
|
+
default: timeoutDefaultCell(),
|
|
53
|
+
note: "tier-aware wall-clock deadline; an explicit `timeoutMs` always wins, and a `timeout` failure carries a `fixHint` naming the tier + budget",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
knob: "serviceTier",
|
|
57
|
+
default: "standard",
|
|
58
|
+
note: "forwarded to the adapter; `meta.servedTier` reports what actually served. On `flex`, set `timeoutMs` in minutes (default 900 s)",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
knob: "temperature",
|
|
62
|
+
default: "adapter default — not sent",
|
|
63
|
+
note: "absent ⇒ no `temperature` on the request (byte-identical dispatch)",
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
knob: "topP",
|
|
67
|
+
default: "adapter default — not sent",
|
|
68
|
+
note: "absent ⇒ no `topP` on the request (byte-identical dispatch)",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
knob: "maxOutputTokens",
|
|
72
|
+
default: "adapter default — not sent",
|
|
73
|
+
note: "absent ⇒ no output-token cap on the request (byte-identical dispatch)",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
knob: "grounding",
|
|
77
|
+
default: "absent ⇒ byte-identical",
|
|
78
|
+
note: "native provider grounding; provider support per the raw-lane knob matrix",
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
knob: "reasoning",
|
|
82
|
+
default: "absent ⇒ byte-identical",
|
|
83
|
+
note: "reasoning/thinking effort; provider support per the raw-lane knob matrix",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
knob: "responseFormat",
|
|
87
|
+
default: "absent ⇒ byte-identical",
|
|
88
|
+
note: "syntactic-JSON forcing (mime-shaping only); provider support per the raw-lane knob matrix",
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
knob: "cache",
|
|
92
|
+
default: "none",
|
|
93
|
+
note: "customer cache handle passed through verbatim when supplied; ModelRig never creates, refreshes, or deletes the resource",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
knob: "tags",
|
|
97
|
+
default: "none",
|
|
98
|
+
note: "`lane=raw` and `rung=primary` are stamped by the SDK and cannot be overridden by a caller tag",
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
knob: "tools / toolChoice",
|
|
102
|
+
default: "none",
|
|
103
|
+
note: "absent ⇒ no tools declared; on the raw lane a grounding-originated `functionCall` part is NOT a tool-call turn",
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
knob: "stepKey",
|
|
107
|
+
default: "auto — `tags.step`, else `<provider>/<model>#<n>` inside a run context",
|
|
108
|
+
note: "names the ground-truth step a run context records for this call (G1); explicit key wins; no run context ⇒ no step",
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
/**
|
|
112
|
+
* Render the defaults table as a Markdown table, FROM `RAW_DEFAULTS` (never a
|
|
113
|
+
* hand-written twin — R2/R3). Consumed by the docs generator
|
|
114
|
+
* (scripts/build-docs-site.ts) at the `<!-- RAW_DEFAULTS -->` marker and in
|
|
115
|
+
* llms.txt, so the published table and the runtime defaults derive from one
|
|
116
|
+
* source.
|
|
117
|
+
*/
|
|
118
|
+
function renderRawDefaults() {
|
|
119
|
+
const header = "| Knob | Default | Note |";
|
|
120
|
+
const sep = "|---|---|---|";
|
|
121
|
+
const rows = exports.RAW_DEFAULTS.map((r) => `| \`${r.knob}\` | ${r.default} | ${r.note} |`);
|
|
122
|
+
return [header, sep, ...rows].join("\n");
|
|
123
|
+
}
|