@warmdrift/kgauto-compiler 2.0.0-alpha.39 → 2.0.0-alpha.41
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/dist/glassbox/index.d.mts +3 -3
- package/dist/glassbox/index.d.ts +3 -3
- package/dist/glassbox-routes/format.d.mts +2 -2
- package/dist/glassbox-routes/format.d.ts +2 -2
- package/dist/glassbox-routes/index.d.mts +4 -4
- package/dist/glassbox-routes/index.d.ts +4 -4
- package/dist/glassbox-routes/react/index.d.mts +2 -2
- package/dist/glassbox-routes/react/index.d.ts +2 -2
- package/dist/index.d.mts +234 -3
- package/dist/index.d.ts +234 -3
- package/dist/index.js +710 -138
- package/dist/index.mjs +706 -138
- package/dist/{ir-CZ9Ng96k.d.ts → ir-DYpvUSEw.d.ts} +32 -3
- package/dist/{ir-BiZSAVCJ.d.mts → ir-D_kgJcaV.d.mts} +32 -3
- package/dist/profiles.d.mts +28 -1
- package/dist/profiles.d.ts +28 -1
- package/dist/{types-HEl2tS4P.d.ts → types-C8gOJ7hV.d.ts} +1 -1
- package/dist/{types-kzYpX7wB.d.mts → types-CYY769Ls.d.mts} +1 -1
- package/dist/{types-CsFP-H-U.d.ts → types-DigtHnEt.d.ts} +1 -1
- package/dist/{types-f7idIVsm.d.mts → types-MkiWUPM8.d.mts} +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27,6 +27,7 @@ __export(index_exports, {
|
|
|
27
27
|
CallError: () => CallError,
|
|
28
28
|
DEFAULT_FINDINGS_ENDPOINT: () => DEFAULT_FINDINGS_ENDPOINT,
|
|
29
29
|
DIALECT_VERSION: () => DIALECT_VERSION,
|
|
30
|
+
FamilyResolutionError: () => FamilyResolutionError,
|
|
30
31
|
INTENT_ARCHETYPES: () => INTENT_ARCHETYPES,
|
|
31
32
|
MEASURED_GROUNDING_MIN_N: () => MEASURED_GROUNDING_MIN_N,
|
|
32
33
|
PROVIDER_ENV_KEYS: () => PROVIDER_ENV_KEYS,
|
|
@@ -44,6 +45,7 @@ __export(index_exports, {
|
|
|
44
45
|
compile: () => compile2,
|
|
45
46
|
configureBrain: () => configureBrain,
|
|
46
47
|
countTokens: () => countTokens,
|
|
48
|
+
deriveFamilyFromModelId: () => deriveFamilyFromModelId,
|
|
47
49
|
execute: () => execute,
|
|
48
50
|
getActionableAdvisories: () => getActionableAdvisories,
|
|
49
51
|
getAllStarterChains: () => getAllStarterChains,
|
|
@@ -55,6 +57,7 @@ __export(index_exports, {
|
|
|
55
57
|
getPerAxisMetrics: () => getPerAxisMetrics,
|
|
56
58
|
getProfile: () => getProfile,
|
|
57
59
|
getReachabilityDiagnostic: () => getReachabilityDiagnostic,
|
|
60
|
+
getRecommendedPrimary: () => getRecommendedPrimary,
|
|
58
61
|
getSequentialStarterChain: () => getSequentialStarterChain,
|
|
59
62
|
getSequentialStarterChainWithGrounding: () => getSequentialStarterChainWithGrounding,
|
|
60
63
|
getStaleExclusionFindings: () => getStaleExclusionFindings,
|
|
@@ -75,6 +78,7 @@ __export(index_exports, {
|
|
|
75
78
|
loadPricingFromBrain: () => loadPricingFromBrain,
|
|
76
79
|
markAdvisoryResolved: () => markAdvisoryResolved,
|
|
77
80
|
markExclusionFindingHandled: () => markExclusionFindingHandled,
|
|
81
|
+
markPromoteReadyHandled: () => markPromoteReadyHandled,
|
|
78
82
|
profileToRow: () => profileToRow,
|
|
79
83
|
profilesByProvider: () => profilesByProvider,
|
|
80
84
|
record: () => record,
|
|
@@ -463,7 +467,8 @@ function passScoreTargets(ir, opts) {
|
|
|
463
467
|
const preferredSet = new Set(policy.preferredModels ?? []);
|
|
464
468
|
const scores = [];
|
|
465
469
|
const policyMutations = [];
|
|
466
|
-
|
|
470
|
+
const modelIds = ir.models.filter((m) => typeof m === "string");
|
|
471
|
+
for (const modelId of modelIds) {
|
|
467
472
|
let profile;
|
|
468
473
|
try {
|
|
469
474
|
profile = opts.profilesById(modelId);
|
|
@@ -507,7 +512,7 @@ function passScoreTargets(ir, opts) {
|
|
|
507
512
|
}
|
|
508
513
|
const baseQuality = profile.strengths.includes("reasoning") ? 0.85 : profile.strengths.includes("quality") ? 0.8 : 0.6;
|
|
509
514
|
const qualityScore = Math.max(0, baseQuality - qualityPenalty);
|
|
510
|
-
const callerOrderBoost = (
|
|
515
|
+
const callerOrderBoost = (modelIds.length - modelIds.indexOf(modelId)) * 0.1;
|
|
511
516
|
const costPenalty = estimatedCostUsd * 5;
|
|
512
517
|
const preferredBoost = preferredSet.has(modelId) ? 0.5 : 0;
|
|
513
518
|
const rank = qualityScore + callerOrderBoost - costPenalty - reasons.length * 10 + preferredBoost;
|
|
@@ -2523,6 +2528,393 @@ function defaultOnError2(err) {
|
|
|
2523
2528
|
);
|
|
2524
2529
|
}
|
|
2525
2530
|
|
|
2531
|
+
// src/promote-ready-brain.ts
|
|
2532
|
+
function isRawPromoteReadyRow(x) {
|
|
2533
|
+
if (!x || typeof x !== "object") return false;
|
|
2534
|
+
const r = x;
|
|
2535
|
+
return typeof r.intent_archetype === "string" && typeof r.family === "string" && typeof r.candidate_model === "string" && typeof r.current_model === "string" && typeof r.detected_at === "string";
|
|
2536
|
+
}
|
|
2537
|
+
function coerceNumber(v) {
|
|
2538
|
+
if (typeof v === "number") return Number.isFinite(v) ? v : null;
|
|
2539
|
+
if (typeof v === "string") {
|
|
2540
|
+
const n = Number(v);
|
|
2541
|
+
return Number.isFinite(n) ? n : null;
|
|
2542
|
+
}
|
|
2543
|
+
return null;
|
|
2544
|
+
}
|
|
2545
|
+
function mapRowsToFindings2(rows) {
|
|
2546
|
+
const out = [];
|
|
2547
|
+
for (const row of rows) {
|
|
2548
|
+
if (!isRawPromoteReadyRow(row)) continue;
|
|
2549
|
+
const sampleN = coerceNumber(row.sample_n);
|
|
2550
|
+
const passRate = coerceNumber(row.judge_pass_rate);
|
|
2551
|
+
const avgScore = coerceNumber(row.judge_avg_score);
|
|
2552
|
+
if (sampleN === null || passRate === null || avgScore === null) continue;
|
|
2553
|
+
out.push({
|
|
2554
|
+
archetype: row.intent_archetype,
|
|
2555
|
+
family: row.family,
|
|
2556
|
+
candidateModel: row.candidate_model,
|
|
2557
|
+
currentModel: row.current_model,
|
|
2558
|
+
sampleN,
|
|
2559
|
+
judgePassRate: passRate,
|
|
2560
|
+
judgeAvgScore: avgScore,
|
|
2561
|
+
costDeltaPct: coerceNumber(row.cost_delta_pct),
|
|
2562
|
+
detectedAt: row.detected_at
|
|
2563
|
+
});
|
|
2564
|
+
}
|
|
2565
|
+
return out;
|
|
2566
|
+
}
|
|
2567
|
+
var snapshots2 = /* @__PURE__ */ new Map();
|
|
2568
|
+
var runtime3;
|
|
2569
|
+
var warnedOnce2 = false;
|
|
2570
|
+
function isPromoteReadyBrainActive() {
|
|
2571
|
+
return runtime3 !== void 0;
|
|
2572
|
+
}
|
|
2573
|
+
function loadPromoteReadyFindings(opts) {
|
|
2574
|
+
const rt = runtime3;
|
|
2575
|
+
if (!rt) return [];
|
|
2576
|
+
const appId = opts.appId;
|
|
2577
|
+
if (!appId) return [];
|
|
2578
|
+
let snap = snapshots2.get(appId);
|
|
2579
|
+
if (!snap) {
|
|
2580
|
+
snap = { data: [], expiresAt: 0, refreshing: false };
|
|
2581
|
+
snapshots2.set(appId, snap);
|
|
2582
|
+
}
|
|
2583
|
+
const now = Date.now();
|
|
2584
|
+
const stale = snap.expiresAt <= now;
|
|
2585
|
+
if (stale && !snap.refreshing) {
|
|
2586
|
+
snap.refreshing = true;
|
|
2587
|
+
void asyncRefresh3(rt, appId);
|
|
2588
|
+
}
|
|
2589
|
+
let rows = snap.data;
|
|
2590
|
+
if (opts.archetype) {
|
|
2591
|
+
rows = rows.filter((f) => f.archetype === opts.archetype);
|
|
2592
|
+
}
|
|
2593
|
+
if (opts.family) {
|
|
2594
|
+
rows = rows.filter((f) => f.family === opts.family);
|
|
2595
|
+
}
|
|
2596
|
+
return rows;
|
|
2597
|
+
}
|
|
2598
|
+
var pendingRefreshes2 = /* @__PURE__ */ new Map();
|
|
2599
|
+
async function asyncRefresh3(rt, appId) {
|
|
2600
|
+
const promise = doRefresh3(rt, appId);
|
|
2601
|
+
pendingRefreshes2.set(appId, promise);
|
|
2602
|
+
try {
|
|
2603
|
+
await promise;
|
|
2604
|
+
} finally {
|
|
2605
|
+
if (pendingRefreshes2.get(appId) === promise) {
|
|
2606
|
+
pendingRefreshes2.delete(appId);
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
}
|
|
2610
|
+
async function doRefresh3(rt, appId) {
|
|
2611
|
+
const url = `${rt.endpoint}?app_id=${encodeURIComponent(appId)}`;
|
|
2612
|
+
let snap = snapshots2.get(appId);
|
|
2613
|
+
if (!snap) {
|
|
2614
|
+
snap = { data: [], expiresAt: 0, refreshing: false };
|
|
2615
|
+
snapshots2.set(appId, snap);
|
|
2616
|
+
}
|
|
2617
|
+
try {
|
|
2618
|
+
const res = await rt.fetchImpl(url, { method: "GET" });
|
|
2619
|
+
if (!res.ok) {
|
|
2620
|
+
throw new Error(`promote-ready ${res.status}: ${res.statusText}`);
|
|
2621
|
+
}
|
|
2622
|
+
const body = await res.json();
|
|
2623
|
+
if (runtime3 !== rt) return;
|
|
2624
|
+
const rows = Array.isArray(body) ? mapRowsToFindings2(body) : [];
|
|
2625
|
+
snap.data = rows;
|
|
2626
|
+
snap.expiresAt = Date.now() + rt.ttlMs;
|
|
2627
|
+
snap.refreshing = false;
|
|
2628
|
+
} catch (err) {
|
|
2629
|
+
if (runtime3 !== rt) return;
|
|
2630
|
+
snap.refreshing = false;
|
|
2631
|
+
snap.expiresAt = Date.now() + rt.ttlMs;
|
|
2632
|
+
if (!warnedOnce2) {
|
|
2633
|
+
warnedOnce2 = true;
|
|
2634
|
+
(rt.onError ?? defaultOnError3)(err);
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
function defaultOnError3(err) {
|
|
2639
|
+
console.warn(
|
|
2640
|
+
"[kgauto] promote-ready fetch failed (using empty fallback):",
|
|
2641
|
+
err
|
|
2642
|
+
);
|
|
2643
|
+
}
|
|
2644
|
+
function resolveFetchImpl(injected) {
|
|
2645
|
+
return injected ?? ((...args) => globalThis.fetch(...args));
|
|
2646
|
+
}
|
|
2647
|
+
function normalizeEndpoint(endpoint) {
|
|
2648
|
+
return endpoint.replace(/\/+$/, "");
|
|
2649
|
+
}
|
|
2650
|
+
async function markPromoteReadyHandled(opts) {
|
|
2651
|
+
const {
|
|
2652
|
+
appId,
|
|
2653
|
+
archetype,
|
|
2654
|
+
family,
|
|
2655
|
+
resolution,
|
|
2656
|
+
resolutionNote,
|
|
2657
|
+
brainEndpoint,
|
|
2658
|
+
brainJwt,
|
|
2659
|
+
brainAnonKey,
|
|
2660
|
+
fetch: injectedFetch
|
|
2661
|
+
} = opts;
|
|
2662
|
+
if (!appId) return { ok: false, reason: "app_id_required" };
|
|
2663
|
+
if (!archetype) return { ok: false, reason: "archetype_required" };
|
|
2664
|
+
if (!family) return { ok: false, reason: "family_required" };
|
|
2665
|
+
if (resolution !== "promoted" && resolution !== "declined" && resolution !== "still-evaluating") {
|
|
2666
|
+
return { ok: false, reason: "resolution_invalid" };
|
|
2667
|
+
}
|
|
2668
|
+
const doFetch = resolveFetchImpl(injectedFetch);
|
|
2669
|
+
const base = normalizeEndpoint(brainEndpoint);
|
|
2670
|
+
const url = `${base}/rest/v1/promote_ready_findings?app_id=eq.${encodeURIComponent(appId)}&intent_archetype=eq.${encodeURIComponent(archetype)}&family=eq.${encodeURIComponent(family)}&resolved_at=is.null`;
|
|
2671
|
+
const patchBody = {
|
|
2672
|
+
resolved_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2673
|
+
resolution
|
|
2674
|
+
};
|
|
2675
|
+
if (resolutionNote !== void 0) {
|
|
2676
|
+
patchBody.resolution_note = resolutionNote;
|
|
2677
|
+
}
|
|
2678
|
+
let res;
|
|
2679
|
+
try {
|
|
2680
|
+
res = await doFetch(url, {
|
|
2681
|
+
method: "PATCH",
|
|
2682
|
+
headers: {
|
|
2683
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
2684
|
+
apikey: brainAnonKey,
|
|
2685
|
+
"Content-Type": "application/json",
|
|
2686
|
+
Accept: "application/json",
|
|
2687
|
+
Prefer: "return=minimal"
|
|
2688
|
+
},
|
|
2689
|
+
body: JSON.stringify(patchBody)
|
|
2690
|
+
});
|
|
2691
|
+
} catch (err) {
|
|
2692
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2693
|
+
return { ok: false, reason: `network_error:${msg}` };
|
|
2694
|
+
}
|
|
2695
|
+
if (res.status === 401 || res.status === 403) {
|
|
2696
|
+
return { ok: false, reason: "brain_auth_misconfig" };
|
|
2697
|
+
}
|
|
2698
|
+
if (res.status >= 500) {
|
|
2699
|
+
return { ok: false, reason: "brain_unavailable" };
|
|
2700
|
+
}
|
|
2701
|
+
if (!res.ok) {
|
|
2702
|
+
return { ok: false, reason: `patch_failed:${res.status}` };
|
|
2703
|
+
}
|
|
2704
|
+
return { ok: true };
|
|
2705
|
+
}
|
|
2706
|
+
|
|
2707
|
+
// src/advisor-rules/promote-ready.ts
|
|
2708
|
+
var PROMOTE_READY_THRESHOLDS = {
|
|
2709
|
+
minPassRate: 0.8,
|
|
2710
|
+
minAvgScore: 4
|
|
2711
|
+
};
|
|
2712
|
+
function shouldFirePromoteReady(finding, resolvedPrimary) {
|
|
2713
|
+
if (finding.currentModel !== resolvedPrimary) return false;
|
|
2714
|
+
if (finding.judgePassRate < PROMOTE_READY_THRESHOLDS.minPassRate) return false;
|
|
2715
|
+
if (finding.judgeAvgScore < PROMOTE_READY_THRESHOLDS.minAvgScore) return false;
|
|
2716
|
+
return true;
|
|
2717
|
+
}
|
|
2718
|
+
function deriveFamilyLocal(modelId) {
|
|
2719
|
+
if (modelId.startsWith("claude-opus-")) return "claude-opus";
|
|
2720
|
+
if (modelId.startsWith("claude-sonnet-")) return "claude-sonnet";
|
|
2721
|
+
if (modelId.startsWith("claude-haiku-")) return "claude-haiku";
|
|
2722
|
+
if (/^gemini-.*-flash-lite/.test(modelId)) return "gemini-flash-lite";
|
|
2723
|
+
if (/^gemini-.*-flash/.test(modelId)) return "gemini-flash";
|
|
2724
|
+
if (/^gemini-.*-pro/.test(modelId)) return "gemini-pro";
|
|
2725
|
+
if (/^deepseek-.*-pro/.test(modelId)) return "deepseek-reasoner";
|
|
2726
|
+
if (modelId.startsWith("deepseek-")) return "deepseek-chat";
|
|
2727
|
+
if (modelId.startsWith("gpt-")) return "openai-gpt";
|
|
2728
|
+
return null;
|
|
2729
|
+
}
|
|
2730
|
+
function advisorRulePromoteReady(ctx) {
|
|
2731
|
+
if (!isPromoteReadyBrainActive()) return [];
|
|
2732
|
+
if (!ctx.appId) return [];
|
|
2733
|
+
if (!ctx.resolvedPrimary) return [];
|
|
2734
|
+
const family = deriveFamilyLocal(ctx.resolvedPrimary);
|
|
2735
|
+
if (!family) return [];
|
|
2736
|
+
const findings = loadPromoteReadyFindings({
|
|
2737
|
+
appId: ctx.appId,
|
|
2738
|
+
archetype: ctx.archetype,
|
|
2739
|
+
family
|
|
2740
|
+
});
|
|
2741
|
+
if (findings.length === 0) return [];
|
|
2742
|
+
const qualifying = findings.filter(
|
|
2743
|
+
(f) => shouldFirePromoteReady(f, ctx.resolvedPrimary)
|
|
2744
|
+
);
|
|
2745
|
+
if (qualifying.length === 0) return [];
|
|
2746
|
+
qualifying.sort((a, b) => {
|
|
2747
|
+
if (a.judgeAvgScore !== b.judgeAvgScore) {
|
|
2748
|
+
return b.judgeAvgScore - a.judgeAvgScore;
|
|
2749
|
+
}
|
|
2750
|
+
return b.judgePassRate - a.judgePassRate;
|
|
2751
|
+
});
|
|
2752
|
+
const top = qualifying[0];
|
|
2753
|
+
const pctPass = Math.round(top.judgePassRate * 100);
|
|
2754
|
+
const score = top.judgeAvgScore.toFixed(2);
|
|
2755
|
+
let costClause = "";
|
|
2756
|
+
if (top.costDeltaPct !== null) {
|
|
2757
|
+
const sign = top.costDeltaPct < 0 ? "cheaper" : "more expensive";
|
|
2758
|
+
const magnitude = Math.abs(top.costDeltaPct * 100).toFixed(1);
|
|
2759
|
+
costClause = `, cost ${magnitude}% ${sign}`;
|
|
2760
|
+
}
|
|
2761
|
+
const message = `Probe found ${top.candidateModel} produces equivalent-or-better outputs vs ${top.currentModel} on ${top.sampleN} recent ${top.archetype} prompts (pass rate ${pctPass}%, avg score ${score}/5${costClause}). Consider promoting via markPromoteReadyHandled.`;
|
|
2762
|
+
return [
|
|
2763
|
+
{
|
|
2764
|
+
level: "info",
|
|
2765
|
+
code: "promote-ready",
|
|
2766
|
+
message,
|
|
2767
|
+
suggestion: `Migrate ${top.archetype} traffic from ${top.currentModel} to ${top.candidateModel}, then call markPromoteReadyHandled({ appId, archetype: '${top.archetype}', family: '${top.family}', resolution: 'promoted' }) to silence this advisory.`,
|
|
2768
|
+
// alpha.36 architectural field — not a no-ai-needed case.
|
|
2769
|
+
recommendedArchitecture: void 0,
|
|
2770
|
+
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories"
|
|
2771
|
+
}
|
|
2772
|
+
];
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
// src/advisor-rules/consumer-on-stale-model.ts
|
|
2776
|
+
function isStaleStatus(v) {
|
|
2777
|
+
return v === "legacy" || v === "deprecated";
|
|
2778
|
+
}
|
|
2779
|
+
function asString(v) {
|
|
2780
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
2781
|
+
}
|
|
2782
|
+
function mapRowsToFindings3(rows) {
|
|
2783
|
+
const out = [];
|
|
2784
|
+
for (const raw of rows) {
|
|
2785
|
+
if (!raw || typeof raw !== "object") continue;
|
|
2786
|
+
const r = raw;
|
|
2787
|
+
const archetype = asString(r.intent_archetype) ?? asString(r.applies_to_archetype);
|
|
2788
|
+
const staleModel = asString(r.stale_model) ?? asString(r.applies_to_model);
|
|
2789
|
+
const staleProvider = asString(r.stale_provider);
|
|
2790
|
+
const recommendedModel = asString(r.recommended_model);
|
|
2791
|
+
const family = asString(r.family);
|
|
2792
|
+
const message = asString(r.message);
|
|
2793
|
+
if (!archetype || !staleModel || !recommendedModel || !family || !message) {
|
|
2794
|
+
continue;
|
|
2795
|
+
}
|
|
2796
|
+
if (!isStaleStatus(r.stale_status)) continue;
|
|
2797
|
+
const row = {
|
|
2798
|
+
archetype,
|
|
2799
|
+
staleModel,
|
|
2800
|
+
staleProvider: staleProvider ?? "unknown",
|
|
2801
|
+
staleStatus: r.stale_status,
|
|
2802
|
+
recommendedModel,
|
|
2803
|
+
family,
|
|
2804
|
+
message
|
|
2805
|
+
};
|
|
2806
|
+
const suggestion = asString(r.suggestion);
|
|
2807
|
+
if (suggestion) row.suggestion = suggestion;
|
|
2808
|
+
if (typeof r.observation_count === "number" && Number.isFinite(r.observation_count)) {
|
|
2809
|
+
row.observationCount = r.observation_count;
|
|
2810
|
+
}
|
|
2811
|
+
out.push(row);
|
|
2812
|
+
}
|
|
2813
|
+
return out;
|
|
2814
|
+
}
|
|
2815
|
+
var snapshots3 = /* @__PURE__ */ new Map();
|
|
2816
|
+
var runtime4;
|
|
2817
|
+
var warnedOnce3 = false;
|
|
2818
|
+
var pendingRefreshes3 = /* @__PURE__ */ new Map();
|
|
2819
|
+
function isStaleModelFindingsBrainActive() {
|
|
2820
|
+
return runtime4 !== void 0;
|
|
2821
|
+
}
|
|
2822
|
+
function getStaleModelFindings(opts) {
|
|
2823
|
+
const rt = runtime4;
|
|
2824
|
+
if (!rt) return [];
|
|
2825
|
+
const appId = opts.appId;
|
|
2826
|
+
if (!appId) return [];
|
|
2827
|
+
let snap = snapshots3.get(appId);
|
|
2828
|
+
if (!snap) {
|
|
2829
|
+
snap = { data: [], expiresAt: 0, refreshing: false };
|
|
2830
|
+
snapshots3.set(appId, snap);
|
|
2831
|
+
}
|
|
2832
|
+
const now = Date.now();
|
|
2833
|
+
const stale = snap.expiresAt <= now;
|
|
2834
|
+
if (stale && !snap.refreshing) {
|
|
2835
|
+
snap.refreshing = true;
|
|
2836
|
+
void asyncRefresh4(rt, appId);
|
|
2837
|
+
}
|
|
2838
|
+
if (opts.archetype) {
|
|
2839
|
+
return snap.data.filter((f) => f.archetype === opts.archetype);
|
|
2840
|
+
}
|
|
2841
|
+
return snap.data;
|
|
2842
|
+
}
|
|
2843
|
+
async function asyncRefresh4(rt, appId) {
|
|
2844
|
+
const promise = doRefresh4(rt, appId);
|
|
2845
|
+
pendingRefreshes3.set(appId, promise);
|
|
2846
|
+
try {
|
|
2847
|
+
await promise;
|
|
2848
|
+
} finally {
|
|
2849
|
+
if (pendingRefreshes3.get(appId) === promise) {
|
|
2850
|
+
pendingRefreshes3.delete(appId);
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
}
|
|
2854
|
+
async function doRefresh4(rt, appId) {
|
|
2855
|
+
const url = `${rt.endpoint}?app_id=${encodeURIComponent(appId)}`;
|
|
2856
|
+
let snap = snapshots3.get(appId);
|
|
2857
|
+
if (!snap) {
|
|
2858
|
+
snap = { data: [], expiresAt: 0, refreshing: false };
|
|
2859
|
+
snapshots3.set(appId, snap);
|
|
2860
|
+
}
|
|
2861
|
+
try {
|
|
2862
|
+
const res = await rt.fetchImpl(url, { method: "GET" });
|
|
2863
|
+
if (!res.ok) {
|
|
2864
|
+
throw new Error(`stale-model findings ${res.status}: ${res.statusText}`);
|
|
2865
|
+
}
|
|
2866
|
+
const body = await res.json();
|
|
2867
|
+
if (runtime4 !== rt) return;
|
|
2868
|
+
const rows = Array.isArray(body) ? mapRowsToFindings3(body) : [];
|
|
2869
|
+
snap.data = rows;
|
|
2870
|
+
snap.expiresAt = Date.now() + rt.ttlMs;
|
|
2871
|
+
snap.refreshing = false;
|
|
2872
|
+
} catch (err) {
|
|
2873
|
+
if (runtime4 !== rt) return;
|
|
2874
|
+
snap.refreshing = false;
|
|
2875
|
+
snap.expiresAt = Date.now() + rt.ttlMs;
|
|
2876
|
+
if (!warnedOnce3) {
|
|
2877
|
+
warnedOnce3 = true;
|
|
2878
|
+
(rt.onError ?? defaultOnError4)(err);
|
|
2879
|
+
}
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
function defaultOnError4(err) {
|
|
2883
|
+
console.warn(
|
|
2884
|
+
"[kgauto] stale-model findings fetch failed (using empty fallback):",
|
|
2885
|
+
err
|
|
2886
|
+
);
|
|
2887
|
+
}
|
|
2888
|
+
var CONSUMER_ON_STALE_MODEL_RULE_CODE = "consumer-on-stale-model";
|
|
2889
|
+
function advisorRuleConsumerOnStaleModel(ir) {
|
|
2890
|
+
if (!isStaleModelFindingsBrainActive()) return [];
|
|
2891
|
+
if (!ir.appId) return [];
|
|
2892
|
+
const findings = getStaleModelFindings({
|
|
2893
|
+
appId: ir.appId,
|
|
2894
|
+
archetype: ir.intent.archetype
|
|
2895
|
+
});
|
|
2896
|
+
if (findings.length === 0) return [];
|
|
2897
|
+
const ranked = [...findings].sort((a, b) => {
|
|
2898
|
+
if (a.staleStatus !== b.staleStatus) {
|
|
2899
|
+
return a.staleStatus === "deprecated" ? -1 : 1;
|
|
2900
|
+
}
|
|
2901
|
+
return a.staleModel.localeCompare(b.staleModel);
|
|
2902
|
+
});
|
|
2903
|
+
const top = ranked[0];
|
|
2904
|
+
const extraCount = findings.length - 1;
|
|
2905
|
+
const extraNote = extraCount > 0 ? ` (+ ${extraCount} more stale model${extraCount === 1 ? "" : "s"} for this archetype)` : "";
|
|
2906
|
+
return [
|
|
2907
|
+
{
|
|
2908
|
+
level: "warn",
|
|
2909
|
+
code: CONSUMER_ON_STALE_MODEL_RULE_CODE,
|
|
2910
|
+
message: `${top.message}${extraNote}`,
|
|
2911
|
+
suggestion: top.suggestion ?? `Migrate ${top.staleModel} \u2192 ${top.recommendedModel} for archetype "${top.archetype}". The newer model is the current latest in the "${top.family}" family; the stale one is ${top.staleStatus}.`,
|
|
2912
|
+
recommendationType: "model-swap",
|
|
2913
|
+
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories"
|
|
2914
|
+
}
|
|
2915
|
+
];
|
|
2916
|
+
}
|
|
2917
|
+
|
|
2526
2918
|
// src/advisor.ts
|
|
2527
2919
|
var QUALITY_FLOOR_FOR_RECOMMENDATION = 6;
|
|
2528
2920
|
var TIER_DOWN_COST_RATIO = 0.5;
|
|
@@ -2545,6 +2937,16 @@ function runAdvisor(ir, result, profile, policy, phase2) {
|
|
|
2545
2937
|
if (policy?.posture !== "locked") {
|
|
2546
2938
|
out.push(...detectStaleExclusionCandidate(ir));
|
|
2547
2939
|
}
|
|
2940
|
+
if (policy?.posture !== "locked" && ir.appId) {
|
|
2941
|
+
out.push(
|
|
2942
|
+
...advisorRulePromoteReady({
|
|
2943
|
+
appId: ir.appId,
|
|
2944
|
+
archetype: ir.intent.archetype,
|
|
2945
|
+
resolvedPrimary: profile.id
|
|
2946
|
+
})
|
|
2947
|
+
);
|
|
2948
|
+
out.push(...advisorRuleConsumerOnStaleModel(ir));
|
|
2949
|
+
}
|
|
2548
2950
|
return out;
|
|
2549
2951
|
}
|
|
2550
2952
|
function translatorClearedToolCallCliff(phase2) {
|
|
@@ -2856,6 +3258,261 @@ ${originalText}`;
|
|
|
2856
3258
|
return { rewrittenIR, rewrites };
|
|
2857
3259
|
}
|
|
2858
3260
|
|
|
3261
|
+
// src/models-brain.ts
|
|
3262
|
+
function isModelRow(x) {
|
|
3263
|
+
if (!x || typeof x !== "object") return false;
|
|
3264
|
+
const r = x;
|
|
3265
|
+
return typeof r.model_id === "string" && typeof r.provider === "string";
|
|
3266
|
+
}
|
|
3267
|
+
function isAliasRow(x) {
|
|
3268
|
+
if (!x || typeof x !== "object") return false;
|
|
3269
|
+
const r = x;
|
|
3270
|
+
return typeof r.alias_id === "string" && typeof r.canonical_id === "string";
|
|
3271
|
+
}
|
|
3272
|
+
function rowToProfile(row) {
|
|
3273
|
+
try {
|
|
3274
|
+
if (row.cliffs !== void 0 && row.cliffs !== null && !Array.isArray(row.cliffs)) {
|
|
3275
|
+
return null;
|
|
3276
|
+
}
|
|
3277
|
+
if (row.recovery !== void 0 && row.recovery !== null && !Array.isArray(row.recovery)) {
|
|
3278
|
+
return null;
|
|
3279
|
+
}
|
|
3280
|
+
if (row.lowering !== void 0 && row.lowering !== null && (typeof row.lowering !== "object" || Array.isArray(row.lowering))) {
|
|
3281
|
+
return null;
|
|
3282
|
+
}
|
|
3283
|
+
return {
|
|
3284
|
+
id: row.model_id,
|
|
3285
|
+
provider: row.provider,
|
|
3286
|
+
status: row.status ?? "current",
|
|
3287
|
+
maxContextTokens: row.max_context_tokens ?? 0,
|
|
3288
|
+
maxOutputTokens: row.max_output_tokens ?? 0,
|
|
3289
|
+
maxTools: row.max_tools ?? 0,
|
|
3290
|
+
parallelToolCalls: row.parallel_tool_calls ?? false,
|
|
3291
|
+
structuredOutput: row.structured_output ?? "none",
|
|
3292
|
+
systemPromptMode: row.system_prompt_mode ?? "inline",
|
|
3293
|
+
streaming: row.streaming ?? true,
|
|
3294
|
+
cliffs: row.cliffs ?? [],
|
|
3295
|
+
costInputPer1m: row.cost_input_per_1m ?? 0,
|
|
3296
|
+
costOutputPer1m: row.cost_output_per_1m ?? 0,
|
|
3297
|
+
lowering: row.lowering ?? { system: { mode: "inline" }, cache: { strategy: "unsupported" } },
|
|
3298
|
+
recovery: row.recovery ?? [],
|
|
3299
|
+
strengths: row.strengths ?? [],
|
|
3300
|
+
weaknesses: row.weaknesses ?? [],
|
|
3301
|
+
notes: row.notes ?? void 0,
|
|
3302
|
+
verifiedAgainstDocs: row.verified_against_docs ?? void 0,
|
|
3303
|
+
archetypePerf: row.archetype_perf ?? void 0,
|
|
3304
|
+
// alpha.41 — family-resolution fields. `family` may be null pre-
|
|
3305
|
+
// migration 024; runtime falls back to deriveFamilyFromModelId at
|
|
3306
|
+
// resolution time (see family-resolution.ts, G1).
|
|
3307
|
+
family: row.family ?? void 0,
|
|
3308
|
+
versionAdded: row.version_added ?? void 0,
|
|
3309
|
+
active: row.active ?? void 0
|
|
3310
|
+
};
|
|
3311
|
+
} catch {
|
|
3312
|
+
return null;
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
function profileToRow(profile, opts = {}) {
|
|
3316
|
+
const row = {
|
|
3317
|
+
model_id: profile.id,
|
|
3318
|
+
provider: profile.provider,
|
|
3319
|
+
status: profile.status,
|
|
3320
|
+
max_context_tokens: profile.maxContextTokens,
|
|
3321
|
+
max_output_tokens: profile.maxOutputTokens,
|
|
3322
|
+
max_tools: profile.maxTools,
|
|
3323
|
+
parallel_tool_calls: profile.parallelToolCalls,
|
|
3324
|
+
structured_output: profile.structuredOutput,
|
|
3325
|
+
system_prompt_mode: profile.systemPromptMode,
|
|
3326
|
+
streaming: profile.streaming,
|
|
3327
|
+
cliffs: profile.cliffs,
|
|
3328
|
+
cost_input_per_1m: profile.costInputPer1m,
|
|
3329
|
+
cost_output_per_1m: profile.costOutputPer1m,
|
|
3330
|
+
lowering: profile.lowering,
|
|
3331
|
+
recovery: profile.recovery,
|
|
3332
|
+
strengths: profile.strengths,
|
|
3333
|
+
weaknesses: profile.weaknesses,
|
|
3334
|
+
notes: profile.notes ?? null,
|
|
3335
|
+
archetype_perf: profile.archetypePerf ?? null,
|
|
3336
|
+
active: opts.active ?? profile.active ?? true,
|
|
3337
|
+
// alpha.41 — round-trip family + version_added when present on profile.
|
|
3338
|
+
// version_added is operator-controlled via opts; profile-side value is
|
|
3339
|
+
// used only when opts didn't override.
|
|
3340
|
+
family: profile.family ?? null
|
|
3341
|
+
};
|
|
3342
|
+
if (opts.verifiedAgainstDocs !== void 0) {
|
|
3343
|
+
row.verified_against_docs = opts.verifiedAgainstDocs;
|
|
3344
|
+
} else if (profile.verifiedAgainstDocs !== void 0) {
|
|
3345
|
+
const v = profile.verifiedAgainstDocs;
|
|
3346
|
+
row.verified_against_docs = /^\d{4}-\d{2}-\d{2}/.test(v) ? v : null;
|
|
3347
|
+
}
|
|
3348
|
+
if (opts.versionAdded !== void 0) row.version_added = opts.versionAdded;
|
|
3349
|
+
else if (profile.versionAdded !== void 0) row.version_added = profile.versionAdded;
|
|
3350
|
+
if (opts.versionRemoved !== void 0) row.version_removed = opts.versionRemoved;
|
|
3351
|
+
return row;
|
|
3352
|
+
}
|
|
3353
|
+
function mapRowsToModels(rows) {
|
|
3354
|
+
const out = /* @__PURE__ */ new Map();
|
|
3355
|
+
for (const row of rows) {
|
|
3356
|
+
if (!isModelRow(row)) continue;
|
|
3357
|
+
const profile = rowToProfile(row);
|
|
3358
|
+
if (profile) out.set(profile.id, profile);
|
|
3359
|
+
}
|
|
3360
|
+
return out;
|
|
3361
|
+
}
|
|
3362
|
+
function mapRowsToAliases(rows) {
|
|
3363
|
+
const out = {};
|
|
3364
|
+
for (const row of rows) {
|
|
3365
|
+
if (!isAliasRow(row)) continue;
|
|
3366
|
+
out[row.alias_id] = row.canonical_id;
|
|
3367
|
+
}
|
|
3368
|
+
return out;
|
|
3369
|
+
}
|
|
3370
|
+
function bundledModels() {
|
|
3371
|
+
return new Map(allProfilesRaw().map((p) => [p.id, p]));
|
|
3372
|
+
}
|
|
3373
|
+
function bundledAliases() {
|
|
3374
|
+
return { ...ALIASES };
|
|
3375
|
+
}
|
|
3376
|
+
var loadModelsFromBrain = createBrainQueryCache({
|
|
3377
|
+
table: "kgauto_models",
|
|
3378
|
+
mapRows: mapRowsToModels,
|
|
3379
|
+
bundledFallback: bundledModels
|
|
3380
|
+
});
|
|
3381
|
+
var loadAliasesFromBrain = createBrainQueryCache({
|
|
3382
|
+
table: "kgauto_aliases",
|
|
3383
|
+
mapRows: mapRowsToAliases,
|
|
3384
|
+
bundledFallback: bundledAliases
|
|
3385
|
+
});
|
|
3386
|
+
_setProfileBrainHook({
|
|
3387
|
+
getProfile: (canonical) => loadModelsFromBrain().get(canonical),
|
|
3388
|
+
resolveAlias: (id) => loadAliasesFromBrain()[id]
|
|
3389
|
+
});
|
|
3390
|
+
|
|
3391
|
+
// src/family-resolution.ts
|
|
3392
|
+
var FamilyResolutionError = class extends Error {
|
|
3393
|
+
family;
|
|
3394
|
+
cause;
|
|
3395
|
+
constructor(family, cause) {
|
|
3396
|
+
super(
|
|
3397
|
+
`Family "${family}" did not resolve to any current+active model. ${cause}. Pass a literal model id in ir.models, or call getRecommendedPrimary({ family, fallback }) at IR-construction time.`
|
|
3398
|
+
);
|
|
3399
|
+
this.name = "FamilyResolutionError";
|
|
3400
|
+
this.family = family;
|
|
3401
|
+
this.cause = cause;
|
|
3402
|
+
}
|
|
3403
|
+
};
|
|
3404
|
+
function deriveFamilyFromModelId(modelId) {
|
|
3405
|
+
if (typeof modelId !== "string" || modelId.length === 0) return null;
|
|
3406
|
+
if (modelId.startsWith("claude-opus-")) return "claude-opus";
|
|
3407
|
+
if (modelId.startsWith("claude-sonnet-")) return "claude-sonnet";
|
|
3408
|
+
if (modelId.startsWith("claude-haiku-")) return "claude-haiku";
|
|
3409
|
+
if (modelId.startsWith("gemini-") && modelId.includes("flash-lite")) {
|
|
3410
|
+
return "gemini-flash-lite";
|
|
3411
|
+
}
|
|
3412
|
+
if (modelId.startsWith("gemini-") && modelId.includes("flash")) {
|
|
3413
|
+
return "gemini-flash";
|
|
3414
|
+
}
|
|
3415
|
+
if (modelId.startsWith("gemini-") && modelId.includes("pro")) {
|
|
3416
|
+
return "gemini-pro";
|
|
3417
|
+
}
|
|
3418
|
+
if (modelId.startsWith("deepseek-") && modelId.includes("pro")) {
|
|
3419
|
+
return "deepseek-reasoner";
|
|
3420
|
+
}
|
|
3421
|
+
if (modelId.startsWith("deepseek-")) return "deepseek-chat";
|
|
3422
|
+
if (modelId.startsWith("gpt-")) return "openai-gpt";
|
|
3423
|
+
return null;
|
|
3424
|
+
}
|
|
3425
|
+
function familyOf(profile) {
|
|
3426
|
+
return profile.family ?? deriveFamilyFromModelId(profile.id);
|
|
3427
|
+
}
|
|
3428
|
+
function archetypePerfFor(profile, archetype) {
|
|
3429
|
+
if (!archetype) return 0;
|
|
3430
|
+
const score = profile.archetypePerf?.[archetype];
|
|
3431
|
+
return typeof score === "number" ? score : 5;
|
|
3432
|
+
}
|
|
3433
|
+
function selectCandidates(registry, family, archetype, appId) {
|
|
3434
|
+
const out = [];
|
|
3435
|
+
const excluded = /* @__PURE__ */ new Set();
|
|
3436
|
+
if (appId && archetype) {
|
|
3437
|
+
const findings = getStaleExclusionFindings({ appId, archetype });
|
|
3438
|
+
for (const f of findings) {
|
|
3439
|
+
if (f.verdict === "stay-excluded") excluded.add(f.excludedModel);
|
|
3440
|
+
}
|
|
3441
|
+
}
|
|
3442
|
+
for (const profile of registry.values()) {
|
|
3443
|
+
if (familyOf(profile) !== family) continue;
|
|
3444
|
+
if (profile.status !== "current") continue;
|
|
3445
|
+
if (profile.active === false) continue;
|
|
3446
|
+
if (archetype) {
|
|
3447
|
+
if (archetypePerfFor(profile, archetype) < ARCHETYPE_FLOOR_DEFAULT) continue;
|
|
3448
|
+
}
|
|
3449
|
+
if (excluded.has(profile.id)) continue;
|
|
3450
|
+
out.push(profile);
|
|
3451
|
+
}
|
|
3452
|
+
return out;
|
|
3453
|
+
}
|
|
3454
|
+
function sortCandidates(candidates, archetype) {
|
|
3455
|
+
const sorted = [...candidates];
|
|
3456
|
+
sorted.sort((a, b) => {
|
|
3457
|
+
const perfA = archetypePerfFor(a, archetype);
|
|
3458
|
+
const perfB = archetypePerfFor(b, archetype);
|
|
3459
|
+
if (perfA !== perfB) return perfB - perfA;
|
|
3460
|
+
const vA = a.versionAdded ?? "";
|
|
3461
|
+
const vB = b.versionAdded ?? "";
|
|
3462
|
+
if (vA !== vB) return vA < vB ? 1 : -1;
|
|
3463
|
+
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
3464
|
+
});
|
|
3465
|
+
return sorted;
|
|
3466
|
+
}
|
|
3467
|
+
function getRecommendedPrimary(opts) {
|
|
3468
|
+
if (opts.posture === "locked") return opts.fallback;
|
|
3469
|
+
const registry = loadModelsFromBrain();
|
|
3470
|
+
const candidates = selectCandidates(
|
|
3471
|
+
registry,
|
|
3472
|
+
opts.family,
|
|
3473
|
+
opts.archetype,
|
|
3474
|
+
opts.appId
|
|
3475
|
+
);
|
|
3476
|
+
if (candidates.length === 0) return opts.fallback;
|
|
3477
|
+
const sorted = sortCandidates(candidates, opts.archetype);
|
|
3478
|
+
return sorted[0]?.id ?? opts.fallback;
|
|
3479
|
+
}
|
|
3480
|
+
function resolveFamilyEntry(family, ctx) {
|
|
3481
|
+
if (typeof family !== "string" || family.length === 0) {
|
|
3482
|
+
throw new FamilyResolutionError(
|
|
3483
|
+
String(family),
|
|
3484
|
+
"Family tag must be a non-empty string"
|
|
3485
|
+
);
|
|
3486
|
+
}
|
|
3487
|
+
const registry = loadModelsFromBrain();
|
|
3488
|
+
const candidates = selectCandidates(
|
|
3489
|
+
registry,
|
|
3490
|
+
family,
|
|
3491
|
+
ctx.archetype,
|
|
3492
|
+
ctx.appId
|
|
3493
|
+
);
|
|
3494
|
+
if (candidates.length === 0) {
|
|
3495
|
+
let anyInFamily = false;
|
|
3496
|
+
for (const profile of registry.values()) {
|
|
3497
|
+
if (familyOf(profile) === family) {
|
|
3498
|
+
anyInFamily = true;
|
|
3499
|
+
break;
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
const cause = anyInFamily ? `Family has registered models but none are current+active${ctx.archetype ? ` at archetype-perf >= ${ARCHETYPE_FLOOR_DEFAULT} for "${ctx.archetype}"` : ""}${ctx.appId ? ` and not excluded for app "${ctx.appId}"` : ""}` : `No models in brain registry carry family="${family}". Check the taxonomy table in family-resolution.ts or migration 024`;
|
|
3503
|
+
throw new FamilyResolutionError(family, cause);
|
|
3504
|
+
}
|
|
3505
|
+
const sorted = sortCandidates(candidates, ctx.archetype);
|
|
3506
|
+
const winner = sorted[0];
|
|
3507
|
+
if (!winner) {
|
|
3508
|
+
throw new FamilyResolutionError(
|
|
3509
|
+
family,
|
|
3510
|
+
"Candidates non-empty but sort returned undefined \u2014 internal invariant violation"
|
|
3511
|
+
);
|
|
3512
|
+
}
|
|
3513
|
+
return winner.id;
|
|
3514
|
+
}
|
|
3515
|
+
|
|
2859
3516
|
// src/compile.ts
|
|
2860
3517
|
var counter = 0;
|
|
2861
3518
|
function makeHandle() {
|
|
@@ -2865,6 +3522,7 @@ function makeHandle() {
|
|
|
2865
3522
|
function compile(ir, opts = {}) {
|
|
2866
3523
|
const resolver = opts.profileResolver ?? getProfile;
|
|
2867
3524
|
validateIR(ir);
|
|
3525
|
+
ir = resolveModelEntries(ir);
|
|
2868
3526
|
const sliced = passSlice(ir);
|
|
2869
3527
|
const deduped = passDedupe(sliced.value);
|
|
2870
3528
|
const toolFiltered = passToolRelevance(deduped.value, {
|
|
@@ -3051,6 +3709,29 @@ function validateIR(ir) {
|
|
|
3051
3709
|
throw new Error("compile(): ir.sections must be an array");
|
|
3052
3710
|
}
|
|
3053
3711
|
}
|
|
3712
|
+
function resolveModelEntries(ir) {
|
|
3713
|
+
const out = [];
|
|
3714
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3715
|
+
for (const entry of ir.models) {
|
|
3716
|
+
let id;
|
|
3717
|
+
if (typeof entry === "string") {
|
|
3718
|
+
id = entry;
|
|
3719
|
+
} else if (entry && typeof entry === "object" && "family" in entry) {
|
|
3720
|
+
id = resolveFamilyEntry(entry.family, {
|
|
3721
|
+
archetype: ir.intent.archetype,
|
|
3722
|
+
appId: ir.appId
|
|
3723
|
+
});
|
|
3724
|
+
} else {
|
|
3725
|
+
throw new Error(
|
|
3726
|
+
`compile(): ir.models entry must be a string or { family: string }; got ${JSON.stringify(entry)}`
|
|
3727
|
+
);
|
|
3728
|
+
}
|
|
3729
|
+
if (seen.has(id)) continue;
|
|
3730
|
+
seen.add(id);
|
|
3731
|
+
out.push(id);
|
|
3732
|
+
}
|
|
3733
|
+
return { ...ir, models: out };
|
|
3734
|
+
}
|
|
3054
3735
|
function pickTarget(ir, scores) {
|
|
3055
3736
|
if (ir.constraints?.forceModel) {
|
|
3056
3737
|
const forced = scores.find((s) => s.modelId === ir.constraints.forceModel);
|
|
@@ -3277,7 +3958,7 @@ async function record(input) {
|
|
|
3277
3958
|
}
|
|
3278
3959
|
outcomeId = await tryExtractOutcomeId(res);
|
|
3279
3960
|
} catch (err) {
|
|
3280
|
-
(config.onError ??
|
|
3961
|
+
(config.onError ?? defaultOnError5)(err);
|
|
3281
3962
|
return;
|
|
3282
3963
|
}
|
|
3283
3964
|
const advisories = input.advisories ?? reg?.advisoriesFromCompile;
|
|
@@ -3299,7 +3980,7 @@ async function record(input) {
|
|
|
3299
3980
|
throw new Error(`brain advisories ${res.status}: ${text}`);
|
|
3300
3981
|
}
|
|
3301
3982
|
} catch (err) {
|
|
3302
|
-
(config.onError ??
|
|
3983
|
+
(config.onError ?? defaultOnError5)(err);
|
|
3303
3984
|
}
|
|
3304
3985
|
};
|
|
3305
3986
|
if (config.sync) {
|
|
@@ -3308,7 +3989,7 @@ async function record(input) {
|
|
|
3308
3989
|
void send();
|
|
3309
3990
|
}
|
|
3310
3991
|
}
|
|
3311
|
-
function
|
|
3992
|
+
function defaultOnError5(err) {
|
|
3312
3993
|
console.warn("[kgauto] brain record failed:", err);
|
|
3313
3994
|
}
|
|
3314
3995
|
function buildPayload(input, reg) {
|
|
@@ -3440,12 +4121,12 @@ async function recordOutcome(input) {
|
|
|
3440
4121
|
if (!res.ok) {
|
|
3441
4122
|
const text = await res.text().catch(() => "<no body>");
|
|
3442
4123
|
const err = new Error(`brain ${res.status}: ${text}`);
|
|
3443
|
-
(config.onError ??
|
|
4124
|
+
(config.onError ?? defaultOnError5)(err);
|
|
3444
4125
|
return { ok: false, reason: "persistence_failed" };
|
|
3445
4126
|
}
|
|
3446
4127
|
return { ok: true };
|
|
3447
4128
|
} catch (err) {
|
|
3448
|
-
(config.onError ??
|
|
4129
|
+
(config.onError ?? defaultOnError5)(err);
|
|
3449
4130
|
return { ok: false, reason: "persistence_failed" };
|
|
3450
4131
|
}
|
|
3451
4132
|
};
|
|
@@ -4705,7 +5386,13 @@ async function call(ir, opts = {}) {
|
|
|
4705
5386
|
() => emitCompileStart(traceId, ir.appId, {
|
|
4706
5387
|
appId: ir.appId,
|
|
4707
5388
|
archetype: ir.intent.archetype,
|
|
4708
|
-
|
|
5389
|
+
// alpha.41: ir.models is ChainModelEntry[] (string | { family }).
|
|
5390
|
+
// Glass-Box renderer carries string ids only; surface family entries
|
|
5391
|
+
// as their family tag prefixed so the panel still shows them in the
|
|
5392
|
+
// pre-resolution log.
|
|
5393
|
+
models: ir.models.map(
|
|
5394
|
+
(m) => typeof m === "string" ? m : `family:${m.family}`
|
|
5395
|
+
)
|
|
4709
5396
|
})
|
|
4710
5397
|
);
|
|
4711
5398
|
const initial = compileAndRegister(ir, opts);
|
|
@@ -5171,7 +5858,7 @@ var RESOLUTION_SOURCE_SET = /* @__PURE__ */ new Set([
|
|
|
5171
5858
|
"consumer-marked",
|
|
5172
5859
|
"declined"
|
|
5173
5860
|
]);
|
|
5174
|
-
function
|
|
5861
|
+
function asString2(v) {
|
|
5175
5862
|
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
5176
5863
|
}
|
|
5177
5864
|
function asSeverity(v) {
|
|
@@ -5193,10 +5880,10 @@ function asResolutionSource(v) {
|
|
|
5193
5880
|
return void 0;
|
|
5194
5881
|
}
|
|
5195
5882
|
function rowToAdvisory(row) {
|
|
5196
|
-
const archetype =
|
|
5197
|
-
const model =
|
|
5198
|
-
const docsLink =
|
|
5199
|
-
const suggestion =
|
|
5883
|
+
const archetype = asString2(row.applies_to_archetype);
|
|
5884
|
+
const model = asString2(row.applies_to_model);
|
|
5885
|
+
const docsLink = asString2(row.docs_url);
|
|
5886
|
+
const suggestion = asString2(row.suggestion);
|
|
5200
5887
|
let suggestedFix = null;
|
|
5201
5888
|
if (docsLink || suggestion) {
|
|
5202
5889
|
suggestedFix = { type: "manual" };
|
|
@@ -5220,18 +5907,18 @@ function rowToAdvisory(row) {
|
|
|
5220
5907
|
// reserved — alpha.30+
|
|
5221
5908
|
status: asStatus(row.status)
|
|
5222
5909
|
};
|
|
5223
|
-
const resolvedAt =
|
|
5910
|
+
const resolvedAt = asString2(row.resolved_at);
|
|
5224
5911
|
if (resolvedAt) out.resolvedAt = resolvedAt;
|
|
5225
5912
|
const resolutionSource = asResolutionSource(row.resolution_source);
|
|
5226
5913
|
if (resolutionSource) out.resolutionSource = resolutionSource;
|
|
5227
|
-
const resolutionNote =
|
|
5914
|
+
const resolutionNote = asString2(row.resolution_note);
|
|
5228
5915
|
if (resolutionNote) out.resolutionNote = resolutionNote;
|
|
5229
5916
|
return out;
|
|
5230
5917
|
}
|
|
5231
5918
|
function resolveFetch(injected) {
|
|
5232
5919
|
return injected ?? ((...args) => globalThis.fetch(...args));
|
|
5233
5920
|
}
|
|
5234
|
-
function
|
|
5921
|
+
function normalizeEndpoint2(endpoint) {
|
|
5235
5922
|
return endpoint.replace(/\/+$/, "");
|
|
5236
5923
|
}
|
|
5237
5924
|
async function getActionableAdvisories(opts) {
|
|
@@ -5248,7 +5935,7 @@ async function getActionableAdvisories(opts) {
|
|
|
5248
5935
|
throw new Error("getActionableAdvisories: appId is required");
|
|
5249
5936
|
}
|
|
5250
5937
|
const doFetch = resolveFetch(injectedFetch);
|
|
5251
|
-
const base =
|
|
5938
|
+
const base = normalizeEndpoint2(brainEndpoint);
|
|
5252
5939
|
const qs = new URLSearchParams();
|
|
5253
5940
|
qs.set("app_id", `eq.${appId}`);
|
|
5254
5941
|
if (severity) qs.set("severity", `eq.${severity}`);
|
|
@@ -5311,7 +5998,7 @@ async function markAdvisoryResolved(opts) {
|
|
|
5311
5998
|
return { ok: false, reason: "id_required" };
|
|
5312
5999
|
}
|
|
5313
6000
|
const doFetch = resolveFetch(injectedFetch);
|
|
5314
|
-
const base =
|
|
6001
|
+
const base = normalizeEndpoint2(brainEndpoint);
|
|
5315
6002
|
const lookupUrl = `${base}/rest/v1/actionable_advisories_v?id=eq.${encodeURIComponent(id)}&select=app_id,rule`;
|
|
5316
6003
|
let lookupRes;
|
|
5317
6004
|
try {
|
|
@@ -5455,7 +6142,7 @@ async function markExclusionFindingHandled(opts) {
|
|
|
5455
6142
|
return { ok: false, reason: "resolution_invalid" };
|
|
5456
6143
|
}
|
|
5457
6144
|
const doFetch = resolveFetch(injectedFetch);
|
|
5458
|
-
const base =
|
|
6145
|
+
const base = normalizeEndpoint2(brainEndpoint);
|
|
5459
6146
|
const url = `${base}/rest/v1/exclusion_findings?app_id=eq.${encodeURIComponent(appId)}&intent_archetype=eq.${encodeURIComponent(archetype)}&excluded_model=eq.${encodeURIComponent(excludedModel)}&resolved_at=is.null`;
|
|
5460
6147
|
const patchBody = {
|
|
5461
6148
|
resolved_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -5495,125 +6182,6 @@ async function markExclusionFindingHandled(opts) {
|
|
|
5495
6182
|
return { ok: true };
|
|
5496
6183
|
}
|
|
5497
6184
|
|
|
5498
|
-
// src/models-brain.ts
|
|
5499
|
-
function isModelRow(x) {
|
|
5500
|
-
if (!x || typeof x !== "object") return false;
|
|
5501
|
-
const r = x;
|
|
5502
|
-
return typeof r.model_id === "string" && typeof r.provider === "string";
|
|
5503
|
-
}
|
|
5504
|
-
function isAliasRow(x) {
|
|
5505
|
-
if (!x || typeof x !== "object") return false;
|
|
5506
|
-
const r = x;
|
|
5507
|
-
return typeof r.alias_id === "string" && typeof r.canonical_id === "string";
|
|
5508
|
-
}
|
|
5509
|
-
function rowToProfile(row) {
|
|
5510
|
-
try {
|
|
5511
|
-
if (row.cliffs !== void 0 && row.cliffs !== null && !Array.isArray(row.cliffs)) {
|
|
5512
|
-
return null;
|
|
5513
|
-
}
|
|
5514
|
-
if (row.recovery !== void 0 && row.recovery !== null && !Array.isArray(row.recovery)) {
|
|
5515
|
-
return null;
|
|
5516
|
-
}
|
|
5517
|
-
if (row.lowering !== void 0 && row.lowering !== null && (typeof row.lowering !== "object" || Array.isArray(row.lowering))) {
|
|
5518
|
-
return null;
|
|
5519
|
-
}
|
|
5520
|
-
return {
|
|
5521
|
-
id: row.model_id,
|
|
5522
|
-
provider: row.provider,
|
|
5523
|
-
status: row.status ?? "current",
|
|
5524
|
-
maxContextTokens: row.max_context_tokens ?? 0,
|
|
5525
|
-
maxOutputTokens: row.max_output_tokens ?? 0,
|
|
5526
|
-
maxTools: row.max_tools ?? 0,
|
|
5527
|
-
parallelToolCalls: row.parallel_tool_calls ?? false,
|
|
5528
|
-
structuredOutput: row.structured_output ?? "none",
|
|
5529
|
-
systemPromptMode: row.system_prompt_mode ?? "inline",
|
|
5530
|
-
streaming: row.streaming ?? true,
|
|
5531
|
-
cliffs: row.cliffs ?? [],
|
|
5532
|
-
costInputPer1m: row.cost_input_per_1m ?? 0,
|
|
5533
|
-
costOutputPer1m: row.cost_output_per_1m ?? 0,
|
|
5534
|
-
lowering: row.lowering ?? { system: { mode: "inline" }, cache: { strategy: "unsupported" } },
|
|
5535
|
-
recovery: row.recovery ?? [],
|
|
5536
|
-
strengths: row.strengths ?? [],
|
|
5537
|
-
weaknesses: row.weaknesses ?? [],
|
|
5538
|
-
notes: row.notes ?? void 0,
|
|
5539
|
-
verifiedAgainstDocs: row.verified_against_docs ?? void 0,
|
|
5540
|
-
archetypePerf: row.archetype_perf ?? void 0
|
|
5541
|
-
};
|
|
5542
|
-
} catch {
|
|
5543
|
-
return null;
|
|
5544
|
-
}
|
|
5545
|
-
}
|
|
5546
|
-
function profileToRow(profile, opts = {}) {
|
|
5547
|
-
const row = {
|
|
5548
|
-
model_id: profile.id,
|
|
5549
|
-
provider: profile.provider,
|
|
5550
|
-
status: profile.status,
|
|
5551
|
-
max_context_tokens: profile.maxContextTokens,
|
|
5552
|
-
max_output_tokens: profile.maxOutputTokens,
|
|
5553
|
-
max_tools: profile.maxTools,
|
|
5554
|
-
parallel_tool_calls: profile.parallelToolCalls,
|
|
5555
|
-
structured_output: profile.structuredOutput,
|
|
5556
|
-
system_prompt_mode: profile.systemPromptMode,
|
|
5557
|
-
streaming: profile.streaming,
|
|
5558
|
-
cliffs: profile.cliffs,
|
|
5559
|
-
cost_input_per_1m: profile.costInputPer1m,
|
|
5560
|
-
cost_output_per_1m: profile.costOutputPer1m,
|
|
5561
|
-
lowering: profile.lowering,
|
|
5562
|
-
recovery: profile.recovery,
|
|
5563
|
-
strengths: profile.strengths,
|
|
5564
|
-
weaknesses: profile.weaknesses,
|
|
5565
|
-
notes: profile.notes ?? null,
|
|
5566
|
-
archetype_perf: profile.archetypePerf ?? null,
|
|
5567
|
-
active: opts.active ?? true
|
|
5568
|
-
};
|
|
5569
|
-
if (opts.verifiedAgainstDocs !== void 0) {
|
|
5570
|
-
row.verified_against_docs = opts.verifiedAgainstDocs;
|
|
5571
|
-
} else if (profile.verifiedAgainstDocs !== void 0) {
|
|
5572
|
-
const v = profile.verifiedAgainstDocs;
|
|
5573
|
-
row.verified_against_docs = /^\d{4}-\d{2}-\d{2}/.test(v) ? v : null;
|
|
5574
|
-
}
|
|
5575
|
-
if (opts.versionAdded !== void 0) row.version_added = opts.versionAdded;
|
|
5576
|
-
if (opts.versionRemoved !== void 0) row.version_removed = opts.versionRemoved;
|
|
5577
|
-
return row;
|
|
5578
|
-
}
|
|
5579
|
-
function mapRowsToModels(rows) {
|
|
5580
|
-
const out = /* @__PURE__ */ new Map();
|
|
5581
|
-
for (const row of rows) {
|
|
5582
|
-
if (!isModelRow(row)) continue;
|
|
5583
|
-
const profile = rowToProfile(row);
|
|
5584
|
-
if (profile) out.set(profile.id, profile);
|
|
5585
|
-
}
|
|
5586
|
-
return out;
|
|
5587
|
-
}
|
|
5588
|
-
function mapRowsToAliases(rows) {
|
|
5589
|
-
const out = {};
|
|
5590
|
-
for (const row of rows) {
|
|
5591
|
-
if (!isAliasRow(row)) continue;
|
|
5592
|
-
out[row.alias_id] = row.canonical_id;
|
|
5593
|
-
}
|
|
5594
|
-
return out;
|
|
5595
|
-
}
|
|
5596
|
-
function bundledModels() {
|
|
5597
|
-
return new Map(allProfilesRaw().map((p) => [p.id, p]));
|
|
5598
|
-
}
|
|
5599
|
-
function bundledAliases() {
|
|
5600
|
-
return { ...ALIASES };
|
|
5601
|
-
}
|
|
5602
|
-
var loadModelsFromBrain = createBrainQueryCache({
|
|
5603
|
-
table: "kgauto_models",
|
|
5604
|
-
mapRows: mapRowsToModels,
|
|
5605
|
-
bundledFallback: bundledModels
|
|
5606
|
-
});
|
|
5607
|
-
var loadAliasesFromBrain = createBrainQueryCache({
|
|
5608
|
-
table: "kgauto_aliases",
|
|
5609
|
-
mapRows: mapRowsToAliases,
|
|
5610
|
-
bundledFallback: bundledAliases
|
|
5611
|
-
});
|
|
5612
|
-
_setProfileBrainHook({
|
|
5613
|
-
getProfile: (canonical) => loadModelsFromBrain().get(canonical),
|
|
5614
|
-
resolveAlias: (id) => loadAliasesFromBrain()[id]
|
|
5615
|
-
});
|
|
5616
|
-
|
|
5617
6185
|
// src/index.ts
|
|
5618
6186
|
function compile2(ir, opts) {
|
|
5619
6187
|
const result = compile(ir, opts);
|
|
@@ -5629,6 +6197,7 @@ function compile2(ir, opts) {
|
|
|
5629
6197
|
CallError,
|
|
5630
6198
|
DEFAULT_FINDINGS_ENDPOINT,
|
|
5631
6199
|
DIALECT_VERSION,
|
|
6200
|
+
FamilyResolutionError,
|
|
5632
6201
|
INTENT_ARCHETYPES,
|
|
5633
6202
|
MEASURED_GROUNDING_MIN_N,
|
|
5634
6203
|
PROVIDER_ENV_KEYS,
|
|
@@ -5646,6 +6215,7 @@ function compile2(ir, opts) {
|
|
|
5646
6215
|
compile,
|
|
5647
6216
|
configureBrain,
|
|
5648
6217
|
countTokens,
|
|
6218
|
+
deriveFamilyFromModelId,
|
|
5649
6219
|
execute,
|
|
5650
6220
|
getActionableAdvisories,
|
|
5651
6221
|
getAllStarterChains,
|
|
@@ -5657,6 +6227,7 @@ function compile2(ir, opts) {
|
|
|
5657
6227
|
getPerAxisMetrics,
|
|
5658
6228
|
getProfile,
|
|
5659
6229
|
getReachabilityDiagnostic,
|
|
6230
|
+
getRecommendedPrimary,
|
|
5660
6231
|
getSequentialStarterChain,
|
|
5661
6232
|
getSequentialStarterChainWithGrounding,
|
|
5662
6233
|
getStaleExclusionFindings,
|
|
@@ -5677,6 +6248,7 @@ function compile2(ir, opts) {
|
|
|
5677
6248
|
loadPricingFromBrain,
|
|
5678
6249
|
markAdvisoryResolved,
|
|
5679
6250
|
markExclusionFindingHandled,
|
|
6251
|
+
markPromoteReadyHandled,
|
|
5680
6252
|
profileToRow,
|
|
5681
6253
|
profilesByProvider,
|
|
5682
6254
|
record,
|