nexus-agents 2.162.1 → 2.163.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 (130) hide show
  1. package/dist/{child-mcp-config-VXXBVJY3.js → child-mcp-config-ZSVYMJTH.js} +3 -3
  2. package/dist/{chunk-MJLN336B.js → chunk-2EAKVHOL.js} +3 -3
  3. package/dist/{chunk-23ZSFBBM.js → chunk-2LR2XP3B.js} +9 -9
  4. package/dist/{chunk-FFH35IKD.js → chunk-3EBDRAQW.js} +3 -3
  5. package/dist/{chunk-V7CIVDNO.js → chunk-3JWMDESZ.js} +3 -3
  6. package/dist/{chunk-JB37LBSG.js → chunk-3RDE3OZ6.js} +7 -7
  7. package/dist/{chunk-U4KMGGGF.js → chunk-3ZXNPAUR.js} +2 -2
  8. package/dist/{chunk-THUX4X43.js → chunk-47EFSSZK.js} +3 -3
  9. package/dist/{chunk-VWV34IMA.js → chunk-563FMXWL.js} +2 -2
  10. package/dist/{chunk-754RDQAS.js → chunk-5KFUWUMY.js} +2 -2
  11. package/dist/{chunk-YUAQRJRF.js → chunk-AM7EW7CP.js} +4 -4
  12. package/dist/{chunk-HJZ3RES7.js → chunk-AOXZ42SD.js} +2 -2
  13. package/dist/{chunk-DBHK6EDT.js → chunk-ARTIFRBA.js} +2 -2
  14. package/dist/{chunk-NL7SZQPW.js → chunk-AXTD4TFK.js} +5 -1
  15. package/dist/{chunk-NL7SZQPW.js.map → chunk-AXTD4TFK.js.map} +1 -1
  16. package/dist/{chunk-ZIPTXCET.js → chunk-B3FX6E7M.js} +37 -37
  17. package/dist/{chunk-7QWGLBCE.js → chunk-CNGZ5N4W.js} +5 -5
  18. package/dist/{chunk-XWAV3UC2.js → chunk-D2NBIVAV.js} +5 -5
  19. package/dist/{chunk-DXEYJAGO.js → chunk-ENKFWBRH.js} +2 -2
  20. package/dist/{chunk-W3ZTVYZN.js → chunk-HDLWUFKI.js} +2 -2
  21. package/dist/{chunk-WP6L2PTV.js → chunk-JZ3DVFEW.js} +7 -7
  22. package/dist/{chunk-JYR6SBUB.js → chunk-K5NU57WE.js} +4 -4
  23. package/dist/{chunk-GJSJRJ6Y.js → chunk-K7GAI4WP.js} +2 -2
  24. package/dist/{chunk-EZHYOWWO.js → chunk-LJWB4Z7O.js} +2 -2
  25. package/dist/{chunk-WGDZFYP3.js → chunk-NDV5J3Z5.js} +277 -27
  26. package/dist/chunk-NDV5J3Z5.js.map +1 -0
  27. package/dist/{chunk-N67NSSQT.js → chunk-NG5ZAI7W.js} +2 -2
  28. package/dist/{chunk-MJOHZFJP.js → chunk-OEOBPWBH.js} +15 -8
  29. package/dist/chunk-OEOBPWBH.js.map +1 -0
  30. package/dist/{chunk-ZGSAYLPE.js → chunk-P4J6I5ZI.js} +2 -2
  31. package/dist/{chunk-GMSYKYFA.js → chunk-PRU452SV.js} +2 -2
  32. package/dist/{chunk-TJJW4BGX.js → chunk-S477DLWR.js} +4 -4
  33. package/dist/{chunk-RN5ISNYK.js → chunk-SBCIKT64.js} +3 -3
  34. package/dist/{chunk-JIXCOX7D.js → chunk-SKJK44YC.js} +3 -3
  35. package/dist/{chunk-EVYIQ6N5.js → chunk-U5E2JJ4F.js} +6 -6
  36. package/dist/{chunk-6ILEOLNW.js → chunk-UAK3OVSL.js} +2 -2
  37. package/dist/{chunk-EQJR6WMY.js → chunk-UEAG2PEQ.js} +2 -2
  38. package/dist/{chunk-RDYGX6MQ.js → chunk-WRZ7HENW.js} +2 -2
  39. package/dist/{chunk-6FWMNTPO.js → chunk-Y6O4FB5V.js} +4 -4
  40. package/dist/{cli-circuit-breaker-B4RH2ELX.js → cli-circuit-breaker-KUPKNGN2.js} +5 -5
  41. package/dist/cli.js +42 -42
  42. package/dist/{composite-router-4PYFIB2G.js → composite-router-F6YN34I7.js} +3 -3
  43. package/dist/{consensus-vote-MM5YG3A5.js → consensus-vote-N4HVJT7S.js} +16 -16
  44. package/dist/{context-retriever-YGPEAEPO.js → context-retriever-W6Z6JNEF.js} +9 -9
  45. package/dist/{doctor-deep-N576AXQE.js → doctor-deep-MKKGB3KM.js} +4 -4
  46. package/dist/{expert-bridge-YEE7F6TA.js → expert-bridge-KWUVLYXR.js} +5 -5
  47. package/dist/factory-5TRDV3CD.js +15 -0
  48. package/dist/factory-UF6LR6R6.js +22 -0
  49. package/dist/{improvement-review-5CZJIOEH.js → improvement-review-K2FQ5K4H.js} +6 -6
  50. package/dist/index.d.ts +33 -0
  51. package/dist/index.js +31 -31
  52. package/dist/{init-opencode-R3PEVUUI.js → init-opencode-42DWDOPX.js} +7 -7
  53. package/dist/issue-triage-OHJZLCEG.js +18 -0
  54. package/dist/{learning-persistence-M3OTCCNI.js → learning-persistence-6D5GGT7D.js} +4 -2
  55. package/dist/{pr-reviewer-helpers-TOMMTISB.js → pr-reviewer-helpers-ZWGIWDFL.js} +5 -5
  56. package/dist/{registry-command-EBGQHFT3.js → registry-command-X6FLUFKQ.js} +3 -3
  57. package/dist/{repo-security-plan-CWJ3Z4CC.js → repo-security-plan-K4IYY3OY.js} +4 -4
  58. package/dist/{research-helpers-synthesize-UNLGVEND.js → research-helpers-synthesize-GBT6QZIP.js} +5 -5
  59. package/dist/{routing-memory-MTGIZZUO.js → routing-memory-KDVKLC75.js} +3 -3
  60. package/dist/{session-memory-QGUF5TNU.js → session-memory-HQ5KPXQG.js} +4 -4
  61. package/dist/{setup-command-6QSWQMBJ.js → setup-command-USFTGMA3.js} +12 -12
  62. package/dist/setup-config-K66VKRCD.js +11 -0
  63. package/dist/{setup-custom-api-QON4YKJ3.js → setup-custom-api-6CG7HMRX.js} +4 -4
  64. package/dist/{tool-memory-SNH4B5Q7.js → tool-memory-DAGKXCJA.js} +6 -6
  65. package/dist/{unified-registry-XEA2GEOZ.js → unified-registry-GAGQ2VSX.js} +10 -10
  66. package/dist/{weather-report-QQ42WBNZ.js → weather-report-ZYPHCFXL.js} +3 -3
  67. package/package.json +1 -1
  68. package/dist/chunk-MJOHZFJP.js.map +0 -1
  69. package/dist/chunk-WGDZFYP3.js.map +0 -1
  70. package/dist/factory-NQEQY7NV.js +0 -15
  71. package/dist/factory-TWK2UKNH.js +0 -22
  72. package/dist/issue-triage-Y35K4BUV.js +0 -18
  73. package/dist/setup-config-4TGGV7AQ.js +0 -11
  74. /package/dist/{child-mcp-config-VXXBVJY3.js.map → child-mcp-config-ZSVYMJTH.js.map} +0 -0
  75. /package/dist/{chunk-MJLN336B.js.map → chunk-2EAKVHOL.js.map} +0 -0
  76. /package/dist/{chunk-23ZSFBBM.js.map → chunk-2LR2XP3B.js.map} +0 -0
  77. /package/dist/{chunk-FFH35IKD.js.map → chunk-3EBDRAQW.js.map} +0 -0
  78. /package/dist/{chunk-V7CIVDNO.js.map → chunk-3JWMDESZ.js.map} +0 -0
  79. /package/dist/{chunk-JB37LBSG.js.map → chunk-3RDE3OZ6.js.map} +0 -0
  80. /package/dist/{chunk-U4KMGGGF.js.map → chunk-3ZXNPAUR.js.map} +0 -0
  81. /package/dist/{chunk-THUX4X43.js.map → chunk-47EFSSZK.js.map} +0 -0
  82. /package/dist/{chunk-VWV34IMA.js.map → chunk-563FMXWL.js.map} +0 -0
  83. /package/dist/{chunk-754RDQAS.js.map → chunk-5KFUWUMY.js.map} +0 -0
  84. /package/dist/{chunk-YUAQRJRF.js.map → chunk-AM7EW7CP.js.map} +0 -0
  85. /package/dist/{chunk-HJZ3RES7.js.map → chunk-AOXZ42SD.js.map} +0 -0
  86. /package/dist/{chunk-DBHK6EDT.js.map → chunk-ARTIFRBA.js.map} +0 -0
  87. /package/dist/{chunk-ZIPTXCET.js.map → chunk-B3FX6E7M.js.map} +0 -0
  88. /package/dist/{chunk-7QWGLBCE.js.map → chunk-CNGZ5N4W.js.map} +0 -0
  89. /package/dist/{chunk-XWAV3UC2.js.map → chunk-D2NBIVAV.js.map} +0 -0
  90. /package/dist/{chunk-DXEYJAGO.js.map → chunk-ENKFWBRH.js.map} +0 -0
  91. /package/dist/{chunk-W3ZTVYZN.js.map → chunk-HDLWUFKI.js.map} +0 -0
  92. /package/dist/{chunk-WP6L2PTV.js.map → chunk-JZ3DVFEW.js.map} +0 -0
  93. /package/dist/{chunk-JYR6SBUB.js.map → chunk-K5NU57WE.js.map} +0 -0
  94. /package/dist/{chunk-GJSJRJ6Y.js.map → chunk-K7GAI4WP.js.map} +0 -0
  95. /package/dist/{chunk-EZHYOWWO.js.map → chunk-LJWB4Z7O.js.map} +0 -0
  96. /package/dist/{chunk-N67NSSQT.js.map → chunk-NG5ZAI7W.js.map} +0 -0
  97. /package/dist/{chunk-ZGSAYLPE.js.map → chunk-P4J6I5ZI.js.map} +0 -0
  98. /package/dist/{chunk-GMSYKYFA.js.map → chunk-PRU452SV.js.map} +0 -0
  99. /package/dist/{chunk-TJJW4BGX.js.map → chunk-S477DLWR.js.map} +0 -0
  100. /package/dist/{chunk-RN5ISNYK.js.map → chunk-SBCIKT64.js.map} +0 -0
  101. /package/dist/{chunk-JIXCOX7D.js.map → chunk-SKJK44YC.js.map} +0 -0
  102. /package/dist/{chunk-EVYIQ6N5.js.map → chunk-U5E2JJ4F.js.map} +0 -0
  103. /package/dist/{chunk-6ILEOLNW.js.map → chunk-UAK3OVSL.js.map} +0 -0
  104. /package/dist/{chunk-EQJR6WMY.js.map → chunk-UEAG2PEQ.js.map} +0 -0
  105. /package/dist/{chunk-RDYGX6MQ.js.map → chunk-WRZ7HENW.js.map} +0 -0
  106. /package/dist/{chunk-6FWMNTPO.js.map → chunk-Y6O4FB5V.js.map} +0 -0
  107. /package/dist/{cli-circuit-breaker-B4RH2ELX.js.map → cli-circuit-breaker-KUPKNGN2.js.map} +0 -0
  108. /package/dist/{composite-router-4PYFIB2G.js.map → composite-router-F6YN34I7.js.map} +0 -0
  109. /package/dist/{consensus-vote-MM5YG3A5.js.map → consensus-vote-N4HVJT7S.js.map} +0 -0
  110. /package/dist/{context-retriever-YGPEAEPO.js.map → context-retriever-W6Z6JNEF.js.map} +0 -0
  111. /package/dist/{doctor-deep-N576AXQE.js.map → doctor-deep-MKKGB3KM.js.map} +0 -0
  112. /package/dist/{expert-bridge-YEE7F6TA.js.map → expert-bridge-KWUVLYXR.js.map} +0 -0
  113. /package/dist/{factory-NQEQY7NV.js.map → factory-5TRDV3CD.js.map} +0 -0
  114. /package/dist/{factory-TWK2UKNH.js.map → factory-UF6LR6R6.js.map} +0 -0
  115. /package/dist/{improvement-review-5CZJIOEH.js.map → improvement-review-K2FQ5K4H.js.map} +0 -0
  116. /package/dist/{init-opencode-R3PEVUUI.js.map → init-opencode-42DWDOPX.js.map} +0 -0
  117. /package/dist/{issue-triage-Y35K4BUV.js.map → issue-triage-OHJZLCEG.js.map} +0 -0
  118. /package/dist/{learning-persistence-M3OTCCNI.js.map → learning-persistence-6D5GGT7D.js.map} +0 -0
  119. /package/dist/{pr-reviewer-helpers-TOMMTISB.js.map → pr-reviewer-helpers-ZWGIWDFL.js.map} +0 -0
  120. /package/dist/{registry-command-EBGQHFT3.js.map → registry-command-X6FLUFKQ.js.map} +0 -0
  121. /package/dist/{repo-security-plan-CWJ3Z4CC.js.map → repo-security-plan-K4IYY3OY.js.map} +0 -0
  122. /package/dist/{research-helpers-synthesize-UNLGVEND.js.map → research-helpers-synthesize-GBT6QZIP.js.map} +0 -0
  123. /package/dist/{routing-memory-MTGIZZUO.js.map → routing-memory-KDVKLC75.js.map} +0 -0
  124. /package/dist/{session-memory-QGUF5TNU.js.map → session-memory-HQ5KPXQG.js.map} +0 -0
  125. /package/dist/{setup-command-6QSWQMBJ.js.map → setup-command-USFTGMA3.js.map} +0 -0
  126. /package/dist/{setup-config-4TGGV7AQ.js.map → setup-config-K66VKRCD.js.map} +0 -0
  127. /package/dist/{setup-custom-api-QON4YKJ3.js.map → setup-custom-api-6CG7HMRX.js.map} +0 -0
  128. /package/dist/{tool-memory-SNH4B5Q7.js.map → tool-memory-DAGKXCJA.js.map} +0 -0
  129. /package/dist/{unified-registry-XEA2GEOZ.js.map → unified-registry-GAGQ2VSX.js.map} +0 -0
  130. /package/dist/{weather-report-QQ42WBNZ.js.map → weather-report-ZYPHCFXL.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  GitHubProvider,
3
3
  ScmError
4
- } from "./chunk-GJSJRJ6Y.js";
4
+ } from "./chunk-K7GAI4WP.js";
5
5
  import {
6
6
  ROLE_DEFAULT_TRUST,
7
7
  ReputationCache,
@@ -11,17 +11,17 @@ import {
11
11
  gateWithReputation,
12
12
  resolveReputationGatingMode,
13
13
  sanitizeInput
14
- } from "./chunk-GMSYKYFA.js";
14
+ } from "./chunk-PRU452SV.js";
15
15
  import {
16
16
  emitPolicyEvent
17
- } from "./chunk-N67NSSQT.js";
17
+ } from "./chunk-NG5ZAI7W.js";
18
18
  import {
19
19
  CLI_SUBPROCESS_TIMEOUTS,
20
20
  createLogger,
21
21
  err,
22
22
  getTimeProvider,
23
23
  ok
24
- } from "./chunk-WGDZFYP3.js";
24
+ } from "./chunk-NDV5J3Z5.js";
25
25
 
