@smithers-orchestrator/agents 0.24.0 → 0.25.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.
- package/package.json +15 -5
- package/src/AgentLike.ts +5 -0
- package/src/AmpAgent.js +15 -5
- package/src/AmpAgentOptions.ts +6 -0
- package/src/BaseCliAgent/BaseCliAgent.js +205 -11
- package/src/BaseCliAgent/createAgentStdoutTextEmitter.js +21 -3
- package/src/BaseCliAgent/index.d.ts +467 -0
- package/src/ClaudeCodeAgent.js +6 -2
- package/src/CodexAgent.js +17 -2
- package/src/CodexAgentOptions.ts +11 -0
- package/src/GeminiAgent.js +34 -224
- package/src/GeminiAgentOptions.ts +4 -9
- package/src/OpenCodeAgent.js +2 -12
- package/src/OpenCodeAgentOptions.ts +19 -0
- package/src/PiAgent.js +63 -5
- package/src/cli-capabilities/CliAgentCapabilityAdapterId.ts +0 -1
- package/src/cli-capabilities/getCliAgentCapabilityDoctorReport.js +3 -2
- package/src/cli-capabilities/getCliAgentCapabilityReport.js +0 -6
- package/src/cli-surface/cliAgentSurfaceManifest.js +1 -40
- package/src/createElevenLabsTextToSpeechTool.js +128 -0
- package/src/createElevenLabsTextToSpeechTool.ts +33 -0
- package/src/diagnostics/getDiagnosticStrategy.js +94 -23
- package/src/diagnostics/launchDiagnostics.js +7 -4
- package/src/document-parsing/DocumentParsingProvider.ts +13 -0
- package/src/document-parsing/DocumentParsingResult.ts +13 -0
- package/src/document-parsing/DocumentParsingToolset.ts +4 -0
- package/src/document-parsing/DocumentParsingToolsetOptions.ts +9 -0
- package/src/document-parsing/createDocumentParsingToolset.d.ts +9 -0
- package/src/document-parsing/createDocumentParsingToolset.js +416 -0
- package/src/http/CreateHttpToolOptions.ts +4 -0
- package/src/http/HttpToolAuth.ts +15 -0
- package/src/http/HttpToolInput.ts +11 -0
- package/src/http/HttpToolOutput.ts +7 -0
- package/src/http/createHttpTool.js +136 -0
- package/src/image-generation/ImageGenerationProvider.ts +7 -0
- package/src/image-generation/ImageGenerationRequest.ts +8 -0
- package/src/image-generation/ImageGenerationResult.ts +10 -0
- package/src/image-generation/ImageGenerationToolOptions.ts +10 -0
- package/src/image-generation/createImageGenerationTool.d.ts +18 -0
- package/src/image-generation/createImageGenerationTool.js +92 -0
- package/src/index.d.ts +490 -147
- package/src/index.js +23 -5
- package/src/streamResultToGenerateResult.js +55 -26
- package/src/transcription/createTranscriptionTool.js +182 -0
- package/src/transcription/createTranscriptionTool.ts +29 -0
- package/src/transcription/index.js +1 -0
- package/src/transcription/index.ts +6 -0
- package/src/web-search/GroundedWebSearchProvider.ts +21 -0
- package/src/web-search/GroundedWebSearchToolset.ts +6 -0
- package/src/web-search/createBraveSearchProvider.js +53 -0
- package/src/web-search/createExaSearchProvider.js +72 -0
- package/src/web-search/createGroundedWebSearchToolset.js +110 -0
- package/src/web-search/createSerperSearchProvider.js +63 -0
- package/src/web-search/createTavilySearchProvider.js +59 -0
- package/src/web-search/index.js +5 -0
- package/src/zodToOpenAISchema.js +4 -0
- 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 };
|
package/src/ClaudeCodeAgent.js
CHANGED
|
@@ -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
|
-
|
|
109
|
-
|
|
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 */
|
|
@@ -59,6 +60,15 @@ export class CodexAgent extends BaseCliAgent {
|
|
|
59
60
|
super(opts);
|
|
60
61
|
this.opts = opts;
|
|
61
62
|
this.capabilities = createCodexCapabilityRegistry(opts);
|
|
63
|
+
// Native structured output (`codex exec --output-schema`) constrains the
|
|
64
|
+
// model to emit only final JSON and makes it refuse tool calls ("tool calls
|
|
65
|
+
// are constrained by a JSON response schema"), which breaks any agentic task
|
|
66
|
+
// (read/edit/run). It is therefore OPT-IN: by default Codex is treated like
|
|
67
|
+
// the other CLI engines (supportsNativeStructuredOutput=false), so the engine
|
|
68
|
+
// prompt-injects the schema and extracts JSON from the agent's final text,
|
|
69
|
+
// leaving tool use intact. Set nativeStructuredOutput:true for pure, tool-free
|
|
70
|
+
// extraction tasks that want strict schema enforcement.
|
|
71
|
+
this.supportsNativeStructuredOutput = opts.nativeStructuredOutput === true;
|
|
62
72
|
}
|
|
63
73
|
/**
|
|
64
74
|
* @returns {CliOutputInterpreter}
|
|
@@ -548,11 +558,16 @@ export class CodexAgent extends BaseCliAgent {
|
|
|
548
558
|
// turn.completed with token usage for metrics. extractUsageFromOutput
|
|
549
559
|
// in BaseCliAgent will parse these automatically.
|
|
550
560
|
args.push("--json");
|
|
551
|
-
// Auto-wire output schema from task context if not explicitly set
|
|
561
|
+
// Auto-wire output schema from task context if not explicitly set — only when
|
|
562
|
+
// native structured output is opted in. Otherwise the engine handles the schema
|
|
563
|
+
// via prompt-injection and Codex keeps full tool access (see constructor note).
|
|
552
564
|
// Skip when resuming — `codex exec resume` does not accept --output-schema.
|
|
553
565
|
let schemaCleanupFile = null;
|
|
554
|
-
if (!resumeSession && !this.opts.outputSchema && params.options?.outputSchema) {
|
|
566
|
+
if (!resumeSession && this.opts.nativeStructuredOutput === true && !this.opts.outputSchema && params.options?.outputSchema) {
|
|
555
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);
|
|
556
571
|
const { z } = await import("zod");
|
|
557
572
|
let jsonSchema = z.toJSONSchema(schema);
|
|
558
573
|
// Sanitize for OpenAI structured output compatibility
|
package/src/CodexAgentOptions.ts
CHANGED
|
@@ -17,6 +17,17 @@ export type CodexAgentOptions = BaseCliAgentOptions & {
|
|
|
17
17
|
skipGitRepoCheck?: boolean;
|
|
18
18
|
addDir?: string[];
|
|
19
19
|
outputSchema?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Opt in to Codex's native structured output (`codex exec --output-schema`).
|
|
22
|
+
*
|
|
23
|
+
* Defaults to `false`. Native structured output makes the model emit only the
|
|
24
|
+
* final JSON and refuse tool calls, so it BREAKS agentic tasks (read/edit/run) —
|
|
25
|
+
* Codex returns `blocked` with no changes. Left off, Smithers treats Codex like
|
|
26
|
+
* the other CLI engines: it prompt-injects the schema and extracts JSON from the
|
|
27
|
+
* agent's final message, so tool use stays intact. Enable only for pure, tool-free
|
|
28
|
+
* extraction tasks that need strict schema enforcement.
|
|
29
|
+
*/
|
|
30
|
+
nativeStructuredOutput?: boolean;
|
|
20
31
|
color?: "always" | "never" | "auto";
|
|
21
32
|
json?: boolean;
|
|
22
33
|
outputLastMessage?: string;
|