Skip to content

[Grok/dsh 49] Rhai 工作流执行 dsh 子代理 #181

Description

@Blackman99

Parent

#132

Ticket: 49

Status: ready-for-agent

User Stories: 48, 49(见父规格)

What to build

用户运行一个原格式 Rhai 工作流,参数进入脚本,脚本中的 agent 调用实际创建 dsh 子代理并返回结果。

Acceptance criteria

  • 使用合法复用或适配的 Rhai 执行器接入 dsh 工作流扩展,不要求用户把脚本改成 JavaScript。
  • 元数据、参数、返回值和单个 agent 调用的模型/工具配置符合参考,循环核心仍是 dsh。
  • 语法错误、无效元数据、子代理失败、无限脚本和取消能有界终止;隔离线程不能被误称安全沙箱。
  • 从用户命令到可见结果验证真实原格式脚本;并行与恢复留给后续票,未支持项明确报错。

Blocked by

Delivery contract

用户于2026-09-20批准当前测试与任务拆分。按父规格的已安装产物/真实终端和公开协议测试验收;实际实现须带适用的文档、Changeset及必要检查。ready-for-agent表示任务已定义,不表示前置任务已完成,也不授权自动开始本轮实施、购买付费资源或发布软件版本。

Activity

  1. Blackman99 commented on Sep 25, 2026

    @Blackman99
    OwnerAuthor

    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.mjs 14 项,覆盖 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 test 2382 项通过、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。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions