create-quorum-router 0.1.12 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -13,11 +13,12 @@ cd my-quorum-router-demo
|
|
|
13
13
|
deno --version
|
|
14
14
|
deno task smoke
|
|
15
15
|
deno task calibration:demo
|
|
16
|
+
deno task calibration:hierarchy-demo
|
|
16
17
|
deno task intake
|
|
17
18
|
deno task supabase:status
|
|
18
19
|
```
|
|
19
20
|
|
|
20
|
-
Current package version: `create-quorum-router@0.1.
|
|
21
|
+
Current package version: `create-quorum-router@0.1.15`. Releases are published
|
|
21
22
|
from an immutable Git tag through GitHub Actions OIDC Trusted Publishing.
|
|
22
23
|
|
|
23
24
|
## What the generated project supports
|
|
@@ -25,11 +26,18 @@ from an immutable Git tag through GitHub Actions OIDC Trusted Publishing.
|
|
|
25
26
|
`deno task smoke` is deterministic fixture-only and does not call a provider
|
|
26
27
|
API.
|
|
27
28
|
|
|
28
|
-
`deno task calibration:demo` runs the bundled calibration-by-task API
|
|
29
|
-
deterministic local observations.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
`deno task calibration:demo` runs the bundled flat calibration-by-task API
|
|
30
|
+
against deterministic local observations. `deno task calibration:hierarchy-demo`
|
|
31
|
+
runs three deterministic scenarios that select at the prompt-pattern level, then
|
|
32
|
+
fall back to task subtype, then task type as narrower sample buckets become
|
|
33
|
+
insufficient. Generated projects also export
|
|
34
|
+
`aggregateHierarchicalTaskCalibration()` and
|
|
35
|
+
`resolveHierarchicalTaskCalibration()` with
|
|
36
|
+
`prompt_pattern → task_subtype → task_type` sample-count fallback. Reports are
|
|
37
|
+
advisory-only and are not connected to routing weights, provider eligibility, or
|
|
38
|
+
execution. Both demos are local-only; the hierarchy demo does not call provider
|
|
39
|
+
APIs. On a new Deno installation, the first run resolves the pinned Zod
|
|
40
|
+
dependency before execution.
|
|
33
41
|
|
|
34
42
|
`deno task intake` is the first real setup command. It detects local provider
|
|
35
43
|
wrappers, checks OAuth/session status, runs safe list-only model inventory where
|
|
@@ -40,6 +48,7 @@ the next command.
|
|
|
40
48
|
deno task check
|
|
41
49
|
deno task smoke
|
|
42
50
|
deno task calibration:demo
|
|
51
|
+
deno task calibration:hierarchy-demo
|
|
43
52
|
deno task intake
|
|
44
53
|
deno task auth:status
|
|
45
54
|
deno task auth:login
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# QuorumRouter generated workspace
|
|
2
2
|
|
|
3
3
|
This generated workspace contains the MIT-licensed QuorumRouter current release.
|
|
4
|
-
npm latest targets v0.1.
|
|
4
|
+
npm latest targets v0.1.15.
|
|
5
5
|
|
|
6
6
|
QuorumRouter is **MIT**. It is **open source**. Commercial and production use
|
|
7
7
|
are permitted under the MIT License.
|
|
@@ -38,6 +38,7 @@ deno --version
|
|
|
38
38
|
```bash
|
|
39
39
|
deno task smoke
|
|
40
40
|
deno task calibration:demo
|
|
41
|
+
deno task calibration:hierarchy-demo
|
|
41
42
|
deno task intake
|
|
42
43
|
deno task auth:status
|
|
43
44
|
deno task models:list
|
|
@@ -48,11 +49,23 @@ deno task supabase:status
|
|
|
48
49
|
`smoke` proves the local scaffold runs with deterministic fixtures only. It does
|
|
49
50
|
**not** call a real provider API.
|
|
50
51
|
|
|
51
|
-
`calibration:demo` exercises the bundled calibration-by-task API with local
|
|
52
|
-
fixture observations.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
`calibration:demo` exercises the bundled flat calibration-by-task API with local
|
|
53
|
+
fixture observations. `calibration:hierarchy-demo` runs three deterministic
|
|
54
|
+
queries that select a sufficient prompt-pattern group, fall back to task
|
|
55
|
+
subtype, and fall back again to task type. Calibration reports are
|
|
56
|
+
advisory-only: the scaffold does not use them to change routing weights, ranks,
|
|
57
|
+
provider eligibility, quorum, or execution. Both demos are local-only; the
|
|
58
|
+
hierarchy demo does not call provider APIs. On a new Deno installation, the
|
|
59
|
+
first run resolves the pinned Zod dependency before execution.
|
|
60
|
+
|
|
61
|
+
The hierarchical demo uses `aggregateHierarchicalTaskCalibration()` and
|
|
62
|
+
`resolveHierarchicalTaskCalibration()` from `src/calibration.ts`. Its
|
|
63
|
+
observations use caller-defined categories such as `task_type: "code-review"`,
|
|
64
|
+
`task_subtype: "typescript"`, and `prompt_pattern: "schema-boundary-review"`.
|
|
65
|
+
Resolution checks `prompt_pattern → task_subtype → task_type`, using the first
|
|
66
|
+
group that reaches the configured sample threshold. Groups never cross exact
|
|
67
|
+
provider/model source boundaries, labels must not contain raw prompts, and the
|
|
68
|
+
result remains advisory-only.
|
|
56
69
|
|
|
57
70
|
`intake` detects local provider wrappers, checks OAuth/session status, runs safe
|
|
58
71
|
model inventory/list-only probes where possible, writes local health traces
|
|
@@ -228,8 +241,9 @@ not paste them into chat/logs and do not commit `.env`.
|
|
|
228
241
|
`src/provider_client.ts` — provider discovery and safe invocation.
|
|
229
242
|
- `src/best_route.ts`, `src/agent_chat.ts` — gated dogfood commands.
|
|
230
243
|
- `src/cost_aware.ts` — estimated-cost budget selection for Best Route.
|
|
231
|
-
- `src/calibration.ts`, `src/calibration_demo.ts` — strict
|
|
232
|
-
aggregation and an offline runnable
|
|
244
|
+
- `src/calibration.ts`, `src/calibration_demo.ts` — strict flat and hierarchical
|
|
245
|
+
advisory aggregation, parent fallback resolution, and an offline runnable
|
|
246
|
+
example.
|
|
233
247
|
- `src/trace.ts`, `src/redact.ts`, `src/schema.ts`, `src/fixture_smoke.ts` —
|
|
234
248
|
trace/redaction/schema/fixture support.
|
|
235
249
|
- `out/.gitkeep` — local output directory placeholder.
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
"check": "deno check main.ts src/*.ts",
|
|
8
8
|
"smoke": "deno run main.ts",
|
|
9
9
|
"calibration:demo": "deno run src/calibration_demo.ts",
|
|
10
|
+
"calibration:hierarchy-demo": "deno run src/hierarchical_calibration_demo.ts",
|
|
10
11
|
"intake": "deno run --allow-read --allow-write --allow-env --allow-net --allow-run=grok,codex,claude,gemini,devin src/cli.ts intake",
|
|
11
12
|
"auth:status": "deno run --allow-read --allow-env --allow-run=grok,codex,claude,gemini,devin src/cli.ts auth:status",
|
|
12
13
|
"auth:login": "deno run src/cli.ts auth:login",
|
|
@@ -28,6 +28,10 @@ const ObservationIdSchema = boundedCanonicalText(
|
|
|
28
28
|
MAX_CALIBRATION_IDENTIFIER_LENGTH,
|
|
29
29
|
);
|
|
30
30
|
const TaskTypeSchema = boundedCanonicalText(MAX_CALIBRATION_IDENTIFIER_LENGTH);
|
|
31
|
+
const HierarchicalTaxonomyLabelSchema = boundedCanonicalText(128).refine(
|
|
32
|
+
(value) => /^[a-z0-9](?:[a-z0-9._:/-]{0,126}[a-z0-9])?$/.test(value),
|
|
33
|
+
"hierarchical taxonomy labels must be lowercase canonical ASCII identifiers",
|
|
34
|
+
);
|
|
31
35
|
const SourceLabelSchema = boundedCanonicalText(
|
|
32
36
|
MAX_CALIBRATION_IDENTIFIER_LENGTH,
|
|
33
37
|
);
|
|
@@ -247,3 +251,497 @@ export function aggregateTaskCalibration(
|
|
|
247
251
|
groups,
|
|
248
252
|
});
|
|
249
253
|
}
|
|
254
|
+
|
|
255
|
+
export const MAX_HIERARCHICAL_CALIBRATION_GROUPS =
|
|
256
|
+
MAX_CALIBRATION_OBSERVATIONS * 3;
|
|
257
|
+
|
|
258
|
+
export const HierarchicalCalibrationScopeSchema = z.enum([
|
|
259
|
+
"task_type",
|
|
260
|
+
"task_subtype",
|
|
261
|
+
"prompt_pattern",
|
|
262
|
+
]);
|
|
263
|
+
|
|
264
|
+
export const HierarchicalTaskCalibrationObservationSchema = z.object({
|
|
265
|
+
observation_id: ObservationIdSchema,
|
|
266
|
+
task_type: TaskTypeSchema,
|
|
267
|
+
task_subtype: HierarchicalTaxonomyLabelSchema.optional(),
|
|
268
|
+
prompt_pattern: HierarchicalTaxonomyLabelSchema.optional(),
|
|
269
|
+
source: TaskCalibrationSourceSchema,
|
|
270
|
+
evaluation_basis: z.literal("caller_attested_external_ground_truth"),
|
|
271
|
+
correct: z.boolean(),
|
|
272
|
+
confidence: z.number().finite().min(0).max(1),
|
|
273
|
+
evaluated_at: EvaluationTimestampSchema,
|
|
274
|
+
}).strict().superRefine((observation, context) => {
|
|
275
|
+
if (
|
|
276
|
+
observation.prompt_pattern !== undefined &&
|
|
277
|
+
observation.task_subtype === undefined
|
|
278
|
+
) {
|
|
279
|
+
context.addIssue({
|
|
280
|
+
code: "custom",
|
|
281
|
+
message: "prompt_pattern requires task_subtype",
|
|
282
|
+
path: ["prompt_pattern"],
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
export const HierarchicalTaskCalibrationObservationListSchema = z.array(
|
|
288
|
+
HierarchicalTaskCalibrationObservationSchema,
|
|
289
|
+
).max(MAX_CALIBRATION_OBSERVATIONS).superRefine((observations, context) => {
|
|
290
|
+
const ids = new Set<string>();
|
|
291
|
+
for (const [index, observation] of observations.entries()) {
|
|
292
|
+
if (ids.has(observation.observation_id)) {
|
|
293
|
+
context.addIssue({
|
|
294
|
+
code: "custom",
|
|
295
|
+
message: "observation_id must be unique",
|
|
296
|
+
path: [index, "observation_id"],
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
ids.add(observation.observation_id);
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
export const HierarchicalTaskCalibrationGroupSchema = z.object({
|
|
304
|
+
scope: HierarchicalCalibrationScopeSchema,
|
|
305
|
+
task_type: TaskTypeSchema,
|
|
306
|
+
task_subtype: HierarchicalTaxonomyLabelSchema.optional(),
|
|
307
|
+
prompt_pattern: HierarchicalTaxonomyLabelSchema.optional(),
|
|
308
|
+
source: TaskCalibrationSourceSchema,
|
|
309
|
+
sample_count: z.number().int().positive().max(MAX_CALIBRATION_OBSERVATIONS),
|
|
310
|
+
accuracy: z.number().finite().min(0).max(1),
|
|
311
|
+
mean_confidence: z.number().finite().min(0).max(1),
|
|
312
|
+
brier_score: z.number().finite().min(0).max(1),
|
|
313
|
+
mean_calibration_bias: z.number().finite().min(-1).max(1),
|
|
314
|
+
sample_status: z.enum(["insufficient", "sufficient"]),
|
|
315
|
+
}).strict().superRefine((group, context) => {
|
|
316
|
+
const validLabels =
|
|
317
|
+
(group.scope === "task_type" && group.task_subtype === undefined &&
|
|
318
|
+
group.prompt_pattern === undefined) ||
|
|
319
|
+
(group.scope === "task_subtype" && group.task_subtype !== undefined &&
|
|
320
|
+
group.prompt_pattern === undefined) ||
|
|
321
|
+
(group.scope === "prompt_pattern" && group.task_subtype !== undefined &&
|
|
322
|
+
group.prompt_pattern !== undefined);
|
|
323
|
+
if (!validLabels) {
|
|
324
|
+
context.addIssue({
|
|
325
|
+
code: "custom",
|
|
326
|
+
message: "scope must match task_subtype and prompt_pattern labels",
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
export const HierarchicalTaskCalibrationReportSchema = z.object({
|
|
332
|
+
schema_version: z.literal("quorum-router.hierarchical-calibration.v1"),
|
|
333
|
+
advisory_only: z.literal(true),
|
|
334
|
+
minimum_sample_count: z.number().int().positive().max(
|
|
335
|
+
MAX_CALIBRATION_OBSERVATIONS,
|
|
336
|
+
),
|
|
337
|
+
groups: z.array(HierarchicalTaskCalibrationGroupSchema).max(
|
|
338
|
+
MAX_HIERARCHICAL_CALIBRATION_GROUPS,
|
|
339
|
+
),
|
|
340
|
+
}).strict().superRefine((report, context) => {
|
|
341
|
+
const groupKeys = new Set<string>();
|
|
342
|
+
for (const [index, group] of report.groups.entries()) {
|
|
343
|
+
const groupKey = JSON.stringify([
|
|
344
|
+
group.scope,
|
|
345
|
+
group.task_type,
|
|
346
|
+
group.task_subtype ?? null,
|
|
347
|
+
group.prompt_pattern ?? null,
|
|
348
|
+
group.source.provider,
|
|
349
|
+
group.source.model,
|
|
350
|
+
]);
|
|
351
|
+
if (groupKeys.has(groupKey)) {
|
|
352
|
+
context.addIssue({
|
|
353
|
+
code: "custom",
|
|
354
|
+
message: "hierarchical calibration report groups must be unique",
|
|
355
|
+
path: ["groups", index],
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
groupKeys.add(groupKey);
|
|
359
|
+
|
|
360
|
+
const expectedStatus = group.sample_count < report.minimum_sample_count
|
|
361
|
+
? "insufficient"
|
|
362
|
+
: "sufficient";
|
|
363
|
+
if (group.sample_status !== expectedStatus) {
|
|
364
|
+
context.addIssue({
|
|
365
|
+
code: "custom",
|
|
366
|
+
message: "sample_status must match the configured sample threshold",
|
|
367
|
+
path: ["groups", index, "sample_status"],
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
if (
|
|
371
|
+
group.mean_calibration_bias !==
|
|
372
|
+
stableMetric(group.mean_confidence - group.accuracy)
|
|
373
|
+
) {
|
|
374
|
+
context.addIssue({
|
|
375
|
+
code: "custom",
|
|
376
|
+
message: "mean_calibration_bias must equal mean_confidence - accuracy",
|
|
377
|
+
path: ["groups", index, "mean_calibration_bias"],
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
export const HierarchicalTaskCalibrationQuerySchema = z.object({
|
|
384
|
+
task_type: TaskTypeSchema,
|
|
385
|
+
task_subtype: HierarchicalTaxonomyLabelSchema.optional(),
|
|
386
|
+
prompt_pattern: HierarchicalTaxonomyLabelSchema.optional(),
|
|
387
|
+
source: TaskCalibrationSourceSchema,
|
|
388
|
+
}).strict().superRefine((query, context) => {
|
|
389
|
+
if (query.prompt_pattern !== undefined && query.task_subtype === undefined) {
|
|
390
|
+
context.addIssue({
|
|
391
|
+
code: "custom",
|
|
392
|
+
message: "prompt_pattern requires task_subtype",
|
|
393
|
+
path: ["prompt_pattern"],
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
const HierarchicalCalibrationCandidateSchema = z.object({
|
|
399
|
+
scope: HierarchicalCalibrationScopeSchema,
|
|
400
|
+
sample_count: z.number().int().positive().max(MAX_CALIBRATION_OBSERVATIONS)
|
|
401
|
+
.nullable(),
|
|
402
|
+
sample_status: z.enum(["missing", "insufficient", "sufficient"]),
|
|
403
|
+
}).strict().superRefine((candidate, context) => {
|
|
404
|
+
if (
|
|
405
|
+
(candidate.sample_status === "missing") !==
|
|
406
|
+
(candidate.sample_count === null)
|
|
407
|
+
) {
|
|
408
|
+
context.addIssue({
|
|
409
|
+
code: "custom",
|
|
410
|
+
message: "missing candidates must have a null sample_count",
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
export const HierarchicalTaskCalibrationSelectionSchema = z.object({
|
|
416
|
+
schema_version: z.literal("quorum-router.hierarchical-selection.v1"),
|
|
417
|
+
advisory_only: z.literal(true),
|
|
418
|
+
query: HierarchicalTaskCalibrationQuerySchema,
|
|
419
|
+
requested_scope: HierarchicalCalibrationScopeSchema,
|
|
420
|
+
resolution_status: z.enum(["selected", "no_sufficient_group"]),
|
|
421
|
+
selected_scope: HierarchicalCalibrationScopeSchema.nullable(),
|
|
422
|
+
candidates: z.array(HierarchicalCalibrationCandidateSchema).min(1).max(3),
|
|
423
|
+
selected_group: HierarchicalTaskCalibrationGroupSchema.optional(),
|
|
424
|
+
}).strict().superRefine((selection, context) => {
|
|
425
|
+
const queryScope = selection.query.prompt_pattern !== undefined
|
|
426
|
+
? "prompt_pattern"
|
|
427
|
+
: selection.query.task_subtype !== undefined
|
|
428
|
+
? "task_subtype"
|
|
429
|
+
: "task_type";
|
|
430
|
+
if (selection.requested_scope !== queryScope) {
|
|
431
|
+
context.addIssue({
|
|
432
|
+
code: "custom",
|
|
433
|
+
message: "requested_scope must match the query labels",
|
|
434
|
+
path: ["requested_scope"],
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const expectedScopes = selection.requested_scope === "prompt_pattern"
|
|
439
|
+
? ["prompt_pattern", "task_subtype", "task_type"]
|
|
440
|
+
: selection.requested_scope === "task_subtype"
|
|
441
|
+
? ["task_subtype", "task_type"]
|
|
442
|
+
: ["task_type"];
|
|
443
|
+
if (
|
|
444
|
+
JSON.stringify(selection.candidates.map((candidate) => candidate.scope)) !==
|
|
445
|
+
JSON.stringify(expectedScopes)
|
|
446
|
+
) {
|
|
447
|
+
context.addIssue({
|
|
448
|
+
code: "custom",
|
|
449
|
+
message: "candidates must follow the requested scope fallback order",
|
|
450
|
+
path: ["candidates"],
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
const firstSufficient = selection.candidates.find((candidate) =>
|
|
455
|
+
candidate.sample_status === "sufficient"
|
|
456
|
+
);
|
|
457
|
+
if (firstSufficient === undefined) {
|
|
458
|
+
if (
|
|
459
|
+
selection.resolution_status !== "no_sufficient_group" ||
|
|
460
|
+
selection.selected_scope !== null ||
|
|
461
|
+
selection.selected_group !== undefined
|
|
462
|
+
) {
|
|
463
|
+
context.addIssue({
|
|
464
|
+
code: "custom",
|
|
465
|
+
message: "no sufficient candidate must produce no selection",
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
} else if (
|
|
469
|
+
selection.resolution_status !== "selected" ||
|
|
470
|
+
selection.selected_scope !== firstSufficient.scope ||
|
|
471
|
+
selection.selected_group?.scope !== firstSufficient.scope ||
|
|
472
|
+
selection.selected_group.sample_count !== firstSufficient.sample_count ||
|
|
473
|
+
selection.selected_group.sample_status !== "sufficient" ||
|
|
474
|
+
selection.selected_group.task_type !== selection.query.task_type ||
|
|
475
|
+
selection.selected_group.source.provider !==
|
|
476
|
+
selection.query.source.provider ||
|
|
477
|
+
selection.selected_group.source.model !== selection.query.source.model ||
|
|
478
|
+
(firstSufficient.scope !== "task_type" &&
|
|
479
|
+
selection.selected_group.task_subtype !== selection.query.task_subtype) ||
|
|
480
|
+
(firstSufficient.scope === "prompt_pattern" &&
|
|
481
|
+
selection.selected_group.prompt_pattern !==
|
|
482
|
+
selection.query.prompt_pattern)
|
|
483
|
+
) {
|
|
484
|
+
context.addIssue({
|
|
485
|
+
code: "custom",
|
|
486
|
+
message: "selection must use the first sufficient candidate",
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
export const HierarchicalTaskCalibrationDecisionSchema = z.object({
|
|
492
|
+
report: HierarchicalTaskCalibrationReportSchema,
|
|
493
|
+
selection: HierarchicalTaskCalibrationSelectionSchema,
|
|
494
|
+
}).strict().superRefine((decision, context) => {
|
|
495
|
+
const { query } = decision.selection;
|
|
496
|
+
const expectedGroups = decision.selection.candidates.map((candidate) =>
|
|
497
|
+
decision.report.groups.find((group) =>
|
|
498
|
+
group.scope === candidate.scope && group.task_type === query.task_type &&
|
|
499
|
+
group.source.provider === query.source.provider &&
|
|
500
|
+
group.source.model === query.source.model &&
|
|
501
|
+
(candidate.scope === "task_type" ||
|
|
502
|
+
group.task_subtype === query.task_subtype) &&
|
|
503
|
+
(candidate.scope !== "prompt_pattern" ||
|
|
504
|
+
group.prompt_pattern === query.prompt_pattern)
|
|
505
|
+
)
|
|
506
|
+
);
|
|
507
|
+
|
|
508
|
+
decision.selection.candidates.forEach((candidate, index) => {
|
|
509
|
+
const group = expectedGroups[index];
|
|
510
|
+
const expected = group === undefined
|
|
511
|
+
? { sample_count: null, sample_status: "missing" }
|
|
512
|
+
: {
|
|
513
|
+
sample_count: group.sample_count,
|
|
514
|
+
sample_status: group.sample_status,
|
|
515
|
+
};
|
|
516
|
+
if (
|
|
517
|
+
candidate.sample_count !== expected.sample_count ||
|
|
518
|
+
candidate.sample_status !== expected.sample_status
|
|
519
|
+
) {
|
|
520
|
+
context.addIssue({
|
|
521
|
+
code: "custom",
|
|
522
|
+
message: "selection candidate must match the aggregate report",
|
|
523
|
+
path: ["selection", "candidates", index],
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
const expectedSelected = expectedGroups.find((group) =>
|
|
529
|
+
group?.sample_status === "sufficient"
|
|
530
|
+
);
|
|
531
|
+
if (
|
|
532
|
+
JSON.stringify(decision.selection.selected_group) !==
|
|
533
|
+
JSON.stringify(expectedSelected)
|
|
534
|
+
) {
|
|
535
|
+
context.addIssue({
|
|
536
|
+
code: "custom",
|
|
537
|
+
message: "selected_group must match the first sufficient report group",
|
|
538
|
+
path: ["selection", "selected_group"],
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
export type HierarchicalCalibrationScope = z.infer<
|
|
544
|
+
typeof HierarchicalCalibrationScopeSchema
|
|
545
|
+
>;
|
|
546
|
+
export type HierarchicalTaskCalibrationObservation = z.infer<
|
|
547
|
+
typeof HierarchicalTaskCalibrationObservationSchema
|
|
548
|
+
>;
|
|
549
|
+
export type HierarchicalTaskCalibrationGroup = z.infer<
|
|
550
|
+
typeof HierarchicalTaskCalibrationGroupSchema
|
|
551
|
+
>;
|
|
552
|
+
export type HierarchicalTaskCalibrationReport = z.infer<
|
|
553
|
+
typeof HierarchicalTaskCalibrationReportSchema
|
|
554
|
+
>;
|
|
555
|
+
export type HierarchicalTaskCalibrationQuery = z.infer<
|
|
556
|
+
typeof HierarchicalTaskCalibrationQuerySchema
|
|
557
|
+
>;
|
|
558
|
+
export type HierarchicalTaskCalibrationSelection = z.infer<
|
|
559
|
+
typeof HierarchicalTaskCalibrationSelectionSchema
|
|
560
|
+
>;
|
|
561
|
+
export type HierarchicalTaskCalibrationDecision = z.infer<
|
|
562
|
+
typeof HierarchicalTaskCalibrationDecisionSchema
|
|
563
|
+
>;
|
|
564
|
+
|
|
565
|
+
type HierarchicalGroupSeed = {
|
|
566
|
+
scope: HierarchicalCalibrationScope;
|
|
567
|
+
task_type: string;
|
|
568
|
+
task_subtype?: string;
|
|
569
|
+
prompt_pattern?: string;
|
|
570
|
+
source: TaskCalibrationSource;
|
|
571
|
+
observations: HierarchicalTaskCalibrationObservation[];
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
function summarizeHierarchicalGroup(
|
|
575
|
+
seed: HierarchicalGroupSeed,
|
|
576
|
+
minimumSampleCount: number,
|
|
577
|
+
): HierarchicalTaskCalibrationGroup {
|
|
578
|
+
const sample_count = seed.observations.length;
|
|
579
|
+
const correctCount = seed.observations.reduce(
|
|
580
|
+
(total, observation) => total + Number(observation.correct),
|
|
581
|
+
0,
|
|
582
|
+
);
|
|
583
|
+
const confidenceTotal = stableSum(
|
|
584
|
+
seed.observations.map((observation) => observation.confidence),
|
|
585
|
+
);
|
|
586
|
+
const brierTotal = stableSum(seed.observations.map((observation) => {
|
|
587
|
+
const outcome = Number(observation.correct);
|
|
588
|
+
return (observation.confidence - outcome) ** 2;
|
|
589
|
+
}));
|
|
590
|
+
const accuracy = stableMetric(correctCount / sample_count);
|
|
591
|
+
const mean_confidence = stableMetric(confidenceTotal / sample_count);
|
|
592
|
+
|
|
593
|
+
return HierarchicalTaskCalibrationGroupSchema.parse({
|
|
594
|
+
scope: seed.scope,
|
|
595
|
+
task_type: seed.task_type,
|
|
596
|
+
...(seed.task_subtype === undefined
|
|
597
|
+
? {}
|
|
598
|
+
: { task_subtype: seed.task_subtype }),
|
|
599
|
+
...(seed.prompt_pattern === undefined
|
|
600
|
+
? {}
|
|
601
|
+
: { prompt_pattern: seed.prompt_pattern }),
|
|
602
|
+
source: seed.source,
|
|
603
|
+
sample_count,
|
|
604
|
+
accuracy,
|
|
605
|
+
mean_confidence,
|
|
606
|
+
brier_score: stableMetric(brierTotal / sample_count),
|
|
607
|
+
mean_calibration_bias: stableMetric(mean_confidence - accuracy),
|
|
608
|
+
sample_status: sample_count < minimumSampleCount
|
|
609
|
+
? "insufficient"
|
|
610
|
+
: "sufficient",
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
export function aggregateHierarchicalTaskCalibration(
|
|
615
|
+
observations: readonly unknown[],
|
|
616
|
+
options: TaskCalibrationOptions = {},
|
|
617
|
+
): HierarchicalTaskCalibrationReport {
|
|
618
|
+
const parsed = HierarchicalTaskCalibrationObservationListSchema.parse(
|
|
619
|
+
observations,
|
|
620
|
+
);
|
|
621
|
+
const { minimum_sample_count } = TaskCalibrationOptionsSchema.parse(options);
|
|
622
|
+
const grouped = new Map<string, HierarchicalGroupSeed>();
|
|
623
|
+
|
|
624
|
+
function add(
|
|
625
|
+
observation: HierarchicalTaskCalibrationObservation,
|
|
626
|
+
scope: HierarchicalCalibrationScope,
|
|
627
|
+
) {
|
|
628
|
+
const task_subtype = scope === "task_type"
|
|
629
|
+
? undefined
|
|
630
|
+
: observation.task_subtype;
|
|
631
|
+
const prompt_pattern = scope === "prompt_pattern"
|
|
632
|
+
? observation.prompt_pattern
|
|
633
|
+
: undefined;
|
|
634
|
+
const key = JSON.stringify([
|
|
635
|
+
scope,
|
|
636
|
+
observation.task_type,
|
|
637
|
+
task_subtype ?? null,
|
|
638
|
+
prompt_pattern ?? null,
|
|
639
|
+
observation.source.provider,
|
|
640
|
+
observation.source.model,
|
|
641
|
+
]);
|
|
642
|
+
const existing = grouped.get(key);
|
|
643
|
+
if (existing) {
|
|
644
|
+
existing.observations.push(observation);
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
grouped.set(key, {
|
|
648
|
+
scope,
|
|
649
|
+
task_type: observation.task_type,
|
|
650
|
+
...(task_subtype === undefined ? {} : { task_subtype }),
|
|
651
|
+
...(prompt_pattern === undefined ? {} : { prompt_pattern }),
|
|
652
|
+
source: observation.source,
|
|
653
|
+
observations: [observation],
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
for (const observation of parsed) {
|
|
658
|
+
add(observation, "task_type");
|
|
659
|
+
if (observation.task_subtype !== undefined) {
|
|
660
|
+
add(observation, "task_subtype");
|
|
661
|
+
}
|
|
662
|
+
if (observation.prompt_pattern !== undefined) {
|
|
663
|
+
add(observation, "prompt_pattern");
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
const scopeOrder: Record<HierarchicalCalibrationScope, number> = {
|
|
668
|
+
task_type: 0,
|
|
669
|
+
task_subtype: 1,
|
|
670
|
+
prompt_pattern: 2,
|
|
671
|
+
};
|
|
672
|
+
const groups = [...grouped.values()].map((seed) =>
|
|
673
|
+
summarizeHierarchicalGroup(seed, minimum_sample_count)
|
|
674
|
+
).sort((left, right) =>
|
|
675
|
+
compareCodeUnits(left.task_type, right.task_type) ||
|
|
676
|
+
compareCodeUnits(left.source.provider, right.source.provider) ||
|
|
677
|
+
compareCodeUnits(left.source.model, right.source.model) ||
|
|
678
|
+
scopeOrder[left.scope] - scopeOrder[right.scope] ||
|
|
679
|
+
compareCodeUnits(left.task_subtype ?? "", right.task_subtype ?? "") ||
|
|
680
|
+
compareCodeUnits(left.prompt_pattern ?? "", right.prompt_pattern ?? "")
|
|
681
|
+
);
|
|
682
|
+
|
|
683
|
+
return HierarchicalTaskCalibrationReportSchema.parse({
|
|
684
|
+
schema_version: "quorum-router.hierarchical-calibration.v1",
|
|
685
|
+
advisory_only: true,
|
|
686
|
+
minimum_sample_count,
|
|
687
|
+
groups,
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
export function resolveHierarchicalTaskCalibration(
|
|
692
|
+
report: HierarchicalTaskCalibrationReport,
|
|
693
|
+
query: HierarchicalTaskCalibrationQuery,
|
|
694
|
+
): HierarchicalTaskCalibrationSelection {
|
|
695
|
+
const parsedReport = HierarchicalTaskCalibrationReportSchema.parse(report);
|
|
696
|
+
const parsedQuery = HierarchicalTaskCalibrationQuerySchema.parse(query);
|
|
697
|
+
const requested_scope: HierarchicalCalibrationScope =
|
|
698
|
+
parsedQuery.prompt_pattern !== undefined
|
|
699
|
+
? "prompt_pattern"
|
|
700
|
+
: parsedQuery.task_subtype !== undefined
|
|
701
|
+
? "task_subtype"
|
|
702
|
+
: "task_type";
|
|
703
|
+
const scopes: HierarchicalCalibrationScope[] = requested_scope ===
|
|
704
|
+
"prompt_pattern"
|
|
705
|
+
? ["prompt_pattern", "task_subtype", "task_type"]
|
|
706
|
+
: requested_scope === "task_subtype"
|
|
707
|
+
? ["task_subtype", "task_type"]
|
|
708
|
+
: ["task_type"];
|
|
709
|
+
|
|
710
|
+
const matchingGroups = scopes.map((scope) =>
|
|
711
|
+
parsedReport.groups.find((group) =>
|
|
712
|
+
group.scope === scope && group.task_type === parsedQuery.task_type &&
|
|
713
|
+
group.source.provider === parsedQuery.source.provider &&
|
|
714
|
+
group.source.model === parsedQuery.source.model &&
|
|
715
|
+
(scope === "task_type" ||
|
|
716
|
+
group.task_subtype === parsedQuery.task_subtype) &&
|
|
717
|
+
(scope !== "prompt_pattern" ||
|
|
718
|
+
group.prompt_pattern === parsedQuery.prompt_pattern)
|
|
719
|
+
)
|
|
720
|
+
);
|
|
721
|
+
const candidates = scopes.map((scope, index) => {
|
|
722
|
+
const group = matchingGroups[index];
|
|
723
|
+
return group === undefined
|
|
724
|
+
? { scope, sample_count: null, sample_status: "missing" as const }
|
|
725
|
+
: {
|
|
726
|
+
scope,
|
|
727
|
+
sample_count: group.sample_count,
|
|
728
|
+
sample_status: group.sample_status,
|
|
729
|
+
};
|
|
730
|
+
});
|
|
731
|
+
const selected_group = matchingGroups.find((group) =>
|
|
732
|
+
group?.sample_status === "sufficient"
|
|
733
|
+
);
|
|
734
|
+
|
|
735
|
+
return HierarchicalTaskCalibrationSelectionSchema.parse({
|
|
736
|
+
schema_version: "quorum-router.hierarchical-selection.v1",
|
|
737
|
+
advisory_only: true,
|
|
738
|
+
query: parsedQuery,
|
|
739
|
+
requested_scope,
|
|
740
|
+
resolution_status: selected_group === undefined
|
|
741
|
+
? "no_sufficient_group"
|
|
742
|
+
: "selected",
|
|
743
|
+
selected_scope: selected_group?.scope ?? null,
|
|
744
|
+
candidates,
|
|
745
|
+
...(selected_group === undefined ? {} : { selected_group }),
|
|
746
|
+
});
|
|
747
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import {
|
|
2
|
+
aggregateHierarchicalTaskCalibration,
|
|
3
|
+
resolveHierarchicalTaskCalibration,
|
|
4
|
+
} from "./calibration.ts";
|
|
5
|
+
|
|
6
|
+
const evaluated_at = "2026-07-14T00:00:00Z";
|
|
7
|
+
const source = { provider: "OpenAI", model: "example-model" } as const;
|
|
8
|
+
const observations = [
|
|
9
|
+
{
|
|
10
|
+
observation_id: "hierarchy-demo-pattern-1",
|
|
11
|
+
task_type: "code-review",
|
|
12
|
+
task_subtype: "typescript",
|
|
13
|
+
prompt_pattern: "schema-boundary-review",
|
|
14
|
+
source,
|
|
15
|
+
evaluation_basis: "caller_attested_external_ground_truth",
|
|
16
|
+
correct: true,
|
|
17
|
+
confidence: 0.9,
|
|
18
|
+
evaluated_at,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
observation_id: "hierarchy-demo-pattern-2",
|
|
22
|
+
task_type: "code-review",
|
|
23
|
+
task_subtype: "typescript",
|
|
24
|
+
prompt_pattern: "schema-boundary-review",
|
|
25
|
+
source,
|
|
26
|
+
evaluation_basis: "caller_attested_external_ground_truth",
|
|
27
|
+
correct: true,
|
|
28
|
+
confidence: 0.8,
|
|
29
|
+
evaluated_at,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
observation_id: "hierarchy-demo-pattern-3",
|
|
33
|
+
task_type: "code-review",
|
|
34
|
+
task_subtype: "typescript",
|
|
35
|
+
prompt_pattern: "schema-boundary-review",
|
|
36
|
+
source,
|
|
37
|
+
evaluation_basis: "caller_attested_external_ground_truth",
|
|
38
|
+
correct: false,
|
|
39
|
+
confidence: 0.7,
|
|
40
|
+
evaluated_at,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
observation_id: "hierarchy-demo-subtype-1",
|
|
44
|
+
task_type: "code-review",
|
|
45
|
+
task_subtype: "typescript",
|
|
46
|
+
prompt_pattern: "concurrency-review",
|
|
47
|
+
source,
|
|
48
|
+
evaluation_basis: "caller_attested_external_ground_truth",
|
|
49
|
+
correct: true,
|
|
50
|
+
confidence: 0.8,
|
|
51
|
+
evaluated_at,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
observation_id: "hierarchy-demo-parent-1",
|
|
55
|
+
task_type: "code-review",
|
|
56
|
+
task_subtype: "rust",
|
|
57
|
+
prompt_pattern: "unsafe-boundary-review",
|
|
58
|
+
source,
|
|
59
|
+
evaluation_basis: "caller_attested_external_ground_truth",
|
|
60
|
+
correct: true,
|
|
61
|
+
confidence: 0.7,
|
|
62
|
+
evaluated_at,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
observation_id: "hierarchy-demo-foreign-1",
|
|
66
|
+
task_type: "code-review",
|
|
67
|
+
task_subtype: "typescript",
|
|
68
|
+
prompt_pattern: "schema-boundary-review",
|
|
69
|
+
source: { provider: "Anthropic", model: "example-model" },
|
|
70
|
+
evaluation_basis: "caller_attested_external_ground_truth",
|
|
71
|
+
correct: true,
|
|
72
|
+
confidence: 0.75,
|
|
73
|
+
evaluated_at,
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
const report = aggregateHierarchicalTaskCalibration(observations, {
|
|
78
|
+
minimum_sample_count: 3,
|
|
79
|
+
});
|
|
80
|
+
const scenarios = [
|
|
81
|
+
{
|
|
82
|
+
name: "pattern-sufficient",
|
|
83
|
+
query: {
|
|
84
|
+
task_type: "code-review",
|
|
85
|
+
task_subtype: "typescript",
|
|
86
|
+
prompt_pattern: "schema-boundary-review",
|
|
87
|
+
source,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "fallback-to-subtype",
|
|
92
|
+
query: {
|
|
93
|
+
task_type: "code-review",
|
|
94
|
+
task_subtype: "typescript",
|
|
95
|
+
prompt_pattern: "concurrency-review",
|
|
96
|
+
source,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "fallback-to-task",
|
|
101
|
+
query: {
|
|
102
|
+
task_type: "code-review",
|
|
103
|
+
task_subtype: "rust",
|
|
104
|
+
prompt_pattern: "unsafe-boundary-review",
|
|
105
|
+
source,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
].map(({ name, query }) => {
|
|
109
|
+
const selection = resolveHierarchicalTaskCalibration(report, query);
|
|
110
|
+
return {
|
|
111
|
+
name,
|
|
112
|
+
query,
|
|
113
|
+
candidates: selection.candidates,
|
|
114
|
+
resolution_status: selection.resolution_status,
|
|
115
|
+
selected_scope: selection.selected_scope,
|
|
116
|
+
selected_sample_count: selection.selected_group?.sample_count ?? null,
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
console.log(JSON.stringify(
|
|
121
|
+
{
|
|
122
|
+
schema_version: "quorum-router.hierarchical-demo.v1",
|
|
123
|
+
advisory_only: true,
|
|
124
|
+
provider_request_sent: false,
|
|
125
|
+
fallback_order: ["prompt_pattern", "task_subtype", "task_type"],
|
|
126
|
+
minimum_sample_count: report.minimum_sample_count,
|
|
127
|
+
observation_count: observations.length,
|
|
128
|
+
scenarios,
|
|
129
|
+
},
|
|
130
|
+
null,
|
|
131
|
+
2,
|
|
132
|
+
));
|