Repository navigation
[Grok/dsh 49] Rhai 工作流执行 dsh 子代理 #181
Description
Activity
- added a commit that references this issue
on Sep 25, 2026 Ticket 49 / #181 已合入
rewrite/grok-dsh-20260920的1b03085。参考实现的 Rhai 引擎
xai-workflow(Apache-2.0,rhai 1.25)原样放在rust/upstream/xai-workflow,唯一的代码改动是engine.rs里一处为通过 Clippy 把match改成?(行为相同),记录在rust/upstream/MODIFICATIONS和import.json。原生二进制通过隐藏子命令__workflow-engine以独立进程运行引擎,走 JSON 行协议。dsh 自带的tool-workflow被关闭,改由rust-acp-subagents注册workflow工具,代理循环仍然是 dsh。脚本使用参考格式:
let meta = #{ name, description, phases, ... }、args、agent()、parallel()、phase()、log()、complete(),返回值即结果。来源可以是内联script,也可以是script_path:必须是以meta.name命名的.rhai普通文件(拒绝符号链接,上限 1 MiB),并位于已信任的项目或$GROK_HOME/workflows中。args、累计agent_budget(默认 128,最多 1024,会超出预算的parallel()组整体拒绝)、validate_only以及各项 agent 选项的校验顺序和报错文本都按参考实现。每个agent()/parallel()项都作为真实的 dsh 子代理启动,沿用 subagent 的规划逻辑:agent_type、capability_mode(只能收窄)、model、effort(事先检查)、isolation_worktree。每次运行最多同时 32 个子代理(按机器核数下调)。结果文本包含名称、调用数与预算、阶段、日志和结果。失败和终止都有明确边界。语法错误和无效元数据在任何东西启动前拒绝;子代理失败作为结果交给脚本处理;宿主错误原样传回;永不结束的脚本由引擎的 1 亿次操作上限停止;Ctrl+C 或父回合取消会取消这次运行和它的子代理,引擎 5 秒内不退出就被强制结束,不留引擎进程。文档里明确写了这些限制只约束脚本本身,不是安全沙箱。子代理(包括工作流子代理)拿不到这个工具,调用会以
workflow_depth_exceeded拒绝;--no-subagents或[subagents] enabled = false会移除它;无头模式下的--disallowed-tools Agent也会移除它,因为它只做一件事:启动子代理。Rust 客户端的工具块显示
Workflow running: 'name' · phase · N agents (M running),结束后显示 completed/failed/cancelled 和耗时;/tasks里的子代理带workflow <name>标记。验证(全部只在 Linux 上):新增
scripts/rust-workflow.spec.mjs14 项,覆盖 args、并行、按 agent 的模型/effort/能力、信任与未信任的 script_path、语法与元数据错误、子代理和宿主失败、各项拒绝的选项、预算、validate_only、死循环、取消、嵌套拒绝、Agent 屏蔽和禁用子代理。它和rust-subagents、rust-worktree、rust-acp-protocol、rust-plugin-content、rust-plan一起跑,101/101 通过。新增scripts/rust-workflow-pty-test.py(已加入test:rust:pty)在真实终端里用暂存的 release 二进制通过:输入提示后运行项目中保存的triage.rhai(3 个并行 + 1 个汇总子代理),能看到回复、工具块标题和/tasks标记;Ctrl+C 取消运行中的工作流后没有残留引擎进程;语法错误可见;-p能运行项目脚本和$GROK_HOME/workflows中的个人脚本,--no-subagents下拒绝。rust-subagent-pty-test.py、rust-worktree-pty-test.py、rust-plugin-content-pty-test.py在最终代码上通过;rust-queue-pty-test.py和rust-plan-pty-test.py在 rebase 到 #179 之后通过,#166 合入后没有再跑。rust-plain-pipe-test.py中新增的工具列表断言通过(默认有workflow,Agent屏蔽后没有),脚本随后照旧停在沙箱步骤(本机没有 bubblewrap)。pnpm run build:rust暂存成功,为rhai_codegen补充了取自上游 VCS 修订的许可证文本。pnpm run typecheck通过。pnpm test2382 项通过、1 项失败:reference-evidence.spec.mjs在高负载下 5 秒超时,单独运行也因负载超时,与本改动无关。Rust 工作区测试中 codsh-rust 548 项通过、3 项失败,其余 crate 1043 项通过(含 xai-workflow 61 项、workflow 协议单元测试 16 项);失败的 3 项都在本改动没有触及的文件里:filesystem_sandbox.rs两项是已知的 Linux 沙箱环境限制,voice一项是已知的回环服务器时序问题。cargo fmt --check通过;strict clippy 只报filesystem_sandbox.rs的两个既有问题。未验证:macOS 与 Windows 完全没有运行过,路径解析、O_NOFOLLOW、进程终止和所有 PTY 流程都只在 Linux 上验证;本机多数其他 PTY 测试只能在 macOS 上运行。没有用真实付费模型跑过,全部使用无密钥的确定性 mock。没有与参考二进制逐项对照。参考内置的
deep_research.rhai没有运行,它依赖output_schema和临时文件。文件系统沙箱下的工作流没有端到端验证。未实现:已注册的工作流名称和目录(#184);运行视图以及恢复、暂停、停止(#183);
output_schema及 schema 校正(#182);临时文件(scratch files)、git_diff_since、模板;resume_from;fork_context(参考实现只给内置工作流);后台运行。以上都会给出明确错误。已知限制:子代理结果中的tokens_used为 0,因为 dsh 不回传子代理 token 数;每次运行的并发上限固定为 32(按核数下调),还不能配置,且不计入max_concurrent;脚本自己调用pause()会结束本次运行,无法恢复。main、npm 和默认版本都没有改动。
#182(工作流并行与预算契约)不再有未完成的前置任务。#183 仍等 #182;#184 仍等 #183;#205、#206、#210 仍等 #184。
Parent
#132
Ticket: 49
Status: ready-for-agent
User Stories: 48, 49(见父规格)
What to build
用户运行一个原格式 Rhai 工作流,参数进入脚本,脚本中的 agent 调用实际创建 dsh 子代理并返回结果。
Acceptance criteria
Blocked by
Delivery contract
用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。