@warmdrift/kgauto-compiler 2.0.0-alpha.63 → 2.0.0-alpha.65

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/index.js CHANGED
@@ -27,6 +27,7 @@ __export(index_exports, {
27
27
  ARCHETYPE_FLOOR_DEFAULT: () => ARCHETYPE_FLOOR_DEFAULT,
28
28
  CallError: () => CallError,
29
29
  DEFAULT_FINDINGS_ENDPOINT: () => DEFAULT_FINDINGS_ENDPOINT,
30
+ DEFAULT_PROMOTIONS_ENDPOINT: () => DEFAULT_PROMOTIONS_ENDPOINT,
30
31
  DIALECT_VERSION: () => DIALECT_VERSION,
31
32
  FamilyResolutionError: () => FamilyResolutionError,
32
33
  INTENT_ARCHETYPES: () => INTENT_ARCHETYPES,
@@ -38,6 +39,8 @@ __export(index_exports, {
38
39
  PROVIDER_ENV_KEYS: () => PROVIDER_ENV_KEYS,
39
40
  RULE_SEQUENTIAL_TOOL_CLIFF: () => RULE_SEQUENTIAL_TOOL_CLIFF,
40
41
  TRANSLATOR_FLOOR: () => TRANSLATOR_FLOOR,
42
+ _testResetPromotions: () => _testResetPromotions,
43
+ _testWaitForPromotionsRefresh: () => _testWaitForPromotionsRefresh,
41
44
  allProfiles: () => allProfiles,
42
45
  applyArchetypeConvention: () => applyArchetypeConvention,
43
46
  applySectionRewrites: () => applySectionRewrites,
@@ -57,6 +60,7 @@ __export(index_exports, {
57
60
  compile: () => compile2,
58
61
  compileForAISDKv6: () => compileForAISDKv6,
59
62
  configureBrain: () => configureBrain,
63
+ configurePromotionsBrain: () => configurePromotionsBrain,
60
64
  countTokens: () => countTokens,
61
65
  createBrainForwardRoutes: () => createBrainForwardRoutes,
62
66
  createKeyHealthRoute: () => createKeyHealthRoute,
@@ -68,6 +72,7 @@ __export(index_exports, {
68
72
  getActionableAdvisories: () => getActionableAdvisories,
69
73
  getAllStarterChains: () => getAllStarterChains,
70
74
  getAllStarterChainsWithGrounding: () => getAllStarterChainsWithGrounding,
75
+ getApplicablePromotion: () => getApplicablePromotion,
71
76
  getArchetypePerfScore: () => getArchetypePerfScore,
72
77
  getDefaultFallbackChain: () => getDefaultFallbackChain,
73
78
  getDefaultFallbackChainWithGrounding: () => getDefaultFallbackChainWithGrounding,
@@ -83,10 +88,12 @@ __export(index_exports, {
83
88
  getStarterChainWithGrounding: () => getStarterChainWithGrounding,
84
89
  hashShape: () => hashShape,
85
90
  isArchetype: () => isArchetype,
91
+ isAutoPromoteEnabledFromEnv: () => isAutoPromoteEnabledFromEnv,
86
92
  isBrainQueryActiveFor: () => isBrainQueryActiveFor,
87
93
  isBrainSync: () => isBrainSync,
88
94
  isExclusionFindingsBrainActive: () => isExclusionFindingsBrainActive,
89
95
  isModelReachable: () => isModelReachable,
96
+ isPromotionsBrainActive: () => isPromotionsBrainActive,
90
97
  isProviderReachable: () => isProviderReachable,
91
98
  latencyTierOf: () => latencyTierOf,
92
99
  learningKey: () => learningKey,
@@ -1711,6 +1718,156 @@ var PROFILES_RAW = [
1711
1718
  classify: 8
1712
1719
  // overkill
1713
1720
  }
1721
+ },
1722
+ // ── Z.ai (GLM) ──
1723
+ // alpha.65 (2026-07-18): first Z.ai profile, provider `zai` added same
1724
+ // release. Step-zero sources (L-049/L-081, all fetched 2026-07-18):
1725
+ // docs.z.ai/guides/llm/glm-5.2 (capabilities), docs.z.ai api-reference
1726
+ // chat-completion (wire params: thinking.type enabled|disabled default
1727
+ // enabled, reasoning_effort max..none, tool_stream, max output 131072),
1728
+ // docs.z.ai/guides/overview/pricing ($1.4 in / $4.4 out, cached input
1729
+ // $0.26, cache storage limited-time free), vLLM recipe (native ctx
1730
+ // 1,048,576). NO AI-trained numbers.
1731
+ {
1732
+ id: "glm-5.2",
1733
+ verifiedAgainstDocs: "2026-07-18",
1734
+ provider: "zai",
1735
+ status: "preview",
1736
+ maxContextTokens: 1048576,
1737
+ maxOutputTokens: 131072,
1738
+ // No documented tool-count cap — conservative default pending measured
1739
+ // evidence; matches the deepseek posture, not a doc number.
1740
+ maxTools: 16,
1741
+ // Hosted-API docs document tools + tool_choice + tool_stream but say
1742
+ // NOTHING about multiple tool_calls per response. Conservative false so
1743
+ // hunt-shaped ranking doesn't over-promise; flip on doc or probe
1744
+ // evidence (L-081: undocumented ≠ true).
1745
+ parallelToolCalls: false,
1746
+ structuredOutput: "native",
1747
+ systemPromptMode: "inline",
1748
+ streaming: true,
1749
+ cliffs: [],
1750
+ costInputPer1m: 1.4,
1751
+ costOutputPer1m: 4.4,
1752
+ lowering: {
1753
+ system: { mode: "inline" },
1754
+ // Automatic prefix caching ("intelligent caching mechanism") — no wire
1755
+ // marker to emit, DeepSeek-style. Cache-hit input $0.26/M (~0.19× of
1756
+ // miss) tracked in notes; storage limited-time free as of 2026-07-18.
1757
+ cache: { strategy: "unsupported" },
1758
+ tools: { format: "openai" },
1759
+ // thinking.type: 'enabled' (server default) | 'disabled'. lowerZai
1760
+ // emits an explicit disable only on forceThinkingZero cliffs.
1761
+ thinking: { field: "thinking.type", default: "auto" }
1762
+ },
1763
+ recovery: [
1764
+ { signal: "rate_limit", action: "escalate", reason: "429 \u2014 escalate" },
1765
+ { signal: "model_not_found", action: "escalate", reason: "Deprecated \u2014 escalate (L-061)" }
1766
+ ],
1767
+ strengths: ["cost", "1m_context", "code", "tool_use", "json_output", "reasoning"],
1768
+ weaknesses: ["parallel_tools"],
1769
+ notes: "GLM-5.2 (Z.ai, 2026-06): agentic-coding flagship. 1,048,576 ctx / 131,072 max out. $1.40/$4.40 per 1M; cached input $0.26/M (automatic caching, no marker; storage limited-time free as of 2026-07-18). Thinking on by default (`thinking.type`), `reasoning_effort` max..none. Parallel tool calls UNDOCUMENTED on the hosted API \u2014 profile says false until doc or probe evidence. status:preview \u2014 no brain evidence yet; earns placement via the machinery.",
1770
+ // Starter hypotheses — verify with telemetry/probes; NO brain evidence
1771
+ // yet. Anchored on the vendor's agentic-coding positioning at a
1772
+ // mid-cost tier, discounted for the unproven parallel-tool story.
1773
+ archetypePerf: {
1774
+ generate: 7,
1775
+ // agentic-coding positioning — starter hypothesis
1776
+ transform: 7,
1777
+ // starter hypothesis
1778
+ plan: 7,
1779
+ // starter hypothesis
1780
+ summarize: 7,
1781
+ // tolerant archetype — starter hypothesis
1782
+ ask: 6,
1783
+ extract: 6,
1784
+ critique: 6,
1785
+ classify: 6,
1786
+ hunt: 5
1787
+ // tools work; parallel unproven → discounted
1788
+ }
1789
+ },
1790
+ // ── Moonshot (Kimi) ──
1791
+ // alpha.65 (2026-07-18): first Moonshot profile, provider `moonshot` added
1792
+ // same release. Step-zero sources (all fetched 2026-07-18):
1793
+ // platform.kimi.ai/docs/pricing/chat-k3 ($3.00 cache-miss in / $0.30
1794
+ // cache-hit in / $15.00 out; 1,048,576 ctx; ToolCalls + JSON Mode +
1795
+ // Partial Mode), kimi-k3-quickstart (max_completion_tokens default
1796
+ // 131072, up to 1,048,576; base https://api.moonshot.ai/v1; vision via
1797
+ // base64 or ms://file-id, NO public image URLs), models-overview
1798
+ // (temperature FIXED 1.0, top_p FIXED 0.95, n FIXED 1, always reasons,
1799
+ // reasoning_effort 'max' only), tool-calls guide ("can choose to call
1800
+ // multiple tools at once … will tend to call them in parallel").
1801
+ {
1802
+ id: "kimi-k3",
1803
+ verifiedAgainstDocs: "2026-07-18",
1804
+ provider: "moonshot",
1805
+ status: "preview",
1806
+ maxContextTokens: 1048576,
1807
+ // Documented ceiling; default is 131,072 when unset.
1808
+ maxOutputTokens: 1048576,
1809
+ // No hard doc cap; docs recommend dynamic tool loading at "dozens or
1810
+ // hundreds" — 64 matches the frontier-agentic posture (sonnet-5 tier).
1811
+ maxTools: 64,
1812
+ parallelToolCalls: true,
1813
+ structuredOutput: "native",
1814
+ systemPromptMode: "inline",
1815
+ streaming: true,
1816
+ cliffs: [],
1817
+ costInputPer1m: 3,
1818
+ costOutputPer1m: 15,
1819
+ lowering: {
1820
+ system: { mode: "inline" },
1821
+ // Automatic context caching — no wire marker. Cache-hit input $0.30/M
1822
+ // (0.1× of miss) tracked in notes.
1823
+ cache: { strategy: "unsupported" },
1824
+ tools: { format: "openai" }
1825
+ // No thinking knob: reasoning is always-on and reasoning_effort
1826
+ // accepts only 'max' (= the server default). Nothing to lower.
1827
+ },
1828
+ recovery: [
1829
+ { signal: "rate_limit", action: "escalate", reason: "429 \u2014 escalate" },
1830
+ { signal: "model_not_found", action: "escalate", reason: "Deprecated \u2014 escalate (L-061)" }
1831
+ ],
1832
+ strengths: ["quality", "reasoning", "1m_context", "parallel_tools", "tool_use", "code", "vision"],
1833
+ // 'latency' → latencyTierOf derives 'slow': always-on max-effort
1834
+ // reasoner with no off switch; no measured p50 yet, the tag is the
1835
+ // honest prior (reasoner family precedent: deepseek-v4-pro ~48s).
1836
+ weaknesses: ["cost", "latency"],
1837
+ notes: "Kimi K3 (Moonshot, API live 2026-07-16): 2.8T-param open-weight flagship, native vision. 1,048,576 ctx; max_completion_tokens default 131,072, ceiling 1,048,576. $3.00/$15.00 per 1M, cache-hit input $0.30/M (automatic caching). Reasoning ALWAYS ON (reasoning_effort max only, cannot disable; responses may carry reasoning_content). Wire quirks: temperature fixed 1.0 / top_p 0.95 / n 1 (kgauto never emits those); vision input must be base64 or ms://file-id \u2014 public image URLs rejected. status:preview \u2014 earns placement via the machinery.",
1838
+ // Starter hypotheses — verify with telemetry/probes; NO brain evidence
1839
+ // yet. Anchored on documented long-horizon-agentic + parallel-tool
1840
+ // strengths; discounted on terse archetypes where always-on reasoning
1841
+ // bills $15/M output for thinking the archetype doesn't need.
1842
+ archetypePerf: {
1843
+ hunt: 8,
1844
+ // parallel tools + long-horizon agentic — starter hypothesis
1845
+ plan: 8,
1846
+ // starter hypothesis
1847
+ generate: 8,
1848
+ // starter hypothesis
1849
+ critique: 7,
1850
+ ask: 7,
1851
+ extract: 7,
1852
+ transform: 7,
1853
+ summarize: 6,
1854
+ // works, but $15/M output reasoning tax on a tolerant archetype
1855
+ classify: 5
1856
+ // always-on reasoning cost + reasoner hedge risk
1857
+ },
1858
+ // Diagnostics-only (no prompt rewrite): reasoner-family hedge risk on
1859
+ // decisive archetypes, carried as a warning until K3-specific probe
1860
+ // evidence exists. The deepseek-reasoner family showed 8/10 judge
1861
+ // rationales citing hedging on classify (exclusion-finding ID 20,
1862
+ // 2026-05-28); K3 is an always-on reasoner and inherits the risk class,
1863
+ // not the conviction.
1864
+ archetypeConventions: [
1865
+ {
1866
+ archetype: "classify",
1867
+ cliffWarning: "kimi-k3 is an always-on reasoner: decisive archetypes (classify) may hedge, and reasoning tokens bill at $15/M output. Family-prior risk (deepseek-reasoner precedent), not K3-measured \u2014 probe before relying on it for classify.",
1868
+ reason: "Reasoner-family prior (exclusion-finding ID 20, 2026-05-28, deepseek-v4-pro on tt-intel/classify). No K3-specific evidence yet \u2014 warning only, no prompt rewrite."
1869
+ }
1870
+ ]
1714
1871
  }
1715
1872
  ];
1716
1873
  var ALIASES = {
@@ -2602,6 +2759,7 @@ function passApplyCliffs(ir, profile, estimatedInputTokens) {
2602
2759
  var LATENCY_OVERAGE_WEIGHT = 0.6;
2603
2760
  var LATENCY_PENALTY_CAP = 1;
2604
2761
  var QUALITY_GATE_PENALTY = 4;
2762
+ var PROMOTION_BOOST = 5;
2605
2763
  function effectiveConventions(profile) {
2606
2764
  const own = profile.archetypeConventions ?? [];
2607
2765
  if (own.length > 0) return own;
@@ -2619,6 +2777,9 @@ function passScoreTargets(ir, opts) {
2619
2777
  const preferredSet = new Set(policy.preferredModels ?? []);
2620
2778
  const scores = [];
2621
2779
  const policyMutations = [];
2780
+ const rawPromotion = opts.promotion;
2781
+ const promotionDeferred = rawPromotion !== void 0 && (policy.preferredModels?.length ?? 0) > 0;
2782
+ const promotion = promotionDeferred ? void 0 : rawPromotion;
2622
2783
  const modelIds = ir.models.filter((m) => typeof m === "string");
2623
2784
  for (const modelId of modelIds) {
2624
2785
  let profile;
@@ -2683,7 +2844,12 @@ function passScoreTargets(ir, opts) {
2683
2844
  );
2684
2845
  if (schemaWeak) qualityGatePenalty = QUALITY_GATE_PENALTY;
2685
2846
  }
2686
- const rank = qualityScore + callerOrderBoost - costPenalty - reasons.length * 10 + preferredBoost - latencyPenalty - qualityGatePenalty;
2847
+ const isPromoted = promotion?.promotedModel === modelId;
2848
+ if (isPromoted && promotion.suppressQualityGate) {
2849
+ qualityGatePenalty = 0;
2850
+ }
2851
+ const promotionBoost = isPromoted ? PROMOTION_BOOST : 0;
2852
+ const rank = qualityScore + callerOrderBoost - costPenalty - reasons.length * 10 + preferredBoost - latencyPenalty - qualityGatePenalty + promotionBoost;
2687
2853
  scores.push({
2688
2854
  modelId,
2689
2855
  estimatedCostUsd,
@@ -2733,6 +2899,22 @@ function passScoreTargets(ir, opts) {
2733
2899
  description: `Model ${modelId} gated below the quality floor for archetype '${ir.intent.archetype}' \u2014 declared structuredOutput + kgauto convention flags it schema-weak for this contract (structuredOutputHint:'avoid'). Down-ranked out of leadership; retained as graceful fallback only.`
2734
2900
  });
2735
2901
  }
2902
+ if (isPromoted && reasons.length === 0) {
2903
+ policyMutations.push({
2904
+ id: `promotion-applied-${modelId}`,
2905
+ source: "surface_promotion",
2906
+ passName: "score_targets",
2907
+ description: `Model ${modelId} boosted to surface leadership by active promotion #${promotion.id} (golden-eval run ${promotion.evalRunId ?? "n/a"}, Stage 2 auto-promote, 7-day rollback guard)` + (promotion.suppressQualityGate ? " \u2014 schema-weak quality gate suppressed for this tuple (eval measured the floor holding on real workload)" : "")
2908
+ });
2909
+ }
2910
+ }
2911
+ if (promotionDeferred && rawPromotion && modelIds.includes(rawPromotion.promotedModel)) {
2912
+ policyMutations.push({
2913
+ id: `promotion-deferred-consumer-preference-${rawPromotion.promotedModel}`,
2914
+ source: "surface_promotion",
2915
+ passName: "score_targets",
2916
+ description: `Active promotion #${rawPromotion.id} for ${rawPromotion.promotedModel} deferred \u2014 CompilePolicy.preferredModels is declared and explicit consumer preference outranks brain evidence.`
2917
+ });
2736
2918
  }
2737
2919
  return { value: scores, mutations: policyMutations };
2738
2920
  }
@@ -2940,6 +3122,10 @@ function lower(ir, profile, hints = {}) {
2940
3122
  return lowerOpenAI(ir, profile, hints);
2941
3123
  case "deepseek":
2942
3124
  return lowerDeepSeek(ir, profile);
3125
+ case "zai":
3126
+ return lowerZai(ir, profile, hints);
3127
+ case "moonshot":
3128
+ return lowerMoonshot(ir, profile);
2943
3129
  default:
2944
3130
  throw new Error(`No lowering implementation for provider: ${profile.provider}`);
2945
3131
  }
@@ -3228,6 +3414,68 @@ function lowerDeepSeek(ir, profile) {
3228
3414
  }
3229
3415
  };
3230
3416
  }
3417
+ function buildOpenAICompatibleParts(ir) {
3418
+ const ordered = sortSections(ir.sections);
3419
+ const systemText = ordered.map((s) => s.text).join("\n\n");
3420
+ const messages = systemText ? [{ role: "system", content: systemText }] : [];
3421
+ for (const m of ir.history ?? []) {
3422
+ if (m.role === "system") continue;
3423
+ messages.push({ role: m.role, content: m.parts ?? m.content });
3424
+ }
3425
+ if (ir.currentTurn && ir.currentTurn.role !== "system") {
3426
+ messages.push({
3427
+ role: ir.currentTurn.role,
3428
+ content: ir.currentTurn.parts ?? ir.currentTurn.content
3429
+ });
3430
+ }
3431
+ const history = (ir.history ?? []).filter((m) => m.role !== "system");
3432
+ const histMarkIndex = resolveHistoryMarkIndex(history.length, ir.historyCachePolicy);
3433
+ const historyCacheableTokens = histMarkIndex >= 0 ? sumHistoryTokens(history, histMarkIndex) : 0;
3434
+ return {
3435
+ messages,
3436
+ tools: ir.tools && ir.tools.length > 0 ? toOpenAITools(ir.tools) : void 0,
3437
+ response_format: ir.constraints?.structuredOutput ? { type: "json_object" } : void 0,
3438
+ historyCacheableTokens
3439
+ };
3440
+ }
3441
+ function lowerZai(ir, profile, hints) {
3442
+ const parts = buildOpenAICompatibleParts(ir);
3443
+ return {
3444
+ request: {
3445
+ provider: "zai",
3446
+ model: profile.id,
3447
+ messages: parts.messages,
3448
+ tools: parts.tools,
3449
+ response_format: parts.response_format,
3450
+ // Z.ai thinking defaults to enabled server-side; emit an explicit
3451
+ // disable only when a cliff forced thinking off (the GLM analogue of
3452
+ // Gemini's thinkingBudget=0).
3453
+ thinking: hints.forceThinkingZero ? { type: "disabled" } : void 0
3454
+ },
3455
+ diagnostics: {
3456
+ cacheableTokens: 0,
3457
+ historyCacheableTokens: parts.historyCacheableTokens,
3458
+ estimatedCacheSavingsUsd: 0
3459
+ }
3460
+ };
3461
+ }
3462
+ function lowerMoonshot(ir, profile) {
3463
+ const parts = buildOpenAICompatibleParts(ir);
3464
+ return {
3465
+ request: {
3466
+ provider: "moonshot",
3467
+ model: profile.id,
3468
+ messages: parts.messages,
3469
+ tools: parts.tools,
3470
+ response_format: parts.response_format
3471
+ },
3472
+ diagnostics: {
3473
+ cacheableTokens: 0,
3474
+ historyCacheableTokens: parts.historyCacheableTokens,
3475
+ estimatedCacheSavingsUsd: 0
3476
+ }
3477
+ };
3478
+ }
3231
3479
  function sortSections(sections) {
3232
3480
  return [...sections].sort((a, b) => {
3233
3481
  const wa = a.weight ?? 100;
@@ -4121,6 +4369,130 @@ ${originalText}`;
4121
4369
  return { rewrittenIR, rewrites };
4122
4370
  }
4123
4371
 
4372
+ // src/promotions-brain.ts
4373
+ function isRawPromotionRow(x) {
4374
+ if (!x || typeof x !== "object") return false;
4375
+ const r = x;
4376
+ return (typeof r.id === "number" || typeof r.id === "string") && typeof r.intent_archetype === "string" && typeof r.promoted_model === "string" && typeof r.incumbent_model === "string";
4377
+ }
4378
+ function coerceId(v) {
4379
+ if (typeof v === "number") return Number.isFinite(v) ? v : null;
4380
+ if (typeof v === "string") {
4381
+ const n = Number(v);
4382
+ return Number.isFinite(n) ? n : null;
4383
+ }
4384
+ return null;
4385
+ }
4386
+ function mapRowsToPromotions(rows) {
4387
+ const out = [];
4388
+ for (const row of rows) {
4389
+ if (!isRawPromotionRow(row)) continue;
4390
+ const id = coerceId(row.id);
4391
+ if (id === null) continue;
4392
+ out.push({
4393
+ id,
4394
+ archetype: row.intent_archetype,
4395
+ promotedModel: row.promoted_model,
4396
+ incumbentModel: row.incumbent_model,
4397
+ evalRunId: coerceId(row.eval_run_id ?? null),
4398
+ suppressQualityGate: row.suppress_quality_gate === true,
4399
+ promotedAt: typeof row.promoted_at === "string" ? row.promoted_at : ""
4400
+ });
4401
+ }
4402
+ return out;
4403
+ }
4404
+ var snapshots4 = /* @__PURE__ */ new Map();
4405
+ var runtime5;
4406
+ var warnedOnce4 = false;
4407
+ var DEFAULT_PROMOTIONS_ENDPOINT = "https://kgauto-dashboard.vercel.app/api/kgauto-v2/promotions";
4408
+ function isAutoPromoteEnabledFromEnv(envSource) {
4409
+ const env = envSource ?? (typeof process !== "undefined" && process.env ? process.env : {});
4410
+ const raw = (env.KGAUTO_AUTO_PROMOTE ?? "").trim().toLowerCase();
4411
+ return raw === "1" || raw === "true";
4412
+ }
4413
+ function configurePromotionsBrain(rt) {
4414
+ runtime5 = rt;
4415
+ snapshots4.clear();
4416
+ warnedOnce4 = false;
4417
+ }
4418
+ function isPromotionsBrainActive() {
4419
+ return runtime5 !== void 0;
4420
+ }
4421
+ function getApplicablePromotion(opts) {
4422
+ const rt = runtime5;
4423
+ if (!rt) return void 0;
4424
+ const appId = opts.appId;
4425
+ if (!appId || !opts.archetype) return void 0;
4426
+ let snap = snapshots4.get(appId);
4427
+ if (!snap) {
4428
+ snap = { data: [], expiresAt: 0, refreshing: false };
4429
+ snapshots4.set(appId, snap);
4430
+ }
4431
+ const now = Date.now();
4432
+ const stale = snap.expiresAt <= now;
4433
+ if (stale && !snap.refreshing) {
4434
+ snap.refreshing = true;
4435
+ void asyncRefresh5(rt, appId);
4436
+ }
4437
+ return snap.data.find((p) => p.archetype === opts.archetype);
4438
+ }
4439
+ var pendingRefreshes4 = /* @__PURE__ */ new Map();
4440
+ async function asyncRefresh5(rt, appId) {
4441
+ const promise = doRefresh5(rt, appId);
4442
+ pendingRefreshes4.set(appId, promise);
4443
+ try {
4444
+ await promise;
4445
+ } finally {
4446
+ if (pendingRefreshes4.get(appId) === promise) {
4447
+ pendingRefreshes4.delete(appId);
4448
+ }
4449
+ }
4450
+ }
4451
+ async function doRefresh5(rt, appId) {
4452
+ const url = `${rt.endpoint}?app_id=${encodeURIComponent(appId)}`;
4453
+ let snap = snapshots4.get(appId);
4454
+ if (!snap) {
4455
+ snap = { data: [], expiresAt: 0, refreshing: false };
4456
+ snapshots4.set(appId, snap);
4457
+ }
4458
+ try {
4459
+ const res = await rt.fetchImpl(url, { method: "GET" });
4460
+ if (!res.ok) {
4461
+ throw new Error(`promotions ${res.status}: ${res.statusText}`);
4462
+ }
4463
+ const body = await res.json();
4464
+ if (runtime5 !== rt) return;
4465
+ const rows = Array.isArray(body) ? mapRowsToPromotions(body) : [];
4466
+ snap.data = rows;
4467
+ snap.expiresAt = Date.now() + rt.ttlMs;
4468
+ snap.refreshing = false;
4469
+ } catch (err) {
4470
+ if (runtime5 !== rt) return;
4471
+ snap.refreshing = false;
4472
+ snap.expiresAt = Date.now() + rt.ttlMs;
4473
+ if (!warnedOnce4) {
4474
+ warnedOnce4 = true;
4475
+ (rt.onError ?? defaultOnError5)(err);
4476
+ }
4477
+ }
4478
+ }
4479
+ function defaultOnError5(err) {
4480
+ console.warn(
4481
+ "[kgauto] promotions fetch failed (promotion boost inactive until next refresh):",
4482
+ err
4483
+ );
4484
+ }
4485
+ function _testResetPromotions() {
4486
+ runtime5 = void 0;
4487
+ snapshots4.clear();
4488
+ pendingRefreshes4 = /* @__PURE__ */ new Map();
4489
+ warnedOnce4 = false;
4490
+ }
4491
+ async function _testWaitForPromotionsRefresh() {
4492
+ const pending = Array.from(pendingRefreshes4.values());
4493
+ if (pending.length > 0) await Promise.all(pending);
4494
+ }
4495
+
4124
4496
  // src/compile.ts
4125
4497
  var counter = 0;
4126
4498
  function makeHandle() {
@@ -4147,11 +4519,22 @@ function compile(ir, opts = {}) {
4147
4519
  ...toolFiltered.mutations,
4148
4520
  ...compressed.mutations
4149
4521
  ];
4522
+ const activePromotion = getApplicablePromotion({
4523
+ appId: ir.appId,
4524
+ archetype: ir.intent.archetype
4525
+ });
4526
+ const promotion = activePromotion ? {
4527
+ id: activePromotion.id,
4528
+ promotedModel: activePromotion.promotedModel,
4529
+ evalRunId: activePromotion.evalRunId,
4530
+ suppressQualityGate: activePromotion.suppressQualityGate
4531
+ } : void 0;
4150
4532
  const inputTokens = estimateInputTokens(workingIR);
4151
4533
  const scores = passScoreTargets(workingIR, {
4152
4534
  estimatedInputTokens: inputTokens,
4153
4535
  profilesById: resolver,
4154
- policy: opts.policy
4536
+ policy: opts.policy,
4537
+ promotion
4155
4538
  });
4156
4539
  accumulatedMutations.push(...scores.mutations);
4157
4540
  const target = pickTarget(workingIR, scores.value);
@@ -4483,11 +4866,23 @@ function configureBrain(config) {
4483
4866
  } else {
4484
4867
  configureExclusionFindingsBrain(void 0);
4485
4868
  }
4869
+ const promotionsConsent = config.autoPromote ?? isAutoPromoteEnabledFromEnv();
4870
+ if (promotionsConsent && bq.promotions !== false) {
4871
+ configurePromotionsBrain({
4872
+ endpoint: bq.promotionsEndpoint ?? DEFAULT_PROMOTIONS_ENDPOINT,
4873
+ ttlMs: bq.cacheTtlMs ?? 3e5,
4874
+ fetchImpl: config.fetchImpl ?? fetch,
4875
+ onError: config.onError
4876
+ });
4877
+ } else {
4878
+ configurePromotionsBrain(void 0);
4879
+ }
4486
4880
  }
4487
4881
  function clearBrain() {
4488
4882
  activeConfig = void 0;
4489
4883
  configureBrainQuery(void 0);
4490
4884
  configureExclusionFindingsBrain(void 0);
4885
+ configurePromotionsBrain(void 0);
4491
4886
  }
4492
4887
  var DEAD_LETTER_MAX_ENTRIES = 50;
4493
4888
  var DEAD_LETTER_MAX_ATTEMPTS = 3;
@@ -4604,7 +4999,7 @@ async function flushBrainDeadLetter() {
4604
4999
  if (entry.attempts >= DEAD_LETTER_MAX_ATTEMPTS) {
4605
5000
  const idx = deadLetter.indexOf(entry);
4606
5001
  if (idx !== -1) deadLetter.splice(idx, 1);
4607
- (config.onError ?? defaultOnError5)(
5002
+ (config.onError ?? defaultOnError6)(
4608
5003
  new Error(
4609
5004
  `brain dead-letter: dropping ${entry.route} payload after ${entry.attempts} attempts \u2014 last error: ${entry.lastError}`
4610
5005
  )
@@ -4754,7 +5149,7 @@ async function record(input) {
4754
5149
  } catch (err) {
4755
5150
  noteFailure(err);
4756
5151
  pushDeadLetter("outcomes", config.endpoint, payload, err);
4757
- (config.onError ?? defaultOnError5)(err);
5152
+ (config.onError ?? defaultOnError6)(err);
4758
5153
  return;
4759
5154
  }
4760
5155
  maybeAutoFlush();
@@ -4782,7 +5177,7 @@ async function record(input) {
4782
5177
  } catch (err) {
4783
5178
  noteFailure(err);
4784
5179
  pushDeadLetter("compile_outcome_advisories", config.endpoint, advisoryPayload, err);
4785
- (config.onError ?? defaultOnError5)(err);
5180
+ (config.onError ?? defaultOnError6)(err);
4786
5181
  }
4787
5182
  };
4788
5183
  if (config.sync) {
@@ -4791,7 +5186,7 @@ async function record(input) {
4791
5186
  void send();
4792
5187
  }
4793
5188
  }
4794
- function defaultOnError5(err) {
5189
+ function defaultOnError6(err) {
4795
5190
  console.warn("[kgauto] brain record failed:", err);
4796
5191
  }
4797
5192
  function describeBrainWriteFailure(status, route, body) {
@@ -4943,7 +5338,7 @@ async function recordOutcome(input) {
4943
5338
  } catch (err) {
4944
5339
  noteFailure(err);
4945
5340
  pushDeadLetter("compile_outcome_quality", config.endpoint, payload, err);
4946
- (config.onError ?? defaultOnError5)(err);
5341
+ (config.onError ?? defaultOnError6)(err);
4947
5342
  return { ok: false, reason: "persistence_failed" };
4948
5343
  }
4949
5344
  };
@@ -5014,7 +5409,7 @@ async function recordShadowProbe(input) {
5014
5409
  } catch (err) {
5015
5410
  noteFailure(err);
5016
5411
  pushDeadLetter("probe_outcomes", config.endpoint, row, err);
5017
- (config.onError ?? defaultOnError5)(err);
5412
+ (config.onError ?? defaultOnError6)(err);
5018
5413
  }
5019
5414
  };
5020
5415
  if (config.sync) {
@@ -5069,7 +5464,7 @@ async function recordGoldenIr(input) {
5069
5464
  } catch (err) {
5070
5465
  noteFailure(err);
5071
5466
  pushDeadLetter("golden_irs", config.endpoint, row, err);
5072
- (config.onError ?? defaultOnError5)(err);
5467
+ (config.onError ?? defaultOnError6)(err);
5073
5468
  }
5074
5469
  };
5075
5470
  if (config.sync) {
@@ -5137,7 +5532,9 @@ var SUPPORTED_PROVIDERS = Object.freeze([
5137
5532
  "anthropic",
5138
5533
  "google",
5139
5534
  "openai",
5140
- "deepseek"
5535
+ "deepseek",
5536
+ "zai",
5537
+ "moonshot"
5141
5538
  ]);
5142
5539
  function isSupportedProvider(p) {
5143
5540
  return SUPPORTED_PROVIDERS.includes(p);
@@ -5150,7 +5547,15 @@ var PROVIDER_ENV_KEYS = Object.freeze({
5150
5547
  "GOOGLE_GENERATIVE_AI_API_KEY"
5151
5548
  ]),
5152
5549
  openai: Object.freeze(["OPENAI_API_KEY"]),
5153
- deepseek: Object.freeze(["DEEPSEEK_API_KEY"])
5550
+ deepseek: Object.freeze(["DEEPSEEK_API_KEY"]),
5551
+ // alpha.65 — Z.ai (GLM family). ZAI_API_KEY is the canonical name; the
5552
+ // Z_AI_API_KEY variant covers the underscore convention some tooling uses
5553
+ // for the brand's "Z.ai" spelling.
5554
+ zai: Object.freeze(["ZAI_API_KEY", "Z_AI_API_KEY"]),
5555
+ // alpha.65 — Moonshot AI (Kimi family). MOONSHOT_API_KEY is canonical
5556
+ // (api.moonshot.ai); KIMI_API_KEY covers the platform.kimi.ai rebrand
5557
+ // surface so consumers keyed under either name resolve.
5558
+ moonshot: Object.freeze(["MOONSHOT_API_KEY", "KIMI_API_KEY"])
5154
5559
  });
5155
5560
  function defaultEnv() {
5156
5561
  return typeof process !== "undefined" && process.env ? process.env : {};
@@ -5494,6 +5899,8 @@ function retryableError(status, code, message, raw) {
5494
5899
  var ANTHROPIC_URL2 = "https://api.anthropic.com/v1/messages";
5495
5900
  var OPENAI_URL = "https://api.openai.com/v1/chat/completions";
5496
5901
  var DEEPSEEK_URL = "https://api.deepseek.com/chat/completions";
5902
+ var ZAI_URL = "https://api.z.ai/api/paas/v4/chat/completions";
5903
+ var MOONSHOT_URL = "https://api.moonshot.ai/v1/chat/completions";
5497
5904
  async function execute(request, opts = {}) {
5498
5905
  const merged = applyOverrides(request, opts.providerOverrides);
5499
5906
  switch (merged.provider) {
@@ -5505,6 +5912,18 @@ async function execute(request, opts = {}) {
5505
5912
  return executeOpenAI(merged, opts);
5506
5913
  case "deepseek":
5507
5914
  return executeDeepSeek(merged, opts);
5915
+ case "zai":
5916
+ return executeOpenAICompatible(
5917
+ merged,
5918
+ opts,
5919
+ { provider: "zai", url: ZAI_URL, missingKeyMessage: "ZAI_API_KEY missing" }
5920
+ );
5921
+ case "moonshot":
5922
+ return executeOpenAICompatible(
5923
+ merged,
5924
+ opts,
5925
+ { provider: "moonshot", url: MOONSHOT_URL, missingKeyMessage: "MOONSHOT_API_KEY missing" }
5926
+ );
5508
5927
  default: {
5509
5928
  const _exhaustive = merged;
5510
5929
  throw new Error(`execute(): no executor for provider: ${JSON.stringify(_exhaustive)}`);
@@ -5654,6 +6073,34 @@ async function executeDeepSeek(request, opts) {
5654
6073
  if (!res.ok) return classifyHttpError2(res.status, json);
5655
6074
  return { ok: true, status: res.status, response: normalizeOpenAILike(json) };
5656
6075
  }
6076
+ async function executeOpenAICompatible(request, opts, spec) {
6077
+ const apiKey = resolveProviderKey(spec.provider, { apiKeys: opts.apiKeys });
6078
+ if (!apiKey) {
6079
+ return terminalError(401, "auth", spec.missingKeyMessage);
6080
+ }
6081
+ if (opts.onChunk) {
6082
+ return streamOpenAILike(spec.url, request, apiKey, spec.provider, {
6083
+ onChunk: opts.onChunk,
6084
+ fetchImpl: opts.fetchImpl
6085
+ });
6086
+ }
6087
+ const { provider: _provider, ...body } = request;
6088
+ const fetchFn = opts.fetchImpl ?? fetch;
6089
+ let res;
6090
+ let json;
6091
+ try {
6092
+ res = await fetchFn(spec.url, {
6093
+ method: "POST",
6094
+ headers: { authorization: `Bearer ${apiKey}`, "content-type": "application/json" },
6095
+ body: JSON.stringify(body)
6096
+ });
6097
+ json = await res.json().catch(() => ({}));
6098
+ } catch (err) {
6099
+ return retryableError2(0, "network_error", String(err), null);
6100
+ }
6101
+ if (!res.ok) return classifyHttpError2(res.status, json);
6102
+ return { ok: true, status: res.status, response: normalizeOpenAILike(json) };
6103
+ }
5657
6104
  function normalizeOpenAILike(raw) {
5658
6105
  const r = raw;
5659
6106
  const choice = r.choices?.[0];
@@ -7769,7 +8216,7 @@ function createBrainForwardRoutes(config) {
7769
8216
  }
7770
8217
 
7771
8218
  // src/version.ts
7772
- var LIBRARY_VERSION = "2.0.0-alpha.63";
8219
+ var LIBRARY_VERSION = "2.0.0-alpha.65";
7773
8220
 
7774
8221
  // src/key-health.ts
7775
8222
  var JSON_HEADERS2 = { "Content-Type": "application/json" };
@@ -7818,6 +8265,14 @@ var PROBE_SPECS = [
7818
8265
  return Number.isFinite(n) ? n : void 0;
7819
8266
  }
7820
8267
  },
8268
+ {
8269
+ provider: "moonshot",
8270
+ canonicalEnvName: "MOONSHOT_API_KEY",
8271
+ buildRequest: (key) => ({
8272
+ url: "https://api.moonshot.ai/v1/models",
8273
+ headers: { Authorization: `Bearer ${key}` }
8274
+ })
8275
+ },
7821
8276
  {
7822
8277
  provider: "google",
7823
8278
  canonicalEnvName: "GEMINI_API_KEY",
@@ -7849,6 +8304,11 @@ function createKeyHealthRoute(config) {
7849
8304
  const aiSdk = envKey(env, "GOOGLE_GENERATIVE_AI_API_KEY");
7850
8305
  key = gemini ?? google ?? aiSdk;
7851
8306
  envName = gemini ? "GEMINI_API_KEY" : google ? "GOOGLE_API_KEY" : aiSdk ? "GOOGLE_GENERATIVE_AI_API_KEY" : "GEMINI_API_KEY";
8307
+ } else if (spec.provider === "moonshot") {
8308
+ const moonshot = envKey(env, "MOONSHOT_API_KEY");
8309
+ const kimi = envKey(env, "KIMI_API_KEY");
8310
+ key = moonshot ?? kimi;
8311
+ envName = moonshot ? "MOONSHOT_API_KEY" : kimi ? "KIMI_API_KEY" : "MOONSHOT_API_KEY";
7852
8312
  } else {
7853
8313
  key = envKey(env, spec.canonicalEnvName);
7854
8314
  }
@@ -8389,6 +8849,7 @@ function compile2(ir, opts) {
8389
8849
  ARCHETYPE_FLOOR_DEFAULT,
8390
8850
  CallError,
8391
8851
  DEFAULT_FINDINGS_ENDPOINT,
8852
+ DEFAULT_PROMOTIONS_ENDPOINT,
8392
8853
  DIALECT_VERSION,
8393
8854
  FamilyResolutionError,
8394
8855
  INTENT_ARCHETYPES,
@@ -8400,6 +8861,8 @@ function compile2(ir, opts) {
8400
8861
  PROVIDER_ENV_KEYS,
8401
8862
  RULE_SEQUENTIAL_TOOL_CLIFF,
8402
8863
  TRANSLATOR_FLOOR,
8864
+ _testResetPromotions,
8865
+ _testWaitForPromotionsRefresh,
8403
8866
  allProfiles,
8404
8867
  applyArchetypeConvention,
8405
8868
  applySectionRewrites,
@@ -8419,6 +8882,7 @@ function compile2(ir, opts) {
8419
8882
  compile,
8420
8883
  compileForAISDKv6,
8421
8884
  configureBrain,
8885
+ configurePromotionsBrain,
8422
8886
  countTokens,
8423
8887
  createBrainForwardRoutes,
8424
8888
  createKeyHealthRoute,
@@ -8430,6 +8894,7 @@ function compile2(ir, opts) {
8430
8894
  getActionableAdvisories,
8431
8895
  getAllStarterChains,
8432
8896
  getAllStarterChainsWithGrounding,
8897
+ getApplicablePromotion,
8433
8898
  getArchetypePerfScore,
8434
8899
  getDefaultFallbackChain,
8435
8900
  getDefaultFallbackChainWithGrounding,
@@ -8445,10 +8910,12 @@ function compile2(ir, opts) {
8445
8910
  getStarterChainWithGrounding,
8446
8911
  hashShape,
8447
8912
  isArchetype,
8913
+ isAutoPromoteEnabledFromEnv,
8448
8914
  isBrainQueryActiveFor,
8449
8915
  isBrainSync,
8450
8916
  isExclusionFindingsBrainActive,
8451
8917
  isModelReachable,
8918
+ isPromotionsBrainActive,
8452
8919
  isProviderReachable,
8453
8920
  latencyTierOf,
8454
8921
  learningKey,