nexus-agents 2.104.0 → 2.106.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/{child-mcp-config-XOIMNU6R.js → child-mcp-config-KP2XBOIB.js} +2 -2
  2. package/dist/{chunk-WDVUKSIQ.js → chunk-2DHISFDY.js} +90 -49
  3. package/dist/chunk-2DHISFDY.js.map +1 -0
  4. package/dist/{chunk-FVJ2LM2G.js → chunk-2J6HSR6X.js} +2 -2
  5. package/dist/{chunk-47FQ3BU7.js → chunk-3YWBA5GE.js} +24 -9
  6. package/dist/chunk-3YWBA5GE.js.map +1 -0
  7. package/dist/{chunk-46GXDOWQ.js → chunk-5UU6BQJ3.js} +2 -2
  8. package/dist/{chunk-M54LGBTY.js → chunk-75NKH2VD.js} +4 -4
  9. package/dist/{chunk-ETGNZ6H2.js → chunk-BEWKRRNZ.js} +2 -2
  10. package/dist/{chunk-I5QZ3PVT.js → chunk-BJQA6DSN.js} +2 -2
  11. package/dist/{chunk-WT46JLBD.js → chunk-CNIRLXNH.js} +3 -3
  12. package/dist/{chunk-TFRXRKU5.js → chunk-CUX775NF.js} +4 -4
  13. package/dist/{chunk-UFTQXDUA.js → chunk-DLFJQ6W6.js} +2 -2
  14. package/dist/{chunk-I7UDM43R.js → chunk-DOIOSEDU.js} +118 -4
  15. package/dist/chunk-DOIOSEDU.js.map +1 -0
  16. package/dist/{chunk-2B7332HE.js → chunk-E3JGMUGY.js} +4 -4
  17. package/dist/{chunk-IFO52GSQ.js → chunk-EBJJGYOQ.js} +3 -3
  18. package/dist/{chunk-VIHUOFIT.js → chunk-GMHCPEHS.js} +1418 -176
  19. package/dist/chunk-GMHCPEHS.js.map +1 -0
  20. package/dist/{chunk-2MM5MC45.js → chunk-GRHCGUBQ.js} +9 -1034
  21. package/dist/chunk-GRHCGUBQ.js.map +1 -0
  22. package/dist/{chunk-LM3BH55G.js → chunk-HNBA265P.js} +81 -44
  23. package/dist/{chunk-LM3BH55G.js.map → chunk-HNBA265P.js.map} +1 -1
  24. package/dist/{chunk-ABNHZEKO.js → chunk-KMASI7UC.js} +2 -2
  25. package/dist/{chunk-XWOLOXKN.js → chunk-KZWJ52HH.js} +2 -2
  26. package/dist/{chunk-A5UJBVCQ.js → chunk-M6JRWJZW.js} +2 -2
  27. package/dist/{chunk-RZ4A2RRN.js → chunk-MYXT7VPF.js} +2 -2
  28. package/dist/{chunk-7RE2S46N.js → chunk-OP4VPTQZ.js} +3 -3
  29. package/dist/{chunk-P5XUYJBO.js → chunk-PRPHNXUM.js} +3 -3
  30. package/dist/{chunk-4KTPDSFZ.js → chunk-R2VTDJO5.js} +5 -5
  31. package/dist/{chunk-5YMSKNUG.js → chunk-RWAI74H6.js} +9 -9
  32. package/dist/{chunk-VCLQMXVJ.js → chunk-SFIGDPAE.js} +3 -3
  33. package/dist/{chunk-3TZUEGNB.js → chunk-U3Y6AWG5.js} +2 -2
  34. package/dist/{chunk-VGHPMNDR.js → chunk-VHIRBRZF.js} +2 -2
  35. package/dist/{chunk-PGSXRUH5.js → chunk-VIXH6P3Y.js} +3 -3
  36. package/dist/{chunk-E6FIVDNH.js → chunk-WPF7G56I.js} +2 -2
  37. package/dist/{chunk-K7OKFTCH.js → chunk-YL7SS6JZ.js} +2 -2
  38. package/dist/{cli-circuit-breaker-QMCG6JGV.js → cli-circuit-breaker-PE3AYA56.js} +4 -4
  39. package/dist/cli.js +42 -42
  40. package/dist/cli.js.map +1 -1
  41. package/dist/{composite-router-ZX64CEVG.js → composite-router-GXLSZZQU.js} +2 -2
  42. package/dist/{consensus-vote-7HEHHH5S.js → consensus-vote-ZS4IDC5T.js} +12 -13
  43. package/dist/{context-retriever-J7DIPQUO.js → context-retriever-52RLYDVE.js} +6 -6
  44. package/dist/{doctor-deep-ITSJV2RH.js → doctor-deep-3463IMLO.js} +3 -3
  45. package/dist/{expert-bridge-7R4AU4DE.js → expert-bridge-OBOSFIHR.js} +6 -4
  46. package/dist/factory-SM7AIAFL.js +21 -0
  47. package/dist/{factory-Y2RF33UB.js → factory-VXD4XO7R.js} +5 -5
  48. package/dist/{improvement-review-NBVWPFXR.js → improvement-review-Y4DSR2AF.js} +4 -4
  49. package/dist/index.d.ts +51 -13
  50. package/dist/index.js +61 -63
  51. package/dist/index.js.map +1 -1
  52. package/dist/{init-opencode-QPHX4KVI.js → init-opencode-3FW2TAOR.js} +5 -5
  53. package/dist/{issue-triage-D5ADEG3V.js → issue-triage-KAVEQE5V.js} +5 -5
  54. package/dist/{pr-reviewer-helpers-R7U4EI2P.js → pr-reviewer-helpers-KORDKN6O.js} +4 -4
  55. package/dist/{registry-command-CFNNKJ5S.js → registry-command-WZK7PYVZ.js} +2 -2
  56. package/dist/{repo-security-plan-2AXFDREW.js → repo-security-plan-EO5R3S7C.js} +3 -3
  57. package/dist/{research-helpers-synthesize-YTIDNKBF.js → research-helpers-synthesize-6HFD32XJ.js} +3 -3
  58. package/dist/{routing-memory-YLX6QNY2.js → routing-memory-XPJT3Y6Z.js} +2 -2
  59. package/dist/{session-memory-Y5MUOY56.js → session-memory-TTE5YPV4.js} +3 -3
  60. package/dist/{setup-command-AS65DYIU.js → setup-command-VVHIWCD4.js} +11 -10
  61. package/dist/{setup-config-5J3R7RET.js → setup-config-NEM4KPUA.js} +3 -3
  62. package/dist/{setup-custom-api-MJ24PJA7.js → setup-custom-api-GMMHEJJ5.js} +4 -6
  63. package/dist/{setup-custom-api-MJ24PJA7.js.map → setup-custom-api-GMMHEJJ5.js.map} +1 -1
  64. package/dist/{tool-memory-YNMRI3PZ.js → tool-memory-TTLQ7MHZ.js} +5 -5
  65. package/dist/{weather-report-GZRODMYW.js → weather-report-KGAHUQFF.js} +2 -2
  66. package/package.json +1 -1
  67. package/dist/chunk-2MM5MC45.js.map +0 -1
  68. package/dist/chunk-47FQ3BU7.js.map +0 -1
  69. package/dist/chunk-BLMWODJG.js +0 -120
  70. package/dist/chunk-BLMWODJG.js.map +0 -1
  71. package/dist/chunk-I7UDM43R.js.map +0 -1
  72. package/dist/chunk-VIHUOFIT.js.map +0 -1
  73. package/dist/chunk-WDVUKSIQ.js.map +0 -1
  74. package/dist/factory-UZQ3RGFQ.js +0 -19
  75. /package/dist/{child-mcp-config-XOIMNU6R.js.map → child-mcp-config-KP2XBOIB.js.map} +0 -0
  76. /package/dist/{chunk-FVJ2LM2G.js.map → chunk-2J6HSR6X.js.map} +0 -0
  77. /package/dist/{chunk-46GXDOWQ.js.map → chunk-5UU6BQJ3.js.map} +0 -0
  78. /package/dist/{chunk-M54LGBTY.js.map → chunk-75NKH2VD.js.map} +0 -0
  79. /package/dist/{chunk-ETGNZ6H2.js.map → chunk-BEWKRRNZ.js.map} +0 -0
  80. /package/dist/{chunk-I5QZ3PVT.js.map → chunk-BJQA6DSN.js.map} +0 -0
  81. /package/dist/{chunk-WT46JLBD.js.map → chunk-CNIRLXNH.js.map} +0 -0
  82. /package/dist/{chunk-TFRXRKU5.js.map → chunk-CUX775NF.js.map} +0 -0
  83. /package/dist/{chunk-UFTQXDUA.js.map → chunk-DLFJQ6W6.js.map} +0 -0
  84. /package/dist/{chunk-2B7332HE.js.map → chunk-E3JGMUGY.js.map} +0 -0
  85. /package/dist/{chunk-IFO52GSQ.js.map → chunk-EBJJGYOQ.js.map} +0 -0
  86. /package/dist/{chunk-ABNHZEKO.js.map → chunk-KMASI7UC.js.map} +0 -0
  87. /package/dist/{chunk-XWOLOXKN.js.map → chunk-KZWJ52HH.js.map} +0 -0
  88. /package/dist/{chunk-A5UJBVCQ.js.map → chunk-M6JRWJZW.js.map} +0 -0
  89. /package/dist/{chunk-RZ4A2RRN.js.map → chunk-MYXT7VPF.js.map} +0 -0
  90. /package/dist/{chunk-7RE2S46N.js.map → chunk-OP4VPTQZ.js.map} +0 -0
  91. /package/dist/{chunk-P5XUYJBO.js.map → chunk-PRPHNXUM.js.map} +0 -0
  92. /package/dist/{chunk-4KTPDSFZ.js.map → chunk-R2VTDJO5.js.map} +0 -0
  93. /package/dist/{chunk-5YMSKNUG.js.map → chunk-RWAI74H6.js.map} +0 -0
  94. /package/dist/{chunk-VCLQMXVJ.js.map → chunk-SFIGDPAE.js.map} +0 -0
  95. /package/dist/{chunk-3TZUEGNB.js.map → chunk-U3Y6AWG5.js.map} +0 -0
  96. /package/dist/{chunk-VGHPMNDR.js.map → chunk-VHIRBRZF.js.map} +0 -0
  97. /package/dist/{chunk-PGSXRUH5.js.map → chunk-VIXH6P3Y.js.map} +0 -0
  98. /package/dist/{chunk-E6FIVDNH.js.map → chunk-WPF7G56I.js.map} +0 -0
  99. /package/dist/{chunk-K7OKFTCH.js.map → chunk-YL7SS6JZ.js.map} +0 -0
  100. /package/dist/{cli-circuit-breaker-QMCG6JGV.js.map → cli-circuit-breaker-PE3AYA56.js.map} +0 -0
  101. /package/dist/{composite-router-ZX64CEVG.js.map → composite-router-GXLSZZQU.js.map} +0 -0
  102. /package/dist/{consensus-vote-7HEHHH5S.js.map → consensus-vote-ZS4IDC5T.js.map} +0 -0
  103. /package/dist/{context-retriever-J7DIPQUO.js.map → context-retriever-52RLYDVE.js.map} +0 -0
  104. /package/dist/{doctor-deep-ITSJV2RH.js.map → doctor-deep-3463IMLO.js.map} +0 -0
  105. /package/dist/{expert-bridge-7R4AU4DE.js.map → expert-bridge-OBOSFIHR.js.map} +0 -0
  106. /package/dist/{factory-UZQ3RGFQ.js.map → factory-SM7AIAFL.js.map} +0 -0
  107. /package/dist/{factory-Y2RF33UB.js.map → factory-VXD4XO7R.js.map} +0 -0
  108. /package/dist/{improvement-review-NBVWPFXR.js.map → improvement-review-Y4DSR2AF.js.map} +0 -0
  109. /package/dist/{init-opencode-QPHX4KVI.js.map → init-opencode-3FW2TAOR.js.map} +0 -0
  110. /package/dist/{issue-triage-D5ADEG3V.js.map → issue-triage-KAVEQE5V.js.map} +0 -0
  111. /package/dist/{pr-reviewer-helpers-R7U4EI2P.js.map → pr-reviewer-helpers-KORDKN6O.js.map} +0 -0
  112. /package/dist/{registry-command-CFNNKJ5S.js.map → registry-command-WZK7PYVZ.js.map} +0 -0
  113. /package/dist/{repo-security-plan-2AXFDREW.js.map → repo-security-plan-EO5R3S7C.js.map} +0 -0
  114. /package/dist/{research-helpers-synthesize-YTIDNKBF.js.map → research-helpers-synthesize-6HFD32XJ.js.map} +0 -0
  115. /package/dist/{routing-memory-YLX6QNY2.js.map → routing-memory-XPJT3Y6Z.js.map} +0 -0
  116. /package/dist/{session-memory-Y5MUOY56.js.map → session-memory-TTE5YPV4.js.map} +0 -0
  117. /package/dist/{setup-command-AS65DYIU.js.map → setup-command-VVHIWCD4.js.map} +0 -0
  118. /package/dist/{setup-config-5J3R7RET.js.map → setup-config-NEM4KPUA.js.map} +0 -0
  119. /package/dist/{tool-memory-YNMRI3PZ.js.map → tool-memory-TTLQ7MHZ.js.map} +0 -0
  120. /package/dist/{weather-report-GZRODMYW.js.map → weather-report-KGAHUQFF.js.map} +0 -0
