nexus-agents 2.105.0 → 2.106.0

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 (119) hide show
  1. package/dist/{child-mcp-config-XOIMNU6R.js → child-mcp-config-KP2XBOIB.js} +2 -2
  2. package/dist/{chunk-WDVUKSIQ.js → chunk-2DHISFDY.js} +90 -49
  3. package/dist/chunk-2DHISFDY.js.map +1 -0
  4. package/dist/{chunk-FVJ2LM2G.js → chunk-2J6HSR6X.js} +2 -2
  5. package/dist/{chunk-BMM6OX2K.js → chunk-3YWBA5GE.js} +7 -7
  6. package/dist/{chunk-46GXDOWQ.js → chunk-5UU6BQJ3.js} +2 -2
  7. package/dist/{chunk-M54LGBTY.js → chunk-75NKH2VD.js} +4 -4
  8. package/dist/{chunk-ETGNZ6H2.js → chunk-BEWKRRNZ.js} +2 -2
  9. package/dist/{chunk-I5QZ3PVT.js → chunk-BJQA6DSN.js} +2 -2
  10. package/dist/{chunk-WT46JLBD.js → chunk-CNIRLXNH.js} +3 -3
  11. package/dist/{chunk-TFRXRKU5.js → chunk-CUX775NF.js} +4 -4
  12. package/dist/{chunk-UFTQXDUA.js → chunk-DLFJQ6W6.js} +2 -2
  13. package/dist/{chunk-I7UDM43R.js → chunk-DOIOSEDU.js} +118 -4
  14. package/dist/chunk-DOIOSEDU.js.map +1 -0
  15. package/dist/{chunk-2B7332HE.js → chunk-E3JGMUGY.js} +4 -4
  16. package/dist/{chunk-IFO52GSQ.js → chunk-EBJJGYOQ.js} +3 -3
  17. package/dist/{chunk-VIHUOFIT.js → chunk-GMHCPEHS.js} +1418 -176
  18. package/dist/chunk-GMHCPEHS.js.map +1 -0
  19. package/dist/{chunk-MKSP4M55.js → chunk-GRHCGUBQ.js} +9 -1034
  20. package/dist/chunk-GRHCGUBQ.js.map +1 -0
  21. package/dist/{chunk-FTFFYAY6.js → chunk-HNBA265P.js} +39 -37
  22. package/dist/{chunk-FTFFYAY6.js.map → chunk-HNBA265P.js.map} +1 -1
  23. package/dist/{chunk-ABNHZEKO.js → chunk-KMASI7UC.js} +2 -2
  24. package/dist/{chunk-XWOLOXKN.js → chunk-KZWJ52HH.js} +2 -2
  25. package/dist/{chunk-A5UJBVCQ.js → chunk-M6JRWJZW.js} +2 -2
  26. package/dist/{chunk-RZ4A2RRN.js → chunk-MYXT7VPF.js} +2 -2
  27. package/dist/{chunk-7RE2S46N.js → chunk-OP4VPTQZ.js} +3 -3
  28. package/dist/{chunk-P5XUYJBO.js → chunk-PRPHNXUM.js} +3 -3
  29. package/dist/{chunk-75BXDWVG.js → chunk-R2VTDJO5.js} +5 -5
  30. package/dist/{chunk-OESO6AQL.js → chunk-RWAI74H6.js} +9 -9
  31. package/dist/{chunk-VCLQMXVJ.js → chunk-SFIGDPAE.js} +3 -3
  32. package/dist/{chunk-3TZUEGNB.js → chunk-U3Y6AWG5.js} +2 -2
  33. package/dist/{chunk-VGHPMNDR.js → chunk-VHIRBRZF.js} +2 -2
  34. package/dist/{chunk-PGSXRUH5.js → chunk-VIXH6P3Y.js} +3 -3
  35. package/dist/{chunk-E6FIVDNH.js → chunk-WPF7G56I.js} +2 -2
  36. package/dist/{chunk-K7OKFTCH.js → chunk-YL7SS6JZ.js} +2 -2
  37. package/dist/{cli-circuit-breaker-QMCG6JGV.js → cli-circuit-breaker-PE3AYA56.js} +4 -4
  38. package/dist/cli.js +42 -42
  39. package/dist/cli.js.map +1 -1
  40. package/dist/{composite-router-ZX64CEVG.js → composite-router-GXLSZZQU.js} +2 -2
  41. package/dist/{consensus-vote-VUNGPXXS.js → consensus-vote-ZS4IDC5T.js} +12 -13
  42. package/dist/{context-retriever-J7DIPQUO.js → context-retriever-52RLYDVE.js} +6 -6
  43. package/dist/{doctor-deep-ITSJV2RH.js → doctor-deep-3463IMLO.js} +3 -3
  44. package/dist/{expert-bridge-MQURDKJI.js → expert-bridge-OBOSFIHR.js} +4 -4
  45. package/dist/factory-SM7AIAFL.js +21 -0
  46. package/dist/{factory-Y2RF33UB.js → factory-VXD4XO7R.js} +5 -5
  47. package/dist/{improvement-review-NBVWPFXR.js → improvement-review-Y4DSR2AF.js} +4 -4
  48. package/dist/index.d.ts +36 -13
  49. package/dist/index.js +61 -63
  50. package/dist/index.js.map +1 -1
  51. package/dist/{init-opencode-QPHX4KVI.js → init-opencode-3FW2TAOR.js} +5 -5
  52. package/dist/{issue-triage-D5ADEG3V.js → issue-triage-KAVEQE5V.js} +5 -5
  53. package/dist/{pr-reviewer-helpers-R7U4EI2P.js → pr-reviewer-helpers-KORDKN6O.js} +4 -4
  54. package/dist/{registry-command-CFNNKJ5S.js → registry-command-WZK7PYVZ.js} +2 -2
  55. package/dist/{repo-security-plan-2AXFDREW.js → repo-security-plan-EO5R3S7C.js} +3 -3
  56. package/dist/{research-helpers-synthesize-YTIDNKBF.js → research-helpers-synthesize-6HFD32XJ.js} +3 -3
  57. package/dist/{routing-memory-YLX6QNY2.js → routing-memory-XPJT3Y6Z.js} +2 -2
  58. package/dist/{session-memory-Y5MUOY56.js → session-memory-TTE5YPV4.js} +3 -3
  59. package/dist/{setup-command-KTMIAEU6.js → setup-command-VVHIWCD4.js} +11 -10
  60. package/dist/{setup-config-5J3R7RET.js → setup-config-NEM4KPUA.js} +3 -3
  61. package/dist/{setup-custom-api-MJ24PJA7.js → setup-custom-api-GMMHEJJ5.js} +4 -6
  62. package/dist/{setup-custom-api-MJ24PJA7.js.map → setup-custom-api-GMMHEJJ5.js.map} +1 -1
  63. package/dist/{tool-memory-YNMRI3PZ.js → tool-memory-TTLQ7MHZ.js} +5 -5
  64. package/dist/{weather-report-GZRODMYW.js → weather-report-KGAHUQFF.js} +2 -2
  65. package/package.json +1 -1
  66. package/dist/chunk-BLMWODJG.js +0 -120
  67. package/dist/chunk-BLMWODJG.js.map +0 -1
  68. package/dist/chunk-I7UDM43R.js.map +0 -1
  69. package/dist/chunk-MKSP4M55.js.map +0 -1
  70. package/dist/chunk-VIHUOFIT.js.map +0 -1
  71. package/dist/chunk-WDVUKSIQ.js.map +0 -1
  72. package/dist/factory-UZQ3RGFQ.js +0 -19
  73. /package/dist/{child-mcp-config-XOIMNU6R.js.map → child-mcp-config-KP2XBOIB.js.map} +0 -0
  74. /package/dist/{chunk-FVJ2LM2G.js.map → chunk-2J6HSR6X.js.map} +0 -0
  75. /package/dist/{chunk-BMM6OX2K.js.map → chunk-3YWBA5GE.js.map} +0 -0
  76. /package/dist/{chunk-46GXDOWQ.js.map → chunk-5UU6BQJ3.js.map} +0 -0
  77. /package/dist/{chunk-M54LGBTY.js.map → chunk-75NKH2VD.js.map} +0 -0
  78. /package/dist/{chunk-ETGNZ6H2.js.map → chunk-BEWKRRNZ.js.map} +0 -0
  79. /package/dist/{chunk-I5QZ3PVT.js.map → chunk-BJQA6DSN.js.map} +0 -0
  80. /package/dist/{chunk-WT46JLBD.js.map → chunk-CNIRLXNH.js.map} +0 -0
  81. /package/dist/{chunk-TFRXRKU5.js.map → chunk-CUX775NF.js.map} +0 -0
  82. /package/dist/{chunk-UFTQXDUA.js.map → chunk-DLFJQ6W6.js.map} +0 -0
  83. /package/dist/{chunk-2B7332HE.js.map → chunk-E3JGMUGY.js.map} +0 -0
  84. /package/dist/{chunk-IFO52GSQ.js.map → chunk-EBJJGYOQ.js.map} +0 -0
  85. /package/dist/{chunk-ABNHZEKO.js.map → chunk-KMASI7UC.js.map} +0 -0
  86. /package/dist/{chunk-XWOLOXKN.js.map → chunk-KZWJ52HH.js.map} +0 -0
  87. /package/dist/{chunk-A5UJBVCQ.js.map → chunk-M6JRWJZW.js.map} +0 -0
  88. /package/dist/{chunk-RZ4A2RRN.js.map → chunk-MYXT7VPF.js.map} +0 -0
  89. /package/dist/{chunk-7RE2S46N.js.map → chunk-OP4VPTQZ.js.map} +0 -0
  90. /package/dist/{chunk-P5XUYJBO.js.map → chunk-PRPHNXUM.js.map} +0 -0
  91. /package/dist/{chunk-75BXDWVG.js.map → chunk-R2VTDJO5.js.map} +0 -0
  92. /package/dist/{chunk-OESO6AQL.js.map → chunk-RWAI74H6.js.map} +0 -0
  93. /package/dist/{chunk-VCLQMXVJ.js.map → chunk-SFIGDPAE.js.map} +0 -0
  94. /package/dist/{chunk-3TZUEGNB.js.map → chunk-U3Y6AWG5.js.map} +0 -0
  95. /package/dist/{chunk-VGHPMNDR.js.map → chunk-VHIRBRZF.js.map} +0 -0
  96. /package/dist/{chunk-PGSXRUH5.js.map → chunk-VIXH6P3Y.js.map} +0 -0
  97. /package/dist/{chunk-E6FIVDNH.js.map → chunk-WPF7G56I.js.map} +0 -0
  98. /package/dist/{chunk-K7OKFTCH.js.map → chunk-YL7SS6JZ.js.map} +0 -0
  99. /package/dist/{cli-circuit-breaker-QMCG6JGV.js.map → cli-circuit-breaker-PE3AYA56.js.map} +0 -0
  100. /package/dist/{composite-router-ZX64CEVG.js.map → composite-router-GXLSZZQU.js.map} +0 -0
  101. /package/dist/{consensus-vote-VUNGPXXS.js.map → consensus-vote-ZS4IDC5T.js.map} +0 -0
  102. /package/dist/{context-retriever-J7DIPQUO.js.map → context-retriever-52RLYDVE.js.map} +0 -0
  103. /package/dist/{doctor-deep-ITSJV2RH.js.map → doctor-deep-3463IMLO.js.map} +0 -0
  104. /package/dist/{expert-bridge-MQURDKJI.js.map → expert-bridge-OBOSFIHR.js.map} +0 -0
  105. /package/dist/{factory-UZQ3RGFQ.js.map → factory-SM7AIAFL.js.map} +0 -0
  106. /package/dist/{factory-Y2RF33UB.js.map → factory-VXD4XO7R.js.map} +0 -0
  107. /package/dist/{improvement-review-NBVWPFXR.js.map → improvement-review-Y4DSR2AF.js.map} +0 -0
  108. /package/dist/{init-opencode-QPHX4KVI.js.map → init-opencode-3FW2TAOR.js.map} +0 -0
  109. /package/dist/{issue-triage-D5ADEG3V.js.map → issue-triage-KAVEQE5V.js.map} +0 -0
  110. /package/dist/{pr-reviewer-helpers-R7U4EI2P.js.map → pr-reviewer-helpers-KORDKN6O.js.map} +0 -0
  111. /package/dist/{registry-command-CFNNKJ5S.js.map → registry-command-WZK7PYVZ.js.map} +0 -0
  112. /package/dist/{repo-security-plan-2AXFDREW.js.map → repo-security-plan-EO5R3S7C.js.map} +0 -0
  113. /package/dist/{research-helpers-synthesize-YTIDNKBF.js.map → research-helpers-synthesize-6HFD32XJ.js.map} +0 -0
  114. /package/dist/{routing-memory-YLX6QNY2.js.map → routing-memory-XPJT3Y6Z.js.map} +0 -0
  115. /package/dist/{session-memory-Y5MUOY56.js.map → session-memory-TTE5YPV4.js.map} +0 -0
  116. /package/dist/{setup-command-KTMIAEU6.js.map → setup-command-VVHIWCD4.js.map} +0 -0
  117. /package/dist/{setup-config-5J3R7RET.js.map → setup-config-NEM4KPUA.js.map} +0 -0
  118. /package/dist/{tool-memory-YNMRI3PZ.js.map → tool-memory-TTLQ7MHZ.js.map} +0 -0
  119. /package/dist/{weather-report-GZRODMYW.js.map → weather-report-KGAHUQFF.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createLogger
3
- } from "./chunk-WDVUKSIQ.js";
3
+ } from "./chunk-2DHISFDY.js";
4
4
  import "./chunk-CH7QIDHQ.js";
