@ clemrig/ 流量
在 TypeScript 中写入代理工作流程并运行 克劳德代码, (中文(简体) ), 代码 或者说 Pi。 。 。 .
工作流程是一个清晰的图表: CODE 代码 阶段(你的代码), 高级 (由 Claude 代码、 Codex 或 Pi 操作的代理)和 目标 阶段,即接受结果或将结果发回更正时,限定次数。 这个软件包是引擎:用于写入工作流程的API,其执行,代理运行时间和运行. @clemrig/factory 在此基础上建立一个命令,在存储器自己的工作流程之外,从光谱到调取存储器的问题; @clemrig/flow-ui 在本地仪表板中显示运行.
所需资源
macOS或Linux,节点.js 24或后. 对于剂相 claude (二) CLI(2.1.296或以后) codex CLI(0.160.1或以后,在Git仓库中)或 pi (一.1.0或后期) PATH,与其供应商连接。 每个代理都使用机器自己的CLI配置,加上其配置配置设置(一个 Claude 代码配置文件可以将用户的设置文件留下 settingSources 和机器的MCP服务器 mcp: "profile"),一个克洛德代码(Claude Code)的呼叫也等待代理的子代理,无论他们停留在闲置的时间,在配置的超时(CCLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0),其中打印模式会在10分钟后阻止它们并降低结果. 代理的回答结束调用:克劳德代码在那里被停止了,任何在背景中留下的代理运行的命令,如dev服务器,舞台的日记盘计算它们. Claude代码代理的每个命令都登记它运行的流程组,这样不管它留下什么运行,都与 & 或者说 nohup 包括,以电话结束,无论结束什么:这需要一个 ps 在运行前检查。 引擎从不读取或存储证书.
运行工作流程
npm install @clemrig/flow
import { defineWorkflow, END, node, startRun, step, z } from "@clemrig/flow";
const hello = defineWorkflow({
name: "hello",
input: z.object({ name: z.string().min(1) }),
initial: "greet",
nodes: {
greet: node(
step(async ({ state }) => ({ greeting: `Hello ${String(state.input.name)}` })),
{ ok: END },
),
},
});
const run = await startRun(
{
workflow: hello,
input: { name: "flow" },
prompts: async () => ({}), // prompt texts by name, for agent stages
dir: process.cwd(), // where stages and agents work, until a stage moves the run; given to stages as `dir`
configDir: process.cwd(), // where relative skill, extension and MCP paths of profiles resolve
},
{ onEvent: (event) => console.log(event.type, event.stage) },
);
const state = await run.done;
console.log(state.status, state.data);
工作流程可以宣布 steps: 命令其阶段的分组, 以显示跑多远, 例如 steps: [{ name: "greet", stages: ["greet"] }]。 。 。 . defineWorkflow 拒绝台阶,除非它们给每个台阶命名一次,并精确地保持每个台阶一次;发动机本身忽略了它们,而工厂的坎班显示它们.
在它创造运行之前, startRun 检查,按照这个顺序, dir 预算(现有目录)maxCostUsd,以美元表示,取代工作流程;当代理阶段使用宣布不收费的Codex时,拒绝,输入与工作流程相对应 input (单位:千美元) InvalidInputError 列表每个问题),提示(每个代理阶段的提示的非空文本),以及工作流程使用的每次运行时间,其版本和检查过的连接 dir; 第一次失败的检查以它的理由拒绝了它。 然后记录发射情况(a) launch 事件: 流程的版本 caller 所给出的标签,如一个呼叫器的版本以及它的提示来自何处,每次运行时间如检查,有效的预算以及它是否得到,运行本身或工作流程的,机器, dir,且运行时间所读取的变量名称设定,从不包含其值)并返回运行,其结束(done和 stop(reason),在下一个阶段前失败。 运行被保存在 runsDir 当它被赋予。 引擎从不改变进程当前目录: 舞台码通过工作目录 dir,然后运行自己的文件夹通过 runDir,用于保存属于运行的文件。 一个舞台通过返回移动运行 dir,一个现有目录的绝对路径:它的下一阶段和代理人在那里工作,当它恢复时运行也是如此(state.dir,在目录中的运行工作开始或恢复时缺席;舞台的活动也保留它。 一个给出相对路径或没有目录失败的阶段,其数据会下降. 一个代理的对话在它开始的目录中继续,因为一个运行时间如克洛德代码(Claude Code)保存它每个目录:在对话之间移动运行,而不是在一个过程中. 当子进程运行(代理,命令)时,一个SIGINT或SIGTERM到程序会打断它们,每个代理都带有它结束自己命令的信号,这样没有哪个代理能够活过它,并且在下一个阶段之前停止运行,即使一个阶段抓住了中断. runCommand(argv, { cwd, timeoutMs, signal, env, onLine, stdin, output }) 实值 runProcess'完整形式 : signal 停止程序, 包括程序进程组, 一旦程序中断, 不失败, 如服务器, 它的调用器不再需要, 然后不需要 timeoutMs· ; output 将程序所写的,包括的错误附加到一个文件,而不是抓取它. 即将退出的程序可以立即调用 killChildProcesses(),它杀死了每跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑跑.
resumeRun({ workflow, runId, maxCostUsd, data, prompts, dir, configDir, runsDir, caller }, hooks) 在停止运行的阶段恢复失败运行,同时使用相同的ID,输入,数据,校正,措施和代理谈话:该阶段再次运行,日记为何停止运行(Resumed after: …),并传递给它的代理人,它被要求继续而不是重新开始. 它拒绝, 改变不了, 一个没有失败的跑步( 左跑) running 在它的程序被杀死之后),运行另一个工作流程,一个工作流程不再拥有的阶段,一个已经花费了预算的运行,一个运行阶段移动到一个已经不存在的目录,以及不管工作流程的可选性 resumeProblem({ state, dir }) 返回时, dir 运行的地方,例如一个工作目录,它不再是舞台留下的;然后它检查提示和运行时间,如 startRun,将运行完成(两次恢复从未同时运行过:状态重新加载并标记) running a 项下 run.lock 文件在运行文件夹中以原子方式创建,以给出的值记录发射,并返回相同的控件。 预算是 maxCostUsd 给定的,否则运行开始或最后恢复运行(state.maxCostUsd),否则工作流程的. 舞台从头开始:它失败前所做的一切必须能够安全地再做,或者 resumeProblem 必须拒绝. data 给出运算符决定的运行值,在阶段再次运行前合并到其数据中,由 resumeProblem 并在《日刊》中注明名称。 在每次恢复时,可以对该边缘再作一次修正(state.allowances· ; exceededEdge(workflow, state) 名字的边缘, <stage>.<outcome>数字 : state.exceeded,或者对于在引擎保留它之前停止的跑道,其舞台的边缘,如果一个错误是:舞台再次运行,如果它再次要求改正,它就把它拿走;它不能取的改正被保存在它失败的舞台事件上 feedback。每个已完成的阶段活动也带有其代理人的答案(output和它发回的更正feedback) (中文(简体) ). 在恢复之前宣布不支付任何费用的呼吁(因暂停而停止的呼吁)不再辜负预算;后来的呼声也是如此。 停止运行的时间不属于其持续时间(state.pausedMs时 elapsedMs) (中文(简体) ).
各个阶段、门、校正、代理配置、会话和提示在“Write a group”的一节中有所描述 @clemrig/factory读取; 从 @clemrig/flow 在这里。 上面写的是什么 .factory/,提示文件和 factory run 选项属于工厂: 仅凭引擎, 程序会给出输入、 即时文本和目录 startRun。 。 。 .
运行
每次运行都保持 state.json, (中文(简体) ), events.jsonl 和每一次代理通话,记录在 calls/<n>.json (工作流程的即时,请求作为运行时间读取它,带有即时的指令,子代理的定义和MCP服务器的配置被所取名称和请求所添加变量的名称所取代)env),绝不是他们的值,而是由什么请求命名而不是发送(omitted: Claude Code 对话中, 已经持有一个很长的数值, 并且没有变化 # Already received,而不是再次显示值),会话在运行时间宣布一个时确认的配置,一个成功的调用错误输出的结束,以及代理商的最终文本)在自己的文件夹中表示: runsDir,默认情况下 .flow/runs/ 联 合 国 dir当引擎创建时 .flow/它写着 .gitignore 它忽略了其中的一切:运行持有投入,代理输出和日记,并保持隐私. listRuns(runsDir), (中文(简体) ), loadRun(runsDir, id), (中文(简体) ), loadRunEvents(runsDir, id), (中文(简体) ), loadAgentCall(runsDir, id, n), (中文(简体) ), summarizeRun(state), (中文(简体) ), summarizeCorrections(state, events) (每一次重试取出边缘,最多记录其事件)和 presentResult(workflow, state) (任何带有 presentResult 取代工作流程;没有工作流程,验证数据为JSON)读取; flow-ui 给他们看看.
许可证
麻省理工学院