@@ -1,15 +1,3 @@
1
- import {
2
- AdapterModelError,
3
- BaseAdapter,
4
- createStream,
5
- requireApiKey,
6
- validateApiKeyPresence
7
- } from "./chunk-ABNHZEKO.js";
8
- import {
9
- CUSTOM_API_BASE_URL_ENV,
10
- PROVIDER_ENV_KEYS,
11
- validateCustomApiBaseUrl
12
- } from "./chunk-BLMWODJG.js";
13
1
  import {
14
2
  NOOP_NOTIFIER,
15
3
  createMcpNotifier,
@@ -21,30 +9,23 @@ import {
21
9
  toolSuccess,
22
10
  withProgressHeartbeat,
23
11
  wrapToolWithTimeout
24
- } from "./chunk-XWOLOXKN.js";
12
+ } from "./chunk-KZWJ52HH.js";
25
13
  import {
26
14
  getToolMemory
27
- } from "./chunk-M54LGBTY.js";
28
- import {
29
- CUSTOM_API_DEFAULT_MODEL
30
- } from "./chunk-I7UDM43R.js";
15
+ } from "./chunk-75NKH2VD.js";
31
16
  import {
32
17
  authRemediation,
33
- createCliAdapter,
34
- createCliDetectionCache,
18
+ createAutoAdapter,
35
19
  delay,
36
20
  getAvailableClis,
37
- isCliAvailable,
38
- sanitizeOutput,
39
21
  withTimeout
40
- } from "./chunk-VIHUOFIT.js";
22
+ } from "./chunk-GMHCPEHS.js";
41
23
  import {
42
24
  AgentError,
43
25
  CLI_NAMES,
44
26
  CircularBuffer,
45
27
  DEFAULT_CLI,
46
28
  ErrorCode,
47
- ModelCapability,
48
29
  ModelError,
49
30
  OutcomeStore,
50
31
  TASK_SPECIALIZATION_MATRIX,
@@ -55,10 +36,8 @@ import {
55
36
  createLogger,
56
37
  detectTaskCategory,
57
38
  err,
58
- estimateTokens,
59
39
  formatPercentage,
60
40
  formatZodError,
61
- getCliModelName,
62
41
  getDefaultAvailableModelsCache,
63
42
  getDefaultModelForCli,
64
43
  getDefaultRegistry,
@@ -69,15 +48,13 @@ import {
69
48
  getPipelineEventBus,
70
49
  getRandomProvider,
71
50
  getTimeProvider,
72
- getTokenEstimator,
73
51
  isRateLimitLikeError,
74
52
  ok,
75
53
  recordRateLimitEvent,
76
54
  registerPersistentOutcomeStoreFactory,
77
- resolveCliAlias,
78
55
  resolveVoteTimeout,
79
56
  toRateLimitError
80
- } from "./chunk-WDVUKSIQ.js";
57
+ } from "./chunk-2DHISFDY.js";
81
58
  import {
82
59
  ensureLearningDir,
83
60
  getOutcomesFile,
@@ -99,999 +76,6 @@ var VOTER_ROLES = {
99
76
  scope_steward: "Scope Steward - asks whether to build at all; checks existing tools, biases toward kill-the-feature (#2185)"
100
77
  };
101
78
 
102
- // src/cli-adapters/cli-to-model-adapter.ts
103
- var CliToModelAdapter = class {
104
- providerId;
105
- modelId;
106
- capabilities;
107
- cliAdapter;
108
- defaultTimeoutMs;
109
- /**
110
- * Creates a bridge from CLI adapter to model adapter.
111
- *
112
- * @param cliAdapter - The CLI adapter to wrap
113
- * @param config - Optional configuration (e.g. timeout override)
114
- */
115
- constructor(cliAdapter, config) {
116
- this.cliAdapter = cliAdapter;
117
- this.defaultTimeoutMs = config?.defaultTimeoutMs;
118
- this.providerId = `cli-${cliAdapter.name}`;
119
- this.modelId = cliAdapter.getModelInfo().id;
120
- this.capabilities = this.deriveCapabilities();
121
- }
122
- /**
123
- * Derives ModelCapability from CLI capabilities.
124
- */
125
- deriveCapabilities() {
126
- const caps = [ModelCapability.COMPLETION, ModelCapability.TOOL_USE];
127
- if (this.cliAdapter.name === "claude") {
128
- caps.push(ModelCapability.EXTENDED_THINKING);
129
- }
130
- return caps;
131
- }
132
- /**
133
- * Converts CompletionRequest to CliTask.
134
- */
135
- toCliTask(request) {
136
- const content = request.messages.map((msg) => {
137
- const text = typeof msg.content === "string" ? msg.content : msg.content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
138
- return `[${msg.role}]: ${text}`;
139
- }).join("\n\n");
140
- const task = { content };
141
- if (request.systemPrompt !== void 0) {
142
- task.systemPrompt = request.systemPrompt;
143
- }
144
- if (request.maxTokens !== void 0) {
145
- task.maxTokens = request.maxTokens;
146
- }
147
- return task;
148
- }
149
- /**
150
- * Converts CliResponse to CompletionResponse.
151
- */
152
- toCompletionResponse(response) {
153
- return {
154
- content: [{ type: "text", text: response.text }],
155
- usage: {
156
- inputTokens: response.usage?.inputTokens ?? 0,
157
- outputTokens: response.usage?.outputTokens ?? 0,
158
- totalTokens: response.usage?.totalTokens ?? 0
159
- },
160
- stopReason: "end_turn",
161
- model: response.model ?? this.modelId
162
- };
163
- }
164
- /**
165
- * Converts CliError to ModelError.
166
- */
167
- toModelError(cliError) {
168
- const options = cliError.cause !== void 0 ? { cause: cliError.cause } : {};
169
- return new ModelError(cliError.message, options);
170
- }
171
- /**
172
- * Send a completion request via CLI.
173
- */
174
- async complete(request) {
175
- const task = this.toCliTask(request);
176
- const effectiveTimeoutMs = request.timeoutMs ?? this.defaultTimeoutMs;
177
- const opts = effectiveTimeoutMs !== void 0 ? { timeoutMs: effectiveTimeoutMs } : void 0;
178
- const result = await this.cliAdapter.execute(task, opts);
179
- if (!result.ok) {
180
- return err(this.toModelError(result.error));
181
- }
182
- return ok(this.toCompletionResponse(result.value));
183
- }
184
- /**
185
- * Streaming is not supported via CLI adapters.
186
- * Falls back to non-streaming and yields single chunk.
187
- */
188
- async *stream(request) {
189
- const result = await this.complete(request);
190
- if (!result.ok) {
191
- throw result.error;
192
- }
193
- const response = result.value;
194
- yield { type: "message_start", message: { model: response.model } };
195
- yield {
196
- type: "content_block_start",
197
- index: 0,
198
- contentBlock: response.content[0] ?? { type: "text", text: "" }
199
- };
200
- const firstBlock = response.content[0];
201
- const text = firstBlock?.type === "text" ? firstBlock.text : "";
202
- yield { type: "content_block_delta", index: 0, delta: { type: "text_delta", text } };
203
- yield { type: "content_block_stop", index: 0 };
204
- yield {
205
- type: "message_delta",
206
- delta: { stop_reason: response.stopReason },
207
- usage: response.usage
208
- };
209
- yield { type: "message_stop" };
210
- }
211
- /**
212
- * Token count via canonical estimator (DRY consolidation Issue #1596).
213
- */
214
- countTokens(text) {
215
- return Promise.resolve(estimateTokens(text));
216
- }
217
- /**
218
- * Validate configuration by running health check.
219
- */
220
- validateConfig() {
221
- return ok(void 0);
222
- }
223
- /**
224
- * Initialize the underlying CLI adapter.
225
- */
226
- async initialize() {
227
- await this.cliAdapter.initialize();
228
- }
229
- /**
230
- * Dispose the underlying CLI adapter.
231
- */
232
- async dispose() {
233
- await this.cliAdapter.dispose();
234
- }
235
- };
236
- function createCliToModelAdapter(cliAdapter, config) {
237
- return new CliToModelAdapter(cliAdapter, config);
238
- }
239
-
240
- // src/adapters/claude-adapter.ts
241
- import Anthropic3 from "@anthropic-ai/sdk";
242
-
243
- // src/adapters/claude-adapter-types.ts
244
- var CLAUDE_MODELS = {
245
- OPUS_4: getCliModelName("claude-opus"),
246
- SONNET_4: getCliModelName("claude-sonnet"),
247
- HAIKU_4: getCliModelName("claude-haiku")
248
- };
249
- var CLAUDE_MODEL_ALIASES = {
250
- "claude-opus-4": CLAUDE_MODELS.OPUS_4,
251
- "claude-sonnet-4": CLAUDE_MODELS.SONNET_4,
252
- "claude-haiku-4": CLAUDE_MODELS.HAIKU_4,
253
- // Legacy alias — pre-4.x users routed to the current haiku.
254
- "claude-haiku-3": CLAUDE_MODELS.HAIKU_4
255
- };
256
- var DEFAULT_MAX_TOKENS = 4096;
257
-
258
- // src/adapters/claude-adapter-helpers.ts
259
- import "@anthropic-ai/sdk";
260
- function mapStopReason(anthropicReason) {
261
- switch (anthropicReason) {
262
- case "end_turn":
263
- return "end_turn";
264
- case "max_tokens":
265
- return "max_tokens";
266
- case "stop_sequence":
267
- return "stop_sequence";
268
- case "tool_use":
269
- return "tool_use";
270
- default:
271
- return "end_turn";
272
- }
273
- }
274
- function mapContentBlock(block) {
275
- if (block.type === "text") {
276
- return { type: "text", text: block.text };
277
- }
278
- if (block.type === "tool_use") {
279
- const toolBlock = block;
280
- return {
281
- type: "tool_use",
282
- id: toolBlock.id,
283
- name: toolBlock.name,
284
- input: toolBlock.input
285
- };
286
- }
287
- return { type: "text", text: "" };
288
- }
289
- function mapMessage(message) {
290
- const role = message.role === "user" ? "user" : "assistant";
291
- if (typeof message.content === "string") {
292
- return { role, content: message.content };
293
- }
294
- const content = message.content.map((block) => {
295
- if (block.type === "text") {
296
- return { type: "text", text: block.text };
297
- }
298
- if (block.type === "tool_use") {
299
- return {
300
- type: "tool_use",
301
- id: block.id,
302
- name: block.name,
303
- input: block.input
304
- };
305
- }
306
- if (block.type === "tool_result") {
307
- const toolResult = {
308
- type: "tool_result",
309
- tool_use_id: block.tool_use_id,
310
- content: block.content
311
- };
312
- if (block.is_error !== void 0) {
313
- toolResult.is_error = block.is_error;
314
- }
315
- return toolResult;
316
- }
317
- return {
318
- type: "image",
319
- source: block.source
320
- };
321
- });
322
- return { role, content };
323
- }
324
- function mapTool(tool) {
325
- return {
326
- name: tool.name,
327
- description: tool.description,
328
- input_schema: tool.inputSchema
329
- };
330
- }
331
- function resolveModelId(modelId) {
332
- const registryId = resolveCliAlias(modelId);
333
- if (registryId !== void 0) return getCliModelName(registryId);
334
- return modelId;
335
- }
336
- function getModelCapabilities(modelId) {
337
- const capabilities = [
338
- ModelCapability.COMPLETION,
339
- ModelCapability.STREAMING,
340
- ModelCapability.TOOL_USE,
341
- ModelCapability.VISION
342
- ];
343
- const resolvedId = resolveModelId(modelId);
344
- if (resolvedId.includes("opus") || resolvedId.includes("sonnet-4")) {
345
- capabilities.push(ModelCapability.EXTENDED_THINKING);
346
- }
347
- return capabilities;
348
- }
349
-
350
- // src/context/token-counter-helpers.ts
351
- import "@anthropic-ai/sdk";
352
- function generateCacheKey(content, provider, model) {
353
- const contentStr = typeof content === "string" ? content : JSON.stringify(content);
354
- return `${provider}:${model ?? "default"}:${contentStr}`;
355
- }
356
- function messagesToAnthropicFormat(messages) {
357
- return messages.filter((m) => m.role !== "system").map((m) => {
358
- const role = m.role === "user" ? "user" : "assistant";
359
- if (typeof m.content === "string") {
360
- return { role, content: m.content };
361
- }
362
- const content = m.content.map((block) => {
363
- if (block.type === "text") {
364
- return { type: "text", text: block.text };
365
- }
366
- if (block.type === "tool_use") {
367
- return {
368
- type: "tool_use",
369
- id: block.id,
370
- name: block.name,
371
- input: block.input
372
- };
373
- }
374
- if (block.type === "tool_result") {
375
- return {
376
- type: "tool_result",
377
- tool_use_id: block.tool_use_id,
378
- content: block.content
379
- };
380
- }
381
- return {
382
- type: "image",
383
- source: block.source
384
- };
385
- });
386
- return { role, content };
387
- });
388
- }
389
- function extractSystemPrompt(messages) {
390
- const systemMsg = messages.find((m) => m.role === "system");
391
- if (systemMsg === void 0) {
392
- return void 0;
393
- }
394
- if (typeof systemMsg.content === "string") {
395
- return systemMsg.content;
396
- }
397
- return systemMsg.content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
398
- }
399
-
400
- // src/adapters/prompt-utils.ts
401
- function extractRequestSystemPrompt(request) {
402
- if (request.systemPrompt !== void 0 && request.systemPrompt !== "") {
403
- return request.systemPrompt;
404
- }
405
- return extractSystemPrompt(request.messages);
406
- }
407
-
408
- // src/adapters/claude-adapter.ts
409
- var ClaudeAdapter = class extends BaseAdapter {
410
- client;
411
- resolvedModelId;
412
- /**
413
- * Creates a new ClaudeAdapter instance.
414
- *
415
- * @param config - Claude adapter configuration
416
- * @throws {ConfigError} If API key is missing
417
- */
418
- constructor(config) {
419
- const resolvedModelId = resolveModelId(config.modelId);
420
- const baseConfig = {
421
- providerId: "anthropic",
422
- modelId: resolvedModelId,
423
- capabilities: getModelCapabilities(config.modelId),
424
- apiKey: config.apiKey
425
- };
426
- if (config.baseUrl !== void 0) {
427
- baseConfig.baseUrl = config.baseUrl;
428
- }
429
- if (config.timeout !== void 0) {
430
- baseConfig.timeout = config.timeout;
431
- }
432
- if (config.maxRetries !== void 0) {
433
- baseConfig.maxRetries = config.maxRetries;
434
- }
435
- super(baseConfig);
436
- this.resolvedModelId = resolvedModelId;
437
- requireApiKey(config.apiKey, "Anthropic", config.modelId);
438
- this.client = new Anthropic3({
439
- apiKey: config.apiKey,
440
- baseURL: config.baseUrl,
441
- timeout: config.timeout,
442
- maxRetries: config.maxRetries ?? 2
443
- });
444
- }
445
- /**
446
- * Validates adapter configuration.
447
- * Extends base validation with Claude-specific checks.
448
- */
449
- validateConfig() {
450
- const baseResult = super.validateConfig();
451
- if (!baseResult.ok) {
452
- return baseResult;
453
- }
454
- const keyResult = validateApiKeyPresence(this.config.apiKey, this.providerId, this.modelId);
455
- if (!keyResult.ok) return keyResult;
456
- return ok(void 0);
457
- }
458
- /**
459
- * Send a completion request to Claude.
460
- *
461
- * @param request - The completion request
462
- * @returns Result with response or ModelError
463
- */
464
- async complete(request) {
465
- this.logRequest(request);
466
- try {
467
- const response = await this.executeCompletion(request);
468
- this.logResponse(response);
469
- return ok(response);
470
- } catch (error) {
471
- return err(this.transformError(error));
472
- }
473
- }
474
- /**
475
- * Stream a completion request from Claude.
476
- *
477
- * @param request - The completion request
478
- * @yields StreamChunk objects as they arrive
479
- */
480
- async *stream(request) {
481
- this.logRequest(request);
482
- const [controller, iterable] = createStream();
483
- this.executeStream(request, controller).catch((error) => {
484
- const modelError = this.transformError(error);
485
- controller.error(modelError);
486
- });
487
- yield* iterable;
488
- }
489
- /**
490
- * Count tokens in text using Claude-specific estimation.
491
- *
492
- * Claude uses a custom tokenizer. This provides a more accurate estimate
493
- * than the base adapter's generic calculation.
494
- *
495
- * @param text - Text to count tokens for
496
- * @returns Approximate token count
497
- */
498
- countTokens(text) {
499
- return Promise.resolve(getTokenEstimator().estimateText(text, "claude"));
500
- }
501
- /**
502
- * Executes the completion request against the Anthropic API.
503
- */
504
- async executeCompletion(request) {
505
- const params = this.buildRequestParams(request);
506
- const response = request.signal !== void 0 ? await this.client.messages.create(params, { signal: request.signal }) : await this.client.messages.create(params);
507
- return this.mapResponse(response);
508
- }
509
- /**
510
- * Executes streaming completion and pushes chunks to the controller.
511
- */
512
- async executeStream(request, controller) {
513
- try {
514
- const params = this.buildRequestParams(request);
515
- const stream = this.client.messages.stream(params);
516
- for await (const event of stream) {
517
- const chunk = this.mapStreamEvent(event);
518
- if (chunk) {
519
- controller.push(chunk);
520
- }
521
- }
522
- controller.complete();
523
- } catch (error) {
524
- const modelError = this.transformError(error);
525
- controller.error(modelError);
526
- }
527
- }
528
- /**
529
- * Builds Anthropic API request parameters from our CompletionRequest.
530
- */
531
- buildRequestParams(request) {
532
- const messages = request.messages.filter((m) => m.role !== "system").map(mapMessage);
533
- const params = {
534
- model: this.resolvedModelId,
535
- messages,
536
- max_tokens: request.maxTokens ?? DEFAULT_MAX_TOKENS
537
- };
538
- const systemPrompt = extractRequestSystemPrompt(request);
539
- if (systemPrompt !== void 0) {
540
- params.system = systemPrompt;
541
- }
542
- this.applyOptionalParams(params, request);
543
- return params;
544
- }
545
- /**
546
- * Applies optional parameters to the request params.
547
- */
548
- applyOptionalParams(params, request) {
549
- if (request.temperature !== void 0) {
550
- params.temperature = request.temperature;
551
- }
552
- if (request.stop !== void 0 && request.stop.length > 0) {
553
- params.stop_sequences = request.stop;
554
- }
555
- if (request.tools !== void 0 && request.tools.length > 0) {
556
- params.tools = request.tools.map(mapTool);
557
- }
558
- if (request.responseFormat !== void 0 && request.responseFormat.type !== "text") {
559
- this.logger.warn("responseFormat is not supported by Claude adapter", {
560
- requestedFormat: request.responseFormat.type,
561
- suggestion: "Use tool use or prompt engineering for structured output"
562
- });
563
- }
564
- }
565
- /**
566
- * Maps Anthropic API response to our CompletionResponse format.
567
- */
568
- mapResponse(response) {
569
- const content = response.content.map(mapContentBlock);
570
- const usage = {
571
- inputTokens: response.usage.input_tokens,
572
- outputTokens: response.usage.output_tokens,
573
- totalTokens: response.usage.input_tokens + response.usage.output_tokens
574
- };
575
- return {
576
- content,
577
- usage,
578
- stopReason: mapStopReason(response.stop_reason),
579
- model: response.model
580
- };
581
- }
582
- /**
583
- * Maps Anthropic stream events to our StreamChunk format.
584
- */
585
- mapStreamEvent(event) {
586
- switch (event.type) {
587
- case "message_start":
588
- return {
589
- type: "message_start",
590
- message: { model: event.message.model }
591
- };
592
- case "content_block_start":
593
- return {
594
- type: "content_block_start",
595
- index: event.index,
596
- contentBlock: mapContentBlock(event.content_block)
597
- };
598
- case "content_block_delta":
599
- if (event.delta.type === "text_delta") {
600
- return {
601
- type: "content_block_delta",
602
- index: event.index,
603
- delta: { type: "text_delta", text: event.delta.text }
604
- };
605
- }
606
- return null;
607
- case "content_block_stop":
608
- return {
609
- type: "content_block_stop",
610
- index: event.index
611
- };
612
- case "message_delta":
613
- return {
614
- type: "message_delta",
615
- delta: { stop_reason: mapStopReason(event.delta.stop_reason ?? null) },
616
- usage: {
617
- inputTokens: 0,
618
- // Not available in delta
619
- outputTokens: event.usage.output_tokens,
620
- totalTokens: event.usage.output_tokens
621
- }
622
- };
623
- case "message_stop":
624
- return { type: "message_stop" };
625
- default:
626
- return null;
627
- }
628
- }
629
- /**
630
- * (#2540) List models the Anthropic API currently exposes.
631
- * Wraps `client.models.list()`. Cached for 5 min, in-flight promise
632
- * shared across concurrent callers, throws on non-2xx so the
633
- * harness-side identity resolver knows to fall back.
634
- */
635
- async listModels() {
636
- const now = Date.now();
637
- if (this.modelsCache !== null && now - this.modelsCache.fetchedAt < CLAUDE_LIST_MODELS_TTL_MS) {
638
- return this.modelsCache.value;
639
- }
640
- if (this.modelsInFlight !== null) return this.modelsInFlight;
641
- const inFlight2 = this.fetchModels();
642
- this.modelsInFlight = inFlight2;
643
- try {
644
- const value = await inFlight2;
645
- this.modelsCache = { value, fetchedAt: Date.now() };
646
- return value;
647
- } finally {
648
- this.modelsInFlight = null;
649
- }
650
- }
651
- modelsCache = null;
652
- modelsInFlight = null;
653
- async fetchModels() {
654
- const list = await this.client.models.list();
655
- const out = [];
656
- for (const m of list.data) {
657
- const entry = { id: m.id };
658
- if (typeof m.created_at === "string") {
659
- const ts = Date.parse(m.created_at);
660
- if (!Number.isNaN(ts)) {
661
- out.push({ ...entry, ownedBy: "anthropic", createdAt: Math.floor(ts / 1e3) });
662
- continue;
663
- }
664
- }
665
- out.push({ ...entry, ownedBy: "anthropic" });
666
- }
667
- return out;
668
- }
669
- };
670
- var CLAUDE_LIST_MODELS_TTL_MS = 5 * 60 * 1e3;
671
- function createClaudeAdapter(config) {
672
- return new ClaudeAdapter(config);
673
- }
674
-
675
- // src/adapters/sdk/sdk-adapter.ts
676
- function extractProviderFactory(mod, factoryName) {
677
- const factory = mod[factoryName];
678
- if (typeof factory !== "function") {
679
- throw new Error(`AI SDK module missing expected export: ${factoryName}`);
680
- }
681
- return factory;
682
- }
683
- function extractAiSdkFunctions(mod) {
684
- const generateText = mod["generateText"];
685
- const streamText = mod["streamText"];
686
- if (typeof generateText !== "function") {
687
- throw new Error("AI SDK module missing expected export: 'generateText'");
688
- }
689
- if (typeof streamText !== "function") {
690
- throw new Error("AI SDK module missing expected export: 'streamText'");
691
- }
692
- return {
693
- generateText,
694
- streamText
695
- };
696
- }
697
- function resolveApiKey(providerId, configKey) {
698
- if (configKey !== void 0) return configKey;
699
- const envVar = PROVIDER_ENV_KEYS[providerId];
700
- return process.env[envVar];
701
- }
702
- function resolveAndValidateCustomBaseUrl(config) {
703
- if (config.providerId !== "custom-openai") return void 0;
704
- const raw = config.baseUrl ?? process.env[CUSTOM_API_BASE_URL_ENV];
705
- const validated = validateCustomApiBaseUrl(raw);
706
- if (!validated.ok) throw validated.error;
707
- return validated.value.toString();
708
- }
709
- function mapFinishReason(reason) {
710
- switch (reason) {
711
- case "stop":
712
- case "end-turn":
713
- return "end_turn";
714
- case "length":
715
- return "max_tokens";
716
- case "tool-calls":
717
- return "tool_use";
718
- default:
719
- return "end_turn";
720
- }
721
- }
722
- function categorizeError(error) {
723
- if (isRateLimitLikeError(error)) {
724
- return ErrorCode.MODEL_RATE_LIMITED;
725
- }
726
- const message = getErrorMessage(error).toLowerCase();
727
- if (message.includes("timeout") || message.includes("timed out")) {
728
- return ErrorCode.MODEL_TIMEOUT;
729
- }
730
- if (message.includes("401") || message.includes("unauthorized") || message.includes("api key")) {
731
- return ErrorCode.CONFIG_INVALID;
732
- }
733
- return ErrorCode.MODEL_ERROR;
734
- }
735
- var SdkAdapter = class extends BaseAdapter {
736
- sdkProviderId;
737
- model;
738
- sdkFunctions;
739
- sdkConfig;
740
- /** Validated base URL for custom-openai provider; undefined for built-ins. */
741
- customBaseUrl;
742
- /** Inflight init promise for coalescing concurrent calls (Issue #1438). */
743
- initPromise;
744
- constructor(config, logger11) {
745
- const apiKey = resolveApiKey(config.providerId, config.apiKey);
746
- super({
747
- providerId: `sdk-${config.providerId}`,
748
- modelId: config.modelId,
749
- capabilities: [ModelCapability.COMPLETION, ModelCapability.STREAMING],
750
- logger: logger11 ?? createLogger({ adapter: `sdk-${config.providerId}` }),
751
- ...apiKey !== void 0 ? { apiKey } : {},
752
- ...config.timeout !== void 0 ? { timeout: config.timeout } : {},
753
- ...config.maxRetries !== void 0 ? { maxRetries: config.maxRetries } : {}
754
- });
755
- this.sdkProviderId = config.providerId;
756
- this.sdkConfig = config;
757
- this.customBaseUrl = resolveAndValidateCustomBaseUrl(config);
758
- }
759
- /**
760
- * Lazily initialize the AI SDK model and functions.
761
- * This allows the adapter to be created without the AI SDK installed,
762
- * failing only when actually used.
763
- */
764
- async ensureInitialized() {
765
- if (this.model !== void 0) return;
766
- if (this.initPromise !== void 0) {
767
- await this.initPromise;
768
- return;
769
- }
770
- this.initPromise = this.doInitialize();
771
- try {
772
- await this.initPromise;
773
- } finally {
774
- this.initPromise = void 0;
775
- }
776
- }
777
- async doInitialize() {
778
- const apiKey = resolveApiKey(this.sdkProviderId, this.sdkConfig.apiKey);
779
- if (apiKey === void 0) {
780
- throw new AdapterModelError(`No API key for ${this.sdkProviderId}`, {
781
- code: ErrorCode.CONFIG_INVALID
782
- });
783
- }
784
- const providerModule = await this.loadProvider(apiKey);
785
- this.model = providerModule.model;
786
- const aiModule = await import("ai");
787
- this.sdkFunctions = extractAiSdkFunctions(aiModule);
788
- }
789
- /**
790
- * Loads the provider-specific AI SDK module.
791
- *
792
- * Each @ai-sdk/* package exports a factory function (e.g., createAnthropic)
793
- * that returns a callable provider instance. We use extractProviderFactory()
794
- * to validate the export exists at runtime, since these are optional peer deps.
795
- */
796
- async loadProvider(apiKey) {
797
- switch (this.sdkProviderId) {
798
- case "anthropic": {
799
- const mod = await import("@ai-sdk/anthropic");
800
- const factory = extractProviderFactory(mod, "createAnthropic");
801
- const provider = factory({ apiKey });
802
- return { model: provider(this.modelId) };
803
- }
804
- case "openai": {
805
- const mod = await import("@ai-sdk/openai");
806
- const factory = extractProviderFactory(mod, "createOpenAI");
807
- const provider = factory({ apiKey });
808
- return { model: provider(this.modelId) };
809
- }
810
- case "google": {
811
- const mod = await import("@ai-sdk/google");
812
- const factory = extractProviderFactory(mod, "createGoogleGenerativeAI");
813
- const provider = factory({ apiKey });
814
- return { model: provider(this.modelId) };
815
- }
816
- case "custom-openai": {
817
- const mod = await import("@ai-sdk/openai");
818
- const factory = extractProviderFactory(mod, "createOpenAI");
819
- const opts = { apiKey };
820
- if (this.customBaseUrl !== void 0) opts["baseURL"] = this.customBaseUrl;
821
- const provider = factory(opts);
822
- return { model: provider(this.modelId) };
823
- }
824
- }
825
- }
826
- /**
827
- * Maps our CompletionRequest to AI SDK generateText options.
828
- */
829
- buildSdkOptions(request) {
830
- const options = {
831
- model: this.model,
832
- messages: request.messages.map((m) => ({
833
- role: m.role === "system" ? "system" : m.role,
834
- content: typeof m.content === "string" ? m.content : m.content.map((c) => {
835
- if (c.type === "text") return { type: "text", text: c.text };
836
- return c;
837
- })
838
- }))
839
- };
840
- if (request.systemPrompt !== void 0) {
841
- options["system"] = request.systemPrompt;
842
- }
843
- if (request.temperature !== void 0) {
844
- options["temperature"] = request.temperature;
845
- }
846
- if (request.maxTokens !== void 0) {
847
- options["maxTokens"] = request.maxTokens;
848
- }
849
- if (request.stop !== void 0) {
850
- options["stopSequences"] = request.stop;
851
- }
852
- return options;
853
- }
854
- async complete(request) {
855
- try {
856
- await this.ensureInitialized();
857
- this.logRequest(request);
858
- const sdk = this.sdkFunctions;
859
- if (sdk === void 0) {
860
- throw new Error(
861
- `SDK not initialized for model '${this.sdkConfig.modelId}' (provider: ${this.sdkProviderId}). Ensure ensureInitialized() completes before calling complete().`
862
- );
863
- }
864
- const options = this.buildSdkOptions(request);
865
- const result = await sdk.generateText(options);
866
- const response = {
867
- content: [{ type: "text", text: result.text }],
868
- usage: {
869
- inputTokens: result.usage.inputTokens ?? 0,
870
- outputTokens: result.usage.outputTokens ?? 0,
871
- totalTokens: result.usage.totalTokens ?? 0
872
- },
873
- stopReason: mapFinishReason(result.finishReason),
874
- model: result.response.modelId
875
- };
876
- this.logResponse(response);
877
- return ok(response);
878
- } catch (error) {
879
- const code = categorizeError(error);
880
- return this.toErrorResult(error, code);
881
- }
882
- }
883
- async *stream(request) {
884
- await this.ensureInitialized();
885
- this.logRequest(request);
886
- const sdk = this.sdkFunctions;
887
- if (sdk === void 0) {
888
- throw new AdapterModelError("SDK not initialized after ensureInitialized()", {
889
- code: ErrorCode.CONFIG_INVALID
890
- });
891
- }
892
- const options = this.buildSdkOptions(request);
893
- yield { type: "message_start", message: { model: this.modelId } };
894
- const result = sdk.streamText(options);
895
- let index = 0;
896
- yield { type: "content_block_start", index, contentBlock: { type: "text", text: "" } };
897
- for await (const text of result.textStream) {
898
- yield {
899
- type: "content_block_delta",
900
- index,
901
- delta: { type: "text_delta", text }
902
- };
903
- }
904
- yield { type: "content_block_stop", index };
905
- index++;
906
- yield {
907
- type: "message_delta",
908
- delta: { stop_reason: "end_turn" },
909
- usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 }
910
- };
911
- yield { type: "message_stop" };
912
- }
913
- /**
914
- * Converts a caught error into a Result error with categorized ErrorCode.
915
- */
916
- toErrorResult(error, code) {
917
- const message = getErrorMessage(error);
918
- const safeMessage = sanitizeOutput(message);
919
- const errorObj = error instanceof Error ? error : new Error(safeMessage);
920
- this.logger.error(`SDK adapter error (${this.sdkProviderId})`, errorObj);
921
- const modelError = new AdapterModelError(`${this.sdkProviderId} SDK error: ${safeMessage}`, {
922
- code
923
- });
924
- return { ok: false, error: modelError };
925
- }
926
- };
927
-
928
- // src/adapters/auto-adapter.ts
929
- var defaultLogger = createLogger({ component: "auto-adapter" });
930
- function resolveCache(config, logger11) {
931
- if (config.cache !== void 0) {
932
- return config.cache;
933
- }
934
- const enableCache = config.enableCache ?? true;
935
- return enableCache ? createCliDetectionCache({ logger: logger11 }) : void 0;
936
- }
937
- async function tryCliAdapter(config, logger11, cache) {
938
- const preferredCli = config.preferredCli;
939
- const bridgeConfig = config.defaultCliTimeoutMs !== void 0 ? { defaultTimeoutMs: config.defaultCliTimeoutMs } : void 0;
940
- if (preferredCli !== void 0 && await isCliAvailable(preferredCli, cache)) {
941
- logger11.info("Using preferred CLI", { cli: preferredCli });
942
- const cliAdapter2 = createCliAdapter({ cli: preferredCli, logger: logger11 });
943
- await cliAdapter2.initialize();
944
- return {
945
- adapter: createCliToModelAdapter(cliAdapter2, bridgeConfig),
946
- source: "cli",
947
- name: preferredCli,
948
- reason: `Preferred CLI '${preferredCli}' is available (model selection handled by CLI)`,
949
- cache
950
- };
951
- }
952
- const availableClis = await getAvailableClis(cache);
953
- if (availableClis.length === 0) {
954
- logger11.info("No CLI adapters available");
955
- return null;
956
- }
957
- const selectedCli = availableClis[0];
958
- if (selectedCli === void 0) {
959
- return null;
960
- }
961
- logger11.info("Auto-selected CLI", { cli: selectedCli, available: availableClis });
962
- const cliAdapter = createCliAdapter({ cli: selectedCli, logger: logger11 });
963
- await cliAdapter.initialize();
964
- return {
965
- adapter: createCliToModelAdapter(cliAdapter, bridgeConfig),
966
- source: "cli",
967
- name: selectedCli,
968
- reason: `Using '${selectedCli}' CLI (model selection handled by CLI)`,
969
- cache
970
- };
971
- }
972
- function resolveApiKeyFromEnv(configKey, envVar) {
973
- const key = configKey ?? process.env[envVar];
974
- return key !== void 0 && key.length > 0 ? key : void 0;
975
- }
976
- function tryApiAdapter(config, logger11) {
977
- const claudeModelId = getCliModelName(getDefaultModelForCli("claude"));
978
- const codexModelId = getCliModelName(getDefaultModelForCli("codex"));
979
- const geminiModelId = getCliModelName(getDefaultModelForCli("gemini"));
980
- const anthropicKey = resolveApiKeyFromEnv(config.anthropicApiKey, "ANTHROPIC_API_KEY");
981
- if (anthropicKey !== void 0) {
982
- logger11.info("Using Anthropic API adapter", { model: claudeModelId });
983
- return {
984
- adapter: createClaudeAdapter({ modelId: claudeModelId, apiKey: anthropicKey }),
985
- source: "api",
986
- name: "anthropic",
987
- reason: `Using Anthropic API (native adapter, model: ${claudeModelId})`
988
- };
989
- }
990
- const openaiKey = resolveApiKeyFromEnv(config.openaiApiKey, "OPENAI_API_KEY");
991
- if (openaiKey !== void 0) {
992
- logger11.info("Using OpenAI API adapter (AI SDK)", { model: codexModelId });
993
- return {
994
- adapter: new SdkAdapter({ providerId: "openai", modelId: codexModelId, apiKey: openaiKey }),
995
- source: "api",
996
- name: "openai",
997
- reason: `Using OpenAI API via AI SDK (model: ${codexModelId})`
998
- };
999
- }
1000
- const googleKey = resolveApiKeyFromEnv(config.googleApiKey, "GOOGLE_AI_API_KEY");
1001
- if (googleKey !== void 0) {
1002
- logger11.info("Using Google AI API adapter (AI SDK)", { model: geminiModelId });
1003
- return {
1004
- adapter: new SdkAdapter({
1005
- providerId: "google",
1006
- modelId: geminiModelId,
1007
- apiKey: googleKey
1008
- }),
1009
- source: "api",
1010
- name: "google",
1011
- reason: `Using Google AI API via AI SDK (model: ${geminiModelId})`
1012
- };
1013
- }
1014
- const custom = tryCustomOpenAiAdapter(logger11);
1015
- if (custom !== null) return custom;
1016
- logger11.info("No API keys available for any provider");
1017
- return null;
1018
- }
1019
- function tryCustomOpenAiAdapter(logger11) {
1020
- const customKey = resolveApiKeyFromEnv(void 0, "NEXUS_CUSTOM_API_KEY");
1021
- const customBaseUrl = process.env["NEXUS_CUSTOM_API_BASE_URL"];
1022
- if (customKey === void 0 || customBaseUrl === void 0 || customBaseUrl === "") {
1023
- return null;
1024
- }
1025
- const customModelId = process.env["NEXUS_CUSTOM_MODEL"] ?? CUSTOM_API_DEFAULT_MODEL;
1026
- logger11.info("Using custom-openai SDK adapter", {
1027
- model: customModelId,
1028
- baseUrl: customBaseUrl
1029
- });
1030
- return {
1031
- adapter: new SdkAdapter({
1032
- providerId: "custom-openai",
1033
- modelId: customModelId,
1034
- apiKey: customKey,
1035
- baseUrl: customBaseUrl
1036
- }),
1037
- source: "api",
1038
- name: "custom-openai",
1039
- reason: `Using custom OpenAI-compatible gateway at ${customBaseUrl} (model: ${customModelId})`
1040
- };
1041
- }
1042
- async function selectCliFirst(config, logger11, cache) {
1043
- const cliResult = await tryCliAdapter(config, logger11, cache);
1044
- if (cliResult !== null) return cliResult;
1045
- const apiResult = tryApiAdapter(config, logger11);
1046
- if (apiResult !== null) return apiResult;
1047
- throw new Error(
1048
- "No adapters available. Install a CLI (claude/gemini/codex) or set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GOOGLE_AI_API_KEY."
1049
- );
1050
- }
1051
- async function selectApiFirst(config, logger11, cache) {
1052
- const apiResult = tryApiAdapter(config, logger11);
1053
- if (apiResult !== null) return apiResult;
1054
- const cliResult = await tryCliAdapter(config, logger11, cache);
1055
- if (cliResult !== null) return cliResult;
1056
- throw new Error(
1057
- "No adapters available. Set ANTHROPIC_API_KEY/OPENAI_API_KEY/GOOGLE_AI_API_KEY or install a CLI (claude/gemini/codex)."
1058
- );
1059
- }
1060
- async function selectCliOnly(config, logger11, cache) {
1061
- const cliResult = await tryCliAdapter(config, logger11, cache);
1062
- if (cliResult !== null) return cliResult;
1063
- throw new Error(
1064
- "No CLI adapters available. Install and authenticate claude, gemini, or codex CLI."
1065
- );
1066
- }
1067
- function selectApiOnly(config, logger11) {
1068
- const apiResult = tryApiAdapter(config, logger11);
1069
- if (apiResult !== null) return apiResult;
1070
- throw new Error(
1071
- "No API key available. Set ANTHROPIC_API_KEY, OPENAI_API_KEY, or GOOGLE_AI_API_KEY."
1072
- );
1073
- }
1074
- async function createAutoAdapter(config = {}) {
1075
- const logger11 = config.logger ?? defaultLogger;
1076
- const priority = config.priority ?? "cli-first";
1077
- const cache = resolveCache(config, logger11);
1078
- logger11.info("Auto-selecting adapter", { priority, cacheEnabled: cache !== void 0 });
1079
- switch (priority) {
1080
- case "cli-first":
1081
- return selectCliFirst(config, logger11, cache);
1082
- case "api-first":
1083
- return selectApiFirst(config, logger11, cache);
1084
- case "cli-only":
1085
- return selectCliOnly(config, logger11, cache);
1086
- case "api-only":
1087
- return selectApiOnly(config, logger11);
1088
- default: {
1089
- const exhaustive = priority;
1090
- throw new Error(`Unknown priority: ${String(exhaustive)}`);
1091
- }
1092
- }
1093
- }
1094
-
1095
79
  // src/agents/collaboration/event-bus-helpers.ts
1096
80
  import { randomUUID } from "crypto";
1097
81
  var DEFAULT_MAX_HISTORY_SIZE = 1e3;
@@ -2706,7 +1690,7 @@ function computeOverallConsensusDeadlineMs(timeoutMs, maxRetries, roleCount, int
2706
1690
  return perVoteBudget + staggerBudget + VOTE_TIMEOUTS.overallDeadlineBufferMs;
2707
1691
  }
2708
1692
  var DEFAULT_INTER_AGENT_DELAY_MS = 2e3;
2709
- var defaultLogger2 = createLogger({ component: "voter-agents" });
1693
+ var defaultLogger = createLogger({ component: "voter-agents" });
2710
1694
  async function executeAgentVote(role, proposal, adapter, logger11, options) {
2711
1695
  const start = getTimeProvider().now();
2712
1696
  const timeoutMs = options?.timeoutMs ?? resolveVoteTimeout();
@@ -2839,7 +1823,7 @@ async function launchStaggeredVotes(input) {
2839
1823
  });
2840
1824
  }
