nexus-agents 8.103.2 → 8.103.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 (135) hide show
  1. package/dist/{ast-rule-runner-VIIZKD35.js → ast-rule-runner-XJLYSAGE.js} +3 -3
  2. package/dist/{child-mcp-config-2JYO5AJP.js → child-mcp-config-U6SFHNXN.js} +2 -2
  3. package/dist/{chunk-WWDTDPX4.js → chunk-24XTED4P.js} +2 -2
  4. package/dist/{chunk-FU3IJOUI.js → chunk-3IZPJAIC.js} +5 -5
  5. package/dist/{chunk-SXO5CV6E.js → chunk-5LG5RMTM.js} +2 -2
  6. package/dist/{chunk-JFQJLOW4.js → chunk-6PB7JUNT.js} +4 -4
  7. package/dist/{chunk-4K3SY7XD.js → chunk-73Y7XRKL.js} +10 -79
  8. package/dist/chunk-73Y7XRKL.js.map +1 -0
  9. package/dist/{chunk-F7SZ56LN.js → chunk-BNRWICG7.js} +8 -8
  10. package/dist/{chunk-GAYE5GWR.js → chunk-EBABZGF7.js} +4 -4
  11. package/dist/{chunk-USGPMAWQ.js → chunk-FKN4CJDF.js} +4 -4
  12. package/dist/{chunk-MG7HNWZT.js → chunk-G47BD5WL.js} +2 -2
  13. package/dist/{chunk-HI5SDT6A.js → chunk-HCPESANB.js} +2 -2
  14. package/dist/{chunk-TFAI7OB7.js → chunk-HDERP5V6.js} +2 -2
  15. package/dist/{chunk-Q34QYIQZ.js → chunk-ISKYBNLW.js} +2 -2
  16. package/dist/{chunk-5TRW6QSO.js → chunk-IXYKYOYP.js} +42 -40
  17. package/dist/{chunk-5TRW6QSO.js.map → chunk-IXYKYOYP.js.map} +1 -1
  18. package/dist/chunk-JX7D7GXS.js +82 -0
  19. package/dist/chunk-JX7D7GXS.js.map +1 -0
  20. package/dist/{chunk-2SAKTPAB.js → chunk-K3QNYYJZ.js} +2 -2
  21. package/dist/{chunk-QOBBJAQK.js → chunk-K3XIXAWE.js} +2 -2
  22. package/dist/{chunk-DUHH2IS4.js → chunk-KGLMAIY3.js} +3 -3
  23. package/dist/{chunk-Y365LONR.js → chunk-KH3QDRPJ.js} +2 -2
  24. package/dist/{chunk-CRTPETKD.js → chunk-KIKYLN2U.js} +2 -2
  25. package/dist/{chunk-UP2GSUT5.js → chunk-KKGN23Z5.js} +4 -4
  26. package/dist/{chunk-NIMOQ4ZY.js → chunk-LJJHGXLZ.js} +3 -3
  27. package/dist/{chunk-JL22F4XW.js → chunk-LSSX77DS.js} +5 -5
  28. package/dist/{chunk-5ZONF4CQ.js → chunk-NAQDGUNA.js} +2 -2
  29. package/dist/{chunk-JI4WSYTK.js → chunk-PTB4NERU.js} +3 -3
  30. package/dist/{chunk-AKOWEZKO.js → chunk-PV7WSTTS.js} +2 -2
  31. package/dist/{chunk-SFXQEW3O.js → chunk-Q3JF6G7N.js} +3 -3
  32. package/dist/{chunk-XPXTELLI.js → chunk-QDELEGK7.js} +2 -2
  33. package/dist/{chunk-7LX3GAS5.js → chunk-RSDRQQTA.js} +25 -10
  34. package/dist/chunk-RSDRQQTA.js.map +1 -0
  35. package/dist/{chunk-ILUSO4TT.js → chunk-S6PDNDLL.js} +2 -2
  36. package/dist/{chunk-P6UFA2UN.js → chunk-SGRWJW57.js} +2 -2
  37. package/dist/{chunk-2DBAC2OY.js → chunk-ULL23ADE.js} +13 -11
  38. package/dist/{chunk-2DBAC2OY.js.map → chunk-ULL23ADE.js.map} +1 -1
  39. package/dist/{chunk-3GYS7COR.js → chunk-W7IFJFYX.js} +3 -3
  40. package/dist/{chunk-47G5DKIB.js → chunk-XEXQG3VV.js} +2 -2
  41. package/dist/{chunk-F2UTYE6D.js → chunk-YOEWP7LI.js} +12 -12
  42. package/dist/{chunk-JZQQVIKS.js → chunk-ZG6UJP6U.js} +2 -2
  43. package/dist/{cli-circuit-breaker-TUSDZ2SV.js → cli-circuit-breaker-XWXGC4LJ.js} +3 -3
  44. package/dist/cli.js +47 -45
  45. package/dist/cli.js.map +1 -1
  46. package/dist/{composite-router-RPUHBTVN.js → composite-router-ZY5ZYCJ6.js} +2 -2
  47. package/dist/{consensus-vote-NBVBPFIB.js → consensus-vote-QYKZ4Y73.js} +17 -16
  48. package/dist/{context-retriever-BKOWAH5O.js → context-retriever-EXBO3PJ3.js} +8 -8
  49. package/dist/{doctor-deep-KNTBC4H2.js → doctor-deep-TB36AVUC.js} +3 -3
  50. package/dist/{doctor-gateway-report-HOQXHTPV.js → doctor-gateway-report-3IOPQ5ZY.js} +6 -6
  51. package/dist/{doctor-live-GZDB4B33.js → doctor-live-VK7XA7SX.js} +10 -10
  52. package/dist/{expert-bridge-YGKTCGCZ.js → expert-bridge-NOHPIEDY.js} +5 -4
  53. package/dist/{factory-5QHVFCXC.js → factory-2QMQC7MF.js} +9 -9
  54. package/dist/{factory-22OXEIIE.js → factory-NINQ76ZS.js} +5 -5
  55. package/dist/{improvement-review-XTP7JMEZ.js → improvement-review-JAX2WDGT.js} +5 -5
  56. package/dist/index.js +32 -31
  57. package/dist/index.js.map +1 -1
  58. package/dist/{init-opencode-ETQVTJS2.js → init-opencode-TYXXLQCC.js} +5 -5
  59. package/dist/issue-triage-NTSZQ6M5.js +16 -0
  60. package/dist/{openai-compat-adapter-OYPGYA7H.js → openai-compat-adapter-KDVYYW3X.js} +5 -5
  61. package/dist/{pr-reviewer-helpers-UQCX6JJV.js → pr-reviewer-helpers-R3IC24OM.js} +4 -4
  62. package/dist/{registry-command-5ZDFQVNQ.js → registry-command-S6F5AL2O.js} +2 -2
  63. package/dist/{repo-security-plan-C3E4UCMK.js → repo-security-plan-4ISGRT2F.js} +3 -3
  64. package/dist/{research-helpers-synthesize-MHHRXBUM.js → research-helpers-synthesize-HYDSM5TV.js} +4 -4
  65. package/dist/{routing-memory-ZY2HWUJH.js → routing-memory-VR36BYAN.js} +2 -2
  66. package/dist/{session-memory-OTOULTRW.js → session-memory-4SOE5DXW.js} +3 -3
  67. package/dist/{setup-config-2WG42YRL.js → setup-config-GMMASPIP.js} +3 -3
  68. package/dist/{setup-custom-api-XLCFXFP6.js → setup-custom-api-5DUXUYZV.js} +4 -4
  69. package/dist/setup-data-dir-RPDT6UGI.js +34 -0
  70. package/dist/{tool-memory-FQR6ZO5H.js → tool-memory-EPQZ2ZY7.js} +5 -5
  71. package/dist/{unified-registry-F23TAIRP.js → unified-registry-I76W6WEZ.js} +11 -10
  72. package/dist/{weather-report-6XYTDVTL.js → weather-report-G4EUXYN4.js} +2 -2
  73. package/package.json +1 -1
  74. package/dist/chunk-4K3SY7XD.js.map +0 -1
  75. package/dist/chunk-7LX3GAS5.js.map +0 -1
  76. package/dist/issue-triage-LWHJZJXW.js +0 -16
  77. package/dist/setup-data-dir-BOZJED5R.js +0 -33
  78. /package/dist/{ast-rule-runner-VIIZKD35.js.map → ast-rule-runner-XJLYSAGE.js.map} +0 -0
  79. /package/dist/{child-mcp-config-2JYO5AJP.js.map → child-mcp-config-U6SFHNXN.js.map} +0 -0
  80. /package/dist/{chunk-WWDTDPX4.js.map → chunk-24XTED4P.js.map} +0 -0
  81. /package/dist/{chunk-FU3IJOUI.js.map → chunk-3IZPJAIC.js.map} +0 -0
  82. /package/dist/{chunk-SXO5CV6E.js.map → chunk-5LG5RMTM.js.map} +0 -0
  83. /package/dist/{chunk-JFQJLOW4.js.map → chunk-6PB7JUNT.js.map} +0 -0
  84. /package/dist/{chunk-F7SZ56LN.js.map → chunk-BNRWICG7.js.map} +0 -0
  85. /package/dist/{chunk-GAYE5GWR.js.map → chunk-EBABZGF7.js.map} +0 -0
  86. /package/dist/{chunk-USGPMAWQ.js.map → chunk-FKN4CJDF.js.map} +0 -0
  87. /package/dist/{chunk-MG7HNWZT.js.map → chunk-G47BD5WL.js.map} +0 -0
  88. /package/dist/{chunk-HI5SDT6A.js.map → chunk-HCPESANB.js.map} +0 -0
  89. /package/dist/{chunk-TFAI7OB7.js.map → chunk-HDERP5V6.js.map} +0 -0
  90. /package/dist/{chunk-Q34QYIQZ.js.map → chunk-ISKYBNLW.js.map} +0 -0
  91. /package/dist/{chunk-2SAKTPAB.js.map → chunk-K3QNYYJZ.js.map} +0 -0
  92. /package/dist/{chunk-QOBBJAQK.js.map → chunk-K3XIXAWE.js.map} +0 -0
  93. /package/dist/{chunk-DUHH2IS4.js.map → chunk-KGLMAIY3.js.map} +0 -0
  94. /package/dist/{chunk-Y365LONR.js.map → chunk-KH3QDRPJ.js.map} +0 -0
  95. /package/dist/{chunk-CRTPETKD.js.map → chunk-KIKYLN2U.js.map} +0 -0
  96. /package/dist/{chunk-UP2GSUT5.js.map → chunk-KKGN23Z5.js.map} +0 -0
  97. /package/dist/{chunk-NIMOQ4ZY.js.map → chunk-LJJHGXLZ.js.map} +0 -0
  98. /package/dist/{chunk-JL22F4XW.js.map → chunk-LSSX77DS.js.map} +0 -0
  99. /package/dist/{chunk-5ZONF4CQ.js.map → chunk-NAQDGUNA.js.map} +0 -0
  100. /package/dist/{chunk-JI4WSYTK.js.map → chunk-PTB4NERU.js.map} +0 -0
  101. /package/dist/{chunk-AKOWEZKO.js.map → chunk-PV7WSTTS.js.map} +0 -0
  102. /package/dist/{chunk-SFXQEW3O.js.map → chunk-Q3JF6G7N.js.map} +0 -0
  103. /package/dist/{chunk-XPXTELLI.js.map → chunk-QDELEGK7.js.map} +0 -0
  104. /package/dist/{chunk-ILUSO4TT.js.map → chunk-S6PDNDLL.js.map} +0 -0
  105. /package/dist/{chunk-P6UFA2UN.js.map → chunk-SGRWJW57.js.map} +0 -0
  106. /package/dist/{chunk-3GYS7COR.js.map → chunk-W7IFJFYX.js.map} +0 -0
  107. /package/dist/{chunk-47G5DKIB.js.map → chunk-XEXQG3VV.js.map} +0 -0
  108. /package/dist/{chunk-F2UTYE6D.js.map → chunk-YOEWP7LI.js.map} +0 -0
  109. /package/dist/{chunk-JZQQVIKS.js.map → chunk-ZG6UJP6U.js.map} +0 -0
  110. /package/dist/{cli-circuit-breaker-TUSDZ2SV.js.map → cli-circuit-breaker-XWXGC4LJ.js.map} +0 -0
  111. /package/dist/{composite-router-RPUHBTVN.js.map → composite-router-ZY5ZYCJ6.js.map} +0 -0
  112. /package/dist/{consensus-vote-NBVBPFIB.js.map → consensus-vote-QYKZ4Y73.js.map} +0 -0
  113. /package/dist/{context-retriever-BKOWAH5O.js.map → context-retriever-EXBO3PJ3.js.map} +0 -0
  114. /package/dist/{doctor-deep-KNTBC4H2.js.map → doctor-deep-TB36AVUC.js.map} +0 -0
  115. /package/dist/{doctor-gateway-report-HOQXHTPV.js.map → doctor-gateway-report-3IOPQ5ZY.js.map} +0 -0
  116. /package/dist/{doctor-live-GZDB4B33.js.map → doctor-live-VK7XA7SX.js.map} +0 -0
  117. /package/dist/{expert-bridge-YGKTCGCZ.js.map → expert-bridge-NOHPIEDY.js.map} +0 -0
  118. /package/dist/{factory-22OXEIIE.js.map → factory-2QMQC7MF.js.map} +0 -0
  119. /package/dist/{factory-5QHVFCXC.js.map → factory-NINQ76ZS.js.map} +0 -0
  120. /package/dist/{improvement-review-XTP7JMEZ.js.map → improvement-review-JAX2WDGT.js.map} +0 -0
  121. /package/dist/{init-opencode-ETQVTJS2.js.map → init-opencode-TYXXLQCC.js.map} +0 -0
  122. /package/dist/{issue-triage-LWHJZJXW.js.map → issue-triage-NTSZQ6M5.js.map} +0 -0
  123. /package/dist/{openai-compat-adapter-OYPGYA7H.js.map → openai-compat-adapter-KDVYYW3X.js.map} +0 -0
  124. /package/dist/{pr-reviewer-helpers-UQCX6JJV.js.map → pr-reviewer-helpers-R3IC24OM.js.map} +0 -0
  125. /package/dist/{registry-command-5ZDFQVNQ.js.map → registry-command-S6F5AL2O.js.map} +0 -0
  126. /package/dist/{repo-security-plan-C3E4UCMK.js.map → repo-security-plan-4ISGRT2F.js.map} +0 -0
  127. /package/dist/{research-helpers-synthesize-MHHRXBUM.js.map → research-helpers-synthesize-HYDSM5TV.js.map} +0 -0
  128. /package/dist/{routing-memory-ZY2HWUJH.js.map → routing-memory-VR36BYAN.js.map} +0 -0
  129. /package/dist/{session-memory-OTOULTRW.js.map → session-memory-4SOE5DXW.js.map} +0 -0
  130. /package/dist/{setup-config-2WG42YRL.js.map → setup-config-GMMASPIP.js.map} +0 -0
  131. /package/dist/{setup-custom-api-XLCFXFP6.js.map → setup-custom-api-5DUXUYZV.js.map} +0 -0
  132. /package/dist/{setup-data-dir-BOZJED5R.js.map → setup-data-dir-RPDT6UGI.js.map} +0 -0
  133. /package/dist/{tool-memory-FQR6ZO5H.js.map → tool-memory-EPQZ2ZY7.js.map} +0 -0
  134. /package/dist/{unified-registry-F23TAIRP.js.map → unified-registry-I76W6WEZ.js.map} +0 -0
  135. /package/dist/{weather-report-6XYTDVTL.js.map → weather-report-G4EUXYN4.js.map} +0 -0
