@warmdrift/kgauto-compiler 2.0.0-alpha.83 → 2.0.0-alpha.85
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-VVRDFE6T.mjs → chunk-FD3NFXDC.mjs} +4 -0
- package/dist/{chunk-XPD4I3Q5.mjs → chunk-LO2JXTGG.mjs} +19 -5
- package/dist/{chunk-QEFIAAE7.mjs → chunk-WXN7FNXP.mjs} +1 -1
- 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 +16 -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 +217 -131
- package/dist/index.d.ts +217 -131
- package/dist/index.js +140 -27
- package/dist/index.mjs +124 -25
- package/dist/{ir-Cx9hJj0B.d.ts → ir-DfrM71pA.d.ts} +49 -0
- package/dist/{ir-D4S9R816.d.mts → ir-JUoybVM-.d.mts} +49 -0
- package/dist/key-health.js +1 -1
- package/dist/key-health.mjs +1 -1
- package/dist/profiles.d.mts +11 -2
- package/dist/profiles.d.ts +11 -2
- package/dist/profiles.js +5 -0
- package/dist/profiles.mjs +3 -1
- package/dist/{types-DHi4FcUu.d.mts → types-BGH_KAHu.d.mts} +1 -1
- package/dist/{types-CAs9-0S4.d.ts → types-BqTKRECa.d.ts} +1 -1
- package/dist/{types-Cvd6kRNv.d.ts → types-DLDJbCha.d.ts} +1 -1
- package/dist/{types-CRXaR7nJ.d.mts → types-y42mwdvM.d.mts} +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27,6 +27,8 @@ __export(index_exports, {
|
|
|
27
27
|
ALT_STRATEGY_IDS: () => ALT_STRATEGY_IDS,
|
|
28
28
|
ARCHETYPE_FAMILY_FITS: () => ARCHETYPE_FAMILY_FITS,
|
|
29
29
|
ARCHETYPE_FLOOR_DEFAULT: () => ARCHETYPE_FLOOR_DEFAULT,
|
|
30
|
+
BLOCKED_MODEL_FAMILY_SIBLING_SERVED_CODE: () => BLOCKED_MODEL_FAMILY_SIBLING_SERVED_CODE,
|
|
31
|
+
BLOCKED_MODEL_NOT_IN_ROSTER_CODE: () => BLOCKED_MODEL_NOT_IN_ROSTER_CODE,
|
|
30
32
|
BRAIN_READ_ENV_NAMES: () => BRAIN_READ_ENV_NAMES,
|
|
31
33
|
BURST_SPAN_MS: () => BURST_SPAN_MS,
|
|
32
34
|
COACH_CFG: () => COACH_CFG,
|
|
@@ -168,6 +170,7 @@ __export(index_exports, {
|
|
|
168
170
|
resetTokenizer: () => resetTokenizer,
|
|
169
171
|
resolveConventionsForProfile: () => resolveConventionsForProfile,
|
|
170
172
|
resolveGoldenCaptureRate: () => resolveGoldenCaptureRate,
|
|
173
|
+
resolveModelAlias: () => resolveModelAlias,
|
|
171
174
|
resolvePricingAt: () => resolvePricingAt,
|
|
172
175
|
resolveProviderKey: () => resolveProviderKey,
|
|
173
176
|
rowToAdvisory: () => rowToAdvisory,
|
|
@@ -2024,6 +2027,9 @@ function _setProfileBrainHook(hook) {
|
|
|
2024
2027
|
function canonicalId(id) {
|
|
2025
2028
|
return brainHook.resolveAlias?.(id) ?? ALIASES[id] ?? id;
|
|
2026
2029
|
}
|
|
2030
|
+
function resolveModelAlias(id) {
|
|
2031
|
+
return canonicalId(id);
|
|
2032
|
+
}
|
|
2027
2033
|
var PROFILE_INDEX = new Map(
|
|
2028
2034
|
PROFILES_RAW.map((p) => [p.id, p])
|
|
2029
2035
|
);
|
|
@@ -2523,6 +2529,17 @@ function resolveFamilyEntry(family, ctx) {
|
|
|
2523
2529
|
return winner.id;
|
|
2524
2530
|
}
|
|
2525
2531
|
|
|
2532
|
+
// src/policy-match.ts
|
|
2533
|
+
function canonicalPolicySet(ids) {
|
|
2534
|
+
const set = /* @__PURE__ */ new Set();
|
|
2535
|
+
for (const id of ids ?? []) set.add(resolveModelAlias(id));
|
|
2536
|
+
return set;
|
|
2537
|
+
}
|
|
2538
|
+
function policySetHas(set, modelId) {
|
|
2539
|
+
if (set.size === 0) return false;
|
|
2540
|
+
return set.has(resolveModelAlias(modelId));
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2526
2543
|
// src/tokenizer.ts
|
|
2527
2544
|
var tokenizerImpl = defaultCharBasedCounter;
|
|
2528
2545
|
function defaultCharBasedCounter(text) {
|
|
@@ -2918,8 +2935,8 @@ function effectiveConventions(profile) {
|
|
|
2918
2935
|
function passScoreTargets(ir, opts) {
|
|
2919
2936
|
const constraints = ir.constraints ?? {};
|
|
2920
2937
|
const policy = opts.policy ?? {};
|
|
2921
|
-
const blockedSet =
|
|
2922
|
-
const preferredSet =
|
|
2938
|
+
const blockedSet = canonicalPolicySet(policy.blockedModels);
|
|
2939
|
+
const preferredSet = canonicalPolicySet(policy.preferredModels);
|
|
2923
2940
|
const scores = [];
|
|
2924
2941
|
const policyMutations = [];
|
|
2925
2942
|
const rawPromotion = opts.promotion;
|
|
@@ -2942,7 +2959,7 @@ function passScoreTargets(ir, opts) {
|
|
|
2942
2959
|
continue;
|
|
2943
2960
|
}
|
|
2944
2961
|
const reasons = [];
|
|
2945
|
-
if (blockedSet
|
|
2962
|
+
if (policySetHas(blockedSet, modelId)) {
|
|
2946
2963
|
reasons.push(`blocked_by_policy (consumer gated this model \u2014 see CompilePolicy.blockedModels)`);
|
|
2947
2964
|
}
|
|
2948
2965
|
if (opts.estimatedInputTokens > profile.maxContextTokens * 0.9) {
|
|
@@ -2972,7 +2989,7 @@ function passScoreTargets(ir, opts) {
|
|
|
2972
2989
|
const qualityScore = Math.max(0, baseQuality - qualityPenalty);
|
|
2973
2990
|
const callerOrderBoost = (modelIds.length - modelIds.indexOf(modelId)) * 0.1;
|
|
2974
2991
|
const costPenalty = estimatedCostUsd * 5;
|
|
2975
|
-
const preferredBoost = preferredSet
|
|
2992
|
+
const preferredBoost = policySetHas(preferredSet, modelId) ? 0.5 : 0;
|
|
2976
2993
|
let latencyPenalty = 0;
|
|
2977
2994
|
const maxLatencyMs = constraints.maxLatencyMs;
|
|
2978
2995
|
if (typeof maxLatencyMs === "number" && maxLatencyMs > 0) {
|
|
@@ -3029,7 +3046,7 @@ function passScoreTargets(ir, opts) {
|
|
|
3029
3046
|
description: `Model ${modelId} excluded \u2014 estimated cost $${estimatedCostUsd.toFixed(4)} exceeds policy ceiling $${policy.maxCostPerCallUsd.toFixed(4)}`
|
|
3030
3047
|
});
|
|
3031
3048
|
}
|
|
3032
|
-
if (preferredSet
|
|
3049
|
+
if (policySetHas(preferredSet, modelId) && reasons.length === 0) {
|
|
3033
3050
|
policyMutations.push({
|
|
3034
3051
|
id: `policy-preferred-${modelId}`,
|
|
3035
3052
|
source: "compile_policy",
|
|
@@ -4071,8 +4088,8 @@ function getDefaultFallbackChain(opts) {
|
|
|
4071
4088
|
chain = [...starter];
|
|
4072
4089
|
}
|
|
4073
4090
|
if (policy?.blockedModels && policy.blockedModels.length > 0) {
|
|
4074
|
-
const blocked =
|
|
4075
|
-
chain = chain.filter((id) => !blocked
|
|
4091
|
+
const blocked = canonicalPolicySet(policy.blockedModels);
|
|
4092
|
+
chain = chain.filter((id) => !policySetHas(blocked, id));
|
|
4076
4093
|
}
|
|
4077
4094
|
const seen = /* @__PURE__ */ new Set();
|
|
4078
4095
|
const deduped = [];
|
|
@@ -4175,8 +4192,8 @@ function getDefaultFallbackChainWithGrounding(opts) {
|
|
|
4175
4192
|
chain = [...starter];
|
|
4176
4193
|
}
|
|
4177
4194
|
if (policy?.blockedModels && policy.blockedModels.length > 0) {
|
|
4178
|
-
const blocked =
|
|
4179
|
-
chain = chain.filter((e) => !blocked
|
|
4195
|
+
const blocked = canonicalPolicySet(policy.blockedModels);
|
|
4196
|
+
chain = chain.filter((e) => !policySetHas(blocked, e.id));
|
|
4180
4197
|
}
|
|
4181
4198
|
const seen = /* @__PURE__ */ new Set();
|
|
4182
4199
|
const deduped = [];
|
|
@@ -5053,6 +5070,67 @@ function advisorRuleCrossFamilyFit(ctx) {
|
|
|
5053
5070
|
];
|
|
5054
5071
|
}
|
|
5055
5072
|
|
|
5073
|
+
// src/advisor-rules/blocked-model-drift.ts
|
|
5074
|
+
var BLOCKED_MODEL_NOT_IN_ROSTER_CODE = "blocked-model-not-in-roster";
|
|
5075
|
+
var BLOCKED_MODEL_FAMILY_SIBLING_SERVED_CODE = "blocked-model-family-sibling-served";
|
|
5076
|
+
var DOCS_URL = "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories";
|
|
5077
|
+
function familyOf2(modelId, profile) {
|
|
5078
|
+
return profile?.family ?? deriveFamilyFromModelId(modelId);
|
|
5079
|
+
}
|
|
5080
|
+
function isOnTheWayOut(status) {
|
|
5081
|
+
return status === "legacy" || status === "deprecated";
|
|
5082
|
+
}
|
|
5083
|
+
function advisorRuleBlockedModelDrift(ctx) {
|
|
5084
|
+
const blocked = ctx.policy?.blockedModels;
|
|
5085
|
+
if (!blocked || blocked.length === 0) return [];
|
|
5086
|
+
const resolve = ctx.resolveProfile ?? tryGetProfile;
|
|
5087
|
+
const out = [];
|
|
5088
|
+
const entries = [...new Set(blocked)].sort();
|
|
5089
|
+
const selectedProfile = resolve(ctx.selectedModelId);
|
|
5090
|
+
const selectedFamily = familyOf2(ctx.selectedModelId, selectedProfile);
|
|
5091
|
+
const orphans = entries.filter((e) => resolve(e) === void 0);
|
|
5092
|
+
if (orphans.length > 0) {
|
|
5093
|
+
const list = orphans.map((o) => `\`${o}\``).join(", ");
|
|
5094
|
+
const plural = orphans.length === 1 ? "entry" : "entries";
|
|
5095
|
+
const verb = orphans.length === 1 ? "matches" : "match";
|
|
5096
|
+
out.push({
|
|
5097
|
+
level: "warn",
|
|
5098
|
+
code: BLOCKED_MODEL_NOT_IN_ROSTER_CODE,
|
|
5099
|
+
message: `CompilePolicy.blockedModels ${plural} ${list} ${verb} no model in the current roster, so ${orphans.length === 1 ? "it is" : "they are"} inert \u2014 \`blockedModels\` is matched by exact model id, and nothing kgauto can select carries ${orphans.length === 1 ? "that id" : "those ids"}. The block will never fire.`,
|
|
5100
|
+
suggestion: `Check for a typo, or for an id that was retired from the roster since the block was written. This is how a block goes quiet without an error: tt-intel (2026-07-29) carried \`KGAUTO_BLOCKED_MODELS="claude-sonnet-4-6"\` across a roster retarget and the block stopped covering the traffic they believed it covered. Resolve the intended model id against the live roster \u2014 \`getRecommendedPrimary({ family, fallback })\` returns the id the family currently resolves to \u2014 and block that id, or drop the entry if it is no longer needed.`,
|
|
5101
|
+
docsUrl: DOCS_URL
|
|
5102
|
+
});
|
|
5103
|
+
}
|
|
5104
|
+
if (selectedFamily !== null) {
|
|
5105
|
+
const siblings = entries.filter((e) => {
|
|
5106
|
+
if (resolveModelAlias(e) === resolveModelAlias(ctx.selectedModelId)) return false;
|
|
5107
|
+
const p = resolve(e);
|
|
5108
|
+
if (familyOf2(e, p) !== selectedFamily) return false;
|
|
5109
|
+
if (p && selectedProfile && p.provider !== selectedProfile.provider) {
|
|
5110
|
+
return false;
|
|
5111
|
+
}
|
|
5112
|
+
return true;
|
|
5113
|
+
});
|
|
5114
|
+
if (siblings.length > 0) {
|
|
5115
|
+
const list = siblings.map((s) => `\`${s}\``).join(", ");
|
|
5116
|
+
const plural = siblings.length === 1 ? "" : "s";
|
|
5117
|
+
const retargetShaped = siblings.some((s) => {
|
|
5118
|
+
const p = resolve(s);
|
|
5119
|
+
return isOnTheWayOut(p?.status) && selectedProfile?.status === "current";
|
|
5120
|
+
});
|
|
5121
|
+
const retargetNote = retargetShaped ? ` The blocked id${plural} ${siblings.length === 1 ? "is" : "are"} legacy/deprecated while \`${ctx.selectedModelId}\` is current \u2014 that is the signature of a roster lifecycle move rather than a deliberate per-generation block, so this is more likely to be drift than intent.` : "";
|
|
5122
|
+
out.push({
|
|
5123
|
+
level: "warn",
|
|
5124
|
+
code: BLOCKED_MODEL_FAMILY_SIBLING_SERVED_CODE,
|
|
5125
|
+
message: `\`${ctx.selectedModelId}\` was selected for this call. It is in the same family (\`${selectedFamily}\`) as blocked entr${siblings.length === 1 ? "y" : "ies"} ${list}, but its exact id differs \u2014 and \`CompilePolicy.blockedModels\` matches by exact id, so the block does not cover it.${retargetNote}`,
|
|
5126
|
+
suggestion: `Two readings, and kgauto cannot tell them apart: (1) intentional \u2014 you meant to gate that specific id and \`${ctx.selectedModelId}\` is fine, in which case nothing needs doing and you can filter this code; (2) drift \u2014 you meant to gate the family, and a roster change moved traffic to a sibling your block never named. This happened to tt-intel: when the \`claude-sonnet\` family primary retargeted from \`claude-sonnet-4-6\` to \`claude-sonnet-5\`, their literal-id gate stopped matching the family's routed traffic (their fix was local family resolution). If you meant the family, add \`${ctx.selectedModelId}\` to \`blockedModels\` \u2014 kgauto deliberately does NOT widen exact-id blocks into family globs, because that would silently change what every existing block covers.`,
|
|
5127
|
+
docsUrl: DOCS_URL
|
|
5128
|
+
});
|
|
5129
|
+
}
|
|
5130
|
+
}
|
|
5131
|
+
return out;
|
|
5132
|
+
}
|
|
5133
|
+
|
|
5056
5134
|
// src/advisor.ts
|
|
5057
5135
|
var QUALITY_FLOOR_FOR_RECOMMENDATION = 6;
|
|
5058
5136
|
var TIER_DOWN_COST_RATIO = 0.5;
|
|
@@ -5071,6 +5149,12 @@ function runAdvisor(ir, result, profile, policy, phase2) {
|
|
|
5071
5149
|
out.push(...detectToolBloat(ir, result));
|
|
5072
5150
|
out.push(...detectHistoryUncached(ir, profile));
|
|
5073
5151
|
out.push(...detectSingleModelArray(ir, policy));
|
|
5152
|
+
out.push(
|
|
5153
|
+
...advisorRuleBlockedModelDrift({
|
|
5154
|
+
policy,
|
|
5155
|
+
selectedModelId: profile.id
|
|
5156
|
+
})
|
|
5157
|
+
);
|
|
5074
5158
|
if (policy?.posture !== "locked") {
|
|
5075
5159
|
out.push(...detectCostMismatchedArchetype(ir, profile, phase2));
|
|
5076
5160
|
out.push(...detectModelStaleEvidence(ir, profile));
|
|
@@ -5182,18 +5266,27 @@ function detectHistoryUncached(ir, profile) {
|
|
|
5182
5266
|
function detectSingleModelArray(ir, policy) {
|
|
5183
5267
|
if (ir.models.length !== 1) return [];
|
|
5184
5268
|
if (policy?.posture === "locked") return [];
|
|
5185
|
-
const
|
|
5269
|
+
const entry = ir.models[0];
|
|
5270
|
+
const only = typeof entry === "string" ? entry : `family:${entry.family}`;
|
|
5271
|
+
const blocked = canonicalPolicySet(policy?.blockedModels);
|
|
5272
|
+
let alternatives = [];
|
|
5273
|
+
try {
|
|
5274
|
+
alternatives = getDefaultFallbackChain({
|
|
5275
|
+
archetype: ir.intent.archetype,
|
|
5276
|
+
primary: only,
|
|
5277
|
+
posture: "preferred",
|
|
5278
|
+
policy
|
|
5279
|
+
}).filter((id) => resolveModelAlias(id) !== resolveModelAlias(only)).filter((id) => !policySetHas(blocked, id)).filter((id) => getModelCompatibility(id, { archetype: ir.intent.archetype }).status !== "reject");
|
|
5280
|
+
} catch {
|
|
5281
|
+
}
|
|
5282
|
+
const hasAlternative = alternatives.length > 0;
|
|
5283
|
+
const remedy = "Widen the chain AND pin your primary: `compile({ ...ir, models: getDefaultFallbackChain({ archetype: ir.intent.archetype, primary: '" + only + "', posture: 'preferred' }) }, { policy: { preferredModels: ['" + only + "'] } })`. The chain is a CANDIDATE SET \u2014 compile() scores it and does not honour its order, so without the `preferredModels` pin the extra entries can retarget your primary (and with it your cost profile). With the pin, `" + only + "` stays primary and the added entries serve only as the safety net. Note `posture` has no effect once `primary` is passed. If you gate models by spend, re-verify `policy.blockedModels` against the widened set before shipping. If single-model is intentional (compliance/brand promise), set `policy.posture = 'locked'` to silence this rule.";
|
|
5186
5284
|
return [
|
|
5187
5285
|
{
|
|
5188
|
-
level: "warn",
|
|
5286
|
+
level: hasAlternative ? "critical" : "warn",
|
|
5189
5287
|
code: "single-model-array",
|
|
5190
|
-
message: `\`ir.models\` has length 1 (only "${only}") and posture is not 'locked'. A single-model chain has no safety net \u2014 the first 429 / 5xx / cliff hits the user as a failure.
|
|
5191
|
-
|
|
5192
|
-
// position 0 and is therefore cost-neutral; `'open'` re-picks the
|
|
5193
|
-
// primary and is NOT. This rule is about reliability, not cost, so both
|
|
5194
|
-
// stay on offer — but the cost consequence of the second is now stated,
|
|
5195
|
-
// since a reliability fix should not silently become a repricing.
|
|
5196
|
-
suggestion: "Use `getDefaultFallbackChain({ archetype: ir.intent.archetype, primary: '" + only + "', posture: 'preferred' })` for a user-anchored chain \u2014 this keeps `" + only + "` as your primary and only adds fallbacks, so your cost profile is unchanged. `getDefaultFallbackChain({ archetype, posture: 'open' })` instead lets the library pick the PRIMARY, ordered by archetype performance rather than cost \u2014 check what it returns before adopting it. If single-model is intentional (compliance/brand promise), set `policy.posture = 'locked'` to silence this rule.",
|
|
5288
|
+
message: hasAlternative ? `\`ir.models\` has length 1 (only "${only}") for archetype "${ir.intent.archetype}" and posture is not 'locked'. A single-model chain has no safety net \u2014 the first 429 / 5xx / cliff hits the user as a failure \u2014 and a compatible, non-blocked alternative exists in the roster today (${alternatives[0]}), so this is critical: the missing safety net is adoptable now.` : `\`ir.models\` has length 1 (only "${only}") for archetype "${ir.intent.archetype}" and posture is not 'locked'. A single-model chain has no safety net \u2014 the first 429 / 5xx / cliff hits the user as a failure. No compatible non-blocked alternative is visible in the roster for this archetype, so this stays a warning.`,
|
|
5289
|
+
suggestion: remedy,
|
|
5197
5290
|
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#single-model-array"
|
|
5198
5291
|
}
|
|
5199
5292
|
];
|
|
@@ -5747,6 +5840,15 @@ function compile(ir, opts = {}) {
|
|
|
5747
5840
|
sectionRewritesApplied
|
|
5748
5841
|
}
|
|
5749
5842
|
);
|
|
5843
|
+
if (ir["policy"] !== void 0 && opts.policy === void 0) {
|
|
5844
|
+
rawAdvisories.push({
|
|
5845
|
+
level: "critical",
|
|
5846
|
+
code: "policy-in-ir-ignored",
|
|
5847
|
+
message: "The IR passed to compile() carries a `policy` field. `policy` belongs in the SECOND argument \u2014 `compile(ir, { policy })` \u2014 and inside the IR it is an unknown field that is completely ignored. If that policy names blockedModels, no block is being enforced on this call.",
|
|
5848
|
+
suggestion: "Move it: `compile(ir, { policy: { ... } })`. If you also configure policy correctly elsewhere on this path, remove the IR copy so the next reader is not misled.",
|
|
5849
|
+
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#public-api"
|
|
5850
|
+
});
|
|
5851
|
+
}
|
|
5750
5852
|
const advisories = rawAdvisories.map((a) => ({
|
|
5751
5853
|
...a,
|
|
5752
5854
|
kgautoRequestId: handle,
|
|
@@ -5865,7 +5967,7 @@ function validateFinalFit(ir, profile, tokens) {
|
|
|
5865
5967
|
}
|
|
5866
5968
|
|
|
5867
5969
|
// src/version.ts
|
|
5868
|
-
var LIBRARY_VERSION = "2.0.0-alpha.
|
|
5970
|
+
var LIBRARY_VERSION = "2.0.0-alpha.85";
|
|
5869
5971
|
|
|
5870
5972
|
// src/pricing-brain.ts
|
|
5871
5973
|
function isPricingRow(x) {
|
|
@@ -7820,11 +7922,11 @@ async function call(ir, opts = {}) {
|
|
|
7820
7922
|
}
|
|
7821
7923
|
let policyBlockedFiltered;
|
|
7822
7924
|
if (opts.policy?.blockedModels && opts.policy.blockedModels.length > 0) {
|
|
7823
|
-
const blocked =
|
|
7925
|
+
const blocked = canonicalPolicySet(opts.policy.blockedModels);
|
|
7824
7926
|
const filtered = [];
|
|
7825
7927
|
const dropped = [];
|
|
7826
7928
|
for (const t of targetsToTry) {
|
|
7827
|
-
if (blocked
|
|
7929
|
+
if (policySetHas(blocked, t)) {
|
|
7828
7930
|
dropped.push(t);
|
|
7829
7931
|
} else {
|
|
7830
7932
|
filtered.push(t);
|
|
@@ -7864,10 +7966,18 @@ async function call(ir, opts = {}) {
|
|
|
7864
7966
|
const failedProviders = /* @__PURE__ */ new Map();
|
|
7865
7967
|
const sameModelRetryEnabled = opts.sameModelRetry ?? isSameModelRetryEnabledFromEnv();
|
|
7866
7968
|
let retriedSameModel = false;
|
|
7969
|
+
const pushAttempt = (attempt) => {
|
|
7970
|
+
attempts.push(attempt);
|
|
7971
|
+
if (attempt.status === "success") return;
|
|
7972
|
+
try {
|
|
7973
|
+
opts.onFailedAttempt?.(attempt);
|
|
7974
|
+
} catch {
|
|
7975
|
+
}
|
|
7976
|
+
};
|
|
7867
7977
|
for (let i = 0; i < targetsToTry.length; i++) {
|
|
7868
7978
|
const targetModel = targetsToTry[i];
|
|
7869
7979
|
if (opts.abortSignal?.aborted) {
|
|
7870
|
-
|
|
7980
|
+
pushAttempt({
|
|
7871
7981
|
model: targetModel,
|
|
7872
7982
|
status: "terminal",
|
|
7873
7983
|
errorCode: "aborted",
|
|
@@ -7878,7 +7988,7 @@ async function call(ir, opts = {}) {
|
|
|
7878
7988
|
const targetProfile = tryGetProfile(targetModel);
|
|
7879
7989
|
const providerFailReason = targetProfile ? failedProviders.get(targetProfile.provider) : void 0;
|
|
7880
7990
|
if (targetProfile && providerFailReason && !opts.noFallback) {
|
|
7881
|
-
|
|
7991
|
+
pushAttempt({
|
|
7882
7992
|
model: targetModel,
|
|
7883
7993
|
status: "terminal",
|
|
7884
7994
|
errorCode: `${providerFailReason}_inferred`,
|
|
@@ -7897,7 +8007,7 @@ async function call(ir, opts = {}) {
|
|
|
7897
8007
|
opts
|
|
7898
8008
|
);
|
|
7899
8009
|
} catch (err) {
|
|
7900
|
-
|
|
8010
|
+
pushAttempt({
|
|
7901
8011
|
model: targetModel,
|
|
7902
8012
|
status: "terminal",
|
|
7903
8013
|
errorCode: "compile_error",
|
|
@@ -7935,7 +8045,7 @@ async function call(ir, opts = {}) {
|
|
|
7935
8045
|
}
|
|
7936
8046
|
if (!validated.ok && isStructuredContractViolation(validated.errorCode) && sameModelRetryEnabled && !retriedSameModel && !retrySuppressionNote) {
|
|
7937
8047
|
retriedSameModel = true;
|
|
7938
|
-
|
|
8048
|
+
pushAttempt({
|
|
7939
8049
|
model: targetModel,
|
|
7940
8050
|
status: validated.errorType,
|
|
7941
8051
|
errorCode: validated.errorCode,
|
|
@@ -7950,7 +8060,7 @@ async function call(ir, opts = {}) {
|
|
|
7950
8060
|
servedByRetry = true;
|
|
7951
8061
|
}
|
|
7952
8062
|
if (validated.ok) {
|
|
7953
|
-
|
|
8063
|
+
pushAttempt({
|
|
7954
8064
|
model: targetModel,
|
|
7955
8065
|
status: "success",
|
|
7956
8066
|
...servedByRetry ? { sameModelRetry: true } : {}
|
|
@@ -8068,7 +8178,7 @@ async function call(ir, opts = {}) {
|
|
|
8068
8178
|
advisories: activeCompile.advisories
|
|
8069
8179
|
};
|
|
8070
8180
|
}
|
|
8071
|
-
|
|
8181
|
+
pushAttempt({
|
|
8072
8182
|
model: targetModel,
|
|
8073
8183
|
status: validated.errorType,
|
|
8074
8184
|
errorCode: validated.errorCode,
|
|
@@ -10588,6 +10698,8 @@ function compile2(ir, opts) {
|
|
|
10588
10698
|
ALT_STRATEGY_IDS,
|
|
10589
10699
|
ARCHETYPE_FAMILY_FITS,
|
|
10590
10700
|
ARCHETYPE_FLOOR_DEFAULT,
|
|
10701
|
+
BLOCKED_MODEL_FAMILY_SIBLING_SERVED_CODE,
|
|
10702
|
+
BLOCKED_MODEL_NOT_IN_ROSTER_CODE,
|
|
10591
10703
|
BRAIN_READ_ENV_NAMES,
|
|
10592
10704
|
BURST_SPAN_MS,
|
|
10593
10705
|
COACH_CFG,
|
|
@@ -10729,6 +10841,7 @@ function compile2(ir, opts) {
|
|
|
10729
10841
|
resetTokenizer,
|
|
10730
10842
|
resolveConventionsForProfile,
|
|
10731
10843
|
resolveGoldenCaptureRate,
|
|
10844
|
+
resolveModelAlias,
|
|
10732
10845
|
resolvePricingAt,
|
|
10733
10846
|
resolveProviderKey,
|
|
10734
10847
|
rowToAdvisory,
|
package/dist/index.mjs
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
LIBRARY_VERSION,
|
|
20
20
|
createKeyHealthRoute,
|
|
21
21
|
keyFingerprint
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-WXN7FNXP.mjs";
|
|
23
23
|
import {
|
|
24
24
|
ABSOLUTE_FLOOR,
|
|
25
25
|
ARCHETYPE_FLOOR_DEFAULT,
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
COST_RANKING_REFERENCE_SHAPE,
|
|
28
28
|
MEASURED_GROUNDING_MIN_N,
|
|
29
29
|
PROVIDER_ENV_KEYS,
|
|
30
|
+
canonicalPolicySet,
|
|
30
31
|
chainProviderSpread,
|
|
31
32
|
configureBrainQuery,
|
|
32
33
|
createBrainQueryCache,
|
|
@@ -52,9 +53,10 @@ import {
|
|
|
52
53
|
loadArchetypePerfFromBrain,
|
|
53
54
|
loadArchetypePerfNFromBrain,
|
|
54
55
|
loadChainsFromBrain,
|
|
56
|
+
policySetHas,
|
|
55
57
|
readBrainReadEnv,
|
|
56
58
|
resolveProviderKey
|
|
57
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-LO2JXTGG.mjs";
|
|
58
60
|
import {
|
|
59
61
|
ALIASES,
|
|
60
62
|
LATENCY_TIER_MS,
|
|
@@ -64,8 +66,9 @@ import {
|
|
|
64
66
|
getProfile,
|
|
65
67
|
latencyTierOf,
|
|
66
68
|
profilesByProvider,
|
|
69
|
+
resolveModelAlias,
|
|
67
70
|
tryGetProfile
|
|
68
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-FD3NFXDC.mjs";
|
|
69
72
|
import {
|
|
70
73
|
emitAdvisoryFired,
|
|
71
74
|
emitCompileDone,
|
|
@@ -767,8 +770,8 @@ function effectiveConventions(profile) {
|
|
|
767
770
|
function passScoreTargets(ir, opts) {
|
|
768
771
|
const constraints = ir.constraints ?? {};
|
|
769
772
|
const policy = opts.policy ?? {};
|
|
770
|
-
const blockedSet =
|
|
771
|
-
const preferredSet =
|
|
773
|
+
const blockedSet = canonicalPolicySet(policy.blockedModels);
|
|
774
|
+
const preferredSet = canonicalPolicySet(policy.preferredModels);
|
|
772
775
|
const scores = [];
|
|
773
776
|
const policyMutations = [];
|
|
774
777
|
const rawPromotion = opts.promotion;
|
|
@@ -791,7 +794,7 @@ function passScoreTargets(ir, opts) {
|
|
|
791
794
|
continue;
|
|
792
795
|
}
|
|
793
796
|
const reasons = [];
|
|
794
|
-
if (blockedSet
|
|
797
|
+
if (policySetHas(blockedSet, modelId)) {
|
|
795
798
|
reasons.push(`blocked_by_policy (consumer gated this model \u2014 see CompilePolicy.blockedModels)`);
|
|
796
799
|
}
|
|
797
800
|
if (opts.estimatedInputTokens > profile.maxContextTokens * 0.9) {
|
|
@@ -821,7 +824,7 @@ function passScoreTargets(ir, opts) {
|
|
|
821
824
|
const qualityScore = Math.max(0, baseQuality - qualityPenalty);
|
|
822
825
|
const callerOrderBoost = (modelIds.length - modelIds.indexOf(modelId)) * 0.1;
|
|
823
826
|
const costPenalty = estimatedCostUsd * 5;
|
|
824
|
-
const preferredBoost = preferredSet
|
|
827
|
+
const preferredBoost = policySetHas(preferredSet, modelId) ? 0.5 : 0;
|
|
825
828
|
let latencyPenalty = 0;
|
|
826
829
|
const maxLatencyMs = constraints.maxLatencyMs;
|
|
827
830
|
if (typeof maxLatencyMs === "number" && maxLatencyMs > 0) {
|
|
@@ -878,7 +881,7 @@ function passScoreTargets(ir, opts) {
|
|
|
878
881
|
description: `Model ${modelId} excluded \u2014 estimated cost $${estimatedCostUsd.toFixed(4)} exceeds policy ceiling $${policy.maxCostPerCallUsd.toFixed(4)}`
|
|
879
882
|
});
|
|
880
883
|
}
|
|
881
|
-
if (preferredSet
|
|
884
|
+
if (policySetHas(preferredSet, modelId) && reasons.length === 0) {
|
|
882
885
|
policyMutations.push({
|
|
883
886
|
id: `policy-preferred-${modelId}`,
|
|
884
887
|
source: "compile_policy",
|
|
@@ -2361,6 +2364,67 @@ function advisorRuleCrossFamilyFit(ctx) {
|
|
|
2361
2364
|
];
|
|
2362
2365
|
}
|
|
2363
2366
|
|
|
2367
|
+
// src/advisor-rules/blocked-model-drift.ts
|
|
2368
|
+
var BLOCKED_MODEL_NOT_IN_ROSTER_CODE = "blocked-model-not-in-roster";
|
|
2369
|
+
var BLOCKED_MODEL_FAMILY_SIBLING_SERVED_CODE = "blocked-model-family-sibling-served";
|
|
2370
|
+
var DOCS_URL = "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories";
|
|
2371
|
+
function familyOf2(modelId, profile) {
|
|
2372
|
+
return profile?.family ?? deriveFamilyFromModelId(modelId);
|
|
2373
|
+
}
|
|
2374
|
+
function isOnTheWayOut(status) {
|
|
2375
|
+
return status === "legacy" || status === "deprecated";
|
|
2376
|
+
}
|
|
2377
|
+
function advisorRuleBlockedModelDrift(ctx) {
|
|
2378
|
+
const blocked = ctx.policy?.blockedModels;
|
|
2379
|
+
if (!blocked || blocked.length === 0) return [];
|
|
2380
|
+
const resolve = ctx.resolveProfile ?? tryGetProfile;
|
|
2381
|
+
const out = [];
|
|
2382
|
+
const entries = [...new Set(blocked)].sort();
|
|
2383
|
+
const selectedProfile = resolve(ctx.selectedModelId);
|
|
2384
|
+
const selectedFamily = familyOf2(ctx.selectedModelId, selectedProfile);
|
|
2385
|
+
const orphans = entries.filter((e) => resolve(e) === void 0);
|
|
2386
|
+
if (orphans.length > 0) {
|
|
2387
|
+
const list = orphans.map((o) => `\`${o}\``).join(", ");
|
|
2388
|
+
const plural = orphans.length === 1 ? "entry" : "entries";
|
|
2389
|
+
const verb = orphans.length === 1 ? "matches" : "match";
|
|
2390
|
+
out.push({
|
|
2391
|
+
level: "warn",
|
|
2392
|
+
code: BLOCKED_MODEL_NOT_IN_ROSTER_CODE,
|
|
2393
|
+
message: `CompilePolicy.blockedModels ${plural} ${list} ${verb} no model in the current roster, so ${orphans.length === 1 ? "it is" : "they are"} inert \u2014 \`blockedModels\` is matched by exact model id, and nothing kgauto can select carries ${orphans.length === 1 ? "that id" : "those ids"}. The block will never fire.`,
|
|
2394
|
+
suggestion: `Check for a typo, or for an id that was retired from the roster since the block was written. This is how a block goes quiet without an error: tt-intel (2026-07-29) carried \`KGAUTO_BLOCKED_MODELS="claude-sonnet-4-6"\` across a roster retarget and the block stopped covering the traffic they believed it covered. Resolve the intended model id against the live roster \u2014 \`getRecommendedPrimary({ family, fallback })\` returns the id the family currently resolves to \u2014 and block that id, or drop the entry if it is no longer needed.`,
|
|
2395
|
+
docsUrl: DOCS_URL
|
|
2396
|
+
});
|
|
2397
|
+
}
|
|
2398
|
+
if (selectedFamily !== null) {
|
|
2399
|
+
const siblings = entries.filter((e) => {
|
|
2400
|
+
if (resolveModelAlias(e) === resolveModelAlias(ctx.selectedModelId)) return false;
|
|
2401
|
+
const p = resolve(e);
|
|
2402
|
+
if (familyOf2(e, p) !== selectedFamily) return false;
|
|
2403
|
+
if (p && selectedProfile && p.provider !== selectedProfile.provider) {
|
|
2404
|
+
return false;
|
|
2405
|
+
}
|
|
2406
|
+
return true;
|
|
2407
|
+
});
|
|
2408
|
+
if (siblings.length > 0) {
|
|
2409
|
+
const list = siblings.map((s) => `\`${s}\``).join(", ");
|
|
2410
|
+
const plural = siblings.length === 1 ? "" : "s";
|
|
2411
|
+
const retargetShaped = siblings.some((s) => {
|
|
2412
|
+
const p = resolve(s);
|
|
2413
|
+
return isOnTheWayOut(p?.status) && selectedProfile?.status === "current";
|
|
2414
|
+
});
|
|
2415
|
+
const retargetNote = retargetShaped ? ` The blocked id${plural} ${siblings.length === 1 ? "is" : "are"} legacy/deprecated while \`${ctx.selectedModelId}\` is current \u2014 that is the signature of a roster lifecycle move rather than a deliberate per-generation block, so this is more likely to be drift than intent.` : "";
|
|
2416
|
+
out.push({
|
|
2417
|
+
level: "warn",
|
|
2418
|
+
code: BLOCKED_MODEL_FAMILY_SIBLING_SERVED_CODE,
|
|
2419
|
+
message: `\`${ctx.selectedModelId}\` was selected for this call. It is in the same family (\`${selectedFamily}\`) as blocked entr${siblings.length === 1 ? "y" : "ies"} ${list}, but its exact id differs \u2014 and \`CompilePolicy.blockedModels\` matches by exact id, so the block does not cover it.${retargetNote}`,
|
|
2420
|
+
suggestion: `Two readings, and kgauto cannot tell them apart: (1) intentional \u2014 you meant to gate that specific id and \`${ctx.selectedModelId}\` is fine, in which case nothing needs doing and you can filter this code; (2) drift \u2014 you meant to gate the family, and a roster change moved traffic to a sibling your block never named. This happened to tt-intel: when the \`claude-sonnet\` family primary retargeted from \`claude-sonnet-4-6\` to \`claude-sonnet-5\`, their literal-id gate stopped matching the family's routed traffic (their fix was local family resolution). If you meant the family, add \`${ctx.selectedModelId}\` to \`blockedModels\` \u2014 kgauto deliberately does NOT widen exact-id blocks into family globs, because that would silently change what every existing block covers.`,
|
|
2421
|
+
docsUrl: DOCS_URL
|
|
2422
|
+
});
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
return out;
|
|
2426
|
+
}
|
|
2427
|
+
|
|
2364
2428
|
// src/advisor.ts
|
|
2365
2429
|
var QUALITY_FLOOR_FOR_RECOMMENDATION = 6;
|
|
2366
2430
|
var TIER_DOWN_COST_RATIO = 0.5;
|
|
@@ -2379,6 +2443,12 @@ function runAdvisor(ir, result, profile, policy, phase2) {
|
|
|
2379
2443
|
out.push(...detectToolBloat(ir, result));
|
|
2380
2444
|
out.push(...detectHistoryUncached(ir, profile));
|
|
2381
2445
|
out.push(...detectSingleModelArray(ir, policy));
|
|
2446
|
+
out.push(
|
|
2447
|
+
...advisorRuleBlockedModelDrift({
|
|
2448
|
+
policy,
|
|
2449
|
+
selectedModelId: profile.id
|
|
2450
|
+
})
|
|
2451
|
+
);
|
|
2382
2452
|
if (policy?.posture !== "locked") {
|
|
2383
2453
|
out.push(...detectCostMismatchedArchetype(ir, profile, phase2));
|
|
2384
2454
|
out.push(...detectModelStaleEvidence(ir, profile));
|
|
@@ -2490,18 +2560,27 @@ function detectHistoryUncached(ir, profile) {
|
|
|
2490
2560
|
function detectSingleModelArray(ir, policy) {
|
|
2491
2561
|
if (ir.models.length !== 1) return [];
|
|
2492
2562
|
if (policy?.posture === "locked") return [];
|
|
2493
|
-
const
|
|
2563
|
+
const entry = ir.models[0];
|
|
2564
|
+
const only = typeof entry === "string" ? entry : `family:${entry.family}`;
|
|
2565
|
+
const blocked = canonicalPolicySet(policy?.blockedModels);
|
|
2566
|
+
let alternatives = [];
|
|
2567
|
+
try {
|
|
2568
|
+
alternatives = getDefaultFallbackChain({
|
|
2569
|
+
archetype: ir.intent.archetype,
|
|
2570
|
+
primary: only,
|
|
2571
|
+
posture: "preferred",
|
|
2572
|
+
policy
|
|
2573
|
+
}).filter((id) => resolveModelAlias(id) !== resolveModelAlias(only)).filter((id) => !policySetHas(blocked, id)).filter((id) => getModelCompatibility(id, { archetype: ir.intent.archetype }).status !== "reject");
|
|
2574
|
+
} catch {
|
|
2575
|
+
}
|
|
2576
|
+
const hasAlternative = alternatives.length > 0;
|
|
2577
|
+
const remedy = "Widen the chain AND pin your primary: `compile({ ...ir, models: getDefaultFallbackChain({ archetype: ir.intent.archetype, primary: '" + only + "', posture: 'preferred' }) }, { policy: { preferredModels: ['" + only + "'] } })`. The chain is a CANDIDATE SET \u2014 compile() scores it and does not honour its order, so without the `preferredModels` pin the extra entries can retarget your primary (and with it your cost profile). With the pin, `" + only + "` stays primary and the added entries serve only as the safety net. Note `posture` has no effect once `primary` is passed. If you gate models by spend, re-verify `policy.blockedModels` against the widened set before shipping. If single-model is intentional (compliance/brand promise), set `policy.posture = 'locked'` to silence this rule.";
|
|
2494
2578
|
return [
|
|
2495
2579
|
{
|
|
2496
|
-
level: "warn",
|
|
2580
|
+
level: hasAlternative ? "critical" : "warn",
|
|
2497
2581
|
code: "single-model-array",
|
|
2498
|
-
message: `\`ir.models\` has length 1 (only "${only}") and posture is not 'locked'. A single-model chain has no safety net \u2014 the first 429 / 5xx / cliff hits the user as a failure.
|
|
2499
|
-
|
|
2500
|
-
// position 0 and is therefore cost-neutral; `'open'` re-picks the
|
|
2501
|
-
// primary and is NOT. This rule is about reliability, not cost, so both
|
|
2502
|
-
// stay on offer — but the cost consequence of the second is now stated,
|
|
2503
|
-
// since a reliability fix should not silently become a repricing.
|
|
2504
|
-
suggestion: "Use `getDefaultFallbackChain({ archetype: ir.intent.archetype, primary: '" + only + "', posture: 'preferred' })` for a user-anchored chain \u2014 this keeps `" + only + "` as your primary and only adds fallbacks, so your cost profile is unchanged. `getDefaultFallbackChain({ archetype, posture: 'open' })` instead lets the library pick the PRIMARY, ordered by archetype performance rather than cost \u2014 check what it returns before adopting it. If single-model is intentional (compliance/brand promise), set `policy.posture = 'locked'` to silence this rule.",
|
|
2582
|
+
message: hasAlternative ? `\`ir.models\` has length 1 (only "${only}") for archetype "${ir.intent.archetype}" and posture is not 'locked'. A single-model chain has no safety net \u2014 the first 429 / 5xx / cliff hits the user as a failure \u2014 and a compatible, non-blocked alternative exists in the roster today (${alternatives[0]}), so this is critical: the missing safety net is adoptable now.` : `\`ir.models\` has length 1 (only "${only}") for archetype "${ir.intent.archetype}" and posture is not 'locked'. A single-model chain has no safety net \u2014 the first 429 / 5xx / cliff hits the user as a failure. No compatible non-blocked alternative is visible in the roster for this archetype, so this stays a warning.`,
|
|
2583
|
+
suggestion: remedy,
|
|
2505
2584
|
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#single-model-array"
|
|
2506
2585
|
}
|
|
2507
2586
|
];
|
|
@@ -3055,6 +3134,15 @@ function compile(ir, opts = {}) {
|
|
|
3055
3134
|
sectionRewritesApplied
|
|
3056
3135
|
}
|
|
3057
3136
|
);
|
|
3137
|
+
if (ir["policy"] !== void 0 && opts.policy === void 0) {
|
|
3138
|
+
rawAdvisories.push({
|
|
3139
|
+
level: "critical",
|
|
3140
|
+
code: "policy-in-ir-ignored",
|
|
3141
|
+
message: "The IR passed to compile() carries a `policy` field. `policy` belongs in the SECOND argument \u2014 `compile(ir, { policy })` \u2014 and inside the IR it is an unknown field that is completely ignored. If that policy names blockedModels, no block is being enforced on this call.",
|
|
3142
|
+
suggestion: "Move it: `compile(ir, { policy: { ... } })`. If you also configure policy correctly elsewhere on this path, remove the IR copy so the next reader is not misled.",
|
|
3143
|
+
docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#public-api"
|
|
3144
|
+
});
|
|
3145
|
+
}
|
|
3058
3146
|
const advisories = rawAdvisories.map((a) => ({
|
|
3059
3147
|
...a,
|
|
3060
3148
|
kgautoRequestId: handle,
|
|
@@ -4824,11 +4912,11 @@ async function call(ir, opts = {}) {
|
|
|
4824
4912
|
}
|
|
4825
4913
|
let policyBlockedFiltered;
|
|
4826
4914
|
if (opts.policy?.blockedModels && opts.policy.blockedModels.length > 0) {
|
|
4827
|
-
const blocked =
|
|
4915
|
+
const blocked = canonicalPolicySet(opts.policy.blockedModels);
|
|
4828
4916
|
const filtered = [];
|
|
4829
4917
|
const dropped = [];
|
|
4830
4918
|
for (const t of targetsToTry) {
|
|
4831
|
-
if (blocked
|
|
4919
|
+
if (policySetHas(blocked, t)) {
|
|
4832
4920
|
dropped.push(t);
|
|
4833
4921
|
} else {
|
|
4834
4922
|
filtered.push(t);
|
|
@@ -4868,10 +4956,18 @@ async function call(ir, opts = {}) {
|
|
|
4868
4956
|
const failedProviders = /* @__PURE__ */ new Map();
|
|
4869
4957
|
const sameModelRetryEnabled = opts.sameModelRetry ?? isSameModelRetryEnabledFromEnv();
|
|
4870
4958
|
let retriedSameModel = false;
|
|
4959
|
+
const pushAttempt = (attempt) => {
|
|
4960
|
+
attempts.push(attempt);
|
|
4961
|
+
if (attempt.status === "success") return;
|
|
4962
|
+
try {
|
|
4963
|
+
opts.onFailedAttempt?.(attempt);
|
|
4964
|
+
} catch {
|
|
4965
|
+
}
|
|
4966
|
+
};
|
|
4871
4967
|
for (let i = 0; i < targetsToTry.length; i++) {
|
|
4872
4968
|
const targetModel = targetsToTry[i];
|
|
4873
4969
|
if (opts.abortSignal?.aborted) {
|
|
4874
|
-
|
|
4970
|
+
pushAttempt({
|
|
4875
4971
|
model: targetModel,
|
|
4876
4972
|
status: "terminal",
|
|
4877
4973
|
errorCode: "aborted",
|
|
@@ -4882,7 +4978,7 @@ async function call(ir, opts = {}) {
|
|
|
4882
4978
|
const targetProfile = tryGetProfile(targetModel);
|
|
4883
4979
|
const providerFailReason = targetProfile ? failedProviders.get(targetProfile.provider) : void 0;
|
|
4884
4980
|
if (targetProfile && providerFailReason && !opts.noFallback) {
|
|
4885
|
-
|
|
4981
|
+
pushAttempt({
|
|
4886
4982
|
model: targetModel,
|
|
4887
4983
|
status: "terminal",
|
|
4888
4984
|
errorCode: `${providerFailReason}_inferred`,
|
|
@@ -4901,7 +4997,7 @@ async function call(ir, opts = {}) {
|
|
|
4901
4997
|
opts
|
|
4902
4998
|
);
|
|
4903
4999
|
} catch (err) {
|
|
4904
|
-
|
|
5000
|
+
pushAttempt({
|
|
4905
5001
|
model: targetModel,
|
|
4906
5002
|
status: "terminal",
|
|
4907
5003
|
errorCode: "compile_error",
|
|
@@ -4939,7 +5035,7 @@ async function call(ir, opts = {}) {
|
|
|
4939
5035
|
}
|
|
4940
5036
|
if (!validated.ok && isStructuredContractViolation(validated.errorCode) && sameModelRetryEnabled && !retriedSameModel && !retrySuppressionNote) {
|
|
4941
5037
|
retriedSameModel = true;
|
|
4942
|
-
|
|
5038
|
+
pushAttempt({
|
|
4943
5039
|
model: targetModel,
|
|
4944
5040
|
status: validated.errorType,
|
|
4945
5041
|
errorCode: validated.errorCode,
|
|
@@ -4954,7 +5050,7 @@ async function call(ir, opts = {}) {
|
|
|
4954
5050
|
servedByRetry = true;
|
|
4955
5051
|
}
|
|
4956
5052
|
if (validated.ok) {
|
|
4957
|
-
|
|
5053
|
+
pushAttempt({
|
|
4958
5054
|
model: targetModel,
|
|
4959
5055
|
status: "success",
|
|
4960
5056
|
...servedByRetry ? { sameModelRetry: true } : {}
|
|
@@ -5072,7 +5168,7 @@ async function call(ir, opts = {}) {
|
|
|
5072
5168
|
advisories: activeCompile.advisories
|
|
5073
5169
|
};
|
|
5074
5170
|
}
|
|
5075
|
-
|
|
5171
|
+
pushAttempt({
|
|
5076
5172
|
model: targetModel,
|
|
5077
5173
|
status: validated.errorType,
|
|
5078
5174
|
errorCode: validated.errorCode,
|
|
@@ -7216,6 +7312,8 @@ export {
|
|
|
7216
7312
|
ALT_STRATEGY_IDS,
|
|
7217
7313
|
ARCHETYPE_FAMILY_FITS,
|
|
7218
7314
|
ARCHETYPE_FLOOR_DEFAULT,
|
|
7315
|
+
BLOCKED_MODEL_FAMILY_SIBLING_SERVED_CODE,
|
|
7316
|
+
BLOCKED_MODEL_NOT_IN_ROSTER_CODE,
|
|
7219
7317
|
BRAIN_READ_ENV_NAMES,
|
|
7220
7318
|
BURST_SPAN_MS,
|
|
7221
7319
|
COACH_CFG,
|
|
@@ -7357,6 +7455,7 @@ export {
|
|
|
7357
7455
|
resetTokenizer,
|
|
7358
7456
|
resolveConventionsForProfile,
|
|
7359
7457
|
resolveGoldenCaptureRate,
|
|
7458
|
+
resolveModelAlias,
|
|
7360
7459
|
resolvePricingAt,
|
|
7361
7460
|
resolveProviderKey,
|
|
7362
7461
|
rowToAdvisory,
|