coding-agents-sdk 0.0.1 → 0.2.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 (41) hide show
  1. package/README.md +242 -0
  2. package/dist/Agent-D8WkUilj.mjs +262 -0
  3. package/dist/SdkAgent-B47mJiIE.mjs +38 -0
  4. package/dist/adapters/claude-code-cli/index.d.mts +2 -0
  5. package/dist/adapters/claude-code-cli/index.mjs +490 -0
  6. package/dist/adapters/claude-code-sdk/index.d.mts +2 -0
  7. package/dist/adapters/claude-code-sdk/index.mjs +483 -0
  8. package/dist/adapters/codex-cli/index.d.mts +2 -0
  9. package/dist/adapters/codex-cli/index.mjs +626 -0
  10. package/dist/adapters/codex-sdk/index.d.mts +2 -0
  11. package/dist/adapters/codex-sdk/index.mjs +286 -0
  12. package/dist/adapters/gemini-cli/index.d.mts +2 -0
  13. package/dist/adapters/gemini-cli/index.mjs +292 -0
  14. package/dist/classify-error-pL6jeu4T.mjs +456 -0
  15. package/dist/container/index.d.mts +2 -0
  16. package/dist/container/index.mjs +24 -0
  17. package/dist/container-2UmPZ0CI.mjs +22 -0
  18. package/dist/container-CHxKIonn.mjs +440 -0
  19. package/dist/container-D2Z0ITDJ.mjs +22 -0
  20. package/dist/diff-De8d3MVb.mjs +333 -0
  21. package/dist/errors-BAmHDQu8.mjs +45 -0
  22. package/dist/events-nxuRbYIu.d.mts +239 -0
  23. package/dist/index-B3YqrgIp.d.mts +45 -0
  24. package/dist/index-ByAOGMUM.d.mts +224 -0
  25. package/dist/index-C3ZxLAd0.d.mts +315 -0
  26. package/dist/index-CFpNOmdA.d.mts +145 -0
  27. package/dist/index-dRVpEAr8.d.mts +39 -0
  28. package/dist/index-nzo1sBiK.d.mts +110 -0
  29. package/dist/index.d.mts +16 -0
  30. package/dist/index.mjs +61 -0
  31. package/dist/oci-DMZZQZ47.mjs +438 -0
  32. package/dist/schemas/index.d.mts +2 -0
  33. package/dist/schemas/index.mjs +2 -0
  34. package/dist/schemas-DwD4pwJB.mjs +96 -0
  35. package/dist/spawner-Bw9UBEGX.mjs +54 -0
  36. package/dist/structured-output-BHtr_zpz.mjs +19 -0
  37. package/dist/types-Cb_EXIEe.d.mts +177 -0
  38. package/dist/types-aNMD8h3x.mjs +19 -0
  39. package/dist/util-B4RQZkKr.mjs +77 -0
  40. package/package.json +86 -9
  41. package/index.js +0 -7