@@ -9,8 +9,8 @@ import {
9
9
  getBuiltInAstRulesPath,
10
10
  loadRules,
11
11
  runAstQaRules
12
- } from "./chunk-47G5DKIB.js";
13
- import "./chunk-DUHH2IS4.js";
12
+ } from "./chunk-XEXQG3VV.js";
13
+ import "./chunk-KGLMAIY3.js";
14
14
  import "./chunk-UE7A2XHM.js";
15
15
  import "./chunk-LWOX65CP.js";
16
16
  import "./chunk-PX6F3LHL.js";
@@ -26,4 +26,4 @@ export {
26
26
  loadRules,
27
27
  runAstQaRules
28
28
  };
29
- //# sourceMappingURL=ast-rule-runner-VIIZKD35.js.map
29
+ //# sourceMappingURL=ast-rule-runner-XJLYSAGE.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-OITVVSWO.js";
4
4
  import {
5
5
  createLogger
6
- } from "./chunk-DUHH2IS4.js";
6
+ } from "./chunk-KGLMAIY3.js";
7
7
  import "./chunk-UE7A2XHM.js";
8
8
  import "./chunk-LWOX65CP.js";
9
9
  import "./chunk-PX6F3LHL.js";
@@ -56,4 +56,4 @@ async function generateMcpConfig(options) {
56
56
  export {
57
57
  generateMcpConfig
58
58
  };
59
- //# sourceMappingURL=child-mcp-config-2JYO5AJP.js.map
59
+ //# sourceMappingURL=child-mcp-config-U6SFHNXN.js.map
@@ -2,7 +2,7 @@ import {
2
2
  CACHE_TIMEOUTS,
3
3
  createLogger,
4
4
  getTimeProvider
5
- } from "./chunk-DUHH2IS4.js";
5
+ } from "./chunk-KGLMAIY3.js";
6
6
 
7
7
  // src/security/trust-types.ts
8
8
  import { z } from "zod";
@@ -610,4 +610,4 @@ export {
610
610
  resolveReputationGatingMode,
611
611
  gateWithReputation
612
612
  };
613
- //# sourceMappingURL=chunk-WWDTDPX4.js.map
613
+ //# sourceMappingURL=chunk-24XTED4P.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-W654ME6B.js";
4
4
  import {
5
5
  resolveToken
6
- } from "./chunk-ILUSO4TT.js";
6
+ } from "./chunk-S6PDNDLL.js";
7
7
  import {
8
8
  REGISTRY_PATH,
9
9
  getProjectRoot,
@@ -11,10 +11,10 @@ import {
11
11
  loadTechniquesRegistry,
12
12
  resolveInsideRoot,
13
13
  savePapersRegistry
14
- } from "./chunk-SXO5CV6E.js";
14
+ } from "./chunk-5LG5RMTM.js";
15
15
  import {
16
16
  getToolMemory
17
- } from "./chunk-UP2GSUT5.js";
17
+ } from "./chunk-KKGN23Z5.js";
18
18
  import {
19
19
  capitalizeWords,
20
20
  tokenizeFiltered,
@@ -43,7 +43,7 @@ import {
43
43
  ok,
44
44
  registerPersistentDistillerFactory,
45
45
  sigmoidConfidence
46
- } from "./chunk-DUHH2IS4.js";
46
+ } from "./chunk-KGLMAIY3.js";
47
47
  import {
48
48
  ensureLearningDir,
49
49
  getRulesFile
@@ -4275,4 +4275,4 @@ export {
4275
4275
  DEFAULT_CONTEXT_BUDGET_TOKENS,
4276
4276
  getContextPromptPrefix
4277
4277
  };
4278
- //# sourceMappingURL=chunk-FU3IJOUI.js.map
4278
+ //# sourceMappingURL=chunk-3IZPJAIC.js.map
@@ -5,7 +5,7 @@ import {
5
5
  err,
6
6
  getErrorMessage,
7
7
  ok
8
- } from "./chunk-DUHH2IS4.js";
8
+ } from "./chunk-KGLMAIY3.js";
9
9
  import {
10
10
  findRepoRoot,
11
11
  getActiveWorkspaceRoot,
@@ -290,4 +290,4 @@ export {
290
290
  loadPapersRegistry,
291
291
  savePapersRegistry
292
292
  };
293
- //# sourceMappingURL=chunk-SXO5CV6E.js.map
293
+ //# sourceMappingURL=chunk-5LG5RMTM.js.map
@@ -7,12 +7,12 @@ import {
7
7
  readGatewayTransport,
8
8
  requireApiKey,
9
9
  validateApiKeyPresence
10
- } from "./chunk-JZQQVIKS.js";
10
+ } from "./chunk-ZG6UJP6U.js";
11
11
  import {
12
12
  assertCustomApiHostResolvesPublic,
13
13
  hostnameOf,
14
14
  redactApiKey
15
- } from "./chunk-2SAKTPAB.js";
15
+ } from "./chunk-K3QNYYJZ.js";
16
16
  import {
17
17
  sanitizeErrorDetails
18
18
  } from "./chunk-2NDA4DHW.js";
@@ -40,7 +40,7 @@ import {
40
40
  readModelAllowlist,
41
41
  recordUsageEvent,
42
42
  refineGatewayCatalog
43
- } from "./chunk-DUHH2IS4.js";
43
+ } from "./chunk-KGLMAIY3.js";
44
44
 
45
45
  // src/adapters/openai-compat-adapter.ts
46
46
  import OpenAI2 from "openai";
@@ -1038,4 +1038,4 @@ export {
1038
1038
  createOpenAICompatAdapter,
1039
1039
  buildOpenAICompatAdapters
1040
1040
  };
1041
- //# sourceMappingURL=chunk-JFQJLOW4.js.map
1041
+ //# sourceMappingURL=chunk-6PB7JUNT.js.map
@@ -1,10 +1,14 @@
1
+ import {
2
+ ensureGatewayDiscovered,
3
+ gatewayDiscoveryGeneration
4
+ } from "./chunk-JX7D7GXS.js";
1
5
  import {
2
6
  createAutoAdapter
3
- } from "./chunk-F7SZ56LN.js";
7
+ } from "./chunk-BNRWICG7.js";
4
8
  import {
5
9
  getDefaultCliCircuitBreakerRegistry,
6
10
  mapModelErrorToCategory
7
- } from "./chunk-XPXTELLI.js";
11
+ } from "./chunk-QDELEGK7.js";
8
12
  import {
9
13
  CircularBuffer,
10
14
  ConfigError,
@@ -30,7 +34,7 @@ import {
30
34
  resolveModelIdentitySync,
31
35
  toRateLimitError,
32
36
  warnIfGatewayCostUndeclared
33
- } from "./chunk-DUHH2IS4.js";
37
+ } from "./chunk-KGLMAIY3.js";
34
38
 
35
39
  // src/config/model-equivalence.ts
36
40
  var VARIANT_QUIRKS = /* @__PURE__ */ new Set(["small", "image"]);
@@ -64,76 +68,6 @@ function assessPanelIndependence(modelIds) {
64
68
  return { kind: "diverse", distinct };
65
69
  }
66
70
 
67
- // src/adapters/gateway-rediscovery.ts
68
- var GATEWAY_REDISCOVERY_INTERVAL_MS = 6e4;
69
- var generation = 0;
70
- function gatewayDiscoveryGeneration() {
71
- return generation;
72
- }
73
- var GatewayRediscovery = class {
74
- constructor(options) {
75
- this.options = options;
76
- this.minIntervalMs = options.minIntervalMs ?? GATEWAY_REDISCOVERY_INTERVAL_MS;
77
- this.lastAttemptAt = options.lastAttemptAt ?? getTimeProvider().now();
78
- }
79
- options;
80
- minIntervalMs;
81
- lastAttemptAt;
82
- inFlight;
83
- refused = false;
84
- /**
85
- * Re-run discovery if the gateway is still missing and the backoff allows.
86
- * Never rejects: a failed attempt is logged and the caller proceeds on
87
- * whatever the list holds (empty means the CLI path, as at boot).
88
- */
89
- ensure() {
90
- if (this.refused || this.options.target.length > 0) return Promise.resolve();
91
- if (this.inFlight !== void 0) return this.inFlight;
92
- const now = getTimeProvider().now();
93
- if (now - this.lastAttemptAt < this.minIntervalMs) return Promise.resolve();
94
- this.lastAttemptAt = now;
95
- this.inFlight = this.attempt().finally(() => {
96
- this.inFlight = void 0;
97
- });
98
- return this.inFlight;
99
- }
100
- async attempt() {
101
- const { logger, target } = this.options;
102
- let found;
103
- try {
104
- found = await this.options.discover();
105
- } catch (error) {
106
- logger.warn("Gateway re-discovery threw; calls stay on CLI subprocesses", {
107
- error: getErrorMessage(error)
108
- });
109
- return;
110
- }
111
- if (found === "refused") {
112
- this.refused = true;
113
- return;
114
- }
115
- if (found === void 0 || found.length === 0) {
116
- logger.warn(
117
- `Gateway re-discovery found no usable gateway; calls stay on CLI subprocesses. Next attempt no sooner than ${String(Math.round(this.minIntervalMs / 1e3))} s, on the next gateway call.`
118
- );
119
- return;
120
- }
121
- target.push(...found);
122
- logger.info("OpenAI-compatible gateway re-discovered; gateway calls now go in-process", {
123
- modelCount: found.length
124
- });
125
- this.options.onDiscovered?.(found);
126
- generation += 1;
127
- }
128
- };
129
- var active;
130
- function setGatewayRediscovery(rediscovery) {
131
- active = rediscovery;
132
- }
133
- async function ensureGatewayDiscovered() {
134
- await active?.ensure();
135
- }
136
-
137
71
  // src/agents/collaboration/event-bus-helpers.ts
