龙虾

OpenClaw-native工作流程外壳:打出(JSON-First)管线和批准口.
示例
命名的工作流程获取拉动请求 gh,将其与已保存的快照相比较,并仅在更改时返回通知:
node bin/lobster.js run --mode tool "workflows.run --name github.pr.monitor.notify --args-json '{\"repo\":\"openclaw/lobster\",\"pr\":167}'"
对于可重复的自动化,在工作流程文件中放出弹壳命令,本土管线步骤,以及明确的批准/输入门. OpenClaw向用户赠送大门,并恢复其决定.
目标
- 已打入的管道(物体/阵列),而不是文字管.
- 地方先行处决.
- 没有新的认证表面:龙虾不能拥有OAuth/tokens.
- OpenClaw(或任何代理)在一步中可以引用的可编译宏来保存符.
快开始
需要更新的节点(Node.js 22)和被钉入的pnpm版本 package.json从此文件夹中 :
pnpm install --frozen-lockfilepnpm buildpnpm testpnpm lintnode ./bin/lobster.js --helpnode ./bin/lobster.js doctornode ./bin/lobster.js "exec --json --shell 'echo [1,2,3]' | where '0>=0' | json"
页:1
pnpm test运行tsc然后针对dist/。 。 。 .bin/lobster.js运行编译的条目dist/; 更改源文件后构建. 无效的工作流程文件路径被报告为输入错误( exit code 2) , 无论是否通过--file或作为一个单一位置路径( 无空白; 包含路径分隔符或结束于.lobster, (中文(简体) ),.yaml, (中文(简体) ),.yml,或.json) (中文(简体) ). 单位--mode tool,这些失败与其他解析错误使用相同的 JSON 错误信封.
进程产出限制
抓取的流程 stdout 和 stderr 默认仍然是无限的 。 设定
LOBSTER_MAX_OUTPUT_BYTES 以正整数选择到字节限制 百分比
每个进程。未设置或空意味着无限;0、负、分数,
和非数字值在进程开始前被拒绝。 这适用于
国 际 exec工作流程外壳步骤, SDK exec贝壳呼叫, GitHub 食谱, 和高格
命令。 现有 openclaw.agent 10个米B限制仍然有效;选择使用
极限可以降低.
LOBSTER_MAX_OUTPUT_BYTES=1048576 lobster run --mode tool 'exec my-command'
使用工作流程或步骤 env 限制范围:
steps:
- id: bounded
env:
LOBSTER_MAX_OUTPUT_BYTES: "1048576"
run: my-command
SDK 调用器将相同的变量设置在 new Lobster({ env: { ...process.env, LOBSTER_MAX_OUTPUT_BYTES: "1048576" } })完全达到极限的数值成功;
溢出终止进程树并返回一个没有部分错误
输出。 POSIX 封口呼叫拥有一个进程组,所以背景制作人不能
溢出后保持管道开通。 没有中止信号中继终端的呼叫
中断到该组,并保留主机现有的信号处理器或
常规中断退出状态.
图标
exec: 运行 OS 命令exec --json <command...>: 在下一阶段之前将子进程 stdout 解析为 JSONexec --stdin raw|json|jsonl: 将管道输入子进程 stdin- 两条管道都保留明确引用的空辩
exec和 SDK 数据exec使用shims保持了论据的分解而不扩大外壳. where, (中文(简体) ),pick, (中文(简体) ),head: 数据塑造head --n N一旦产生N项,就停止上游读取;--n 0不读取上游输入.pick财务报告和审定财务报表map保存字段名称,例如__proto__作为普通自己的数据字段.json, (中文(简体) ),table: 渲染器approve: 批准门(TTY 即时或--emitopenClaw一体化)
在顶级 --mode tool 管道(包括恢复和核心工具API), json 财务报告和审定财务报表 table 保存单个 JSON 信封中输入的项目,而不是写入终端输出。 在工作流程文件步骤中捕获的人类模式渲染和产出保持不变.
SDK 注销
通过一个 AbortSignal 改为 new Lobster({ signal }) 取消 SDK exec() 阶段,
包括 exec(command, { shell: true })。该信号由 clone()
并在管道恢复时转发。 中止终止运行中的孩子
进程树之前 run() 或者说 resume() 返回含有以下内容的错误结果:
终止原因 。 已经中止的信号阻止命令启动 .
import { Lobster, exec } from '@clawdbot/lobster';
const controller = new AbortController();
const pending = new Lobster({ signal: controller.signal })
.pipe(exec('node long-task.js', { json: false }))
.run();
// When the host needs to stop the command:
controller.abort(new Error('Host cancelled the command'));
const result = await pending;
自定义阶段接收信号为 ctx.signal 必须与之合作
取消他们自己的工作.
主机援引权限
使用核心的主机 runToolRequest() 财务报告和审定财务报表 resumeToolRequest() API 可以通过
ctx.assertInvocationCurrent,当主机出现时,同步回调
已经停止引用。 龙虾在内置过程,网络之前重新检查它,
和状态效应,包括在同步恢复准备之后。 继续通过
a 一个 AbortSignal 以取消已经开始的工作.
一个退休的复职人员在没有不安全发送时恢复其呼叫者的检查站 已经开始了。 一旦一个不安全的管道命令被输入,批准就会停止 即使后来的当局检查可以防止这种影响,也会消耗。 这个保守派 边界可以防止可能已经发生的重放工作。 自定义命令 和注入适配器必须在等待准备后自行检查回调 在他们自己的效果之前 SDK没有披露这个主办方合同; 不提供回调时CLI行为不变.
GitHub 食谱取消
SDK GitHub 食谱接受 AbortSignal 两者
prMonitor({ repo, pr, signal }) 财务报告和审定财务报表 prMonitorNotify({ repo, pr, signal })。 。 。 .
中止在食谱返回出错前停止运行 GitHub CLI 子程序
含有中止原因的结果。 已取消的获取不更新已保存
公关快照或发出通知.
对于人工编组的管道,将信号传递至
new Lobster({ signal }).pipe(ghPrView({ repo, pr }))。接收自定义阶段
ctx.signal 并且必须与它合作取消他们自己的工作.
工作流程文件
龙虾工作流程文件意在像小脚本一样读取:
run:或者说command:用于确定外壳/CLI步骤pipeline:对于本地龙虾阶段,例如llm.invokeapproval:跨步骤的硬工作流程门stdin: $step.stdout或者说stdin: $step.json以转发数据
lobster run path/to/workflow.lobster
lobster run --file path/to/workflow.lobster --args-json '{"tag":"family"}'
示例文件 :
name: jacket-advice
args:
location:
default: Phoenix
steps:
- id: fetch
run: weather --json ${location}
- id: confirm
approval: Want jacket advice from the LLM?
stdin: $fetch.json
- id: advice
pipeline: >
llm.invoke --prompt "Given this weather data, should I wear a jacket?
Be concise and return JSON."
stdin: $fetch.json
when: $confirm.approved
注释:
run:财务报告和审定财务报表command:等同;run:是新文件的首选拼写.pipeline:共享与 shell 步骤相同的 args/env/ results 模型, 所以以后的步骤仍然可以参考$step.stdout或者说$step.json。 。 。 .- 如果在LLM呼叫前需要人员检查站,请使用专用的
approval:在工作流程文件中步骤而不是approve在筑巢管道内. cwd, (中文(简体) ),env, (中文(简体) ),stdin, (中文(简体) ),when,以及condition用于壳和管道步骤的工作.- 使用
retry, (中文(简体) ),timeout_ms,以及on_error每一步控制瞬间故障行为和恢复. - 打开
for_each,这些政策覆盖整个循环:每次尝试都得到一次超时预算(包括批量暂停),并在第一个项目中重试重启. 以前完成的儿童可能再次跑步,因此只能让循环重复安全的工作。 A 类cost_limit停止或尝试的 OpenClaw 调度可以阻止重试; 即使在后期的管道命令失败时, 仍会检查已付的 LLM 使用情况 .on_error: continue记录$loop.error进入下一个工作流程步骤;skip_rest跳过剩下的工作流程步骤. - 批准步骤可以选择性地执行身份限制:
approval.required_approver(或requiredApprover)需要准确的核准人id.approval.require_different_approver(或requireDifferentApprover)要求批准人id不同于发起人.approval.initiated_by(或initiatedBy)设置发起人身份以进行比较.LOBSTER_APPROVAL_INITIATED_BY可以在运行时提供默认发起人 id.LOBSTER_APPROVAL_APPROVED_BY在恢复/批准时用于身份检查.
OpenClaw 发送后重试
openclaw.invoke (包括 clawd.invoke和 openclaw.agent 一旦尝试发送, 即停止自动工作流程步骤重试 。 这适用于超时,HTTP或处理失败,以及同一管道步骤的后继命令出错,即使 retry.max 大于一个。 本地请求失败无法确定远程动作是否已经完成 。 只读和干跑请求使用同样的保守规则:龙虾不知道远程工具的再试保证 OpenClaw 网关目前被忽略 dryRun。旗帜不妨碍工具执行。 在再次手动运行步骤前检查远程结果 . llm.invoke 保留其现有的重试政策.
命令级的输入请求
管道命令可以调用 ctx.requestInput({ prompt, responseSchema, defaults, subject, suspendedState }) 在工具模式、工作流程或SDK中暂停,并在结构化响应后恢复同一命令。 CLI/tool恢复符只存储一个状态密钥;持续状态在返回提交回复到命令之前验证被中止的请求元数据. SDK同名指令恢复将命令框存储在所配置的SDK状态目录中.
命令在恢复时重新运行,所以它们必须是一能的,直到 requestInput 返回。 组合后的命令输入会被带边框来进行回放;懒散的流输入不会被缓冲,需要紧凑的 JSON suspendedState 由指挥部提供。 复会时打电话 ctx.requestInput.getSuspendedState() 在读取懒惰的输入之前 恢复命令的延续状态.
可视化工作流程
使用 lobster graph 在执行前检查工作流程结构.
lobster graph --help
lobster graph --file path/to/workflow.lobster
lobster graph --file path/to/workflow.lobster --format mermaid
lobster graph --file path/to/workflow.lobster --format dot
lobster graph --file path/to/workflow.lobster --format ascii
lobster graph --file path/to/workflow.lobster --args-json '{"location":"Seattle"}'
何为可视:
- 每个工作流程步骤作为节点(
run, (中文(简体) ),pipeline, (中文(简体) ),approval页:1 - 数据流边缘
stdin: $step.stdout编号 :$step.json参考文献 - 有条件的依赖性来自
when:编号 :condition:表达式 - 作为钻石形状节点的核准闸门
mermaid财务报告和审定财务报表dot产出
格式注释 :
mermaid(默认):发射flowchart TDgitHub/ Markdown 渲染文本dot: 发布 Graphviz DOT 语法ascii: 发布一个方便终端的节点/接口列表
从工作流程调用法学硕士
使用 llm.invoke 来自本地 pipeline: 用于模型辅助工作的步骤:
llm.invoke --prompt 'Summarize this diff'
llm.invoke --provider openclaw --prompt 'Summarize this diff'
llm.invoke --provider pi --prompt 'Summarize this diff'
提供者解析命令 :
--providerLOBSTER_LLM_PROVIDER- 从环境自动检测
今天内建的供应商:
openclaw通过OPENCLAW_URL编号 :OPENCLAW_TOKENpi通过LOBSTER_PI_LLM_ADAPTER_URL(通常由Pi扩展提供)http通过LOBSTER_LLM_ADAPTER_URL
OpenClaw 适配器呼叫网关 llm-task 工具:文物变成 input,以及 --max-output-tokens 变成 maxTokens它从工具读取 JSON details.json 结果. --output-schema 包含在模型中,即时并在当地验证,因此 --max-validation-retries 仍然控制重试,包括验证反馈. 网关出故障时不进行验证重试。 该工具目前不返回令牌使用量,因此这个适配器无法估计这些调用的开支或执行以令牌为基础的成本限制.
主机嵌入龙虾可以通过 ctx.llmAdapters步骤 timeout_ms 和工作流程取消到达适配器为 ctx.signal: 龙虾一旦信号中止就停止等待,所以该步骤失败或者在任一方式上及时重试,但它不能取消一个适配器已经启动的工作. 注入的适配器应当观察 ctx.signal 并中止它自己的请求——否则一个超时步骤可以留下一个模式调用运行,并在背景中计费.
工作流程 _meta.cost 财务报告和审定财务报表 cost_limit 使用静态定价表加从 LOBSTER_LLM_PRICING_JSON,例如 {"my-model":{"input":1.0,"output":2.0}} 单位:百万令牌美元。 未知或缺失的型号ID仍然以零估算成本记录了符号计数,但龙虾在stderr上发出警告,如此僵硬或缺失定价不会默默地失败.
缓存或重放的答案不再计费:模式调用一次,在完成的运行中,无论后来的很多步骤都重播它的答案. 当答案停留在龙虾体内时,它会保持: 通过管道, 渲染器,预测,运行状态, workflow: 步骤和简历。 它无法活过将物品交给外部过程并读回来的阶段—— exec --stdin json --json ... ——因为复出的东西是那个过程所印刷的,而龙虾不能告诉一个忠实的复出副本从一个新的声称中得知是打过电话的. 这一步骤被记为一项呼吁,这是早先版本在各地所做的。 A 类 workflow: 步骤计算其子工作流程花费多少,重放返回的子工作流程不会被构成它的运行第二次计费. 花费也活过一个暂停——一个在批准时停止的工作流程或 input 门保持它的记录,所以 _meta.cost 覆盖整个运行之后的简历和 cost_limit 适用于整个跑道,而不是最后一道门后的步骤.
llm_task.invoke 仍可作为OpenClaw供应商的后相配别名.
调用已配置的 OpenClaw 代理
使用 openclaw.agent 当工作流程需要配置的 OpenClaw 代理而不是直接的模型调用时:
openclaw.agent --agent ops --prompt 'Summarize these logs'
openclaw.agent --agent ops --session-key incident-42 --model openai/gpt-5.4 --prompt 'Continue the investigation'
命令代表代理身份、模型默认和覆盖、会话、认证和执行到已安装 openclaw agent CLI(英语:CLI). 它接受 --agent, (中文(简体) ), --session-key, (中文(简体) ), --session-id, (中文(简体) ), --model, (中文(简体) ), --thinking, (中文(简体) ), --timeout,以及 --local,返回 OpenClaw 结构 --json 反应。 管道输入被附加在被标记为JSONL的提示上.
pipeline: 对 run: 用于 LLM 呼叫
- 使用
pipeline:页:1openclaw.agent, (中文(简体) ),llm.invoke,以及llm_task.invoke(它们是龙虾管级,而不是可执行壳). - 使用
run:仅用于您外壳中的真实二进制( 例如)openclaw.invoke) (中文(简体) ).
示例stdin 从前一步作为文物传给LLM:
steps:
- id: make_words
run: echo "One two three four five six"
- id: count_words
pipeline: llm_task.invoke --prompt "How many words have been pasted below?"
stdin: $make_words.stdout
从工作流程调用 OpenClaw 工具
贝壳 run: 在您的系统 shell 中执行步骤, 因此 OpenClaw 工具调用时, 必须有真正的可执行文件 .
如果您通过npm/pnpm安装了龙虾,它会安装一个名为:
openclaw.invoke(首选)clawd.invoke(别名)
这些闪电推进到同名龙虾管道指挥部.
示例: 引用 llm 任务
总理:
OPENCLAW_URL运行中的 OpenClaw 网关的点数- 可选择
OPENCLAW_TOKEN如果启用了认证
export OPENCLAW_URL=http://127.0.0.1:18789
# export OPENCLAW_TOKEN=...
在工作流程中:
name: hello-world
steps:
- id: greeting
run: >
openclaw.invoke --tool llm-task --action json --args-json '{"prompt":"Hello"}'
在步骤之间传递数据( 无临时文件)
使用 stdin: $stepId.stdout 从一步到下一步的管道输出.
标记和外壳安全
${arg} 替换是一个原始字符串替换到 shell 命令文本中.
对于任何可能包含引用, $,回击,或新线, 更喜欢env vars:
- 每个已解析的工作流程参数被曝光为
LOBSTER_ARG_<NAME>(上行,非上行)_(中文(简体) ) - 完整的参数对象也可以作为
LOBSTER_ARGS_JSON
示例
args:
text:
default: ""
steps:
- id: safe
command: |
jq -n --arg text "$LOBSTER_ARG_TEXT" '{"result": $text}'
数值在一个 env: 块没有扩展外壳,所以 TEXT: "$LOBSTER_ARG_TEXT"
套装 TEXT 到字串。 要用另一个名称传递一个参数, 请使用
TEXT: "${text}"; env值从不穿透外壳,所以这个值保持安全.
HTTP 响应限制
HTTP 响应机构默认仍然是无限的. 设定
LOBSTER_MAX_HTTP_RESPONSE_BYTES 改为正整数,以选择一个偶应
字节限制 openclaw.invoke编号 :clawd.invoke 和内置的 OpenClaw, HTTP,
和 Pi 键 llm.invoke 适应器. 未设置或空表示无限;无效或非正数
值在发送前失败 。 主机被注入的适配器拥有其运输极限.
LOBSTER_MAX_HTTP_RESPONSE_BYTES=1048576 lobster run --mode tool 'openclaw.invoke --tool example --action read'
工作流程和步骤 env 可以设置相同的变量。 SDK集成器传入
环境状况new Lobster({ env: { ...process.env, LOBSTER_MAX_HTTP_RESPONSE_BYTES: "1048576" } }) 或工具运行时上下文).
答复恰好达到了极限。 过多的申报或流体
在 JSON 解析前被取消和拒绝; 没有返回部分答复.
限制数为响应流读取的字节数, 包括已解压
内容。 超过限制的宣布内容-Length也立即被拒绝.
工具发送在溢出后仍不可重复,与其他一样
发送后错误; llm.invoke 保留其现有的重试政策.
发展
来源为一款TypeScript包. src/core 包含可嵌入工具API、成本跟踪和LLM核算; src/sdk 提供管道构成; src/commands 拥有命令注册和标准库。 工作流程加载、表达式、干跑渲染以及执行均在 src/workflows。 。 。 . src/state 拥有原子文件的持久性,锁和还原能力. GitHub SDK配方和内置工作流程共享传输和快照帮助.
运行 pnpm test, (中文(简体) ), pnpm typecheck,以及 pnpm lint 在提交更改之前。 编译为 dist/test 并使用Node的测试跑道; 平台特定流程测试仅在其OS原始存在的地方运行. 家属遵守两天释放年龄政策的情况 pnpm-workspace.yaml。 。 。 .
验证当前释放容器 main 不发布, 运行 gh workflow run lobster-npm-release.yml --ref main -f tag=v$(node -p "require('./package.json').version") -F dry_run=true。这将构建选定的承诺,并跳过出版、推广和上传可推广的文物。 现有 preflight_only 模式仍然为以后的推广构建所要求的释放标记.