@warmdrift/kgauto-compiler 2.0.0-alpha.42 → 2.0.0-alpha.43
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-KCNQUMHN.mjs → chunk-6MSJQCAP.mjs} +1 -1
- package/dist/{chunk-JQGRWJZO.mjs → chunk-ZHUD3I52.mjs} +60 -2
- package/dist/glassbox/index.d.mts +3 -3
- package/dist/glassbox/index.d.ts +3 -3
- package/dist/glassbox-routes/format.d.mts +2 -2
- package/dist/glassbox-routes/format.d.ts +2 -2
- package/dist/glassbox-routes/index.d.mts +4 -4
- package/dist/glassbox-routes/index.d.ts +4 -4
- package/dist/glassbox-routes/index.js +60 -2
- package/dist/glassbox-routes/index.mjs +2 -2
- package/dist/glassbox-routes/react/index.d.mts +2 -2
- package/dist/glassbox-routes/react/index.d.ts +2 -2
- package/dist/index.d.mts +101 -4
- package/dist/index.d.ts +101 -4
- package/dist/index.js +2658 -2333
- package/dist/index.mjs +640 -377
- package/dist/{ir-BG70lg9b.d.mts → ir-CSgyol5D.d.mts} +14 -0
- package/dist/{ir-BmumS1Du.d.ts → ir-MN9bGclm.d.ts} +14 -0
- package/dist/profiles.d.mts +92 -2
- package/dist/profiles.d.ts +92 -2
- package/dist/profiles.js +60 -2
- package/dist/profiles.mjs +1 -1
- package/dist/{types-DIl0tCDX.d.mts → types-M48csxKK.d.mts} +1 -1
- package/dist/{types-Cs_hsBGm.d.ts → types-_1tcDEqa.d.ts} +1 -1
- package/dist/{types-eKKDeADI.d.mts → types-acFM2-iZ.d.mts} +1 -1
- package/dist/{types-kFsIDC_5.d.ts → types-uRIiYY_y.d.ts} +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
loadChainsFromBrain,
|
|
34
34
|
readBrainReadEnv,
|
|
35
35
|
resolveProviderKey
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-6MSJQCAP.mjs";
|
|
37
37
|
import {
|
|
38
38
|
ALIASES,
|
|
39
39
|
_setProfileBrainHook,
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
getProfile,
|
|
43
43
|
profilesByProvider,
|
|
44
44
|
tryGetProfile
|
|
45
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-ZHUD3I52.mjs";
|
|
46
46
|
import {
|
|
47
47
|
emitAdvisoryFired,
|
|
48
48
|
emitCompileDone,
|
|
@@ -52,6 +52,380 @@ import {
|
|
|
52
52
|
emitFallbackWalked
|
|
53
53
|
} from "./chunk-NBO4R5PC.mjs";
|
|
54
54
|
|
|
55
|
+
// src/models-brain.ts
|
|
56
|
+
function isModelRow(x) {
|
|
57
|
+
if (!x || typeof x !== "object") return false;
|
|
58
|
+
const r = x;
|
|
59
|
+
return typeof r.model_id === "string" && typeof r.provider === "string";
|
|
60
|
+
}
|
|
61
|
+
function isAliasRow(x) {
|
|
62
|
+
if (!x || typeof x !== "object") return false;
|
|
63
|
+
const r = x;
|
|
64
|
+
return typeof r.alias_id === "string" && typeof r.canonical_id === "string";
|
|
65
|
+
}
|
|
66
|
+
function rowToProfile(row) {
|
|
67
|
+
try {
|
|
68
|
+
if (row.cliffs !== void 0 && row.cliffs !== null && !Array.isArray(row.cliffs)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
if (row.recovery !== void 0 && row.recovery !== null && !Array.isArray(row.recovery)) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
if (row.lowering !== void 0 && row.lowering !== null && (typeof row.lowering !== "object" || Array.isArray(row.lowering))) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
id: row.model_id,
|
|
79
|
+
provider: row.provider,
|
|
80
|
+
status: row.status ?? "current",
|
|
81
|
+
maxContextTokens: row.max_context_tokens ?? 0,
|
|
82
|
+
maxOutputTokens: row.max_output_tokens ?? 0,
|
|
83
|
+
maxTools: row.max_tools ?? 0,
|
|
84
|
+
parallelToolCalls: row.parallel_tool_calls ?? false,
|
|
85
|
+
structuredOutput: row.structured_output ?? "none",
|
|
86
|
+
systemPromptMode: row.system_prompt_mode ?? "inline",
|
|
87
|
+
streaming: row.streaming ?? true,
|
|
88
|
+
cliffs: row.cliffs ?? [],
|
|
89
|
+
costInputPer1m: row.cost_input_per_1m ?? 0,
|
|
90
|
+
costOutputPer1m: row.cost_output_per_1m ?? 0,
|
|
91
|
+
lowering: row.lowering ?? { system: { mode: "inline" }, cache: { strategy: "unsupported" } },
|
|
92
|
+
recovery: row.recovery ?? [],
|
|
93
|
+
strengths: row.strengths ?? [],
|
|
94
|
+
weaknesses: row.weaknesses ?? [],
|
|
95
|
+
notes: row.notes ?? void 0,
|
|
96
|
+
verifiedAgainstDocs: row.verified_against_docs ?? void 0,
|
|
97
|
+
archetypePerf: row.archetype_perf ?? void 0,
|
|
98
|
+
// alpha.41 — family-resolution fields. `family` may be null pre-
|
|
99
|
+
// migration 024; runtime falls back to deriveFamilyFromModelId at
|
|
100
|
+
// resolution time (see family-resolution.ts, G1).
|
|
101
|
+
family: row.family ?? void 0,
|
|
102
|
+
versionAdded: row.version_added ?? void 0,
|
|
103
|
+
active: row.active ?? void 0
|
|
104
|
+
};
|
|
105
|
+
} catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function profileToRow(profile, opts = {}) {
|
|
110
|
+
const row = {
|
|
111
|
+
model_id: profile.id,
|
|
112
|
+
provider: profile.provider,
|
|
113
|
+
status: profile.status,
|
|
114
|
+
max_context_tokens: profile.maxContextTokens,
|
|
115
|
+
max_output_tokens: profile.maxOutputTokens,
|
|
116
|
+
max_tools: profile.maxTools,
|
|
117
|
+
parallel_tool_calls: profile.parallelToolCalls,
|
|
118
|
+
structured_output: profile.structuredOutput,
|
|
119
|
+
system_prompt_mode: profile.systemPromptMode,
|
|
120
|
+
streaming: profile.streaming,
|
|
121
|
+
cliffs: profile.cliffs,
|
|
122
|
+
cost_input_per_1m: profile.costInputPer1m,
|
|
123
|
+
cost_output_per_1m: profile.costOutputPer1m,
|
|
124
|
+
lowering: profile.lowering,
|
|
125
|
+
recovery: profile.recovery,
|
|
126
|
+
strengths: profile.strengths,
|
|
127
|
+
weaknesses: profile.weaknesses,
|
|
128
|
+
notes: profile.notes ?? null,
|
|
129
|
+
archetype_perf: profile.archetypePerf ?? null,
|
|
130
|
+
active: opts.active ?? profile.active ?? true,
|
|
131
|
+
// alpha.41 — round-trip family + version_added when present on profile.
|
|
132
|
+
// version_added is operator-controlled via opts; profile-side value is
|
|
133
|
+
// used only when opts didn't override.
|
|
134
|
+
family: profile.family ?? null
|
|
135
|
+
};
|
|
136
|
+
if (opts.verifiedAgainstDocs !== void 0) {
|
|
137
|
+
row.verified_against_docs = opts.verifiedAgainstDocs;
|
|
138
|
+
} else if (profile.verifiedAgainstDocs !== void 0) {
|
|
139
|
+
const v = profile.verifiedAgainstDocs;
|
|
140
|
+
row.verified_against_docs = /^\d{4}-\d{2}-\d{2}/.test(v) ? v : null;
|
|
141
|
+
}
|
|
142
|
+
if (opts.versionAdded !== void 0) row.version_added = opts.versionAdded;
|
|
143
|
+
else if (profile.versionAdded !== void 0) row.version_added = profile.versionAdded;
|
|
144
|
+
if (opts.versionRemoved !== void 0) row.version_removed = opts.versionRemoved;
|
|
145
|
+
return row;
|
|
146
|
+
}
|
|
147
|
+
function mapRowsToModels(rows) {
|
|
148
|
+
const out = /* @__PURE__ */ new Map();
|
|
149
|
+
for (const row of rows) {
|
|
150
|
+
if (!isModelRow(row)) continue;
|
|
151
|
+
const profile = rowToProfile(row);
|
|
152
|
+
if (profile) out.set(profile.id, profile);
|
|
153
|
+
}
|
|
154
|
+
return out;
|
|
155
|
+
}
|
|
156
|
+
function mapRowsToAliases(rows) {
|
|
157
|
+
const out = {};
|
|
158
|
+
for (const row of rows) {
|
|
159
|
+
if (!isAliasRow(row)) continue;
|
|
160
|
+
out[row.alias_id] = row.canonical_id;
|
|
161
|
+
}
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
function bundledModels() {
|
|
165
|
+
return new Map(allProfilesRaw().map((p) => [p.id, p]));
|
|
166
|
+
}
|
|
167
|
+
function bundledAliases() {
|
|
168
|
+
return { ...ALIASES };
|
|
169
|
+
}
|
|
170
|
+
var loadModelsFromBrain = createBrainQueryCache({
|
|
171
|
+
table: "kgauto_models",
|
|
172
|
+
mapRows: mapRowsToModels,
|
|
173
|
+
bundledFallback: bundledModels
|
|
174
|
+
});
|
|
175
|
+
var loadAliasesFromBrain = createBrainQueryCache({
|
|
176
|
+
table: "kgauto_aliases",
|
|
177
|
+
mapRows: mapRowsToAliases,
|
|
178
|
+
bundledFallback: bundledAliases
|
|
179
|
+
});
|
|
180
|
+
_setProfileBrainHook({
|
|
181
|
+
getProfile: (canonical) => loadModelsFromBrain().get(canonical),
|
|
182
|
+
resolveAlias: (id) => loadAliasesFromBrain()[id]
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// src/exclusion-findings-brain.ts
|
|
186
|
+
function isValidVerdict(v) {
|
|
187
|
+
return v === "recommend-probe" || v === "unblock" || v === "stay-excluded" || v === "inconclusive";
|
|
188
|
+
}
|
|
189
|
+
function isValidConfidence(v) {
|
|
190
|
+
return v === "high" || v === "medium" || v === "low";
|
|
191
|
+
}
|
|
192
|
+
function isRawFindingRow(x) {
|
|
193
|
+
if (!x || typeof x !== "object") return false;
|
|
194
|
+
const r = x;
|
|
195
|
+
return typeof r.intent_archetype === "string" && typeof r.excluded_model === "string" && typeof r.excluded_provider === "string" && typeof r.verdict === "string" && typeof r.message === "string" && typeof r.suggestion === "string" && typeof r.confidence === "string";
|
|
196
|
+
}
|
|
197
|
+
function mapRowsToFindings(rows) {
|
|
198
|
+
const out = [];
|
|
199
|
+
for (const row of rows) {
|
|
200
|
+
if (!isRawFindingRow(row)) continue;
|
|
201
|
+
if (!isValidVerdict(row.verdict)) continue;
|
|
202
|
+
if (!isValidConfidence(row.confidence)) continue;
|
|
203
|
+
let savings = null;
|
|
204
|
+
if (typeof row.estimated_savings_usd_30d === "number") {
|
|
205
|
+
savings = Number.isFinite(row.estimated_savings_usd_30d) ? row.estimated_savings_usd_30d : null;
|
|
206
|
+
} else if (typeof row.estimated_savings_usd_30d === "string") {
|
|
207
|
+
const n = Number(row.estimated_savings_usd_30d);
|
|
208
|
+
savings = Number.isFinite(n) ? n : null;
|
|
209
|
+
}
|
|
210
|
+
out.push({
|
|
211
|
+
archetype: row.intent_archetype,
|
|
212
|
+
excludedModel: row.excluded_model,
|
|
213
|
+
excludedProvider: row.excluded_provider,
|
|
214
|
+
verdict: row.verdict,
|
|
215
|
+
estimatedSavingsUsd30d: savings,
|
|
216
|
+
message: row.message,
|
|
217
|
+
suggestion: row.suggestion,
|
|
218
|
+
confidence: row.confidence,
|
|
219
|
+
evidence: row.evidence && typeof row.evidence === "object" ? row.evidence : void 0
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
var snapshots = /* @__PURE__ */ new Map();
|
|
225
|
+
var runtime;
|
|
226
|
+
var warnedOnce = false;
|
|
227
|
+
var DEFAULT_FINDINGS_ENDPOINT = "https://kgauto-dashboard.vercel.app/api/kgauto-v2/findings/exclusions";
|
|
228
|
+
function configureExclusionFindingsBrain(rt) {
|
|
229
|
+
runtime = rt;
|
|
230
|
+
snapshots.clear();
|
|
231
|
+
warnedOnce = false;
|
|
232
|
+
}
|
|
233
|
+
function isExclusionFindingsBrainActive() {
|
|
234
|
+
return runtime !== void 0;
|
|
235
|
+
}
|
|
236
|
+
function getStaleExclusionFindings(opts) {
|
|
237
|
+
const rt = runtime;
|
|
238
|
+
if (!rt) return [];
|
|
239
|
+
const appId = opts.appId;
|
|
240
|
+
if (!appId) return [];
|
|
241
|
+
let snap = snapshots.get(appId);
|
|
242
|
+
if (!snap) {
|
|
243
|
+
snap = { data: [], expiresAt: 0, refreshing: false };
|
|
244
|
+
snapshots.set(appId, snap);
|
|
245
|
+
}
|
|
246
|
+
const now = Date.now();
|
|
247
|
+
const stale = snap.expiresAt <= now;
|
|
248
|
+
if (stale && !snap.refreshing) {
|
|
249
|
+
snap.refreshing = true;
|
|
250
|
+
void asyncRefresh(rt, appId);
|
|
251
|
+
}
|
|
252
|
+
if (opts.archetype) {
|
|
253
|
+
return snap.data.filter((f) => f.archetype === opts.archetype);
|
|
254
|
+
}
|
|
255
|
+
return snap.data;
|
|
256
|
+
}
|
|
257
|
+
var pendingRefreshes = /* @__PURE__ */ new Map();
|
|
258
|
+
async function asyncRefresh(rt, appId) {
|
|
259
|
+
const promise = doRefresh(rt, appId);
|
|
260
|
+
pendingRefreshes.set(appId, promise);
|
|
261
|
+
try {
|
|
262
|
+
await promise;
|
|
263
|
+
} finally {
|
|
264
|
+
if (pendingRefreshes.get(appId) === promise) {
|
|
265
|
+
pendingRefreshes.delete(appId);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async function doRefresh(rt, appId) {
|
|
270
|
+
const url = `${rt.endpoint}?app_id=${encodeURIComponent(appId)}`;
|
|
271
|
+
let snap = snapshots.get(appId);
|
|
272
|
+
if (!snap) {
|
|
273
|
+
snap = { data: [], expiresAt: 0, refreshing: false };
|
|
274
|
+
snapshots.set(appId, snap);
|
|
275
|
+
}
|
|
276
|
+
try {
|
|
277
|
+
const res = await rt.fetchImpl(url, { method: "GET" });
|
|
278
|
+
if (!res.ok) {
|
|
279
|
+
throw new Error(`findings ${res.status}: ${res.statusText}`);
|
|
280
|
+
}
|
|
281
|
+
const body = await res.json();
|
|
282
|
+
if (runtime !== rt) return;
|
|
283
|
+
const rows = Array.isArray(body) ? mapRowsToFindings(body) : [];
|
|
284
|
+
snap.data = rows;
|
|
285
|
+
snap.expiresAt = Date.now() + rt.ttlMs;
|
|
286
|
+
snap.refreshing = false;
|
|
287
|
+
} catch (err) {
|
|
288
|
+
if (runtime !== rt) return;
|
|
289
|
+
snap.refreshing = false;
|
|
290
|
+
snap.expiresAt = Date.now() + rt.ttlMs;
|
|
291
|
+
if (!warnedOnce) {
|
|
292
|
+
warnedOnce = true;
|
|
293
|
+
(rt.onError ?? defaultOnError)(err);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function defaultOnError(err) {
|
|
298
|
+
console.warn(
|
|
299
|
+
"[kgauto] exclusion-findings fetch failed (using empty fallback):",
|
|
300
|
+
err
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// src/family-resolution.ts
|
|
305
|
+
var FamilyResolutionError = class extends Error {
|
|
306
|
+
family;
|
|
307
|
+
cause;
|
|
308
|
+
constructor(family, cause) {
|
|
309
|
+
super(
|
|
310
|
+
`Family "${family}" did not resolve to any current+active model. ${cause}. Pass a literal model id in ir.models, or call getRecommendedPrimary({ family, fallback }) at IR-construction time.`
|
|
311
|
+
);
|
|
312
|
+
this.name = "FamilyResolutionError";
|
|
313
|
+
this.family = family;
|
|
314
|
+
this.cause = cause;
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
function deriveFamilyFromModelId(modelId) {
|
|
318
|
+
if (typeof modelId !== "string" || modelId.length === 0) return null;
|
|
319
|
+
if (modelId.startsWith("claude-opus-")) return "claude-opus";
|
|
320
|
+
if (modelId.startsWith("claude-sonnet-")) return "claude-sonnet";
|
|
321
|
+
if (modelId.startsWith("claude-haiku-")) return "claude-haiku";
|
|
322
|
+
if (modelId.startsWith("gemini-") && modelId.includes("flash-lite")) {
|
|
323
|
+
return "gemini-flash-lite";
|
|
324
|
+
}
|
|
325
|
+
if (modelId.startsWith("gemini-") && modelId.includes("flash")) {
|
|
326
|
+
return "gemini-flash";
|
|
327
|
+
}
|
|
328
|
+
if (modelId.startsWith("gemini-") && modelId.includes("pro")) {
|
|
329
|
+
return "gemini-pro";
|
|
330
|
+
}
|
|
331
|
+
if (modelId.startsWith("deepseek-") && modelId.includes("pro")) {
|
|
332
|
+
return "deepseek-reasoner";
|
|
333
|
+
}
|
|
334
|
+
if (modelId.startsWith("deepseek-")) return "deepseek-chat";
|
|
335
|
+
if (modelId.startsWith("gpt-")) return "openai-gpt";
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
function familyOf(profile) {
|
|
339
|
+
return profile.family ?? deriveFamilyFromModelId(profile.id);
|
|
340
|
+
}
|
|
341
|
+
function archetypePerfFor(profile, archetype) {
|
|
342
|
+
if (!archetype) return 0;
|
|
343
|
+
const score = profile.archetypePerf?.[archetype];
|
|
344
|
+
return typeof score === "number" ? score : 5;
|
|
345
|
+
}
|
|
346
|
+
function selectCandidates(registry, family, archetype, appId) {
|
|
347
|
+
const out = [];
|
|
348
|
+
const excluded = /* @__PURE__ */ new Set();
|
|
349
|
+
if (appId && archetype) {
|
|
350
|
+
const findings = getStaleExclusionFindings({ appId, archetype });
|
|
351
|
+
for (const f of findings) {
|
|
352
|
+
if (f.verdict === "stay-excluded") excluded.add(f.excludedModel);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
for (const profile of registry.values()) {
|
|
356
|
+
if (familyOf(profile) !== family) continue;
|
|
357
|
+
if (profile.status !== "current") continue;
|
|
358
|
+
if (profile.active === false) continue;
|
|
359
|
+
if (archetype) {
|
|
360
|
+
if (archetypePerfFor(profile, archetype) < ARCHETYPE_FLOOR_DEFAULT) continue;
|
|
361
|
+
}
|
|
362
|
+
if (excluded.has(profile.id)) continue;
|
|
363
|
+
out.push(profile);
|
|
364
|
+
}
|
|
365
|
+
return out;
|
|
366
|
+
}
|
|
367
|
+
function sortCandidates(candidates, archetype) {
|
|
368
|
+
const sorted = [...candidates];
|
|
369
|
+
sorted.sort((a, b) => {
|
|
370
|
+
const perfA = archetypePerfFor(a, archetype);
|
|
371
|
+
const perfB = archetypePerfFor(b, archetype);
|
|
372
|
+
if (perfA !== perfB) return perfB - perfA;
|
|
373
|
+
const vA = a.versionAdded ?? "";
|
|
374
|
+
const vB = b.versionAdded ?? "";
|
|
375
|
+
if (vA !== vB) return vA < vB ? 1 : -1;
|
|
376
|
+
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
377
|
+
});
|
|
378
|
+
return sorted;
|
|
379
|
+
}
|
|
380
|
+
function getRecommendedPrimary(opts) {
|
|
381
|
+
if (opts.posture === "locked") return opts.fallback;
|
|
382
|
+
const registry = loadModelsFromBrain();
|
|
383
|
+
const candidates = selectCandidates(
|
|
384
|
+
registry,
|
|
385
|
+
opts.family,
|
|
386
|
+
opts.archetype,
|
|
387
|
+
opts.appId
|
|
388
|
+
);
|
|
389
|
+
if (candidates.length === 0) return opts.fallback;
|
|
390
|
+
const sorted = sortCandidates(candidates, opts.archetype);
|
|
391
|
+
return sorted[0]?.id ?? opts.fallback;
|
|
392
|
+
}
|
|
393
|
+
function resolveFamilyEntry(family, ctx) {
|
|
394
|
+
if (typeof family !== "string" || family.length === 0) {
|
|
395
|
+
throw new FamilyResolutionError(
|
|
396
|
+
String(family),
|
|
397
|
+
"Family tag must be a non-empty string"
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
const registry = loadModelsFromBrain();
|
|
401
|
+
const candidates = selectCandidates(
|
|
402
|
+
registry,
|
|
403
|
+
family,
|
|
404
|
+
ctx.archetype,
|
|
405
|
+
ctx.appId
|
|
406
|
+
);
|
|
407
|
+
if (candidates.length === 0) {
|
|
408
|
+
let anyInFamily = false;
|
|
409
|
+
for (const profile of registry.values()) {
|
|
410
|
+
if (familyOf(profile) === family) {
|
|
411
|
+
anyInFamily = true;
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
const cause = anyInFamily ? `Family has registered models but none are current+active${ctx.archetype ? ` at archetype-perf >= ${ARCHETYPE_FLOOR_DEFAULT} for "${ctx.archetype}"` : ""}${ctx.appId ? ` and not excluded for app "${ctx.appId}"` : ""}` : `No models in brain registry carry family="${family}". Check the taxonomy table in family-resolution.ts or migration 024`;
|
|
416
|
+
throw new FamilyResolutionError(family, cause);
|
|
417
|
+
}
|
|
418
|
+
const sorted = sortCandidates(candidates, ctx.archetype);
|
|
419
|
+
const winner = sorted[0];
|
|
420
|
+
if (!winner) {
|
|
421
|
+
throw new FamilyResolutionError(
|
|
422
|
+
family,
|
|
423
|
+
"Candidates non-empty but sort returned undefined \u2014 internal invariant violation"
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
return winner.id;
|
|
427
|
+
}
|
|
428
|
+
|
|
55
429
|
// src/tokenizer.ts
|
|
56
430
|
var tokenizerImpl = defaultCharBasedCounter;
|
|
57
431
|
function defaultCharBasedCounter(text) {
|
|
@@ -450,6 +824,175 @@ function simpleHash(s) {
|
|
|
450
824
|
}
|
|
451
825
|
return (h >>> 0).toString(36);
|
|
452
826
|
}
|
|
827
|
+
function resolveConventionsForProfile(profile) {
|
|
828
|
+
const own = profile.archetypeConventions ?? [];
|
|
829
|
+
const family = profile.family ?? deriveFamilyFromModelId(profile.id);
|
|
830
|
+
if (!family) return own;
|
|
831
|
+
return own;
|
|
832
|
+
}
|
|
833
|
+
function applyArchetypeConvention(promptText, archetype, family) {
|
|
834
|
+
if (typeof promptText !== "string" || promptText.length === 0) return promptText;
|
|
835
|
+
const repId = familyRepId(family);
|
|
836
|
+
if (!repId) return promptText;
|
|
837
|
+
const profile = tryGetProfile(repId);
|
|
838
|
+
if (!profile || !profile.archetypeConventions) return promptText;
|
|
839
|
+
const conventions = profile.archetypeConventions.filter((c) => c.archetype === archetype);
|
|
840
|
+
if (conventions.length === 0) return promptText;
|
|
841
|
+
let next = promptText;
|
|
842
|
+
for (const c of conventions) {
|
|
843
|
+
if (c.promptPrefix) {
|
|
844
|
+
if (!next.startsWith(c.promptPrefix)) {
|
|
845
|
+
next = c.promptPrefix + next;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
if (c.promptSuffix) {
|
|
849
|
+
if (!next.endsWith(c.promptSuffix)) {
|
|
850
|
+
next = next + c.promptSuffix;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
return next;
|
|
855
|
+
}
|
|
856
|
+
function familyRepId(family) {
|
|
857
|
+
switch (family) {
|
|
858
|
+
case "deepseek-reasoner":
|
|
859
|
+
return "deepseek-v4-pro";
|
|
860
|
+
case "deepseek-chat":
|
|
861
|
+
return "deepseek-v4-flash";
|
|
862
|
+
default:
|
|
863
|
+
return void 0;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
function passApplyConventions(ir, profile) {
|
|
867
|
+
const mutations = [];
|
|
868
|
+
const cliffWarnings = [];
|
|
869
|
+
const structuredOutputHints = [];
|
|
870
|
+
const own = profile.archetypeConventions ?? [];
|
|
871
|
+
let effective = own;
|
|
872
|
+
if (effective.length === 0) {
|
|
873
|
+
const family2 = profile.family ?? deriveFamilyFromModelId(profile.id);
|
|
874
|
+
if (family2) {
|
|
875
|
+
const repId = familyRepId(family2);
|
|
876
|
+
if (repId && repId !== profile.id) {
|
|
877
|
+
const repProfile = tryGetProfile(repId);
|
|
878
|
+
if (repProfile && repProfile.archetypeConventions) {
|
|
879
|
+
effective = repProfile.archetypeConventions;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
if (effective.length === 0) {
|
|
885
|
+
return {
|
|
886
|
+
value: { ir, cliffWarnings, structuredOutputHints },
|
|
887
|
+
mutations
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
const archetype = ir.intent.archetype;
|
|
891
|
+
const matching = effective.filter((c) => c.archetype === archetype);
|
|
892
|
+
if (matching.length === 0) {
|
|
893
|
+
return {
|
|
894
|
+
value: { ir, cliffWarnings, structuredOutputHints },
|
|
895
|
+
mutations
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
const family = profile.family ?? deriveFamilyFromModelId(profile.id) ?? "unknown";
|
|
899
|
+
let nextIR = ir;
|
|
900
|
+
for (const convention of matching) {
|
|
901
|
+
let touched = false;
|
|
902
|
+
if (convention.promptPrefix) {
|
|
903
|
+
const sections = nextIR.sections ?? [];
|
|
904
|
+
const alreadyPresent = sections.some(
|
|
905
|
+
(s) => s.text.includes(convention.promptPrefix)
|
|
906
|
+
);
|
|
907
|
+
if (!alreadyPresent) {
|
|
908
|
+
const prefixSection = {
|
|
909
|
+
id: `convention-prefix-${family}-${archetype}`,
|
|
910
|
+
text: convention.promptPrefix
|
|
911
|
+
};
|
|
912
|
+
nextIR = { ...nextIR, sections: [prefixSection, ...sections] };
|
|
913
|
+
touched = true;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
if (convention.promptSuffix) {
|
|
917
|
+
const history = nextIR.history ?? [];
|
|
918
|
+
let lastUserIdx = -1;
|
|
919
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
920
|
+
if (history[i]?.role === "user") {
|
|
921
|
+
lastUserIdx = i;
|
|
922
|
+
break;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
if (lastUserIdx >= 0) {
|
|
926
|
+
const target = history[lastUserIdx];
|
|
927
|
+
if (!target.content.endsWith(convention.promptSuffix)) {
|
|
928
|
+
const newHistory = history.slice();
|
|
929
|
+
newHistory[lastUserIdx] = {
|
|
930
|
+
...target,
|
|
931
|
+
content: target.content + convention.promptSuffix
|
|
932
|
+
};
|
|
933
|
+
nextIR = { ...nextIR, history: newHistory };
|
|
934
|
+
touched = true;
|
|
935
|
+
}
|
|
936
|
+
} else if (nextIR.currentTurn && nextIR.currentTurn.role === "user") {
|
|
937
|
+
const target = nextIR.currentTurn;
|
|
938
|
+
if (!target.content.endsWith(convention.promptSuffix)) {
|
|
939
|
+
nextIR = {
|
|
940
|
+
...nextIR,
|
|
941
|
+
currentTurn: {
|
|
942
|
+
...target,
|
|
943
|
+
content: target.content + convention.promptSuffix
|
|
944
|
+
}
|
|
945
|
+
};
|
|
946
|
+
touched = true;
|
|
947
|
+
}
|
|
948
|
+
} else {
|
|
949
|
+
nextIR = {
|
|
950
|
+
...nextIR,
|
|
951
|
+
currentTurn: {
|
|
952
|
+
role: "user",
|
|
953
|
+
content: convention.promptSuffix.trim()
|
|
954
|
+
}
|
|
955
|
+
};
|
|
956
|
+
touched = true;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
if (convention.structuredOutputHint) {
|
|
960
|
+
const wantsStructured = !!nextIR.constraints?.structuredOutput;
|
|
961
|
+
const shouldSurface = convention.structuredOutputHint === "avoid" && wantsStructured || convention.structuredOutputHint === "enforce" && !wantsStructured;
|
|
962
|
+
if (shouldSurface) {
|
|
963
|
+
structuredOutputHints.push({
|
|
964
|
+
archetype,
|
|
965
|
+
hint: convention.structuredOutputHint,
|
|
966
|
+
reason: convention.reason
|
|
967
|
+
});
|
|
968
|
+
if (convention.cliffWarning) {
|
|
969
|
+
cliffWarnings.push(`${profile.id}: ${convention.cliffWarning}`);
|
|
970
|
+
}
|
|
971
|
+
touched = true;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
if (convention.cliffWarning && !convention.structuredOutputHint) {
|
|
975
|
+
const toolCount = nextIR.tools?.length ?? 0;
|
|
976
|
+
const thresholdOk = convention.whenToolCountAtLeast === void 0 || toolCount >= convention.whenToolCountAtLeast;
|
|
977
|
+
if (thresholdOk) {
|
|
978
|
+
cliffWarnings.push(`${profile.id}: ${convention.cliffWarning}`);
|
|
979
|
+
touched = true;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
if (touched) {
|
|
983
|
+
mutations.push({
|
|
984
|
+
id: `apply-convention-${family}-${archetype}`,
|
|
985
|
+
source: "archetype_convention",
|
|
986
|
+
passName: "apply_conventions",
|
|
987
|
+
description: `${profile.id}: applied ${family}-family convention for archetype=${archetype} \u2014 ${convention.reason}`
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
return {
|
|
992
|
+
value: { ir: nextIR, cliffWarnings, structuredOutputHints },
|
|
993
|
+
mutations
|
|
994
|
+
};
|
|
995
|
+
}
|
|
453
996
|
|
|
454
997
|
// src/lower.ts
|
|
455
998
|
function lower(ir, profile, hints = {}) {
|
|
@@ -827,125 +1370,6 @@ function getArchetypePerfScore(modelId, archetype) {
|
|
|
827
1370
|
return { score, n, grounding };
|
|
828
1371
|
}
|
|
829
1372
|
|
|
830
|
-
// src/exclusion-findings-brain.ts
|
|
831
|
-
function isValidVerdict(v) {
|
|
832
|
-
return v === "recommend-probe" || v === "unblock" || v === "stay-excluded" || v === "inconclusive";
|
|
833
|
-
}
|
|
834
|
-
function isValidConfidence(v) {
|
|
835
|
-
return v === "high" || v === "medium" || v === "low";
|
|
836
|
-
}
|
|
837
|
-
function isRawFindingRow(x) {
|
|
838
|
-
if (!x || typeof x !== "object") return false;
|
|
839
|
-
const r = x;
|
|
840
|
-
return typeof r.intent_archetype === "string" && typeof r.excluded_model === "string" && typeof r.excluded_provider === "string" && typeof r.verdict === "string" && typeof r.message === "string" && typeof r.suggestion === "string" && typeof r.confidence === "string";
|
|
841
|
-
}
|
|
842
|
-
function mapRowsToFindings(rows) {
|
|
843
|
-
const out = [];
|
|
844
|
-
for (const row of rows) {
|
|
845
|
-
if (!isRawFindingRow(row)) continue;
|
|
846
|
-
if (!isValidVerdict(row.verdict)) continue;
|
|
847
|
-
if (!isValidConfidence(row.confidence)) continue;
|
|
848
|
-
let savings = null;
|
|
849
|
-
if (typeof row.estimated_savings_usd_30d === "number") {
|
|
850
|
-
savings = Number.isFinite(row.estimated_savings_usd_30d) ? row.estimated_savings_usd_30d : null;
|
|
851
|
-
} else if (typeof row.estimated_savings_usd_30d === "string") {
|
|
852
|
-
const n = Number(row.estimated_savings_usd_30d);
|
|
853
|
-
savings = Number.isFinite(n) ? n : null;
|
|
854
|
-
}
|
|
855
|
-
out.push({
|
|
856
|
-
archetype: row.intent_archetype,
|
|
857
|
-
excludedModel: row.excluded_model,
|
|
858
|
-
excludedProvider: row.excluded_provider,
|
|
859
|
-
verdict: row.verdict,
|
|
860
|
-
estimatedSavingsUsd30d: savings,
|
|
861
|
-
message: row.message,
|
|
862
|
-
suggestion: row.suggestion,
|
|
863
|
-
confidence: row.confidence,
|
|
864
|
-
evidence: row.evidence && typeof row.evidence === "object" ? row.evidence : void 0
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
|
-
return out;
|
|
868
|
-
}
|
|
869
|
-
var snapshots = /* @__PURE__ */ new Map();
|
|
870
|
-
var runtime;
|
|
871
|
-
var warnedOnce = false;
|
|
872
|
-
var DEFAULT_FINDINGS_ENDPOINT = "https://kgauto-dashboard.vercel.app/api/kgauto-v2/findings/exclusions";
|
|
873
|
-
function configureExclusionFindingsBrain(rt) {
|
|
874
|
-
runtime = rt;
|
|
875
|
-
snapshots.clear();
|
|
876
|
-
warnedOnce = false;
|
|
877
|
-
}
|
|
878
|
-
function isExclusionFindingsBrainActive() {
|
|
879
|
-
return runtime !== void 0;
|
|
880
|
-
}
|
|
881
|
-
function getStaleExclusionFindings(opts) {
|
|
882
|
-
const rt = runtime;
|
|
883
|
-
if (!rt) return [];
|
|
884
|
-
const appId = opts.appId;
|
|
885
|
-
if (!appId) return [];
|
|
886
|
-
let snap = snapshots.get(appId);
|
|
887
|
-
if (!snap) {
|
|
888
|
-
snap = { data: [], expiresAt: 0, refreshing: false };
|
|
889
|
-
snapshots.set(appId, snap);
|
|
890
|
-
}
|
|
891
|
-
const now = Date.now();
|
|
892
|
-
const stale = snap.expiresAt <= now;
|
|
893
|
-
if (stale && !snap.refreshing) {
|
|
894
|
-
snap.refreshing = true;
|
|
895
|
-
void asyncRefresh(rt, appId);
|
|
896
|
-
}
|
|
897
|
-
if (opts.archetype) {
|
|
898
|
-
return snap.data.filter((f) => f.archetype === opts.archetype);
|
|
899
|
-
}
|
|
900
|
-
return snap.data;
|
|
901
|
-
}
|
|
902
|
-
var pendingRefreshes = /* @__PURE__ */ new Map();
|
|
903
|
-
async function asyncRefresh(rt, appId) {
|
|
904
|
-
const promise = doRefresh(rt, appId);
|
|
905
|
-
pendingRefreshes.set(appId, promise);
|
|
906
|
-
try {
|
|
907
|
-
await promise;
|
|
908
|
-
} finally {
|
|
909
|
-
if (pendingRefreshes.get(appId) === promise) {
|
|
910
|
-
pendingRefreshes.delete(appId);
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
async function doRefresh(rt, appId) {
|
|
915
|
-
const url = `${rt.endpoint}?app_id=${encodeURIComponent(appId)}`;
|
|
916
|
-
let snap = snapshots.get(appId);
|
|
917
|
-
if (!snap) {
|
|
918
|
-
snap = { data: [], expiresAt: 0, refreshing: false };
|
|
919
|
-
snapshots.set(appId, snap);
|
|
920
|
-
}
|
|
921
|
-
try {
|
|
922
|
-
const res = await rt.fetchImpl(url, { method: "GET" });
|
|
923
|
-
if (!res.ok) {
|
|
924
|
-
throw new Error(`findings ${res.status}: ${res.statusText}`);
|
|
925
|
-
}
|
|
926
|
-
const body = await res.json();
|
|
927
|
-
if (runtime !== rt) return;
|
|
928
|
-
const rows = Array.isArray(body) ? mapRowsToFindings(body) : [];
|
|
929
|
-
snap.data = rows;
|
|
930
|
-
snap.expiresAt = Date.now() + rt.ttlMs;
|
|
931
|
-
snap.refreshing = false;
|
|
932
|
-
} catch (err) {
|
|
933
|
-
if (runtime !== rt) return;
|
|
934
|
-
snap.refreshing = false;
|
|
935
|
-
snap.expiresAt = Date.now() + rt.ttlMs;
|
|
936
|
-
if (!warnedOnce) {
|
|
937
|
-
warnedOnce = true;
|
|
938
|
-
(rt.onError ?? defaultOnError)(err);
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
function defaultOnError(err) {
|
|
943
|
-
console.warn(
|
|
944
|
-
"[kgauto] exclusion-findings fetch failed (using empty fallback):",
|
|
945
|
-
err
|
|
946
|
-
);
|
|
947
|
-
}
|
|
948
|
-
|
|
949
1373
|
// src/promote-ready-brain.ts
|
|
950
1374
|
function isRawPromoteReadyRow(x) {
|
|
951
1375
|
if (!x || typeof x !== "object") return false;
|
|
@@ -1333,6 +1757,77 @@ function advisorRuleConsumerOnStaleModel(ir) {
|
|
|
1333
1757
|
];
|
|
1334
1758
|
}
|
|
1335
1759
|
|
|
1760
|
+
// src/archetype-fits.ts
|
|
1761
|
+
var ARCHETYPE_FAMILY_FITS = Object.freeze([
|
|
1762
|
+
{
|
|
1763
|
+
archetype: "plan",
|
|
1764
|
+
betterFitFamily: "deepseek-reasoner",
|
|
1765
|
+
reason: "Plan archetype is reasoning-shaped (multi-step chains, hypothesis-and-check, sub-goal decomposition) \u2014 exactly where reasoner-family models excel. Sonnet/Opus produce plans but at higher cost; reasoners produce equivalent-or-better plans at 7-17x lower cost at current promo pricing (deepseek-v4-pro $0.435/$0.87 per 1M promo through 2026-05-31 vs sonnet $3/$15).",
|
|
1766
|
+
costGuidance: "substantially cheaper at current pricing (deepseek-v4-pro promo: ~7-17x cheaper than sonnet)"
|
|
1767
|
+
},
|
|
1768
|
+
{
|
|
1769
|
+
archetype: "critique",
|
|
1770
|
+
betterFitFamily: "deepseek-reasoner",
|
|
1771
|
+
reason: "Critique archetype rewards epistemic humility and explicit reasoning \u2014 reasoner-family default behavior. Sonnet/Opus over-confident on critique tasks; reasoners surface uncertainty productively.",
|
|
1772
|
+
costGuidance: "comparable or cheaper at current pricing"
|
|
1773
|
+
}
|
|
1774
|
+
]);
|
|
1775
|
+
function findBetterFit(archetype, currentFamily) {
|
|
1776
|
+
for (const fit of ARCHETYPE_FAMILY_FITS) {
|
|
1777
|
+
if (fit.archetype !== archetype) continue;
|
|
1778
|
+
if (fit.betterFitFamily === currentFamily) return null;
|
|
1779
|
+
return fit;
|
|
1780
|
+
}
|
|
1781
|
+
return null;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
// src/advisor-rules/cross-family-fit.ts
|
|
1785
|
+
function familyHasCurrentActiveModel(family) {
|
|
1786
|
+
for (const profile of allProfiles()) {
|
|
1787
|
+
const profileFamily = profile.family ?? deriveFamilyFromModelId(profile.id);
|
|
1788
|
+
if (profileFamily !== family) continue;
|
|
1789
|
+
if (profile.status !== "current") continue;
|
|
1790
|
+
if (profile.active === false) continue;
|
|
1791
|
+
return true;
|
|
1792
|
+
}
|
|
1793
|
+
return false;
|
|
1794
|
+
}
|
|
1795
|
+
function listCandidatesInFamily(family) {
|
|
1796
|
+
const candidates = [];
|
|
1797
|
+
for (const profile of allProfiles()) {
|
|
1798
|
+
const profileFamily = profile.family ?? deriveFamilyFromModelId(profile.id);
|
|
1799
|
+
if (profileFamily !== family) continue;
|
|
1800
|
+
if (profile.status !== "current") continue;
|
|
1801
|
+
if (profile.active === false) continue;
|
|
1802
|
+
candidates.push(profile.id);
|
|
1803
|
+
if (candidates.length >= 3) break;
|
|
1804
|
+
}
|
|
1805
|
+
return candidates;
|
|
1806
|
+
}
|
|
1807
|
+
function advisorRuleCrossFamilyFit(ctx) {
|
|
1808
|
+
if (!ctx.resolvedPrimary) return [];
|
|
1809
|
+
const currentFamily = deriveFamilyFromModelId(ctx.resolvedPrimary);
|
|
1810
|
+
if (!currentFamily) return [];
|
|
1811
|
+
const fit = findBetterFit(ctx.archetype, currentFamily);
|
|
1812
|
+
if (!fit) return [];
|
|
1813
|
+
if (!familyHasCurrentActiveModel(fit.betterFitFamily)) return [];
|
|
1814
|
+
const candidates = listCandidatesInFamily(fit.betterFitFamily);
|
|
1815
|
+
if (candidates.length === 0) return [];
|
|
1816
|
+
const candidateStr = candidates.join(", ");
|
|
1817
|
+
const message = `Your ${currentFamily} call on ${ctx.archetype} could shift to ${fit.betterFitFamily} \u2014 typically better quality + ${fit.costGuidance}. Suggested candidates: ${candidateStr}.`;
|
|
1818
|
+
return [
|
|
1819
|
+
{
|
|
1820
|
+
level: "info",
|
|
1821
|
+
code: "cross-family-fit-candidate",
|
|
1822
|
+
ownership: "consumer-actionable",
|
|
1823
|
+
message,
|
|
1824
|
+
suggestion: `Swap the model literal in \`ir.models\` to one of: ${candidateStr}. Or call \`getRecommendedPrimary({ family: '${fit.betterFitFamily}', archetype: '${ctx.archetype}', fallback: { id: '${candidates[0]}', reason: 'cross-family-fit-recommendation' } })\` to let kgauto resolve to the current+active family member.`,
|
|
1825
|
+
recommendationType: "model-swap",
|
|
1826
|
+
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories"
|
|
1827
|
+
}
|
|
1828
|
+
];
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1336
1831
|
// src/advisor.ts
|
|
1337
1832
|
var QUALITY_FLOOR_FOR_RECOMMENDATION = 6;
|
|
1338
1833
|
var TIER_DOWN_COST_RATIO = 0.5;
|
|
@@ -1372,6 +1867,14 @@ function runAdvisor(ir, result, profile, policy, phase2) {
|
|
|
1372
1867
|
);
|
|
1373
1868
|
out.push(...advisorRuleConsumerOnStaleModel(ir));
|
|
1374
1869
|
}
|
|
1870
|
+
if (policy?.posture !== "locked") {
|
|
1871
|
+
out.push(
|
|
1872
|
+
...advisorRuleCrossFamilyFit({
|
|
1873
|
+
archetype: ir.intent.archetype,
|
|
1874
|
+
resolvedPrimary: profile.id
|
|
1875
|
+
})
|
|
1876
|
+
);
|
|
1877
|
+
}
|
|
1375
1878
|
return out;
|
|
1376
1879
|
}
|
|
1377
1880
|
function translatorClearedToolCallCliff(phase2) {
|
|
@@ -1683,261 +2186,6 @@ ${originalText}`;
|
|
|
1683
2186
|
return { rewrittenIR, rewrites };
|
|
1684
2187
|
}
|
|
1685
2188
|
|
|
1686
|
-
// src/models-brain.ts
|
|
1687
|
-
function isModelRow(x) {
|
|
1688
|
-
if (!x || typeof x !== "object") return false;
|
|
1689
|
-
const r = x;
|
|
1690
|
-
return typeof r.model_id === "string" && typeof r.provider === "string";
|
|
1691
|
-
}
|
|
1692
|
-
function isAliasRow(x) {
|
|
1693
|
-
if (!x || typeof x !== "object") return false;
|
|
1694
|
-
const r = x;
|
|
1695
|
-
return typeof r.alias_id === "string" && typeof r.canonical_id === "string";
|
|
1696
|
-
}
|
|
1697
|
-
function rowToProfile(row) {
|
|
1698
|
-
try {
|
|
1699
|
-
if (row.cliffs !== void 0 && row.cliffs !== null && !Array.isArray(row.cliffs)) {
|
|
1700
|
-
return null;
|
|
1701
|
-
}
|
|
1702
|
-
if (row.recovery !== void 0 && row.recovery !== null && !Array.isArray(row.recovery)) {
|
|
1703
|
-
return null;
|
|
1704
|
-
}
|
|
1705
|
-
if (row.lowering !== void 0 && row.lowering !== null && (typeof row.lowering !== "object" || Array.isArray(row.lowering))) {
|
|
1706
|
-
return null;
|
|
1707
|
-
}
|
|
1708
|
-
return {
|
|
1709
|
-
id: row.model_id,
|
|
1710
|
-
provider: row.provider,
|
|
1711
|
-
status: row.status ?? "current",
|
|
1712
|
-
maxContextTokens: row.max_context_tokens ?? 0,
|
|
1713
|
-
maxOutputTokens: row.max_output_tokens ?? 0,
|
|
1714
|
-
maxTools: row.max_tools ?? 0,
|
|
1715
|
-
parallelToolCalls: row.parallel_tool_calls ?? false,
|
|
1716
|
-
structuredOutput: row.structured_output ?? "none",
|
|
1717
|
-
systemPromptMode: row.system_prompt_mode ?? "inline",
|
|
1718
|
-
streaming: row.streaming ?? true,
|
|
1719
|
-
cliffs: row.cliffs ?? [],
|
|
1720
|
-
costInputPer1m: row.cost_input_per_1m ?? 0,
|
|
1721
|
-
costOutputPer1m: row.cost_output_per_1m ?? 0,
|
|
1722
|
-
lowering: row.lowering ?? { system: { mode: "inline" }, cache: { strategy: "unsupported" } },
|
|
1723
|
-
recovery: row.recovery ?? [],
|
|
1724
|
-
strengths: row.strengths ?? [],
|
|
1725
|
-
weaknesses: row.weaknesses ?? [],
|
|
1726
|
-
notes: row.notes ?? void 0,
|
|
1727
|
-
verifiedAgainstDocs: row.verified_against_docs ?? void 0,
|
|
1728
|
-
archetypePerf: row.archetype_perf ?? void 0,
|
|
1729
|
-
// alpha.41 — family-resolution fields. `family` may be null pre-
|
|
1730
|
-
// migration 024; runtime falls back to deriveFamilyFromModelId at
|
|
1731
|
-
// resolution time (see family-resolution.ts, G1).
|
|
1732
|
-
family: row.family ?? void 0,
|
|
1733
|
-
versionAdded: row.version_added ?? void 0,
|
|
1734
|
-
active: row.active ?? void 0
|
|
1735
|
-
};
|
|
1736
|
-
} catch {
|
|
1737
|
-
return null;
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1740
|
-
function profileToRow(profile, opts = {}) {
|
|
1741
|
-
const row = {
|
|
1742
|
-
model_id: profile.id,
|
|
1743
|
-
provider: profile.provider,
|
|
1744
|
-
status: profile.status,
|
|
1745
|
-
max_context_tokens: profile.maxContextTokens,
|
|
1746
|
-
max_output_tokens: profile.maxOutputTokens,
|
|
1747
|
-
max_tools: profile.maxTools,
|
|
1748
|
-
parallel_tool_calls: profile.parallelToolCalls,
|
|
1749
|
-
structured_output: profile.structuredOutput,
|
|
1750
|
-
system_prompt_mode: profile.systemPromptMode,
|
|
1751
|
-
streaming: profile.streaming,
|
|
1752
|
-
cliffs: profile.cliffs,
|
|
1753
|
-
cost_input_per_1m: profile.costInputPer1m,
|
|
1754
|
-
cost_output_per_1m: profile.costOutputPer1m,
|
|
1755
|
-
lowering: profile.lowering,
|
|
1756
|
-
recovery: profile.recovery,
|
|
1757
|
-
strengths: profile.strengths,
|
|
1758
|
-
weaknesses: profile.weaknesses,
|
|
1759
|
-
notes: profile.notes ?? null,
|
|
1760
|
-
archetype_perf: profile.archetypePerf ?? null,
|
|
1761
|
-
active: opts.active ?? profile.active ?? true,
|
|
1762
|
-
// alpha.41 — round-trip family + version_added when present on profile.
|
|
1763
|
-
// version_added is operator-controlled via opts; profile-side value is
|
|
1764
|
-
// used only when opts didn't override.
|
|
1765
|
-
family: profile.family ?? null
|
|
1766
|
-
};
|
|
1767
|
-
if (opts.verifiedAgainstDocs !== void 0) {
|
|
1768
|
-
row.verified_against_docs = opts.verifiedAgainstDocs;
|
|
1769
|
-
} else if (profile.verifiedAgainstDocs !== void 0) {
|
|
1770
|
-
const v = profile.verifiedAgainstDocs;
|
|
1771
|
-
row.verified_against_docs = /^\d{4}-\d{2}-\d{2}/.test(v) ? v : null;
|
|
1772
|
-
}
|
|
1773
|
-
if (opts.versionAdded !== void 0) row.version_added = opts.versionAdded;
|
|
1774
|
-
else if (profile.versionAdded !== void 0) row.version_added = profile.versionAdded;
|
|
1775
|
-
if (opts.versionRemoved !== void 0) row.version_removed = opts.versionRemoved;
|
|
1776
|
-
return row;
|
|
1777
|
-
}
|
|
1778
|
-
function mapRowsToModels(rows) {
|
|
1779
|
-
const out = /* @__PURE__ */ new Map();
|
|
1780
|
-
for (const row of rows) {
|
|
1781
|
-
if (!isModelRow(row)) continue;
|
|
1782
|
-
const profile = rowToProfile(row);
|
|
1783
|
-
if (profile) out.set(profile.id, profile);
|
|
1784
|
-
}
|
|
1785
|
-
return out;
|
|
1786
|
-
}
|
|
1787
|
-
function mapRowsToAliases(rows) {
|
|
1788
|
-
const out = {};
|
|
1789
|
-
for (const row of rows) {
|
|
1790
|
-
if (!isAliasRow(row)) continue;
|
|
1791
|
-
out[row.alias_id] = row.canonical_id;
|
|
1792
|
-
}
|
|
1793
|
-
return out;
|
|
1794
|
-
}
|
|
1795
|
-
function bundledModels() {
|
|
1796
|
-
return new Map(allProfilesRaw().map((p) => [p.id, p]));
|
|
1797
|
-
}
|
|
1798
|
-
function bundledAliases() {
|
|
1799
|
-
return { ...ALIASES };
|
|
1800
|
-
}
|
|
1801
|
-
var loadModelsFromBrain = createBrainQueryCache({
|
|
1802
|
-
table: "kgauto_models",
|
|
1803
|
-
mapRows: mapRowsToModels,
|
|
1804
|
-
bundledFallback: bundledModels
|
|
1805
|
-
});
|
|
1806
|
-
var loadAliasesFromBrain = createBrainQueryCache({
|
|
1807
|
-
table: "kgauto_aliases",
|
|
1808
|
-
mapRows: mapRowsToAliases,
|
|
1809
|
-
bundledFallback: bundledAliases
|
|
1810
|
-
});
|
|
1811
|
-
_setProfileBrainHook({
|
|
1812
|
-
getProfile: (canonical) => loadModelsFromBrain().get(canonical),
|
|
1813
|
-
resolveAlias: (id) => loadAliasesFromBrain()[id]
|
|
1814
|
-
});
|
|
1815
|
-
|
|
1816
|
-
// src/family-resolution.ts
|
|
1817
|
-
var FamilyResolutionError = class extends Error {
|
|
1818
|
-
family;
|
|
1819
|
-
cause;
|
|
1820
|
-
constructor(family, cause) {
|
|
1821
|
-
super(
|
|
1822
|
-
`Family "${family}" did not resolve to any current+active model. ${cause}. Pass a literal model id in ir.models, or call getRecommendedPrimary({ family, fallback }) at IR-construction time.`
|
|
1823
|
-
);
|
|
1824
|
-
this.name = "FamilyResolutionError";
|
|
1825
|
-
this.family = family;
|
|
1826
|
-
this.cause = cause;
|
|
1827
|
-
}
|
|
1828
|
-
};
|
|
1829
|
-
function deriveFamilyFromModelId(modelId) {
|
|
1830
|
-
if (typeof modelId !== "string" || modelId.length === 0) return null;
|
|
1831
|
-
if (modelId.startsWith("claude-opus-")) return "claude-opus";
|
|
1832
|
-
if (modelId.startsWith("claude-sonnet-")) return "claude-sonnet";
|
|
1833
|
-
if (modelId.startsWith("claude-haiku-")) return "claude-haiku";
|
|
1834
|
-
if (modelId.startsWith("gemini-") && modelId.includes("flash-lite")) {
|
|
1835
|
-
return "gemini-flash-lite";
|
|
1836
|
-
}
|
|
1837
|
-
if (modelId.startsWith("gemini-") && modelId.includes("flash")) {
|
|
1838
|
-
return "gemini-flash";
|
|
1839
|
-
}
|
|
1840
|
-
if (modelId.startsWith("gemini-") && modelId.includes("pro")) {
|
|
1841
|
-
return "gemini-pro";
|
|
1842
|
-
}
|
|
1843
|
-
if (modelId.startsWith("deepseek-") && modelId.includes("pro")) {
|
|
1844
|
-
return "deepseek-reasoner";
|
|
1845
|
-
}
|
|
1846
|
-
if (modelId.startsWith("deepseek-")) return "deepseek-chat";
|
|
1847
|
-
if (modelId.startsWith("gpt-")) return "openai-gpt";
|
|
1848
|
-
return null;
|
|
1849
|
-
}
|
|
1850
|
-
function familyOf(profile) {
|
|
1851
|
-
return profile.family ?? deriveFamilyFromModelId(profile.id);
|
|
1852
|
-
}
|
|
1853
|
-
function archetypePerfFor(profile, archetype) {
|
|
1854
|
-
if (!archetype) return 0;
|
|
1855
|
-
const score = profile.archetypePerf?.[archetype];
|
|
1856
|
-
return typeof score === "number" ? score : 5;
|
|
1857
|
-
}
|
|
1858
|
-
function selectCandidates(registry, family, archetype, appId) {
|
|
1859
|
-
const out = [];
|
|
1860
|
-
const excluded = /* @__PURE__ */ new Set();
|
|
1861
|
-
if (appId && archetype) {
|
|
1862
|
-
const findings = getStaleExclusionFindings({ appId, archetype });
|
|
1863
|
-
for (const f of findings) {
|
|
1864
|
-
if (f.verdict === "stay-excluded") excluded.add(f.excludedModel);
|
|
1865
|
-
}
|
|
1866
|
-
}
|
|
1867
|
-
for (const profile of registry.values()) {
|
|
1868
|
-
if (familyOf(profile) !== family) continue;
|
|
1869
|
-
if (profile.status !== "current") continue;
|
|
1870
|
-
if (profile.active === false) continue;
|
|
1871
|
-
if (archetype) {
|
|
1872
|
-
if (archetypePerfFor(profile, archetype) < ARCHETYPE_FLOOR_DEFAULT) continue;
|
|
1873
|
-
}
|
|
1874
|
-
if (excluded.has(profile.id)) continue;
|
|
1875
|
-
out.push(profile);
|
|
1876
|
-
}
|
|
1877
|
-
return out;
|
|
1878
|
-
}
|
|
1879
|
-
function sortCandidates(candidates, archetype) {
|
|
1880
|
-
const sorted = [...candidates];
|
|
1881
|
-
sorted.sort((a, b) => {
|
|
1882
|
-
const perfA = archetypePerfFor(a, archetype);
|
|
1883
|
-
const perfB = archetypePerfFor(b, archetype);
|
|
1884
|
-
if (perfA !== perfB) return perfB - perfA;
|
|
1885
|
-
const vA = a.versionAdded ?? "";
|
|
1886
|
-
const vB = b.versionAdded ?? "";
|
|
1887
|
-
if (vA !== vB) return vA < vB ? 1 : -1;
|
|
1888
|
-
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
1889
|
-
});
|
|
1890
|
-
return sorted;
|
|
1891
|
-
}
|
|
1892
|
-
function getRecommendedPrimary(opts) {
|
|
1893
|
-
if (opts.posture === "locked") return opts.fallback;
|
|
1894
|
-
const registry = loadModelsFromBrain();
|
|
1895
|
-
const candidates = selectCandidates(
|
|
1896
|
-
registry,
|
|
1897
|
-
opts.family,
|
|
1898
|
-
opts.archetype,
|
|
1899
|
-
opts.appId
|
|
1900
|
-
);
|
|
1901
|
-
if (candidates.length === 0) return opts.fallback;
|
|
1902
|
-
const sorted = sortCandidates(candidates, opts.archetype);
|
|
1903
|
-
return sorted[0]?.id ?? opts.fallback;
|
|
1904
|
-
}
|
|
1905
|
-
function resolveFamilyEntry(family, ctx) {
|
|
1906
|
-
if (typeof family !== "string" || family.length === 0) {
|
|
1907
|
-
throw new FamilyResolutionError(
|
|
1908
|
-
String(family),
|
|
1909
|
-
"Family tag must be a non-empty string"
|
|
1910
|
-
);
|
|
1911
|
-
}
|
|
1912
|
-
const registry = loadModelsFromBrain();
|
|
1913
|
-
const candidates = selectCandidates(
|
|
1914
|
-
registry,
|
|
1915
|
-
family,
|
|
1916
|
-
ctx.archetype,
|
|
1917
|
-
ctx.appId
|
|
1918
|
-
);
|
|
1919
|
-
if (candidates.length === 0) {
|
|
1920
|
-
let anyInFamily = false;
|
|
1921
|
-
for (const profile of registry.values()) {
|
|
1922
|
-
if (familyOf(profile) === family) {
|
|
1923
|
-
anyInFamily = true;
|
|
1924
|
-
break;
|
|
1925
|
-
}
|
|
1926
|
-
}
|
|
1927
|
-
const cause = anyInFamily ? `Family has registered models but none are current+active${ctx.archetype ? ` at archetype-perf >= ${ARCHETYPE_FLOOR_DEFAULT} for "${ctx.archetype}"` : ""}${ctx.appId ? ` and not excluded for app "${ctx.appId}"` : ""}` : `No models in brain registry carry family="${family}". Check the taxonomy table in family-resolution.ts or migration 024`;
|
|
1928
|
-
throw new FamilyResolutionError(family, cause);
|
|
1929
|
-
}
|
|
1930
|
-
const sorted = sortCandidates(candidates, ctx.archetype);
|
|
1931
|
-
const winner = sorted[0];
|
|
1932
|
-
if (!winner) {
|
|
1933
|
-
throw new FamilyResolutionError(
|
|
1934
|
-
family,
|
|
1935
|
-
"Candidates non-empty but sort returned undefined \u2014 internal invariant violation"
|
|
1936
|
-
);
|
|
1937
|
-
}
|
|
1938
|
-
return winner.id;
|
|
1939
|
-
}
|
|
1940
|
-
|
|
1941
2189
|
// src/compile.ts
|
|
1942
2190
|
var counter = 0;
|
|
1943
2191
|
function makeHandle() {
|
|
@@ -1982,6 +2230,9 @@ function compile(ir, opts = {}) {
|
|
|
1982
2230
|
const cliffs = passApplyCliffs(workingIR, profile, inputTokens);
|
|
1983
2231
|
workingIR = cliffs.value.ir;
|
|
1984
2232
|
accumulatedMutations.push(...cliffs.mutations);
|
|
2233
|
+
const conventions = passApplyConventions(workingIR, profile);
|
|
2234
|
+
workingIR = conventions.value.ir;
|
|
2235
|
+
accumulatedMutations.push(...conventions.mutations);
|
|
1985
2236
|
const translated = applySectionRewrites({
|
|
1986
2237
|
ir: workingIR,
|
|
1987
2238
|
profile,
|
|
@@ -2033,7 +2284,15 @@ function compile(ir, opts = {}) {
|
|
|
2033
2284
|
toolOrchestration: ir.constraints?.toolOrchestration,
|
|
2034
2285
|
// alpha.33 — see top-of-block comment.
|
|
2035
2286
|
historyCacheMarkIndex,
|
|
2036
|
-
systemCacheMarkIndex
|
|
2287
|
+
systemCacheMarkIndex,
|
|
2288
|
+
// alpha.43 — cliff-style warnings emitted by passApplyConventions.
|
|
2289
|
+
// Merge convention-pass cliffWarnings with any cliff-guard quality
|
|
2290
|
+
// warnings the cliff pass surfaced (the same shape — informational
|
|
2291
|
+
// text the consumer can route on without changing behavior).
|
|
2292
|
+
cliffWarnings: [
|
|
2293
|
+
...cliffs.value.loweringHints.qualityWarning ?? [],
|
|
2294
|
+
...conventions.value.cliffWarnings
|
|
2295
|
+
]
|
|
2037
2296
|
};
|
|
2038
2297
|
if (ir.intent.archetype === "hunt" && ir.constraints?.toolOrchestration === "sequential") {
|
|
2039
2298
|
accumulatedMutations.push({
|
|
@@ -3917,6 +4176,7 @@ export {
|
|
|
3917
4176
|
ABSOLUTE_FLOOR,
|
|
3918
4177
|
ALIASES,
|
|
3919
4178
|
ALL_ARCHETYPES,
|
|
4179
|
+
ARCHETYPE_FAMILY_FITS,
|
|
3920
4180
|
ARCHETYPE_FLOOR_DEFAULT,
|
|
3921
4181
|
CallError,
|
|
3922
4182
|
DEFAULT_FINDINGS_ENDPOINT,
|
|
@@ -3929,6 +4189,7 @@ export {
|
|
|
3929
4189
|
RULE_SEQUENTIAL_TOOL_CLIFF,
|
|
3930
4190
|
TRANSLATOR_FLOOR,
|
|
3931
4191
|
allProfiles,
|
|
4192
|
+
applyArchetypeConvention,
|
|
3932
4193
|
applySectionRewrites,
|
|
3933
4194
|
attachCacheControlToStreamTextInput,
|
|
3934
4195
|
bucketContext,
|
|
@@ -3943,6 +4204,7 @@ export {
|
|
|
3943
4204
|
deriveFamilyFromModelId,
|
|
3944
4205
|
deriveOwnership,
|
|
3945
4206
|
execute,
|
|
4207
|
+
findBetterFit,
|
|
3946
4208
|
getActionableAdvisories,
|
|
3947
4209
|
getAllStarterChains,
|
|
3948
4210
|
getAllStarterChainsWithGrounding,
|
|
@@ -3981,6 +4243,7 @@ export {
|
|
|
3981
4243
|
record,
|
|
3982
4244
|
recordOutcome,
|
|
3983
4245
|
resetTokenizer,
|
|
4246
|
+
resolveConventionsForProfile,
|
|
3984
4247
|
resolvePricingAt,
|
|
3985
4248
|
resolveProviderKey,
|
|
3986
4249
|
runAdvisor,
|