138
72
  import { randomUUID } from "node:crypto";
139
73
  var DEFAULT_MAX_HISTORY_SIZE = 1e3;
@@ -625,7 +559,7 @@ var ResilientAdapter = class {
625
559
  return this.detectionPromise;
626
560
  }
627
561
  async detectAdapter() {
628
- const generation2 = gatewayDiscoveryGeneration();
562
+ const generation = gatewayDiscoveryGeneration();
629
563
  try {
630
564
  this.logger.info("Detecting model adapter (lazy)");
631
565
  const config = {
@@ -637,7 +571,7 @@ var ResilientAdapter = class {
637
571
  };
638
572
  const selection = await createAutoAdapter(config);
639
573
  this.applySelection(selection);
640
- this.detectedAtGeneration = generation2;
574
+ this.detectedAtGeneration = generation;
641
575
  return this.currentAdapter;
642
576
  } catch (error) {
643
577
  const message = getErrorMessage(error);
@@ -1124,9 +1058,6 @@ export {
1124
1058
  countDistinctModels,
1125
1059
  UNRESOLVED_MODEL_ID,
1126
1060
  assessPanelIndependence,
1127
- GatewayRediscovery,
1128
- setGatewayRediscovery,
1129
- ensureGatewayDiscovered,
1130
1061
  getGlobalEventBus,
1131
1062
  createEvent,
1132
1063
  EventTopics,
@@ -1137,4 +1068,4 @@ export {
1137
1068
  getGlobalRegistry,
1138
1069
  resetGlobalRegistry
1139
1070
  };
1140
- //# sourceMappingURL=chunk-4K3SY7XD.js.map
1071
+ //# sourceMappingURL=chunk-73Y7XRKL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/model-equivalence.ts","../src/agents/collaboration/event-bus-helpers.ts","../src/agents/collaboration/event-bus.ts","../src/agents/collaboration/event-bus-topics.ts","../src/adapters/resilient-adapter.ts","../src/adapters/model-bound-adapter.ts","../src/adapters/unified-registry.ts"],"sourcesContent":["/**\n * nexus-agents/config - Canonical model equivalence\n *\n * Answers \"are these two model strings the same underlying model?\" (#4390).\n *\n * The same weights are reachable through several gateways under different\n * strings — `claude-sonnet-4-6` via the claude CLI,\n * `anthropic/claude-sonnet-4-6` via opencode, `custom/claude-sonnet-4-6` via an\n * OpenAI-compatible endpoint. Comparing those strings directly makes one model\n * look like three, which is why the consensus panel's diversity check could not\n * see two roles running identical weights, and why cost rollup prices one model\n * as several.\n *\n * Measured context for why this matters at all: of 2,955 distinct model ids on\n * models.dev, 943 are served by more than one provider. `claude-sonnet-4-6`\n * alone is served by 19.\n *\n * @module config/model-equivalence\n */\n\nimport { canonicalVersionKey, resolveModelIdentitySync } from './model-identity.js';\n\n/**\n * A key that is equal for two model strings iff they denote the same model, or\n * `null` when the model cannot be identified.\n *\n * `null` is deliberate rather than a sentinel string. A bare alias like\n * `sonnet` — which the claude CLI adapter really can report — resolves to\n * `unknown` vendor and family. If unidentifiable models shared a key they would\n * compare EQUAL to each other, so two genuinely different models would be\n * called the same. That is the inverse of the bug this module fixes, and the\n * worse direction: it would silence a diversity warning that should fire.\n *\n * Gateway prefixes are handled by `resolveModelIdentitySync`, which normalises\n * `/` to `-` and matches vendor/family with unanchored patterns. That behaviour\n * is incidental to its design but is test-covered for the prefixed form.\n */\n/**\n * Quirks that denote distinct model weights or output modalities (#6616).\n *\n * `small` (mini, nano, lite) and `image` (image generation) distinguish\n * variants that otherwise share a vendor, family, and version with the base\n * model (e.g. `gpt-4o` vs `gpt-4o-mini`, or `gemini-2.5-flash` vs\n * `gemini-2.5-flash-image`).\n */\nconst VARIANT_QUIRKS: ReadonlySet<string> = new Set(['small', 'image']);\n\nexport function canonicalModelKey(modelId: string): string | null {\n if (modelId === '') return null;\n const identity = resolveModelIdentitySync(modelId);\n if (identity.vendor === 'unknown' || identity.family === 'unknown') return null;\n // The version goes through the registry's version key, so `4.5` and `4-5`\n // name one model here exactly as they do in registry lookup (#6605).\n const version = identity.version === undefined ? '' : canonicalVersionKey(identity.version);\n // Size and modality variants denote different weights (#6616).\n const variant = identity.quirks\n .filter((q) => VARIANT_QUIRKS.has(q))\n .sort()\n .join('-');\n return variant === ''\n ? `${identity.vendor}|${identity.family}|${version}`\n : `${identity.vendor}|${identity.family}|${version}|${variant}`;\n}\n\n/**\n * How many genuinely distinct models a set of model strings represents.\n *\n * Unidentifiable entries are counted by their raw string: two adapters\n * configured with the same unrecognised model ARE the same adapter config, but\n * two different unrecognised strings must never be assumed equivalent.\n */\nexport function countDistinctModels(modelIds: readonly string[]): number {\n const distinct = new Set<string>();\n for (const id of modelIds) {\n const key = canonicalModelKey(id);\n // Prefix the raw fallback so an unresolvable string can never collide with\n // a resolved key.\n distinct.add(key ?? `raw:${id}`);\n }\n return distinct.size;\n}\n\n/**\n * What a {@link ResilientAdapter} reports as its `modelId` before lazy\n * detection (#811) resolves a concrete CLI behind it.\n *\n * It is a placeholder, not a model. The distinction matters because\n * {@link countDistinctModels} treats two identical unrecognised strings as one\n * model — true of two adapters configured alike, false of two adapters that\n * have merely not looked yet.\n */\nexport const UNRESOLVED_MODEL_ID = 'pending-detection';\n\n/**\n * Whether a voter panel's roles run on genuinely different models.\n *\n * `unmeasured` is a distinct outcome rather than a defaulted `diverse` or\n * `collapsed`: a panel nobody could measure is not a healthy panel and not a\n * correlated one, and reporting either would be inventing a measurement\n * (#4983).\n */\nexport type PanelIndependence =\n | { readonly kind: 'unmeasured'; readonly unresolved: number; readonly total: number }\n | { readonly kind: 'collapsed'; readonly model: string }\n | { readonly kind: 'diverse'; readonly distinct: number };\n\n/**\n * Classifies a panel from the model ids its role adapters report.\n *\n * Any unresolved id makes the whole panel unmeasured. Concluding from the\n * resolved subset would be guessing: two resolved ids that collide say nothing\n * about the arm that has not reported yet.\n */\nexport function assessPanelIndependence(\n modelIds: readonly (string | undefined)[]\n): PanelIndependence {\n // `undefined` is in the input type because real adapters supply it: the\n // interface declares `modelId: string`, but an adapter constructed without\n // one reports undefined at runtime, and this runs AFTER the votes are in —\n // a diagnostic that throws here would discard a completed panel's results.\n const resolved = modelIds.filter(\n (id): id is string => typeof id === 'string' && id !== '' && id !== UNRESOLVED_MODEL_ID\n );\n const unresolved = modelIds.length - resolved.length;\n // An empty panel is unmeasured, not diverse — `countDistinctModels([])` is 0,\n // which would otherwise slip past the `=== 1` collapse test and report the\n // absence of any adapter as a healthy spread.\n if (unresolved > 0 || modelIds.length === 0) {\n return { kind: 'unmeasured', unresolved, total: modelIds.length };\n }\n const distinct = countDistinctModels(resolved);\n if (distinct === 1) return { kind: 'collapsed', model: resolved[0] ?? '' };\n return { kind: 'diverse', distinct };\n}\n","/**\n * Event Bus Helper Functions\n *\n * Pure utility functions for event bus operations.\n * Extracted from event-bus.ts to maintain file size limits.\n *\n * @module agents/collaboration/event-bus-helpers\n * (Source: Issue #182, ARCHITECTURE.md Hybrid Architecture)\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { getTimeProvider } from '../../core/index.js';\nimport type { SubscriptionId, TopicPattern, DomainEvent, EventFilter } from './event-bus-types.js';\n\n/** Default maximum history size */\nexport const DEFAULT_MAX_HISTORY_SIZE = 1000;\n\n/** Maximum number of subscriptions per bus */\nexport const MAX_SUBSCRIPTIONS = 500;\n\n/**\n * Internal subscription record.\n */\nexport interface SubscriptionRecord {\n readonly id: SubscriptionId;\n readonly pattern: TopicPattern;\n readonly regex: RegExp;\n readonly listener: (event: DomainEvent) => void | Promise<void>;\n}\n\n/** Maximum allowed topic pattern length */\nconst MAX_TOPIC_PATTERN_LENGTH = 200;\n\n/**\n * Convert a topic pattern to a regex for matching.\n * Supports wildcard patterns:\n * - 'session.created' -> exact match\n * - 'session.*' -> matches session.anything\n * - '*' -> matches everything\n *\n * Security Note (Issue #341): This function is safe from ReDoS because:\n * 1. The input is fully escaped before regex construction\n * 2. Only `*` wildcards are converted to `[^.]+` (bounded, non-greedy)\n * 3. Pattern length is bounded to prevent memory issues\n *\n * @throws Error if pattern exceeds MAX_TOPIC_PATTERN_LENGTH\n */\nexport function patternToRegex(pattern: TopicPattern): RegExp {\n // Validate length to prevent memory issues (Issue #341)\n if (pattern.length > MAX_TOPIC_PATTERN_LENGTH) {\n throw new Error(`Topic pattern exceeds maximum length of ${String(MAX_TOPIC_PATTERN_LENGTH)}`);\n }\n\n if (pattern === '*') {\n return /^.+$/;\n }\n // Use placeholder for * before escaping, then restore as regex wildcard\n // WILDCARD_PLACEHOLDER is a static constant, safe for RegExp (Issue #341)\n const WILDCARD_PLACEHOLDER = '\\x00WILDCARD\\x00';\n const withPlaceholder = pattern.replace(/\\*/g, WILDCARD_PLACEHOLDER);\n // Escape all regex special characters - this makes the pattern safe\n const escaped = withPlaceholder.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n // Replace placeholder with bounded wildcard - safe since input was escaped\n const withWildcards = escaped.replace(new RegExp(WILDCARD_PLACEHOLDER, 'g'), '[^.]+');\n return new RegExp(`^${withWildcards}$`);\n}\n\n/**\n * Check if a topic matches a pattern.\n */\nexport function topicMatchesPattern(topic: string, regex: RegExp): boolean {\n return regex.test(topic);\n}\n\n/**\n * Generate a unique event ID.\n */\nexport function generateEventId(): string {\n return `evt-${String(getTimeProvider().now())}-${randomUUID().slice(0, 8)}`;\n}\n\n/**\n * Generate a unique subscription ID.\n */\nexport function generateSubscriptionId(): SubscriptionId {\n return `sub-${String(getTimeProvider().now())}-${randomUUID().slice(0, 8)}`;\n}\n\n/**\n * Generate a unique correlation ID for request tracing.\n * (Source: Issue #224, Sprint #228)\n *\n * @example\n * ```typescript\n * const correlationId = generateCorrelationId();\n * // -> 'cor_a1b2c3d4'\n * ```\n */\nexport function generateCorrelationId(): string {\n return `cor_${randomUUID().slice(0, 8)}`;\n}\n\n/**\n * Create a child correlation ID that chains to a parent.\n * Enables hierarchical tracing of subtasks.\n * (Source: Issue #224, Sprint #228)\n *\n * @param parentCorrelationId - The parent correlation ID to chain from\n * @returns A new correlation ID in format 'parentId.child_xxxxxxxx'\n *\n * @example\n * ```typescript\n * const parentId = generateCorrelationId();\n * // -> 'cor_a1b2c3d4'\n *\n * const childId = createChildCorrelationId(parentId);\n * // -> 'cor_a1b2c3d4.child_e5f6g7h8'\n * ```\n */\nexport function createChildCorrelationId(parentCorrelationId: string): string {\n return `${parentCorrelationId}.child_${randomUUID().slice(0, 8)}`;\n}\n\n/**\n * Apply topic, session, correlation, and timestamp filters to events.\n */\nexport function applyHistoryFilters(history: DomainEvent[], filter: EventFilter): DomainEvent[] {\n let result: DomainEvent[] = history;\n\n if (filter.topic !== undefined && filter.topic !== '') {\n const regex = patternToRegex(filter.topic);\n result = result.filter((e) => topicMatchesPattern(e.topic, regex));\n }\n\n if (filter.sessionId !== undefined && filter.sessionId !== '') {\n result = result.filter((e) => e.sessionId === filter.sessionId);\n }\n\n if (filter.correlationId !== undefined && filter.correlationId !== '') {\n result = result.filter((e) => e.correlationId === filter.correlationId);\n }\n\n return applyTimestampFilters(result, filter);\n}\n\n/**\n * Apply timestamp-based filters to events.\n */\nexport function applyTimestampFilters(result: DomainEvent[], filter: EventFilter): DomainEvent[] {\n let filtered = result;\n\n if (filter.after !== undefined && filter.after !== '') {\n const afterTimestamp = filter.after;\n filtered = filtered.filter((e) => e.timestamp > afterTimestamp);\n }\n\n if (filter.before !== undefined && filter.before !== '') {\n const beforeTimestamp = filter.before;\n filtered = filtered.filter((e) => e.timestamp < beforeTimestamp);\n }\n\n return filtered;\n}\n\n/**\n * Apply limit to history results.\n */\nexport function applyHistoryLimit(result: DomainEvent[], filter: EventFilter): DomainEvent[] {\n if (filter.limit !== undefined && filter.limit > 0) {\n return result.slice(-filter.limit);\n }\n return result;\n}\n\n/**\n * Enrich event with generated fields if missing.\n */\nexport function enrichEvent(event: DomainEvent): DomainEvent {\n return {\n ...event,\n eventId: event.eventId || generateEventId(),\n timestamp: event.timestamp || getTimeProvider().nowIso(),\n };\n}\n\n/**\n * Count subscribers matching a topic from a subscription map.\n */\nexport function countMatchingSubscribers(\n topic: string,\n subscriptions: Map<SubscriptionId, SubscriptionRecord>\n): number {\n let count = 0;\n for (const record of subscriptions.values()) {\n if (topicMatchesPattern(topic, record.regex)) {\n count++;\n }\n }\n return count;\n}\n","/**\n * Event Bus Implementation\n *\n * Async message passing for agent-to-agent communication.\n * Supports topic-based routing, wildcard patterns, and event history.\n *\n * @module agents/collaboration/event-bus\n * (Source: Issue #182, ARCHITECTURE.md Hybrid Architecture)\n */\n\nimport { getTimeProvider } from '../../core/index.js';\nimport type {\n ICollaborationEventBus,\n DomainEvent,\n EventListener,\n Subscription,\n SubscriptionId,\n TopicPattern,\n EventFilter,\n EventBusOptions,\n EventBusStats,\n} from './event-bus-types.js';\n\nimport {\n DEFAULT_MAX_HISTORY_SIZE,\n MAX_SUBSCRIPTIONS,\n type SubscriptionRecord,\n patternToRegex,\n topicMatchesPattern,\n generateEventId,\n generateSubscriptionId,\n applyHistoryFilters,\n applyHistoryLimit,\n enrichEvent,\n countMatchingSubscribers,\n} from './event-bus-helpers.js';\n\nimport { CircularBuffer } from '../../core/circular-buffer.js';\n\n// Re-export correlation ID helpers for public API\nexport { generateCorrelationId, createChildCorrelationId } from './event-bus-helpers.js';\n\n/**\n * Event Bus for agent-to-agent communication.\n *\n * Features:\n * - Topic-based pub/sub with wildcard support\n * - Async and sync event emission\n * - Event history with filtering\n * - Error isolation (one listener failure doesn't block others)\n *\n * @example\n * ```typescript\n * const bus = new CollaborationEventBus();\n *\n * // Subscribe to all session events\n * const sub = bus.subscribe('session.*', (event) => {\n * console.log('Session event:', event.topic);\n * });\n *\n * // Emit an event\n * bus.emit(createSessionCreatedEvent({ sessionId: '123', ... }));\n *\n * // Cleanup\n * sub.unsubscribe();\n * ```\n */\nexport class CollaborationEventBus implements ICollaborationEventBus {\n private readonly subscriptions: Map<SubscriptionId, SubscriptionRecord> = new Map();\n private readonly history: CircularBuffer<DomainEvent>;\n private readonly asyncHandling: boolean;\n private readonly logger?: EventBusOptions['logger'];\n\n private stats: EventBusStats = {\n eventsEmitted: 0,\n subscriptionsCreated: 0,\n activeSubscriptions: 0,\n historySize: 0,\n errorCount: 0,\n };\n\n constructor(options: EventBusOptions = {}) {\n const maxHistorySize = options.maxHistorySize ?? DEFAULT_MAX_HISTORY_SIZE;\n this.history = new CircularBuffer<DomainEvent>(maxHistorySize);\n this.asyncHandling = options.asyncHandling ?? false;\n this.logger = options.logger;\n }\n\n /**\n * Emit an event synchronously to all matching subscribers.\n */\n emit(event: DomainEvent): void {\n const enrichedEvent = enrichEvent(event);\n this.addToHistory(enrichedEvent);\n this.stats.eventsEmitted++;\n\n this.logger?.debug('Event emitted', {\n topic: enrichedEvent.topic,\n eventId: enrichedEvent.eventId,\n subscriberCount: countMatchingSubscribers(enrichedEvent.topic, this.subscriptions),\n });\n\n for (const record of this.subscriptions.values()) {\n if (topicMatchesPattern(enrichedEvent.topic, record.regex)) {\n this.invokeListener(record, enrichedEvent);\n }\n }\n }\n\n /**\n * Emit an event and wait for all async handlers to complete.\n */\n async emitAsync(event: DomainEvent): Promise<void> {\n const enrichedEvent = enrichEvent(event);\n this.addToHistory(enrichedEvent);\n this.stats.eventsEmitted++;\n\n this.logger?.debug('Async event emitted', {\n topic: enrichedEvent.topic,\n eventId: enrichedEvent.eventId,\n });\n\n const promises: Promise<void>[] = [];\n\n for (const record of this.subscriptions.values()) {\n if (topicMatchesPattern(enrichedEvent.topic, record.regex)) {\n promises.push(this.invokeListenerAsync(record, enrichedEvent));\n }\n }\n\n await Promise.all(promises);\n }\n\n /**\n * Subscribe to events matching a topic pattern.\n */\n subscribe<T extends DomainEvent = DomainEvent>(\n pattern: TopicPattern,\n listener: EventListener<T>\n ): Subscription {\n if (this.subscriptions.size >= MAX_SUBSCRIPTIONS) {\n throw new Error(\n `Maximum subscription limit reached (${String(MAX_SUBSCRIPTIONS)}). ` +\n 'Unsubscribe from unused patterns before adding new ones.'\n );\n }\n\n const id = generateSubscriptionId();\n const regex = patternToRegex(pattern);\n\n const record: SubscriptionRecord = {\n id,\n pattern,\n regex,\n listener: listener as EventListener,\n };\n\n this.subscriptions.set(id, record);\n this.stats.subscriptionsCreated++;\n this.stats.activeSubscriptions = this.subscriptions.size;\n\n this.logger?.debug('Subscription created', { id, pattern });\n\n return {\n id,\n pattern,\n unsubscribe: () => {\n this.unsubscribe(id);\n },\n };\n }\n\n /**\n * Unsubscribe from events.\n */\n unsubscribe(subscriptionId: SubscriptionId): void {\n const existed = this.subscriptions.delete(subscriptionId);\n if (existed) {\n this.stats.activeSubscriptions = this.subscriptions.size;\n this.logger?.debug('Subscription removed', { subscriptionId });\n }\n }\n\n /**\n * Get event history matching filter criteria.\n */\n getHistory(filter?: EventFilter): readonly DomainEvent[] {\n const historyArray = this.history.toArray();\n if (filter === undefined) {\n return historyArray;\n }\n\n const filtered = applyHistoryFilters(historyArray, filter);\n return applyHistoryLimit(filtered, filter);\n }\n\n /**\n * Clear event history.\n */\n clearHistory(): void {\n this.history.clear();\n this.stats.historySize = 0;\n this.logger?.debug('History cleared');\n }\n\n /**\n * Get event bus statistics.\n */\n getStats(): EventBusStats {\n return { ...this.stats };\n }\n\n /**\n * Check if a topic pattern has any subscribers.\n */\n hasSubscribers(pattern: TopicPattern): boolean {\n const regex = patternToRegex(pattern);\n for (const record of this.subscriptions.values()) {\n // Check if the patterns could overlap\n if (\n topicMatchesPattern(pattern, record.regex) ||\n topicMatchesPattern(record.pattern, regex)\n ) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Add event to history, maintaining size limit via O(1) circular buffer.\n * @see Issue #407 - Performance optimization\n */\n private addToHistory(event: DomainEvent): void {\n this.history.push(event);\n this.stats.historySize = this.history.size;\n }\n\n /**\n * Invoke a listener synchronously with error isolation.\n */\n private invokeListener(record: SubscriptionRecord, event: DomainEvent): void {\n try {\n const result = record.listener(event);\n // If async handling is enabled and listener returns a promise, don't wait\n if (this.asyncHandling && result instanceof Promise) {\n result.catch((error: unknown) => {\n this.handleListenerError(record, event, error);\n });\n }\n } catch (error) {\n this.handleListenerError(record, event, error);\n }\n }\n\n /**\n * Invoke a listener asynchronously.\n */\n private async invokeListenerAsync(record: SubscriptionRecord, event: DomainEvent): Promise<void> {\n try {\n await record.listener(event);\n } catch (error) {\n this.handleListenerError(record, event, error);\n }\n }\n\n /**\n * Handle listener errors without disrupting other listeners.\n */\n private handleListenerError(\n record: SubscriptionRecord,\n event: DomainEvent,\n error: unknown\n ): void {\n this.stats.errorCount++;\n const errorObj = error instanceof Error ? error : new Error(String(error));\n this.logger?.error('Event listener error', errorObj, {\n subscriptionId: record.id,\n pattern: record.pattern,\n eventTopic: event.topic,\n eventId: event.eventId,\n });\n }\n}\n\n/**\n * Create a singleton event bus instance for global coordination.\n * Use with caution - prefer dependency injection for testability.\n */\nlet globalBus: CollaborationEventBus | null = null;\n\nexport function getGlobalEventBus(options?: EventBusOptions): CollaborationEventBus {\n globalBus ??= new CollaborationEventBus(options);\n return globalBus;\n}\n\n/**\n * Reset the global event bus (for testing).\n */\nexport function resetGlobalEventBus(): void {\n globalBus = null;\n}\n\n/**\n * Factory functions for creating typed events.\n */\nexport function createEvent<T extends DomainEvent>(\n topic: T['topic'],\n payload: T['payload'],\n options?: {\n sessionId?: string;\n correlationId?: string;\n }\n): T {\n return {\n eventId: generateEventId(),\n timestamp: getTimeProvider().nowIso(),\n topic,\n payload,\n sessionId: options?.sessionId,\n correlationId: options?.correlationId,\n } as T;\n}\n","/**\n * Event Bus Topic Constants\n *\n * Type-safe topic constants for event subscription.\n *\n * @module agents/collaboration/event-bus-topics\n * (Source: Issue #182, ARCHITECTURE.md Hybrid Architecture)\n */\n\n/**\n * Topic constants for type-safe subscription.\n */\nexport const EventTopics = {\n // Session events\n SESSION_CREATED: 'session.created',\n SESSION_STATUS_CHANGED: 'session.status_changed',\n SESSION_PARTICIPANT_JOINED: 'session.participant_joined',\n SESSION_RESULT_SUBMITTED: 'session.result_submitted',\n SESSION_FINALIZED: 'session.finalized',\n SESSION_ALL: 'session.*',\n\n // Message events\n MESSAGE_SENT: 'message.sent',\n MESSAGE_RECEIVED: 'message.received',\n MESSAGE_ALL: 'message.*',\n\n // Agent events\n AGENT_TASK_DELEGATED: 'agent.task_delegated',\n AGENT_RESULT_BROADCAST: 'agent.result_broadcast',\n AGENT_ALL: 'agent.*',\n\n // Consensus events\n CONSENSUS_VOTE_REQUESTED: 'consensus.vote_requested',\n CONSENSUS_VOTE_CAST: 'consensus.vote_cast',\n CONSENSUS_REACHED: 'consensus.reached',\n CONSENSUS_ALL: 'consensus.*',\n\n // Protocol events\n PROTOCOL_STARTED: 'protocol.started',\n PROTOCOL_ITERATION: 'protocol.iteration',\n PROTOCOL_COMPLETED: 'protocol.completed',\n PROTOCOL_ALL: 'protocol.*',\n\n // Aegean phase events (Issue #216)\n AEGEAN_ROUND_STARTED: 'protocol.aegean.round_started',\n AEGEAN_VOTE_COLLECTED: 'protocol.aegean.vote_collected',\n AEGEAN_QUORUM_DETECTED: 'protocol.aegean.quorum_detected',\n AEGEAN_ALL: 'protocol.aegean.*',\n\n // Reflexion phase events (Issue #216)\n REFLEXION_CRITIQUE_STARTED: 'protocol.reflexion.critique_started',\n REFLEXION_CRITIQUE_COMPLETED: 'protocol.reflexion.critique_completed',\n REFLEXION_SYNTHESIS: 'protocol.reflexion.synthesis',\n REFLEXION_ALL: 'protocol.reflexion.*',\n\n // Trinity phase events (Issue #216)\n TRINITY_PHASE_STARTED: 'protocol.trinity.phase_started',\n TRINITY_PHASE_COMPLETED: 'protocol.trinity.phase_completed',\n TRINITY_ALL: 'protocol.trinity.*',\n\n // Byzantine detection events (Issue #218)\n BYZANTINE_WEIGHT_UPDATED: 'byzantine.weight_updated',\n BYZANTINE_PATTERN_DETECTED: 'byzantine.pattern_detected',\n BYZANTINE_AGENT_FLAGGED: 'byzantine.agent_flagged',\n BYZANTINE_COLLUSION_SUSPECTED: 'byzantine.collusion_suspected',\n BYZANTINE_ALL: 'byzantine.*',\n\n // Wildcard\n ALL: '*',\n} as const;\n","/**\n * Resilient Model Adapter\n *\n * Transparent proxy implementing IModelAdapter with lazy detection,\n * automatic failover on circuit breaker events, and observable health.\n *\n * Key design: ResilientAdapter IS an IModelAdapter. Every existing consumer\n * works unchanged. The health/failover API lives on IResilientAdapter for\n * dashboard and monitoring consumers only.\n *\n * @module adapters/resilient-adapter\n * (Source: Issue #811 - Resilient model adapter architecture)\n */\n\nimport type {\n IModelAdapter,\n CompletionRequest,\n CompletionResponse,\n StreamChunk,\n ModelCapability,\n} from '../core/types/model.js';\nimport type { Result } from '../core/result.js';\nimport { ok, err } from '../core/result.js';\nimport { ModelError, ConfigError, ErrorCode } from '../core/errors.js';\nimport type { ILogger } from '../core/index.js';\nimport { getTimeProvider, getRandomProvider } from '../core/index.js';\nimport { getErrorMessage, createLogger } from '../core/index.js';\nimport { UNRESOLVED_MODEL_ID } from '../config/model-equivalence.js';\n\nimport { createAutoAdapter, type AdapterSelection } from './auto-adapter.js';\nimport { ensureGatewayDiscovered, gatewayDiscoveryGeneration } from './gateway-rediscovery.js';\nimport {\n isRateLimitLikeError,\n isDurableCapacityError,\n toRateLimitError,\n recordRateLimitEvent,\n} from './rate-limit-detector.js';\nimport type { CliName, EndpointArmId } from '../cli-adapters/types.js';\nimport { isEndpointArmId } from '../cli-adapters/types.js';\nimport type {\n IResilientAdapter,\n AdapterHealthInfo,\n ResilientAdapterConfig,\n} from './resilient-adapter-types.js';\nimport type { CircuitStateChangeEvent } from '../cli-adapters/circuit-breaker-types.js';\nimport type { CircuitBreakerRegistry } from '../cli-adapters/circuit-breaker.js';\nimport { mapModelErrorToCategory } from '../cli-adapters/circuit-breaker.js';\nimport { getGlobalEventBus } from '../core/event-bus.js';\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Creates a resilient adapter with lazy detection and automatic failover.\n *\n * @example\n * ```typescript\n * const adapter = createResilientAdapter({ logger });\n * // No detection at creation time — detection happens on first use\n * const result = await adapter.complete(request); // triggers detection\n * ```\n */\nexport function createResilientAdapter(config?: ResilientAdapterConfig): IResilientAdapter {\n return new ResilientAdapter(config);\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Resilient adapter proxy. Implements IModelAdapter transparently.\n */\nexport class ResilientAdapter implements IResilientAdapter {\n private readonly logger: ILogger;\n private currentAdapter: IModelAdapter | undefined;\n private currentSelection: AdapterSelection | undefined;\n private hasEverDetected = false;\n private health: AdapterHealthInfo | undefined;\n private preferredCli: CliName | undefined;\n private readonly failoverCallbacks = new Set<(info: AdapterHealthInfo) => void>();\n private circuitBreakerRegistry: CircuitBreakerRegistry | undefined;\n private circuitListener: ((event: CircuitStateChangeEvent) => void) | undefined;\n private disposed = false;\n private readonly defaultCliTimeoutMs: number | undefined;\n /** Inflight detection promise for coalescing concurrent calls (Issue #1423). */\n private detectionPromise: Promise<IModelAdapter | undefined> | undefined;\n /** The {@link gatewayDiscoveryGeneration} the current selection was made under (#6659). */\n private detectedAtGeneration = 0;\n\n constructor(config?: ResilientAdapterConfig) {\n this.logger = config?.logger ?? createLogger({ component: 'resilient-adapter' });\n this.preferredCli = config?.preferredCli;\n this.defaultCliTimeoutMs = config?.defaultCliTimeoutMs;\n\n // #4659: arm at construction. The previous `attach`-only API was not on\n // IResilientAdapter, so neither production construction site could reach\n // it and the breaker never fired.\n if (config?.circuitBreakerRegistry !== undefined) {\n this.attachCircuitBreakerRegistry(config.circuitBreakerRegistry);\n }\n }\n\n // --- IModelAdapter properties (forwarded) ---\n\n /**\n * Before detection a CLI-pinned proxy identifies as the CLI it was asked\n * for (`cli-<name>`, the id its detected `CliToModelAdapter` will carry);\n * an unpinned proxy stays `resilient-proxy`.\n *\n * #6119: the voter fallover (#3587) keys seats by this id and skips a seat\n * whose key equals the fallback's. When codex never detected, the pinned\n * seat and the unpinned default were BOTH `resilient-proxy`, so the seat was\n * read as \"already on the fallback\" and errored instead of falling over.\n */\n get providerId(): string {\n if (this.currentAdapter !== undefined) return this.currentAdapter.providerId;\n return this.preferredCli === undefined ? 'resilient-proxy' : `cli-${this.preferredCli}`;\n }\n\n get modelId(): string {\n return this.currentAdapter?.modelId ?? UNRESOLVED_MODEL_ID;\n }\n\n get capabilities(): readonly ModelCapability[] {\n return this.currentAdapter?.capabilities ?? [];\n }\n\n /**\n * The gateway arm of the adapter currently serving this proxy, when a\n * gateway model serves it (#6604 family slots); otherwise undefined. A\n * telemetry writer handed this proxy reads it (`isGatewayModelAdapter`) to\n * price the call by the gateway's `NEXUS_GATEWAY_COST` declaration instead\n * of a list price.\n */\n get gatewayArm(): EndpointArmId | undefined {\n const arm: unknown = (this.currentAdapter as { gatewayArm?: unknown } | undefined)?.gatewayArm;\n return typeof arm === 'string' && isEndpointArmId(arm) ? arm : undefined;\n }\n\n // --- IModelAdapter methods ---\n\n async complete(request: CompletionRequest): Promise<Result<CompletionResponse, ModelError>> {\n const adapter = await this.ensureAdapter();\n if (adapter === undefined) {\n return err(new ModelError('No model adapter available'));\n }\n const result = await adapter.complete(request);\n if (!result.ok) {\n if (isRateLimitLikeError(result.error)) {\n const rlError = toRateLimitError(result.error, adapter.providerId);\n recordRateLimitEvent({\n provider: adapter.providerId,\n timestamp: getTimeProvider().now(),\n retryAfterMs: rlError.retryAfterMs,\n });\n this.logger.warn('Rate limit detected', {\n provider: adapter.providerId,\n retryAfterMs: rlError.retryAfterMs,\n });\n }\n this.recordBreakerFailure(adapter, result.error);\n }\n return result;\n }\n\n async *stream(request: CompletionRequest): AsyncIterable<StreamChunk> {\n const adapter = await this.ensureAdapter();\n if (adapter === undefined) {\n // #3105: error like complete() rather than yielding an empty stream — a\n // silent-empty stream masks \"no adapter available\" as a clean empty\n // completion, so streamWithFallback can't tell failure from a\n // legitimately-empty result.\n throw new ModelError('No model adapter available');\n }\n yield* adapter.stream(request);\n }\n\n async countTokens(text: string): Promise<number> {\n const adapter = await this.ensureAdapter();\n if (adapter === undefined) {\n return 0;\n }\n return adapter.countTokens(text);\n }\n\n validateConfig(): Result<void, ConfigError> {\n if (this.currentAdapter !== undefined) {\n return this.currentAdapter.validateConfig();\n }\n // Before first use, config is trivially valid\n return ok(undefined);\n }\n\n // --- IResilientAdapter methods ---\n\n getHealth(): AdapterHealthInfo | undefined {\n return this.health;\n }\n\n async refresh(): Promise<void> {\n this.currentAdapter = undefined;\n this.currentSelection = undefined;\n this.detectionPromise = undefined;\n await this.ensureAdapter();\n }\n\n setPreferredCli(cli: CliName | undefined): void {\n this.preferredCli = cli;\n this.currentAdapter = undefined;\n this.currentSelection = undefined;\n }\n\n onFailover(cb: (info: AdapterHealthInfo) => void): () => void {\n this.failoverCallbacks.add(cb);\n return () => {\n this.failoverCallbacks.delete(cb);\n };\n }\n\n /**\n * Attach a circuit breaker registry for automatic failover.\n * When the current adapter's circuit opens, the cached adapter\n * is cleared so the next call triggers re-detection.\n */\n /** The registry arming failover, or undefined if this adapter is unarmed (#4659). */\n getCircuitBreakerRegistry(): CircuitBreakerRegistry | undefined {\n return this.circuitBreakerRegistry;\n }\n\n attachCircuitBreakerRegistry(registry: CircuitBreakerRegistry): void {\n this.detachCircuitBreakerRegistry();\n this.circuitBreakerRegistry = registry;\n this.circuitListener = (event: CircuitStateChangeEvent) => {\n this.handleCircuitStateChange(event);\n };\n registry.addGlobalStateChangeListener(this.circuitListener);\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.disposed = true;\n this.detachCircuitBreakerRegistry();\n this.failoverCallbacks.clear();\n }\n\n // --- Private methods ---\n\n private async ensureAdapter(): Promise<IModelAdapter | undefined> {\n // #6659: the shared acquisition seam re-discovers a gateway that was down\n // at boot (backoff-bounded, one shared attempt; a no-op unless armed).\n // Once one is found, an adapter detected before it re-detects ONCE, so the\n // default and the family slots move onto the gateway. Not a failover: the\n // adapter left behind did not fail.\n // An adapter that already serves calls never waits on discovery: it fires\n // the attempt and keeps serving, and the generation check below switches\n // it on a LATER call. Only an adapter with nothing to serve yet waits,\n // since the discovery may be what gives it something (#6671 review).\n if (this.currentAdapter === undefined) {\n await ensureGatewayDiscovered();\n } else {\n void ensureGatewayDiscovered();\n }\n if (\n this.currentAdapter !== undefined &&\n this.detectedAtGeneration !== gatewayDiscoveryGeneration()\n ) {\n this.currentAdapter = undefined;\n this.currentSelection = undefined;\n this.hasEverDetected = false;\n }\n if (this.currentAdapter !== undefined) {\n return this.currentAdapter;\n }\n // Coalesce concurrent detection calls into a single probe (Issue #1423)\n this.detectionPromise ??= this.detectAdapter().finally(() => {\n this.detectionPromise = undefined;\n });\n return this.detectionPromise;\n }\n\n private async detectAdapter(): Promise<IModelAdapter | undefined> {\n // Read BEFORE detecting: a discovery that lands mid-detection leaves this\n // selection tagged stale, so the next call re-detects instead of keeping it.\n const generation = gatewayDiscoveryGeneration();\n try {\n this.logger.info('Detecting model adapter (lazy)');\n const config = {\n logger: this.logger,\n ...(this.preferredCli !== undefined && { preferredCli: this.preferredCli }),\n ...(this.defaultCliTimeoutMs !== undefined && {\n defaultCliTimeoutMs: this.defaultCliTimeoutMs,\n }),\n };\n const selection = await createAutoAdapter(config);\n this.applySelection(selection);\n this.detectedAtGeneration = generation;\n return this.currentAdapter;\n } catch (error) {\n const message = getErrorMessage(error);\n this.logger.warn('No model adapter available', { error: message });\n this.health = {\n source: 'api',\n state: 'unavailable',\n selectedAt: new Date(),\n failoverCount: this.health?.failoverCount ?? 0,\n lastError: message,\n };\n return undefined;\n }\n }\n\n private applySelection(selection: AdapterSelection): void {\n const isFailover = this.hasEverDetected;\n // #4670: capture the OUTGOING health before it is overwritten below. The\n // failover signal is about the adapter we are leaving — `unhealthyCliFrom`\n // reads `payload.source` as \"which CLI is unhealthy\" — and that state was\n // being destroyed one statement before `emitFailover` read it.\n const outgoingHealth = this.health;\n this.currentAdapter = selection.adapter;\n this.currentSelection = selection;\n this.hasEverDetected = true;\n\n const source = mapSelectionSource(selection);\n const failoverCount = (this.health?.failoverCount ?? 0) + (isFailover ? 1 : 0);\n\n this.health = {\n source,\n state: 'healthy',\n selectedAt: new Date(),\n failoverCount,\n };\n\n this.logger.info('Adapter selected', {\n source: selection.source,\n name: selection.name,\n model: selection.adapter.modelId,\n provider: selection.adapter.providerId,\n failover: isFailover,\n });\n\n if (isFailover) {\n // The state/source describe the adapter we LEFT; `failoverCount` is a\n // run-level counter, so it carries the post-increment value.\n this.emitFailover(\n outgoingHealth === undefined ? undefined : { ...outgoingHealth, failoverCount }\n );\n }\n }\n\n /**\n * Record a direct-API failure to the circuit breaker so API adapters get the\n * same degradation/failover learning that CLI subprocess failures get (#3423).\n *\n * The breaker key is `currentSelection.name` — distinct from the `api:<vendor>`\n * arm key used by the ModelToCliAdapter path (#3422), so the two paths never\n * double-count the same failure.\n *\n * Rate-limit failures are deliberately skipped here: they are already recorded\n * by the `recordRateLimitEvent` telemetry branch in `complete()`, and the\n * breaker counts rate limits as failures by default\n * (`countRateLimitsAsFailures`), so recording them again would double-count.\n *\n * Security (#3422 constraint): the logged payload carries only `provider` and\n * `category` — never `error.message`, the request, or the ModelError object,\n * any of which could embed credentials.\n */\n private recordBreakerFailure(adapter: IModelAdapter, error: ModelError): void {\n if (this.circuitBreakerRegistry === undefined || this.currentSelection === undefined) {\n return;\n }\n\n // #6599: caller input (e.g. a requested model the CLI cannot resolve) is\n // not a health signal. Counting it let one bad model preference open the\n // breaker for every caller of the CLI.\n if (error.code === ErrorCode.INVALID_INPUT) return;\n\n const category = mapModelErrorToCategory(error);\n // Skip rate limits: already accounted for by the rate-limit telemetry branch\n // (and the breaker counts them by default). Check BOTH the mapped category\n // AND the telemetry predicate — their rate-limit pattern lists differ\n // (`isRateLimitLikeError` matches \"quota exceeded\"/\"throttl\"/… that\n // `categorizeError` does not), so a code-less MODEL_ERROR could otherwise\n // fire the telemetry branch yet fall through to a counted failure here,\n // double-counting against the threshold (#3423 review).\n // #5359: a DURABLE capacity cap is excluded from this exemption. The\n // exemption is right for a transient throttle — an ordinary panel trips a\n // per-minute limit while plenty of quota remains, and opening a breaker on\n // that would empty the candidate pool for a condition clearing within the\n // minute. It is wrong for an exhausted credential, which does not clear:\n // never counting it means the breaker never opens, so every subsequent call\n // pays the same futile retries against the same dead key.\n if (isDurableCapacityError(error)) {\n this.circuitBreakerRegistry\n .getBreaker(this.currentSelection.name as CliName)\n .recordFailure(category);\n this.logger.warn('Durable capacity cap recorded to circuit breaker', {\n provider: adapter.providerId,\n category,\n });\n return;\n }\n\n if (category === 'rate_limit' || isRateLimitLikeError(error)) {\n return;\n }\n\n this.circuitBreakerRegistry\n .getBreaker(this.currentSelection.name as CliName)\n .recordFailure(category);\n\n this.logger.warn('API failure recorded to circuit breaker', {\n provider: adapter.providerId,\n category,\n });\n }\n\n private handleCircuitStateChange(event: CircuitStateChangeEvent): void {\n if (event.newState !== 'open') return;\n\n const currentSource = this.currentSelection?.name;\n if (currentSource === undefined || currentSource !== event.cliName) {\n return; // Not our current adapter\n }\n\n this.logger.warn('Current adapter circuit opened, clearing cache for re-detection', {\n cli: event.cliName,\n reason: event.reason,\n });\n\n this.currentAdapter = undefined;\n this.currentSelection = undefined;\n\n if (this.health !== undefined) {\n this.health = {\n ...this.health,\n state: 'degraded',\n lastError: event.reason,\n };\n }\n }\n\n /**\n * Emit the failover signal describing the adapter we failed AWAY FROM (#4670).\n *\n * This used to read `this.health`, which `applySelection` had just replaced\n * with the incoming adapter's `state: 'healthy'`. So every `adapter.failover`\n * payload said healthy, `unhealthyCliFrom` (`observability/failover-signals.ts`)\n * returned undefined for all of them, and `signal.swarm_unhealthy` was never\n * produced by this — the more reliable of its two producers.\n *\n * An undefined outgoing health emits NOTHING rather than falling back to the\n * current one. Falling back would silently restore the old behaviour, and a\n * failover whose prior state we cannot describe is not evidence that the\n * prior adapter was healthy.\n */\n private emitFailover(outgoingHealth: AdapterHealthInfo | undefined): void {\n const info = outgoingHealth;\n if (info === undefined) return;\n\n for (const cb of this.failoverCallbacks) {\n try {\n cb(info);\n } catch (error: unknown) {\n this.logger.debug('Failover callback error', { error: getErrorMessage(error) });\n }\n }\n\n try {\n const eventBus = getGlobalEventBus();\n eventBus.emit({\n eventId: `failover-${getTimeProvider().now().toString(36)}-${getRandomProvider().random().toString(36).slice(2, 8)}`,\n timestamp: new Date().toISOString(),\n topic: 'adapter.failover',\n payload: info,\n });\n } catch (error: unknown) {\n this.logger.debug('CollaborationEventBus emit failed during failover', {\n error: getErrorMessage(error),\n });\n }\n }\n\n private detachCircuitBreakerRegistry(): void {\n if (this.circuitBreakerRegistry !== undefined && this.circuitListener !== undefined) {\n this.circuitBreakerRegistry.removeGlobalStateChangeListener(this.circuitListener);\n }\n this.circuitBreakerRegistry = undefined;\n this.circuitListener = undefined;\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction mapSelectionSource(selection: AdapterSelection): CliName | 'api' {\n if (selection.source === 'cli') {\n return selection.name as CliName;\n }\n return 'api';\n}\n","/**\n * A CLI slot adapter bound to one requested model (#6599).\n *\n * `UnifiedAdapterRegistry.getAdapterForModel` resolves a model preference to\n * its CLI slot, and the slot adapter is shared and CLI-scoped: it has no\n * model of its own beyond the CLI default. Returning it bare dropped the\n * model, so `execute_expert` ran the CLI's default whatever was asked for.\n * This view stamps the model onto every request that does not name its own,\n * and delegates everything else to the shared slot adapter, which the\n * registry still owns.\n *\n * @module adapters/model-bound-adapter\n */\n\nimport type {\n CompletionRequest,\n CompletionResponse,\n ConfigError,\n ModelCapability,\n ModelError,\n Result,\n} from '../core/index.js';\nimport type { StreamChunk } from '../core/types/model.js';\nimport type { CliName } from '../cli-adapters/types.js';\nimport type { CircuitBreakerRegistry } from '../cli-adapters/circuit-breaker.js';\nimport type { AdapterHealthInfo, IResilientAdapter } from './resilient-adapter-types.js';\n\nexport class ModelBoundAdapter implements IResilientAdapter {\n constructor(\n private readonly slot: IResilientAdapter,\n /** Canonical registry id every unmodelled request is sent with. */\n readonly boundModel: string\n ) {}\n\n get providerId(): string {\n return this.slot.providerId;\n }\n\n get modelId(): string {\n return this.slot.modelId;\n }\n\n get capabilities(): readonly ModelCapability[] {\n return this.slot.capabilities;\n }\n\n private bind(request: CompletionRequest): CompletionRequest {\n return request.model !== undefined ? request : { ...request, model: this.boundModel };\n }\n\n complete(request: CompletionRequest): Promise<Result<CompletionResponse, ModelError>> {\n return this.slot.complete(this.bind(request));\n }\n\n stream(request: CompletionRequest): AsyncIterable<StreamChunk> {\n return this.slot.stream(this.bind(request));\n }\n\n countTokens(text: string): Promise<number> {\n return this.slot.countTokens(text);\n }\n\n validateConfig(): Result<void, ConfigError> {\n return this.slot.validateConfig();\n }\n\n getHealth(): AdapterHealthInfo | undefined {\n return this.slot.getHealth();\n }\n\n refresh(): Promise<void> {\n return this.slot.refresh();\n }\n\n setPreferredCli(cli: CliName | undefined): void {\n this.slot.setPreferredCli(cli);\n }\n\n onFailover(cb: (info: AdapterHealthInfo) => void): () => void {\n return this.slot.onFailover(cb);\n }\n\n getCircuitBreakerRegistry(): CircuitBreakerRegistry | undefined {\n return this.slot.getCircuitBreakerRegistry?.();\n }\n\n /** No-op: the shared slot adapter belongs to the registry, which disposes it. */\n dispose(): void {\n // Intentionally empty — disposing the view must not dispose the slot.\n }\n}\n","/**\n * Unified Adapter Registry — single entry point for all model adapter access.\n *\n * Pre-computes task-to-CLI routing from the canonical model registry and\n * task specialization matrix at creation time. All consumers get adapters\n * through this registry instead of calling createAutoAdapter/createResilientAdapter\n * directly.\n *\n * Design:\n * - One IResilientAdapter per CLI (claude/gemini/codex), created lazily on first access\n * - One \"default\" adapter for unscoped requests (uses createAutoAdapter priority)\n * - Task routing is deterministic: category → primary CLI → cached adapter\n * - Session-scoped: create once at MCP startup, reuse for the session lifetime\n *\n * @module adapters/unified-registry\n * (Source: Issue #1149 — Unified Adapter Registry)\n * (Source: Issue #1151 — Single adapter entry point)\n */\n\nimport type { ILogger } from '../core/index.js';\nimport { ConfigError } from '../core/errors.js';\nimport { getDefaultCliCircuitBreakerRegistry } from '../cli-adapters/cli-circuit-breaker.js';\nimport { createLogger } from '../core/index.js';\nimport { createResilientAdapter } from './resilient-adapter.js';\nimport { ModelBoundAdapter } from './model-bound-adapter.js';\nimport { isGatewayArmId, warnIfGatewayCostUndeclared } from './sdk/gateway-cost.js';\nimport type { IResilientAdapter } from './resilient-adapter-types.js';\nimport type { CliName, EndpointArmId, ObservedArmId } from '../cli-adapters/types.js';\nimport { isCliName, isEndpointArmId } from '../cli-adapters/types.js';\nimport { TASK_SPECIALIZATION_MATRIX, detectTaskCategory } from '../config/task-specialization.js';\nimport type { TaskCategory } from '../config/task-specialization-types.js';\nimport {\n getDefaultModelForCli,\n getInTreeCapabilitiesMatrix,\n} from '../config/model-config-helpers.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Configuration for the unified registry. */\nexport interface UnifiedRegistryConfig {\n /** Logger instance */\n readonly logger?: ILogger;\n /** Default CLI timeout for subprocess calls (ms) */\n readonly defaultCliTimeoutMs?: number;\n}\n\n/** Summary of the pre-computed task routing table. */\nexport interface TaskRoutingEntry {\n readonly category: TaskCategory;\n readonly primaryCli: CliName;\n readonly secondaryCli: CliName;\n readonly primaryModel: string;\n}\n\n/** Snapshot of registry state for observability. */\nexport interface RegistrySnapshot {\n readonly taskRouting: readonly TaskRoutingEntry[];\n /**\n * CLI-slot view of {@link cachedArms}: the lazily created CLI slots only.\n * A registered `api:*` arm is never listed here (#6290 panel: this field\n * keeps its `CliName[]` type; it is retired in 9.0, #6291).\n */\n readonly cachedAdapters: readonly CliName[];\n /** Every cached arm: lazily created CLI slots and registered `api:*` endpoint arms (#4392). */\n readonly cachedArms: readonly ObservedArmId[];\n readonly availableModels: number;\n}\n\n// ============================================================================\n// Registry\n// ============================================================================\n\n/**\n * Unified adapter registry. Centralizes all adapter creation and task routing.\n *\n * Usage:\n * ```typescript\n * const registry = createUnifiedRegistry({ logger });\n * const adapter = registry.getAdapter('code_generation'); // → codex adapter\n * const adapter2 = registry.getAdapterForCli('claude'); // → claude adapter\n * const adapter3 = registry.getDefault(); // → best available\n * ```\n */\n\nexport class UnifiedAdapterRegistry {\n private readonly logger: ILogger;\n private readonly defaultCliTimeoutMs: number | undefined;\n\n /**\n * Per-arm adapter cache. CLI slots are created lazily by\n * {@link getAdapterForCli}; `api:*` arms enter only through\n * {@link registerApiArm} and are never synthesised (#4392).\n */\n private readonly cliAdapters = new Map<ObservedArmId, IResilientAdapter>();\n\n /** Default adapter for unscoped requests. */\n private defaultAdapter: IResilientAdapter | undefined;\n\n constructor(config?: UnifiedRegistryConfig) {\n this.logger = config?.logger ?? createLogger({ component: 'unified-registry' });\n this.defaultCliTimeoutMs = config?.defaultCliTimeoutMs;\n this.logger.info('UnifiedAdapterRegistry initialized', {\n categories: TASK_SPECIALIZATION_MATRIX.length,\n models: getInTreeCapabilitiesMatrix().models.length,\n });\n }\n\n // --------------------------------------------------------------------------\n // Public API\n // --------------------------------------------------------------------------\n\n /** Logger used by this registry. Exposed so singleton helpers can warn. */\n getLogger(): ILogger {\n return this.logger;\n }\n\n /**\n * Get adapter for a task category. Routing is re-resolved on every read\n * (#3185) so a post-startup overlay/registry update propagates without a\n * restart. Falls back to default adapter if category unknown.\n */\n getAdapter(category: TaskCategory): IResilientAdapter {\n const routing = this.getRouting(category);\n if (routing === undefined) {\n this.logger.warn('Unknown task category, using default', { category });\n return this.getDefault();\n }\n return this.getAdapterForCli(routing.primaryCli);\n }\n\n /**\n * Get adapter for a free-text task description.\n * Detects category from keywords, falls back to default.\n */\n getAdapterForTask(taskDescription: string): IResilientAdapter {\n const match = detectTaskCategory(taskDescription);\n if (match !== null) {\n this.logger.debug('Task category detected', {\n category: match.category,\n cli: match.primaryCli,\n });\n return this.getAdapterForCli(match.primaryCli);\n }\n return this.getDefault();\n }\n\n /**\n * Get adapter pinned to a specific CLI.\n * Creates and caches one IResilientAdapter per CLI.\n */\n getAdapterForCli(cli: CliName): IResilientAdapter {\n const cached = this.cliAdapters.get(cli);\n if (cached !== undefined) return cached;\n\n const raw = createResilientAdapter({\n logger: this.logger,\n preferredCli: cli,\n // #4659: the SHARED registry — the same one that already gates\n // voter-panel availability (#4330). Per-adapter registries would let one\n // adapter keep routing to a CLI another has already seen fail.\n circuitBreakerRegistry: getDefaultCliCircuitBreakerRegistry(),\n ...(this.defaultCliTimeoutMs !== undefined && {\n defaultCliTimeoutMs: this.defaultCliTimeoutMs,\n }),\n });\n const adapter = raw;\n this.cliAdapters.set(cli, adapter);\n this.logger.info('Created CLI-specific adapter', {\n cli,\n });\n return adapter;\n }\n\n /**\n * Get the adapter for a routing arm (#4392). A CLI slot resolves exactly as\n * {@link getAdapterForCli} (created lazily, cached, armed with the shared\n * breaker registry). An `api:*` arm resolves to what {@link registerApiArm}\n * supplied, or `undefined` — never to a CLI slot, and never by creating one.\n */\n getAdapterForArm(arm: ObservedArmId): IResilientAdapter | undefined {\n // Split on CLI-slot membership, not on the validator: an `api:` string\n // that fails validation must read as \"not registered\", never be handed\n // to getAdapterForCli to mint a slot adapter under a garbage name.\n if (isCliName(arm)) {\n return this.getAdapterForCli(arm);\n }\n return this.cliAdapters.get(arm);\n }\n\n /**\n * Register an `api:*` arm's adapter under its endpoint identity (#4392).\n * Refuses built-in vendor arms (`api:anthropic`, `api:openai`, `api:google`, `api:gemini`)\n * to prevent hijacking or redirecting vendor traffic without authorization.\n * Accepts a dynamic `EndpointArmId`; the id is re-validated at runtime\n * because the `EndpointArmId` type admits any `api:` string, so a cast from an\n * unvalidated name is exactly what this refuses.\n * Registering an id twice replaces (and disposes) the earlier adapter.\n * CLI-slot behaviour is untouched. A registered endpoint arm is observable\n * here and in the breaker registry but is NOT a `RoutingArmId`: it cannot\n * enter outcome records until #6291. A gateway arm registered without a\n * `NEXUS_GATEWAY_COST` declaration is warned about here, once, at the\n * moment it becomes routable (#4392 increment 2).\n */\n registerApiArm(arm: EndpointArmId, adapter: IResilientAdapter): void {\n if (!isEndpointArmId(arm)) {\n throw new Error(`Invalid api arm id: ${JSON.stringify(arm)} (expected api:<endpoint>)`);\n }\n if (!isGatewayArmId(arm) || arm === 'api:gemini') {\n throw new Error(`Cannot overwrite built-in vendor arm: ${arm}`);\n }\n this.cliAdapters.get(arm)?.dispose();\n this.cliAdapters.set(arm, adapter);\n this.logger.info('Registered api arm adapter', { arm });\n warnIfGatewayCostUndeclared(arm, this.logger);\n }\n\n /**\n * Get adapter for a model preference string (e.g., \"claude-opus-4-6\").\n * Resolves the model to its CLI via the canonical registry.\n * Falls back to default adapter if model not recognized.\n *\n * An exact match returns the CLI slot adapter bound to the matched registry\n * id, so the model reaches the CLI instead of its default (#6599). A prefix\n * match routes to the CLI only, as before: the name was not an entry.\n */\n getAdapterForModel(modelPreference: string): IResilientAdapter {\n // Prefer exact matches (id / cliAlias / cliModelName) over prefix matches.\n // For prefix fallback, longest-prefix-wins so a future registry containing\n // both 'gemini-pro' and 'gemini-pro-experimental' resolves correctly even\n // though the registry's natural array order isn't sorted by id length.\n // Defense-in-depth — no current registry has prefix overlaps. (#2192)\n const allModels = getInTreeCapabilitiesMatrix().models;\n const exact = allModels.find(\n (m) =>\n m.id === modelPreference ||\n m.cliAlias === modelPreference ||\n m.cliModelName === modelPreference\n );\n const prefix =\n exact ??\n [...allModels]\n .filter((m) => modelPreference.startsWith(m.id))\n .sort((a, b) => b.id.length - a.id.length)[0];\n const model = prefix;\n if (model !== undefined) {\n this.logger.debug('Model resolved to CLI', {\n model: modelPreference,\n cli: model.cliName,\n });\n const slot = this.getAdapterForCli(model.cliName as CliName);\n return exact !== undefined ? new ModelBoundAdapter(slot, exact.id) : slot;\n }\n this.logger.debug('Model not in registry, using default', {\n model: modelPreference,\n });\n return this.getDefault();\n }\n\n /**\n * Get adapter for an expert role (e.g., \"code_expert\").\n * Uses ROLE_TO_TASK_CATEGORY mapping → task specialization → CLI.\n */\n getAdapterForRole(role: string): IResilientAdapter {\n const category = ROLE_TO_CATEGORY[role];\n if (category !== undefined) return this.getAdapter(category);\n return this.getDefault();\n }\n\n /**\n * Get the default adapter (no CLI preference — auto-detection priority).\n */\n getDefault(): IResilientAdapter {\n if (this.defaultAdapter !== undefined) return this.defaultAdapter;\n const raw = createResilientAdapter({\n logger: this.logger,\n circuitBreakerRegistry: getDefaultCliCircuitBreakerRegistry(),\n ...(this.defaultCliTimeoutMs !== undefined && {\n defaultCliTimeoutMs: this.defaultCliTimeoutMs,\n }),\n });\n this.defaultAdapter = raw;\n return this.defaultAdapter;\n }\n\n /**\n * Get snapshot of registry state for observability/debugging. Routing is\n * re-resolved on read (#3185) so the snapshot reflects the live registry.\n */\n getSnapshot(): RegistrySnapshot {\n return {\n taskRouting: TASK_SPECIALIZATION_MATRIX.map((spec) => this.resolveRouting(spec)),\n cachedAdapters: [...this.cliAdapters.keys()].filter(isCliName),\n cachedArms: [...this.cliAdapters.keys()],\n availableModels: getInTreeCapabilitiesMatrix().models.length,\n };\n }\n\n /**\n * Resolve the routing for a specific category.\n *\n * Computed on every read (#3185) rather than cached at construction, so a\n * post-startup model-registry / overlay update (e.g. a default-model change\n * surfaced via `getDefaultModelForCli`) propagates to routing decisions\n * without a process restart. The matrix is ~10 categories — the per-read\n * resolution cost is negligible.\n */\n getRouting(category: TaskCategory): TaskRoutingEntry | undefined {\n const spec = TASK_SPECIALIZATION_MATRIX.find((s) => s.category === category);\n if (spec === undefined) return undefined;\n return this.resolveRouting(spec);\n }\n\n /**\n * Dispose all cached adapters.\n */\n dispose(): void {\n for (const adapter of this.cliAdapters.values()) {\n adapter.dispose();\n }\n this.cliAdapters.clear();\n this.defaultAdapter?.dispose();\n this.defaultAdapter = undefined;\n this.logger.info('UnifiedAdapterRegistry disposed');\n }\n\n // --------------------------------------------------------------------------\n // Private\n // --------------------------------------------------------------------------\n\n /**\n * Resolve one specialization-matrix row into a routing entry, re-reading the\n * primary model from the (overlay-aware) model registry each call (#3185).\n */\n private resolveRouting(spec: (typeof TASK_SPECIALIZATION_MATRIX)[number]): TaskRoutingEntry {\n return {\n category: spec.category,\n primaryCli: spec.primaryCli,\n secondaryCli: spec.secondaryCli,\n primaryModel: resolveDefaultModel(spec.primaryCli),\n };\n }\n}\n\n// ============================================================================\n// Role → Category Mapping (consolidated from create-expert-routing.ts)\n// ============================================================================\n\n/** Maps expert roles to task categories for CLI specialization. */\nconst ROLE_TO_CATEGORY: Record<string, TaskCategory> = {\n code_expert: 'code_generation',\n architecture_expert: 'architecture',\n security_expert: 'security_review',\n documentation_expert: 'documentation',\n testing_expert: 'testing',\n devops_expert: 'devops',\n research_expert: 'research',\n pm_expert: 'planning',\n ux_expert: 'planning',\n infrastructure_expert: 'devops',\n};\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/** Resolve the default model name for a CLI from the canonical registry. */\nfunction resolveDefaultModel(cli: string): string {\n if (isCliName(cli)) {\n return getDefaultModelForCli(cli);\n }\n return cli;\n}\n\n// ============================================================================\n// Factory & Singleton\n// ============================================================================\n\nlet globalRegistry: UnifiedAdapterRegistry | undefined;\n\n/**\n * Create a new UnifiedAdapterRegistry instance.\n * For most uses, prefer `getGlobalRegistry()` instead.\n */\nexport function createUnifiedRegistry(config?: UnifiedRegistryConfig): UnifiedAdapterRegistry {\n return new UnifiedAdapterRegistry(config);\n}\n\n/**\n * Claim the global registry for a process entry point, choosing its logger\n * (#6012). Idempotent and SILENT when the registry already exists — unlike\n * {@link getGlobalRegistry} with a config, which warns.\n *\n * That difference is the point. There is not exactly one composition root: the\n * bundled CLI enters through `cli.ts main()`, and an embedder can start the MCP\n * server directly without it. Both should be able to claim, first-one-wins,\n * without the second producing a warning an operator cannot act on — which is\n * what a config-passing `getGlobalRegistry` call does, and is the noise this\n * whole change removes.\n *\n * This does NOT provide per-caller log attribution: the singleton has one\n * logger. It makes that one logger a deliberate choice rather than a\n * consequence of which module happened to run first.\n */\nexport function claimGlobalRegistry(logger: ILogger): UnifiedAdapterRegistry {\n globalRegistry ??= new UnifiedAdapterRegistry({ logger });\n return globalRegistry;\n}\n\n/**\n * Thrown by {@link getGlobalRegistry} when a non-empty config arrives after\n * the singleton exists (#5211). The registry has no way to apply it — the\n * logger and `defaultCliTimeoutMs` are fixed at construction — so until this\n * error existed the config was logged at `warn` and dropped, and the caller\n * went on with a registry built from someone else's settings. A config that is\n * accepted and ignored is an instrument that misreports what it was given.\n *\n * The check is on presence, not on equality with the live config: the registry\n * does not keep the config it was built from, and a caller re-supplying the\n * same values is still a caller that believes it configured something.\n */\nexport class RegistryAlreadyInitializedError extends ConfigError {\n constructor(providedKeys: readonly string[]) {\n super(\n 'UnifiedAdapterRegistry singleton is already initialized, so getGlobalRegistry() cannot ' +\n `apply the supplied config (keys: ${providedKeys.join(', ')}). Call resetGlobalRegistry() ` +\n 'first if reconfiguration is intentional, or getGlobalRegistry() with no config to use the ' +\n 'existing instance; claimGlobalRegistry(logger) is the idempotent way to name the logger.',\n { context: { providedKeys: [...providedKeys] } }\n );\n this.name = 'RegistryAlreadyInitializedError';\n }\n}\n\n/**\n * Get the global singleton registry.\n * Creates it on first access with default config.\n *\n * If the singleton already exists and a non-empty config is supplied, this\n * throws {@link RegistryAlreadyInitializedError} — the config cannot be\n * applied, and returning the existing instance would silently hand the caller\n * a registry configured by whoever ran first (#5211). Omitting the config, or\n * passing an empty object, returns the existing instance as before.\n */\nexport function getGlobalRegistry(config?: UnifiedRegistryConfig): UnifiedAdapterRegistry {\n if (globalRegistry === undefined) {\n globalRegistry = new UnifiedAdapterRegistry(config);\n return globalRegistry;\n }\n if (config !== undefined && Object.keys(config).length > 0) {\n throw new RegistryAlreadyInitializedError(Object.keys(config));\n }\n return globalRegistry;\n}\n\n/** Reset the global registry (for testing). */\nexport function resetGlobalRegistry(): void {\n globalRegistry?.dispose();\n globalRegistry = undefined;\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  CUSTOM_API_DEFAULT_MODEL
3
- } from "./chunk-HI5SDT6A.js";
3
+ } from "./chunk-HCPESANB.js";
4
4
  import {
5
5
  AdapterModelError,
6
6
  BaseAdapter,
@@ -10,7 +10,7 @@ import {
10
10
  readGatewayTransport,
11
11
  requireApiKey,
12
12
  validateApiKeyPresence
13
- } from "./chunk-JZQQVIKS.js";
13
+ } from "./chunk-ZG6UJP6U.js";
14
14
  import {
15
15
  assertCustomApiHostResolvesPublic,
16
16
  hostnameOf,
@@ -19,7 +19,7 @@ import {
19
19
  readGatewayEnv,
20
20
  redactApiKey,
21
21
  validateCustomApiBaseUrl
22
- } from "./chunk-2SAKTPAB.js";
22
+ } from "./chunk-K3QNYYJZ.js";
23
23
  import {
24
24
  sanitizeOutput
25
25
  } from "./chunk-2NDA4DHW.js";
@@ -28,13 +28,13 @@ import {
28
28
  } from "./chunk-OITVVSWO.js";
29
29
  import {
30
30
  getAvailabilityCache
31
- } from "./chunk-MG7HNWZT.js";
31
+ } from "./chunk-G47BD5WL.js";
32
32
  import {
33
33
  extractSystemPrompt
34
34
  } from "./chunk-QZUG667L.js";
35
35
  import {
36
36
  generateHyphenId
37
- } from "./chunk-AKOWEZKO.js";
37
+ } from "./chunk-PV7WSTTS.js";
38
38
  import {
39
39
  CliCircuitBreaker,
40
40
  DEFAULT_CIRCUIT_BREAKER_CONFIG,
@@ -45,7 +45,7 @@ import {
45
45
  getDefaultCliCircuitBreakerRegistry,
46
46
  isCallerInputCliError,
47
47
  isTimeoutText
48
- } from "./chunk-XPXTELLI.js";
48
+ } from "./chunk-QDELEGK7.js";
49
49
  import {
50
50
  CLI_NAMES,
51
51
  CLI_SUBPROCESS_TIMEOUTS,
@@ -101,7 +101,7 @@ import {
101
101
  resolveRetryAfterMs,
102
102
  toModelTokenUsage,
103
103
  warnIfGatewayCostUndeclared
104
- } from "./chunk-DUHH2IS4.js";
104
+ } from "./chunk-KGLMAIY3.js";
105
105
  import {
106
106
  parseBoolValue
107
107
  } from "./chunk-LWOX65CP.js";