@@ -0,0 +1,286 @@
1
+ import { r as parseJsonResponseText } from "../../util-B4RQZkKr.mjs";
2
+ import { a as buildBaseProcessEnv, l as toTextPart, o as createAgentEvent, r as applyMappedEventBatch } from "../../classify-error-pL6jeu4T.mjs";
3
+ import { t as SdkAgent } from "../../SdkAgent-B47mJiIE.mjs";
4
+ import { Codex } from "@openai/codex-sdk";
5
+ //#region src/adapters/codex-sdk/events/mappers.ts
6
+ const toStats = (usage) => ({
7
+ turns: 1,
8
+ costUsd: 0,
9
+ inputTokens: usage.input_tokens,
10
+ cacheReadInputTokens: usage.cached_input_tokens,
11
+ outputTokens: usage.output_tokens,
12
+ totalTokens: usage.input_tokens + usage.cached_input_tokens + usage.output_tokens
13
+ });
14
+ const getCommandToolRecord = (item) => ({
15
+ toolCallId: item.id,
16
+ toolName: "Bash",
17
+ input: { command: item.command }
18
+ });
19
+ const getMcpToolRecord = (item) => ({
20
+ toolCallId: item.id,
21
+ toolName: item.tool,
22
+ input: {
23
+ server: item.server,
24
+ arguments: item.arguments
25
+ }
26
+ });
27
+ const getWebSearchToolRecord = (item) => ({
28
+ toolCallId: item.id,
29
+ toolName: "WebSearch",
30
+ input: { query: item.query }
31
+ });
32
+ const mapToolCallStart = (toolRecord, context, options) => ({
33
+ events: [createAgentEvent(context.runId, "tool-call", {
34
+ sessionId: context.sessionId,
35
+ model: options.model ?? null,
36
+ toolCallId: toolRecord.toolCallId,
37
+ toolName: toolRecord.toolName,
38
+ input: toolRecord.input
39
+ })],
40
+ toolCalls: [{
41
+ toolCallId: toolRecord.toolCallId,
42
+ toolName: toolRecord.toolName,
43
+ input: toolRecord.input
44
+ }]
45
+ });
46
+ const mapToolResultCompletion = (toolRecord, output, errorState, context, options) => {
47
+ const priorToolCall = context.toolCalls.get(toolRecord.toolCallId);
48
+ const resolvedTool = priorToolCall ?? toolRecord;
49
+ const events = [];
50
+ const toolCalls = [];
51
+ if (!priorToolCall) {
52
+ events.push(createAgentEvent(context.runId, "tool-call", {
53
+ sessionId: context.sessionId,
54
+ model: options.model ?? null,
55
+ toolCallId: toolRecord.toolCallId,
56
+ toolName: toolRecord.toolName,
57
+ input: toolRecord.input
58
+ }));
59
+ toolCalls.push({
60
+ toolCallId: toolRecord.toolCallId,
61
+ toolName: toolRecord.toolName,
62
+ input: toolRecord.input
63
+ });
64
+ }
65
+ events.push(createAgentEvent(context.runId, "tool-result", {
66
+ sessionId: context.sessionId,
67
+ toolCallId: toolRecord.toolCallId,
68
+ toolName: resolvedTool.toolName,
69
+ input: resolvedTool.input,
70
+ output,
71
+ isError: errorState.isError || void 0,
72
+ error: errorState.error
73
+ }));
74
+ return {
75
+ events,
76
+ toolCalls: toolCalls.length > 0 ? toolCalls : void 0
77
+ };
78
+ };
79
+ const getCommandErrorState = (item) => {
80
+ const isError = item.status === "failed" || item.exit_code !== void 0 && item.exit_code !== 0;
81
+ return {
82
+ isError,
83
+ error: isError ? `Command exited with code ${item.exit_code ?? 1}.` : void 0
84
+ };
85
+ };
86
+ const getMcpOutput = (item) => item.result?.structured_content ?? item.result?.content ?? item.error?.message ?? "";
87
+ const getMcpErrorState = (item) => ({
88
+ isError: item.status === "failed" || item.error !== void 0,
89
+ error: item.error?.message
90
+ });
91
+ const mapErrorItem = (item, context) => ({
92
+ events: [createAgentEvent(context.runId, "stderr", {
93
+ sessionId: context.sessionId,
94
+ text: item.message
95
+ })],
96
+ state: { error: {
97
+ kind: "provider",
98
+ message: item.message
99
+ } }
100
+ });
101
+ const mapItemStartedEvent = (event, context, options) => {
102
+ switch (event.item.type) {
103
+ case "command_execution": return mapToolCallStart(getCommandToolRecord(event.item), context, options);
104
+ case "mcp_tool_call": return mapToolCallStart(getMcpToolRecord(event.item), context, options);
105
+ case "web_search": return mapToolCallStart(getWebSearchToolRecord(event.item), context, options);
106
+ default: return { events: [] };
107
+ }
108
+ };
109
+ const mapItemCompletedEvent = (event, context, options) => {
110
+ switch (event.item.type) {
111
+ case "agent_message": return {
112
+ events: [createAgentEvent(context.runId, "message", {
113
+ sessionId: context.sessionId,
114
+ model: options.model ?? null,
115
+ role: "assistant",
116
+ content: [toTextPart(event.item.text)],
117
+ text: event.item.text
118
+ })],
119
+ state: { output: { text: event.item.text } }
120
+ };
121
+ case "reasoning": return { events: [createAgentEvent(context.runId, "reasoning", {
122
+ sessionId: context.sessionId,
123
+ model: options.model ?? null,
124
+ content: [toTextPart(event.item.text)],
125
+ text: event.item.text
126
+ })] };
127
+ case "command_execution": return mapToolResultCompletion(getCommandToolRecord(event.item), event.item.aggregated_output, getCommandErrorState(event.item), context, options);
128
+ case "mcp_tool_call": return mapToolResultCompletion(getMcpToolRecord(event.item), getMcpOutput(event.item), getMcpErrorState(event.item), context, options);
129
+ case "web_search": return mapToolResultCompletion(getWebSearchToolRecord(event.item), "", { isError: false }, context, options);
130
+ case "error": return mapErrorItem(event.item, context);
131
+ default: return { events: [] };
132
+ }
133
+ };
134
+ const mapCodexSdkEvent = (event, context, options = {}) => {
135
+ switch (event.type) {
136
+ case "thread.started": return {
137
+ events: [],
138
+ sessionId: event.thread_id
139
+ };
140
+ case "turn.started": return { events: [] };
141
+ case "turn.completed": return {
142
+ events: [],
143
+ state: {
144
+ stats: toStats(event.usage),
145
+ status: "completed",
146
+ error: void 0
147
+ }
148
+ };
149
+ case "turn.failed": return {
150
+ events: [],
151
+ state: {
152
+ status: "failed",
153
+ error: {
154
+ kind: "provider",
155
+ message: event.error.message
156
+ }
157
+ }
158
+ };
159
+ case "item.started": return mapItemStartedEvent(event, context, options);
160
+ case "item.updated": return { events: [] };
161
+ case "item.completed": return mapItemCompletedEvent(event, context, options);
162
+ case "error": return {
163
+ events: [],
164
+ state: {
165
+ status: "failed",
166
+ error: {
167
+ kind: "provider",
168
+ message: event.message
169
+ }
170
+ }
171
+ };
172
+ default: return { events: [] };
173
+ }
174
+ };
175
+ //#endregion
176
+ //#region src/adapters/codex-sdk/adapter.ts
177
+ const CODEX_SDK_CAPABILITIES = {
178
+ structuredOutput: true,
179
+ sessionResume: true,
180
+ imageInput: true,
181
+ mcp: true,
182
+ eventStreaming: true
183
+ };
184
+ const toCodexInput = (input) => {
185
+ return input.length === 1 && input[0]?.type === "text" ? input[0].text : input.map((part) => part.type === "text" ? {
186
+ type: "text",
187
+ text: part.text
188
+ } : {
189
+ type: "local_image",
190
+ path: part.path
191
+ });
192
+ };
193
+ const buildTurnOptions = (run, signal) => ({
194
+ outputSchema: run.normalizedRequest.schema.kind === "none" ? void 0 : run.normalizedRequest.schema.jsonSchema,
195
+ signal
196
+ });
197
+ var CodexSdkAgentImpl = class extends SdkAgent {
198
+ type = "codex-sdk";
199
+ defaults;
200
+ runDefaults;
201
+ command;
202
+ codex;
203
+ resolvedEnv;
204
+ constructor(options = {}) {
205
+ super({
206
+ type: "codex-sdk",
207
+ capabilities: CODEX_SDK_CAPABILITIES,
208
+ sessionId: options.sessionId,
209
+ onEvent: options.onEvent
210
+ });
211
+ this.command = options.command;
212
+ this.defaults = {
213
+ cwd: options.cwd,
214
+ model: options.model
215
+ };
216
+ this.runDefaults = {
217
+ permissionMode: options.permissionMode,
218
+ sandboxMode: options.sandboxMode,
219
+ skipGitRepoCheck: options.skipGitRepoCheck,
220
+ modelReasoningEffort: options.modelReasoningEffort,
221
+ networkAccessEnabled: options.networkAccessEnabled,
222
+ webSearchMode: options.webSearchMode,
223
+ webSearchEnabled: options.webSearchEnabled,
224
+ additionalDirectories: options.additionalDirectories ? [...options.additionalDirectories] : void 0
225
+ };
226
+ const env = buildBaseProcessEnv({ propagateEnv: options.propagateEnv });
227
+ if (options.env) Object.assign(env, options.env);
228
+ this.resolvedEnv = env;
229
+ this.codex = options.codex ?? new Codex({
230
+ codexPathOverride: this.command,
231
+ baseUrl: options.baseUrl,
232
+ apiKey: options.apiKey,
233
+ config: options.config,
234
+ env
235
+ });
236
+ }
237
+ getResolvedEnvForTesting() {
238
+ return this.resolvedEnv;
239
+ }
240
+ get runRequestDefaults() {
241
+ return this.defaults;
242
+ }
243
+ async executeSdkRun(run, request, abortController) {
244
+ const threadOptions = this.buildThreadOptions(request, run);
245
+ const thread = run.requestedSessionId ? this.codex.resumeThread(run.requestedSessionId, threadOptions) : this.codex.startThread(threadOptions);
246
+ if (!run.sessionId && thread.id) {
247
+ run.sessionId = thread.id;
248
+ this.setSessionId(thread.id);
249
+ }
250
+ if (run.stopReason) return;
251
+ const streamed = await thread.runStreamed(toCodexInput(run.normalizedRequest.input), buildTurnOptions(run, abortController.signal));
252
+ for await (const event of streamed.events) {
253
+ const batch = mapCodexSdkEvent(event, {
254
+ runId: run.runId,
255
+ requestedSessionId: run.requestedSessionId,
256
+ sessionId: run.sessionId,
257
+ schemaRequested: run.normalizedRequest.schema.kind !== "none",
258
+ toolCalls: run.toolCalls
259
+ }, { model: run.normalizedRequest.model });
260
+ this.applyBatch(run, batch);
261
+ }
262
+ if (run.normalizedRequest.schema.kind !== "none" && run.output.value === void 0 && run.error === void 0 && run.status !== "failed" && run.output.text) try {
263
+ applyMappedEventBatch(run, {
264
+ events: [],
265
+ state: { output: { value: parseJsonResponseText(run.output.text) } }
266
+ });
267
+ } catch {}
268
+ }
269
+ buildThreadOptions(request, run) {
270
+ return {
271
+ model: run.normalizedRequest.model,
272
+ workingDirectory: run.normalizedRequest.cwd,
273
+ approvalPolicy: request.permissionMode ?? this.runDefaults.permissionMode,
274
+ sandboxMode: request.sandboxMode ?? this.runDefaults.sandboxMode,
275
+ skipGitRepoCheck: request.skipGitRepoCheck ?? this.runDefaults.skipGitRepoCheck,
276
+ modelReasoningEffort: request.modelReasoningEffort ?? this.runDefaults.modelReasoningEffort,
277
+ networkAccessEnabled: request.networkAccessEnabled ?? this.runDefaults.networkAccessEnabled,
278
+ webSearchMode: request.webSearchMode ?? this.runDefaults.webSearchMode,
279
+ webSearchEnabled: request.webSearchEnabled ?? this.runDefaults.webSearchEnabled,
280
+ additionalDirectories: request.additionalDirectories ?? this.runDefaults.additionalDirectories
281
+ };
282
+ }
283
+ };
284
+ const createCodexSdkAgent = (options) => new CodexSdkAgentImpl(options);
285
+ //#endregion
286
+ export { createCodexSdkAgent };
@@ -0,0 +1,2 @@
1
+ import { a as GeminiCliRunOptions, i as GeminiCliPermissionMode, n as GeminiCliAgent, o as GeminiEvent, r as GeminiCliAgentOptions, t as createGeminiCliAgent } from "../../index-dRVpEAr8.mjs";
2
+ export { GeminiCliAgent, GeminiCliAgentOptions, GeminiCliPermissionMode, GeminiCliRunOptions, GeminiEvent, createGeminiCliAgent };
@@ -0,0 +1,292 @@
1
+ import { a as toArray, n as isRecord } from "../../util-B4RQZkKr.mjs";
2
+ import { c as getInputText, l as toTextPart, o as createAgentEvent, s as createEventParser } from "../../classify-error-pL6jeu4T.mjs";
3
+ import { t as Agent } from "../../Agent-D8WkUilj.mjs";
4
+ import { z } from "zod/v4";
5
+ //#region src/adapters/gemini-cli/events/mappers.ts
6
+ const asString = (value) => typeof value === "string" ? value : void 0;
7
+ const asNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : void 0;
8
+ const extractText = (value) => {
9
+ if (typeof value === "string") return value;
10
+ if (Array.isArray(value)) return value.map(extractText).join("");
11
+ if (isRecord(value)) {
12
+ const text = asString(value.text);
13
+ if (text) return text;
14
+ const parts = value.parts ?? value.content;
15
+ if (Array.isArray(parts)) return parts.map(extractText).join("");
16
+ }
17
+ return "";
18
+ };
19
+ const stringifyValue = (value) => {
20
+ if (typeof value === "string") return value;
21
+ if (value === null || value === void 0) return "";
22
+ try {
23
+ return JSON.stringify(value);
24
+ } catch {
25
+ return String(value);
26
+ }
27
+ };
28
+ const nextId = () => crypto.randomUUID();
29
+ const getGeminiSessionId = (event) => {
30
+ const raw = event;
31
+ const sessionId = asString(raw.session_id) ?? asString(raw.sessionId);
32
+ if (sessionId) return sessionId;
33
+ if (isRecord(raw.message)) return asString(raw.message.session_id) ?? asString(raw.message.sessionId);
34
+ };
35
+ const mapInitEvent = (_raw, context) => {
36
+ const text = "[init]";
37
+ return { events: [createAgentEvent(context.runId, "message", {
38
+ sessionId: context.sessionId,
39
+ model: null,
40
+ role: "system",
41
+ content: [toTextPart(text)],
42
+ text
43
+ })] };
44
+ };
45
+ const mapMessageEvent = (raw, context, options) => {
46
+ const payload = isRecord(raw.message) ? raw.message : raw;
47
+ const role = asString(payload.role) ?? asString(raw.role) ?? "assistant";
48
+ const model = asString(payload.model) ?? asString(raw.model) ?? options.model ?? null;
49
+ const text = extractText(payload.content ?? payload.parts ?? payload.text ?? raw.content ?? raw.text);
50
+ if (!text?.trim()) return { events: [] };
51
+ if (role === "assistant") return { events: [createAgentEvent(context.runId, "message", {
52
+ sessionId: context.sessionId,
53
+ model,
54
+ role: "assistant",
55
+ content: [toTextPart(text)],
56
+ text
57
+ })] };
58
+ return { events: [createAgentEvent(context.runId, "message", {
59
+ sessionId: context.sessionId,
60
+ model: null,
61
+ role: "user",
62
+ content: [toTextPart(text)],
63
+ text
64
+ })] };
65
+ };
66
+ const mapThoughtEvent = (raw, context, options) => {
67
+ const text = asString(raw.thought) ?? asString(raw.text) ?? asString(raw.content) ?? "";
68
+ if (!text.trim()) return { events: [] };
69
+ return { events: [createAgentEvent(context.runId, "reasoning", {
70
+ sessionId: context.sessionId,
71
+ model: options.model ?? null,
72
+ content: [toTextPart(text)],
73
+ text
74
+ })] };
75
+ };
76
+ const mapToolUseEvent = (raw, context, options) => {
77
+ const toolCallId = asString(raw.tool_id) ?? asString(raw.id) ?? nextId();
78
+ const toolName = asString(raw.tool_name) ?? asString(raw.name) ?? "tool";
79
+ const input = (isRecord(raw.parameters) ? raw.parameters : void 0) ?? (isRecord(raw.args) ? raw.args : void 0) ?? (isRecord(raw.input) ? raw.input : void 0) ?? {};
80
+ return {
81
+ events: [createAgentEvent(context.runId, "tool-call", {
82
+ sessionId: context.sessionId,
83
+ model: options.model ?? null,
84
+ toolCallId,
85
+ toolName,
86
+ input
87
+ })],
88
+ toolCalls: [{
89
+ toolCallId,
90
+ toolName,
91
+ input
92
+ }]
93
+ };
94
+ };
95
+ const mapToolResultEvent = (raw, context) => {
96
+ const toolCallId = asString(raw.tool_id) ?? asString(raw.tool_use_id) ?? asString(raw.id) ?? nextId();
97
+ const status = asString(raw.status);
98
+ const isError = status ? status !== "success" : Boolean(raw.error);
99
+ const output = raw.output ?? raw.result ?? raw.content ?? raw.message ?? (typeof raw.error === "string" ? raw.error : void 0);
100
+ const outputStr = stringifyValue(output);
101
+ const tool = context.toolCalls.get(toolCallId);
102
+ return { events: [createAgentEvent(context.runId, "tool-result", {
103
+ sessionId: context.sessionId,
104
+ toolCallId,
105
+ toolName: tool?.toolName,
106
+ input: tool?.input,
107
+ output: outputStr,
108
+ isError: isError || void 0,
109
+ error: isError ? stringifyValue(raw.error ?? output) : void 0
110
+ })] };
111
+ };
112
+ const extractUsage = (raw) => {
113
+ const tokenCount = (isRecord(raw.token_count) ? raw.token_count : void 0) ?? (isRecord(raw.tokenCount) ? raw.tokenCount : void 0) ?? (isRecord(raw.usage) ? raw.usage : void 0) ?? (isRecord(raw.usage_metadata) ? raw.usage_metadata : void 0) ?? (isRecord(raw.usageMetadata) ? raw.usageMetadata : void 0) ?? (isRecord(raw.stats) ? raw.stats : void 0);
114
+ if (!tokenCount) return void 0;
115
+ const inputTokens = asNumber(tokenCount.prompt_tokens) ?? asNumber(tokenCount.promptTokens) ?? asNumber(tokenCount.input_tokens) ?? asNumber(tokenCount.inputTokens) ?? asNumber(tokenCount.prompt_token_count);
116
+ const outputTokens = asNumber(tokenCount.completion_tokens) ?? asNumber(tokenCount.output_tokens) ?? asNumber(tokenCount.outputTokens) ?? asNumber(tokenCount.candidates_token_count) ?? asNumber(tokenCount.completion_token_count);
117
+ if (inputTokens === void 0 && outputTokens === void 0) return void 0;
118
+ return {
119
+ inputTokens: inputTokens ?? 0,
120
+ outputTokens: outputTokens ?? 0
121
+ };
122
+ };
123
+ const mapResultEvent = (raw, context) => {
124
+ const status = asString(raw.status) ?? asString(raw.subtype) ?? "success";
125
+ const isError = status !== "success" || Boolean(raw.error) || raw.is_error === true;
126
+ const resultValue = raw.result ?? raw.output ?? raw.text ?? raw.content;
127
+ const durationMs = asNumber(raw.duration_ms) ?? asNumber(raw.durationMs) ?? (isRecord(raw.stats) ? asNumber(raw.stats.total_time_ms) : void 0) ?? 0;
128
+ const usage = extractUsage(raw);
129
+ const totalTokens = usage ? usage.inputTokens + usage.outputTokens : void 0;
130
+ const state = { stats: {
131
+ durationMs,
132
+ apiDurationMs: durationMs,
133
+ turns: asNumber(raw.num_turns) ?? 1,
134
+ costUsd: asNumber(raw.total_cost_usd) ?? 0,
135
+ inputTokens: usage?.inputTokens,
136
+ outputTokens: usage?.outputTokens,
137
+ totalTokens
138
+ } };
139
+ if (typeof resultValue === "string") state.output = { text: resultValue };
140
+ if (raw.structured_output !== void 0) state.output = {
141
+ ...state.output,
142
+ value: raw.structured_output
143
+ };
144
+ else if (context.schemaRequested && resultValue !== void 0) state.output = {
145
+ ...state.output,
146
+ value: resultValue
147
+ };
148
+ if (isError) {
149
+ state.status = "failed";
150
+ state.error = {
151
+ kind: "provider",
152
+ message: asString(raw.error) ?? (typeof resultValue === "string" && resultValue.trim() ? resultValue : stringifyValue(raw.error ?? resultValue ?? status))
153
+ };
154
+ } else state.status = "completed";
155
+ return {
156
+ events: [],
157
+ state
158
+ };
159
+ };
160
+ const mapErrorEvent = (raw, context) => {
161
+ const message = asString(raw.message) ?? (raw.error === void 0 ? void 0 : stringifyValue(raw.error)) ?? (raw.details === void 0 ? void 0 : stringifyValue(raw.details)) ?? "Gemini emitted an error event.";
162
+ return { events: [createAgentEvent(context.runId, "stderr", {
163
+ sessionId: context.sessionId,
164
+ text: message
165
+ })] };
166
+ };
167
+ const mapGeminiEvent = (event, context, options = {}) => {
168
+ const raw = event;
169
+ switch (event.type) {
170
+ case "init": return mapInitEvent(raw, context);
171
+ case "message": return mapMessageEvent(raw, context, options);
172
+ case "thought": return mapThoughtEvent(raw, context, options);
173
+ case "tool_use": return mapToolUseEvent(raw, context, options);
174
+ case "tool_result": return mapToolResultEvent(raw, context);
175
+ case "result": return mapResultEvent(raw, context);
176
+ case "error": return mapErrorEvent(raw, context);
177
+ default: return { events: [] };
178
+ }
179
+ };
180
+ //#endregion
181
+ //#region src/adapters/gemini-cli/events/parser.ts
182
+ const parseGeminiEvent = createEventParser(z.object({ type: z.string() }).passthrough());
183
+ //#endregion
184
+ //#region src/adapters/gemini-cli/adapter.ts
185
+ const GEMINI_CLI_CAPABILITIES = {
186
+ structuredOutput: false,
187
+ sessionResume: true,
188
+ imageInput: false,
189
+ mcp: true,
190
+ eventStreaming: true
191
+ };
192
+ var GeminiCliAgentImpl = class extends Agent {
193
+ type = "gemini-cli";
194
+ creationOptions;
195
+ runDefaults;
196
+ runModels = /* @__PURE__ */ new Map();
197
+ runTextBuffers = /* @__PURE__ */ new Map();
198
+ constructor(options = {}) {
199
+ super({
200
+ type: "gemini-cli",
201
+ capabilities: GEMINI_CLI_CAPABILITIES,
202
+ defaults: {
203
+ cwd: options.cwd,
204
+ env: options.env,
205
+ command: toArray(options.command ?? "gemini"),
206
+ sessionId: options.sessionId,
207
+ model: options.model,
208
+ systemPrompt: options.systemPrompt
209
+ },
210
+ spawner: options.spawner,
211
+ container: options.container,
212
+ logPath: options.logPath,
213
+ onEvent: options.onEvent
214
+ });
215
+ this.creationOptions = options;
216
+ this.runDefaults = {
217
+ allowedTools: options.allowedTools ? [...options.allowedTools] : void 0,
218
+ disallowedTools: options.disallowedTools ? [...options.disallowedTools] : void 0,
219
+ permissionMode: options.permissionMode,
220
+ extraArgs: options.extraArgs ? [...options.extraArgs] : void 0
221
+ };
222
+ }
223
+ buildArgs(request, run) {
224
+ const args = ["--output-format", "stream-json"];
225
+ const inputText = getInputText(request.input);
226
+ const allowedTools = request.allowedTools ?? this.runDefaults.allowedTools;
227
+ const disallowedTools = request.disallowedTools ?? this.runDefaults.disallowedTools;
228
+ const permissionMode = request.permissionMode ?? this.runDefaults.permissionMode;
229
+ const extraArgs = request.extraArgs ?? this.runDefaults.extraArgs;
230
+ this.runModels.set(run.runId, request.model);
231
+ if (request.model) args.push("--model", request.model);
232
+ if (request.systemPrompt) args.push("--system-prompt", request.systemPrompt);
233
+ if (permissionMode === "full") args.push("--approval-mode", "yolo");
234
+ if (allowedTools && allowedTools.length > 0) {
235
+ const disallowed = new Set((disallowedTools ?? []).map((t) => t.toLowerCase()));
236
+ const filtered = allowedTools.filter((t) => !disallowed.has(t.toLowerCase()));
237
+ for (const tool of filtered) args.push("--allowed-tools", tool);
238
+ }
239
+ if (run.requestedSessionId) args.push("--resume", run.requestedSessionId);
240
+ if (extraArgs && extraArgs.length > 0) args.push(...extraArgs);
241
+ if (inputText.trim().startsWith("-")) args.push("--prompt", inputText);
242
+ else args.push(inputText);
243
+ return args;
244
+ }
245
+ buildEnv(_request, _run) {
246
+ return this.buildDefaultEnv(this.creationOptions.propagateEnv);
247
+ }
248
+ mapRawEvent(raw, context) {
249
+ this.appendRawLog(raw);
250
+ const parsed = parseGeminiEvent(raw);
251
+ if (!parsed) {
252
+ this.onParseError(JSON.stringify(raw).slice(0, 200), /* @__PURE__ */ new Error("schema validation failed"));
253
+ return { events: [] };
254
+ }
255
+ const sessionId = getGeminiSessionId(parsed) ?? context.sessionId;
256
+ const batch = mapGeminiEvent(parsed, {
257
+ ...context,
258
+ sessionId
259
+ }, { model: this.runModels.get(context.runId) });
260
+ if (sessionId && batch.sessionId === void 0) batch.sessionId = sessionId;
261
+ let assistantText;
262
+ for (const event of batch.events) {
263
+ if (event.type !== "message" || event.role !== "assistant" || !event.text) continue;
264
+ const nextText = `${this.runTextBuffers.get(context.runId) ?? ""}${event.text}`;
265
+ this.runTextBuffers.set(context.runId, nextText);
266
+ assistantText = nextText;
267
+ }
268
+ if (parsed.type === "result" && batch.state?.output?.text !== void 0) this.runTextBuffers.set(context.runId, batch.state.output.text);
269
+ else if (assistantText !== void 0) batch.state = {
270
+ ...batch.state,
271
+ output: {
272
+ ...batch.state?.output,
273
+ text: assistantText
274
+ }
275
+ };
276
+ return batch;
277
+ }
278
+ async onRunFinished(run) {
279
+ await super.onRunFinished(run);
280
+ this.runModels.delete(run.runId);
281
+ this.runTextBuffers.delete(run.runId);
282
+ }
283
+ };
284
+ const createGeminiCliAgent = (options) => {
285
+ if (!options?.container) return new GeminiCliAgentImpl(options);
286
+ return new GeminiCliAgentImpl({
287
+ ...options,
288
+ spawner: options.container.spawner
289
+ });
290
+ };
291
+ //#endregion
292
+ export { createGeminiCliAgent };