@warmdrift/kgauto-compiler 2.0.0-alpha.27 → 2.0.0-alpha.29
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 +42 -0
- package/dist/chunk-WXCFWUCN.mjs +678 -0
- package/dist/glassbox/index.d.mts +3 -3
- package/dist/glassbox/index.d.ts +3 -3
- package/dist/glassbox-routes/index.d.mts +117 -6
- package/dist/glassbox-routes/index.d.ts +117 -6
- package/dist/glassbox-routes/index.js +1859 -8
- package/dist/glassbox-routes/index.mjs +359 -8
- package/dist/index.d.mts +473 -13
- package/dist/index.d.ts +473 -13
- package/dist/index.js +543 -10
- package/dist/index.mjs +484 -585
- package/dist/{ir-B_XX2LAO.d.ts → ir-BIAT9gJk.d.ts} +195 -1
- package/dist/{ir-B9zqlwjH.d.mts → ir-De2AQtlr.d.mts} +195 -1
- package/dist/profiles.d.mts +1 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/{types-o9etg93a.d.mts → types-BjrIFPGe.d.mts} +1 -1
- package/dist/{types-bt0aVJb8.d.ts → types-D_JAhCv4.d.ts} +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -9,6 +9,30 @@ import {
|
|
|
9
9
|
isArchetype,
|
|
10
10
|
learningKey
|
|
11
11
|
} from "./chunk-5TI6PNSK.mjs";
|
|
12
|
+
import {
|
|
13
|
+
ABSOLUTE_FLOOR,
|
|
14
|
+
ARCHETYPE_FLOOR_DEFAULT,
|
|
15
|
+
PROVIDER_ENV_KEYS,
|
|
16
|
+
configureBrainQuery,
|
|
17
|
+
createBrainQueryCache,
|
|
18
|
+
ensureCrossProviderTail,
|
|
19
|
+
getAllStarterChains,
|
|
20
|
+
getAllStarterChainsWithGrounding,
|
|
21
|
+
getDefaultFallbackChain,
|
|
22
|
+
getDefaultFallbackChainWithGrounding,
|
|
23
|
+
getModelCompatibility,
|
|
24
|
+
getPerAxisMetrics,
|
|
25
|
+
getReachabilityDiagnostic,
|
|
26
|
+
getSequentialStarterChain,
|
|
27
|
+
getSequentialStarterChainWithGrounding,
|
|
28
|
+
getStarterChain,
|
|
29
|
+
getStarterChainWithGrounding,
|
|
30
|
+
isBrainQueryActiveFor,
|
|
31
|
+
isModelReachable,
|
|
32
|
+
isProviderReachable,
|
|
33
|
+
loadChainsFromBrain,
|
|
34
|
+
resolveProviderKey
|
|
35
|
+
} from "./chunk-WXCFWUCN.mjs";
|
|
12
36
|
import {
|
|
13
37
|
ALIASES,
|
|
14
38
|
_setProfileBrainHook,
|
|
@@ -451,6 +475,7 @@ function lowerAnthropic(ir, profile, hints) {
|
|
|
451
475
|
const historyCacheableTokens = markIndex >= 0 ? sumHistoryTokens(history, markIndex) : 0;
|
|
452
476
|
const totalCacheableTokens = cacheableTokens + historyCacheableTokens;
|
|
453
477
|
const cacheSavings = totalCacheableTokens / 1e6 * profile.costInputPer1m * (1 - (profile.lowering.cache.discount ?? 0.1));
|
|
478
|
+
const toolChoice = hints.wireOverrides?.parallelToolCalls === false && tools && tools.length > 0 ? { type: "auto", disable_parallel_tool_use: true } : void 0;
|
|
454
479
|
return {
|
|
455
480
|
request: {
|
|
456
481
|
provider: "anthropic",
|
|
@@ -462,7 +487,8 @@ function lowerAnthropic(ir, profile, hints) {
|
|
|
462
487
|
// floor surprised every consumer once (PB-Cairn contract-gaps brief, Gap 3).
|
|
463
488
|
// Profile is the single source of truth; consumers wanting a tighter
|
|
464
489
|
// budget can pass providerOverrides.anthropic.max_tokens explicitly.
|
|
465
|
-
max_tokens: hints.forceTerseOutput ? 200 : profile.maxOutputTokens
|
|
490
|
+
max_tokens: hints.forceTerseOutput ? 200 : profile.maxOutputTokens,
|
|
491
|
+
tool_choice: toolChoice
|
|
466
492
|
},
|
|
467
493
|
diagnostics: {
|
|
468
494
|
cacheableTokens,
|
|
@@ -656,6 +682,7 @@ function lowerOpenAI(ir, profile, hints) {
|
|
|
656
682
|
const history = (ir.history ?? []).filter((m) => m.role !== "system");
|
|
657
683
|
const histMarkIndex = resolveHistoryMarkIndex(history.length, ir.historyCachePolicy);
|
|
658
684
|
const historyCacheableTokens = histMarkIndex >= 0 ? sumHistoryTokens(history, histMarkIndex) : 0;
|
|
685
|
+
const openaiParallelToolCalls = hints.wireOverrides?.parallelToolCalls === false && ir.tools && ir.tools.length > 0 ? false : void 0;
|
|
659
686
|
return {
|
|
660
687
|
request: {
|
|
661
688
|
provider: "openai",
|
|
@@ -663,7 +690,8 @@ function lowerOpenAI(ir, profile, hints) {
|
|
|
663
690
|
messages,
|
|
664
691
|
tools: ir.tools && ir.tools.length > 0 ? toOpenAITools(ir.tools) : void 0,
|
|
665
692
|
response_format: ir.constraints?.structuredOutput ? { type: "json_object" } : void 0,
|
|
666
|
-
reasoning_effort: hints.forceTerseOutput ? "low" : void 0
|
|
693
|
+
reasoning_effort: hints.forceTerseOutput ? "low" : void 0,
|
|
694
|
+
parallel_tool_calls: openaiParallelToolCalls
|
|
667
695
|
},
|
|
668
696
|
diagnostics: {
|
|
669
697
|
cacheableTokens: 0,
|
|
@@ -740,177 +768,6 @@ function setNestedField(obj, path, value) {
|
|
|
740
768
|
cursor[parts[parts.length - 1]] = value;
|
|
741
769
|
}
|
|
742
770
|
|
|
743
|
-
// src/brain-query.ts
|
|
744
|
-
var FRESH_SNAPSHOT = {
|
|
745
|
-
data: null,
|
|
746
|
-
expiresAt: 0,
|
|
747
|
-
refreshing: false,
|
|
748
|
-
warned: false
|
|
749
|
-
};
|
|
750
|
-
var snapshot = { ...FRESH_SNAPSHOT };
|
|
751
|
-
var runtime;
|
|
752
|
-
function configureBrainQuery(rt) {
|
|
753
|
-
runtime = rt;
|
|
754
|
-
snapshot = { ...FRESH_SNAPSHOT };
|
|
755
|
-
}
|
|
756
|
-
function createBrainQueryCache(opts) {
|
|
757
|
-
return () => {
|
|
758
|
-
const rt = runtime;
|
|
759
|
-
if (!rt || !rt.enabledTables.has(opts.table)) {
|
|
760
|
-
return opts.bundledFallback();
|
|
761
|
-
}
|
|
762
|
-
const now = Date.now();
|
|
763
|
-
const stale = snapshot.expiresAt <= now;
|
|
764
|
-
if (stale && !snapshot.refreshing) {
|
|
765
|
-
snapshot.refreshing = true;
|
|
766
|
-
void asyncRefresh(rt);
|
|
767
|
-
}
|
|
768
|
-
if (snapshot.data) {
|
|
769
|
-
const rows = snapshot.data[opts.table];
|
|
770
|
-
if (Array.isArray(rows) && rows.length > 0) {
|
|
771
|
-
try {
|
|
772
|
-
return opts.mapRows(rows);
|
|
773
|
-
} catch {
|
|
774
|
-
return opts.bundledFallback();
|
|
775
|
-
}
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
return opts.bundledFallback();
|
|
779
|
-
};
|
|
780
|
-
}
|
|
781
|
-
var pendingRefresh;
|
|
782
|
-
async function asyncRefresh(rt) {
|
|
783
|
-
const promise = doRefresh(rt);
|
|
784
|
-
pendingRefresh = promise;
|
|
785
|
-
try {
|
|
786
|
-
await promise;
|
|
787
|
-
} finally {
|
|
788
|
-
if (pendingRefresh === promise) pendingRefresh = void 0;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
var DEFAULT_CONFIG_URL = "https://kgauto-dashboard.vercel.app/api/kgauto-v2/config";
|
|
792
|
-
async function doRefresh(rt) {
|
|
793
|
-
const url = rt.configEndpoint ?? DEFAULT_CONFIG_URL;
|
|
794
|
-
try {
|
|
795
|
-
const res = await rt.fetchImpl(url, { method: "GET" });
|
|
796
|
-
if (!res.ok) {
|
|
797
|
-
throw new Error(`brain-query ${res.status}: ${res.statusText}`);
|
|
798
|
-
}
|
|
799
|
-
const body = await res.json();
|
|
800
|
-
if (runtime !== rt) return;
|
|
801
|
-
snapshot = {
|
|
802
|
-
data: body,
|
|
803
|
-
expiresAt: Date.now() + rt.ttlMs,
|
|
804
|
-
refreshing: false,
|
|
805
|
-
warned: snapshot.warned
|
|
806
|
-
};
|
|
807
|
-
} catch (err) {
|
|
808
|
-
if (runtime !== rt) return;
|
|
809
|
-
snapshot.refreshing = false;
|
|
810
|
-
snapshot.expiresAt = Date.now() + rt.ttlMs;
|
|
811
|
-
if (!snapshot.warned) {
|
|
812
|
-
snapshot.warned = true;
|
|
813
|
-
(rt.onError ?? defaultOnError)(err);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
function defaultOnError(err) {
|
|
818
|
-
console.warn("[kgauto] brain-query failed (using bundled fallback):", err);
|
|
819
|
-
}
|
|
820
|
-
function isBrainQueryActiveFor(table) {
|
|
821
|
-
return runtime !== void 0 && runtime.enabledTables.has(table);
|
|
822
|
-
}
|
|
823
|
-
async function getPerAxisMetrics(opts) {
|
|
824
|
-
const fetchFn = opts.fetch ?? fetch;
|
|
825
|
-
const endpoint = opts.endpoint ?? runtime?.endpoint;
|
|
826
|
-
if (!endpoint) return null;
|
|
827
|
-
const windowDays = opts.windowDays ?? 30;
|
|
828
|
-
const body = {
|
|
829
|
-
p_app_id: opts.appId,
|
|
830
|
-
p_archetype: opts.archetype,
|
|
831
|
-
p_model: opts.model,
|
|
832
|
-
p_window_days: windowDays,
|
|
833
|
-
p_quality_floor: opts.qualityFloor ?? null
|
|
834
|
-
};
|
|
835
|
-
const headers = {
|
|
836
|
-
Accept: "application/json",
|
|
837
|
-
"Content-Type": "application/json",
|
|
838
|
-
...opts.apiKey ? { Authorization: `Bearer ${opts.apiKey}` } : {}
|
|
839
|
-
};
|
|
840
|
-
try {
|
|
841
|
-
const res = await fetchFn(`${endpoint}/rpc/get_per_axis_metrics`, {
|
|
842
|
-
method: "POST",
|
|
843
|
-
headers,
|
|
844
|
-
body: JSON.stringify(body)
|
|
845
|
-
});
|
|
846
|
-
if (!res.ok) return null;
|
|
847
|
-
const raw = await res.json();
|
|
848
|
-
return mapPerAxisMetrics(raw, opts.appId, opts.archetype, opts.model, windowDays);
|
|
849
|
-
} catch {
|
|
850
|
-
return null;
|
|
851
|
-
}
|
|
852
|
-
}
|
|
853
|
-
function mapPerAxisMetrics(raw, fallbackAppId, fallbackArchetype, fallbackModel, fallbackWindowDays) {
|
|
854
|
-
if (raw === null || raw === void 0) return null;
|
|
855
|
-
if (typeof raw !== "object") return null;
|
|
856
|
-
const r = raw;
|
|
857
|
-
if (Array.isArray(raw)) {
|
|
858
|
-
if (raw.length === 0) return null;
|
|
859
|
-
return mapPerAxisMetrics(raw[0], fallbackAppId, fallbackArchetype, fallbackModel, fallbackWindowDays);
|
|
860
|
-
}
|
|
861
|
-
const num = (v) => {
|
|
862
|
-
if (v === null || v === void 0) return null;
|
|
863
|
-
if (typeof v === "number") return Number.isFinite(v) ? v : null;
|
|
864
|
-
if (typeof v === "string") {
|
|
865
|
-
const n = Number(v);
|
|
866
|
-
return Number.isFinite(n) ? n : null;
|
|
867
|
-
}
|
|
868
|
-
return null;
|
|
869
|
-
};
|
|
870
|
-
const int = (v) => {
|
|
871
|
-
const n = num(v);
|
|
872
|
-
return n === null ? 0 : Math.trunc(n);
|
|
873
|
-
};
|
|
874
|
-
const bool = (v) => {
|
|
875
|
-
if (v === null || v === void 0) return null;
|
|
876
|
-
if (typeof v === "boolean") return v;
|
|
877
|
-
return null;
|
|
878
|
-
};
|
|
879
|
-
const str = (v, fallback) => typeof v === "string" ? v : fallback;
|
|
880
|
-
const cost = r.cost_efficiency ?? {};
|
|
881
|
-
const time = r.time_efficiency ?? {};
|
|
882
|
-
const rel = r.reliability ?? {};
|
|
883
|
-
return {
|
|
884
|
-
appId: str(r.app_id, fallbackAppId),
|
|
885
|
-
archetype: str(r.archetype, fallbackArchetype),
|
|
886
|
-
model: str(r.model, fallbackModel),
|
|
887
|
-
windowDays: num(r.window_days) ?? fallbackWindowDays,
|
|
888
|
-
nRows: int(r.n_rows),
|
|
889
|
-
nRowsClean: int(r.n_rows_clean),
|
|
890
|
-
nQualityOutcomes: int(r.n_quality_outcomes),
|
|
891
|
-
magicRate: num(r.magic_rate),
|
|
892
|
-
qualityFloorMet: bool(r.quality_floor_met),
|
|
893
|
-
costEfficiency: {
|
|
894
|
-
avgCostUsd: num(cost.avg_cost_usd),
|
|
895
|
-
avgCostUsdClean: num(cost.avg_cost_usd_clean),
|
|
896
|
-
avgInputTokens: num(cost.avg_input_tokens),
|
|
897
|
-
avgOutputTokens: num(cost.avg_output_tokens),
|
|
898
|
-
inputTokenRatio: num(cost.input_token_ratio)
|
|
899
|
-
},
|
|
900
|
-
timeEfficiency: {
|
|
901
|
-
avgLatencyMs: num(time.avg_latency_ms),
|
|
902
|
-
avgTtftMs: num(time.avg_ttft_ms)
|
|
903
|
-
},
|
|
904
|
-
reliability: {
|
|
905
|
-
successRate: num(rel.success_rate),
|
|
906
|
-
successRateClean: num(rel.success_rate_clean),
|
|
907
|
-
emptyRate: num(rel.empty_rate),
|
|
908
|
-
emptyRateClean: num(rel.empty_rate_clean)
|
|
909
|
-
},
|
|
910
|
-
evidenceFreshnessDays: num(r.evidence_freshness_days)
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
|
|
914
771
|
// src/archetype-perf-brain.ts
|
|
915
772
|
function isPerfRow(x) {
|
|
916
773
|
if (!x || typeof x !== "object") return false;
|
|
@@ -984,8 +841,19 @@ function runAdvisor(ir, result, profile, policy, phase2) {
|
|
|
984
841
|
out.push(...detectModelStaleEvidence(ir, profile));
|
|
985
842
|
out.push(...detectTierDown(ir, profile, phase2));
|
|
986
843
|
}
|
|
844
|
+
if (!translatorClearedToolCallCliff(phase2)) {
|
|
845
|
+
out.push(...detectArchetypePerfFloorBreach(ir, profile));
|
|
846
|
+
}
|
|
987
847
|
return out;
|
|
988
848
|
}
|
|
849
|
+
function translatorClearedToolCallCliff(phase2) {
|
|
850
|
+
const rewrites = phase2?.sectionRewritesApplied;
|
|
851
|
+
if (!rewrites || rewrites.length === 0) return false;
|
|
852
|
+
for (const rw of rewrites) {
|
|
853
|
+
if (rw.kind === "tool_call_contract") return true;
|
|
854
|
+
}
|
|
855
|
+
return false;
|
|
856
|
+
}
|
|
989
857
|
function detectCachingOff(ir, profile) {
|
|
990
858
|
if (profile.provider !== "anthropic") return [];
|
|
991
859
|
const totalChars = ir.sections.reduce((s, sec) => s + sec.text.length, 0);
|
|
@@ -1154,6 +1022,77 @@ function detectTierDown(ir, profile, phase2) {
|
|
|
1154
1022
|
}
|
|
1155
1023
|
];
|
|
1156
1024
|
}
|
|
1025
|
+
function detectArchetypePerfFloorBreach(ir, profile) {
|
|
1026
|
+
const compat = getModelCompatibility(profile.id, {
|
|
1027
|
+
archetype: ir.intent.archetype,
|
|
1028
|
+
toolOrchestration: ir.constraints?.toolOrchestration
|
|
1029
|
+
});
|
|
1030
|
+
if (compat.status === "compatible") return [];
|
|
1031
|
+
if (compat.status === "requires-adapter") {
|
|
1032
|
+
return [
|
|
1033
|
+
{
|
|
1034
|
+
level: "warn",
|
|
1035
|
+
code: "archetype-perf-floor-breach",
|
|
1036
|
+
message: `${profile.id} sits below the archetype floor for ${ir.intent.archetype} (score ${compat.archetypePerf}/10, floor ${6}). A known adapter would lift it: ${compat.adapter.parameter}=${compat.adapter.value}. ${compat.adapter.consequence}`,
|
|
1037
|
+
suggestion: `Pass \`ir.constraints.${compat.adapter.parameter} = '${compat.adapter.value}'\` for this call, OR pick a model whose archetypePerf for ${ir.intent.archetype} already clears the floor (call \`getModelCompatibility(modelId, { archetype: '${ir.intent.archetype}' })\` to check). Estimated post-adapter score: ${compat.archetypePerfWithAdapter}/10.`,
|
|
1038
|
+
recommendationType: "prompt-fix",
|
|
1039
|
+
suggestedAdaptation: compat.adapter,
|
|
1040
|
+
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories"
|
|
1041
|
+
}
|
|
1042
|
+
];
|
|
1043
|
+
}
|
|
1044
|
+
return [
|
|
1045
|
+
{
|
|
1046
|
+
level: "critical",
|
|
1047
|
+
code: "archetype-perf-floor-breach",
|
|
1048
|
+
message: `${profile.id} sits below the archetype floor for ${ir.intent.archetype} (score ${compat.archetypePerf}/10, floor ${6}) and no known adapter would lift it. ${compat.reason}`,
|
|
1049
|
+
suggestion: `Swap to a model whose archetypePerf for ${ir.intent.archetype} clears the floor. Use \`getModelCompatibility(candidateId, { archetype: '${ir.intent.archetype}' })\` to vet candidates, or \`getDefaultFallbackChain({ archetype: '${ir.intent.archetype}', posture: 'open' })\` for a library-picked chain that respects the floor by construction.`,
|
|
1050
|
+
recommendationType: "model-swap",
|
|
1051
|
+
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories"
|
|
1052
|
+
}
|
|
1053
|
+
];
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
// src/translator.ts
|
|
1057
|
+
var TRANSLATOR_FLOOR = ARCHETYPE_FLOOR_DEFAULT;
|
|
1058
|
+
var RULE_SEQUENTIAL_TOOL_CLIFF = "sequential-tool-cliff-below-floor";
|
|
1059
|
+
var SEQUENTIAL_TOOL_PREAMBLE = "IMPORTANT: Use one tool call per response. Wait for the tool result before deciding the next tool. Do NOT batch tool calls in parallel.";
|
|
1060
|
+
function applySectionRewrites(args) {
|
|
1061
|
+
const { ir, profile, archetype } = args;
|
|
1062
|
+
if (!Array.isArray(ir.sections) || ir.sections.length === 0) {
|
|
1063
|
+
return { rewrittenIR: ir, rewrites: [] };
|
|
1064
|
+
}
|
|
1065
|
+
if (!profile.archetypePerf) {
|
|
1066
|
+
return { rewrittenIR: ir, rewrites: [] };
|
|
1067
|
+
}
|
|
1068
|
+
const archetypeScore = profile.archetypePerf[archetype];
|
|
1069
|
+
const cliffFires = typeof archetypeScore === "number" && archetypeScore < TRANSLATOR_FLOOR;
|
|
1070
|
+
if (!cliffFires) {
|
|
1071
|
+
return { rewrittenIR: ir, rewrites: [] };
|
|
1072
|
+
}
|
|
1073
|
+
const rewrites = [];
|
|
1074
|
+
const newSections = ir.sections.map((section) => {
|
|
1075
|
+
if (section.kind !== "tool_call_contract") return section;
|
|
1076
|
+
const originalText = section.text;
|
|
1077
|
+
const transformedText = `${SEQUENTIAL_TOOL_PREAMBLE}
|
|
1078
|
+
|
|
1079
|
+
${originalText}`;
|
|
1080
|
+
rewrites.push({
|
|
1081
|
+
sectionId: section.id,
|
|
1082
|
+
kind: "tool_call_contract",
|
|
1083
|
+
rule: RULE_SEQUENTIAL_TOOL_CLIFF,
|
|
1084
|
+
originalText,
|
|
1085
|
+
transformedText,
|
|
1086
|
+
wireOverrides: { parallelToolCalls: false }
|
|
1087
|
+
});
|
|
1088
|
+
return { ...section, text: transformedText };
|
|
1089
|
+
});
|
|
1090
|
+
if (rewrites.length === 0) {
|
|
1091
|
+
return { rewrittenIR: ir, rewrites: [] };
|
|
1092
|
+
}
|
|
1093
|
+
const rewrittenIR = { ...ir, sections: newSections };
|
|
1094
|
+
return { rewrittenIR, rewrites };
|
|
1095
|
+
}
|
|
1157
1096
|
|
|
1158
1097
|
// src/compile.ts
|
|
1159
1098
|
var counter = 0;
|
|
@@ -1198,9 +1137,33 @@ function compile(ir, opts = {}) {
|
|
|
1198
1137
|
const cliffs = passApplyCliffs(workingIR, profile, inputTokens);
|
|
1199
1138
|
workingIR = cliffs.value.ir;
|
|
1200
1139
|
accumulatedMutations.push(...cliffs.mutations);
|
|
1140
|
+
const translated = applySectionRewrites({
|
|
1141
|
+
ir: workingIR,
|
|
1142
|
+
profile,
|
|
1143
|
+
archetype: ir.intent.archetype
|
|
1144
|
+
});
|
|
1145
|
+
workingIR = translated.rewrittenIR;
|
|
1146
|
+
const sectionRewritesApplied = translated.rewrites;
|
|
1147
|
+
let wireOverrides;
|
|
1148
|
+
for (const rw of sectionRewritesApplied) {
|
|
1149
|
+
if (!rw.wireOverrides) continue;
|
|
1150
|
+
if (!wireOverrides) wireOverrides = {};
|
|
1151
|
+
if (rw.wireOverrides.parallelToolCalls !== void 0) {
|
|
1152
|
+
wireOverrides.parallelToolCalls = rw.wireOverrides.parallelToolCalls;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
for (const rw of sectionRewritesApplied) {
|
|
1156
|
+
accumulatedMutations.push({
|
|
1157
|
+
id: `translator:${rw.rule}:${rw.sectionId}`,
|
|
1158
|
+
source: "translator",
|
|
1159
|
+
passName: "translator",
|
|
1160
|
+
description: `Rewrote section "${rw.sectionId}" (kind=${rw.kind}) via rule "${rw.rule}".`
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1201
1163
|
const lowered = lower(workingIR, profile, {
|
|
1202
1164
|
forceThinkingZero: cliffs.value.loweringHints.forceThinkingZero,
|
|
1203
|
-
forceTerseOutput: cliffs.value.loweringHints.forceTerseOutput
|
|
1165
|
+
forceTerseOutput: cliffs.value.loweringHints.forceTerseOutput,
|
|
1166
|
+
wireOverrides
|
|
1204
1167
|
});
|
|
1205
1168
|
validateFinalFit(workingIR, profile, inputTokens);
|
|
1206
1169
|
const handle = makeHandle();
|
|
@@ -1248,7 +1211,13 @@ function compile(ir, opts = {}) {
|
|
|
1248
1211
|
opts.policy,
|
|
1249
1212
|
{
|
|
1250
1213
|
fallbackChain,
|
|
1251
|
-
profileResolver: phase2ProfileResolver
|
|
1214
|
+
profileResolver: phase2ProfileResolver,
|
|
1215
|
+
// alpha.29 — feed translator rewrites to the advisor so the
|
|
1216
|
+
// `archetype-perf-floor-breach` rule can suppress when the translator
|
|
1217
|
+
// already cleared the cliff for the same archetype. Without this,
|
|
1218
|
+
// both the rewrite AND the advisory fire — noisy, and the advisory
|
|
1219
|
+
// would mislead consumers into thinking the cliff is unaddressed.
|
|
1220
|
+
sectionRewritesApplied
|
|
1252
1221
|
}
|
|
1253
1222
|
);
|
|
1254
1223
|
return {
|
|
@@ -1261,7 +1230,9 @@ function compile(ir, opts = {}) {
|
|
|
1261
1230
|
mutationsApplied: accumulatedMutations,
|
|
1262
1231
|
fallbackChain,
|
|
1263
1232
|
advisories,
|
|
1264
|
-
diagnostics
|
|
1233
|
+
diagnostics,
|
|
1234
|
+
sectionRewritesApplied,
|
|
1235
|
+
wireOverrides
|
|
1265
1236
|
};
|
|
1266
1237
|
}
|
|
1267
1238
|
function validateIR(ir) {
|
|
@@ -1414,6 +1385,9 @@ function registerCompile(appId, archetype, ir, result) {
|
|
|
1414
1385
|
tokens
|
|
1415
1386
|
);
|
|
1416
1387
|
const shapeKey = `${shape.contextBucket}-${shape.toolCountBucket}-${shape.historyDepth}-${shape.outputMode}`;
|
|
1388
|
+
const toolsCount = result.diagnostics.toolsKept;
|
|
1389
|
+
const historyDepth = Array.isArray(ir.history) ? ir.history.length : 0;
|
|
1390
|
+
const systemPromptChars = estimateSystemPromptChars(ir.sections);
|
|
1417
1391
|
compileRegistry.set(result.handle, {
|
|
1418
1392
|
appId,
|
|
1419
1393
|
archetype,
|
|
@@ -1427,9 +1401,28 @@ function registerCompile(appId, archetype, ir, result) {
|
|
|
1427
1401
|
historyCacheableTokens: result.diagnostics.historyCacheableTokens,
|
|
1428
1402
|
historyTokensTotal: result.diagnostics.historyTokensTotal,
|
|
1429
1403
|
// alpha.20 E3: capture consumer's declared mode for the brain payload.
|
|
1430
|
-
toolOrchestration: result.diagnostics.toolOrchestration
|
|
1404
|
+
toolOrchestration: result.diagnostics.toolOrchestration,
|
|
1405
|
+
// alpha.28: shape fields for Glass-Box renderer.
|
|
1406
|
+
toolsCount,
|
|
1407
|
+
historyDepth,
|
|
1408
|
+
systemPromptChars,
|
|
1409
|
+
// alpha.29: translator activity — persisted on the brain row so
|
|
1410
|
+
// cross-app aggregates can answer "Sonnet narration rule fired N times,
|
|
1411
|
+
// outcome quality lifted to M."
|
|
1412
|
+
sectionRewritesApplied: result.sectionRewritesApplied
|
|
1431
1413
|
});
|
|
1432
1414
|
}
|
|
1415
|
+
function estimateSystemPromptChars(sections) {
|
|
1416
|
+
if (!Array.isArray(sections) || sections.length === 0) return void 0;
|
|
1417
|
+
let total = 0;
|
|
1418
|
+
for (const s of sections) {
|
|
1419
|
+
if (s && typeof s === "object") {
|
|
1420
|
+
const content = s.content;
|
|
1421
|
+
if (typeof content === "string") total += content.length;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
return total > 0 ? total : void 0;
|
|
1425
|
+
}
|
|
1433
1426
|
async function record(input) {
|
|
1434
1427
|
const reg = compileRegistry.get(input.handle);
|
|
1435
1428
|
if (reg) compileRegistry.delete(input.handle);
|
|
@@ -1466,7 +1459,7 @@ async function record(input) {
|
|
|
1466
1459
|
}
|
|
1467
1460
|
outcomeId = await tryExtractOutcomeId(res);
|
|
1468
1461
|
} catch (err) {
|
|
1469
|
-
(config.onError ??
|
|
1462
|
+
(config.onError ?? defaultOnError)(err);
|
|
1470
1463
|
return;
|
|
1471
1464
|
}
|
|
1472
1465
|
const advisories = input.advisories;
|
|
@@ -1488,7 +1481,7 @@ async function record(input) {
|
|
|
1488
1481
|
throw new Error(`brain advisories ${res.status}: ${text}`);
|
|
1489
1482
|
}
|
|
1490
1483
|
} catch (err) {
|
|
1491
|
-
(config.onError ??
|
|
1484
|
+
(config.onError ?? defaultOnError)(err);
|
|
1492
1485
|
}
|
|
1493
1486
|
};
|
|
1494
1487
|
if (config.sync) {
|
|
@@ -1497,7 +1490,7 @@ async function record(input) {
|
|
|
1497
1490
|
void send();
|
|
1498
1491
|
}
|
|
1499
1492
|
}
|
|
1500
|
-
function
|
|
1493
|
+
function defaultOnError(err) {
|
|
1501
1494
|
console.warn("[kgauto] brain record failed:", err);
|
|
1502
1495
|
}
|
|
1503
1496
|
function buildPayload(input, reg) {
|
|
@@ -1507,6 +1500,8 @@ function buildPayload(input, reg) {
|
|
|
1507
1500
|
const mutationsApplied = input.mutationsApplied ?? reg?.mutationsApplied ?? [];
|
|
1508
1501
|
const costModel = actual;
|
|
1509
1502
|
const costUsdActual = costModel ? computeCostUsd(costModel, input.tokensIn, input.tokensOut) : void 0;
|
|
1503
|
+
const fellOverFrom = input.fellOverFrom ?? requested;
|
|
1504
|
+
const fallbackReason = fellOverFrom ? input.fallbackReason : void 0;
|
|
1510
1505
|
return {
|
|
1511
1506
|
handle: input.handle,
|
|
1512
1507
|
app_id: reg?.appId,
|
|
@@ -1541,7 +1536,20 @@ function buildPayload(input, reg) {
|
|
|
1541
1536
|
// the brain can measure per-mode model perf separately (DeepSeek in
|
|
1542
1537
|
// sequential vs parallel mode is two different stories — L-040).
|
|
1543
1538
|
// Null when consumer hadn't adopted the constraint yet.
|
|
1544
|
-
tool_orchestration: reg?.toolOrchestration ?? null
|
|
1539
|
+
tool_orchestration: reg?.toolOrchestration ?? null,
|
|
1540
|
+
// alpha.28 — Glass-Box renderer substrate (migration 018). All optional;
|
|
1541
|
+
// omitted-undefined PostgREST inserts store NULL → renderer renders "—".
|
|
1542
|
+
finish_reason: input.finishReason,
|
|
1543
|
+
total_ms: input.totalMs ?? input.latencyMs,
|
|
1544
|
+
tools_count: input.toolsCount ?? reg?.toolsCount,
|
|
1545
|
+
history_depth: input.historyDepth ?? reg?.historyDepth,
|
|
1546
|
+
system_prompt_chars: input.systemPromptChars ?? reg?.systemPromptChars,
|
|
1547
|
+
fell_over_from: fellOverFrom,
|
|
1548
|
+
fallback_reason: fallbackReason,
|
|
1549
|
+
// alpha.29 — translator activity (migration 019). Send NULL when no
|
|
1550
|
+
// rewrites fired so the brain's "did the translator do anything?"
|
|
1551
|
+
// queries can use `IS NOT NULL` cleanly.
|
|
1552
|
+
section_rewrites_applied: reg?.sectionRewritesApplied && reg.sectionRewritesApplied.length > 0 ? reg.sectionRewritesApplied : null
|
|
1545
1553
|
};
|
|
1546
1554
|
}
|
|
1547
1555
|
function computeCostUsd(modelId, tokensIn, tokensOut) {
|
|
@@ -1614,12 +1622,12 @@ async function recordOutcome(input) {
|
|
|
1614
1622
|
if (!res.ok) {
|
|
1615
1623
|
const text = await res.text().catch(() => "<no body>");
|
|
1616
1624
|
const err = new Error(`brain ${res.status}: ${text}`);
|
|
1617
|
-
(config.onError ??
|
|
1625
|
+
(config.onError ?? defaultOnError)(err);
|
|
1618
1626
|
return { ok: false, reason: "persistence_failed" };
|
|
1619
1627
|
}
|
|
1620
1628
|
return { ok: true };
|
|
1621
1629
|
} catch (err) {
|
|
1622
|
-
(config.onError ??
|
|
1630
|
+
(config.onError ?? defaultOnError)(err);
|
|
1623
1631
|
return { ok: false, reason: "persistence_failed" };
|
|
1624
1632
|
}
|
|
1625
1633
|
};
|
|
@@ -1644,67 +1652,6 @@ var CallError = class extends Error {
|
|
|
1644
1652
|
}
|
|
1645
1653
|
};
|
|
1646
1654
|
|
|
1647
|
-
// src/env.ts
|
|
1648
|
-
var SUPPORTED_PROVIDERS = Object.freeze([
|
|
1649
|
-
"anthropic",
|
|
1650
|
-
"google",
|
|
1651
|
-
"openai",
|
|
1652
|
-
"deepseek"
|
|
1653
|
-
]);
|
|
1654
|
-
function isSupportedProvider(p) {
|
|
1655
|
-
return SUPPORTED_PROVIDERS.includes(p);
|
|
1656
|
-
}
|
|
1657
|
-
var PROVIDER_ENV_KEYS = Object.freeze({
|
|
1658
|
-
anthropic: Object.freeze(["ANTHROPIC_API_KEY"]),
|
|
1659
|
-
google: Object.freeze([
|
|
1660
|
-
"GOOGLE_API_KEY",
|
|
1661
|
-
"GEMINI_API_KEY",
|
|
1662
|
-
"GOOGLE_GENERATIVE_AI_API_KEY"
|
|
1663
|
-
]),
|
|
1664
|
-
openai: Object.freeze(["OPENAI_API_KEY"]),
|
|
1665
|
-
deepseek: Object.freeze(["DEEPSEEK_API_KEY"])
|
|
1666
|
-
});
|
|
1667
|
-
function defaultEnv() {
|
|
1668
|
-
return typeof process !== "undefined" && process.env ? process.env : {};
|
|
1669
|
-
}
|
|
1670
|
-
function readKeyValue(raw) {
|
|
1671
|
-
if (raw === void 0) return void 0;
|
|
1672
|
-
const trimmed = raw.trim();
|
|
1673
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
1674
|
-
}
|
|
1675
|
-
function resolveProviderKey(provider, opts = {}) {
|
|
1676
|
-
if (!isSupportedProvider(provider)) return void 0;
|
|
1677
|
-
const explicit = readKeyValue(opts.apiKeys?.[provider]);
|
|
1678
|
-
if (explicit) return explicit;
|
|
1679
|
-
const env = opts.envSource ?? defaultEnv();
|
|
1680
|
-
for (const name of PROVIDER_ENV_KEYS[provider]) {
|
|
1681
|
-
const v = readKeyValue(env[name]);
|
|
1682
|
-
if (v) return v;
|
|
1683
|
-
}
|
|
1684
|
-
return void 0;
|
|
1685
|
-
}
|
|
1686
|
-
function isProviderReachable(provider, opts = {}) {
|
|
1687
|
-
return resolveProviderKey(provider, opts) !== void 0;
|
|
1688
|
-
}
|
|
1689
|
-
function isModelReachable(modelId, opts = {}) {
|
|
1690
|
-
const profile = tryGetProfile(modelId);
|
|
1691
|
-
if (!profile) return false;
|
|
1692
|
-
return isProviderReachable(profile.provider, opts);
|
|
1693
|
-
}
|
|
1694
|
-
function getReachabilityDiagnostic(opts = {}) {
|
|
1695
|
-
const env = opts.envSource ?? defaultEnv();
|
|
1696
|
-
const out = {};
|
|
1697
|
-
for (const provider of SUPPORTED_PROVIDERS) {
|
|
1698
|
-
if (readKeyValue(opts.apiKeys?.[provider])) {
|
|
1699
|
-
out[provider] = { reachable: true, via: "apiKeys" };
|
|
1700
|
-
continue;
|
|
1701
|
-
}
|
|
1702
|
-
const envKeyFound = PROVIDER_ENV_KEYS[provider].find((name) => readKeyValue(env[name]));
|
|
1703
|
-
out[provider] = envKeyFound ? { reachable: true, via: "env", envKeyFound } : { reachable: false, via: null };
|
|
1704
|
-
}
|
|
1705
|
-
return out;
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
1655
|
// src/execute.ts
|
|
1709
1656
|
var ANTHROPIC_URL = "https://api.anthropic.com/v1/messages";
|
|
1710
1657
|
var OPENAI_URL = "https://api.openai.com/v1/chat/completions";
|
|
@@ -1923,344 +1870,6 @@ function tryParseJson(s) {
|
|
|
1923
1870
|
}
|
|
1924
1871
|
}
|
|
1925
1872
|
|
|
1926
|
-
// src/chains-brain.ts
|
|
1927
|
-
function isChainsRow(x) {
|
|
1928
|
-
if (!x || typeof x !== "object") return false;
|
|
1929
|
-
const r = x;
|
|
1930
|
-
return typeof r.archetype === "string" && typeof r.tier === "number" && typeof r.model_id === "string";
|
|
1931
|
-
}
|
|
1932
|
-
function mapRowsToChains(rows) {
|
|
1933
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
1934
|
-
for (const row of rows) {
|
|
1935
|
-
if (!isChainsRow(row)) continue;
|
|
1936
|
-
const list = grouped.get(row.archetype) ?? [];
|
|
1937
|
-
list.push(row);
|
|
1938
|
-
grouped.set(row.archetype, list);
|
|
1939
|
-
}
|
|
1940
|
-
const out = {};
|
|
1941
|
-
for (const [archetype, group] of grouped.entries()) {
|
|
1942
|
-
group.sort((a, b) => a.tier - b.tier);
|
|
1943
|
-
out[archetype] = group.map((r) => r.model_id);
|
|
1944
|
-
}
|
|
1945
|
-
const bundled = getAllStarterChains();
|
|
1946
|
-
for (const archetype of Object.keys(bundled)) {
|
|
1947
|
-
if (!out[archetype]) out[archetype] = bundled[archetype];
|
|
1948
|
-
}
|
|
1949
|
-
return out;
|
|
1950
|
-
}
|
|
1951
|
-
var loadChainsFromBrain = createBrainQueryCache({
|
|
1952
|
-
table: "kgauto_chains",
|
|
1953
|
-
mapRows: mapRowsToChains,
|
|
1954
|
-
bundledFallback: getAllStarterChains
|
|
1955
|
-
});
|
|
1956
|
-
|
|
1957
|
-
// src/fallback.ts
|
|
1958
|
-
var STARTER_CHAINS_GROUNDED = {
|
|
1959
|
-
// Reasoning floor — never degrade. Walk UP on 429 to Opus → cross-provider.
|
|
1960
|
-
critique: [
|
|
1961
|
-
{ id: "claude-opus-4-7", grounding: "judgment", reason: "Highest reasoning bar, no degradation tier \u2014 engineer pick, awaiting measured backing" },
|
|
1962
|
-
{ id: "claude-sonnet-4-6", grounding: "judgment", reason: "Same-provider walk-down from Opus on 429" },
|
|
1963
|
-
{ id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor in similar quality bracket" },
|
|
1964
|
-
{ id: "gpt-5.5", grounding: "judgment", reason: "alpha.16: third-provider frontier-tier floor (archetypePerf=9)" }
|
|
1965
|
-
],
|
|
1966
|
-
// Reasoning matters — Sonnet primary; walk UP to Opus on 429.
|
|
1967
|
-
plan: [
|
|
1968
|
-
{ id: "claude-sonnet-4-6", grounding: "judgment", reason: "Reasoning + cost balance \u2014 engineer pick" },
|
|
1969
|
-
{ id: "claude-opus-4-7", grounding: "judgment", reason: 'Same-provider walk-UP on 429 (rare exception to "always cheaper")' },
|
|
1970
|
-
{ id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor" },
|
|
1971
|
-
{ id: "deepseek-v4-pro", grounding: "judgment", reason: "Tier 3 cost floor \u2014 no brain evidence yet" }
|
|
1972
|
-
],
|
|
1973
|
-
// Quality + cost match.
|
|
1974
|
-
generate: [
|
|
1975
|
-
{ id: "claude-sonnet-4-6", grounding: "judgment", reason: "Quality + cost match \u2014 engineer pick" },
|
|
1976
|
-
{ id: "claude-haiku-4-5", grounding: "judgment", reason: "Same-provider step-down" },
|
|
1977
|
-
{ id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor" },
|
|
1978
|
-
{ id: "gpt-5.4-mini", grounding: "judgment", reason: "alpha.16: third-provider tail (archetypePerf=7) \u2014 closes mono-Anthropic gap" }
|
|
1979
|
-
],
|
|
1980
|
-
// ask::sonnet — STARTER_CHAINS calls this "Quality + cost match" but
|
|
1981
|
-
// tt-intel s78 prod data showed 27% empty rate. Labeled 'judgment' until
|
|
1982
|
-
// evidence either validates or refutes the placement.
|
|
1983
|
-
ask: [
|
|
1984
|
-
{ id: "claude-sonnet-4-6", grounding: "judgment", reason: "Quality + cost match \u2014 engineer pick. NOTE: tt-intel s78 prod showed 27% empty rate; placement awaits measurement validation" },
|
|
1985
|
-
{ id: "claude-haiku-4-5", grounding: "judgment", reason: "Same-provider step-down" },
|
|
1986
|
-
{ id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor" },
|
|
1987
|
-
{ id: "gpt-5.4-mini", grounding: "judgment", reason: "alpha.16: third-provider tail (archetypePerf=7)" }
|
|
1988
|
-
],
|
|
1989
|
-
// Structured-output archetype — Flash skipped (alpha.8 MAX_TOKENS cliff,
|
|
1990
|
-
// capability-fact); DeepSeek skipped (no brain evidence).
|
|
1991
|
-
extract: [
|
|
1992
|
-
{ id: "claude-sonnet-4-6", grounding: "judgment", reason: "Reliable structured-output anchor \u2014 engineer pick" },
|
|
1993
|
-
{ id: "claude-haiku-4-5", grounding: "judgment", reason: "Same-provider step-down with native structured output" },
|
|
1994
|
-
{ id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor with structured-output support" },
|
|
1995
|
-
{ id: "gpt-5.4", grounding: "capability-fact", reason: "alpha.16: third-provider floor \u2014 native structured-output capability (archetypePerf=8)" }
|
|
1996
|
-
],
|
|
1997
|
-
// Forgiving archetype — Sonnet primary but Flash safely floors it.
|
|
1998
|
-
transform: [
|
|
1999
|
-
{ id: "claude-sonnet-4-6", grounding: "judgment", reason: "Quality anchor \u2014 engineer pick" },
|
|
2000
|
-
{ id: "claude-haiku-4-5", grounding: "judgment", reason: "Same-provider step-down" },
|
|
2001
|
-
{ id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor" },
|
|
2002
|
-
{ id: "gemini-2.5-flash", grounding: "judgment", reason: "Cost floor \u2014 forgiving archetype tolerates Flash" }
|
|
2003
|
-
],
|
|
2004
|
-
// Parallel-tool throughput champion — Flash leads on the L-040 cliff
|
|
2005
|
-
// (capability-fact: Flash 15-75 parallel calls/step vs DeepSeek 7-8).
|
|
2006
|
-
hunt: [
|
|
2007
|
-
{ id: "gemini-2.5-flash", grounding: "capability-fact", reason: "L-040 parallel-tool throughput champion (15-75 calls/step)" },
|
|
2008
|
-
{ id: "gemini-2.5-pro", grounding: "capability-fact", reason: "Cross-provider tier 1 with strong parallel-tool support" },
|
|
2009
|
-
{ id: "claude-sonnet-4-6", grounding: "judgment", reason: "Quality safety net for blocked-Flash case" },
|
|
2010
|
-
{ id: "claude-haiku-4-5", grounding: "judgment", reason: "Reduced tool budget \u2014 cliff at 16 fires" }
|
|
2011
|
-
],
|
|
2012
|
-
// Cost-sensitive + tolerant. DeepSeek brain-evidence tier 1.
|
|
2013
|
-
summarize: [
|
|
2014
|
-
{ id: "gemini-2.5-flash", grounding: "judgment", reason: "Cost-sensitive primary \u2014 engineer pick" },
|
|
2015
|
-
{ id: "deepseek-v4-flash", grounding: "measured", reason: "Brain-validated tier 1 for cost-sensitive summarize workloads", n: 169 },
|
|
2016
|
-
{ id: "claude-haiku-4-5", grounding: "judgment", reason: "Quality safety net" },
|
|
2017
|
-
{ id: "gemini-2.5-flash-lite", grounding: "judgment", reason: "Emergency floor \u2014 onboarded s22, no brain evidence yet" }
|
|
2018
|
-
],
|
|
2019
|
-
// Brain-validated DeepSeek tier 1 (169 rows, 0% empty rate).
|
|
2020
|
-
classify: [
|
|
2021
|
-
{ id: "gemini-2.5-flash", grounding: "judgment", reason: "Cost-sensitive primary \u2014 engineer pick" },
|
|
2022
|
-
{ id: "deepseek-v4-flash", grounding: "measured", reason: "Brain-validated tier 1 (169 rows, 0% empty rate)", n: 169 },
|
|
2023
|
-
{ id: "claude-haiku-4-5", grounding: "judgment", reason: "Quality safety net" },
|
|
2024
|
-
{ id: "gemini-2.5-flash-lite", grounding: "judgment", reason: "Cache-discount 10\xD7 floor for repeat-prompt workloads" }
|
|
2025
|
-
]
|
|
2026
|
-
};
|
|
2027
|
-
var STARTER_CHAINS = (() => {
|
|
2028
|
-
const out = {};
|
|
2029
|
-
for (const [archetype, entries] of Object.entries(STARTER_CHAINS_GROUNDED)) {
|
|
2030
|
-
out[archetype] = entries.map((e) => e.id);
|
|
2031
|
-
}
|
|
2032
|
-
return out;
|
|
2033
|
-
})();
|
|
2034
|
-
var STARTER_CHAINS_BY_MODE_GROUNDED = {
|
|
2035
|
-
hunt: {
|
|
2036
|
-
sequential: [
|
|
2037
|
-
{
|
|
2038
|
-
id: "deepseek-v4-pro",
|
|
2039
|
-
grounding: "judgment",
|
|
2040
|
-
reason: "alpha.20 E3: cheap + good reasoning at single-step granularity; L-040 cliff silenced when sequential \u2014 hypothesis not yet measured"
|
|
2041
|
-
},
|
|
2042
|
-
{
|
|
2043
|
-
id: "deepseek-v4-flash",
|
|
2044
|
-
grounding: "judgment",
|
|
2045
|
-
reason: "Cheapest viable; sibling-provider fallback"
|
|
2046
|
-
},
|
|
2047
|
-
{
|
|
2048
|
-
id: "claude-sonnet-4-6",
|
|
2049
|
-
grounding: "judgment",
|
|
2050
|
-
reason: "Cross-provider safety net \u2014 Sonnet handles sequential agentic loops cleanly"
|
|
2051
|
-
},
|
|
2052
|
-
{
|
|
2053
|
-
id: "gemini-2.5-pro",
|
|
2054
|
-
grounding: "judgment",
|
|
2055
|
-
reason: "Third-provider tail when no DeepSeek key reachable"
|
|
2056
|
-
}
|
|
2057
|
-
]
|
|
2058
|
-
}
|
|
2059
|
-
};
|
|
2060
|
-
var STARTER_CHAINS_BY_MODE = (() => {
|
|
2061
|
-
const out = {};
|
|
2062
|
-
for (const [archetype, modes] of Object.entries(STARTER_CHAINS_BY_MODE_GROUNDED)) {
|
|
2063
|
-
if (modes?.sequential) {
|
|
2064
|
-
out[archetype] = {
|
|
2065
|
-
sequential: modes.sequential.map((e) => e.id)
|
|
2066
|
-
};
|
|
2067
|
-
}
|
|
2068
|
-
}
|
|
2069
|
-
return out;
|
|
2070
|
-
})();
|
|
2071
|
-
function resolveStarterForMode(archetype, toolOrchestration, allChains) {
|
|
2072
|
-
if (toolOrchestration === "sequential") {
|
|
2073
|
-
const overlay = STARTER_CHAINS_BY_MODE[archetype]?.sequential;
|
|
2074
|
-
if (overlay) return [...overlay];
|
|
2075
|
-
}
|
|
2076
|
-
return allChains[archetype];
|
|
2077
|
-
}
|
|
2078
|
-
function getDefaultFallbackChain(opts) {
|
|
2079
|
-
const { archetype, primary, maxDepth = 3, policy, reachability, toolOrchestration } = opts;
|
|
2080
|
-
if (maxDepth < 1) {
|
|
2081
|
-
throw new Error(
|
|
2082
|
-
`getDefaultFallbackChain: maxDepth must be >= 1, got ${maxDepth}`
|
|
2083
|
-
);
|
|
2084
|
-
}
|
|
2085
|
-
const allChains = loadChainsFromBrain();
|
|
2086
|
-
const starter = resolveStarterForMode(archetype, toolOrchestration, allChains);
|
|
2087
|
-
if (!starter) {
|
|
2088
|
-
throw new Error(
|
|
2089
|
-
`getDefaultFallbackChain: unknown archetype "${archetype}". Known: ${Object.keys(allChains).join(", ")}`
|
|
2090
|
-
);
|
|
2091
|
-
}
|
|
2092
|
-
let chain;
|
|
2093
|
-
if (primary) {
|
|
2094
|
-
chain = [primary, ...starter.filter((id) => id !== primary)];
|
|
2095
|
-
} else {
|
|
2096
|
-
chain = [...starter];
|
|
2097
|
-
}
|
|
2098
|
-
if (policy?.blockedModels && policy.blockedModels.length > 0) {
|
|
2099
|
-
const blocked = new Set(policy.blockedModels);
|
|
2100
|
-
chain = chain.filter((id) => !blocked.has(id));
|
|
2101
|
-
}
|
|
2102
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2103
|
-
const deduped = [];
|
|
2104
|
-
for (const id of chain) {
|
|
2105
|
-
if (!seen.has(id)) {
|
|
2106
|
-
seen.add(id);
|
|
2107
|
-
deduped.push(id);
|
|
2108
|
-
}
|
|
2109
|
-
}
|
|
2110
|
-
let filtered = deduped;
|
|
2111
|
-
if (reachability) {
|
|
2112
|
-
filtered = deduped.filter((id) => isModelReachable(id, reachability));
|
|
2113
|
-
}
|
|
2114
|
-
return filtered.slice(0, maxDepth);
|
|
2115
|
-
}
|
|
2116
|
-
function getStarterChain(archetype) {
|
|
2117
|
-
const chain = STARTER_CHAINS[archetype];
|
|
2118
|
-
if (!chain) {
|
|
2119
|
-
throw new Error(
|
|
2120
|
-
`getStarterChain: unknown archetype "${archetype}"`
|
|
2121
|
-
);
|
|
2122
|
-
}
|
|
2123
|
-
return [...chain];
|
|
2124
|
-
}
|
|
2125
|
-
function getAllStarterChains() {
|
|
2126
|
-
const out = {};
|
|
2127
|
-
for (const [archetype, chain] of Object.entries(STARTER_CHAINS)) {
|
|
2128
|
-
out[archetype] = [...chain];
|
|
2129
|
-
}
|
|
2130
|
-
return out;
|
|
2131
|
-
}
|
|
2132
|
-
function getSequentialStarterChain(archetype) {
|
|
2133
|
-
const overlay = STARTER_CHAINS_BY_MODE[archetype]?.sequential;
|
|
2134
|
-
return overlay ? [...overlay] : void 0;
|
|
2135
|
-
}
|
|
2136
|
-
function copyEntry(e) {
|
|
2137
|
-
const out = { id: e.id, grounding: e.grounding };
|
|
2138
|
-
if (e.reason !== void 0) out.reason = e.reason;
|
|
2139
|
-
if (e.n !== void 0) out.n = e.n;
|
|
2140
|
-
return out;
|
|
2141
|
-
}
|
|
2142
|
-
function lookupStaticEntry(id, archetype) {
|
|
2143
|
-
const archetypeEntries = STARTER_CHAINS_GROUNDED[archetype];
|
|
2144
|
-
if (archetypeEntries) {
|
|
2145
|
-
const hit = archetypeEntries.find((e) => e.id === id);
|
|
2146
|
-
if (hit) return hit;
|
|
2147
|
-
}
|
|
2148
|
-
const seqOverlay = STARTER_CHAINS_BY_MODE_GROUNDED[archetype]?.sequential;
|
|
2149
|
-
if (seqOverlay) {
|
|
2150
|
-
const hit = seqOverlay.find((e) => e.id === id);
|
|
2151
|
-
if (hit) return hit;
|
|
2152
|
-
}
|
|
2153
|
-
return void 0;
|
|
2154
|
-
}
|
|
2155
|
-
function resolveGroundedChainForArchetype(archetype, toolOrchestration) {
|
|
2156
|
-
if (toolOrchestration === "sequential") {
|
|
2157
|
-
const overlay = STARTER_CHAINS_BY_MODE_GROUNDED[archetype]?.sequential;
|
|
2158
|
-
if (overlay) return overlay.map(copyEntry);
|
|
2159
|
-
}
|
|
2160
|
-
const allChains = loadChainsFromBrain();
|
|
2161
|
-
const ids = allChains[archetype];
|
|
2162
|
-
if (!ids) return void 0;
|
|
2163
|
-
return ids.map((id) => {
|
|
2164
|
-
const known = lookupStaticEntry(id, archetype);
|
|
2165
|
-
if (known) return copyEntry(known);
|
|
2166
|
-
return { id, grounding: "judgment" };
|
|
2167
|
-
});
|
|
2168
|
-
}
|
|
2169
|
-
function getDefaultFallbackChainWithGrounding(opts) {
|
|
2170
|
-
const {
|
|
2171
|
-
archetype,
|
|
2172
|
-
primary,
|
|
2173
|
-
maxDepth = 3,
|
|
2174
|
-
policy,
|
|
2175
|
-
reachability,
|
|
2176
|
-
toolOrchestration
|
|
2177
|
-
} = opts;
|
|
2178
|
-
if (maxDepth < 1) {
|
|
2179
|
-
throw new Error(
|
|
2180
|
-
`getDefaultFallbackChainWithGrounding: maxDepth must be >= 1, got ${maxDepth}`
|
|
2181
|
-
);
|
|
2182
|
-
}
|
|
2183
|
-
const starter = resolveGroundedChainForArchetype(archetype, toolOrchestration);
|
|
2184
|
-
if (!starter) {
|
|
2185
|
-
throw new Error(
|
|
2186
|
-
`getDefaultFallbackChainWithGrounding: unknown archetype "${archetype}". Known: ${Object.keys(STARTER_CHAINS_GROUNDED).join(", ")}`
|
|
2187
|
-
);
|
|
2188
|
-
}
|
|
2189
|
-
let chain;
|
|
2190
|
-
if (primary) {
|
|
2191
|
-
const primaryEntry = (() => {
|
|
2192
|
-
const inStarter = starter.find((e) => e.id === primary);
|
|
2193
|
-
if (inStarter) return copyEntry(inStarter);
|
|
2194
|
-
const knownAnywhere = lookupStaticEntry(primary, archetype);
|
|
2195
|
-
if (knownAnywhere) return { ...copyEntry(knownAnywhere), id: primary };
|
|
2196
|
-
return { id: primary, grounding: "judgment" };
|
|
2197
|
-
})();
|
|
2198
|
-
chain = [primaryEntry, ...starter.filter((e) => e.id !== primary)];
|
|
2199
|
-
} else {
|
|
2200
|
-
chain = [...starter];
|
|
2201
|
-
}
|
|
2202
|
-
if (policy?.blockedModels && policy.blockedModels.length > 0) {
|
|
2203
|
-
const blocked = new Set(policy.blockedModels);
|
|
2204
|
-
chain = chain.filter((e) => !blocked.has(e.id));
|
|
2205
|
-
}
|
|
2206
|
-
const seen = /* @__PURE__ */ new Set();
|
|
2207
|
-
const deduped = [];
|
|
2208
|
-
for (const e of chain) {
|
|
2209
|
-
if (!seen.has(e.id)) {
|
|
2210
|
-
seen.add(e.id);
|
|
2211
|
-
deduped.push(e);
|
|
2212
|
-
}
|
|
2213
|
-
}
|
|
2214
|
-
let filtered = deduped;
|
|
2215
|
-
if (reachability) {
|
|
2216
|
-
filtered = deduped.filter((e) => isModelReachable(e.id, reachability));
|
|
2217
|
-
}
|
|
2218
|
-
return filtered.slice(0, maxDepth);
|
|
2219
|
-
}
|
|
2220
|
-
function getStarterChainWithGrounding(archetype) {
|
|
2221
|
-
const entries = STARTER_CHAINS_GROUNDED[archetype];
|
|
2222
|
-
if (!entries) {
|
|
2223
|
-
throw new Error(
|
|
2224
|
-
`getStarterChainWithGrounding: unknown archetype "${archetype}"`
|
|
2225
|
-
);
|
|
2226
|
-
}
|
|
2227
|
-
return entries.map(copyEntry);
|
|
2228
|
-
}
|
|
2229
|
-
function getAllStarterChainsWithGrounding() {
|
|
2230
|
-
const out = {};
|
|
2231
|
-
for (const [archetype, entries] of Object.entries(STARTER_CHAINS_GROUNDED)) {
|
|
2232
|
-
out[archetype] = entries.map(copyEntry);
|
|
2233
|
-
}
|
|
2234
|
-
return out;
|
|
2235
|
-
}
|
|
2236
|
-
function getSequentialStarterChainWithGrounding(archetype) {
|
|
2237
|
-
const overlay = STARTER_CHAINS_BY_MODE_GROUNDED[archetype]?.sequential;
|
|
2238
|
-
return overlay ? overlay.map(copyEntry) : void 0;
|
|
2239
|
-
}
|
|
2240
|
-
function ensureCrossProviderTail(opts) {
|
|
2241
|
-
const { chain, archetype, apiKeys, envSource } = opts;
|
|
2242
|
-
if (chain.length < 1) return { chain };
|
|
2243
|
-
const providers = /* @__PURE__ */ new Set();
|
|
2244
|
-
for (const t of chain) {
|
|
2245
|
-
const p = tryGetProfile(t);
|
|
2246
|
-
if (p) providers.add(p.provider);
|
|
2247
|
-
}
|
|
2248
|
-
if (providers.size >= 2) return { chain };
|
|
2249
|
-
const existingProvider = providers.values().next().value;
|
|
2250
|
-
if (!existingProvider) return { chain };
|
|
2251
|
-
const allChains = loadChainsFromBrain();
|
|
2252
|
-
const fullChain = allChains[archetype];
|
|
2253
|
-
if (!fullChain) return { chain };
|
|
2254
|
-
for (const candidate of fullChain) {
|
|
2255
|
-
if (chain.includes(candidate)) continue;
|
|
2256
|
-
const cp = tryGetProfile(candidate);
|
|
2257
|
-
if (!cp || cp.provider === existingProvider) continue;
|
|
2258
|
-
if (!isModelReachable(candidate, { apiKeys, envSource })) continue;
|
|
2259
|
-
return { chain: [...chain, candidate], appended: candidate };
|
|
2260
|
-
}
|
|
2261
|
-
return { chain };
|
|
2262
|
-
}
|
|
2263
|
-
|
|
2264
1873
|
// src/call.ts
|
|
2265
1874
|
async function call(ir, opts = {}) {
|
|
2266
1875
|
const traceId = generateTraceId();
|
|
@@ -2438,6 +2047,8 @@ async function call(ir, opts = {}) {
|
|
|
2438
2047
|
latencyMs: latencyMs2
|
|
2439
2048
|
})
|
|
2440
2049
|
);
|
|
2050
|
+
const fellOver = targetModel !== initial.target;
|
|
2051
|
+
const fallbackReason = fellOver ? normalizeFallbackReason(attempts) : void 0;
|
|
2441
2052
|
await record({
|
|
2442
2053
|
handle: initial.handle,
|
|
2443
2054
|
tokensIn: validated.response.tokens.input,
|
|
@@ -2451,10 +2062,18 @@ async function call(ir, opts = {}) {
|
|
|
2451
2062
|
promptPreview: extractPromptPreview(ir),
|
|
2452
2063
|
responsePreview: validated.response.text.slice(0, 200),
|
|
2453
2064
|
cacheReadInputTokens: validated.response.tokens.cached,
|
|
2454
|
-
cacheCreationInputTokens: validated.response.tokens.cacheCreated
|
|
2065
|
+
cacheCreationInputTokens: validated.response.tokens.cacheCreated,
|
|
2066
|
+
// alpha.28 — Glass-Box renderer substrate (migration 018). call()
|
|
2067
|
+
// owns the lifecycle so it has direct visibility into finishReason
|
|
2068
|
+
// (from the normalized provider response), totalMs (mirrors latencyMs
|
|
2069
|
+
// for non-streaming; future streaming variant may diverge), and the
|
|
2070
|
+
// fell-over-from / fallback-reason pair (already computed above for
|
|
2071
|
+
// the CallResult return shape).
|
|
2072
|
+
finishReason: validated.response.finishReason,
|
|
2073
|
+
totalMs: latencyMs2,
|
|
2074
|
+
fellOverFrom: fellOver ? initial.target : void 0,
|
|
2075
|
+
fallbackReason
|
|
2455
2076
|
});
|
|
2456
|
-
const fellOver = targetModel !== initial.target;
|
|
2457
|
-
const fallbackReason = fellOver ? normalizeFallbackReason(attempts) : void 0;
|
|
2458
2077
|
if (fellOver) {
|
|
2459
2078
|
const firstFailed = attempts.find((a) => a.status !== "success");
|
|
2460
2079
|
if (firstFailed) {
|
|
@@ -2685,6 +2304,278 @@ function clamp(n) {
|
|
|
2685
2304
|
return Math.max(0, Math.min(1, n));
|
|
2686
2305
|
}
|
|
2687
2306
|
|
|
2307
|
+
// src/advisories-api.ts
|
|
2308
|
+
var SEVERITY_SET = /* @__PURE__ */ new Set(["info", "warn", "critical"]);
|
|
2309
|
+
var STATUS_SET = /* @__PURE__ */ new Set(["open", "snoozed", "resolved"]);
|
|
2310
|
+
var RESOLUTION_SOURCE_SET = /* @__PURE__ */ new Set([
|
|
2311
|
+
"auto",
|
|
2312
|
+
"consumer-marked",
|
|
2313
|
+
"declined"
|
|
2314
|
+
]);
|
|
2315
|
+
function asString(v) {
|
|
2316
|
+
return typeof v === "string" && v.length > 0 ? v : void 0;
|
|
2317
|
+
}
|
|
2318
|
+
function asSeverity(v) {
|
|
2319
|
+
if (typeof v === "string" && SEVERITY_SET.has(v)) {
|
|
2320
|
+
return v;
|
|
2321
|
+
}
|
|
2322
|
+
return "info";
|
|
2323
|
+
}
|
|
2324
|
+
function asStatus(v) {
|
|
2325
|
+
if (typeof v === "string" && STATUS_SET.has(v)) {
|
|
2326
|
+
return v;
|
|
2327
|
+
}
|
|
2328
|
+
return "open";
|
|
2329
|
+
}
|
|
2330
|
+
function asResolutionSource(v) {
|
|
2331
|
+
if (typeof v === "string" && RESOLUTION_SOURCE_SET.has(v)) {
|
|
2332
|
+
return v;
|
|
2333
|
+
}
|
|
2334
|
+
return void 0;
|
|
2335
|
+
}
|
|
2336
|
+
function rowToAdvisory(row) {
|
|
2337
|
+
const archetype = asString(row.applies_to_archetype);
|
|
2338
|
+
const model = asString(row.applies_to_model);
|
|
2339
|
+
const docsLink = asString(row.docs_url);
|
|
2340
|
+
const suggestion = asString(row.suggestion);
|
|
2341
|
+
let suggestedFix = null;
|
|
2342
|
+
if (docsLink || suggestion) {
|
|
2343
|
+
suggestedFix = { type: "manual" };
|
|
2344
|
+
if (docsLink) suggestedFix.docsLink = docsLink;
|
|
2345
|
+
if (suggestion) suggestedFix.before = suggestion;
|
|
2346
|
+
}
|
|
2347
|
+
const out = {
|
|
2348
|
+
id: typeof row.id === "string" ? row.id : "",
|
|
2349
|
+
rule: typeof row.rule === "string" ? row.rule : "",
|
|
2350
|
+
severity: asSeverity(row.severity),
|
|
2351
|
+
openedAt: typeof row.opened_at === "string" ? row.opened_at : "",
|
|
2352
|
+
lastObservedAt: typeof row.last_observed_at === "string" ? row.last_observed_at : "",
|
|
2353
|
+
observationCount: typeof row.observation_count === "number" ? row.observation_count : 0,
|
|
2354
|
+
appliesTo: {
|
|
2355
|
+
...archetype ? { archetype } : {},
|
|
2356
|
+
...model ? { model } : {}
|
|
2357
|
+
},
|
|
2358
|
+
message: typeof row.message === "string" ? row.message : "",
|
|
2359
|
+
suggestedFix,
|
|
2360
|
+
autoApplicable: false,
|
|
2361
|
+
// reserved — alpha.30+
|
|
2362
|
+
status: asStatus(row.status)
|
|
2363
|
+
};
|
|
2364
|
+
const resolvedAt = asString(row.resolved_at);
|
|
2365
|
+
if (resolvedAt) out.resolvedAt = resolvedAt;
|
|
2366
|
+
const resolutionSource = asResolutionSource(row.resolution_source);
|
|
2367
|
+
if (resolutionSource) out.resolutionSource = resolutionSource;
|
|
2368
|
+
const resolutionNote = asString(row.resolution_note);
|
|
2369
|
+
if (resolutionNote) out.resolutionNote = resolutionNote;
|
|
2370
|
+
return out;
|
|
2371
|
+
}
|
|
2372
|
+
function resolveFetch(injected) {
|
|
2373
|
+
return injected ?? ((...args) => globalThis.fetch(...args));
|
|
2374
|
+
}
|
|
2375
|
+
function normalizeEndpoint(endpoint) {
|
|
2376
|
+
return endpoint.replace(/\/+$/, "");
|
|
2377
|
+
}
|
|
2378
|
+
async function getActionableAdvisories(opts) {
|
|
2379
|
+
const {
|
|
2380
|
+
appId,
|
|
2381
|
+
severity,
|
|
2382
|
+
status,
|
|
2383
|
+
brainEndpoint,
|
|
2384
|
+
brainJwt,
|
|
2385
|
+
brainAnonKey,
|
|
2386
|
+
fetch: injectedFetch
|
|
2387
|
+
} = opts;
|
|
2388
|
+
if (!appId) {
|
|
2389
|
+
throw new Error("getActionableAdvisories: appId is required");
|
|
2390
|
+
}
|
|
2391
|
+
const doFetch = resolveFetch(injectedFetch);
|
|
2392
|
+
const base = normalizeEndpoint(brainEndpoint);
|
|
2393
|
+
const qs = new URLSearchParams();
|
|
2394
|
+
qs.set("app_id", `eq.${appId}`);
|
|
2395
|
+
if (severity) qs.set("severity", `eq.${severity}`);
|
|
2396
|
+
const effectiveStatus = status ?? "open";
|
|
2397
|
+
if (effectiveStatus !== "all") {
|
|
2398
|
+
qs.set("status", `eq.${effectiveStatus}`);
|
|
2399
|
+
}
|
|
2400
|
+
qs.set("order", "last_observed_at.desc");
|
|
2401
|
+
const url = `${base}/rest/v1/actionable_advisories_v?${qs.toString()}`;
|
|
2402
|
+
let res;
|
|
2403
|
+
try {
|
|
2404
|
+
res = await doFetch(url, {
|
|
2405
|
+
method: "GET",
|
|
2406
|
+
headers: {
|
|
2407
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
2408
|
+
apikey: brainAnonKey,
|
|
2409
|
+
Accept: "application/json"
|
|
2410
|
+
}
|
|
2411
|
+
});
|
|
2412
|
+
} catch (err) {
|
|
2413
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2414
|
+
throw new Error(`getActionableAdvisories: network error: ${msg}`);
|
|
2415
|
+
}
|
|
2416
|
+
if (res.status === 401 || res.status === 403) {
|
|
2417
|
+
throw new Error("getActionableAdvisories: brain auth misconfig");
|
|
2418
|
+
}
|
|
2419
|
+
if (res.status >= 500) {
|
|
2420
|
+
throw new Error(`getActionableAdvisories: brain unavailable (${res.status})`);
|
|
2421
|
+
}
|
|
2422
|
+
if (!res.ok) {
|
|
2423
|
+
throw new Error(`getActionableAdvisories: bad request (${res.status})`);
|
|
2424
|
+
}
|
|
2425
|
+
let rows;
|
|
2426
|
+
try {
|
|
2427
|
+
rows = await res.json();
|
|
2428
|
+
} catch {
|
|
2429
|
+
throw new Error("getActionableAdvisories: malformed brain response");
|
|
2430
|
+
}
|
|
2431
|
+
if (!Array.isArray(rows)) {
|
|
2432
|
+
throw new Error("getActionableAdvisories: expected array from brain");
|
|
2433
|
+
}
|
|
2434
|
+
const out = [];
|
|
2435
|
+
for (const raw of rows) {
|
|
2436
|
+
if (raw && typeof raw === "object") {
|
|
2437
|
+
out.push(rowToAdvisory(raw));
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
return out;
|
|
2441
|
+
}
|
|
2442
|
+
async function markAdvisoryResolved(opts) {
|
|
2443
|
+
const {
|
|
2444
|
+
id,
|
|
2445
|
+
resolutionNote,
|
|
2446
|
+
brainEndpoint,
|
|
2447
|
+
brainJwt,
|
|
2448
|
+
brainAnonKey,
|
|
2449
|
+
fetch: injectedFetch
|
|
2450
|
+
} = opts;
|
|
2451
|
+
if (!id) {
|
|
2452
|
+
return { ok: false, reason: "id_required" };
|
|
2453
|
+
}
|
|
2454
|
+
const doFetch = resolveFetch(injectedFetch);
|
|
2455
|
+
const base = normalizeEndpoint(brainEndpoint);
|
|
2456
|
+
const lookupUrl = `${base}/rest/v1/actionable_advisories_v?id=eq.${encodeURIComponent(id)}&select=app_id,rule`;
|
|
2457
|
+
let lookupRes;
|
|
2458
|
+
try {
|
|
2459
|
+
lookupRes = await doFetch(lookupUrl, {
|
|
2460
|
+
method: "GET",
|
|
2461
|
+
headers: {
|
|
2462
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
2463
|
+
apikey: brainAnonKey,
|
|
2464
|
+
Accept: "application/json"
|
|
2465
|
+
}
|
|
2466
|
+
});
|
|
2467
|
+
} catch (err) {
|
|
2468
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2469
|
+
return { ok: false, reason: `network_error:${msg}` };
|
|
2470
|
+
}
|
|
2471
|
+
if (lookupRes.status === 401 || lookupRes.status === 403) {
|
|
2472
|
+
return { ok: false, reason: "brain_auth_misconfig" };
|
|
2473
|
+
}
|
|
2474
|
+
if (lookupRes.status >= 500) {
|
|
2475
|
+
return { ok: false, reason: "brain_unavailable" };
|
|
2476
|
+
}
|
|
2477
|
+
if (!lookupRes.ok) {
|
|
2478
|
+
return { ok: false, reason: `brain_lookup_failed:${lookupRes.status}` };
|
|
2479
|
+
}
|
|
2480
|
+
let lookupRows;
|
|
2481
|
+
try {
|
|
2482
|
+
lookupRows = await lookupRes.json();
|
|
2483
|
+
} catch {
|
|
2484
|
+
return { ok: false, reason: "brain_lookup_malformed" };
|
|
2485
|
+
}
|
|
2486
|
+
if (!Array.isArray(lookupRows) || lookupRows.length === 0) {
|
|
2487
|
+
return { ok: false, reason: "advisory_not_found" };
|
|
2488
|
+
}
|
|
2489
|
+
const tuple = lookupRows[0];
|
|
2490
|
+
const appId = typeof tuple.app_id === "string" ? tuple.app_id : "";
|
|
2491
|
+
const code = typeof tuple.rule === "string" ? tuple.rule : "";
|
|
2492
|
+
if (!appId || !code) {
|
|
2493
|
+
return { ok: false, reason: "advisory_tuple_invalid" };
|
|
2494
|
+
}
|
|
2495
|
+
const outcomesUrl = `${base}/rest/v1/compile_outcomes?app_id=eq.${encodeURIComponent(appId)}&select=id`;
|
|
2496
|
+
let outcomesRes;
|
|
2497
|
+
try {
|
|
2498
|
+
outcomesRes = await doFetch(outcomesUrl, {
|
|
2499
|
+
method: "GET",
|
|
2500
|
+
headers: {
|
|
2501
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
2502
|
+
apikey: brainAnonKey,
|
|
2503
|
+
Accept: "application/json"
|
|
2504
|
+
}
|
|
2505
|
+
});
|
|
2506
|
+
} catch (err) {
|
|
2507
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2508
|
+
return { ok: false, reason: `network_error:${msg}` };
|
|
2509
|
+
}
|
|
2510
|
+
if (outcomesRes.status === 401 || outcomesRes.status === 403) {
|
|
2511
|
+
return { ok: false, reason: "brain_auth_misconfig" };
|
|
2512
|
+
}
|
|
2513
|
+
if (outcomesRes.status >= 500) {
|
|
2514
|
+
return { ok: false, reason: "brain_unavailable" };
|
|
2515
|
+
}
|
|
2516
|
+
if (!outcomesRes.ok) {
|
|
2517
|
+
return { ok: false, reason: `brain_lookup_failed:${outcomesRes.status}` };
|
|
2518
|
+
}
|
|
2519
|
+
let outcomeRows;
|
|
2520
|
+
try {
|
|
2521
|
+
outcomeRows = await outcomesRes.json();
|
|
2522
|
+
} catch {
|
|
2523
|
+
return { ok: false, reason: "brain_lookup_malformed" };
|
|
2524
|
+
}
|
|
2525
|
+
if (!Array.isArray(outcomeRows)) {
|
|
2526
|
+
return { ok: false, reason: "brain_lookup_malformed" };
|
|
2527
|
+
}
|
|
2528
|
+
const outcomeIds = [];
|
|
2529
|
+
for (const row of outcomeRows) {
|
|
2530
|
+
if (row && typeof row === "object") {
|
|
2531
|
+
const idVal = row.id;
|
|
2532
|
+
if (typeof idVal === "number" && Number.isFinite(idVal)) {
|
|
2533
|
+
outcomeIds.push(idVal);
|
|
2534
|
+
}
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
if (outcomeIds.length === 0) {
|
|
2538
|
+
return { ok: true };
|
|
2539
|
+
}
|
|
2540
|
+
const inList = outcomeIds.join(",");
|
|
2541
|
+
const patchUrl = `${base}/rest/v1/compile_outcome_advisories?outcome_id=in.(${inList})&code=eq.${encodeURIComponent(code)}&resolved_at=is.null`;
|
|
2542
|
+
const patchBody = {
|
|
2543
|
+
resolved_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2544
|
+
resolution_source: "consumer-marked"
|
|
2545
|
+
};
|
|
2546
|
+
if (resolutionNote !== void 0) {
|
|
2547
|
+
patchBody.resolution_note = resolutionNote;
|
|
2548
|
+
}
|
|
2549
|
+
let patchRes;
|
|
2550
|
+
try {
|
|
2551
|
+
patchRes = await doFetch(patchUrl, {
|
|
2552
|
+
method: "PATCH",
|
|
2553
|
+
headers: {
|
|
2554
|
+
Authorization: `Bearer ${brainJwt}`,
|
|
2555
|
+
apikey: brainAnonKey,
|
|
2556
|
+
"Content-Type": "application/json",
|
|
2557
|
+
Accept: "application/json",
|
|
2558
|
+
// PostgREST default is no return; we don't need the row back.
|
|
2559
|
+
Prefer: "return=minimal"
|
|
2560
|
+
},
|
|
2561
|
+
body: JSON.stringify(patchBody)
|
|
2562
|
+
});
|
|
2563
|
+
} catch (err) {
|
|
2564
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2565
|
+
return { ok: false, reason: `network_error:${msg}` };
|
|
2566
|
+
}
|
|
2567
|
+
if (patchRes.status === 401 || patchRes.status === 403) {
|
|
2568
|
+
return { ok: false, reason: "brain_auth_misconfig" };
|
|
2569
|
+
}
|
|
2570
|
+
if (patchRes.status >= 500) {
|
|
2571
|
+
return { ok: false, reason: "brain_unavailable" };
|
|
2572
|
+
}
|
|
2573
|
+
if (!patchRes.ok) {
|
|
2574
|
+
return { ok: false, reason: `patch_failed:${patchRes.status}` };
|
|
2575
|
+
}
|
|
2576
|
+
return { ok: true };
|
|
2577
|
+
}
|
|
2578
|
+
|
|
2688
2579
|
// src/models-brain.ts
|
|
2689
2580
|
function isModelRow(x) {
|
|
2690
2581
|
if (!x || typeof x !== "object") return false;
|
|
@@ -2811,14 +2702,19 @@ function compile2(ir, opts) {
|
|
|
2811
2702
|
return result;
|
|
2812
2703
|
}
|
|
2813
2704
|
export {
|
|
2705
|
+
ABSOLUTE_FLOOR,
|
|
2814
2706
|
ALIASES,
|
|
2815
2707
|
ALL_ARCHETYPES,
|
|
2708
|
+
ARCHETYPE_FLOOR_DEFAULT,
|
|
2816
2709
|
CallError,
|
|
2817
2710
|
DIALECT_VERSION,
|
|
2818
2711
|
INTENT_ARCHETYPES,
|
|
2819
2712
|
MEASURED_GROUNDING_MIN_N,
|
|
2820
2713
|
PROVIDER_ENV_KEYS,
|
|
2714
|
+
RULE_SEQUENTIAL_TOOL_CLIFF,
|
|
2715
|
+
TRANSLATOR_FLOOR,
|
|
2821
2716
|
allProfiles,
|
|
2717
|
+
applySectionRewrites,
|
|
2822
2718
|
bucketContext,
|
|
2823
2719
|
bucketHistory,
|
|
2824
2720
|
bucketToolCount,
|
|
@@ -2829,11 +2725,13 @@ export {
|
|
|
2829
2725
|
configureBrain,
|
|
2830
2726
|
countTokens,
|
|
2831
2727
|
execute,
|
|
2728
|
+
getActionableAdvisories,
|
|
2832
2729
|
getAllStarterChains,
|
|
2833
2730
|
getAllStarterChainsWithGrounding,
|
|
2834
2731
|
getArchetypePerfScore,
|
|
2835
2732
|
getDefaultFallbackChain,
|
|
2836
2733
|
getDefaultFallbackChainWithGrounding,
|
|
2734
|
+
getModelCompatibility,
|
|
2837
2735
|
getPerAxisMetrics,
|
|
2838
2736
|
getProfile,
|
|
2839
2737
|
getReachabilityDiagnostic,
|
|
@@ -2853,6 +2751,7 @@ export {
|
|
|
2853
2751
|
loadChainsFromBrain,
|
|
2854
2752
|
loadModelsFromBrain,
|
|
2855
2753
|
loadPricingFromBrain,
|
|
2754
|
+
markAdvisoryResolved,
|
|
2856
2755
|
profileToRow,
|
|
2857
2756
|
profilesByProvider,
|
|
2858
2757
|
record,
|