|
1 | | -import { Codex } from "@openai/codex-sdk"; |
| 1 | +import { Codex, type ThreadEvent } from "@openai/codex-sdk"; |
2 | 2 | import { execSync } from "node:child_process"; |
3 | 3 | import * as fs from "node:fs"; |
4 | 4 | import * as os from "node:os"; |
@@ -77,20 +77,10 @@ export async function runCodegen(opts: CodegenOptions): Promise<void> { |
77 | 77 | log(opts, `Prompt length: ${prompt.length} chars`); |
78 | 78 | } |
79 | 79 |
|
80 | | - const turn = await thread.run(prompt); |
| 80 | + const { events } = await thread.runStreamed(prompt); |
81 | 81 |
|
82 | | - if (opts.verbose && turn.finalResponse) { |
83 | | - log( |
84 | | - opts, |
85 | | - `Agent response (truncated): ${turn.finalResponse.slice(0, 500)}`, |
86 | | - ); |
87 | | - } |
88 | | - |
89 | | - if (turn.usage) { |
90 | | - log( |
91 | | - opts, |
92 | | - `Token usage -- input: ${turn.usage.input_tokens}, output: ${turn.usage.output_tokens}`, |
93 | | - ); |
| 82 | + for await (const event of events) { |
| 83 | + printEvent(event, opts); |
94 | 84 | } |
95 | 85 |
|
96 | 86 | // Run verification ourselves to confirm state. |
@@ -269,3 +259,37 @@ function log(opts: CodegenOptions, msg: string): void { |
269 | 259 | console.log(msg); |
270 | 260 | } |
271 | 261 | } |
| 262 | + |
| 263 | +function printEvent(event: ThreadEvent, opts: CodegenOptions): void { |
| 264 | + switch (event.type) { |
| 265 | + case "item.completed": { |
| 266 | + const item = event.item; |
| 267 | + if (item.type === "agent_message") { |
| 268 | + console.log(`\n[agent] ${item.text}\n`); |
| 269 | + } else if (item.type === "command_execution") { |
| 270 | + const cmd = "command" in item ? String(item.command) : ""; |
| 271 | + const exit = "exit_code" in item ? item.exit_code : undefined; |
| 272 | + console.log(`[exec] ${cmd} (exit ${exit ?? "?"})`); |
| 273 | + } else if (item.type === "file_change") { |
| 274 | + const file = "path" in item ? String(item.path) : ""; |
| 275 | + console.log(`[file] ${file}`); |
| 276 | + } else if (item.type === "reasoning" && opts.verbose) { |
| 277 | + const text = "text" in item ? String(item.text) : ""; |
| 278 | + console.log(`[think] ${text.slice(0, 200)}`); |
| 279 | + } |
| 280 | + break; |
| 281 | + } |
| 282 | + case "turn.completed": |
| 283 | + if (event.usage) { |
| 284 | + console.log( |
| 285 | + `[usage] input: ${event.usage.input_tokens}, output: ${event.usage.output_tokens}`, |
| 286 | + ); |
| 287 | + } |
| 288 | + break; |
| 289 | + case "turn.failed": |
| 290 | + console.error(`[error] ${event.error.message}`); |
| 291 | + break; |
| 292 | + default: |
| 293 | + break; |
| 294 | + } |
| 295 | +} |
0 commit comments