create-quorum-router 0.1.15 → 0.1.17
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
|
@@ -18,7 +18,7 @@ deno task intake
|
|
|
18
18
|
deno task supabase:status
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Current package version: `create-quorum-router@0.1.
|
|
21
|
+
Current package version: `create-quorum-router@0.1.17`. Releases are published
|
|
22
22
|
from an immutable Git tag through GitHub Actions OIDC Trusted Publishing.
|
|
23
23
|
|
|
24
24
|
## What the generated project supports
|
|
@@ -39,6 +39,12 @@ execution. Both demos are local-only; the hierarchy demo does not call provider
|
|
|
39
39
|
APIs. On a new Deno installation, the first run resolves the pinned Zod
|
|
40
40
|
dependency before execution.
|
|
41
41
|
|
|
42
|
+
Generated projects also export the opt-in
|
|
43
|
+
`resolveHierarchicalTaskCalibrationWithDriftGuard()` API. It can quarantine a
|
|
44
|
+
child whose Brier score is worse than its immediate parent by more than an
|
|
45
|
+
explicit caller threshold. This is outcome-metric drift handling, not semantic
|
|
46
|
+
label verification; it does not rename labels or affect routing authority.
|
|
47
|
+
|
|
42
48
|
`deno task intake` is the first real setup command. It detects local provider
|
|
43
49
|
wrappers, checks OAuth/session status, runs safe list-only model inventory where
|
|
44
50
|
possible, writes redacted local health artifacts under `out/`, and recommends
|
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.17.
|
|
5
5
|
|
|
6
6
|
QuorumRouter is **MIT**. It is **open source**. Commercial and production use
|
|
7
7
|
are permitted under the MIT License.
|
|
@@ -67,6 +67,13 @@ group that reaches the configured sample threshold. Groups never cross exact
|
|
|
67
67
|
provider/model source boundaries, labels must not contain raw prompts, and the
|
|
68
68
|
result remains advisory-only.
|
|
69
69
|
|
|
70
|
+
The scaffold also exports opt-in
|
|
71
|
+
`resolveHierarchicalTaskCalibrationWithDriftGuard()`. It can quarantine a child
|
|
72
|
+
whose Brier score is worse than its immediate parent by more than an explicit
|
|
73
|
+
caller threshold and continue parent fallback. This is an outcome-metric
|
|
74
|
+
heuristic, not semantic label verification; it does not rename labels or affect
|
|
75
|
+
routing authority.
|
|
76
|
+
|
|
70
77
|
`intake` detects local provider wrappers, checks OAuth/session status, runs safe
|
|
71
78
|
model inventory/list-only probes where possible, writes local health traces
|
|
72
79
|
under `out/`, and recommends the next command.
|
|
@@ -8,6 +8,14 @@ function stableMetric(value: number): number {
|
|
|
8
8
|
return rounded === 0 ? 0 : rounded;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
function isCanonicalBinaryAccuracy(
|
|
12
|
+
sampleCount: number,
|
|
13
|
+
accuracy: number,
|
|
14
|
+
): boolean {
|
|
15
|
+
const correctCount = Math.round(accuracy * sampleCount);
|
|
16
|
+
return accuracy === stableMetric(correctCount / sampleCount);
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
function boundedCanonicalText(maxLength: number) {
|
|
12
20
|
return z.string().trim().transform((value) => value.normalize("NFC")).pipe(
|
|
13
21
|
z.string().min(1).max(maxLength).refine(
|
|
@@ -254,6 +262,7 @@ export function aggregateTaskCalibration(
|
|
|
254
262
|
|
|
255
263
|
export const MAX_HIERARCHICAL_CALIBRATION_GROUPS =
|
|
256
264
|
MAX_CALIBRATION_OBSERVATIONS * 3;
|
|
265
|
+
const HIERARCHICAL_ROLLUP_TOLERANCE = 1e-9;
|
|
257
266
|
|
|
258
267
|
export const HierarchicalCalibrationScopeSchema = z.enum([
|
|
259
268
|
"task_type",
|
|
@@ -488,6 +497,344 @@ export const HierarchicalTaskCalibrationSelectionSchema = z.object({
|
|
|
488
497
|
}
|
|
489
498
|
});
|
|
490
499
|
|
|
500
|
+
export const HierarchicalCalibrationDriftGuardOptionsSchema = z.object({
|
|
501
|
+
maximum_child_parent_brier_score_delta: z.number().finite().min(0).max(1),
|
|
502
|
+
}).strict();
|
|
503
|
+
|
|
504
|
+
export const HierarchicalTaskCalibrationGuardedReportSchema =
|
|
505
|
+
HierarchicalTaskCalibrationReportSchema.superRefine((report, context) => {
|
|
506
|
+
report.groups.forEach((parent, parentIndex) => {
|
|
507
|
+
if (!isCanonicalBinaryAccuracy(parent.sample_count, parent.accuracy)) {
|
|
508
|
+
context.addIssue({
|
|
509
|
+
code: "custom",
|
|
510
|
+
message:
|
|
511
|
+
"guarded accuracy must be the canonical ratio of integer correct observations",
|
|
512
|
+
path: ["groups", parentIndex, "accuracy"],
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
const childScope = parent.scope === "task_type"
|
|
517
|
+
? "task_subtype"
|
|
518
|
+
: parent.scope === "task_subtype"
|
|
519
|
+
? "prompt_pattern"
|
|
520
|
+
: undefined;
|
|
521
|
+
if (childScope === undefined) return;
|
|
522
|
+
|
|
523
|
+
const children = report.groups.filter((child) =>
|
|
524
|
+
child.scope === childScope && child.task_type === parent.task_type &&
|
|
525
|
+
child.source.provider === parent.source.provider &&
|
|
526
|
+
child.source.model === parent.source.model &&
|
|
527
|
+
(parent.scope === "task_type" ||
|
|
528
|
+
child.task_subtype === parent.task_subtype)
|
|
529
|
+
);
|
|
530
|
+
if (children.length === 0) return;
|
|
531
|
+
|
|
532
|
+
const childCount = children.reduce(
|
|
533
|
+
(sum, child) => sum + child.sample_count,
|
|
534
|
+
0,
|
|
535
|
+
);
|
|
536
|
+
const remainderCount = parent.sample_count - childCount;
|
|
537
|
+
if (remainderCount < 0) {
|
|
538
|
+
context.addIssue({
|
|
539
|
+
code: "custom",
|
|
540
|
+
message:
|
|
541
|
+
"hierarchical child sample counts cannot exceed their parent",
|
|
542
|
+
path: ["groups", parentIndex, "sample_count"],
|
|
543
|
+
});
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
for (
|
|
548
|
+
const metric of ["accuracy", "mean_confidence", "brier_score"] as const
|
|
549
|
+
) {
|
|
550
|
+
const parentTotal = parent[metric] * parent.sample_count;
|
|
551
|
+
const childTotal = children.reduce(
|
|
552
|
+
(sum, child) => sum + child[metric] * child.sample_count,
|
|
553
|
+
0,
|
|
554
|
+
);
|
|
555
|
+
const remainderTotal = parentTotal - childTotal;
|
|
556
|
+
if (
|
|
557
|
+
remainderTotal < -HIERARCHICAL_ROLLUP_TOLERANCE ||
|
|
558
|
+
remainderTotal > remainderCount + HIERARCHICAL_ROLLUP_TOLERANCE
|
|
559
|
+
) {
|
|
560
|
+
context.addIssue({
|
|
561
|
+
code: "custom",
|
|
562
|
+
message:
|
|
563
|
+
`hierarchical ${metric} totals are incompatible with the parent roll-up`,
|
|
564
|
+
path: ["groups", parentIndex, metric],
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
export const HierarchicalCalibrationDriftStatusSchema = z.enum([
|
|
572
|
+
"not_applicable",
|
|
573
|
+
"not_evaluated",
|
|
574
|
+
"parent_unavailable",
|
|
575
|
+
"within_threshold",
|
|
576
|
+
"quarantined",
|
|
577
|
+
]);
|
|
578
|
+
|
|
579
|
+
const HierarchicalGuardedCalibrationCandidateSchema = z.object({
|
|
580
|
+
scope: HierarchicalCalibrationScopeSchema,
|
|
581
|
+
sample_count: z.number().int().positive().max(MAX_CALIBRATION_OBSERVATIONS)
|
|
582
|
+
.nullable(),
|
|
583
|
+
sample_status: z.enum(["missing", "insufficient", "sufficient"]),
|
|
584
|
+
accuracy: z.number().finite().min(0).max(1).nullable(),
|
|
585
|
+
mean_confidence: z.number().finite().min(0).max(1).nullable(),
|
|
586
|
+
mean_calibration_bias: z.number().finite().min(-1).max(1).nullable(),
|
|
587
|
+
brier_score: z.number().finite().min(0).max(1).nullable(),
|
|
588
|
+
drift_status: HierarchicalCalibrationDriftStatusSchema,
|
|
589
|
+
parent_scope: HierarchicalCalibrationScopeSchema.nullable(),
|
|
590
|
+
child_parent_brier_score_delta: z.number().finite().min(-1).max(1).nullable(),
|
|
591
|
+
}).strict().superRefine((candidate, context) => {
|
|
592
|
+
const metrics = [
|
|
593
|
+
candidate.accuracy,
|
|
594
|
+
candidate.mean_confidence,
|
|
595
|
+
candidate.mean_calibration_bias,
|
|
596
|
+
candidate.brier_score,
|
|
597
|
+
];
|
|
598
|
+
if (
|
|
599
|
+
(candidate.sample_status === "missing") !==
|
|
600
|
+
(candidate.sample_count === null)
|
|
601
|
+
) {
|
|
602
|
+
context.addIssue({
|
|
603
|
+
code: "custom",
|
|
604
|
+
message: "missing candidates must have a null sample_count",
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
if (
|
|
608
|
+
candidate.sample_status === "missing"
|
|
609
|
+
? metrics.some((metric) => metric !== null)
|
|
610
|
+
: metrics.some((metric) => metric === null)
|
|
611
|
+
) {
|
|
612
|
+
context.addIssue({
|
|
613
|
+
code: "custom",
|
|
614
|
+
message:
|
|
615
|
+
"candidate metrics must be null exactly when the candidate is missing",
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
if (
|
|
619
|
+
candidate.sample_count !== null && candidate.accuracy !== null &&
|
|
620
|
+
candidate.mean_confidence !== null &&
|
|
621
|
+
candidate.mean_calibration_bias !== null
|
|
622
|
+
) {
|
|
623
|
+
if (
|
|
624
|
+
candidate.mean_calibration_bias !==
|
|
625
|
+
stableMetric(candidate.mean_confidence - candidate.accuracy)
|
|
626
|
+
) {
|
|
627
|
+
context.addIssue({
|
|
628
|
+
code: "custom",
|
|
629
|
+
message:
|
|
630
|
+
"candidate mean_calibration_bias must equal mean_confidence - accuracy",
|
|
631
|
+
path: ["mean_calibration_bias"],
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
if (
|
|
635
|
+
!isCanonicalBinaryAccuracy(candidate.sample_count, candidate.accuracy)
|
|
636
|
+
) {
|
|
637
|
+
context.addIssue({
|
|
638
|
+
code: "custom",
|
|
639
|
+
message:
|
|
640
|
+
"candidate accuracy must be the canonical ratio of integer correct observations",
|
|
641
|
+
path: ["accuracy"],
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
export const HierarchicalTaskCalibrationGuardedSelectionSchema = z.object({
|
|
648
|
+
schema_version: z.literal(
|
|
649
|
+
"quorum-router.hierarchical-guarded-selection.v1",
|
|
650
|
+
),
|
|
651
|
+
advisory_only: z.literal(true),
|
|
652
|
+
query: HierarchicalTaskCalibrationQuerySchema,
|
|
653
|
+
requested_scope: HierarchicalCalibrationScopeSchema,
|
|
654
|
+
minimum_sample_count: z.number().int().positive().max(
|
|
655
|
+
MAX_CALIBRATION_OBSERVATIONS,
|
|
656
|
+
),
|
|
657
|
+
drift_guard: HierarchicalCalibrationDriftGuardOptionsSchema,
|
|
658
|
+
resolution_status: z.enum(["selected", "no_eligible_group"]),
|
|
659
|
+
selected_scope: HierarchicalCalibrationScopeSchema.nullable(),
|
|
660
|
+
candidates: z.array(HierarchicalGuardedCalibrationCandidateSchema).min(1)
|
|
661
|
+
.max(3),
|
|
662
|
+
selected_group: HierarchicalTaskCalibrationGroupSchema.optional(),
|
|
663
|
+
}).strict().superRefine((selection, context) => {
|
|
664
|
+
const queryScope = selection.query.prompt_pattern !== undefined
|
|
665
|
+
? "prompt_pattern"
|
|
666
|
+
: selection.query.task_subtype !== undefined
|
|
667
|
+
? "task_subtype"
|
|
668
|
+
: "task_type";
|
|
669
|
+
if (selection.requested_scope !== queryScope) {
|
|
670
|
+
context.addIssue({
|
|
671
|
+
code: "custom",
|
|
672
|
+
message: "requested_scope must match the query labels",
|
|
673
|
+
path: ["requested_scope"],
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
const expectedScopes: HierarchicalCalibrationScope[] =
|
|
678
|
+
selection.requested_scope === "prompt_pattern"
|
|
679
|
+
? ["prompt_pattern", "task_subtype", "task_type"]
|
|
680
|
+
: selection.requested_scope === "task_subtype"
|
|
681
|
+
? ["task_subtype", "task_type"]
|
|
682
|
+
: ["task_type"];
|
|
683
|
+
if (
|
|
684
|
+
JSON.stringify(selection.candidates.map((candidate) => candidate.scope)) !==
|
|
685
|
+
JSON.stringify(expectedScopes)
|
|
686
|
+
) {
|
|
687
|
+
context.addIssue({
|
|
688
|
+
code: "custom",
|
|
689
|
+
message: "candidates must follow the requested scope fallback order",
|
|
690
|
+
path: ["candidates"],
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
selection.candidates.forEach((candidate, index) => {
|
|
695
|
+
const expectedSampleStatus = candidate.sample_count === null
|
|
696
|
+
? "missing"
|
|
697
|
+
: candidate.sample_count < selection.minimum_sample_count
|
|
698
|
+
? "insufficient"
|
|
699
|
+
: "sufficient";
|
|
700
|
+
if (candidate.sample_status !== expectedSampleStatus) {
|
|
701
|
+
context.addIssue({
|
|
702
|
+
code: "custom",
|
|
703
|
+
message:
|
|
704
|
+
"candidate sample_status must match the configured sample threshold",
|
|
705
|
+
path: ["candidates", index, "sample_status"],
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
const isRoot = candidate.scope === "task_type";
|
|
709
|
+
const immediateParent = selection.candidates[index + 1];
|
|
710
|
+
if (isRoot) {
|
|
711
|
+
if (
|
|
712
|
+
candidate.drift_status !== "not_applicable" ||
|
|
713
|
+
candidate.parent_scope !== null ||
|
|
714
|
+
candidate.child_parent_brier_score_delta !== null
|
|
715
|
+
) {
|
|
716
|
+
context.addIssue({
|
|
717
|
+
code: "custom",
|
|
718
|
+
message: "task_type drift comparison must be not_applicable",
|
|
719
|
+
path: ["candidates", index],
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
if (candidate.parent_scope !== immediateParent?.scope) {
|
|
726
|
+
context.addIssue({
|
|
727
|
+
code: "custom",
|
|
728
|
+
message: "child candidates must name their immediate parent scope",
|
|
729
|
+
path: ["candidates", index, "parent_scope"],
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
if (candidate.sample_status !== "sufficient") {
|
|
733
|
+
if (
|
|
734
|
+
candidate.drift_status !== "not_evaluated" ||
|
|
735
|
+
candidate.child_parent_brier_score_delta !== null
|
|
736
|
+
) {
|
|
737
|
+
context.addIssue({
|
|
738
|
+
code: "custom",
|
|
739
|
+
message: "non-sufficient child drift must not be evaluated",
|
|
740
|
+
path: ["candidates", index],
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
if (immediateParent?.sample_status !== "sufficient") {
|
|
746
|
+
if (
|
|
747
|
+
candidate.drift_status !== "parent_unavailable" ||
|
|
748
|
+
candidate.child_parent_brier_score_delta !== null
|
|
749
|
+
) {
|
|
750
|
+
context.addIssue({
|
|
751
|
+
code: "custom",
|
|
752
|
+
message:
|
|
753
|
+
"a sufficient child without a sufficient parent is unavailable",
|
|
754
|
+
path: ["candidates", index],
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
const delta = candidate.child_parent_brier_score_delta;
|
|
761
|
+
if (
|
|
762
|
+
delta === null || candidate.brier_score === null ||
|
|
763
|
+
immediateParent.brier_score === null
|
|
764
|
+
) {
|
|
765
|
+
context.addIssue({
|
|
766
|
+
code: "custom",
|
|
767
|
+
message: "comparable child candidates require Brier score evidence",
|
|
768
|
+
path: ["candidates", index, "child_parent_brier_score_delta"],
|
|
769
|
+
});
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
const rawDelta = candidate.brier_score - immediateParent.brier_score;
|
|
773
|
+
if (delta !== stableMetric(rawDelta)) {
|
|
774
|
+
context.addIssue({
|
|
775
|
+
code: "custom",
|
|
776
|
+
message: "Brier score delta must match the candidate metric snapshots",
|
|
777
|
+
path: ["candidates", index, "child_parent_brier_score_delta"],
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
const expectedStatus = rawDelta >
|
|
781
|
+
selection.drift_guard.maximum_child_parent_brier_score_delta
|
|
782
|
+
? "quarantined"
|
|
783
|
+
: "within_threshold";
|
|
784
|
+
if (candidate.drift_status !== expectedStatus) {
|
|
785
|
+
context.addIssue({
|
|
786
|
+
code: "custom",
|
|
787
|
+
message: "drift_status must match the configured Brier score threshold",
|
|
788
|
+
path: ["candidates", index, "drift_status"],
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
const firstEligible = selection.candidates.find((candidate) =>
|
|
794
|
+
candidate.sample_status === "sufficient" &&
|
|
795
|
+
(candidate.drift_status === "within_threshold" ||
|
|
796
|
+
candidate.drift_status === "not_applicable")
|
|
797
|
+
);
|
|
798
|
+
if (firstEligible === undefined) {
|
|
799
|
+
if (
|
|
800
|
+
selection.resolution_status !== "no_eligible_group" ||
|
|
801
|
+
selection.selected_scope !== null ||
|
|
802
|
+
selection.selected_group !== undefined
|
|
803
|
+
) {
|
|
804
|
+
context.addIssue({
|
|
805
|
+
code: "custom",
|
|
806
|
+
message: "no eligible candidate must produce no selection",
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
} else if (
|
|
810
|
+
selection.resolution_status !== "selected" ||
|
|
811
|
+
selection.selected_scope !== firstEligible.scope ||
|
|
812
|
+
selection.selected_group?.scope !== firstEligible.scope ||
|
|
813
|
+
selection.selected_group.sample_count !== firstEligible.sample_count ||
|
|
814
|
+
selection.selected_group.sample_status !== "sufficient" ||
|
|
815
|
+
selection.selected_group.accuracy !== firstEligible.accuracy ||
|
|
816
|
+
selection.selected_group.mean_confidence !==
|
|
817
|
+
firstEligible.mean_confidence ||
|
|
818
|
+
selection.selected_group.mean_calibration_bias !==
|
|
819
|
+
firstEligible.mean_calibration_bias ||
|
|
820
|
+
selection.selected_group.brier_score !== firstEligible.brier_score ||
|
|
821
|
+
selection.selected_group.task_type !== selection.query.task_type ||
|
|
822
|
+
selection.selected_group.source.provider !==
|
|
823
|
+
selection.query.source.provider ||
|
|
824
|
+
selection.selected_group.source.model !== selection.query.source.model ||
|
|
825
|
+
(firstEligible.scope !== "task_type" &&
|
|
826
|
+
selection.selected_group.task_subtype !== selection.query.task_subtype) ||
|
|
827
|
+
(firstEligible.scope === "prompt_pattern" &&
|
|
828
|
+
selection.selected_group.prompt_pattern !==
|
|
829
|
+
selection.query.prompt_pattern)
|
|
830
|
+
) {
|
|
831
|
+
context.addIssue({
|
|
832
|
+
code: "custom",
|
|
833
|
+
message: "guarded selection must use the first eligible candidate",
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
|
|
491
838
|
export const HierarchicalTaskCalibrationDecisionSchema = z.object({
|
|
492
839
|
report: HierarchicalTaskCalibrationReportSchema,
|
|
493
840
|
selection: HierarchicalTaskCalibrationSelectionSchema,
|
|
@@ -540,6 +887,38 @@ export const HierarchicalTaskCalibrationDecisionSchema = z.object({
|
|
|
540
887
|
}
|
|
541
888
|
});
|
|
542
889
|
|
|
890
|
+
export const HierarchicalTaskCalibrationGuardedDecisionSchema = z.object({
|
|
891
|
+
report: HierarchicalTaskCalibrationGuardedReportSchema,
|
|
892
|
+
selection: HierarchicalTaskCalibrationGuardedSelectionSchema,
|
|
893
|
+
}).strict().superRefine((decision, context) => {
|
|
894
|
+
const parsedReport = HierarchicalTaskCalibrationGuardedReportSchema.safeParse(
|
|
895
|
+
decision.report,
|
|
896
|
+
);
|
|
897
|
+
const parsedSelection = HierarchicalTaskCalibrationGuardedSelectionSchema
|
|
898
|
+
.safeParse(
|
|
899
|
+
decision.selection,
|
|
900
|
+
);
|
|
901
|
+
if (!parsedReport.success || !parsedSelection.success) return;
|
|
902
|
+
|
|
903
|
+
const expected = resolveHierarchicalTaskCalibrationWithDriftGuard(
|
|
904
|
+
parsedReport.data,
|
|
905
|
+
parsedSelection.data.query,
|
|
906
|
+
parsedSelection.data.drift_guard,
|
|
907
|
+
);
|
|
908
|
+
if (JSON.stringify(parsedSelection.data) !== JSON.stringify(expected)) {
|
|
909
|
+
context.addIssue({
|
|
910
|
+
code: "custom",
|
|
911
|
+
message: "guarded selection must be derived from the aggregate report",
|
|
912
|
+
path: ["selection"],
|
|
913
|
+
});
|
|
914
|
+
}
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
export const HierarchicalTaskCalibrationAnyDecisionSchema = z.union([
|
|
918
|
+
HierarchicalTaskCalibrationDecisionSchema,
|
|
919
|
+
HierarchicalTaskCalibrationGuardedDecisionSchema,
|
|
920
|
+
]);
|
|
921
|
+
|
|
543
922
|
export type HierarchicalCalibrationScope = z.infer<
|
|
544
923
|
typeof HierarchicalCalibrationScopeSchema
|
|
545
924
|
>;
|
|
@@ -561,6 +940,18 @@ export type HierarchicalTaskCalibrationSelection = z.infer<
|
|
|
561
940
|
export type HierarchicalTaskCalibrationDecision = z.infer<
|
|
562
941
|
typeof HierarchicalTaskCalibrationDecisionSchema
|
|
563
942
|
>;
|
|
943
|
+
export type HierarchicalCalibrationDriftGuardOptions = z.infer<
|
|
944
|
+
typeof HierarchicalCalibrationDriftGuardOptionsSchema
|
|
945
|
+
>;
|
|
946
|
+
export type HierarchicalTaskCalibrationGuardedSelection = z.infer<
|
|
947
|
+
typeof HierarchicalTaskCalibrationGuardedSelectionSchema
|
|
948
|
+
>;
|
|
949
|
+
export type HierarchicalTaskCalibrationGuardedDecision = z.infer<
|
|
950
|
+
typeof HierarchicalTaskCalibrationGuardedDecisionSchema
|
|
951
|
+
>;
|
|
952
|
+
export type HierarchicalTaskCalibrationAnyDecision = z.infer<
|
|
953
|
+
typeof HierarchicalTaskCalibrationAnyDecisionSchema
|
|
954
|
+
>;
|
|
564
955
|
|
|
565
956
|
type HierarchicalGroupSeed = {
|
|
566
957
|
scope: HierarchicalCalibrationScope;
|
|
@@ -745,3 +1136,125 @@ export function resolveHierarchicalTaskCalibration(
|
|
|
745
1136
|
...(selected_group === undefined ? {} : { selected_group }),
|
|
746
1137
|
});
|
|
747
1138
|
}
|
|
1139
|
+
|
|
1140
|
+
export function resolveHierarchicalTaskCalibrationWithDriftGuard(
|
|
1141
|
+
report: HierarchicalTaskCalibrationReport,
|
|
1142
|
+
query: HierarchicalTaskCalibrationQuery,
|
|
1143
|
+
driftGuard: HierarchicalCalibrationDriftGuardOptions,
|
|
1144
|
+
): HierarchicalTaskCalibrationGuardedSelection {
|
|
1145
|
+
const parsedReport = HierarchicalTaskCalibrationGuardedReportSchema.parse(
|
|
1146
|
+
report,
|
|
1147
|
+
);
|
|
1148
|
+
const parsedQuery = HierarchicalTaskCalibrationQuerySchema.parse(query);
|
|
1149
|
+
const drift_guard = HierarchicalCalibrationDriftGuardOptionsSchema.parse(
|
|
1150
|
+
driftGuard,
|
|
1151
|
+
);
|
|
1152
|
+
const requested_scope: HierarchicalCalibrationScope =
|
|
1153
|
+
parsedQuery.prompt_pattern !== undefined
|
|
1154
|
+
? "prompt_pattern"
|
|
1155
|
+
: parsedQuery.task_subtype !== undefined
|
|
1156
|
+
? "task_subtype"
|
|
1157
|
+
: "task_type";
|
|
1158
|
+
const scopes: HierarchicalCalibrationScope[] = requested_scope ===
|
|
1159
|
+
"prompt_pattern"
|
|
1160
|
+
? ["prompt_pattern", "task_subtype", "task_type"]
|
|
1161
|
+
: requested_scope === "task_subtype"
|
|
1162
|
+
? ["task_subtype", "task_type"]
|
|
1163
|
+
: ["task_type"];
|
|
1164
|
+
|
|
1165
|
+
const matchingGroups = scopes.map((scope) =>
|
|
1166
|
+
parsedReport.groups.find((group) =>
|
|
1167
|
+
group.scope === scope && group.task_type === parsedQuery.task_type &&
|
|
1168
|
+
group.source.provider === parsedQuery.source.provider &&
|
|
1169
|
+
group.source.model === parsedQuery.source.model &&
|
|
1170
|
+
(scope === "task_type" ||
|
|
1171
|
+
group.task_subtype === parsedQuery.task_subtype) &&
|
|
1172
|
+
(scope !== "prompt_pattern" ||
|
|
1173
|
+
group.prompt_pattern === parsedQuery.prompt_pattern)
|
|
1174
|
+
)
|
|
1175
|
+
);
|
|
1176
|
+
const candidates = scopes.map((scope, index) => {
|
|
1177
|
+
const group = matchingGroups[index];
|
|
1178
|
+
const base = group === undefined
|
|
1179
|
+
? {
|
|
1180
|
+
scope,
|
|
1181
|
+
sample_count: null,
|
|
1182
|
+
sample_status: "missing" as const,
|
|
1183
|
+
accuracy: null,
|
|
1184
|
+
mean_confidence: null,
|
|
1185
|
+
mean_calibration_bias: null,
|
|
1186
|
+
brier_score: null,
|
|
1187
|
+
}
|
|
1188
|
+
: {
|
|
1189
|
+
scope,
|
|
1190
|
+
sample_count: group.sample_count,
|
|
1191
|
+
sample_status: group.sample_status,
|
|
1192
|
+
accuracy: group.accuracy,
|
|
1193
|
+
mean_confidence: group.mean_confidence,
|
|
1194
|
+
mean_calibration_bias: group.mean_calibration_bias,
|
|
1195
|
+
brier_score: group.brier_score,
|
|
1196
|
+
};
|
|
1197
|
+
if (scope === "task_type") {
|
|
1198
|
+
return {
|
|
1199
|
+
...base,
|
|
1200
|
+
drift_status: "not_applicable" as const,
|
|
1201
|
+
parent_scope: null,
|
|
1202
|
+
child_parent_brier_score_delta: null,
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
const parent_scope = scopes[index + 1] ?? null;
|
|
1207
|
+
if (group?.sample_status !== "sufficient") {
|
|
1208
|
+
return {
|
|
1209
|
+
...base,
|
|
1210
|
+
drift_status: "not_evaluated" as const,
|
|
1211
|
+
parent_scope,
|
|
1212
|
+
child_parent_brier_score_delta: null,
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
const parent = matchingGroups[index + 1];
|
|
1216
|
+
if (parent?.sample_status !== "sufficient") {
|
|
1217
|
+
return {
|
|
1218
|
+
...base,
|
|
1219
|
+
drift_status: "parent_unavailable" as const,
|
|
1220
|
+
parent_scope,
|
|
1221
|
+
child_parent_brier_score_delta: null,
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
const rawDelta = group.brier_score - parent.brier_score;
|
|
1226
|
+
const child_parent_brier_score_delta = stableMetric(rawDelta);
|
|
1227
|
+
return {
|
|
1228
|
+
...base,
|
|
1229
|
+
drift_status: rawDelta >
|
|
1230
|
+
drift_guard.maximum_child_parent_brier_score_delta
|
|
1231
|
+
? "quarantined" as const
|
|
1232
|
+
: "within_threshold" as const,
|
|
1233
|
+
parent_scope,
|
|
1234
|
+
child_parent_brier_score_delta,
|
|
1235
|
+
};
|
|
1236
|
+
});
|
|
1237
|
+
const selectedCandidate = candidates.find((candidate) =>
|
|
1238
|
+
candidate.sample_status === "sufficient" &&
|
|
1239
|
+
(candidate.drift_status === "within_threshold" ||
|
|
1240
|
+
candidate.drift_status === "not_applicable")
|
|
1241
|
+
);
|
|
1242
|
+
const selected_group = selectedCandidate === undefined
|
|
1243
|
+
? undefined
|
|
1244
|
+
: matchingGroups[candidates.indexOf(selectedCandidate)];
|
|
1245
|
+
|
|
1246
|
+
return HierarchicalTaskCalibrationGuardedSelectionSchema.parse({
|
|
1247
|
+
schema_version: "quorum-router.hierarchical-guarded-selection.v1",
|
|
1248
|
+
advisory_only: true,
|
|
1249
|
+
query: parsedQuery,
|
|
1250
|
+
requested_scope,
|
|
1251
|
+
minimum_sample_count: parsedReport.minimum_sample_count,
|
|
1252
|
+
drift_guard,
|
|
1253
|
+
resolution_status: selected_group === undefined
|
|
1254
|
+
? "no_eligible_group"
|
|
1255
|
+
: "selected",
|
|
1256
|
+
selected_scope: selected_group?.scope ?? null,
|
|
1257
|
+
candidates,
|
|
1258
|
+
...(selected_group === undefined ? {} : { selected_group }),
|
|
1259
|
+
});
|
|
1260
|
+
}
|