agenttaskflow
v0.4.9
Published
TypeScript workflows with persistent Codex and Claude Code sessions
Readme
AgentTaskFlow
atf 命令行
包名是 agenttaskflow,命令名是 atf。npm 上的 atf 已是另一个 CSS 工具,不能用 npm install -g atf 安装本项目。
本地安装当前开发版本(Node.js 22.15+):
cd /Users/maple/workbench/agenttaskflow
nvm use
npm run build
npm install -g .
atf examples/simple.ts
atf examples/multi-fields.ts
atf examples/smoke.ts --command cxh --rounds 5从 npm 安装:npm install -g agenttaskflow(需要 Node.js 22.15+)。
atf 文件.ts 执行普通 TS/JS 文件,保留当前工作目录,文件名之后的参数原样交给流程。支持相对 import、顶层 await 和导出的 main(args) 入口;main 若存在会在文件加载完成后调用一次。直接调用 flow(...) 的现有脚本无需改写。不做类型检查,需要时运行项目自己的 tsc。执行器通过 esbuild 编译 TS,没有新造流程语言。
独立文件可以直接 import { flow } from 'agenttaskflow';优先使用项目本地依赖,找不到时回退到 atf 安装中的 AgentTaskFlow 和 Zod。其它业务依赖仍由项目正常安装。atf --help 查看用法,atf --version 查看版本。
流程启动独立 TypeScript 子进程时,可使用 spawnSync(process.execPath, ['--import', import.meta.resolve('agenttaskflow/register'), workerPath], options)。子进程使用安装包自带的 loader,支持独立文件中的 AgentTaskFlow、Zod 与相对 TS import;无需额外安装 tsx。
用普通 TypeScript 脚本控制 Codex 和 Claude Code。没有 DSL、没有 .flow 文件、没有自定义语法。默认同步 API 不需要 async/await。
step() 等当前步骤完成后返回结果。一次 flow 只启动一个 CLI 进程,循环、分支和格式补答都复用它。终端按顺序显示:当前步骤 → 实际输入 → agent 实时输出 → 完成/失败。
import { flow } from 'agenttaskflow';
flow('cxh', step => {
// 先生成方案。
step('设计一个本地待办工具,只给方案,不修改文件。');
// 审查通过才继续,最多三轮。
for (let i = 0; i < 3; i++) {
if (step.check('方案是否满足全部要求?')) break;
if (i === 2) throw new Error('三轮后仍未通过');
step('根据审查意见修订方案');
}
// 汇总已经通过审查的方案。
step('总结最终方案');
});不需要声明类型、schema、async/await,也不用手动启动和关闭。步骤名称自动取提示词第一行。完整示例见 examples/simple.ts,在项目目录执行 npm run simple。
需要一次返回多个字段时,运行 npm run multi-fields(使用 cxh)。examples/multi-fields.ts 演示通过 step.data 获取 passed、score、problems、suggestion 四个字段,打印结果并按审查意见修订,最多三轮。提示词直接写在示例文件中。
更多可运行流程位于 test/,说明见 test/README.md。执行 npm run flows -- --list 列出流程,npm run flows -- branches loop 测试指定流程,npm run flows -- all 依次运行全部六个真实 agent 测试。
| 调用 | 返回值 |
| --- | --- |
| step('执行任务') | 回答文本 |
| step.check('是否满足要求?') | true / false |
| step.choose('评估风险', ['low', 'high']) | 选项之一 |
| step.data('提取结果', schema) | 自定义结构化结果 |
check 和 choose 自动要求结构化输出、校验并在格式错误时提示补答。它们返回模型的判断;涉及文件、测试等可核实事实时,还应由脚本验证实际证据。配置 Claude Code 使用 flow({ provider: 'claude', command: 'claude' }, step => { /* 流程 */ })。
直接运行
需要 Node.js 22+,以及已经安装、登录的 Codex 或 Claude Code CLI。
cd /Users/maple/workbench/agenttaskflow
nvm use
npm run smoke -- --provider codex --command cxh --rounds 5等价于直接执行普通 TypeScript:
npx tsx examples/smoke.ts --provider codex --command cxh --rounds 5Claude Code:
npm run smoke -- --provider claude --command claude --rounds 5本地依赖和构建产物已准备好。新检出环境执行 npm install && npm run build。
示例先交给 agent 一个随机标记,然后五次回忆。后续输入不再携带标记,脚本检查标记、轮数和 PID。每一轮会调用真实模型,但不要求 agent 读写业务文件。
首次启动 cxh 仍可能花时间:包装脚本会预热后端,本机 Node 加载也可能较慢。默认只预热一次,不会每一步重来。 示例每步超时默认 600 秒,可用 --timeout 600 调整;每 15 秒显示等待状态。若已确认后端就绪,可以使用包装脚本自己的 CXH_NO_WARM=1 开关,这不等于修复后端问题。
需要更多控制时
全自动任务可显式配置 approvals: 'auto':Codex 的命令/文件修改审批和 Claude Code 的工具审批会自动通过,并保留审批日志与原会话。默认 approvals: 'deny';未知的宿主交互仍报告错误。
需要自定义步骤名、详细结果或 checkpoint 时,使用 withAgent。它与 flow 使用同一套会话和执行能力:
import { z } from 'zod';
import { withAgent } from 'agenttaskflow';
const REVIEW = `审查当前方案。返回 verdict(pass 或 revise)和 reason。`;
const REVISE = `根据上一轮审查意见修订方案,并报告真实修改。`;
const Review = z.strictObject({
verdict: z.enum(['pass', 'revise']),
reason: z.string(),
});
withAgent({ command: 'cxh' }, agent => {
// 先生成方案,让后续审查使用同一个上下文。
agent.run('设计一个本地待办工具,只给方案,不修改文件。', { name: '生成方案' });
// 审查通过就结束;否则修订,最多三轮。
for (let round = 1; round <= 3; round++) {
const result = agent.run(REVIEW, { name: `审查 ${round}`, schema: Review });
if (result.verdict === 'pass') break;
if (round === 3) throw new Error('三轮后仍未通过');
agent.run(REVISE, { name: `修订 ${round}` });
}
});withAgent 在正常结束或抛错后关闭进程。也可以手动管理:
import { Agent } from 'agenttaskflow';
const agent = new Agent({ command: 'cxh' });
try {
const answer = agent.run('说明你的任务', { name: '开始' });
console.log(answer); // string,不是 Promise
} finally {
agent.close();
}业务流程由 TypeScript 的 if/else、for/while、函数、try/catch、import 控制,不使用 next 变量模拟 goto。
提示词直接写在 .ts 文件中的字符串常量或函数里。共享内容放到公共 .ts 模块,用正常 import 复用。不要把各种文字拆成一堆小文本文件,不要让 agent 每一步去读提示词文件。 主流程每个阶段前加一句说明目的的注释。
命令和配置
new Agent({ provider: 'codex', command: 'cxh' });
new Agent({ provider: 'codex', command: ['/path/to/cx', 'fixed-argument'] });
new Agent({ provider: 'claude', command: 'claude', cwd: '/path/to/project' });provider 是协议,command 是可执行命令或 argv 数组。不会从 cxh 名字猜测协议,也不会把字符串当 shell 代码执行。alias/function 需要用户提供可执行包装脚本,通过 "$@" 原样转发参数。
示例命令行的固定参数用重复的 --command-arg VALUE 传入。一般 cxh 不需要额外参数。
| 配置 | 默认值 | 作用 |
| --- | --- | --- |
| provider | codex | codex 或 claude |
| command | provider 对应名称 | 自定义命令或 argv |
| cwd | 当前目录 | agent 工作目录 |
| timeoutMs | 3600000 | 每步总超时,包含补答;示例设为 600000 |
| idleTimeoutMs | 不启用 | stdout/stderr 无新输出超时 |
| progressIntervalMs | 15000 | 等待提示间隔,设 null 关闭 |
| maxCorrections | 不设次数上限 | 格式不合格时向同一 agent 补答,仍受单步超时和取消限制;可显式设置次数上限 |
| nativeSchema | false | 显式启用时向 Codex 发送原生 outputSchema;默认只约束最终回答并在本地校验,避免兼容后端限制工具调用 |
| display | new Console() | 设 false 关闭终端展示 |
| onEvent | 无 | 接收事件的同步回调 |
| extraArgs | [] | 模型等 CLI 选项;会话和协议参数由库管理 |
| env | {} | 合并到子进程环境的显式变量 |
| runId | 自动生成 | 显式恢复同一逻辑运行 |
| workflowVersion | 1 | 流程版本,修改流程时递增 |
| stateDir | <cwd>/.agenttaskflow | 状态与日志目录 |
| sessionId | 无 | 首次打开时绑定已有外部会话 |
调用 agent.run(prompt, { name, schema })。不提供 schema 就返回字符串;提供 Zod schema 后返回其推导出的类型。建议使用 z.strictObject、枚举和明确字段。z.number() 不会把数字字符串当数字,但用户显式使用 z.coerce 时遵循该 schema 的规则。
常驻会话与结果校验
Codex 只启动一次 app-server,初始化并创建/续接一个 thread,再逐轮发送 turn/start。Claude Code 只启动一次双向 stream-json 进程,持续发送 user 消息。agent.pid 在多步之间保持不变。
Codex 的 schema 随轮次变化。Claude 常驻模式用每一步的 prompt 约束格式,在本地验证,避免进程级固定 schema 限制不同步骤。即使 nativeSchema: false,仍发送 prompt 格式要求并本地校验。
正常完成但输出不符合 schema 时,在同一进程、同一会话发送补答 prompt,明确不要重复已完成操作;补答次数耗尽后抛出 ResultValidationError。自定义 Zod refinement 在调用方执行,也能触发补答。schema 必须可以转换为 JSON Schema;异步 refinement 请使用适合的异步业务逻辑,不在默认同步 API 中执行。
进程失败、通信异常或超时不会自动重启或重发任务。完成依赖当前轮次的明确完成事件,不等待进程退出,也不靠“几秒没有输出”猜测。Codex 过滤 thread/turn ID,防止旧轮次的延迟事件成为新答案。
CLI 的既有权限设置仍然生效。库不主动添加跳过权限检查的参数。若 CLI 要求宿主批准工具或回答其他交互请求,本版会拒绝未经批准的动作并报错,不静默授权。
同步 API 为什么还能实时显示
流程线程在 run() 中等待,独立工作线程继续处理 agent 的输入输出。事件会在等待期间交给调用方展示,故不需要流程作者写 async/await。默认 Console 使用直接写入终端的方式,隐藏的协议事件不会把流式文字切成多行。
这不会把所有 JavaScript API 变成同步 API:你自己调用 fetch() 等仍应遵循它们的接口。默认同步方式适合独立的顺序工作流;Web 服务、GUI、同一主线程需要同时处理其他工作时使用可选异步 API:
import { withAsyncAgent } from 'agenttaskflow';
await withAsyncAgent({ command: 'cxh' }, async agent => {
const answer = await agent.run('hello');
});同步事件回调不能重新调用当前 Agent 方法,否则会形成嵌套等待。回调请保持简短。显示回调异常会在当前请求处理结束后抛出;不要把显示回调当作任务取消接口。异步 API 可传 AbortSignal。
close() 会关闭连接并清理进程。macOS/Linux 有独立生命周期监视进程,工作流被 Ctrl+C 或意外退出时清理对应 agent 进程组。Windows 未验证,仅直接子进程清理,不保证完整后代清理。
同步模式下普通主线程 timer/Promise 回调不会在阻塞等待中执行;进程通信、超时和锁的心跳在工作线程运行。不要安装一个依赖主线程继续执行才能生效的 SIGINT 处理器来代替默认 Ctrl+C。
显式 checkpoint
withAgent({ command: 'cxh', runId: 'research-001', workflowVersion: 'v1' }, agent => {
const inputs = { topic: 'example', promptVersion: 1 };
let state = agent.loadCheckpoint<{ answer: string }>('outline', inputs);
if (!state) {
const answer = agent.run('生成提纲', { name: '提纲' });
state = { answer };
agent.saveCheckpoint('outline', state, inputs);
}
console.log(state.answer);
});同一个 runId 自动读取保存的会话 ID。工作目录、命令、provider、显式环境、额外参数或流程版本变化时,拒绝复用旧状态;checkpoint 输入变化也会拒绝复用。
不恢复 TypeScript 的调用栈,不自动跳过任何 run,不自动重放任务。 恢复位置由普通 TypeScript 判断。中断前外部操作可能已完成,应先检查产物再决定重做。
同一运行使用跨进程锁,正常 close 释放;进程崩溃留下的锁在停止心跳至少 30 秒后才可被下一次调用识别为过期。不要手动删除仍在使用的锁。不同 run 可以使用不同 agent 并发,不能主动操纵同一个外部 session。
日志与排错
交互终端中,步骤标题为紫色粗体,输入为青色并带边框,agent 回答为绿色,运行状态淡化显示,警告为黄色,失败为红色。重定向到文件时默认不带颜色;设置 NO_COLOR=1 可禁用,或通过 new Console({ color: false }) 关闭。
import { Console } from 'agenttaskflow';
new Agent({ command: 'cxh', display: new Console({ showInputs: false }) });默认 .agenttaskflow/<runId>/:
state.json 配置指纹、会话 ID、checkpoint
steps/<stepId>/status.json 步骤状态、结果或错误
steps/<stepId>/events.jsonl 原始事件与规范化事件、时间戳
steps/<stepId>/0.input.txt 实际发送的输入;补答递增编号
steps/<stepId>/0.output.txt 当前回答
steps/<stepId>/schema.json 结果 schema(如有)进程突然退出可能留下 running 记录,它不证明任务还在运行,也不证明未产生副作用。需要结合 CLI/产物核实。
错误导出:AgentTaskFlowError、AgentProcessError、ProtocolError、AgentTimeoutError、ResultValidationError、StateError、CancelledError。
日志含提示词和工具输出,可能包含业务数据;不要提交运行目录。provider 自身的上下文窗口和压缩机制仍然有效,不保证无限记忆。
开发和归档
npm run check
npm test
npm pack --dry-runsrc/:TypeScript 库。examples/:普通 TypeScript 流程,无自定义解释器。docs/workflow-authoring.md:其他 agent 编写流程的指南。archive/python-v0.2.0/:完整 Python 实现、测试、文档、环境和运行记录。archive/agentflow/:更早的 DSL/终端版完整归档。
旧版全部保留;当前 npm 发布包只包含 dist、示例和文档,不包含归档或运行数据。现有 explore/docs/flow 研究流程未迁移。
