nexus-agents 4.23.0 → 4.26.3

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.
Files changed (132) hide show
  1. package/dist/{child-mcp-config-FEK2HK5L.js → child-mcp-config-TUGS6R7G.js} +2 -2
  2. package/dist/{chunk-MSHZHT5X.js → chunk-4Z7HJXDZ.js} +2 -2
  3. package/dist/{chunk-LLGK3NRY.js → chunk-5UGFRPRO.js} +2 -2
  4. package/dist/{chunk-K2DSQJEH.js → chunk-72QXEEC3.js} +6 -6
  5. package/dist/{chunk-OYFKB64X.js → chunk-7GWPLERY.js} +200 -131
  6. package/dist/chunk-7GWPLERY.js.map +1 -0
  7. package/dist/{chunk-NMFXYX7R.js → chunk-7POSQDHD.js} +2 -2
  8. package/dist/chunk-BAXVGVEV.js +7 -0
  9. package/dist/chunk-BAXVGVEV.js.map +1 -0
  10. package/dist/{chunk-3SMGCYGN.js → chunk-BAYBBQKK.js} +2 -2
  11. package/dist/{chunk-R3H46BNY.js → chunk-BQC3QOHD.js} +2 -2
  12. package/dist/{chunk-XQEWXGJ5.js → chunk-COOYB7X3.js} +47 -17
  13. package/dist/chunk-COOYB7X3.js.map +1 -0
  14. package/dist/{chunk-K7RASYIZ.js → chunk-EYBUDKXP.js} +3 -3
  15. package/dist/{chunk-YFDE4AM3.js → chunk-GQDKGV34.js} +7 -7
  16. package/dist/{chunk-EPZCODRK.js → chunk-HCI3SOTV.js} +15 -8
  17. package/dist/chunk-HCI3SOTV.js.map +1 -0
  18. package/dist/{chunk-PUGRS4KW.js → chunk-IFSLM46W.js} +10 -5
  19. package/dist/chunk-IFSLM46W.js.map +1 -0
  20. package/dist/{chunk-LMTBX4GZ.js → chunk-IIQZ77BJ.js} +2 -2
  21. package/dist/{chunk-GGQOP4VK.js → chunk-IWGOE6JT.js} +5 -5
  22. package/dist/{chunk-IC6WLIGJ.js → chunk-JBOKMCJB.js} +4 -4
  23. package/dist/{chunk-HPGPOZG4.js → chunk-K3UKVFL4.js} +5 -5
  24. package/dist/{chunk-LMENHZQ6.js → chunk-KUNQLRUR.js} +4 -4
  25. package/dist/{chunk-2FYFHAI4.js → chunk-MLX4CMGD.js} +2 -2
  26. package/dist/{chunk-AWMXPIMK.js → chunk-MMN77SDX.js} +2 -2
  27. package/dist/{chunk-5KKJKQVE.js → chunk-NSKEVAK2.js} +2 -2
  28. package/dist/{chunk-LSJ2EPOF.js → chunk-OGVHWFYR.js} +17 -4
  29. package/dist/chunk-OGVHWFYR.js.map +1 -0
  30. package/dist/{chunk-32IMMUXP.js → chunk-PHGT3XKE.js} +2 -2
  31. package/dist/{chunk-K2A24T36.js → chunk-QQFPLIJ4.js} +2 -2
  32. package/dist/{chunk-2MPJ7UDR.js → chunk-QQKT5X2M.js} +99 -56
  33. package/dist/chunk-QQKT5X2M.js.map +1 -0
  34. package/dist/{chunk-YVW743K3.js → chunk-RDJWMBUQ.js} +2 -2
  35. package/dist/{chunk-GVLMTQ46.js → chunk-RNOT2H4K.js} +3 -3
  36. package/dist/{chunk-ADC7YEU2.js → chunk-SLDESHM5.js} +90 -43
  37. package/dist/chunk-SLDESHM5.js.map +1 -0
  38. package/dist/{chunk-Z37OVF33.js → chunk-TG5SQK44.js} +2 -2
  39. package/dist/{chunk-EYQUQ2PZ.js → chunk-UBEH2VOU.js} +2 -2
  40. package/dist/{chunk-TXCJMTLN.js → chunk-UDK2A7TX.js} +9 -10
  41. package/dist/chunk-UDK2A7TX.js.map +1 -0
  42. package/dist/{chunk-WJGTRYWS.js → chunk-VFBNMNDY.js} +2 -2
  43. package/dist/{chunk-CMZGRDKF.js → chunk-ZIUPKCRD.js} +2 -2
  44. package/dist/{cli-circuit-breaker-VUWP2GRN.js → cli-circuit-breaker-5PGGNAXR.js} +3 -3
  45. package/dist/cli.js +49 -51
  46. package/dist/cli.js.map +1 -1
  47. package/dist/{composite-router-4F3ZVLJV.js → composite-router-S2YRQVR2.js} +2 -2
  48. package/dist/{consensus-vote-ETJ63JRC.js → consensus-vote-D3ALVGKQ.js} +17 -16
  49. package/dist/{context-retriever-L2LTCKV6.js → context-retriever-G3UORDWI.js} +8 -8
  50. package/dist/{doctor-deep-HPBHFGBZ.js → doctor-deep-QERHI4YH.js} +3 -3
  51. package/dist/{doctor-live-NQ35PQ5B.js → doctor-live-6LCPVDTF.js} +9 -9
  52. package/dist/{expert-bridge-XN5MFZOG.js → expert-bridge-I4VMWOAZ.js} +4 -4
  53. package/dist/{factory-2TJ44P7L.js → factory-4WA3SMPI.js} +5 -5
  54. package/dist/{factory-GVBBWUOE.js → factory-KHYFJ7SI.js} +9 -9
  55. package/dist/{improvement-review-7VJYOI2F.js → improvement-review-DNKRLYEA.js} +6 -5
  56. package/dist/index.d.ts +113 -3
  57. package/dist/index.js +33 -31
  58. package/dist/index.js.map +1 -1
  59. package/dist/{init-opencode-TLVVMG54.js → init-opencode-R4IXHVBI.js} +6 -6
  60. package/dist/issue-triage-MWEG22WT.js +17 -0
  61. package/dist/{pr-reviewer-helpers-4ERCFSZ7.js → pr-reviewer-helpers-P4RCRFEU.js} +4 -4
  62. package/dist/{registry-command-GN2REQQP.js → registry-command-BTVFJEOS.js} +2 -2
  63. package/dist/{repo-security-plan-VPAXEENC.js → repo-security-plan-3KI6NNJ4.js} +3 -3
  64. package/dist/{research-helpers-synthesize-OZOOIEFW.js → research-helpers-synthesize-EY764EKA.js} +4 -4
  65. package/dist/{routing-memory-OF7J3OE4.js → routing-memory-UVFPT6FL.js} +2 -2
  66. package/dist/{session-memory-O5M3CLRX.js → session-memory-VAMUQSGC.js} +3 -3
  67. package/dist/{setup-config-WW5BNLVS.js → setup-config-H426VPM7.js} +3 -3
  68. package/dist/{setup-custom-api-UX4XNOT6.js → setup-custom-api-RFFSTRMT.js} +4 -4
  69. package/dist/setup-data-dir-RZ4KCZR7.js +29 -0
  70. package/dist/{tool-memory-PIBTMGPH.js → tool-memory-PDK7HIEG.js} +5 -5
  71. package/dist/{unified-registry-MUXCSSG5.js → unified-registry-CLZZ46D5.js} +10 -10
  72. package/dist/{weather-report-JOATSJWU.js → weather-report-YZBDIZSV.js} +2 -2
  73. package/package.json +1 -1
  74. package/dist/chunk-2MPJ7UDR.js.map +0 -1
  75. package/dist/chunk-ADC7YEU2.js.map +0 -1
  76. package/dist/chunk-EPZCODRK.js.map +0 -1
  77. package/dist/chunk-LSJ2EPOF.js.map +0 -1
  78. package/dist/chunk-OYFKB64X.js.map +0 -1
  79. package/dist/chunk-PUGRS4KW.js.map +0 -1
  80. package/dist/chunk-TXCJMTLN.js.map +0 -1
  81. package/dist/chunk-XQEWXGJ5.js.map +0 -1
  82. package/dist/issue-triage-YREC36AC.js +0 -17
  83. package/dist/setup-data-dir-KHLK534F.js +0 -28
  84. /package/dist/{child-mcp-config-FEK2HK5L.js.map → child-mcp-config-TUGS6R7G.js.map} +0 -0
  85. /package/dist/{chunk-MSHZHT5X.js.map → chunk-4Z7HJXDZ.js.map} +0 -0
  86. /package/dist/{chunk-LLGK3NRY.js.map → chunk-5UGFRPRO.js.map} +0 -0
  87. /package/dist/{chunk-K2DSQJEH.js.map → chunk-72QXEEC3.js.map} +0 -0
  88. /package/dist/{chunk-NMFXYX7R.js.map → chunk-7POSQDHD.js.map} +0 -0
  89. /package/dist/{chunk-3SMGCYGN.js.map → chunk-BAYBBQKK.js.map} +0 -0
  90. /package/dist/{chunk-R3H46BNY.js.map → chunk-BQC3QOHD.js.map} +0 -0
  91. /package/dist/{chunk-K7RASYIZ.js.map → chunk-EYBUDKXP.js.map} +0 -0
  92. /package/dist/{chunk-YFDE4AM3.js.map → chunk-GQDKGV34.js.map} +0 -0
  93. /package/dist/{chunk-LMTBX4GZ.js.map → chunk-IIQZ77BJ.js.map} +0 -0
  94. /package/dist/{chunk-GGQOP4VK.js.map → chunk-IWGOE6JT.js.map} +0 -0
  95. /package/dist/{chunk-IC6WLIGJ.js.map → chunk-JBOKMCJB.js.map} +0 -0
  96. /package/dist/{chunk-HPGPOZG4.js.map → chunk-K3UKVFL4.js.map} +0 -0
  97. /package/dist/{chunk-LMENHZQ6.js.map → chunk-KUNQLRUR.js.map} +0 -0
  98. /package/dist/{chunk-2FYFHAI4.js.map → chunk-MLX4CMGD.js.map} +0 -0
  99. /package/dist/{chunk-AWMXPIMK.js.map → chunk-MMN77SDX.js.map} +0 -0
  100. /package/dist/{chunk-5KKJKQVE.js.map → chunk-NSKEVAK2.js.map} +0 -0
  101. /package/dist/{chunk-32IMMUXP.js.map → chunk-PHGT3XKE.js.map} +0 -0
  102. /package/dist/{chunk-K2A24T36.js.map → chunk-QQFPLIJ4.js.map} +0 -0
  103. /package/dist/{chunk-YVW743K3.js.map → chunk-RDJWMBUQ.js.map} +0 -0
  104. /package/dist/{chunk-GVLMTQ46.js.map → chunk-RNOT2H4K.js.map} +0 -0
  105. /package/dist/{chunk-Z37OVF33.js.map → chunk-TG5SQK44.js.map} +0 -0
  106. /package/dist/{chunk-EYQUQ2PZ.js.map → chunk-UBEH2VOU.js.map} +0 -0
  107. /package/dist/{chunk-WJGTRYWS.js.map → chunk-VFBNMNDY.js.map} +0 -0
  108. /package/dist/{chunk-CMZGRDKF.js.map → chunk-ZIUPKCRD.js.map} +0 -0
  109. /package/dist/{cli-circuit-breaker-VUWP2GRN.js.map → cli-circuit-breaker-5PGGNAXR.js.map} +0 -0
  110. /package/dist/{composite-router-4F3ZVLJV.js.map → composite-router-S2YRQVR2.js.map} +0 -0
  111. /package/dist/{consensus-vote-ETJ63JRC.js.map → consensus-vote-D3ALVGKQ.js.map} +0 -0
  112. /package/dist/{context-retriever-L2LTCKV6.js.map → context-retriever-G3UORDWI.js.map} +0 -0
  113. /package/dist/{doctor-deep-HPBHFGBZ.js.map → doctor-deep-QERHI4YH.js.map} +0 -0
  114. /package/dist/{doctor-live-NQ35PQ5B.js.map → doctor-live-6LCPVDTF.js.map} +0 -0
  115. /package/dist/{expert-bridge-XN5MFZOG.js.map → expert-bridge-I4VMWOAZ.js.map} +0 -0
  116. /package/dist/{factory-2TJ44P7L.js.map → factory-4WA3SMPI.js.map} +0 -0
  117. /package/dist/{factory-GVBBWUOE.js.map → factory-KHYFJ7SI.js.map} +0 -0
  118. /package/dist/{improvement-review-7VJYOI2F.js.map → improvement-review-DNKRLYEA.js.map} +0 -0
  119. /package/dist/{init-opencode-TLVVMG54.js.map → init-opencode-R4IXHVBI.js.map} +0 -0
  120. /package/dist/{issue-triage-YREC36AC.js.map → issue-triage-MWEG22WT.js.map} +0 -0
  121. /package/dist/{pr-reviewer-helpers-4ERCFSZ7.js.map → pr-reviewer-helpers-P4RCRFEU.js.map} +0 -0
  122. /package/dist/{registry-command-GN2REQQP.js.map → registry-command-BTVFJEOS.js.map} +0 -0
  123. /package/dist/{repo-security-plan-VPAXEENC.js.map → repo-security-plan-3KI6NNJ4.js.map} +0 -0
  124. /package/dist/{research-helpers-synthesize-OZOOIEFW.js.map → research-helpers-synthesize-EY764EKA.js.map} +0 -0
  125. /package/dist/{routing-memory-OF7J3OE4.js.map → routing-memory-UVFPT6FL.js.map} +0 -0
  126. /package/dist/{session-memory-O5M3CLRX.js.map → session-memory-VAMUQSGC.js.map} +0 -0
  127. /package/dist/{setup-config-WW5BNLVS.js.map → setup-config-H426VPM7.js.map} +0 -0
  128. /package/dist/{setup-custom-api-UX4XNOT6.js.map → setup-custom-api-RFFSTRMT.js.map} +0 -0
  129. /package/dist/{setup-data-dir-KHLK534F.js.map → setup-data-dir-RZ4KCZR7.js.map} +0 -0
  130. /package/dist/{tool-memory-PIBTMGPH.js.map → tool-memory-PDK7HIEG.js.map} +0 -0
  131. /package/dist/{unified-registry-MUXCSSG5.js.map → unified-registry-CLZZ46D5.js.map} +0 -0
  132. /package/dist/{weather-report-JOATSJWU.js.map → weather-report-YZBDIZSV.js.map} +0 -0