5
5
  import "./chunk-PR4QN5HX.js";
6
6
 
@@ -59,4 +59,4 @@ export {
59
59
  generateMcpConfig,
60
60
  getDefaultAllowedTools
61
61
  };
62
- //# sourceMappingURL=child-mcp-config-XOIMNU6R.js.map
62
+ //# sourceMappingURL=child-mcp-config-KP2XBOIB.js.map
@@ -4151,6 +4151,25 @@ function estimateTokens(text) {
4151
4151
  return getTokenEstimator().estimateText(text);
4152
4152
  }
4153
4153
 
4154
+ // src/cli-adapters/types-core.ts
4155
+ function apiArmId(vendor) {
4156
+ return `api:${vendor}`;
4157
+ }
4158
+ function routingArmDisplaySlot(armId) {
4159
+ switch (armId) {
4160
+ case "api:anthropic":
4161
+ return "claude";
4162
+ case "api:openai":
4163
+ return "codex";
4164
+ case "api:google":
4165
+ return "gemini";
4166
+ case "api:custom-openai":
4167
+ return "opencode";
4168
+ default:
4169
+ return armId;
4170
+ }
4171
+ }
4172
+
4154
4173
  // src/cli-adapters/types-capability.ts
4155
4174
  var CLI_VERSION_REQUIREMENTS = {
4156
4175
  claude: {
@@ -4536,13 +4555,14 @@ var BudgetRouter = class {
4536
4555
  }
4537
4556
  selectAdapterWithinBudget(budget, estimatedTokens) {
4538
4557
  const sortedAdapters = [...this.adapters].sort((a, b) => {
4539
- const capA = DEFAULT_CAPABILITIES[a[0]];
4540
- const capB = DEFAULT_CAPABILITIES[b[0]];
4558
+ const capA = DEFAULT_CAPABILITIES[routingArmDisplaySlot(a[0])];
4559
+ const capB = DEFAULT_CAPABILITIES[routingArmDisplaySlot(b[0])];
4541
4560
  return capB.cost - capA.cost;
4542
4561
  });
4543
4562
  for (const [name, adapter] of sortedAdapters) {
4544
- const estimatedCost = estimateCost(name, estimatedTokens / 2, estimatedTokens / 2);
4545
- const caps = DEFAULT_CAPABILITIES[name];
4563
+ const slot = routingArmDisplaySlot(name);
4564
+ const estimatedCost = estimateCost(slot, estimatedTokens / 2, estimatedTokens / 2);
4565
+ const caps = DEFAULT_CAPABILITIES[slot];
4546
4566
  const withinTokenBudget = budget.maxTokens === void 0 || estimatedTokens <= budget.maxTokens;
4547
4567
  const withinCostBudget = budget.maxCostUsd === void 0 || estimatedCost <= budget.maxCostUsd;
4548
4568
  const withinContextWindow = estimatedTokens <= caps.contextWindow;
@@ -8835,7 +8855,7 @@ function filterByPreferenceTier(candidates, tier) {
8835
8855
  const strongModels = ["claude"];
8836
8856
  const weakModels = ["gemini", "codex"];
8837
8857
  const preferred = tier === "strong" ? strongModels : weakModels;
8838
- const filtered = candidates.filter((c) => preferred.includes(c));
8858
+ const filtered = candidates.filter((c) => preferred.includes(routingArmDisplaySlot(c)));
8839
8859
  return filtered.length > 0 ? filtered : candidates;
8840
8860
  }
8841
8861
  function cliTaskToTask(cliTask) {
@@ -8914,7 +8934,8 @@ function adjustProfileWithStageScores(profiles, stageScores) {
8914
8934
  });
8915
8935
  }
8916
8936
  function buildAdjustedProfiles(taskProfile, candidates, options) {
8917
- const profiles = DEFAULT_MODEL_PROFILES.filter((p) => candidates.includes(p.cliName));
8937
+ const candidateSlots = new Set(candidates.map(routingArmDisplaySlot));
8938
+ const profiles = DEFAULT_MODEL_PROFILES.filter((p) => candidateSlots.has(p.cliName));
8918
8939
  let adjusted = profiles.map((p) => adjustProfileForTask(p, taskProfile));
8919
8940
  if (options?.stageScores !== void 0 && options.stageScores.size > 0) {
8920
8941
  adjusted = adjustProfileWithStageScores(adjusted, options.stageScores);
@@ -8933,10 +8954,12 @@ function applyTopsisRanking(taskProfile, candidates, topsisRouter, options) {
8933
8954
  const adjustedProfiles = buildAdjustedProfiles(taskProfile, candidates, options);
8934
8955
  const result = router.selectModel({ profiles: adjustedProfiles });
8935
8956
  const scoreMap = new Map(result.scores.map((s) => [s.cliName, s.closenessScore]));
8936
- const ranking = [...candidates].sort((a, b) => (scoreMap.get(b) ?? 0) - (scoreMap.get(a) ?? 0));
8937
- const topScore = scoreMap.get(ranking[0] ?? "claude") ?? 1;
8957
+ const scoreOf = (arm) => scoreMap.get(routingArmDisplaySlot(arm)) ?? 0;
8958
+ const ranking = [...candidates].sort((a, b) => scoreOf(b) - scoreOf(a));
8959
+ const topArm = ranking[0];
8960
+ const topScore = topArm !== void 0 ? scoreOf(topArm) : 1;
8938
8961
  const threshold = topScore * (1 - TOPSIS_TOLERANCE_BAND_PERCENT);
8939
- const toleranceBandSize = ranking.filter((c) => (scoreMap.get(c) ?? 0) >= threshold).length;
8962
+ const toleranceBandSize = ranking.filter((c) => scoreOf(c) >= threshold).length;
8940
8963
  return { ranking, topScore, toleranceBandSize };
8941
8964
  }
8942
8965
  function defaultPreferenceStageResult(candidates) {
@@ -8961,8 +8984,8 @@ function filterByDifficultyTier(candidates, tier) {
8961
8984
  };
8962
8985
  const preferred = tierPreferences[tier];
8963
8986
  const sortedCandidates = [...candidates].sort((a, b) => {
8964
- const aIndex = preferred.indexOf(a);
8965
- const bIndex = preferred.indexOf(b);
8987
+ const aIndex = preferred.indexOf(routingArmDisplaySlot(a));
8988
+ const bIndex = preferred.indexOf(routingArmDisplaySlot(b));
8966
8989
  const aPos = aIndex === -1 ? preferred.length : aIndex;
8967
8990
  const bPos = bIndex === -1 ? preferred.length : bIndex;
8968
8991
  return aPos - bPos;
@@ -8973,7 +8996,7 @@ function applyZeroRouterFilter(task, candidates, zeroRouter) {
8973
8996
  if (zeroRouter === void 0 || candidates.length === 0) {
8974
8997
  return defaultZeroRouterStageResult(candidates);
8975
8998
  }
8976
- const decision = zeroRouter.routeByDifficulty(task, candidates);
8999
+ const decision = zeroRouter.routeByDifficulty(task, candidates.map(routingArmDisplaySlot));
8977
9000
  const difficultyEstimate = decision.difficulty;
8978
9001
  const difficultyTier = decision.tier;
8979
9002
  const filteredCandidates = filterByDifficultyTier(candidates, difficultyTier);
@@ -10606,6 +10629,13 @@ function getFallbackChainForCategory(category, bucketType, registry = DEFAULT_FA
10606
10629
  // src/cli-adapters/composite-router-stages.ts
10607
10630
  var logger9 = createLogger({ component: "composite-router-stages" });
10608
10631
  var sharedAnalyzer2 = createSharedTaskAnalyzer();
10632
+ function armsToSlots(candidates) {
10633
+ return [...new Set(candidates.map(routingArmDisplaySlot))];
10634
+ }
10635
+ function keepArmsForSlots(candidates, survivingSlots) {
10636
+ const slotSet = new Set(survivingSlots);
10637
+ return candidates.filter((arm) => slotSet.has(routingArmDisplaySlot(arm)));
10638
+ }
10609
10639
  function analyzeTaskProfile(task, stagesExecuted) {
10610
10640
  const internalTask = cliTaskToTask(task);
10611
10641
  const analysis = sharedAnalyzer2.analyze(internalTask);
@@ -10666,7 +10696,7 @@ async function runConfidenceCascadeStage(task, candidates, stagesExecuted, deps)
10666
10696
  if (!deps.config.enableConfidenceCascade || deps.confidenceCascadeStage === void 0) {
10667
10697
  return DEFAULT_CASCADE_RESULT;
10668
10698
  }
10669
- const ctx = createRoutingContext(task.content, candidates);
10699
+ const ctx = createRoutingContext(task.content, armsToSlots(candidates));
10670
10700
  const result = await deps.confidenceCascadeStage.route(ctx);
10671
10701
  stagesExecuted.push("confidence-cascade");
10672
10702
  if (!result.ok) {
@@ -10692,7 +10722,7 @@ async function runCapabilityMatchStage(task, candidates, stagesExecuted, deps) {
10692
10722
  if (!deps.config.enableCapabilityMatch || deps.capabilityMatchStage === void 0) {
10693
10723
  return DEFAULT_CAPABILITY_RESULT;
10694
10724
  }
10695
- const ctx = createRoutingContext(task.content, candidates);
10725
+ const ctx = createRoutingContext(task.content, armsToSlots(candidates));
10696
10726
  const result = await deps.capabilityMatchStage.route(ctx);
10697
10727
  stagesExecuted.push("capability-match");
10698
10728
  if (!result.ok) {
@@ -10713,7 +10743,7 @@ async function runQualityConstraintStage(candidates, stagesExecuted, deps) {
10713
10743
  if (!deps.config.enableQualityConstraint || deps.qualityConstraintStage === void 0) {
10714
10744
  return { eligible: candidates, filtered: /* @__PURE__ */ new Map(), usedFallback: false };
10715
10745
  }
10716
- const ctx = createRoutingContext("", candidates);
10746
+ const ctx = createRoutingContext("", armsToSlots(candidates));
10717
10747
  const result = await deps.qualityConstraintStage.route(ctx);
10718
10748
  stagesExecuted.push("quality-constraint");
10719
10749
  if (!result.ok) {
@@ -10728,7 +10758,7 @@ async function runQualityConstraintStage(candidates, stagesExecuted, deps) {
10728
10758
  filtered: filtered.size,
10729
10759
  usedFallback
10730
10760
  });
10731
- const eligible = remaining.length > 0 ? remaining : candidates;
10761
+ const eligible = remaining.length > 0 ? keepArmsForSlots(candidates, remaining) : candidates;
10732
10762
  return { eligible, filtered, usedFallback: remaining.length === 0 || usedFallback };
10733
10763
  }
10734
10764
  var DEFAULT_RESOURCE_RESULT = {
@@ -10740,7 +10770,7 @@ async function runResourceStrategyStage(task, candidates, stagesExecuted, deps)
10740
10770
  if (!deps.config.enableResourceStrategy || deps.resourceStrategyStage === void 0) {
10741
10771
  return DEFAULT_RESOURCE_RESULT;
10742
10772
  }
10743
- const ctx = createRoutingContext(task.content, candidates);
10773
+ const ctx = createRoutingContext(task.content, armsToSlots(candidates));
10744
10774
  const result = await deps.resourceStrategyStage.route(ctx);
10745
10775
  stagesExecuted.push("resource-strategy");
10746
10776
  if (!result.ok) {
@@ -10756,7 +10786,7 @@ async function runDistilledRuleStage(task, candidates, stagesExecuted, deps) {
10756
10786
  if (!deps.config.enableStrategyDistillation || deps.distilledRuleStage === void 0) {
10757
10787
  return { scores: /* @__PURE__ */ new Map(), rulesApplied: 0 };
10758
10788
  }
10759
- const ctx = createRoutingContext(task.content, candidates);
10789
+ const ctx = createRoutingContext(task.content, armsToSlots(candidates));
10760
10790
  const result = await deps.distilledRuleStage.route(ctx);
10761
10791
  stagesExecuted.push("distilled-rule");
10762
10792
  if (!result.ok) {
@@ -10772,7 +10802,7 @@ async function runKnnRoutingStage(task, candidates, stagesExecuted, deps) {
10772
10802
  if (!deps.config.enableKnnRouting || deps.knnRoutingStage === void 0) {
10773
10803
  return { scores: /* @__PURE__ */ new Map(), hasExperience: false };
10774
10804
  }
10775
- const ctx = createRoutingContext(task.content, candidates);
10805
+ const ctx = createRoutingContext(task.content, armsToSlots(candidates));
10776
10806
  const result = await deps.knnRoutingStage.route(ctx);
10777
10807
  stagesExecuted.push("knn-routing");
10778
10808
  if (!result.ok) {
@@ -10871,14 +10901,12 @@ function runLatencyStage(candidates, stagesExecuted, deps) {
10871
10901
  if (!deps.config.enableLatencyTracking || deps.latencyTracker === void 0) {
10872
10902
  return { latencyScore: void 0, latencyAdjustedRanking: candidates };
10873
10903
  }
10874
- const scores = deps.latencyTracker.getScores(candidates);
10904
+ const scores = deps.latencyTracker.getScores(armsToSlots(candidates));
10875
10905
  stagesExecuted.push("latency-scoring");
10876
- const sortedCandidates = [...candidates].sort((a, b) => {
10877
- const scoreA = scores.find((s) => s.cli === a)?.score ?? 0;
10878
- const scoreB = scores.find((s) => s.cli === b)?.score ?? 0;
10879
- return scoreB - scoreA;
10880
- });
10881
- const topScore = scores.find((s) => s.cli === sortedCandidates[0])?.score;
10906
+ const scoreOf = (arm) => scores.find((s) => s.cli === routingArmDisplaySlot(arm))?.score ?? 0;
10907
+ const sortedCandidates = [...candidates].sort((a, b) => scoreOf(b) - scoreOf(a));
10908
+ const topArm = sortedCandidates[0];
10909
+ const topScore = topArm !== void 0 ? scores.find((s) => s.cli === routingArmDisplaySlot(topArm))?.score : void 0;
10882
10910
  deps.logger.debug("Latency scoring applied", {
10883
10911
  scores: scores.map((s) => ({
10884
10912
  cli: s.cli,
@@ -10899,7 +10927,7 @@ function runRoutingMemoryStage(task, candidates, stagesExecuted, deps) {
10899
10927
  const taskType = inferTaskTypeFromContent(task.content);
10900
10928
  const recommendation = deps.routingMemory.getRecommendation(taskType);
10901
10929
  stagesExecuted.push("routing-memory");
10902
- if (recommendation !== void 0 && candidates.includes(recommendation)) {
10930
+ if (recommendation !== void 0 && armsToSlots(candidates).includes(recommendation)) {
10903
10931
  deps.logger.debug("Routing memory recommendation", {
10904
10932
  taskType,
10905
10933
  recommended: recommendation,
@@ -10970,7 +10998,7 @@ function aggregateStageScores(scoring, taskContent, candidates) {
10970
10998
  scoring.distilledResult.scores,
10971
10999
  scoring.resourceResult.scores,
10972
11000
  weatherScores,
10973
- getTuneAdjustmentScores(candidates)
11001
+ getTuneAdjustmentScores(armsToSlots([...candidates]))
10974
11002
  );
10975
11003
  }
10976
11004
  var TUNE_ENFORCE_ENV = "NEXUS_TUNE_ENFORCE";
@@ -11012,8 +11040,9 @@ function applyCategoryOverride(task, candidates, stagesExecuted) {
11012
11040
  if (match === null) return ok(candidates);
11013
11041
  const override = CATEGORY_CHAIN_OVERRIDES[match.category];
11014
11042
  if (override === void 0) return ok(candidates);
11015
- const candidateSet = new Set(candidates);
11016
- const filtered = override.filter((cli) => candidateSet.has(cli));
11043
+ const overrideSet = new Set(override);
11044
+ const orderIndex = (arm) => override.indexOf(routingArmDisplaySlot(arm));
11045
+ const filtered = candidates.filter((arm) => overrideSet.has(routingArmDisplaySlot(arm))).sort((a, b) => orderIndex(a) - orderIndex(b));
11017
11046
  if (filtered.length === 0) {
11018
11047
  if (isCategoryFailClosed(match.category)) {
11019
11048
  stagesExecuted.push("category-override:fail-closed");
@@ -11037,7 +11066,7 @@ function applyCategoryOverride(task, candidates, stagesExecuted) {
11037
11066
  }
11038
11067
  function applyLinUCBFloorOverride(linucbCli, topsisRanking, opts) {
11039
11068
  if (opts.perfData === void 0) return linucbCli;
11040
- const cliPerf = opts.perfData.get(linucbCli);
11069
+ const cliPerf = opts.perfData.get(routingArmDisplaySlot(linucbCli));
11041
11070
  if (cliPerf === void 0 || cliPerf.sampleCount < 20 || cliPerf.successRate >= 0.5) {
11042
11071
  return linucbCli;
11043
11072
  }
@@ -11475,7 +11504,9 @@ function recordZeroRouterOutcome(task, success, qualityScore, deps) {
11475
11504
  const outcome = buildDifficultyOutcome(
11476
11505
  task.content,
11477
11506
  difficulty,
11478
- selectedCli,
11507
+ // Difficulty calibration is slot-level; collapse an api:* arm to its
11508
+ // display slot here (the bandit retains the distinct arm). (#3422)
11509
+ routingArmDisplaySlot(selectedCli),
11479
11510
  success,
11480
11511
  qualityScore
11481
11512
  );
@@ -11531,11 +11562,12 @@ function computeQualityReward(cli, success, durationMs2) {
11531
11562
  // src/cli-adapters/composite-router-metrics.ts
11532
11563
  function recordDecisionToMetrics(decision, traceId, deps) {
11533
11564
  if (deps.metricsCollector === void 0) return;
11565
+ const selectedModel = routingArmDisplaySlot(decision.cliName);
11534
11566
  deps.metricsCollector.recordDecision({
11535
11567
  timestamp: getTimeProvider().nowIso(),
11536
11568
  traceId,
11537
- selectedModel: decision.cliName,
11538
- alternativeModels: decision.alternatives,
11569
+ selectedModel,
11570
+ alternativeModels: decision.alternatives.map(routingArmDisplaySlot),
11539
11571
  isExploration: decision.ucbScore !== void 0 && decision.ucbScore > 0.5,
11540
11572
  taskType: decision.taskProfile.taskType,
11541
11573
  contextTokens: decision.taskProfile.contextRequired,
@@ -11543,7 +11575,7 @@ function recordDecisionToMetrics(decision, traceId, deps) {
11543
11575
  });
11544
11576
  deps.logger.debug("Recorded routing decision to metrics", {
11545
11577
  traceId,
11546
- selectedModel: decision.cliName
11578
+ selectedModel
11547
11579
  });
11548
11580
  }
11549
11581
  function recordOutcomeToMetrics(opts, deps) {
@@ -11729,7 +11761,9 @@ var CompositeRouter = class _CompositeRouter {
11729
11761
  type: "routing.decision",
11730
11762
  timestamp: getTimeProvider().now(),
11731
11763
  taskId: taskDescription.slice(0, 100),
11732
- selectedModel: decision.cliName,
11764
+ // Trace attribution is slot-level; collapse the api:* arm (#3422) so this
11765
+ // sink matches every other telemetry sink (the bandit keeps the arm).
11766
+ selectedModel: routingArmDisplaySlot(decision.cliName),
11733
11767
  reasoning: decision.reason,
11734
11768
  decisionPath: decision.stagesExecuted
11735
11769
  });
@@ -11806,7 +11840,7 @@ var CompositeRouter = class _CompositeRouter {
11806
11840
  */
11807
11841
  async consultUnifiedContext(task) {
11808
11842
  try {
11809
- const { getContextForTask, inferTaskCategory } = await import("./context-retriever-J7DIPQUO.js");
11843
+ const { getContextForTask, inferTaskCategory } = await import("./context-retriever-52RLYDVE.js");
11810
11844
  const ctx = await getContextForTask({
11811
11845
  task: task.content,
11812
11846
  category: inferTaskCategory(task.content),
@@ -11854,11 +11888,13 @@ var CompositeRouter = class _CompositeRouter {
11854
11888
  return executeResult;
11855
11889
  }
11856
11890
  autoRecordFeedback(decision, task, success, durationMs2) {
11857
- const reward = computeQualityReward(decision.cliName, success, durationMs2);
11858
- this.recordOutcome(decision.cliName, task, reward);
11891
+ const arm = decision.cliName;
11892
+ const slot = routingArmDisplaySlot(arm);
11893
+ const reward = computeQualityReward(slot, success, durationMs2);
11894
+ this.recordOutcome(arm, task, reward);
11859
11895
  this.recordDifficultyOutcome(task, success);
11860
11896
  if (this.latencyTracker !== void 0) {
11861
- this.latencyTracker.record(decision.cliName, durationMs2, success);
11897
+ this.latencyTracker.record(slot, durationMs2, success);
11862
11898
  }
11863
11899
  if (this.routingMemory !== void 0) {
11864
11900
  const taskType = this.inferTaskType(task);
@@ -11869,13 +11905,13 @@ var CompositeRouter = class _CompositeRouter {
11869
11905
  avgTokens: task.maxTokens ?? DEFAULT_TOKEN_ESTIMATE,
11870
11906
  observations: 1
11871
11907
  };
11872
- this.routingMemory.storePreference(decision.cliName, taskType, performance2);
11908
+ this.routingMemory.storePreference(slot, taskType, performance2);
11873
11909
  }
11874
11910
  if (this.lastTraceId !== void 0) {
11875
11911
  recordOutcomeToMetrics(
11876
11912
  {
11877
11913
  traceId: this.lastTraceId,
11878
- cliName: decision.cliName,
11914
+ cliName: slot,
11879
11915
  success,
11880
11916
  reward,
11881
11917
  qualityScore: success ? decision.confidence : FAILURE_QUALITY_SCORE,
@@ -11885,7 +11921,7 @@ var CompositeRouter = class _CompositeRouter {
11885
11921
  );
11886
11922
  }
11887
11923
  this.logger.debug("Auto-recorded feedback", {
11888
- cli: decision.cliName,
11924
+ cli: arm,
11889
11925
  success,
11890
11926
  durationMs: durationMs2,
11891
11927
  reward
@@ -11956,7 +11992,9 @@ var CompositeRouter = class _CompositeRouter {
11956
11992
  const all = await this.availableModelsCache.getAll();
11957
11993
  if (all.length === 0) return this.cliNames;
11958
11994
  const sourcesWithModels = new Set(all.map((m) => m.source));
11959
- const filtered = this.cliNames.filter((name) => sourcesWithModels.has(name));
11995
+ const filtered = this.cliNames.filter(
11996
+ (name) => sourcesWithModels.has(routingArmDisplaySlot(name))
11997
+ );
11960
11998
  return filtered.length > 0 ? filtered : this.cliNames;
11961
11999
  } catch (e) {
11962
12000
  this.logger.warn("AvailableModelsCache query failed; falling back to all CLIs", {
@@ -12012,7 +12050,7 @@ var CompositeRouter = class _CompositeRouter {
12012
12050
  const decisionTimeMs = getTimeProvider().now() - params.startTime;
12013
12051
  this.updateStats(params.selectedCli, decisionTimeMs);
12014
12052
  const { confidence, reason, alternatives } = buildDecisionFields({ ...params, decisionTimeMs });
12015
- const model = isRouteModelSelectionEnabled() && params.difficultyTier !== void 0 ? resolveModelForTier(params.selectedCli, params.difficultyTier) : void 0;
12053
+ const model = isRouteModelSelectionEnabled() && params.difficultyTier !== void 0 ? resolveModelForTier(routingArmDisplaySlot(params.selectedCli), params.difficultyTier) : void 0;
12016
12054
  return ok({
12017
12055
  adapter: selectedAdapter,
12018
12056
  cliName: params.selectedCli,
@@ -12035,7 +12073,7 @@ var CompositeRouter = class _CompositeRouter {
12035
12073
  }
12036
12074
  updateStats(selectedCli, decisionTimeMs) {
12037
12075
  this.totalDecisions++;
12038
- this.decisionsPerCli[selectedCli]++;
12076
+ this.decisionsPerCli[routingArmDisplaySlot(selectedCli)]++;
12039
12077
  this.totalDecisionTimeMs += decisionTimeMs;
12040
12078
  }
12041
12079
  /**
@@ -12049,10 +12087,10 @@ var CompositeRouter = class _CompositeRouter {
12049
12087
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
12050
12088
  taskId: `task-${getRandomProvider().uuid()}`,
12051
12089
  taskDescription: task.content.length > 100 ? task.content.substring(0, 100) + "..." : task.content,
12052
- selectedCli: decision.cliName,
12090
+ selectedCli: routingArmDisplaySlot(decision.cliName),
12053
12091
  confidence: decision.confidence,
12054
12092
  reason: decision.reason,
12055
- alternatives: decision.alternatives,
12093
+ alternatives: decision.alternatives.map(routingArmDisplaySlot),
12056
12094
  stagesExecuted: decision.stagesExecuted,
12057
12095
  decisionTimeMs: decision.decisionTimeMs,
12058
12096
  withinBudget: decision.withinBudget,
@@ -13009,6 +13047,7 @@ export {
13009
13047
  getCliModelName,
13010
13048
  resolveCliAlias,
13011
13049
  buildCapabilityProfiles,
13050
+ buildCliCapabilityProfiles,
13012
13051
  findCanonicalModel,
13013
13052
  buildModelInfo,
13014
13053
  getInTreeCapabilitiesMatrix,
@@ -13047,6 +13086,8 @@ export {
13047
13086
  getRandomProvider,
13048
13087
  getTokenEstimator,
13049
13088
  estimateTokens,
13089
+ apiArmId,
13090
+ routingArmDisplaySlot,
13050
13091
  CLI_VERSION_REQUIREMENTS,
13051
13092
  DEFAULT_CAPABILITIES,
13052
13093
  RoutingMemoryError,
@@ -13156,4 +13197,4 @@ export {
13156
13197
  ParseError,
13157
13198
  OrchestratorError
13158
13199
  };
13159
- //# sourceMappingURL=chunk-WDVUKSIQ.js.map
13200
+ //# sourceMappingURL=chunk-2DHISFDY.js.map