2841
1825
  async function collectRealVotes(options) {
2842
- const logger11 = options.logger ?? defaultLogger2;
1826
+ const logger11 = options.logger ?? defaultLogger;
2843
1827
  const { roles, proposal, simulate, allowSimulation } = options;
2844
1828
  const timeoutMs = options.timeoutMs ?? resolveVoteTimeout();
2845
1829
  const maxRetries = options.maxRetries ?? VOTE_TIMEOUTS.maxRetries;
@@ -7003,7 +5987,7 @@ async function processVotesWithCascade(engineVotes, opts) {
7003
5987
  var CONTRARIAN_ESCALATION_THRESHOLD = 0.8;
7004
5988
  async function runContrarianCheck(proposal, log) {
7005
5989
  try {
7006
- const { executeExpert } = await import("./expert-bridge-7R4AU4DE.js");
5990
+ const { executeExpert } = await import("./expert-bridge-OBOSFIHR.js");
7007
5991
  const prompt = [
7008
5992
  "You are a contrarian analyst. Your job is to find reasons this proposal should be REJECTED.",
7009
5993
  "Look for: YAGNI (not needed), MISALIGNED (wrong tech/architecture), SECURITY_RISK, SCOPE_CREEP.",
@@ -7395,15 +6379,6 @@ function registerConsensusVoteTool(server, deps) {
7395
6379
  }
7396
6380
 
7397
6381
  export {
7398
- generateCacheKey,
7399
- messagesToAnthropicFormat,
7400
- extractSystemPrompt,
7401
- extractRequestSystemPrompt,
7402
- CLAUDE_MODELS,
7403
- CLAUDE_MODEL_ALIASES,
7404
- ClaudeAdapter,
7405
- createClaudeAdapter,
7406
- SdkAdapter,
7407
6382
  getGlobalEventBus,
7408
6383
  createEvent,
7409
6384
  EventTopics,
@@ -7496,4 +6471,4 @@ export {
7496
6471
  CONSENSUS_VOTE_OUTPUT_SCHEMA,
7497
6472
  registerConsensusVoteTool
7498
6473
  };
7499
- //# sourceMappingURL=chunk-2MM5MC45.js.map
6474
+ //# sourceMappingURL=chunk-GRHCGUBQ.js.map