@warmdrift/kgauto-compiler 2.0.0-alpha.26 → 2.0.0-alpha.28
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/{chunk-7MTHFSNY.mjs → chunk-JQGRWJZO.mjs} +181 -48
- 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 +88 -6
- package/dist/glassbox-routes/index.d.ts +88 -6
- package/dist/glassbox-routes/index.js +1820 -8
- package/dist/glassbox-routes/index.mjs +320 -8
- package/dist/index.d.mts +184 -3
- package/dist/index.d.ts +184 -3
- package/dist/index.js +342 -53
- package/dist/index.mjs +108 -581
- package/dist/{ir-B_XX2LAO.d.ts → ir-5W0efxt9.d.ts} +86 -1
- package/dist/{ir-B9zqlwjH.d.mts → ir-MXCJA8L7.d.mts} +86 -1
- package/dist/profiles.d.mts +1 -1
- package/dist/profiles.d.ts +1 -1
- package/dist/profiles.js +181 -48
- package/dist/profiles.mjs +1 -1
- package/dist/{types-bt0aVJb8.d.ts → types-CiZ9HLIU.d.ts} +1 -1
- package/dist/{types-o9etg93a.d.mts → types-sDZQzPM6.d.mts} +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,
|
|
@@ -17,7 +41,7 @@ import {
|
|
|
17
41
|
getProfile,
|
|
18
42
|
profilesByProvider,
|
|
19
43
|
tryGetProfile
|
|
20
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-JQGRWJZO.mjs";
|
|
21
45
|
import {
|
|
22
46
|
emitAdvisoryFired,
|
|
23
47
|
emitCompileDone,
|
|
@@ -740,177 +764,6 @@ function setNestedField(obj, path, value) {
|
|
|
740
764
|
cursor[parts[parts.length - 1]] = value;
|
|
741
765
|
}
|
|
742
766
|
|
|
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
767
|
// src/archetype-perf-brain.ts
|
|
915
768
|
function isPerfRow(x) {
|
|
916
769
|
if (!x || typeof x !== "object") return false;
|
|
@@ -984,6 +837,7 @@ function runAdvisor(ir, result, profile, policy, phase2) {
|
|
|
984
837
|
out.push(...detectModelStaleEvidence(ir, profile));
|
|
985
838
|
out.push(...detectTierDown(ir, profile, phase2));
|
|
986
839
|
}
|
|
840
|
+
out.push(...detectArchetypePerfFloorBreach(ir, profile));
|
|
987
841
|
return out;
|
|
988
842
|
}
|
|
989
843
|
function detectCachingOff(ir, profile) {
|
|
@@ -1154,6 +1008,36 @@ function detectTierDown(ir, profile, phase2) {
|
|
|
1154
1008
|
}
|
|
1155
1009
|
];
|
|
1156
1010
|
}
|
|
1011
|
+
function detectArchetypePerfFloorBreach(ir, profile) {
|
|
1012
|
+
const compat = getModelCompatibility(profile.id, {
|
|
1013
|
+
archetype: ir.intent.archetype,
|
|
1014
|
+
toolOrchestration: ir.constraints?.toolOrchestration
|
|
1015
|
+
});
|
|
1016
|
+
if (compat.status === "compatible") return [];
|
|
1017
|
+
if (compat.status === "requires-adapter") {
|
|
1018
|
+
return [
|
|
1019
|
+
{
|
|
1020
|
+
level: "warn",
|
|
1021
|
+
code: "archetype-perf-floor-breach",
|
|
1022
|
+
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}`,
|
|
1023
|
+
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.`,
|
|
1024
|
+
recommendationType: "prompt-fix",
|
|
1025
|
+
suggestedAdaptation: compat.adapter,
|
|
1026
|
+
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories"
|
|
1027
|
+
}
|
|
1028
|
+
];
|
|
1029
|
+
}
|
|
1030
|
+
return [
|
|
1031
|
+
{
|
|
1032
|
+
level: "critical",
|
|
1033
|
+
code: "archetype-perf-floor-breach",
|
|
1034
|
+
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}`,
|
|
1035
|
+
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.`,
|
|
1036
|
+
recommendationType: "model-swap",
|
|
1037
|
+
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories"
|
|
1038
|
+
}
|
|
1039
|
+
];
|
|
1040
|
+
}
|
|
1157
1041
|
|
|
1158
1042
|
// src/compile.ts
|
|
1159
1043
|
var counter = 0;
|
|
@@ -1414,6 +1298,9 @@ function registerCompile(appId, archetype, ir, result) {
|
|
|
1414
1298
|
tokens
|
|
1415
1299
|
);
|
|
1416
1300
|
const shapeKey = `${shape.contextBucket}-${shape.toolCountBucket}-${shape.historyDepth}-${shape.outputMode}`;
|
|
1301
|
+
const toolsCount = result.diagnostics.toolsKept;
|
|
1302
|
+
const historyDepth = Array.isArray(ir.history) ? ir.history.length : 0;
|
|
1303
|
+
const systemPromptChars = estimateSystemPromptChars(ir.sections);
|
|
1417
1304
|
compileRegistry.set(result.handle, {
|
|
1418
1305
|
appId,
|
|
1419
1306
|
archetype,
|
|
@@ -1427,9 +1314,24 @@ function registerCompile(appId, archetype, ir, result) {
|
|
|
1427
1314
|
historyCacheableTokens: result.diagnostics.historyCacheableTokens,
|
|
1428
1315
|
historyTokensTotal: result.diagnostics.historyTokensTotal,
|
|
1429
1316
|
// alpha.20 E3: capture consumer's declared mode for the brain payload.
|
|
1430
|
-
toolOrchestration: result.diagnostics.toolOrchestration
|
|
1317
|
+
toolOrchestration: result.diagnostics.toolOrchestration,
|
|
1318
|
+
// alpha.28: shape fields for Glass-Box renderer.
|
|
1319
|
+
toolsCount,
|
|
1320
|
+
historyDepth,
|
|
1321
|
+
systemPromptChars
|
|
1431
1322
|
});
|
|
1432
1323
|
}
|
|
1324
|
+
function estimateSystemPromptChars(sections) {
|
|
1325
|
+
if (!Array.isArray(sections) || sections.length === 0) return void 0;
|
|
1326
|
+
let total = 0;
|
|
1327
|
+
for (const s of sections) {
|
|
1328
|
+
if (s && typeof s === "object") {
|
|
1329
|
+
const content = s.content;
|
|
1330
|
+
if (typeof content === "string") total += content.length;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
return total > 0 ? total : void 0;
|
|
1334
|
+
}
|
|
1433
1335
|
async function record(input) {
|
|
1434
1336
|
const reg = compileRegistry.get(input.handle);
|
|
1435
1337
|
if (reg) compileRegistry.delete(input.handle);
|
|
@@ -1466,7 +1368,7 @@ async function record(input) {
|
|
|
1466
1368
|
}
|
|
1467
1369
|
outcomeId = await tryExtractOutcomeId(res);
|
|
1468
1370
|
} catch (err) {
|
|
1469
|
-
(config.onError ??
|
|
1371
|
+
(config.onError ?? defaultOnError)(err);
|
|
1470
1372
|
return;
|
|
1471
1373
|
}
|
|
1472
1374
|
const advisories = input.advisories;
|
|
@@ -1488,7 +1390,7 @@ async function record(input) {
|
|
|
1488
1390
|
throw new Error(`brain advisories ${res.status}: ${text}`);
|
|
1489
1391
|
}
|
|
1490
1392
|
} catch (err) {
|
|
1491
|
-
(config.onError ??
|
|
1393
|
+
(config.onError ?? defaultOnError)(err);
|
|
1492
1394
|
}
|
|
1493
1395
|
};
|
|
1494
1396
|
if (config.sync) {
|
|
@@ -1497,7 +1399,7 @@ async function record(input) {
|
|
|
1497
1399
|
void send();
|
|
1498
1400
|
}
|
|
1499
1401
|
}
|
|
1500
|
-
function
|
|
1402
|
+
function defaultOnError(err) {
|
|
1501
1403
|
console.warn("[kgauto] brain record failed:", err);
|
|
1502
1404
|
}
|
|
1503
1405
|
function buildPayload(input, reg) {
|
|
@@ -1507,6 +1409,8 @@ function buildPayload(input, reg) {
|
|
|
1507
1409
|
const mutationsApplied = input.mutationsApplied ?? reg?.mutationsApplied ?? [];
|
|
1508
1410
|
const costModel = actual;
|
|
1509
1411
|
const costUsdActual = costModel ? computeCostUsd(costModel, input.tokensIn, input.tokensOut) : void 0;
|
|
1412
|
+
const fellOverFrom = input.fellOverFrom ?? requested;
|
|
1413
|
+
const fallbackReason = fellOverFrom ? input.fallbackReason : void 0;
|
|
1510
1414
|
return {
|
|
1511
1415
|
handle: input.handle,
|
|
1512
1416
|
app_id: reg?.appId,
|
|
@@ -1541,7 +1445,16 @@ function buildPayload(input, reg) {
|
|
|
1541
1445
|
// the brain can measure per-mode model perf separately (DeepSeek in
|
|
1542
1446
|
// sequential vs parallel mode is two different stories — L-040).
|
|
1543
1447
|
// Null when consumer hadn't adopted the constraint yet.
|
|
1544
|
-
tool_orchestration: reg?.toolOrchestration ?? null
|
|
1448
|
+
tool_orchestration: reg?.toolOrchestration ?? null,
|
|
1449
|
+
// alpha.28 — Glass-Box renderer substrate (migration 018). All optional;
|
|
1450
|
+
// omitted-undefined PostgREST inserts store NULL → renderer renders "—".
|
|
1451
|
+
finish_reason: input.finishReason,
|
|
1452
|
+
total_ms: input.totalMs ?? input.latencyMs,
|
|
1453
|
+
tools_count: input.toolsCount ?? reg?.toolsCount,
|
|
1454
|
+
history_depth: input.historyDepth ?? reg?.historyDepth,
|
|
1455
|
+
system_prompt_chars: input.systemPromptChars ?? reg?.systemPromptChars,
|
|
1456
|
+
fell_over_from: fellOverFrom,
|
|
1457
|
+
fallback_reason: fallbackReason
|
|
1545
1458
|
};
|
|
1546
1459
|
}
|
|
1547
1460
|
function computeCostUsd(modelId, tokensIn, tokensOut) {
|
|
@@ -1614,12 +1527,12 @@ async function recordOutcome(input) {
|
|
|
1614
1527
|
if (!res.ok) {
|
|
1615
1528
|
const text = await res.text().catch(() => "<no body>");
|
|
1616
1529
|
const err = new Error(`brain ${res.status}: ${text}`);
|
|
1617
|
-
(config.onError ??
|
|
1530
|
+
(config.onError ?? defaultOnError)(err);
|
|
1618
1531
|
return { ok: false, reason: "persistence_failed" };
|
|
1619
1532
|
}
|
|
1620
1533
|
return { ok: true };
|
|
1621
1534
|
} catch (err) {
|
|
1622
|
-
(config.onError ??
|
|
1535
|
+
(config.onError ?? defaultOnError)(err);
|
|
1623
1536
|
return { ok: false, reason: "persistence_failed" };
|
|
1624
1537
|
}
|
|
1625
1538
|
};
|
|
@@ -1644,67 +1557,6 @@ var CallError = class extends Error {
|
|
|
1644
1557
|
}
|
|
1645
1558
|
};
|
|
1646
1559
|
|
|
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
1560
|
// src/execute.ts
|
|
1709
1561
|
var ANTHROPIC_URL = "https://api.anthropic.com/v1/messages";
|
|
1710
1562
|
var OPENAI_URL = "https://api.openai.com/v1/chat/completions";
|
|
@@ -1923,344 +1775,6 @@ function tryParseJson(s) {
|
|
|
1923
1775
|
}
|
|
1924
1776
|
}
|
|
1925
1777
|
|
|
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
1778
|
// src/call.ts
|
|
2265
1779
|
async function call(ir, opts = {}) {
|
|
2266
1780
|
const traceId = generateTraceId();
|
|
@@ -2438,6 +1952,8 @@ async function call(ir, opts = {}) {
|
|
|
2438
1952
|
latencyMs: latencyMs2
|
|
2439
1953
|
})
|
|
2440
1954
|
);
|
|
1955
|
+
const fellOver = targetModel !== initial.target;
|
|
1956
|
+
const fallbackReason = fellOver ? normalizeFallbackReason(attempts) : void 0;
|
|
2441
1957
|
await record({
|
|
2442
1958
|
handle: initial.handle,
|
|
2443
1959
|
tokensIn: validated.response.tokens.input,
|
|
@@ -2451,10 +1967,18 @@ async function call(ir, opts = {}) {
|
|
|
2451
1967
|
promptPreview: extractPromptPreview(ir),
|
|
2452
1968
|
responsePreview: validated.response.text.slice(0, 200),
|
|
2453
1969
|
cacheReadInputTokens: validated.response.tokens.cached,
|
|
2454
|
-
cacheCreationInputTokens: validated.response.tokens.cacheCreated
|
|
1970
|
+
cacheCreationInputTokens: validated.response.tokens.cacheCreated,
|
|
1971
|
+
// alpha.28 — Glass-Box renderer substrate (migration 018). call()
|
|
1972
|
+
// owns the lifecycle so it has direct visibility into finishReason
|
|
1973
|
+
// (from the normalized provider response), totalMs (mirrors latencyMs
|
|
1974
|
+
// for non-streaming; future streaming variant may diverge), and the
|
|
1975
|
+
// fell-over-from / fallback-reason pair (already computed above for
|
|
1976
|
+
// the CallResult return shape).
|
|
1977
|
+
finishReason: validated.response.finishReason,
|
|
1978
|
+
totalMs: latencyMs2,
|
|
1979
|
+
fellOverFrom: fellOver ? initial.target : void 0,
|
|
1980
|
+
fallbackReason
|
|
2455
1981
|
});
|
|
2456
|
-
const fellOver = targetModel !== initial.target;
|
|
2457
|
-
const fallbackReason = fellOver ? normalizeFallbackReason(attempts) : void 0;
|
|
2458
1982
|
if (fellOver) {
|
|
2459
1983
|
const firstFailed = attempts.find((a) => a.status !== "success");
|
|
2460
1984
|
if (firstFailed) {
|
|
@@ -2811,8 +2335,10 @@ function compile2(ir, opts) {
|
|
|
2811
2335
|
return result;
|
|
2812
2336
|
}
|
|
2813
2337
|
export {
|
|
2338
|
+
ABSOLUTE_FLOOR,
|
|
2814
2339
|
ALIASES,
|
|
2815
2340
|
ALL_ARCHETYPES,
|
|
2341
|
+
ARCHETYPE_FLOOR_DEFAULT,
|
|
2816
2342
|
CallError,
|
|
2817
2343
|
DIALECT_VERSION,
|
|
2818
2344
|
INTENT_ARCHETYPES,
|
|
@@ -2834,6 +2360,7 @@ export {
|
|
|
2834
2360
|
getArchetypePerfScore,
|
|
2835
2361
|
getDefaultFallbackChain,
|
|
2836
2362
|
getDefaultFallbackChainWithGrounding,
|
|
2363
|
+
getModelCompatibility,
|
|
2837
2364
|
getPerAxisMetrics,
|
|
2838
2365
|
getProfile,
|
|
2839
2366
|
getReachabilityDiagnostic,
|