工作区、线程与 SDK 首次运行
任务状态不等于 Git 状态
thread 保存对话,turn 表示一次输入到完成的执行,workspace 保存实际文件。恢复 thread 不会自动把工作区倒回旧版本,取消 turn 也不会撤销已写文件。因此实验使用专用目录,先记录修改前状态,再运行 Agent。
本机核对 CLI 0.153.4;SDK 与 CLI 协议应作为一组固定。Node.js 22 环境创建独立教学仓库:
mkdir codex-lab
cd codex-lab
git init
npm init -y
npm install @openai/codex-sdk@0.153.4
codex --version将无敏感信息的 README.md 写入这个目录。按官方登录方式配置 Codex;在线运行会调用模型,本节未运行计费 turn。保存 inspect.mjs,运行 node inspect.mjs:
import { Codex } from '@openai/codex-sdk';
const codex = new Codex();
const thread = codex.startThread({
workingDirectory: process.cwd(),
sandboxMode: 'read-only',
approvalPolicy: 'never',
});
const turn = await thread.run('读取 README.md,说明它包含哪些信息;不要修改文件。');
console.log('thread', thread.id);
console.log(turn.finalResponse);
console.log(turn.usage);read-only 限制实际能力,提示中的“不要修改”说明意图,二者不能互相替代。approvalPolicy=never 不是授予无限权限;它让需要额外授权的操作无法通过交互升级。真实可执行范围还受宿主策略控制。
同一 thread 上再次 run 延续对话;进程重启后使用 codex.resumeThread(savedId, options)。保存 ID 的同时保存仓库路径和版本,避免恢复到错误目录。SDK 内部启动 CLI 并读取结构化事件,不是把普通 Responses 文字输出当作代码 Agent。
观察流式任务
把上述 run 部分替换为:
const { events } = await thread.runStreamed('读取 README.md 并总结。');
let completed = false;
for await (const event of events) {
if (event.type === 'item.completed') console.log(event.item);
if (event.type === 'turn.completed') completed = true;
if (event.type === 'turn.failed' || event.type === 'error') {
throw new Error(JSON.stringify(event));
}
}
if (!completed) throw new Error('turn ended without completion');item.completed 可能是命令、文件变化或消息,不能把任意 item 完成当成 turn 完成。输出 schema 可以约束最后报告,但不能证明报告引用的测试真的运行;应核对事件中的命令、退出码与工作区差异。
SDK 的 AbortSignal 用于终止等待/执行流,取消后仍检查后台进程和文件状态。工作区写操作实验另建 worktree,避免与用户未提交修改混在一起。参阅 SDK 源码与教程。
练习
离线编写事件检查函数,输入只有 item.completed 应为 false;追加 turn.completed 后为 true;出现 turn.failed 应抛错。
先记录自己的输出与解释,再核对本章答案。