26
26
  // src/security/trust-classifier.ts
27
27
  function mapAuthorAssociation(association) {
@@ -1211,4 +1211,4 @@ export {
1211
1211
  IssueTriage,
1212
1212
  createIssueTriage
1213
1213
  };
1214
- //# sourceMappingURL=chunk-XWAV3UC2.js.map
1214
+ //# sourceMappingURL=chunk-D2NBIVAV.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getRandomProvider,
3
3
  getTimeProvider
4
- } from "./chunk-WGDZFYP3.js";
4
+ } from "./chunk-NDV5J3Z5.js";
5
5
 
6
6
  // src/utils/id-utils.ts
7
7
  import { randomUUID } from "crypto";
@@ -24,4 +24,4 @@ export {
24
24
  generateHyphenId,
25
25
  generateUUID
26
26
  };
27
- //# sourceMappingURL=chunk-DXEYJAGO.js.map
27
+ //# sourceMappingURL=chunk-ENKFWBRH.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getErrorMessage
3
- } from "./chunk-WGDZFYP3.js";
3
+ } from "./chunk-NDV5J3Z5.js";
4
4
 
5
5
  // src/cli/setup-config.ts
6
6
  import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "fs";
@@ -77,4 +77,4 @@ function ensureBackup(outputPath) {
77
77
  export {
78
78
  runConfigInitSync
79
79
  };
80
- //# sourceMappingURL=chunk-W3ZTVYZN.js.map
80
+ //# sourceMappingURL=chunk-HDLWUFKI.js.map
@@ -5,24 +5,24 @@ import {
5
5
  planOptionalParams,
6
6
  requireApiKey,
7
7
  validateApiKeyPresence
8
- } from "./chunk-DBHK6EDT.js";
8
+ } from "./chunk-ARTIFRBA.js";
9
9
  import {
10
10
  CUSTOM_API_BASE_URL_ENV,
11
11
  CUSTOM_API_DEFAULT_MODEL,
12
12
  PROVIDER_ENV_KEYS,
13
13
  assertCustomApiHostResolvesPublic,
14
14
  validateCustomApiBaseUrl
15
- } from "./chunk-RDYGX6MQ.js";
15
+ } from "./chunk-WRZ7HENW.js";
16
16
  import {
17
17
  CliCircuitBreaker,
18
18
  DEFAULT_CIRCUIT_BREAKER_CONFIG
19
- } from "./chunk-HJZ3RES7.js";
19
+ } from "./chunk-AOXZ42SD.js";
20
20
  import {
21
21
  getAvailabilityCache
22
- } from "./chunk-EZHYOWWO.js";
22
+ } from "./chunk-LJWB4Z7O.js";
23
23
  import {
24
24
  generateHyphenId
25
- } from "./chunk-DXEYJAGO.js";
25
+ } from "./chunk-ENKFWBRH.js";
26
26
  import {
27
27
  CLI_SUBPROCESS_TIMEOUTS,
28
28
  CLI_TIMEOUTS,
@@ -58,7 +58,7 @@ import {
58
58
  loadModelsDevSnapshot,
59
59
  ok,
60
60
  resolveCliAlias
61
- } from "./chunk-WGDZFYP3.js";
61
+ } from "./chunk-NDV5J3Z5.js";
62
62
 
