@gonzih/cc-agent 0.15.3 → 0.15.5

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.
@@ -0,0 +1,228 @@
1
+ import { existsSync } from "fs";
2
+ import { spawn } from "child_process";
3
+ import { getPricing } from "./pricing.js";
4
+ import { BaseAgentProcess } from "./types.js";
5
+ /**
6
+ * AmpDriver wraps the `amp` CLI by Sourcegraph (https://ampcode.com).
7
+ * Spawns: amp --execute "<task>" --stream-json --dangerously-allow-all
8
+ *
9
+ * Amp's --stream-json output is documented as compatible with Claude Code's
10
+ * stream-json schema. Parsing logic mirrors claude.ts accordingly.
11
+ */
12
+ export class AmpDriver {
13
+ name = "amp";
14
+ resolveBinary() {
15
+ const dirs = (process.env.PATH ?? "").split(":");
16
+ for (const dir of dirs) {
17
+ const p = `${dir}/amp`;
18
+ if (existsSync(p))
19
+ return p;
20
+ }
21
+ const fallbacks = [
22
+ `${process.env.HOME}/.npm-global/bin/amp`,
23
+ "/opt/homebrew/bin/amp",
24
+ "/usr/local/bin/amp",
25
+ "/usr/bin/amp",
26
+ ];
27
+ for (const p of fallbacks) {
28
+ if (existsSync(p))
29
+ return p;
30
+ }
31
+ return "amp";
32
+ }
33
+ hasSession(_cwd) {
34
+ return false; // no persistent session support
35
+ }
36
+ spawn(options) {
37
+ const bin = this.resolveBinary();
38
+ const args = [
39
+ "--execute", options.task,
40
+ "--stream-json",
41
+ "--dangerously-allow-all",
42
+ ];
43
+ if (options.model) {
44
+ args.push("--model", options.model);
45
+ }
46
+ const env = {
47
+ ...process.env,
48
+ ...(options.env ?? {}),
49
+ };
50
+ // Map token → AMP_API_KEY
51
+ const apiKey = options.token ?? process.env.AMP_API_KEY;
52
+ if (apiKey)
53
+ env.AMP_API_KEY = apiKey;
54
+ let killed = false;
55
+ const emitter = new BaseAgentProcess();
56
+ let proc;
57
+ try {
58
+ proc = spawn(bin, args, { cwd: options.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
59
+ }
60
+ catch (err) {
61
+ process.nextTick(() => {
62
+ emitter.emit("text", `[amp] Failed to spawn: ${String(err)}\nInstall with: npm install -g @sourcegraph/amp`);
63
+ emitter.emit("exit", 1);
64
+ });
65
+ emitter.kill = () => { killed = true; };
66
+ return emitter;
67
+ }
68
+ emitter.pid = proc.pid;
69
+ let buf = "";
70
+ proc.stdout?.on("data", (chunk) => {
71
+ buf += chunk.toString();
72
+ const lines = buf.split("\n");
73
+ buf = lines.pop() ?? "";
74
+ for (const line of lines) {
75
+ if (!line.trim())
76
+ continue;
77
+ try {
78
+ const obj = JSON.parse(line);
79
+ parseAmpEvent(obj, emitter);
80
+ }
81
+ catch {
82
+ // non-JSON line — emit as raw text
83
+ if (line.trim())
84
+ emitter.emit("text", line);
85
+ }
86
+ }
87
+ });
88
+ proc.stderr?.on("data", (chunk) => {
89
+ const s = chunk.toString().trim();
90
+ if (s)
91
+ emitter.emit("text", `[amp stderr] ${s}`);
92
+ });
93
+ proc.on("error", (err) => {
94
+ if (!killed) {
95
+ emitter.emit("text", `[amp] Error: ${err.message}\nInstall with: npm install -g @sourcegraph/amp`);
96
+ emitter.emit("exit", 1);
97
+ }
98
+ });
99
+ proc.on("exit", (code) => {
100
+ if (buf.trim()) {
101
+ try {
102
+ const obj = JSON.parse(buf);
103
+ parseAmpEvent(obj, emitter);
104
+ }
105
+ catch {
106
+ emitter.emit("text", buf.trim());
107
+ }
108
+ }
109
+ if (!killed)
110
+ emitter.emit("exit", code);
111
+ });
112
+ emitter.kill = (signal) => {
113
+ killed = true;
114
+ try {
115
+ proc.kill((signal ?? "SIGTERM"));
116
+ }
117
+ catch { }
118
+ };
119
+ emitter.writeStdin = (data) => {
120
+ if (proc.stdin && !proc.stdin.destroyed) {
121
+ proc.stdin.write(data);
122
+ }
123
+ };
124
+ return emitter;
125
+ }
126
+ estimateCost(usage, model) {
127
+ if (usage.costUsd != null)
128
+ return usage.costUsd;
129
+ const pricing = getPricing(model ?? "amp");
130
+ const cost = (usage.inputTokens * pricing.inputPer1M +
131
+ usage.outputTokens * pricing.outputPer1M) /
132
+ 1_000_000;
133
+ return Math.round(cost * 10000) / 10000;
134
+ }
135
+ }
136
+ /**
137
+ * Parse a single NDJSON event from Amp's --stream-json output.
138
+ *
139
+ * Amp's schema is documented as compatible with Claude Code's stream-json format:
140
+ * - { type: "message_start", message: { usage: { input_tokens, output_tokens, ... } } }
141
+ * - { type: "message_delta", usage: { output_tokens } }
142
+ * - { type: "content_block_delta", delta: { type: "text_delta", text: string } }
143
+ * - { type: "content_block_start", content_block: { type: "tool_use", name: string } }
144
+ * - { type: "result", result: string, cost_usd?: number }
145
+ * - { session_id: string } — session identifier
146
+ */
147
+ function parseAmpEvent(obj, emitter) {
148
+ const type = obj.type;
149
+ // Session ID (may appear on any message type)
150
+ if (obj.session_id && typeof obj.session_id === "string") {
151
+ emitter.emit("sessionId", obj.session_id);
152
+ }
153
+ // Input token usage from message_start
154
+ if (type === "message_start") {
155
+ const message = obj.message;
156
+ if (message?.usage) {
157
+ const u = message.usage;
158
+ emitter.emit("usage", {
159
+ inputTokens: u.input_tokens ?? 0,
160
+ outputTokens: u.output_tokens ?? 0,
161
+ cacheReadTokens: u.cache_read_input_tokens ?? 0,
162
+ cacheWriteTokens: u.cache_creation_input_tokens ?? 0,
163
+ });
164
+ }
165
+ return;
166
+ }
167
+ // Output token usage from message_delta
168
+ if (type === "message_delta" && obj.usage) {
169
+ const u = obj.usage;
170
+ emitter.emit("usage", {
171
+ inputTokens: 0,
172
+ outputTokens: u.output_tokens ?? 0,
173
+ });
174
+ return;
175
+ }
176
+ // Text content from streaming delta
177
+ if (type === "content_block_delta") {
178
+ const delta = obj.delta;
179
+ if (delta?.type === "text_delta" && typeof delta.text === "string" && delta.text) {
180
+ emitter.emit("text", delta.text);
181
+ }
182
+ return;
183
+ }
184
+ // Tool use from content_block_start
185
+ if (type === "content_block_start") {
186
+ const block = obj.content_block;
187
+ if (block?.type === "tool_use" && typeof block.name === "string") {
188
+ emitter.emit("tool", block.name);
189
+ }
190
+ return;
191
+ }
192
+ // Final result message
193
+ if (type === "result") {
194
+ if (typeof obj.result === "string" && obj.result) {
195
+ emitter.emit("text", obj.result);
196
+ }
197
+ if (obj.cost_usd != null) {
198
+ emitter.emit("usage", {
199
+ inputTokens: 0,
200
+ outputTokens: 0,
201
+ costUsd: obj.cost_usd,
202
+ });
203
+ }
204
+ return;
205
+ }
206
+ // assistant message with content array (non-streaming shape)
207
+ if (type === "assistant") {
208
+ const message = obj.message;
209
+ if (!message)
210
+ return;
211
+ const content = message.content;
212
+ if (typeof content === "string" && content) {
213
+ emitter.emit("text", content);
214
+ }
215
+ else if (Array.isArray(content)) {
216
+ for (const block of content) {
217
+ if (block.type === "text" && typeof block.text === "string" && block.text) {
218
+ emitter.emit("text", block.text);
219
+ }
220
+ if (block.type === "tool_use" && typeof block.name === "string") {
221
+ emitter.emit("tool", block.name);
222
+ }
223
+ }
224
+ }
225
+ return;
226
+ }
227
+ }
228
+ //# sourceMappingURL=amp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"amp.js","sourceRoot":"","sources":["../../src/drivers/amp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { AgentDriver, AgentProcess, SpawnOptions, UsageEvent } from "./types.js";
2
+ /**
3
+ * CodexDriver wraps the OpenAI Codex CLI (https://github.com/openai/codex).
4
+ * Spawns: codex exec "<task>" [--model <model>] --full-auto
5
+ *
6
+ * Codex CLI produces plain text output only — no JSON stream mode.
7
+ * Each stdout line is emitted as a "text" event.
8
+ * No structured usage data is available from the CLI output.
9
+ */
10
+ export declare class CodexDriver implements AgentDriver {
11
+ readonly name = "codex";
12
+ resolveBinary(): string;
13
+ hasSession(_cwd: string): boolean;
14
+ spawn(options: SpawnOptions): AgentProcess;
15
+ estimateCost(usage: UsageEvent, model?: string): number;
16
+ }
17
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/drivers/codex.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtF;;;;;;;GAOG;AACH,qBAAa,WAAY,YAAW,WAAW;IAC7C,QAAQ,CAAC,IAAI,WAAW;IAExB,aAAa,IAAI,MAAM;IAoBvB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY;IA+E1C,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;CASxD"}
@@ -0,0 +1,123 @@
1
+ import { existsSync } from "fs";
2
+ import { spawn } from "child_process";
3
+ import { getPricing } from "./pricing.js";
4
+ import { BaseAgentProcess } from "./types.js";
5
+ /**
6
+ * CodexDriver wraps the OpenAI Codex CLI (https://github.com/openai/codex).
7
+ * Spawns: codex exec "<task>" [--model <model>] --full-auto
8
+ *
9
+ * Codex CLI produces plain text output only — no JSON stream mode.
10
+ * Each stdout line is emitted as a "text" event.
11
+ * No structured usage data is available from the CLI output.
12
+ */
13
+ export class CodexDriver {
14
+ name = "codex";
15
+ resolveBinary() {
16
+ const dirs = (process.env.PATH ?? "").split(":");
17
+ for (const dir of dirs) {
18
+ const p = `${dir}/codex`;
19
+ if (existsSync(p))
20
+ return p;
21
+ }
22
+ const fallbacks = [
23
+ `${process.env.HOME}/.npm-global/bin/codex`,
24
+ "/opt/homebrew/bin/codex",
25
+ "/usr/local/bin/codex",
26
+ "/usr/bin/codex",
27
+ // Rust binary installed via cargo
28
+ `${process.env.HOME}/.cargo/bin/codex`,
29
+ ];
30
+ for (const p of fallbacks) {
31
+ if (existsSync(p))
32
+ return p;
33
+ }
34
+ return "codex";
35
+ }
36
+ hasSession(_cwd) {
37
+ return false; // no persistent session support
38
+ }
39
+ spawn(options) {
40
+ const bin = this.resolveBinary();
41
+ const model = options.model ?? "gpt-4.1";
42
+ const args = [
43
+ "exec",
44
+ options.task,
45
+ "--model", model,
46
+ "--full-auto",
47
+ ];
48
+ const env = {
49
+ ...process.env,
50
+ ...(options.env ?? {}),
51
+ };
52
+ // Map token → OPENAI_API_KEY
53
+ const apiKey = options.token ?? process.env.OPENAI_API_KEY;
54
+ if (apiKey)
55
+ env.OPENAI_API_KEY = apiKey;
56
+ let killed = false;
57
+ const emitter = new BaseAgentProcess();
58
+ let proc;
59
+ try {
60
+ proc = spawn(bin, args, { cwd: options.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
61
+ }
62
+ catch (err) {
63
+ process.nextTick(() => {
64
+ emitter.emit("text", `[codex] Failed to spawn: ${String(err)}\nInstall with: npm install -g @openai/codex`);
65
+ emitter.emit("exit", 1);
66
+ });
67
+ emitter.kill = () => { killed = true; };
68
+ return emitter;
69
+ }
70
+ emitter.pid = proc.pid;
71
+ let buffer = "";
72
+ proc.stdout?.on("data", (chunk) => {
73
+ const text = chunk.toString();
74
+ buffer += text;
75
+ const lines = buffer.split("\n");
76
+ buffer = lines.pop() ?? "";
77
+ for (const line of lines) {
78
+ if (line.trim())
79
+ emitter.emit("text", line);
80
+ }
81
+ });
82
+ proc.stderr?.on("data", (chunk) => {
83
+ const s = chunk.toString().trim();
84
+ if (s)
85
+ emitter.emit("text", `[codex stderr] ${s}`);
86
+ });
87
+ proc.on("error", (err) => {
88
+ if (!killed) {
89
+ emitter.emit("text", `[codex] Error: ${err.message}\nInstall with: npm install -g @openai/codex`);
90
+ emitter.emit("exit", 1);
91
+ }
92
+ });
93
+ proc.on("exit", (code) => {
94
+ if (buffer.trim())
95
+ emitter.emit("text", buffer.trim());
96
+ if (!killed)
97
+ emitter.emit("exit", code);
98
+ });
99
+ emitter.kill = (signal) => {
100
+ killed = true;
101
+ try {
102
+ proc.kill((signal ?? "SIGTERM"));
103
+ }
104
+ catch { }
105
+ };
106
+ emitter.writeStdin = (data) => {
107
+ if (proc.stdin && !proc.stdin.destroyed) {
108
+ proc.stdin.write(data);
109
+ }
110
+ };
111
+ return emitter;
112
+ }
113
+ estimateCost(usage, model) {
114
+ if (usage.costUsd != null)
115
+ return usage.costUsd;
116
+ const pricing = getPricing(model ?? "gpt-4.1");
117
+ const cost = (usage.inputTokens * pricing.inputPer1M +
118
+ usage.outputTokens * pricing.outputPer1M) /
119
+ 1_000_000;
120
+ return Math.round(cost * 10000) / 10000;
121
+ }
122
+ }
123
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/drivers/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { AgentDriver, AgentProcess, SpawnOptions, UsageEvent } from "./types.js";
2
+ /**
3
+ * GeminiDriver wraps the `gemini` CLI (https://github.com/google-gemini/gemini-cli).
4
+ * Spawns: gemini -p "<task>" --output-format stream-json --yolo [-m <model>]
5
+ *
6
+ * Parses NDJSON output emitting text, tool, usage, and exit events.
7
+ * The stream-json schema emits objects with a `type` field; text content
8
+ * appears under various field names depending on CLI version.
9
+ */
10
+ export declare class GeminiDriver implements AgentDriver {
11
+ readonly name = "gemini";
12
+ resolveBinary(): string;
13
+ hasSession(_cwd: string): boolean;
14
+ spawn(options: SpawnOptions): AgentProcess;
15
+ estimateCost(usage: UsageEvent, model?: string): number;
16
+ }
17
+ //# sourceMappingURL=gemini.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/drivers/gemini.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtF;;;;;;;GAOG;AACH,qBAAa,YAAa,YAAW,WAAW;IAC9C,QAAQ,CAAC,IAAI,YAAY;IAEzB,aAAa,IAAI,MAAM;IAkBvB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY;IA4F1C,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;CASxD"}
@@ -0,0 +1,217 @@
1
+ import { existsSync } from "fs";
2
+ import { spawn } from "child_process";
3
+ import { getPricing } from "./pricing.js";
4
+ import { BaseAgentProcess } from "./types.js";
5
+ /**
6
+ * GeminiDriver wraps the `gemini` CLI (https://github.com/google-gemini/gemini-cli).
7
+ * Spawns: gemini -p "<task>" --output-format stream-json --yolo [-m <model>]
8
+ *
9
+ * Parses NDJSON output emitting text, tool, usage, and exit events.
10
+ * The stream-json schema emits objects with a `type` field; text content
11
+ * appears under various field names depending on CLI version.
12
+ */
13
+ export class GeminiDriver {
14
+ name = "gemini";
15
+ resolveBinary() {
16
+ const dirs = (process.env.PATH ?? "").split(":");
17
+ for (const dir of dirs) {
18
+ const p = `${dir}/gemini`;
19
+ if (existsSync(p))
20
+ return p;
21
+ }
22
+ const fallbacks = [
23
+ `${process.env.HOME}/.npm-global/bin/gemini`,
24
+ "/opt/homebrew/bin/gemini",
25
+ "/usr/local/bin/gemini",
26
+ "/usr/bin/gemini",
27
+ ];
28
+ for (const p of fallbacks) {
29
+ if (existsSync(p))
30
+ return p;
31
+ }
32
+ return "gemini";
33
+ }
34
+ hasSession(_cwd) {
35
+ return false; // no persistent session support
36
+ }
37
+ spawn(options) {
38
+ const bin = this.resolveBinary();
39
+ const model = options.model ?? "gemini-2.5-pro";
40
+ const args = [
41
+ "-p", options.task,
42
+ "--output-format", "stream-json",
43
+ "--yolo",
44
+ "-m", model,
45
+ ];
46
+ const env = {
47
+ ...process.env,
48
+ ...(options.env ?? {}),
49
+ };
50
+ // Map token → GEMINI_API_KEY
51
+ const apiKey = options.token ?? process.env.GEMINI_API_KEY;
52
+ if (apiKey)
53
+ env.GEMINI_API_KEY = apiKey;
54
+ let killed = false;
55
+ const emitter = new BaseAgentProcess();
56
+ let proc;
57
+ try {
58
+ proc = spawn(bin, args, { cwd: options.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
59
+ }
60
+ catch (err) {
61
+ process.nextTick(() => {
62
+ emitter.emit("text", `[gemini] Failed to spawn: ${String(err)}\nInstall with: npm install -g @google/gemini-cli`);
63
+ emitter.emit("exit", 1);
64
+ });
65
+ emitter.kill = () => { killed = true; };
66
+ return emitter;
67
+ }
68
+ emitter.pid = proc.pid;
69
+ let buf = "";
70
+ proc.stdout?.on("data", (chunk) => {
71
+ buf += chunk.toString();
72
+ const lines = buf.split("\n");
73
+ buf = lines.pop() ?? "";
74
+ for (const line of lines) {
75
+ if (!line.trim())
76
+ continue;
77
+ try {
78
+ const obj = JSON.parse(line);
79
+ parseGeminiEvent(obj, emitter);
80
+ }
81
+ catch {
82
+ // non-JSON line — emit as raw text
83
+ if (line.trim())
84
+ emitter.emit("text", line);
85
+ }
86
+ }
87
+ });
88
+ proc.stderr?.on("data", (chunk) => {
89
+ const s = chunk.toString().trim();
90
+ if (s)
91
+ emitter.emit("text", `[gemini stderr] ${s}`);
92
+ });
93
+ proc.on("error", (err) => {
94
+ if (!killed) {
95
+ emitter.emit("text", `[gemini] Error: ${err.message}\nInstall with: npm install -g @google/gemini-cli`);
96
+ emitter.emit("exit", 1);
97
+ }
98
+ });
99
+ proc.on("exit", (code) => {
100
+ if (buf.trim()) {
101
+ try {
102
+ const obj = JSON.parse(buf);
103
+ parseGeminiEvent(obj, emitter);
104
+ }
105
+ catch {
106
+ emitter.emit("text", buf.trim());
107
+ }
108
+ }
109
+ if (!killed)
110
+ emitter.emit("exit", code);
111
+ });
112
+ emitter.kill = (signal) => {
113
+ killed = true;
114
+ try {
115
+ proc.kill((signal ?? "SIGTERM"));
116
+ }
117
+ catch { }
118
+ };
119
+ emitter.writeStdin = (data) => {
120
+ if (proc.stdin && !proc.stdin.destroyed) {
121
+ proc.stdin.write(data);
122
+ }
123
+ };
124
+ return emitter;
125
+ }
126
+ estimateCost(usage, model) {
127
+ if (usage.costUsd != null)
128
+ return usage.costUsd;
129
+ const pricing = getPricing(model ?? "gemini-2.5-pro");
130
+ const cost = (usage.inputTokens * pricing.inputPer1M +
131
+ usage.outputTokens * pricing.outputPer1M) /
132
+ 1_000_000;
133
+ return Math.round(cost * 10000) / 10000;
134
+ }
135
+ }
136
+ /**
137
+ * Parse a single NDJSON event from the Gemini CLI stream-json output.
138
+ *
139
+ * The Gemini CLI stream-json schema emits objects with a `type` field.
140
+ * Known event shapes:
141
+ * - { type: "content", value: string } — text content chunk
142
+ * - { type: "tool_call", name: string } — tool invocation
143
+ * - { type: "usage", inputTokens: number, outputTokens: number } — token usage
144
+ * - { type: "error", message: string } — error from the CLI
145
+ * - { usageMetadata: { promptTokenCount, candidatesTokenCount } } — Gemini API usage metadata
146
+ * - { candidates: [{ content: { parts: [{ text: string }] } }] } — raw API response shape
147
+ *
148
+ * We apply best-effort matching since the schema is not formally documented.
149
+ */
150
+ function parseGeminiEvent(obj, emitter) {
151
+ const type = obj.type;
152
+ // Structured stream-json events
153
+ if (type === "content") {
154
+ const value = obj.value ?? obj.text ?? obj.content;
155
+ if (typeof value === "string" && value)
156
+ emitter.emit("text", value);
157
+ return;
158
+ }
159
+ if (type === "tool_call" || type === "tool_use" || type === "tool") {
160
+ const name = (obj.name ?? obj.tool_name ?? obj.toolName);
161
+ if (name)
162
+ emitter.emit("tool", name);
163
+ return;
164
+ }
165
+ if (type === "usage") {
166
+ const u = {
167
+ inputTokens: obj.inputTokens ?? obj.input_tokens ?? 0,
168
+ outputTokens: obj.outputTokens ?? obj.output_tokens ?? 0,
169
+ };
170
+ emitter.emit("usage", u);
171
+ return;
172
+ }
173
+ if (type === "error") {
174
+ const msg = (obj.message ?? obj.error ?? obj.text);
175
+ if (msg)
176
+ emitter.emit("text", `[gemini error] ${msg}`);
177
+ return;
178
+ }
179
+ // Gemini API usageMetadata shape (may appear in raw API pass-through)
180
+ if (obj.usageMetadata && typeof obj.usageMetadata === "object") {
181
+ const meta = obj.usageMetadata;
182
+ const inputTokens = meta.promptTokenCount ?? 0;
183
+ const outputTokens = meta.candidatesTokenCount ?? 0;
184
+ if (inputTokens || outputTokens) {
185
+ emitter.emit("usage", { inputTokens, outputTokens });
186
+ }
187
+ }
188
+ // Raw Gemini API candidates shape
189
+ if (Array.isArray(obj.candidates)) {
190
+ for (const candidate of obj.candidates) {
191
+ const content = candidate.content;
192
+ if (!content)
193
+ continue;
194
+ const parts = content.parts;
195
+ if (!parts)
196
+ continue;
197
+ for (const part of parts) {
198
+ if (typeof part.text === "string" && part.text) {
199
+ emitter.emit("text", part.text);
200
+ }
201
+ if (part.functionCall && typeof part.functionCall === "object") {
202
+ const fc = part.functionCall;
203
+ if (typeof fc.name === "string")
204
+ emitter.emit("tool", fc.name);
205
+ }
206
+ }
207
+ }
208
+ return;
209
+ }
210
+ // Plain text fallback for unknown shapes with a text/content/value field
211
+ if (!type) {
212
+ const text = obj.text ?? obj.content ?? obj.value ?? obj.message;
213
+ if (typeof text === "string" && text.trim())
214
+ emitter.emit("text", text);
215
+ }
216
+ }
217
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/drivers/gemini.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,12 @@ import type { AgentDriver } from "./types.js";
2
2
  export { ClaudeCodeDriver } from "./claude-code.js";
3
3
  export { AiderDriver } from "./aider.js";
4
4
  export { OpenAICompatibleDriver } from "./openai-compatible.js";
5
+ export { GeminiDriver } from "./gemini.js";
6
+ export { AmpDriver } from "./amp.js";
7
+ export { CodexDriver } from "./codex.js";
5
8
  export type { AgentDriver, AgentProcess, SpawnOptions, UsageEvent, AgentPricing } from "./types.js";
6
9
  export { getPricing } from "./pricing.js";
7
- declare const VALID_DRIVERS: readonly ["claude", "claude-code", "aider", "openai", "openai-compatible", "qwen", "kimi", "deepseek", "pi"];
10
+ declare const VALID_DRIVERS: readonly ["claude", "claude-code", "aider", "openai", "openai-compatible", "qwen", "kimi", "deepseek", "pi", "gemini", "amp", "codex"];
8
11
  export type DriverName = typeof VALID_DRIVERS[number];
9
12
  /**
10
13
  * Return an AgentDriver instance for the given name.