@smithers-orchestrator/agents 0.24.2 → 0.25.1

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 (55) hide show
  1. package/package.json +15 -5
  2. package/src/AgentLike.ts +5 -0
  3. package/src/AmpAgent.js +15 -5
  4. package/src/AmpAgentOptions.ts +6 -0
  5. package/src/BaseCliAgent/BaseCliAgent.js +198 -10
  6. package/src/BaseCliAgent/createAgentStdoutTextEmitter.js +21 -3
  7. package/src/BaseCliAgent/index.d.ts +467 -0
  8. package/src/ClaudeCodeAgent.js +6 -2
  9. package/src/CodexAgent.js +4 -0
  10. package/src/GeminiAgent.js +34 -224
  11. package/src/GeminiAgentOptions.ts +4 -9
  12. package/src/OpenCodeAgent.js +2 -12
  13. package/src/OpenCodeAgentOptions.ts +19 -0
  14. package/src/PiAgent.js +4 -0
  15. package/src/cli-capabilities/CliAgentCapabilityAdapterId.ts +0 -1
  16. package/src/cli-capabilities/getCliAgentCapabilityDoctorReport.js +3 -2
  17. package/src/cli-capabilities/getCliAgentCapabilityReport.js +0 -6
  18. package/src/cli-surface/cliAgentSurfaceManifest.js +1 -40
  19. package/src/createElevenLabsTextToSpeechTool.js +128 -0
  20. package/src/createElevenLabsTextToSpeechTool.ts +33 -0
  21. package/src/diagnostics/getDiagnosticStrategy.js +163 -35
  22. package/src/document-parsing/DocumentParsingProvider.ts +13 -0
  23. package/src/document-parsing/DocumentParsingResult.ts +13 -0
  24. package/src/document-parsing/DocumentParsingToolset.ts +4 -0
  25. package/src/document-parsing/DocumentParsingToolsetOptions.ts +9 -0
  26. package/src/document-parsing/createDocumentParsingToolset.d.ts +9 -0
  27. package/src/document-parsing/createDocumentParsingToolset.js +416 -0
  28. package/src/http/CreateHttpToolOptions.ts +4 -0
  29. package/src/http/HttpToolAuth.ts +15 -0
  30. package/src/http/HttpToolInput.ts +11 -0
  31. package/src/http/HttpToolOutput.ts +7 -0
  32. package/src/http/createHttpTool.js +136 -0
  33. package/src/image-generation/ImageGenerationProvider.ts +7 -0
  34. package/src/image-generation/ImageGenerationRequest.ts +8 -0
  35. package/src/image-generation/ImageGenerationResult.ts +10 -0
  36. package/src/image-generation/ImageGenerationToolOptions.ts +10 -0
  37. package/src/image-generation/createImageGenerationTool.d.ts +18 -0
  38. package/src/image-generation/createImageGenerationTool.js +92 -0
  39. package/src/index.d.ts +490 -147
  40. package/src/index.js +23 -5
  41. package/src/streamResultToGenerateResult.js +55 -26
  42. package/src/transcription/createTranscriptionTool.js +182 -0
  43. package/src/transcription/createTranscriptionTool.ts +29 -0
  44. package/src/transcription/index.js +1 -0
  45. package/src/transcription/index.ts +6 -0
  46. package/src/web-search/GroundedWebSearchProvider.ts +21 -0
  47. package/src/web-search/GroundedWebSearchToolset.ts +6 -0
  48. package/src/web-search/createBraveSearchProvider.js +53 -0
  49. package/src/web-search/createExaSearchProvider.js +72 -0
  50. package/src/web-search/createGroundedWebSearchToolset.js +110 -0
  51. package/src/web-search/createSerperSearchProvider.js +63 -0
  52. package/src/web-search/createTavilySearchProvider.js +59 -0
  53. package/src/web-search/index.js +5 -0
  54. package/src/zodToOpenAISchema.js +4 -0
  55. package/src/OpenCodeAgent.ts +0 -43