63
63
  // src/cli-adapters/cli-to-model-adapter.ts
64
64
  var CliToModelAdapter = class {
@@ -4867,4 +4867,4 @@ export {
4867
4867
  SdkAdapter,
4868
4868
  createAutoAdapter
4869
4869
  };
4870
- //# sourceMappingURL=chunk-WP6L2PTV.js.map
4870
+ //# sourceMappingURL=chunk-JZ3DVFEW.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  OpenAIAdapter
3
- } from "./chunk-JIXCOX7D.js";
3
+ } from "./chunk-SKJK44YC.js";
4
4
  import {
5
5
  computeCostDetail,
6
6
  recordUsageEvent
7
- } from "./chunk-6ILEOLNW.js";
7
+ } from "./chunk-UAK3OVSL.js";
8
8
  import {
9
9
  ConfigError,
10
10
  createLogger,
@@ -12,7 +12,7 @@ import {
12
12
  getErrorMessage,
13
13
  getTimeProvider,
14
14
  ok
15
- } from "./chunk-WGDZFYP3.js";
15
+ } from "./chunk-NDV5J3Z5.js";
16
16
 
17
17
  // src/config/opencode-bridge.ts
18
18
  import { readFileSync } from "fs";
@@ -194,4 +194,4 @@ export {
194
194
  discoverModels,
195
195
  buildOpenAICompatAdapters
196
196
  };