@@ -4993,4 +4993,4 @@ export {
4993
4993
  SdkAdapter,
4994
4994
  createAutoAdapter
4995
4995
  };
4996
- //# sourceMappingURL=chunk-F7SZ56LN.js.map
4996
+ //# sourceMappingURL=chunk-BNRWICG7.js.map
@@ -4,10 +4,10 @@ import {
4
4
  createOpenAICompatAdapter,
5
5
  discoverGatewayCatalog,
6
6
  readOpenAICompatEnv
7
- } from "./chunk-JFQJLOW4.js";
7
+ } from "./chunk-6PB7JUNT.js";
8
8
  import {
9
9
  gatewayProxyUrl
10
- } from "./chunk-JZQQVIKS.js";
10
+ } from "./chunk-ZG6UJP6U.js";
11
11
  import {
12
12
  DEFAULT_OPENAI_COMPAT_ENDPOINT,
13
13
  GATEWAY_COST_ENV,
@@ -23,7 +23,7 @@ import {
23
23
  getTimeProvider,
24
24
  symbols,
25
25
  writeLine
26
- } from "./chunk-DUHH2IS4.js";
26
+ } from "./chunk-KGLMAIY3.js";
27
27
 
28
28
  // src/cli/doctor-gateway.ts
29
29
  var PROBE_FAMILIES = ["anthropic", "openai", "google"];