@@ -0,0 +1,467 @@
1
+ import * as ai from 'ai';
2
+ import * as _smithers_orchestrator_errors_SmithersError from '@smithers-orchestrator/errors/SmithersError';
3
+ import { SmithersError as SmithersError$1 } from '@smithers-orchestrator/errors/SmithersError';
4
+ import { Effect } from 'effect';
5
+ import { spawn } from 'node:child_process';
6
+
7
+ type RunCommandResult$2 = {
8
+ stdout: string;
9
+ stderr: string;
10
+ exitCode: number | null;
11
+ /** True when captured stdout exceeded maxOutputBytes and was truncated. */
12
+ stdoutTruncated?: boolean;
13
+ /** True when captured stderr exceeded maxOutputBytes and was truncated. */
14
+ stderrTruncated?: boolean;
15
+ };
16
+
17
+ type PiExtensionUiResponse$2 = {
18
+ type: "extension_ui_response";
19
+ id: string;
20
+ value?: string;
21
+ cancelled?: boolean;
22
+ [key: string]: unknown;
23
+ };
24
+
25
+ type PiExtensionUiRequest$2 = {
26
+ type: "extension_ui_request";
27
+ id: string;
28
+ method: string;
29
+ title?: string;
30
+ placeholder?: string;
31
+ [key: string]: unknown;
32
+ };
33
+
34
+ type CodexConfigOverrides$2 = Record<string, string | number | boolean | object | null> | string[];
35
+
36
+ type NormalizedTokenUsage$2 = {
37
+ inputTokens?: number;
38
+ outputTokens?: number;
39
+ cacheReadTokens?: number;
40
+ cacheWriteTokens?: number;
41
+ reasoningTokens?: number;
42
+ totalTokens?: number;
43
+ };
44
+
45
+ type CliUsageInfo$2 = {
46
+ inputTokens?: number;
47
+ outputTokens?: number;
48
+ cacheReadTokens?: number;
49
+ cacheWriteTokens?: number;
50
+ reasoningTokens?: number;
51
+ };
52
+
53
+ type AgentCliActionKind$2 = "turn" | "command" | "tool" | "file_change" | "web_search" | "todo_list" | "reasoning" | "warning" | "note";
54
+
55
+ type AgentCliActionPhase$1 = "started" | "updated" | "completed";
56
+ type AgentCliEventLevel$1 = "debug" | "info" | "warning" | "error";
57
+ type AgentCliStartedEvent$1 = {
58
+ type: "started";
59
+ engine: string;
60
+ title: string;
61
+ resume?: string;
62
+ detail?: Record<string, unknown>;
63
+ };
64
+ type AgentCliActionEvent$1 = {
65
+ type: "action";
66
+ engine: string;
67
+ phase: AgentCliActionPhase$1;
68
+ entryType?: "thought" | "message";
69
+ action: {
70
+ id: string;
71
+ kind: AgentCliActionKind$2;
72
+ title: string;
73
+ detail?: Record<string, unknown>;
74
+ };
75
+ message?: string;
76
+ ok?: boolean;
77
+ level?: AgentCliEventLevel$1;
78
+ };
79
+ type AgentCliCompletedEvent$1 = {
80
+ type: "completed";
81
+ engine: string;
82
+ ok: boolean;
83
+ answer?: string;
84
+ error?: string;
85
+ resume?: string;
86
+ usage?: Record<string, unknown>;
87
+ };
88
+ type AgentCliEvent$1 = AgentCliStartedEvent$1 | AgentCliActionEvent$1 | AgentCliCompletedEvent$1;
89
+
90
+ type CliOutputInterpreter$2 = {
91
+ onStdoutLine?: (line: string) => AgentCliEvent$1[] | AgentCliEvent$1 | null | undefined;
92
+ onStderrLine?: (line: string) => AgentCliEvent$1[] | AgentCliEvent$1 | null | undefined;
93
+ onExit?: (result: RunCommandResult$2) => AgentCliEvent$1[] | AgentCliEvent$1 | null | undefined;
94
+ };
95
+
96
+ type BaseCliAgentOptions$2 = {
97
+ id?: string;
98
+ model?: string;
99
+ systemPrompt?: string;
100
+ instructions?: string;
101
+ cwd?: string;
102
+ env?: Record<string, string>;
103
+ yolo?: boolean;
104
+ timeoutMs?: number;
105
+ idleTimeoutMs?: number;
106
+ maxOutputBytes?: number;
107
+ extraArgs?: string[];
108
+ };
109
+
110
+ /**
111
+ * Loosely-typed generation options. The AI SDK passes a dynamic shape here
112
+ * (GenerateTextOptions / StreamTextOptions and provider-specific extensions)
113
+ * so we keep this permissive but avoid raw `any`.
114
+ */
115
+ type AgentGenerateOptions$2 = {
116
+ prompt?: unknown;
117
+ messages?: unknown;
118
+ timeout?: unknown;
119
+ abortSignal?: AbortSignal;
120
+ rootDir?: string;
121
+ resumeSession?: string;
122
+ maxOutputBytes?: number;
123
+ onStdout?: (text: string) => void;
124
+ onStderr?: (text: string) => void;
125
+ onEvent?: (event: AgentCliEvent$1) => unknown;
126
+ retry?: unknown;
127
+ isRetry?: unknown;
128
+ retryAttempt?: unknown;
129
+ schemaRetry?: unknown;
130
+ /**
131
+ * Run context for the task this agent invocation belongs to. Surfaced to the
132
+ * spawned agent process (and its subprocesses) as SMITHERS_RUN_ID / NODE_ID /
133
+ * ITERATION / ATTEMPT so the agent can address its own run — e.g. to raise a
134
+ * blocking `smithers ask-human` request.
135
+ */
136
+ taskContext?: {
137
+ runId?: string;
138
+ nodeId?: string;
139
+ iteration?: number;
140
+ attempt?: number;
141
+ };
142
+ [key: string]: unknown;
143
+ };
144
+
145
+ /**
146
+ * @typedef {number | { totalMs?: number; idleMs?: number; } | undefined} TimeoutInput
147
+ */
148
+ /**
149
+ * @param {TimeoutInput} timeout
150
+ * @param {{ totalMs?: number; idleMs?: number }} [fallback]
151
+ * @returns {{ totalMs?: number; idleMs?: number }}
152
+ */
153
+ declare function resolveTimeouts(timeout: TimeoutInput, fallback?: {
154
+ totalMs?: number;
155
+ idleMs?: number;
156
+ }): {
157
+ totalMs?: number;
158
+ idleMs?: number;
159
+ };
160
+ type TimeoutInput = number | {
161
+ totalMs?: number;
162
+ idleMs?: number;
163
+ } | undefined;
164
+
165
+ /**
166
+ * @param {Array<string | undefined>} parts
167
+ * @returns {string | undefined}
168
+ */
169
+ declare function combineNonEmpty(parts: Array<string | undefined>): string | undefined;
170
+
171
+ /**
172
+ * @param {unknown} options
173
+ * @returns {PromptParts}
174
+ */
175
+ declare function extractPrompt(options: unknown): PromptParts;
176
+ type PromptParts = {
177
+ prompt: string;
178
+ systemFromMessages?: string;
179
+ };
180
+
181
+ /**
182
+ * @param {string} text
183
+ * @returns {unknown | undefined}
184
+ */
185
+ declare function tryParseJson(text: string): unknown | undefined;
186
+
187
+ /**
188
+ * @param {unknown} value
189
+ * @returns {string | undefined}
190
+ */
191
+ declare function extractTextFromJsonValue(value: unknown): string | undefined;
192
+
193
+ /**
194
+ * @param {unknown} usage
195
+ * @returns {NormalizedTokenUsage | null}
196
+ */
197
+ declare function normalizeTokenUsage(usage: unknown): NormalizedTokenUsage$1 | null;
198
+ type NormalizedTokenUsage$1 = NormalizedTokenUsage$2;
199
+
200
+ /**
201
+ * @param {AgentStdoutTextEmitterOptions} options
202
+ * @returns {AgentStdoutTextEmitter}
203
+ */
204
+ declare function createAgentStdoutTextEmitter(options: AgentStdoutTextEmitterOptions): AgentStdoutTextEmitter;
205
+ type AgentStdoutTextEmitter = {
206
+ push: (chunk: string) => void;
207
+ flush: (finalText?: string) => void;
208
+ };
209
+ type AgentStdoutTextEmitterOptions = {
210
+ outputFormat?: string;
211
+ onText?: (text: string) => void;
212
+ };
213
+
214
+ /**
215
+ * @param {string} text
216
+ * @param {number} [maxBytes]
217
+ * @returns {string}
218
+ */
219
+ declare function truncateToBytes(text: string, maxBytes?: number): string;
220
+
221
+ /** @typedef {import("ai").GenerateTextResult} GenerateTextResult */
222
+ /** @typedef {import("ai").LanguageModelUsage} LanguageModelUsage */
223
+ /**
224
+ * @param {string} text
225
+ * @param {unknown} output
226
+ * @param {string} modelId
227
+ * @param {LanguageModelUsage} [usage]
228
+ * @returns {GenerateTextResult<Record<string, never>, unknown>}
229
+ */
230
+ declare function buildGenerateResult(text: string, output: unknown, modelId: string, usage?: LanguageModelUsage): GenerateTextResult$1<Record<string, never>, unknown>;
231
+ type GenerateTextResult$1 = ai.GenerateTextResult<any, any>;
232
+ type LanguageModelUsage = ai.LanguageModelUsage;
233
+
234
+ /**
235
+ * @typedef {{ cwd: string; env: Record<string, string>; input?: string; timeoutMs?: number; idleTimeoutMs?: number; signal?: AbortSignal; maxOutputBytes?: number; truncateKeep?: "head" | "tail"; onStdout?: (chunk: string) => void; onStderr?: (chunk: string) => void; }} RunCommandOptions
236
+ */
237
+ /** @typedef {import("./RunCommandResult.ts").RunCommandResult} RunCommandResult */
238
+ /** @typedef {import("@smithers-orchestrator/errors/SmithersError").SmithersError} SmithersError */
239
+ /**
240
+ * @param {string} command
241
+ * @param {string[]} args
242
+ * @param {RunCommandOptions} options
243
+ * @returns {Effect.Effect<RunCommandResult, SmithersError>}
244
+ */
245
+ declare function runCommandEffect(command: string, args: string[], options: RunCommandOptions): Effect.Effect<RunCommandResult$1, SmithersError>;
246
+ type RunCommandOptions = {
247
+ cwd: string;
248
+ env: Record<string, string>;
249
+ input?: string;
250
+ timeoutMs?: number;
251
+ idleTimeoutMs?: number;
252
+ signal?: AbortSignal;
253
+ maxOutputBytes?: number;
254
+ truncateKeep?: "head" | "tail";
255
+ onStdout?: (chunk: string) => void;
256
+ onStderr?: (chunk: string) => void;
257
+ };
258
+ type RunCommandResult$1 = RunCommandResult$2;
259
+ type SmithersError = _smithers_orchestrator_errors_SmithersError.SmithersError;
260
+
261
+ /**
262
+ * @param {string} command
263
+ * @param {string[]} args
264
+ * @param {RunRpcCommandOptions} options
265
+ * @returns {Effect.Effect<{ text: string; output: unknown; stderr: string; exitCode: number | null; usage?: any; }, SmithersError>}
266
+ */
267
+ declare function runRpcCommandEffect(command: string, args: string[], options: RunRpcCommandOptions): Effect.Effect<{
268
+ text: string;
269
+ output: unknown;
270
+ stderr: string;
271
+ exitCode: number | null;
272
+ usage?: any;
273
+ }, SmithersError$1>;
274
+ type PiExtensionUiResponse$1 = PiExtensionUiResponse$2;
275
+ type PiExtensionUiRequest$1 = PiExtensionUiRequest$2;
276
+ type RunRpcCommandOptions = {
277
+ cwd: string;
278
+ env: Record<string, string>;
279
+ prompt: string;
280
+ timeoutMs?: number;
281
+ idleTimeoutMs?: number;
282
+ signal?: AbortSignal;
283
+ maxOutputBytes?: number;
284
+ onStdout?: (chunk: string) => void;
285
+ onStderr?: (chunk: string) => void;
286
+ onJsonEvent?: (event: Record<string, unknown>) => Promise<void> | void;
287
+ onExtensionUiRequest?: (request: PiExtensionUiRequest$1) => Promise<PiExtensionUiResponse$1 | null> | PiExtensionUiResponse$1 | null;
288
+ spawnFn?: typeof spawn;
289
+ };
290
+
291
+ /**
292
+ * @param {string[]} args
293
+ * @param {string} flag
294
+ * @param {string | number | boolean} [value]
295
+ */
296
+ declare function pushFlag(args: string[], flag: string, value?: string | number | boolean): void;
297
+
298
+ /**
299
+ * @param {string[]} args
300
+ * @param {string} flag
301
+ * @param {string[]} [values]
302
+ */
303
+ declare function pushList(args: string[], flag: string, values?: string[]): void;
304
+
305
+ /** @typedef {import("./CodexConfigOverrides.ts").CodexConfigOverrides} CodexConfigOverrides */
306
+ /**
307
+ * @param {CodexConfigOverrides} [config]
308
+ * @returns {string[]}
309
+ */
310
+ declare function normalizeCodexConfig(config?: CodexConfigOverrides$1): string[];
311
+ type CodexConfigOverrides$1 = CodexConfigOverrides$2;
312
+
313
+ /** @typedef {import("./AgentCliEvent.ts").AgentCliEvent} AgentCliEvent */
314
+ /** @typedef {import("./AgentGenerateOptions.ts").AgentGenerateOptions} AgentGenerateOptions */
315
+ /** @typedef {import("./BaseCliAgentOptions.ts").BaseCliAgentOptions} BaseCliAgentOptions */
316
+ /** @typedef {import("./CliOutputInterpreter.ts").CliOutputInterpreter} CliOutputInterpreter */
317
+ /** @typedef {import("./CliUsageInfo.ts").CliUsageInfo} CliUsageInfo */
318
+ /** @typedef {import("ai").GenerateTextResult} GenerateTextResult */
319
+ /** @typedef {import("ai").StreamTextResult} StreamTextResult */
320
+ /** @typedef {import("ai").LanguageModelUsage} LanguageModelUsage */
321
+ /**
322
+ * @typedef {"generate" | "stream"} AgentInvocationOperation
323
+ */
324
+ /**
325
+ * @typedef {Record<string, string | undefined>} AgentInvocationTags
326
+ */
327
+ /**
328
+ * @typedef {{
329
+ * inputTokens?: number;
330
+ * outputTokens?: number;
331
+ * cacheReadTokens?: number;
332
+ * cacheWriteTokens?: number;
333
+ * reasoningTokens?: number;
334
+ * totalTokens?: number;
335
+ * }} AgentTokenTotals
336
+ */
337
+ /**
338
+ * @template A
339
+ * @param {Effect.Effect<A, SmithersError, never>} effect
340
+ * @returns {Promise<A>}
341
+ */
342
+ declare function runAgentPromise<A>(effect: Effect.Effect<A, SmithersError$1, never>): Promise<A>;
343
+ /**
344
+ * @param {string} raw
345
+ * @returns {CliUsageInfo | undefined}
346
+ */
347
+ declare function extractUsageFromOutput(raw: string): CliUsageInfo$1 | undefined;
348
+ declare class BaseCliAgent {
349
+ /**
350
+ * @param {BaseCliAgentOptions} opts
351
+ */
352
+ constructor(opts: BaseCliAgentOptions$1);
353
+ version: string;
354
+ tools: {};
355
+ capabilities: any;
356
+ id: string;
357
+ model: string | undefined;
358
+ systemPrompt: string | undefined;
359
+ cwd: string | undefined;
360
+ env: Record<string, string> | undefined;
361
+ yolo: boolean;
362
+ timeoutMs: number | undefined;
363
+ idleTimeoutMs: number | undefined;
364
+ maxOutputBytes: number | undefined;
365
+ extraArgs: string[] | undefined;
366
+ /**
367
+ * @param {AgentGenerateOptions | undefined} options
368
+ * @param {AgentInvocationOperation} operation
369
+ * @returns {Effect.Effect<GenerateTextResult<Record<string, never>, unknown>, SmithersError>}
370
+ */
371
+ runGenerateEffect(options: AgentGenerateOptions$1 | undefined, operation: AgentInvocationOperation): Effect.Effect<GenerateTextResult<Record<string, never>, unknown>, SmithersError$1>;
372
+ /**
373
+ * @param {AgentGenerateOptions} [options]
374
+ * @returns {Promise<void>}
375
+ */
376
+ preflight(options?: AgentGenerateOptions$1): Promise<void>;
377
+ /**
378
+ * @param {AgentGenerateOptions} [options]
379
+ * @returns {Promise<GenerateTextResult<Record<string, never>, unknown>>}
380
+ */
381
+ generate(options?: AgentGenerateOptions$1): Promise<GenerateTextResult<Record<string, never>, unknown>>;
382
+ /**
383
+ * @param {AgentGenerateOptions} [options]
384
+ * @returns {Promise<StreamTextResult<Record<string, never>, unknown>>}
385
+ */
386
+ stream(options?: AgentGenerateOptions$1): Promise<StreamTextResult<Record<string, never>, unknown>>;
387
+ /**
388
+ * @returns {CliOutputInterpreter | undefined}
389
+ */
390
+ createOutputInterpreter(): CliOutputInterpreter$1 | undefined;
391
+ /**
392
+ * @returns {{ provider?: string; model?: string } | undefined}
393
+ */
394
+ diagnosticHints(): {
395
+ provider?: string;
396
+ model?: string;
397
+ } | undefined;
398
+ }
399
+ type AgentGenerateOptions$1 = AgentGenerateOptions$2;
400
+ type BaseCliAgentOptions$1 = BaseCliAgentOptions$2;
401
+ type CliOutputInterpreter$1 = CliOutputInterpreter$2;
402
+ type CliUsageInfo$1 = CliUsageInfo$2;
403
+ type GenerateTextResult = ai.GenerateTextResult<any, any>;
404
+ type StreamTextResult = ai.StreamTextResult<any, any>;
405
+ type AgentInvocationOperation = "generate" | "stream";
406
+
407
+ /** @typedef {import("./AgentCliActionKind.ts").AgentCliActionKind} AgentCliActionKind */
408
+ /**
409
+ * @param {unknown} value
410
+ * @returns {value is Record<string, unknown>}
411
+ */
412
+ declare function isRecord(value: unknown): value is Record<string, unknown>;
413
+ /**
414
+ * @param {unknown} value
415
+ * @returns {string | undefined}
416
+ */
417
+ declare function asString(value: unknown): string | undefined;
418
+ /**
419
+ * @param {unknown} value
420
+ * @returns {number | undefined}
421
+ */
422
+ declare function asNumber(value: unknown): number | undefined;
423
+ /**
424
+ * @param {string} value
425
+ * @returns {string}
426
+ */
427
+ declare function truncate(value: string, maxLength?: number): string;
428
+ /**
429
+ * @param {string | undefined} name
430
+ * @param {ReadonlyArray<readonly [string[], AgentCliActionKind]>} [extraRules]
431
+ * @returns {AgentCliActionKind}
432
+ */
433
+ declare function toolKindFromName(name: string | undefined, extraRules?: ReadonlyArray<readonly [string[], AgentCliActionKind$1]>): AgentCliActionKind$1;
434
+ /**
435
+ * @param {string} value
436
+ * @returns {boolean}
437
+ */
438
+ declare function isLikelyRuntimeMetadata(value: string): boolean;
439
+ /**
440
+ * @param {string} line
441
+ * @returns {boolean}
442
+ */
443
+ declare function shouldSurfaceUnparsedStdout(line: string): boolean;
444
+ /**
445
+ * @returns {(prefix: string) => string}
446
+ */
447
+ declare function createSyntheticIdGenerator(): (prefix: string) => string;
448
+ type AgentCliActionKind$1 = AgentCliActionKind$2;
449
+
450
+ type AgentCliActionEvent = AgentCliActionEvent$1;
451
+ type AgentCliActionKind = AgentCliActionKind$2;
452
+ type AgentCliActionPhase = AgentCliActionPhase$1;
453
+ type AgentCliCompletedEvent = AgentCliCompletedEvent$1;
454
+ type AgentCliEvent = AgentCliEvent$1;
455
+ type AgentCliEventLevel = AgentCliEventLevel$1;
456
+ type AgentCliStartedEvent = AgentCliStartedEvent$1;
457
+ type AgentGenerateOptions = AgentGenerateOptions$2;
458
+ type BaseCliAgentOptions = BaseCliAgentOptions$2;
459
+ type CliOutputInterpreter = CliOutputInterpreter$2;
460
+ type CliUsageInfo = CliUsageInfo$2;
461
+ type NormalizedTokenUsage = NormalizedTokenUsage$2;
462
+ type CodexConfigOverrides = CodexConfigOverrides$2;
463
+ type PiExtensionUiRequest = PiExtensionUiRequest$2;
464
+ type PiExtensionUiResponse = PiExtensionUiResponse$2;
465
+ type RunCommandResult = RunCommandResult$2;
466
+
467
+ export { type AgentCliActionEvent, type AgentCliActionKind, type AgentCliActionPhase, type AgentCliCompletedEvent, type AgentCliEvent, type AgentCliEventLevel, type AgentCliStartedEvent, type AgentGenerateOptions, BaseCliAgent, type BaseCliAgentOptions, type CliOutputInterpreter, type CliUsageInfo, type CodexConfigOverrides, type NormalizedTokenUsage, type PiExtensionUiRequest, type PiExtensionUiResponse, type RunCommandResult, asNumber, asString, buildGenerateResult, combineNonEmpty, createAgentStdoutTextEmitter, createSyntheticIdGenerator, extractPrompt, extractTextFromJsonValue, extractUsageFromOutput, isLikelyRuntimeMetadata, isRecord, normalizeCodexConfig, normalizeTokenUsage, pushFlag, pushList, resolveTimeouts, runAgentPromise, runCommandEffect, runRpcCommandEffect, shouldSurfaceUnparsedStdout, toolKindFromName, truncate, truncateToBytes, tryParseJson };
@@ -56,6 +56,7 @@ export function createClaudeCodeCapabilityRegistry(opts = {}) {
56
56
  };
