@warmdrift/kgauto-compiler 2.0.0-alpha.10 → 2.0.0-alpha.11

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
@@ -38,6 +38,7 @@ __export(index_exports, {
38
38
  countTokens: () => countTokens,
39
39
  execute: () => execute,
40
40
  getAllStarterChains: () => getAllStarterChains,
41
+ getArchetypePerfScore: () => getArchetypePerfScore,
41
42
  getDefaultFallbackChain: () => getDefaultFallbackChain,
42
43
  getProfile: () => getProfile,
43
44
  getReachabilityDiagnostic: () => getReachabilityDiagnostic,
@@ -47,9 +48,15 @@ __export(index_exports, {
47
48
  isModelReachable: () => isModelReachable,
48
49
  isProviderReachable: () => isProviderReachable,
49
50
  learningKey: () => learningKey,
51
+ loadAliasesFromBrain: () => loadAliasesFromBrain,
52
+ loadArchetypePerfFromBrain: () => loadArchetypePerfFromBrain,
53
+ loadChainsFromBrain: () => loadChainsFromBrain,
54
+ loadModelsFromBrain: () => loadModelsFromBrain,
55
+ loadPricingFromBrain: () => loadPricingFromBrain,
50
56
  profilesByProvider: () => profilesByProvider,
51
57
  record: () => record,
52
58
  resetTokenizer: () => resetTokenizer,
59
+ resolvePricingAt: () => resolvePricingAt,
53
60
  resolveProviderKey: () => resolveProviderKey,
54
61
  runAdvisor: () => runAdvisor,
55
62
  setTokenizer: () => setTokenizer,
@@ -1439,14 +1446,20 @@ var ALIASES = {
1439
1446
  // Legacy kgauto typo — actual API alias is dash-form (alpha.1 had dot).
1440
1447
  "claude-haiku-4.5": "claude-haiku-4-5"
1441
1448
  };
1449
+ var brainHook = {};
1450
+ function _setProfileBrainHook(hook) {
1451
+ brainHook = hook;
1452
+ }
1442
1453
  function canonicalId(id) {
1443
- return ALIASES[id] ?? id;
1454
+ return brainHook.resolveAlias?.(id) ?? ALIASES[id] ?? id;
1444
1455
  }
1445
1456
  var PROFILE_INDEX = new Map(
1446
1457
  PROFILES_RAW.map((p) => [p.id, p])
1447
1458
  );
1448
1459
  function getProfile(id) {
1449
1460
  const canonical = canonicalId(id);
1461
+ const fromBrain = brainHook.getProfile?.(canonical);
1462
+ if (fromBrain) return fromBrain;
1450
1463
  const p = PROFILE_INDEX.get(canonical);
1451
1464
  if (!p) {
1452
1465
  const known = [...PROFILE_INDEX.keys(), ...Object.keys(ALIASES)].join(", ");
@@ -1455,11 +1468,15 @@ function getProfile(id) {
1455
1468
  return p;
1456
1469
  }
1457
1470
  function tryGetProfile(id) {
1458
- return PROFILE_INDEX.get(canonicalId(id));
1471
+ const canonical = canonicalId(id);
1472
+ return brainHook.getProfile?.(canonical) ?? PROFILE_INDEX.get(canonical);
1459
1473
  }
1460
1474
  function allProfiles() {
1461
1475
  return PROFILES_RAW;
1462
1476
  }
1477
+ function allProfilesRaw() {
1478
+ return PROFILES_RAW;
1479
+ }
1463
1480
  function profilesByProvider(provider) {
1464
1481
  return PROFILES_RAW.filter((p) => p.provider === provider);
1465
1482
  }
@@ -1683,14 +1700,170 @@ function validateFinalFit(ir, profile, tokens) {
1683
1700
  }
1684
1701
  }
1685
1702
 
1703
+ // src/brain-query.ts
1704
+ var FRESH_SNAPSHOT = {
1705
+ data: null,
1706
+ expiresAt: 0,
1707
+ refreshing: false,
1708
+ warned: false
1709
+ };
1710
+ var snapshot = { ...FRESH_SNAPSHOT };
1711
+ var runtime;
1712
+ function configureBrainQuery(rt) {
1713
+ runtime = rt;
1714
+ snapshot = { ...FRESH_SNAPSHOT };
1715
+ }
1716
+ function createBrainQueryCache(opts) {
1717
+ return () => {
1718
+ const rt = runtime;
1719
+ if (!rt || !rt.enabledTables.has(opts.table)) {
1720
+ return opts.bundledFallback();
1721
+ }
1722
+ const now = Date.now();
1723
+ const stale = snapshot.expiresAt <= now;
1724
+ if (stale && !snapshot.refreshing) {
1725
+ snapshot.refreshing = true;
1726
+ void asyncRefresh(rt);
1727
+ }
1728
+ if (snapshot.data) {
1729
+ const rows = snapshot.data[opts.table];
1730
+ if (Array.isArray(rows) && rows.length > 0) {
1731
+ try {
1732
+ return opts.mapRows(rows);
1733
+ } catch {
1734
+ return opts.bundledFallback();
1735
+ }
1736
+ }
1737
+ }
1738
+ return opts.bundledFallback();
1739
+ };
1740
+ }
1741
+ var pendingRefresh;
1742
+ async function asyncRefresh(rt) {
1743
+ const promise = doRefresh(rt);
1744
+ pendingRefresh = promise;
1745
+ try {
1746
+ await promise;
1747
+ } finally {
1748
+ if (pendingRefresh === promise) pendingRefresh = void 0;
1749
+ }
1750
+ }
1751
+ var DEFAULT_CONFIG_URL = "https://kgauto-dashboard.vercel.app/api/kgauto-v2/config";
1752
+ async function doRefresh(rt) {
1753
+ const url = rt.configEndpoint ?? DEFAULT_CONFIG_URL;
1754
+ try {
1755
+ const res = await rt.fetchImpl(url, { method: "GET" });
1756
+ if (!res.ok) {
1757
+ throw new Error(`brain-query ${res.status}: ${res.statusText}`);
1758
+ }
1759
+ const body = await res.json();
1760
+ if (runtime !== rt) return;
1761
+ snapshot = {
1762
+ data: body,
1763
+ expiresAt: Date.now() + rt.ttlMs,
1764
+ refreshing: false,
1765
+ warned: snapshot.warned
1766
+ };
1767
+ } catch (err) {
1768
+ if (runtime !== rt) return;
1769
+ snapshot.refreshing = false;
1770
+ snapshot.expiresAt = Date.now() + rt.ttlMs;
1771
+ if (!snapshot.warned) {
1772
+ snapshot.warned = true;
1773
+ (rt.onError ?? defaultOnError)(err);
1774
+ }
1775
+ }
1776
+ }
1777
+ function defaultOnError(err) {
1778
+ console.warn("[kgauto] brain-query failed (using bundled fallback):", err);
1779
+ }
1780
+
1781
+ // src/pricing-brain.ts
1782
+ function isPricingRow(x) {
1783
+ if (!x || typeof x !== "object") return false;
1784
+ const r = x;
1785
+ return typeof r.model_id === "string" && typeof r.cost_input_per_1m === "number" && typeof r.cost_output_per_1m === "number" && typeof r.valid_from === "string";
1786
+ }
1787
+ function mapRowsToPricing(rows) {
1788
+ const out = [];
1789
+ for (const row of rows) {
1790
+ if (!isPricingRow(row)) continue;
1791
+ out.push({
1792
+ modelId: row.model_id,
1793
+ costInputPer1m: row.cost_input_per_1m,
1794
+ costOutputPer1m: row.cost_output_per_1m,
1795
+ cacheInputPer1m: row.cache_input_per_1m ?? void 0,
1796
+ cacheCreationPer1m: row.cache_creation_per_1m ?? void 0,
1797
+ validFrom: Date.parse(row.valid_from),
1798
+ validUntil: row.valid_until == null ? void 0 : Date.parse(row.valid_until),
1799
+ source: row.source ?? void 0
1800
+ });
1801
+ }
1802
+ return out;
1803
+ }
1804
+ function bundledPricing() {
1805
+ const out = [];
1806
+ for (const profile of allProfiles()) {
1807
+ out.push({
1808
+ modelId: profile.id,
1809
+ costInputPer1m: profile.costInputPer1m,
1810
+ costOutputPer1m: profile.costOutputPer1m,
1811
+ cacheInputPer1m: profile.lowering.cache.discount !== void 0 && profile.lowering.cache.discount > 0 ? profile.costInputPer1m * profile.lowering.cache.discount : void 0,
1812
+ validFrom: 0,
1813
+ validUntil: void 0,
1814
+ source: "profile_seed"
1815
+ });
1816
+ }
1817
+ return out;
1818
+ }
1819
+ var loadPricingFromBrain = createBrainQueryCache({
1820
+ table: "kgauto_pricing",
1821
+ mapRows: mapRowsToPricing,
1822
+ bundledFallback: bundledPricing
1823
+ });
1824
+ function resolvePricingAt(modelId, at = /* @__PURE__ */ new Date()) {
1825
+ const ts = at.getTime();
1826
+ const all = loadPricingFromBrain();
1827
+ let best;
1828
+ for (const row of all) {
1829
+ if (row.modelId !== modelId) continue;
1830
+ if (row.validFrom > ts) continue;
1831
+ if (row.validUntil !== void 0 && row.validUntil <= ts) continue;
1832
+ if (!best || row.validFrom > best.validFrom) best = row;
1833
+ }
1834
+ return best;
1835
+ }
1836
+
1686
1837
  // src/brain.ts
1687
1838
  var activeConfig;
1688
1839
  function configureBrain(config) {
1689
1840
  const endpoint = config.endpoint.replace(/\/outcomes\/?$/, "");
1690
1841
  activeConfig = { ...config, endpoint };
1842
+ const bq = config.brainQuery ?? {};
1843
+ const enabledTables = /* @__PURE__ */ new Set();
1844
+ if (bq.chains !== false) enabledTables.add("kgauto_chains");
1845
+ if (bq.perf !== false) enabledTables.add("kgauto_archetype_perf");
1846
+ if (bq.pricing !== false) enabledTables.add("kgauto_pricing");
1847
+ if (bq.models !== false) {
1848
+ enabledTables.add("kgauto_models");
1849
+ enabledTables.add("kgauto_aliases");
1850
+ }
1851
+ if (enabledTables.size === 0) {
1852
+ configureBrainQuery(void 0);
1853
+ return;
1854
+ }
1855
+ configureBrainQuery({
1856
+ endpoint,
1857
+ configEndpoint: bq.configEndpoint,
1858
+ ttlMs: bq.cacheTtlMs ?? 3e5,
1859
+ fetchImpl: config.fetchImpl ?? fetch,
1860
+ enabledTables,
1861
+ onError: config.onError
1862
+ });
1691
1863
  }
1692
1864
  function clearBrain() {
1693
1865
  activeConfig = void 0;
1866
+ configureBrainQuery(void 0);
1694
1867
  }
1695
1868
  var compileRegistry = /* @__PURE__ */ new Map();
1696
1869
  var REGISTRY_MAX_ENTRIES = 1e4;
@@ -1755,7 +1928,7 @@ async function record(input) {
1755
1928
  throw new Error(`brain ${res.status}: ${text}`);
1756
1929
  }
1757
1930
  } catch (err) {
1758
- (config.onError ?? defaultOnError)(err);
1931
+ (config.onError ?? defaultOnError2)(err);
1759
1932
  }
1760
1933
  };
1761
1934
  if (config.sync) {
@@ -1764,7 +1937,7 @@ async function record(input) {
1764
1937
  void send();
1765
1938
  }
1766
1939
  }
1767
- function defaultOnError(err) {
1940
+ function defaultOnError2(err) {
1768
1941
  console.warn("[kgauto] brain record failed:", err);
1769
1942
  }
1770
1943
  function buildPayload(input, reg) {
@@ -1808,6 +1981,12 @@ function buildPayload(input, reg) {
1808
1981
  }
1809
1982
  function computeCostUsd(modelId, tokensIn, tokensOut) {
1810
1983
  if (tokensIn === 0 && tokensOut === 0) return void 0;
1984
+ const brainRow = resolvePricingAt(modelId);
1985
+ if (brainRow && (brainRow.costInputPer1m > 0 || brainRow.costOutputPer1m > 0)) {
1986
+ const inUsd2 = tokensIn / 1e6 * brainRow.costInputPer1m;
1987
+ const outUsd2 = tokensOut / 1e6 * brainRow.costOutputPer1m;
1988
+ return Math.round((inUsd2 + outUsd2) * 1e6) / 1e6;
1989
+ }
1811
1990
  const profile = tryGetProfile(modelId);
1812
1991
  if (!profile) return void 0;
1813
1992
  const inUsd = tokensIn / 1e6 * profile.costInputPer1m;
@@ -2390,6 +2569,37 @@ function clamp(n) {
2390
2569
  return Math.max(0, Math.min(1, n));
2391
2570
  }
2392
2571
 
2572
+ // src/chains-brain.ts
2573
+ function isChainsRow(x) {
2574
+ if (!x || typeof x !== "object") return false;
2575
+ const r = x;
2576
+ return typeof r.archetype === "string" && typeof r.tier === "number" && typeof r.model_id === "string";
2577
+ }
2578
+ function mapRowsToChains(rows) {
2579
+ const grouped = /* @__PURE__ */ new Map();
2580
+ for (const row of rows) {
2581
+ if (!isChainsRow(row)) continue;
2582
+ const list = grouped.get(row.archetype) ?? [];
2583
+ list.push(row);
2584
+ grouped.set(row.archetype, list);
2585
+ }
2586
+ const out = {};
2587
+ for (const [archetype, group] of grouped.entries()) {
2588
+ group.sort((a, b) => a.tier - b.tier);
2589
+ out[archetype] = group.map((r) => r.model_id);
2590
+ }
2591
+ const bundled = getAllStarterChains();
2592
+ for (const archetype of Object.keys(bundled)) {
2593
+ if (!out[archetype]) out[archetype] = bundled[archetype];
2594
+ }
2595
+ return out;
2596
+ }
2597
+ var loadChainsFromBrain = createBrainQueryCache({
2598
+ table: "kgauto_chains",
2599
+ mapRows: mapRowsToChains,
2600
+ bundledFallback: getAllStarterChains
2601
+ });
2602
+
2393
2603
  // src/fallback.ts
2394
2604
  var STARTER_CHAINS = {
2395
2605
  // Reasoning floor — never degrade. Walk UP on 429 to Opus → cross-provider.
@@ -2467,10 +2677,11 @@ function getDefaultFallbackChain(opts) {
2467
2677
  `getDefaultFallbackChain: maxDepth must be >= 1, got ${maxDepth}`
2468
2678
  );
2469
2679
  }
2470
- const starter = STARTER_CHAINS[archetype];
2680
+ const allChains = loadChainsFromBrain();
2681
+ const starter = allChains[archetype];
2471
2682
  if (!starter) {
2472
2683
  throw new Error(
2473
- `getDefaultFallbackChain: unknown archetype "${archetype}". Known: ${Object.keys(STARTER_CHAINS).join(", ")}`
2684
+ `getDefaultFallbackChain: unknown archetype "${archetype}". Known: ${Object.keys(allChains).join(", ")}`
2474
2685
  );
2475
2686
  }
2476
2687
  let chain;
@@ -2514,6 +2725,124 @@ function getAllStarterChains() {
2514
2725
  return out;
2515
2726
  }
2516
2727
 
2728
+ // src/archetype-perf-brain.ts
2729
+ function isPerfRow(x) {
2730
+ if (!x || typeof x !== "object") return false;
2731
+ const r = x;
2732
+ return typeof r.model_id === "string" && typeof r.archetype === "string" && typeof r.perf_score === "number";
2733
+ }
2734
+ function mapRowsToPerfMap(rows) {
2735
+ const out = /* @__PURE__ */ new Map();
2736
+ for (const row of rows) {
2737
+ if (!isPerfRow(row)) continue;
2738
+ const existing = out.get(row.model_id) ?? {};
2739
+ existing[row.archetype] = row.perf_score;
2740
+ out.set(row.model_id, existing);
2741
+ }
2742
+ return out;
2743
+ }
2744
+ function bundledArchetypePerf() {
2745
+ const out = /* @__PURE__ */ new Map();
2746
+ for (const profile of allProfiles()) {
2747
+ if (profile.archetypePerf) out.set(profile.id, profile.archetypePerf);
2748
+ }
2749
+ return out;
2750
+ }
2751
+ var loadArchetypePerfFromBrain = createBrainQueryCache({
2752
+ table: "kgauto_archetype_perf",
2753
+ mapRows: mapRowsToPerfMap,
2754
+ bundledFallback: bundledArchetypePerf
2755
+ });
2756
+ function getArchetypePerfScore(modelId, archetype) {
2757
+ return loadArchetypePerfFromBrain().get(modelId)?.[archetype] ?? 5;
2758
+ }
2759
+
2760
+ // src/models-brain.ts
2761
+ function isModelRow(x) {
2762
+ if (!x || typeof x !== "object") return false;
2763
+ const r = x;
2764
+ return typeof r.model_id === "string" && typeof r.provider === "string";
2765
+ }
2766
+ function isAliasRow(x) {
2767
+ if (!x || typeof x !== "object") return false;
2768
+ const r = x;
2769
+ return typeof r.alias_id === "string" && typeof r.canonical_id === "string";
2770
+ }
2771
+ function rowToProfile(row) {
2772
+ try {
2773
+ if (row.cliffs !== void 0 && row.cliffs !== null && !Array.isArray(row.cliffs)) {
2774
+ return null;
2775
+ }
2776
+ if (row.recovery !== void 0 && row.recovery !== null && !Array.isArray(row.recovery)) {
2777
+ return null;
2778
+ }
2779
+ if (row.lowering !== void 0 && row.lowering !== null && (typeof row.lowering !== "object" || Array.isArray(row.lowering))) {
2780
+ return null;
2781
+ }
2782
+ return {
2783
+ id: row.model_id,
2784
+ provider: row.provider,
2785
+ status: row.status ?? "current",
2786
+ maxContextTokens: row.max_context_tokens ?? 0,
2787
+ maxOutputTokens: row.max_output_tokens ?? 0,
2788
+ maxTools: row.max_tools ?? 0,
2789
+ parallelToolCalls: row.parallel_tool_calls ?? false,
2790
+ structuredOutput: row.structured_output ?? "none",
2791
+ systemPromptMode: row.system_prompt_mode ?? "inline",
2792
+ streaming: row.streaming ?? true,
2793
+ cliffs: row.cliffs ?? [],
2794
+ costInputPer1m: row.cost_input_per_1m ?? 0,
2795
+ costOutputPer1m: row.cost_output_per_1m ?? 0,
2796
+ lowering: row.lowering ?? { system: { mode: "inline" }, cache: { strategy: "unsupported" } },
2797
+ recovery: row.recovery ?? [],
2798
+ strengths: row.strengths ?? [],
2799
+ weaknesses: row.weaknesses ?? [],
2800
+ notes: row.notes ?? void 0,
2801
+ verifiedAgainstDocs: row.verified_against_docs ?? void 0,
2802
+ archetypePerf: row.archetype_perf ?? void 0
2803
+ };
2804
+ } catch {
2805
+ return null;
2806
+ }
2807
+ }
2808
+ function mapRowsToModels(rows) {
2809
+ const out = /* @__PURE__ */ new Map();
2810
+ for (const row of rows) {
2811
+ if (!isModelRow(row)) continue;
2812
+ const profile = rowToProfile(row);
2813
+ if (profile) out.set(profile.id, profile);
2814
+ }
2815
+ return out;
2816
+ }
2817
+ function mapRowsToAliases(rows) {
2818
+ const out = {};
2819
+ for (const row of rows) {
2820
+ if (!isAliasRow(row)) continue;
2821
+ out[row.alias_id] = row.canonical_id;
2822
+ }
2823
+ return out;
2824
+ }
2825
+ function bundledModels() {
2826
+ return new Map(allProfilesRaw().map((p) => [p.id, p]));
2827
+ }
2828
+ function bundledAliases() {
2829
+ return { ...ALIASES };
2830
+ }
2831
+ var loadModelsFromBrain = createBrainQueryCache({
2832
+ table: "kgauto_models",
2833
+ mapRows: mapRowsToModels,
2834
+ bundledFallback: bundledModels
2835
+ });
2836
+ var loadAliasesFromBrain = createBrainQueryCache({
2837
+ table: "kgauto_aliases",
2838
+ mapRows: mapRowsToAliases,
2839
+ bundledFallback: bundledAliases
2840
+ });
2841
+ _setProfileBrainHook({
2842
+ getProfile: (canonical) => loadModelsFromBrain().get(canonical),
2843
+ resolveAlias: (id) => loadAliasesFromBrain()[id]
2844
+ });
2845
+
2517
2846
  // src/index.ts
2518
2847
  function compile2(ir, opts) {
2519
2848
  const result = compile(ir, opts);
@@ -2540,6 +2869,7 @@ function compile2(ir, opts) {
2540
2869
  countTokens,
2541
2870
  execute,
2542
2871
  getAllStarterChains,
2872
+ getArchetypePerfScore,
2543
2873
  getDefaultFallbackChain,
2544
2874
  getProfile,
2545
2875
  getReachabilityDiagnostic,
@@ -2549,9 +2879,15 @@ function compile2(ir, opts) {
2549
2879
  isModelReachable,
2550
2880
  isProviderReachable,
2551
2881
  learningKey,
2882
+ loadAliasesFromBrain,
2883
+ loadArchetypePerfFromBrain,
2884
+ loadChainsFromBrain,
2885
+ loadModelsFromBrain,
2886
+ loadPricingFromBrain,
2552
2887
  profilesByProvider,
2553
2888
  record,
2554
2889
  resetTokenizer,
2890
+ resolvePricingAt,
2555
2891
  resolveProviderKey,
2556
2892
  runAdvisor,
2557
2893
  setTokenizer,