@@ -333,4 +333,4 @@ export {
333
333
  formatGatewayReport,
334
334
  formatGatewaySlotWarnings
335
335
  };
336
- //# sourceMappingURL=chunk-GAYE5GWR.js.map
336
+ //# sourceMappingURL=chunk-EBABZGF7.js.map
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  GitHubProvider,
3
3
  ScmError
4
- } from "./chunk-Q34QYIQZ.js";
4
+ } from "./chunk-ISKYBNLW.js";
5
5
  import {
6
6
  resolveToken
7
- } from "./chunk-ILUSO4TT.js";
7
+ } from "./chunk-S6PDNDLL.js";
8
8
  import {
9
9
  err,
10
10
  ok
11
- } from "./chunk-DUHH2IS4.js";
11
+ } from "./chunk-KGLMAIY3.js";
12
12
 
13
13
  // src/scm/factory.ts
14
14
  async function createScmProvider(config) {
@@ -41,4 +41,4 @@ export {
41
41
  createScmProvider,
42
42
  createGitHubProvider
43
43
  };
44
- //# sourceMappingURL=chunk-USGPMAWQ.js.map
44
+ //# sourceMappingURL=chunk-FKN4CJDF.js.map
@@ -3,7 +3,7 @@ import {
3
3
  MODEL_IDS,
4
4
  getTimeProvider,
5
5
  resolveModelIdentitySync
6
- } from "./chunk-DUHH2IS4.js";
6
+ } from "./chunk-KGLMAIY3.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-MG7HNWZT.js.map
153
+ //# sourceMappingURL=chunk-G47BD5WL.js.map
@@ -8,7 +8,7 @@ import {
8
8
  MCP_TIMEOUTS,
9
9
  TEST_TIMEOUTS,
10
10
  WORKFLOW_TIMEOUTS
11
- } from "./chunk-DUHH2IS4.js";
11
+ } from "./chunk-KGLMAIY3.js";
12
12
  import {
13
13
  createGetToolRateLimit
14
14
  } from "./chunk-LWOX65CP.js";