197
- //# sourceMappingURL=chunk-JYR6SBUB.js.map
197
+ //# sourceMappingURL=chunk-K5NU57WE.js.map
@@ -4,7 +4,7 @@ import {
4
4
  err,
5
5
  getErrorMessage,
6
6
  ok
7
- } from "./chunk-WGDZFYP3.js";
7
+ } from "./chunk-NDV5J3Z5.js";
8
8
 
9
9
  // src/scm/types.ts
10
10
  var ScmError = class extends Error {
@@ -263,4 +263,4 @@ export {
263
263
  ScmError,
264
264
  GitHubProvider
265
265
  };
266
- //# sourceMappingURL=chunk-GJSJRJ6Y.js.map
266
+ //# sourceMappingURL=chunk-K7GAI4WP.js.map
@@ -3,7 +3,7 @@ import {
3
3
  MODEL_IDS,
4
4
  getTimeProvider,
5
5
  resolveModelIdentitySync
6
- } from "./chunk-WGDZFYP3.js";
6
+ } from "./chunk-NDV5J3Z5.js";
7
7
 
8
8
  // src/config/model-availability.ts
9
9
  var DEFAULT_TTL_MS = 6e4;
@@ -150,4 +150,4 @@ export {
150
150
  resetAvailabilityCache,
151
151
  filterAvailableModels
152
152
  };
153
- //# sourceMappingURL=chunk-EZHYOWWO.js.map
153
+ //# sourceMappingURL=chunk-LJWB4Z7O.js.map
@@ -1,8 +1,9 @@
1
1
  import {
2
2
  ensureLearningDir,
3
3
  getDecisionCostFile,
4
+ getModelSelectionShadowFile,
4
5
  isPersistenceEnabled
5
- } from "./chunk-NL7SZQPW.js";
6
+ } from "./chunk-AXTD4TFK.js";
6
7
  import {
7
8
  nexusDataPath
8
9
  } from "./chunk-DHVMSIT5.js";
@@ -2612,7 +2613,7 @@ function setDefaultRegistry(registry) {
2612
2613
  }
2613
2614
  async function reloadDefaultRegistry() {
2614
2615
  globalRegistry = buildDefaultRegistry();
2615
- const { resetGlobalRegistry } = await import("./unified-registry-XEA2GEOZ.js");
2616
+ const { resetGlobalRegistry } = await import("./unified-registry-GAGQ2VSX.js");
2616
2617
  resetGlobalRegistry();
2617
2618
  return globalRegistry;
2618
2619
  }