57
57
  }
58
58
  const TOOL_OUTPUT_MAX_CHARS = 500;
59
+ let didWarnAnthropicApiKeyUnset = false;
59
60
  /**
60
61
  * @param {string} toolName
61
62
  * @param {string | undefined} rawOutput
@@ -105,8 +106,11 @@ export class ClaudeCodeAgent extends BaseCliAgent {
105
106
  if (process.env.CLAUDECODE)
106
107
  parentEnvOverrides.CLAUDECODE = "";
107
108
  if (process.env.ANTHROPIC_API_KEY && !opts.apiKey) {
108
- logWarning("ClaudeCodeAgent: unsetting ANTHROPIC_API_KEY so Claude Code uses your subscription. " +
109
- "To use API billing instead, pass `apiKey` to ClaudeCodeAgent or use ToolLoopAgent from 'ai' with anthropic() provider.", {}, "agent.init");
109
+ if (!didWarnAnthropicApiKeyUnset) {
110
+ didWarnAnthropicApiKeyUnset = true;
111
+ logWarning("ClaudeCodeAgent: unsetting ANTHROPIC_API_KEY so Claude Code uses your subscription. " +
112
+ "To use API billing instead, pass `apiKey` to ClaudeCodeAgent or use ToolLoopAgent from 'ai' with anthropic() provider.", {}, "agent.init");
113
+ }
110
114
  parentEnvOverrides.ANTHROPIC_API_KEY = "";
111
115
  }
112
116
  if (Object.keys(parentEnvOverrides).length > 0) {
package/src/CodexAgent.js CHANGED
@@ -4,6 +4,7 @@ import { join } from "node:path";
4
4
  import { randomUUID } from "node:crypto";
5
5
  import { BaseCliAgent, normalizeCodexConfig, pushFlag, pushList, isRecord, asString, asNumber, truncate, shouldSurfaceUnparsedStdout, createSyntheticIdGenerator, } from "./BaseCliAgent/index.js";
6
6
  import { normalizeCapabilityStringList, } from "./capability-registry/index.js";
7
+ import { assertZodV4 } from "@smithers-orchestrator/errors/assertZodV4";
7
8
  import { sanitizeForOpenAI } from "./sanitizeForOpenAI.js";
8
9
  /** @typedef {import("./BaseCliAgent/BaseCliAgentOptions.ts").BaseCliAgentOptions} BaseCliAgentOptions */
9
10
  /** @typedef {import("./BaseCliAgent/CodexConfigOverrides.ts").CodexConfigOverrides} CodexConfigOverrides */
@@ -564,6 +565,9 @@ export class CodexAgent extends BaseCliAgent {
564
565
  let schemaCleanupFile = null;
565
566
  if (!resumeSession && this.opts.nativeStructuredOutput === true && !this.opts.outputSchema && params.options?.outputSchema) {
566
567
  const schema = params.options.outputSchema;
568
+ // z.toJSONSchema() reads Zod v4 internals; a v3 schema throws a cryptic
569
+ // `schema._zod.def` TypeError. Surface a clear, actionable error instead.
570
+ assertZodV4(schema);
567
571
  const { z } = await import("zod");
568
572
  let jsonSchema = z.toJSONSchema(schema);
569
573
  // Sanitize for OpenAI structured output compatibility