@@ -223,4 +223,4 @@ export {
223
223
  CUSTOM_API_DEFAULT_MODEL,
224
224
  DEFAULTS
225
225
  };
226
- //# sourceMappingURL=chunk-HI5SDT6A.js.map
226
+ //# sourceMappingURL=chunk-HCPESANB.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveClassGuardMs
3
- } from "./chunk-DUHH2IS4.js";
3
+ } from "./chunk-KGLMAIY3.js";
4
4
 
5
5
  // src/cli/cli-readiness.ts
6
6
  var READINESS_LEVELS = ["installed", "authenticated", "serves"];
@@ -90,4 +90,4 @@ export {
90
90
  SERVES_PROBE_PROMPT,
91
91
  probeServes
92
92
  };
93
- //# sourceMappingURL=chunk-TFAI7OB7.js.map
93
+ //# sourceMappingURL=chunk-HDERP5V6.js.map
@@ -4,7 +4,7 @@ import {
4
4
  err,
5
5
  getErrorMessage,
6
6
  ok
7
- } from "./chunk-DUHH2IS4.js";
7
+ } from "./chunk-KGLMAIY3.js";
8
8
 
9
9
  // src/scm/types.ts
10
10
  var ScmError = class extends Error {
@@ -281,4 +281,4 @@ export {
281
281
  ScmError,
282
282
  GitHubProvider
283
283
  };
284
- //# sourceMappingURL=chunk-Q34QYIQZ.js.map
284
+ //# sourceMappingURL=chunk-ISKYBNLW.js.map