@@ -9018,14 +9019,14 @@ function detectSuccessPatterns(groups, threshold) {
9018
9019
  const patterns = [];
9019
9020
  for (const g of groups) {
9020
9021
  const successCount = g.outcomes.filter((o) => o.success).length;
9021
- const successRate2 = successCount / g.outcomes.length;
9022
- if (successRate2 >= threshold) {
9022
+ const successRate3 = successCount / g.outcomes.length;
9023
+ if (successRate3 >= threshold) {
9023
9024
  patterns.push({
9024
9025
  cli: g.cli,
9025
9026
  category: g.category,
9026
9027
  patternType: "success-rate",
9027
9028
  action: "boost",
9028
- metric: successRate2,
9029
+ metric: successRate3,
9029
9030
  observationCount: g.outcomes.length
9030
9031
  });
9031
9032
  }
@@ -9218,10 +9219,10 @@ var StrategyDistiller = class {
9218
9219
  }
9219
9220
  /** Convert rule metrics into ModelPerformance for RoutingMemory. */
9220
9221
  ruleToPerformance(rule) {
9221
- const successRate2 = rule.patternType === "success-rate" ? rule.metric : 1 - rule.metric;
9222
+ const successRate3 = rule.patternType === "success-rate" ? rule.metric : 1 - rule.metric;
9222
9223
  return {
9223
9224
  avgQuality: rule.confidence,
9224
- successRate: Math.max(0, Math.min(1, successRate2)),
9225
+ successRate: Math.max(0, Math.min(1, successRate3)),
9225
9226
  avgLatencyMs: 0,
9226
9227
  avgTokens: 0,
9227
9228
  observations: rule.observationCount
@@ -12419,9 +12420,9 @@ function getAdaptiveBonus(cli, category, config) {
12419
12420
  const cliName = cli;
12420
12421
  const outcomes = queryWithLookback(store, cliName, category, cfg);
12421
12422
  if (outcomes.length < cfg.coldStartThreshold) return 0;
12422
- const successRate2 = outcomes.filter((o) => o.success).length / outcomes.length;
12423
+ const successRate3 = outcomes.filter((o) => o.success).length / outcomes.length;
12423
12424
  const FIXED_BASELINE = 0.7;
12424
- const delta = successRate2 - FIXED_BASELINE;
12425
+ const delta = successRate3 - FIXED_BASELINE;
12425
12426
  const FULL_CONFIDENCE_SAMPLES2 = 50;
12426
12427
  const windowedConfidence = Math.min(1, outcomes.length / FULL_CONFIDENCE_SAMPLES2);
12427
12428
  const maxBonus = Math.min(cfg.maxBonusAdjustment * windowedConfidence, cfg.maxBonusAdjustment);
@@ -12696,17 +12697,17 @@ function buildExpertPerformance() {
12696
12697
  const successes = outcomes.filter((o) => o.success).length;
12697
12698
  const totalDuration = outcomes.reduce((s, o) => s + o.durationMs, 0);
12698
12699
  const dominantErrorPattern = findDominantError(outcomes.filter((o) => !o.success));
12699
- const successRate2 = successes / outcomes.length;
12700
+ const successRate3 = successes / outcomes.length;
12700
12701
  const consecutiveFailures = countTrailingFailures(outcomes);
12701
12702
  const lastSuccess = [...outcomes].reverse().find((o) => o.success);
12702
12703
  const lastSuccessAt = lastSuccess !== void 0 ? new Date(lastSuccess.timestamp).toISOString() : void 0;
12703
12704
  entries.push({
12704
12705
  role,
12705
12706
  totalTasks: outcomes.length,
12706
- successRate: successRate2,
12707
+ successRate: successRate3,
12707
12708
  avgDurationMs: Math.round(totalDuration / outcomes.length),
12708
12709
  consecutiveFailures,
12709
- degraded: successRate2 < 0.5,
12710
+ degraded: successRate3 < 0.5,
12710
12711
  ...dominantErrorPattern !== void 0 ? { dominantErrorPattern } : {},
12711
12712
  ...lastSuccessAt !== void 0 ? { lastSuccessAt } : {}
12712
12713
  });
@@ -13686,6 +13687,169 @@ function resolveModelForTier(cliName, tier, opts = {}) {
13686
13687
  return scored[0]?.id ?? getDefaultModelForCli(cliName);
13687
13688
  }
13688
13689
 
13690
+ // src/cli-adapters/model-selection-shadow.ts
13691
+ import { appendFileSync as appendFileSync2, existsSync as existsSync7, readFileSync as readFileSync6 } from "fs";
13692
+ import { z as z19 } from "zod";
13693
+ function isRouteModelShadowEnabled() {
13694
+ return process.env["NEXUS_ROUTE_MODEL_SHADOW"] === "1" && isPersistenceEnabled();
13695
+ }
13696
+ var MODEL_SELECTION_SHADOW_SCHEMA_VERSION = 1;
13697
+ var READ_LOOKBACK_DAYS = 30;
13698
+ var READ_LOOKBACK_MS = READ_LOOKBACK_DAYS * 24 * 60 * 60 * 1e3;
13699
+ var ModelTierSchema = z19.enum(["fast", "balanced", "powerful"]);
13700
+ var ModelSelectionShadowRecordSchema = z19.object({
13701
+ schema: z19.literal(MODEL_SELECTION_SHADOW_SCHEMA_VERSION),
13702
+ /** ISO timestamp of the outcome join. */
13703
+ timestamp: z19.string().min(1),
13704
+ /** Display slot of the routed CLI (api:* arms collapse to their slot). */
13705
+ cli: z19.string().min(1).max(40),
13706
+ /** Difficulty tier the ZeroRouter computed for the task. */
13707
+ tier: ModelTierSchema,
13708
+ /** Model the live decision actually used (or the CLI default when route-time selection is off). */
13709
+ actualModel: z19.string().min(1).max(120),
13710
+ /** Model `resolveModelForTier` WOULD have picked (never executed). */
13711
+ shadowModel: z19.string().min(1).max(120),
13712
+ /** Whether shadow and actual agree. */
13713
+ agree: z19.boolean(),
13714
+ /** Whether the actually-executed decision succeeded. */
13715
+ success: z19.boolean(),
13716
+ /** Measured cost of the actual execution, when available (unmeasured today on the routing path). */
13717
+ costUsd: z19.number().nonnegative().optional()
13718
+ });
13719
+ function computeModelSelectionShadow(cli, tier, actualModel) {
13720
+ const shadowModel = resolveModelForTier(cli, tier);
13721
+ const actual = actualModel ?? getDefaultModelForCli(cli);
13722
+ return { cli, tier, actualModel: actual, shadowModel, agree: shadowModel === actual };
13723
+ }
13724
+ var shadowFailureCount = 0;
13725
+ function recordModelSelectionShadowFailure() {
13726
+ return ++shadowFailureCount;
13727
+ }
13728
+ var persistLogger = createLogger({ component: "ModelSelectionShadow" });
13729
+ function persistModelSelectionShadowRecord(record) {
13730
+ try {
13731
+ ensureLearningDir();
13732
+ appendFileSync2(getModelSelectionShadowFile(), JSON.stringify(record) + "\n", "utf-8");
13733
+ } catch (err2) {
13734
+ recordModelSelectionShadowFailure();
13735
+ persistLogger.warn("Failed to persist model-selection shadow record (ignored)", {
13736
+ error: getErrorMessage(err2)
13737
+ });
13738
+ }
13739
+ }
13740
+ function readModelSelectionShadowRecords() {
13741
+ const file = getModelSelectionShadowFile();
13742
+ if (!existsSync7(file)) return [];
13743
+ const records = [];
13744
+ try {
13745
+ const cutoff = Date.now() - READ_LOOKBACK_MS;
13746
+ const lines = readFileSync6(file, "utf-8").split("\n").filter((l) => l.trim().length > 0);
13747
+ for (const line of lines) {
13748
+ let parsed;
13749
+ try {
13750
+ parsed = JSON.parse(line);
13751
+ } catch {
13752
+ continue;
13753
+ }
13754
+ const result = ModelSelectionShadowRecordSchema.safeParse(parsed);
13755
+ if (!result.success) continue;
13756
+ const ts = Date.parse(result.data.timestamp);
13757
+ if (Number.isNaN(ts) || ts < cutoff) continue;
13758
+ records.push(result.data);
13759
+ }
13760
+ } catch (err2) {
13761
+ persistLogger.warn("Failed to read model-selection shadow records (ignored)", {
13762
+ error: getErrorMessage(err2)
13763
+ });
13764
+ }
13765
+ return records;
13766
+ }
13767
+
13768
+ // src/cli-adapters/model-selection-readiness.ts
13769
+ var DEFAULT_MODEL_SELECTION_READINESS_CONFIG = {
13770
+ minDivergingDecisions: 50,
13771
+ minSuccessDelta: 0.05,
13772
+ minCostSamples: 10
13773
+ };
13774
+ function successRate2(t) {
13775
+ return t.count === 0 ? 0 : t.successes / t.count;
13776
+ }
13777
+ function summarizeModelSelectionShadow(records) {
13778
+ const agree = { count: 0, successes: 0 };
13779
+ const diverge = { count: 0, successes: 0 };
13780
+ let costSamples = 0;
13781
+ let costTotal = 0;
13782
+ for (const r of records) {
13783
+ const cohort = r.agree ? agree : diverge;
13784
+ cohort.count++;
13785
+ if (r.success) cohort.successes++;
13786
+ if (r.costUsd !== void 0) {
13787
+ costSamples++;
13788
+ costTotal += r.costUsd;
13789
+ }
13790
+ }
13791
+ const agreeSuccessRate = successRate2(agree);
13792
+ const divergeSuccessRate = successRate2(diverge);
13793
+ const successDelta = agree.count === 0 || diverge.count === 0 ? 0 : agreeSuccessRate - divergeSuccessRate;
13794
+ return {
13795
+ total: records.length,
13796
+ agreeing: agree.count,
13797
+ diverging: diverge.count,
13798
+ agreeSuccessRate,
13799
+ divergeSuccessRate,
13800
+ successDelta,
13801
+ costSamples,
13802
+ meanCostUsd: costSamples === 0 ? 0 : costTotal / costSamples
13803
+ };
13804
+ }
13805
+ function evaluateModelSelectionReadiness(records, config = DEFAULT_MODEL_SELECTION_READINESS_CONFIG) {
13806
+ const s = summarizeModelSelectionShadow(records);
13807
+ const criteria = [
13808
+ {
13809
+ name: "volume",
13810
+ met: s.diverging >= config.minDivergingDecisions,
13811
+ detail: `${String(s.diverging)} shadow-diverging decisions (need \u2265 ${String(config.minDivergingDecisions)})`
13812
+ },
13813
+ {
13814
+ name: "success-delta",
13815
+ met: s.successDelta >= config.minSuccessDelta,
13816
+ detail: `agree\u2212diverge success delta ${s.successDelta.toFixed(2)} (agree ${s.agreeSuccessRate.toFixed(2)} over ${String(s.agreeing)}, diverge ${s.divergeSuccessRate.toFixed(2)} over ${String(s.diverging)}; need \u2265 ${config.minSuccessDelta.toFixed(2)})`
13817
+ },
13818
+ {
13819
+ name: "cost-measured",
13820
+ met: s.costSamples >= config.minCostSamples,
13821
+ detail: `${String(s.costSamples)} decisions with measured costUsd, mean $${s.meanCostUsd.toFixed(4)} (need \u2265 ${String(config.minCostSamples)})`
13822
+ }
13823
+ ];
13824
+ const blockers = criteria.filter((c) => !c.met).map((c) => c.name);
13825
+ return { ready: blockers.length === 0, criteria, blockers };
13826
+ }
13827
+ var readinessLogged = false;
13828
+ function logModelSelectionReadinessOnce(logger14) {
13829
+ if (readinessLogged) return;
13830
+ readinessLogged = true;
13831
+ try {
13832
+ const records = readModelSelectionShadowRecords();
13833
+ const summary = summarizeModelSelectionShadow(records);
13834
+ const verdict = evaluateModelSelectionReadiness(records);
13835
+ logger14.info("route-model-selection shadow readiness", {
13836
+ ready: verdict.ready,
13837
+ blockers: verdict.blockers,
13838
+ total: summary.total,
13839
+ diverging: summary.diverging,
13840
+ successDelta: summary.successDelta,
13841
+ agreeSuccessRate: summary.agreeSuccessRate,
13842
+ divergeSuccessRate: summary.divergeSuccessRate,
13843
+ costSamples: summary.costSamples,
13844
+ meanCostUsd: summary.meanCostUsd
13845
+ });
13846
+ } catch (err2) {
13847
+ logger14.warn("route-model-selection readiness signal failed (non-fatal)", {
13848
+ error: getErrorMessage(err2)
13849
+ });
13850
+ }
13851
+ }
13852
+
13689
13853
  // src/cli-adapters/composite-router-outcome.ts
13690
13854
  var sharedAnalyzer3 = createSharedTaskAnalyzer();
13691
13855
  function recordBanditOutcome(cliName, task, reward, deps) {
@@ -13894,6 +14058,13 @@ var CompositeRouter = class _CompositeRouter {
13894
14058
  lastRoutedTask;
13895
14059
  // Track last traceId for metrics correlation (Issue #559)
13896
14060
  lastTraceId;
14061
+ /**
14062
+ * Pending model-selection shadow comparison awaiting its outcome join
14063
+ * (#4197). Keyed by task content like {@link lastRoutedTask}; persisted with
14064
+ * `success` when `recordDifficultyOutcome` reports the matching outcome.
14065
+ * The task content itself is never persisted.
14066
+ */
14067
+ pendingModelShadow;
13897
14068
  constructor(adapters, config, logger14) {
13898
14069
  const {
13899
14070
  preferenceRouterConfig,
@@ -14078,7 +14249,7 @@ var CompositeRouter = class _CompositeRouter {
14078
14249
  */
14079
14250
  async consultUnifiedContext(task) {
14080
14251
  try {
14081
- const { getContextForTask, inferTaskCategory } = await import("./context-retriever-YGPEAEPO.js");
14252
+ const { getContextForTask, inferTaskCategory } = await import("./context-retriever-W6Z6JNEF.js");
14082
14253
  const ctx = await getContextForTask({
14083
14254
  task: task.content,
14084
14255
  category: inferTaskCategory(task.content),
@@ -14202,12 +14373,16 @@ var CompositeRouter = class _CompositeRouter {
14202
14373
  return pipelineResult;
14203
14374
  }
14204
14375
  this.trackLastRoutedTask(task, pipelineResult.value);
14205
- return this.buildRoutingDecision({
14376
+ const decisionResult = this.buildRoutingDecision({
14206
14377
  ...pipelineResult.value,
14207
14378
  taskProfile,
14208
14379
  stagesExecuted,
14209
14380
  startTime
14210
14381
  });
14382
+ if (decisionResult.ok) {
14383
+ this.trackModelSelectionShadow(task, decisionResult.value);
14384
+ }
14385
+ return decisionResult;
14211
14386
  } catch (error) {
14212
14387
  return this.handleRoutingError(error, stagesExecuted);
14213
14388
  }
@@ -14293,6 +14468,80 @@ var CompositeRouter = class _CompositeRouter {
14293
14468
  };
14294
14469
  }
14295
14470
  }
14471
+ /**
14472
+ * Compute the model-selection SHADOW comparison for a routed decision
14473
+ * (#4197): what `resolveModelForTier` WOULD have picked vs the model the
14474
+ * decision actually carries (or the CLI default the adapter will resolve).
14475
+ * Held pending until `recordDifficultyOutcome` supplies the outcome, then
14476
+ * persisted to the dedicated shadow log. Gated behind
14477
+ * `NEXUS_ROUTE_MODEL_SHADOW=1` (default OFF). NEVER affects the live
14478
+ * decision — any failure increments the shadow-failure counter and is
14479
+ * logged, not thrown into the routing path.
14480
+ *
14481
+ * Tasks with a PINNED model (`CliTask.model`) are SKIPPED entirely: the
14482
+ * adapter executes the pinned model (base-adapter), not the CLI default the
14483
+ * comparison would otherwise assume, so a pinned run says nothing about the
14484
+ * tier selector — sampling it would mislabel the agree/diverge cohorts and
14485
+ * pad the volume criterion with garbage (#4218 review).
14486
+ */
14487
+ trackModelSelectionShadow(task, decision) {
14488
+ try {
14489
+ if (!isRouteModelShadowEnabled() || decision.difficultyTier === void 0) return;
14490
+ if (task.model !== void 0) return;
14491
+ logModelSelectionReadinessOnce(this.logger);
14492
+ const comparison = computeModelSelectionShadow(
14493
+ routingArmDisplaySlot(decision.cliName),
14494
+ decision.difficultyTier,
14495
+ decision.model
14496
+ );
14497
+ this.pendingModelShadow = { ...comparison, taskContent: task.content };
14498
+ this.logger.debug("Model-selection shadow computed (#4197)", {
14499
+ cli: comparison.cli,
14500
+ tier: comparison.tier,
14501
+ actualModel: comparison.actualModel,
14502
+ shadowModel: comparison.shadowModel,
14503
+ agree: comparison.agree
14504
+ });
14505
+ } catch (error) {
14506
+ const failures = recordModelSelectionShadowFailure();
14507
+ this.logger.warn("Model-selection shadow failed (non-fatal, #4197)", {
14508
+ error: getErrorMessage(error),
14509
+ failures
14510
+ });
14511
+ }
14512
+ }
14513
+ /**
14514
+ * Join a pending model-selection shadow comparison with its task outcome and
14515
+ * persist the completed record (#4197). Matches by task content, mirroring
14516
+ * {@link getDifficultyInfo}'s lastRoutedTask join. `costUsd` is deliberately
14517
+ * absent: the routing outcome path measures no per-decision cost today, and
14518
+ * the readiness gate's cost criterion stays fail-closed until it does.
14519
+ * Exception-guarded — an outcome-join failure never breaks outcome recording.
14520
+ */
14521
+ joinModelSelectionShadowOutcome(task, success) {
14522
+ const pending = this.pendingModelShadow;
14523
+ if (pending === void 0) return;
14524
+ if (pending.taskContent !== task.content) return;
14525
+ this.pendingModelShadow = void 0;
14526
+ try {
14527
+ persistModelSelectionShadowRecord({
14528
+ schema: MODEL_SELECTION_SHADOW_SCHEMA_VERSION,
14529
+ timestamp: new Date(getTimeProvider().now()).toISOString(),
14530
+ cli: pending.cli,
14531
+ tier: pending.tier,
14532
+ actualModel: pending.actualModel,
14533
+ shadowModel: pending.shadowModel,
14534
+ agree: pending.agree,
14535
+ success
14536
+ });
14537
+ } catch (error) {
14538
+ const failures = recordModelSelectionShadowFailure();
14539
+ this.logger.warn("Model-selection shadow outcome join failed (non-fatal, #4197)", {
14540
+ error: getErrorMessage(error),
14541
+ failures
14542
+ });
14543
+ }
14544
+ }
14296
14545
  buildRoutingDecision(params) {
14297
14546
  const selectedAdapter = this.adapters.get(params.selectedCli);
14298
14547
  if (selectedAdapter === void 0) {
@@ -14373,6 +14622,7 @@ var CompositeRouter = class _CompositeRouter {
14373
14622
  }
14374
14623
  recordDifficultyOutcome(task, success, qualityScore) {
14375
14624
  recordZeroRouterOutcome(task, success, qualityScore, this.getOutcomeDependencies());
14625
+ this.joinModelSelectionShadowOutcome(task, success);
14376
14626
  }
14377
14627
  hasMinimumPreferenceData() {
14378
14628
  return hasMinimumPreferenceData(this.getOutcomeDependencies());
@@ -14503,7 +14753,7 @@ import { dirname as dirname5 } from "path";
14503
14753
  import { mkdirSync as mkdirSync3 } from "fs";
14504
14754
 
14505
14755
  // src/context/mobimem-types.ts
14506
- import { z as z19 } from "zod";
14756
+ import { z as z20 } from "zod";
14507
14757
  var DEFAULT_MOBIMEM_CONFIG = {
14508
14758
  dbPath: ":memory:",
14509
14759
  maxProfileEntries: 100,
@@ -14515,15 +14765,15 @@ var DEFAULT_MOBIMEM_CONFIG = {
14515
14765
  minExperienceSuccessRate: 0.7,
14516
14766
  autoEviction: true
14517
14767
  };
14518
- var MobiMemConfigSchema = z19.object({
14519
- dbPath: z19.string(),
14520
- maxProfileEntries: z19.number().int().positive().default(100),
14521
- maxExperiencePatterns: z19.number().int().positive().default(500),
14522
- maxActionCacheEntries: z19.number().int().positive().default(1e3),
14523
- actionCacheTtlMs: z19.number().int().positive().default(36e5),
14524
- minProfileConfidence: z19.number().min(0).max(1).default(0.6),
14525
- minExperienceSuccessRate: z19.number().min(0).max(1).default(0.7),
14526
- autoEviction: z19.boolean().default(true)
14768
+ var MobiMemConfigSchema = z20.object({
14769
+ dbPath: z20.string(),
14770
+ maxProfileEntries: z20.number().int().positive().default(100),
14771
+ maxExperiencePatterns: z20.number().int().positive().default(500),
14772
+ maxActionCacheEntries: z20.number().int().positive().default(1e3),
14773
+ actionCacheTtlMs: z20.number().int().positive().default(36e5),
14774
+ minProfileConfidence: z20.number().min(0).max(1).default(0.6),
14775
+ minExperienceSuccessRate: z20.number().min(0).max(1).default(0.7),
14776
+ autoEviction: z20.boolean().default(true)
14527
14777
  });
14528
14778
 
14529
14779
  // src/context/mobimem-impl.ts
@@ -14543,9 +14793,9 @@ function generatePatternKey(taskType, actionSequence, contextSignature) {
14543
14793
  function hashInput(input) {
14544
14794
  return createHash2("sha256").update(JSON.stringify(input)).digest("hex");
14545
14795
  }
14546
- function calculatePatternScore(successRate2, contextMatches, attemptCount) {
14796
+ function calculatePatternScore(successRate3, contextMatches, attemptCount) {
14547
14797
  const contextMatch = contextMatches ? 1 : 0.5;
14548
- return successRate2 * contextMatch * Math.log10(attemptCount + 1);
14798
+ return successRate3 * contextMatch * Math.log10(attemptCount + 1);
14549
14799
  }
14550
14800
  function computeSuccessRate(successCount, attemptCount) {
14551
14801
  return attemptCount > 0 ? successCount / attemptCount : 0;
@@ -15588,4 +15838,4 @@ export {
15588
15838
  AgentCapability,
15589
15839
  OrchestratorError
15590
15840
  };
15591
- //# sourceMappingURL=chunk-WGDZFYP3.js.map
15841
+ //# sourceMappingURL=chunk-NDV5J3Z5.js.map