@@ -2174,14 +2174,14 @@ var ManifestSchema = z2.object({
2174
2174
  models: z2.array(z2.unknown())
2175
2175
  });
2176
2176
  function loadManifestOverlay(options) {
2177
- const logger15 = options?.logger ?? createLogger({ component: "manifest-overlay" });
2177
+ const logger14 = options?.logger ?? createLogger({ component: "manifest-overlay" });
2178
2178
  if (options?.path !== void 0) {
2179
- return loadManifestFile(options.path, logger15);
2179
+ return loadManifestFile(options.path, logger14);
2180
2180
  }
2181
2181
  const userPath = resolveUserManifestPath(options?.env);
2182
2182
  const operatorPath = resolveManifestPath(options?.env);
2183
- const user = loadManifestFile(userPath, logger15);
2184
- const operator = loadManifestFile(operatorPath, logger15);
2183
+ const user = loadManifestFile(userPath, logger14);
2184
+ const operator = loadManifestFile(operatorPath, logger14);
2185
2185
  return mergeOverlays(user, operator);
2186
2186
  }
2187
2187
  function mergeOverlays(lower, higher) {
@@ -2198,11 +2198,11 @@ function mergeOverlays(lower, higher) {
2198
2198
  return merged;
2199
2199
  }
2200
2200
  function loadUserManifestOverlay(options) {
2201
- const logger15 = options?.logger ?? createLogger({ component: "manifest-overlay" });
2201
+ const logger14 = options?.logger ?? createLogger({ component: "manifest-overlay" });
2202
2202
  const path2 = options?.path ?? resolveUserManifestPath(options?.env);
2203
- return loadManifestFile(path2, logger15);
2203
+ return loadManifestFile(path2, logger14);
2204
2204
  }
2205
- function loadManifestFile(path2, logger15) {
2205
+ function loadManifestFile(path2, logger14) {
2206
2206
  let exists = false;
2207
2207
  try {
2208
2208
  exists = existsSync(path2);
@@ -2217,7 +2217,7 @@ function loadManifestFile(path2, logger15) {
2217
2217
  return { entries: [], rejections: [], path: path2, status: "empty" };
2218
2218
  }
2219
2219
  if (stat.size > MANIFEST_MAX_BYTES) {
2220
- logger15.warn("Manifest overlay too large; skipping", {
2220
+ logger14.warn("Manifest overlay too large; skipping", {
2221
2221
  path: path2,
2222
2222
  size: stat.size,
2223
2223
  max: MANIFEST_MAX_BYTES
@@ -2225,9 +2225,9 @@ function loadManifestFile(path2, logger15) {
2225
2225
  return { entries: [], rejections: [], path: path2, status: "too-large" };
2226
2226
  }
2227
2227
  const raw = readFileSync(path2, "utf-8");
2228
- return parseManifest(raw, path2, logger15);
2228
+ return parseManifest(raw, path2, logger14);
2229
2229
  }
2230
- function parseManifest(raw, path2, logger15) {
2230
+ function parseManifest(raw, path2, logger14) {
2231
2231
  let parsed;
2232
2232
  try {
2233
2233
  if (path2.endsWith(".json")) {
@@ -2236,7 +2236,7 @@ function parseManifest(raw, path2, logger15) {
2236
2236
  parsed = parseYaml(raw);
2237
2237
  }
2238
2238
  } catch (e) {
2239
- logger15.warn("Manifest overlay parse failure; skipping", {
2239
+ logger14.warn("Manifest overlay parse failure; skipping", {
2240
2240
  path: path2,
2241
2241
  error: e instanceof Error ? e.message : String(e)
2242
2242
  });
@@ -2244,7 +2244,7 @@ function parseManifest(raw, path2, logger15) {
2244
2244
  }
2245
2245
  const shape = ManifestSchema.safeParse(parsed);
2246
2246
  if (!shape.success) {
2247
- logger15.warn("Manifest overlay schema mismatch at root; skipping", {
2247
+ logger14.warn("Manifest overlay schema mismatch at root; skipping", {
2248
2248
  path: path2,
2249
2249
  issues: shape.error.issues.slice(0, 5).map((i) => i.message)
2250
2250
  });
@@ -2319,7 +2319,7 @@ function defaultSnapshotPath() {
2319
2319
  return join(here, "models-dev-snapshot.json");
2320
2320
  }
2321
2321
  function loadModelsDevSnapshot(options) {
2322
- const logger15 = createLogger({ component: "models-dev-snapshot" });
2322
+ const logger14 = createLogger({ component: "models-dev-snapshot" });
2323
2323
  const path2 = options?.path ?? defaultSnapshotPath();
2324
2324
  let exists = false;
2325
2325
  try {
@@ -2334,21 +2334,21 @@ function loadModelsDevSnapshot(options) {
2334
2334
  try {
2335
2335
  parsed = JSON.parse(readFileSync2(path2, "utf-8"));
2336
2336
  } catch (e) {
2337
- logger15.warn("models.dev snapshot parse failure; skipping", {
2337
+ logger14.warn("models.dev snapshot parse failure; skipping", {
2338
2338
  path: path2,
2339
2339
  error: e instanceof Error ? e.message : String(e)
2340
2340
  });
2341
2341
  return { entries: [], path: path2, status: "malformed" };
2342
2342
  }
2343
2343
  if (parsed.version !== 1) {
2344
- logger15.warn("models.dev snapshot version unsupported; skipping", {
2344
+ logger14.warn("models.dev snapshot version unsupported; skipping", {
2345
2345
  path: path2,
2346
2346
  version: parsed.version
2347
2347
  });
2348
2348
  return { entries: [], path: path2, status: "malformed" };
2349
2349
  }
2350
2350
  if (!Array.isArray(parsed.entries)) {
2351
- logger15.warn("models.dev snapshot missing entries array; skipping", { path: path2 });
2351
+ logger14.warn("models.dev snapshot missing entries array; skipping", { path: path2 });
2352
2352
  return { entries: [], path: path2, status: "malformed" };
2353
2353
  }
2354
2354
  const entries = parsed.entries;
@@ -2395,7 +2395,7 @@ function toModelEntry(rec) {
2395
2395
  };
2396
2396
  }
2397
2397
  function loadGeneratedRegistryEntries(options) {
2398
- const logger15 = createLogger({ component: "models-generated" });
2398
+ const logger14 = createLogger({ component: "models-generated" });
2399
2399
  const path2 = options?.path ?? defaultGeneratedPath();
2400
2400
  let exists = false;
2401
2401
  try {
@@ -2408,14 +2408,14 @@ function loadGeneratedRegistryEntries(options) {
2408
2408
  try {
2409
2409
  parsed = JSON.parse(readFileSync3(path2, "utf-8"));
2410
2410
  } catch (e) {
2411
- logger15.warn("generated registry parse failure; skipping", {
2411
+ logger14.warn("generated registry parse failure; skipping", {
2412
2412
  path: path2,
2413
2413
  error: e instanceof Error ? e.message : String(e)
2414
2414
  });
2415
2415
  return { entries: [], path: path2, status: "malformed" };
2416
2416
  }
2417
2417
  if (!Array.isArray(parsed.entries)) {
2418
- logger15.warn("generated registry missing entries array; skipping", { path: path2 });
2418
+ logger14.warn("generated registry missing entries array; skipping", { path: path2 });
2419
2419
  return { entries: [], path: path2, status: "malformed" };
2420
2420
  }
2421
2421
  const entries = [];
@@ -2623,7 +2623,7 @@ function setDefaultRegistry(registry) {
2623
2623
  }
2624
2624
  async function reloadDefaultRegistry() {
2625
2625
  globalRegistry = buildDefaultRegistry();
2626
- const { resetGlobalRegistry } = await import("./unified-registry-MUXCSSG5.js");
2626
+ const { resetGlobalRegistry } = await import("./unified-registry-CLZZ46D5.js");
2627
2627
  resetGlobalRegistry();
2628
2628
  return globalRegistry;
2629
2629
  }
@@ -5477,6 +5477,60 @@ function estimateCost(model, inputTokens, outputTokens) {
5477
5477
  return inputCost + outputCost;
5478
5478
  }
5479
5479
 
5480
+ // src/cli-adapters/budget-router-types.ts
5481
+ import { z as z6 } from "zod";
5482
+ var BudgetConstraintSchema = z6.object({
5483
+ maxTokens: z6.number().int().positive().optional(),
5484
+ maxCostUSD: z6.number().positive().optional(),
5485
+ maxLatencyMs: z6.number().positive().optional()
5486
+ });
5487
+ var SessionBudgetSchema = z6.object({
5488
+ totalTokens: z6.number().int().positive(),
5489
+ totalCostUSD: z6.number().positive(),
5490
+ usedTokens: z6.number().int().min(0).default(0),
5491
+ usedCostUSD: z6.number().min(0).default(0),
5492
+ startTime: z6.number().int().positive(),
5493
+ sessionId: z6.string().min(1)
5494
+ });
5495
+ var DEFAULT_COST_MODELS = {
5496
+ claude: {
5497
+ inputTokenCost: 0.015,
5498
+ outputTokenCost: 0.075,
5499
+ avgLatencyMs: 2e3,
5500
+ qualityScore: 0.95
5501
+ },
5502
+ gemini: {
5503
+ inputTokenCost: 125e-5,
5504
+ outputTokenCost: 5e-3,
5505
+ avgLatencyMs: 1500,
5506
+ qualityScore: 0.85
5507
+ },
5508
+ codex: {
5509
+ inputTokenCost: 3e-3,
5510
+ outputTokenCost: 0.015,
5511
+ avgLatencyMs: 1e3,
5512
+ qualityScore: 0.8
5513
+ },
5514
+ opencode: {
5515
+ inputTokenCost: 3e-3,
5516
+ outputTokenCost: 0.012,
5517
+ avgLatencyMs: 1500,
5518
+ qualityScore: 0.82
5519
+ }
5520
+ };
5521
+ var DEFAULT_LINUCB_CONFIG = {
5522
+ numArms: 4,
5523
+ featureDim: 6,
5524
+ alpha: 1,
5525
+ lambda: 1
5526
+ };
5527
+ var LinUCBConfigSchema = z6.object({
5528
+ numArms: z6.number().int().positive().default(4),
5529
+ featureDim: z6.number().int().positive().default(6),
5530
+ alpha: z6.number().positive().default(1),
5531
+ lambda: z6.number().positive().default(1)
5532
+ });
5533
+
5480
5534
  // src/cli-adapters/budget-warnings.ts
5481
5535
  function getWarningLevel(utilization, thresholds) {
5482
5536
  if (utilization >= thresholds.critical) return "critical";
@@ -5539,6 +5593,20 @@ function generateBudgetWarnings(currentBudget, estimatedTokens, estimatedCostUsd
5539
5593
  }
5540
5594
 
5541
5595
  // src/cli-adapters/budget-errors.ts
5596
+ function fastestCandidateLatencyMs() {
5597
+ const values = Object.values(DEFAULT_COST_MODELS).map((m) => m.avgLatencyMs);
5598
+ return values.length === 0 ? 0 : Math.min(...values);
5599
+ }
5600
+ function latencyExceeded(budget, result) {
5601
+ if (budget.maxLatencyMs === void 0) return void 0;
5602
+ if (result.adapter !== null || result.estimatedLatencyMs !== void 0) return void 0;
5603
+ return {
5604
+ constraint: "latency",
5605
+ limit: budget.maxLatencyMs,
5606
+ current: fastestCandidateLatencyMs(),
5607
+ suggestion: "Raise the latency budget or add a faster model"
5608
+ };
5609
+ }
5542
5610
  function determineExceededConstraint(budget, result, currentBudget) {
5543
5611
  if (budget.maxTokens !== void 0 && result.estimatedTokens > budget.maxTokens) {
5544
5612
  return {
@@ -5556,6 +5624,8 @@ function determineExceededConstraint(budget, result, currentBudget) {
5556
5624
  suggestion: "Use a cheaper model or increase cost budget"
5557
5625
  };
5558
5626
  }
5627
+ const latencyViolation = latencyExceeded(budget, result);
5628
+ if (latencyViolation !== void 0) return latencyViolation;
5559
5629
  if (currentBudget.tokensRemaining < result.estimatedTokens) {
5560
5630
  return {
5561
5631
  constraint: "tokens",
@@ -5590,7 +5660,7 @@ function createBudgetExceededError(budget, result, currentBudget) {
5590
5660
  }
5591
5661
 
5592
5662
  // src/config/task-specialization-types.ts
5593
- import { z as z6 } from "zod";
5663
+ import { z as z7 } from "zod";
5594
5664
  var TASK_CATEGORIES = [
5595
5665
  "architecture",
5596
5666
  "code_generation",
@@ -5603,8 +5673,8 @@ var TASK_CATEGORIES = [
5603
5673
  "devops",
5604
5674
  "exploration"
5605
5675
  ];
5606
- var TaskCategorySchema = z6.enum(TASK_CATEGORIES);
5607
- var TaskSpecializationSchema = z6.object({
5676
+ var TaskCategorySchema = z7.enum(TASK_CATEGORIES);
5677
+ var TaskSpecializationSchema = z7.object({
5608
5678
  /** Task category identifier */
5609
5679
  category: TaskCategorySchema,
5610
5680
  /** Primary CLI recommendation */
@@ -5612,11 +5682,11 @@ var TaskSpecializationSchema = z6.object({
5612
5682
  /** Secondary CLI fallback */
5613
5683
  secondaryCli: CliNameSchema,
5614
5684
  /** Why this CLI is preferred for this task type */
5615
- reasoning: z6.string(),
5685
+ reasoning: z7.string(),
5616
5686
  /** Keywords that trigger this category detection */
5617
- keywords: z6.array(z6.string()).min(1),
5687
+ keywords: z7.array(z7.string()).min(1),
5618
5688
  /** Bonus score applied when this category matches (0-20) */
5619
- bonus: z6.number().min(0).max(20)
5689
+ bonus: z7.number().min(0).max(20)
5620
5690
  });
5621
5691
 
5622
5692
  // src/config/task-specialization.ts
@@ -5809,6 +5879,9 @@ function estimateRegistryCostUsd(slot, inputTokens, outputTokens) {
5809
5879
  if (pricing === void 0) return void 0;
5810
5880
  return inputTokens / 1e6 * pricing.inputPer1M + outputTokens / 1e6 * pricing.outputPer1M;
5811
5881
  }
5882
+ function latencyOf(slot) {
5883
+ return DEFAULT_COST_MODELS[slot]?.avgLatencyMs;
5884
+ }
5812
5885
  var BudgetRouter = class {
5813
5886
  adapters;
5814
5887
  options;
@@ -5892,8 +5965,9 @@ var BudgetRouter = class {
5892
5965
  const estimatedTokens = estimatedInputTokens + estimatedOutputTokens;
5893
5966
  const adapter = this.selectAdapterWithinBudget(budget, estimatedTokens);
5894
5967
  const estimatedCostUsd = adapter ? estimateCost(adapter.name, estimatedInputTokens, estimatedOutputTokens) : 0;
5968
+ const estimatedLatencyMs = adapter === null ? void 0 : latencyOf(routingArmDisplaySlot(adapter.name));
5895
5969
  const currentBudget = this.getSessionBudget();
5896
- const withinBudget = this.checkConstraints(budget, estimatedTokens, estimatedCostUsd);
5970
+ const withinBudget = adapter !== null && this.checkConstraints(budget, estimatedTokens, estimatedCostUsd);
5897
5971
  const warnings = generateBudgetWarnings(
5898
5972
  currentBudget,
5899
5973
  estimatedTokens,
@@ -5906,6 +5980,7 @@ var BudgetRouter = class {
5906
5980
  withinBudget,
5907
5981
  estimatedCostUsd,
5908
5982
  estimatedTokens,
5983
+ ...estimatedLatencyMs !== void 0 ? { estimatedLatencyMs } : {},
5909
5984
  warnings,
5910
5985
  projectedBudget
5911
5986
  };
@@ -6060,7 +6135,8 @@ var BudgetRouter = class {
6060
6135
  const withinTokenBudget = budget.maxTokens === void 0 || estimatedTokens <= budget.maxTokens;
6061
6136
  const withinCostBudget = budget.maxCostUsd === void 0 || estimatedCost <= budget.maxCostUsd;
6062
6137
  const withinContextWindow = estimatedTokens <= caps.contextWindow;
6063
- if (withinTokenBudget && withinCostBudget && withinContextWindow) {
6138
+ const withinLatencyBudget = budget.maxLatencyMs === void 0 || latencyOf(slot) === void 0 || latencyOf(slot) <= budget.maxLatencyMs;
6139
+ if (withinTokenBudget && withinCostBudget && withinContextWindow && withinLatencyBudget) {
6064
6140
  return adapter;
6065
6141
  }
6066
6142
  }
@@ -6269,9 +6345,9 @@ var DEFAULT_OUTPUT_TOKENS = 500;
6269
6345
  var TopsisRouter = class {
6270
6346
  config;
6271
6347
  logger;
6272
- constructor(config = {}, logger15) {
6348
+ constructor(config = {}, logger14) {
6273
6349
  this.config = { ...DEFAULT_TOPSIS_CONFIG, ...config };
6274
- this.logger = logger15 ?? createLogger({ component: "TopsisRouter" });
6350
+ this.logger = logger14 ?? createLogger({ component: "TopsisRouter" });
6275
6351
  this.validateWeights();
6276
6352
  }
6277
6353
  /**
@@ -6451,34 +6527,6 @@ var TopsisRouter = class {
6451
6527
  }
6452
6528
  };
6453
6529
 
6454
- // src/cli-adapters/budget-router-types.ts
6455
- import { z as z7 } from "zod";
6456
- var BudgetConstraintSchema = z7.object({
6457
- maxTokens: z7.number().int().positive().optional(),
6458
- maxCostUSD: z7.number().positive().optional(),
6459
- maxLatencyMs: z7.number().positive().optional()
6460
- });
6461
- var SessionBudgetSchema = z7.object({
6462
- totalTokens: z7.number().int().positive(),
6463
- totalCostUSD: z7.number().positive(),
6464
- usedTokens: z7.number().int().min(0).default(0),
6465
- usedCostUSD: z7.number().min(0).default(0),
6466
- startTime: z7.number().int().positive(),
6467
- sessionId: z7.string().min(1)
6468
- });
6469
- var DEFAULT_LINUCB_CONFIG = {
6470
- numArms: 4,
6471
- featureDim: 6,
6472
- alpha: 1,
6473
- lambda: 1
6474
- };
6475
- var LinUCBConfigSchema = z7.object({
6476
- numArms: z7.number().int().positive().default(4),
6477
- featureDim: z7.number().int().positive().default(6),
6478
- alpha: z7.number().positive().default(1),
6479
- lambda: z7.number().positive().default(1)
6480
- });
6481
-
6482
6530
  // src/cli-adapters/warm-start-skips.ts
6483
6531
  var UNATTRIBUTED_ARM = "unknown";
6484
6532
  function partitionWarmStartSkips(skipped) {
@@ -7827,9 +7875,9 @@ var ZeroRouter = class {
7827
7875
  logger;
7828
7876
  outcomes = [];
7829
7877
  calibrationBias = 0;
7830
- constructor(config, logger15) {
7878
+ constructor(config, logger14) {
7831
7879
  this.config = ZeroRouterConfigSchema.parse(config ?? {});
7832
- this.logger = logger15 ?? createLogger({ component: "ZeroRouter" });
7880
+ this.logger = logger14 ?? createLogger({ component: "ZeroRouter" });
7833
7881
  this.logger.debug("ZeroRouter initialized", {
7834
7882
  thresholds: this.config.thresholds,
7835
7883
  enableCalibration: this.config.enableCalibration
@@ -8340,9 +8388,9 @@ var ConfidenceCascadeStage = class {
8340
8388
  routingsCount = 0;
8341
8389
  escalationCount = 0;
8342
8390
  complexityDistribution = { simple: 0, moderate: 0, complex: 0 };
8343
- constructor(config = {}, logger15) {
8391
+ constructor(config = {}, logger14) {
8344
8392
  this.config = { ...DEFAULT_CONFIG, ...config };
8345
- this.logger = logger15 ?? createLogger({ component: "ConfidenceCascadeStage" });
8393
+ this.logger = logger14 ?? createLogger({ component: "ConfidenceCascadeStage" });
8346
8394
  }
8347
8395
  canHandle(ctx) {
8348
8396
  return getRemainingCandidates(ctx).length > 0;
@@ -8504,9 +8552,9 @@ var CapabilityMatchStage = class {
8504
8552
  creative: 0,
8505
8553
  general: 0
8506
8554
  };
8507
- constructor(config = {}, logger15) {
8555
+ constructor(config = {}, logger14) {
8508
8556
  this.config = { ...DEFAULT_CONFIG2, ...config };
8509
- this.logger = logger15 ?? createLogger({ component: "CapabilityMatchStage" });
8557
+ this.logger = logger14 ?? createLogger({ component: "CapabilityMatchStage" });
8510
8558
  }
8511
8559
  canHandle(ctx) {
8512
8560
  return getRemainingCandidates(ctx).length > 0;
@@ -8662,9 +8710,9 @@ var QualityConstraintStage = class {
8662
8710
  filteredCount = 0;
8663
8711
  fallbackCount = 0;
8664
8712
  constraintViolations = { quality: 0, cost: 0, latency: 0 };
8665
- constructor(config = {}, logger15) {
8713
+ constructor(config = {}, logger14) {
8666
8714
  this.config = { ...DEFAULT_CONFIG3, ...config };
8667
- this.logger = logger15 ?? createLogger({ component: "QualityConstraintStage" });
8715
+ this.logger = logger14 ?? createLogger({ component: "QualityConstraintStage" });
8668
8716
  }
8669
8717
  canHandle(ctx) {
8670
8718
  return getRemainingCandidates(ctx).length > 0;
@@ -8862,9 +8910,9 @@ var ResourceStrategyStage = class {
8862
8910
  logger;
8863
8911
  routingsCount = 0;
8864
8912
  tierHistory = [];
8865
- constructor(config = {}, logger15) {
8913
+ constructor(config = {}, logger14) {
8866
8914
  this.config = { ...DEFAULT_CONFIG4, ...config };
8867
- this.logger = logger15 ?? createLogger({ component: "ResourceStrategyStage" });
8915
+ this.logger = logger14 ?? createLogger({ component: "ResourceStrategyStage" });
8868
8916
  }
8869
8917
  canHandle(ctx) {
8870
8918
  return getRemainingCandidates(ctx).length > 1;
@@ -8973,10 +9021,10 @@ var DistilledRuleStage = class {
8973
9021
  config;
8974
9022
  logger;
8975
9023
  rulesAppliedCount = 0;
8976
- constructor(distiller, config, logger15) {
9024
+ constructor(distiller, config, logger14) {
8977
9025
  this.distiller = distiller;
8978
9026
  this.config = { ...DEFAULT_CONFIG5, ...config };
8979
- this.logger = logger15 ?? createLogger({ component: "DistilledRuleStage" });
9027
+ this.logger = logger14 ?? createLogger({ component: "DistilledRuleStage" });
8980
9028
  }
8981
9029
  canHandle(ctx) {
8982
9030
  const candidates = getRemainingCandidates(ctx);
@@ -9019,15 +9067,23 @@ var DistilledRuleStage = class {
9019
9067
  let applied = 0;
9020
9068
  for (const cli of candidates) {
9021
9069
  const matchingRules = this.findMatchingRules(activeRules, cli, category);
9070
+ if (matchingRules.length === 0) continue;
9071
+ const raw = matchingRules.reduce((sum, rule) => sum + this.computeDelta(rule), 0);
9072
+ const capped = Math.min(this.config.boostDelta, Math.max(this.config.avoidDelta, raw));
9073
+ updated = updateScore(updated, cli, capped);
9022
9074
  for (const rule of matchingRules) {
9023
- const delta = this.computeDelta(rule);
9024
- updated = updateScore(updated, cli, delta);
9025
9075
  updated = {
9026
9076
  ...updated,
9027
9077
  signals: [...updated.signals, `distilled-rule:applied=${rule.id}`]
9028
9078
  };
9029
9079
  applied++;
9030
9080
  }
9081
+ if (capped !== raw) {
9082
+ updated = {
9083
+ ...updated,
9084
+ signals: [...updated.signals, `distilled-rule:capped=${cli}`]
9085
+ };
9086
+ }
9031
9087
  }
9032
9088
  this.rulesAppliedCount += applied;
9033
9089
  const elapsed = getTimeProvider().now() - start;
@@ -9111,10 +9167,10 @@ var KnnRoutingStage = class {
9111
9167
  memory;
9112
9168
  routingsCount = 0;
9113
9169
  matchCount = 0;
9114
- constructor(memory, config = {}, logger15) {
9170
+ constructor(memory, config = {}, logger14) {
9115
9171
  this.config = { ...DEFAULT_CONFIG6, ...config };
9116
9172
  this.memory = memory;
9117
- this.logger = logger15 ?? createLogger({ component: "KnnRoutingStage" });
9173
+ this.logger = logger14 ?? createLogger({ component: "KnnRoutingStage" });
9118
9174
  }
9119
9175
  canHandle(ctx) {
9120
9176
  return getRemainingCandidates(ctx).length > 0;
@@ -9248,10 +9304,10 @@ var CapacityFilterStage = class {
9248
9304
  unmeasuredCount = 0;
9249
9305
  /** Candidates whose own rolling window was full (#4456). Never excluded. */
9250
9306
  throttledCount = 0;
9251
- constructor(adapters, config = {}, logger15) {
9307
+ constructor(adapters, config = {}, logger14) {
9252
9308
  this.adapters = adapters;
9253
9309
  this.config = { ...DEFAULT_CONFIG7, ...config };
9254
- this.logger = logger15 ?? createLogger({ component: "CapacityFilterStage" });
9310
+ this.logger = logger14 ?? createLogger({ component: "CapacityFilterStage" });
9255
9311
  }
9256
9312
  canHandle(ctx) {
9257
9313
  return getRemainingCandidates(ctx).length > 0;
@@ -9289,6 +9345,10 @@ var CapacityFilterStage = class {
9289
9345
  }
9290
9346
  getStats() {
9291
9347
  return {
9348
+ // #4658: `excludedCount` can only be zero while enforcement is off, so
9349
+ // reporting it alone presents a default as a measurement. `enforced`
9350
+ // says which of the two a zero is.
9351
+ enforced: this.config.enforceHardLimits,
9292
9352
  excludedCount: this.excludedCount,
9293
9353
  unmeasuredCount: this.unmeasuredCount,
9294
9354
  throttledCount: this.throttledCount
@@ -9580,10 +9640,10 @@ var StrategyDistiller = class {
9580
9640
  rules = /* @__PURE__ */ new Map();
9581
9641
  outcomeCounter = 0;
9582
9642
  lastDistillAt;
9583
- constructor(outcomeStore, logger15, config) {
9643
+ constructor(outcomeStore, logger14, config) {
9584
9644
  this.outcomeStore = outcomeStore;
9585
9645
  this.config = { ...DEFAULT_DISTILLER_CONFIG, ...config };
9586
- this.logger = logger15 ?? createLogger({ component: "StrategyDistiller" });
9646
+ this.logger = logger14 ?? createLogger({ component: "StrategyDistiller" });
9587
9647
  }
9588
9648
  /** Called for each processed outcome. Triggers distillation at threshold. */
9589
9649
  onOutcome() {
@@ -9749,18 +9809,18 @@ var StrategyDistiller = class {
9749
9809
  };
9750
9810
  }
9751
9811
  };
9752
- function createStrategyDistiller(outcomeStore, logger15, config) {
9753
- return new StrategyDistiller(outcomeStore, logger15, config);
9812
+ function createStrategyDistiller(outcomeStore, logger14, config) {
9813
+ return new StrategyDistiller(outcomeStore, logger14, config);
9754
9814
  }
9755
9815
  var persistentDistillerFactory;
9756
9816
  function registerPersistentDistillerFactory(factory) {
9757
9817
  persistentDistillerFactory = factory;
9758
9818
  }
9759
- function createPersistentDistillerOrFallback(outcomeStore, logger15) {
9819
+ function createPersistentDistillerOrFallback(outcomeStore, logger14) {
9760
9820
  if (persistentDistillerFactory !== void 0) {
9761
- return persistentDistillerFactory(outcomeStore, logger15);
9821
+ return persistentDistillerFactory(outcomeStore, logger14);
9762
9822
  }
9763
- return new StrategyDistiller(outcomeStore, logger15);
9823
+ return new StrategyDistiller(outcomeStore, logger14);
9764
9824
  }
9765
9825
 
9766
9826
  // src/orchestration/outcomes/outcome-types.ts
@@ -10444,8 +10504,8 @@ function generateSyntheticPriors() {
10444
10504
  }
10445
10505
  return priors;
10446
10506
  }
10447
- function runWarmUp(logger15) {
10448
- const log = logger15 ?? createLogger({ component: "warm-up" });
10507
+ function runWarmUp(logger14) {
10508
+ const log = logger14 ?? createLogger({ component: "warm-up" });
10449
10509
  const store = getOutcomeStore();
10450
10510
  const existing = store.query();
10451
10511
  const hasSynthetic = existing.some((o) => o.qualitySignals?.includes(SYNTHETIC_MARKER) === true);
@@ -14424,7 +14484,7 @@ function parseCatalog(text) {
14424
14484
  (m) => m.supported_parameters === void 0 ? { id: m.id } : { id: m.id, supportedParameters: m.supported_parameters }
14425
14485
  );
14426
14486
  }
14427
- async function fetchCatalog(url, timeoutMs, doFetch) {
14487
+ async function fetchCatalogOrThrow(url, timeoutMs, doFetch) {
14428
14488
  const controller = new AbortController();
14429
14489
  const timer = setTimeout(() => {
14430
14490
  controller.abort();
@@ -14435,26 +14495,15 @@ async function fetchCatalog(url, timeoutMs, doFetch) {
14435
14495
  headers: { accept: "application/json" }
14436
14496
  });
14437
14497
  if (!res.ok) {
14438
- logger12.warn("OpenRouter catalog fetch returned non-OK; treating as empty", {
14439
- status: res.status
14440
- });
14441
- return [];
14498
+ throw new Error(`OpenRouter catalog fetch returned HTTP ${String(res.status)}`);
14442
14499
  }
14443
14500
  const declaredLen = res.headers.get("content-length");
14444
14501
  if (declaredLen !== null && Number(declaredLen) > MAX_BYTES) {
14445
- logger12.warn("OpenRouter catalog Content-Length exceeds byte cap; ignoring", {
14446
- bytes: declaredLen
14447
- });
14448
- return [];
14502
+ throw new Error(`OpenRouter catalog Content-Length ${declaredLen} exceeds the byte cap`);
14449
14503
  }
14450
14504
  const ids = parseCatalog(await res.text());
14451
14505
  logger12.debug("OpenRouter catalog loaded", { count: ids.length });
14452
14506
  return ids;
14453
- } catch (error) {
14454
- logger12.warn("OpenRouter catalog fetch failed; treating as empty", {
14455
- error: error instanceof Error ? error.message : String(error)
14456
- });
14457
- return [];
14458
14507
  } finally {
14459
14508
  clearTimeout(timer);
14460
14509
  }
@@ -14466,12 +14515,13 @@ function createOpenRouterModelsSource(opts = {}) {
14466
14515
  return {
14467
14516
  name: "openrouter",
14468
14517
  providerHint: "openrouter",
14469
- listModels: () => fetchCatalog(url, timeoutMs, doFetch)
14518
+ // Throws on probe failure so the cache can tell it apart from an empty
14519
+ // catalog (#5059).
14520
+ listModels: () => fetchCatalogOrThrow(url, timeoutMs, doFetch)
14470
14521
  };
14471
14522
  }
14472
14523
 
14473
14524
  // src/config/register-model-sources.ts
14474
- var logger13 = createLogger({ component: "register-model-sources" });
14475
14525
  function isDynamicModelsEnabled() {
14476
14526
  return process.env["NEXUS_DYNAMIC_MODELS"] === "true";
14477
14527
  }
@@ -14481,13 +14531,7 @@ function hasListModels(adapter) {
14481
14531
  function adapterSource(cliName, adapter) {
14482
14532
  return {
14483
14533
  name: cliName,
14484
- listModels: () => adapter.listModels().then((models) => models.map((m) => ({ id: m.id }))).catch((error) => {
14485
- logger13.debug("adapter listModels failed; treating as empty", {
14486
- cli: cliName,
14487
- error: error instanceof Error ? error.message : String(error)
14488
- });
14489
- return [];
14490
- })
14534
+ listModels: () => adapter.listModels().then((models) => models.map((m) => ({ id: m.id })))
14491
14535
  };
14492
14536
  }
14493
14537
  function buildDefaultModelSources(adapters, opts = {}) {
@@ -14681,14 +14725,14 @@ function evaluateModelSelectionReadiness(records, config = DEFAULT_MODEL_SELECTI
14681
14725
  return { ready: blockers.length === 0, criteria, blockers };
14682
14726
  }
14683
14727
  var readinessLogged = false;
14684
- function logModelSelectionReadinessOnce(logger15) {
14728
+ function logModelSelectionReadinessOnce(logger14) {
14685
14729
  if (readinessLogged) return;
14686
14730
  readinessLogged = true;
14687
14731
  try {
14688
14732
  const records = readModelSelectionShadowRecords();
14689
14733
  const summary = summarizeModelSelectionShadow(records);
14690
14734
  const verdict = evaluateModelSelectionReadiness(records);
14691
- logger15.info("route-model-selection shadow readiness", {
14735
+ logger14.info("route-model-selection shadow readiness", {
14692
14736
  ready: verdict.ready,
14693
14737
  blockers: verdict.blockers,
14694
14738
  total: summary.total,
@@ -14700,7 +14744,7 @@ function logModelSelectionReadinessOnce(logger15) {
14700
14744
  meanCostUsd: summary.meanCostUsd
14701
14745
  });
14702
14746
  } catch (err2) {
14703
- logger15.warn("route-model-selection readiness signal failed (non-fatal)", {
14747
+ logger14.warn("route-model-selection readiness signal failed (non-fatal)", {
14704
14748
  error: getErrorMessage(err2)
14705
14749
  });
14706
14750
  }
@@ -14931,7 +14975,7 @@ var CompositeRouter = class _CompositeRouter {
14931
14975
  * The task content itself is never persisted.
14932
14976
  */
14933
14977
  pendingModelShadow;
14934
- constructor(adapters, config, logger15) {
14978
+ constructor(adapters, config, logger14) {
14935
14979
  const {
14936
14980
  preferenceRouterConfig,
14937
14981
  zeroRouterConfig,
@@ -14942,22 +14986,17 @@ var CompositeRouter = class _CompositeRouter {
14942
14986
  qualityConstraintConfig,
14943
14987
  resourceStrategyConfig,
14944
14988
  distilledRuleStageConfig,
14989
+ capacityStageConfig,
14945
14990
  metricsCollector,
14946
14991
  orchestrationObserver,
14947
14992
  availableModelsCache,
14948
14993
  ...baseConfig
14949
14994
  } = config ?? {};
14950
14995
  this.config = CompositeRouterConfigSchema.parse(baseConfig);
14951
- this.logger = logger15 ?? createLogger({ component: "CompositeRouter" });
14996
+ this.logger = logger14 ?? createLogger({ component: "CompositeRouter" });
14952
14997
  this.adapters = adapters;
14953
14998
  this.cliNames = Array.from(adapters.keys());
14954
- if (metricsCollector !== void 0) {
14955
- this.metricsCollector = metricsCollector;
14956
- }
14957
- if (orchestrationObserver !== void 0) {
14958
- this.orchestrationObserver = orchestrationObserver;
14959
- this.logger.debug("OrchestrationObserver wired to CompositeRouter");
14960
- }
14999
+ this.assignOptionalCollaborators(metricsCollector, orchestrationObserver);
14961
15000
  if (availableModelsCache !== void 0) {
14962
15001
  this.availableModelsCache = availableModelsCache;
14963
15002
  this.logger.debug("AvailableModelsCache wired to CompositeRouter");
@@ -14973,10 +15012,25 @@ var CompositeRouter = class _CompositeRouter {
14973
15012
  capabilityMatch: capabilityMatchConfig,
14974
15013
  qualityConstraint: qualityConstraintConfig,
14975
15014
  resourceStrategy: resourceStrategyConfig,
14976
- distilledRule: distilledRuleStageConfig
15015
+ distilledRule: distilledRuleStageConfig,
15016
+ capacity: capacityStageConfig
14977
15017
  });
14978
15018
  this.logInitialization(adapters.size);
14979
15019
  }
15020
+ /**
15021
+ * Optional collaborators, assigned only when supplied so an absent one stays
15022
+ * `undefined` rather than being stored as a null-ish value. Extracted from
15023
+ * the constructor to keep it under the function-length bar (#4658).
15024
+ */
15025
+ assignOptionalCollaborators(metricsCollector, orchestrationObserver) {
15026
+ if (metricsCollector !== void 0) {
15027
+ this.metricsCollector = metricsCollector;
15028
+ }
15029
+ if (orchestrationObserver !== void 0) {
15030
+ this.orchestrationObserver = orchestrationObserver;
15031
+ this.logger.debug("OrchestrationObserver wired to CompositeRouter");
15032
+ }
15033
+ }
14980
15034
  initializeCoreRouters(adapters, preferenceConfig, zeroConfig, latencyConfig) {
14981
15035
  if (this.config.enableBudgetFilter && adapters.size > 0) {
14982
15036
  this.budgetRouter = this.buildBudgetRouter(adapters);
@@ -15023,7 +15077,11 @@ var CompositeRouter = class _CompositeRouter {
15023
15077
  this.resourceStrategyStage = new ResourceStrategyStage(stageConfigs.resourceStrategy);
15024
15078
  }
15025
15079
  if (this.config.enableCapacityBalancing) {
15026
- this.capacityFilterStage = new CapacityFilterStage(this.adapters, {}, this.logger);
15080
+ this.capacityFilterStage = new CapacityFilterStage(
15081
+ this.adapters,
15082
+ stageConfigs.capacity ?? {},
15083
+ this.logger
15084
+ );
15027
15085
  }
15028
15086
  if (this.config.enableStrategyDistillation) {
15029
15087
  this.strategyDistiller = isPersistenceEnabled() ? createPersistentDistillerOrFallback(getOutcomeStore(), this.logger) : new StrategyDistiller(getOutcomeStore(), this.logger);
@@ -15118,7 +15176,7 @@ var CompositeRouter = class _CompositeRouter {
15118
15176
  */
15119
15177
  async consultUnifiedContext(task) {
15120
15178
  try {
15121
- const { getContextForTask, inferTaskCategory } = await import("./context-retriever-L2LTCKV6.js");
15179
+ const { getContextForTask, inferTaskCategory } = await import("./context-retriever-G3UORDWI.js");
15122
15180
  const ctx = await getContextForTask({
15123
15181
  task: task.content,
15124
15182
  category: inferTaskCategory(task.content),
@@ -15544,7 +15602,8 @@ var CompositeRouter = class _CompositeRouter {
15544
15602
  budgetRejectionRate: this.totalDecisions > 0 ? this.budgetRejections / this.totalDecisions : 0,
15545
15603
  banditStats: this.linucbBandit?.getStats() ?? [],
15546
15604
  latencyStats,
15547
- routingMemoryStats
15605
+ routingMemoryStats,
15606
+ ...capacityStatsOf(this.capacityFilterStage)
15548
15607
  };
15549
15608
  if (preferenceStats !== void 0) {
15550
15609
  return { ...baseStats, preferenceStats };
@@ -15556,14 +15615,24 @@ var CompositeRouter = class _CompositeRouter {
15556
15615
  return this.routingMemory;
15557
15616
  }
15558
15617
  };
15559
- function createCompositeRouter(adapters, config, logger15) {
15618
+ function createCompositeRouter(adapters, config, logger14) {
15560
15619
  let resolved = config;
15561
15620
  if (isDynamicModelsEnabled() && config?.availableModelsCache === void 0) {
15562
15621
  const cache = getDefaultAvailableModelsCache();
15563
15622
  registerDefaultModelSources(cache, adapters);
15564
15623
  resolved = { ...config, availableModelsCache: cache };
15565
15624
  }
15566
- return new CompositeRouter(adapters, resolved, logger15);
15625
+ return new CompositeRouter(adapters, resolved, logger14);
15626
+ }
15627
+ function capacityStatsOf(stage) {
15628
+ if (stage === void 0) return {};
15629
+ const stats = stage.getStats();
15630
+ return {
15631
+ capacityStats: {
15632
+ enforced: stats["enforced"] === true,
15633
+ excludedCount: typeof stats["excludedCount"] === "number" ? stats["excludedCount"] : 0
15634
+ }
15635
+ };
15567
15636
  }
15568
15637
 
15569
15638
  // src/core/types/model.ts
@@ -16093,7 +16162,7 @@ var ActionCacheImpl = class {
16093
16162
  };
16094
16163
 
16095
16164
  // src/context/mobimem.ts
16096
- var logger14 = createLogger({ component: "MobiMem" });
16165
+ var logger13 = createLogger({ component: "MobiMem" });
16097
16166
  var MobiMem = class {
16098
16167
  profile;
16099
16168
  experience;
@@ -16114,7 +16183,7 @@ var MobiMem = class {
16114
16183
  this.profile = new ProfileMemoryImpl(this.config, this.db);
16115
16184
  this.experience = new ExperienceMemoryImpl(this.config, this.db);
16116
16185
  this.action = new ActionCacheImpl(this.config, this.db);
16117
- logger14.info("MobiMem initialized", {
16186
+ logger13.info("MobiMem initialized", {
16118
16187
  dbPath: validated.dbPath,
16119
16188
  persisted: this.db !== null,
16120
16189
  maxProfileEntries: this.config.maxProfileEntries,
@@ -16147,13 +16216,13 @@ var MobiMem = class {
16147
16216
  if (this.config.autoEviction) {
16148
16217
  const evicted = this.action.evictExpired();
16149
16218
  if (evicted > 0) {
16150
- logger14.debug("Evicted expired action cache entries", { count: evicted });
16219
+ logger13.debug("Evicted expired action cache entries", { count: evicted });
16151
16220
  }
16152
16221
  }
16153
16222
  }
16154
16223
  close() {
16155
16224
  if (this.db !== null) this.db.close();
16156
- logger14.info("MobiMem closed");
16225
+ logger13.info("MobiMem closed");
16157
16226
  }
16158
16227
  };
16159
16228
  var sharedInstance = null;
@@ -16711,4 +16780,4 @@ export {
16711
16780
  AgentCapability,
16712
16781
  OrchestratorError
16713
16782
  };
16714
- //# sourceMappingURL=chunk-OYFKB64X.js.map
16783
+ //# sourceMappingURL=chunk-7GWPLERY.js.map