Skip to content

[Grok/dsh 50] 工作流并行与预算契约 #182

Closed

Description

@Blackman99

Parent

#132

Ticket: 50

Status: ready-for-agent

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

What to build

用户运行并行 Rhai 工作流时,实际子代理数量、并发、预算和结果排列符合既定规则。

Acceptance criteria

  • 覆盖参考 host 调用和组合器的公开输入/输出、schema 校正、错误传播及排序契约。
  • 累计 agent 预算与活跃并发限制独立;会超预算的并行组按参考整体拒绝,不先启动一半。
  • 子项失败、异常、取消及资源耗尽不泄漏子代理,也不把未执行子项标为成功。
  • 使用真实 dsh 子代理与受控模型证明并发、限额和最终结果,补足跨权限入口测试。

Blocked by

Delivery contract

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

Activity

  1. Blackman99 commented on Sep 25, 2026

    @Blackman99
    OwnerAuthor

    Ticket 50 / #182 已合入 rewrite/grok-dsh-20260920 的 ede08cc。

    行为

    • 参考宿主契约放在新的 rust/src/workflow_host.rs,由工作流引擎执行,错误文本与参考实现一致:
      • output_schema 用参考版本的 jsonschema crate(=0.30.0)编译。无效 schema、外部 $ref、超过 256 KiB 的 schema 在子代理启动前拒绝。
      • 子代理提示词末尾附加参考的 <output-contract>;答案按 ```json 块 → 全文 → {…}/`[…]` 的顺序解析。
      • 不符合时,对同一个 dsh 子代理续发一次参考纠正提示(子代理保持打开,resume_agent → close)。仍不符合则 success: false,output 为 structured output validation failed: …。
      • 通过时 output 为解析后的 JSON,agent_id 不变。重试不计入 agent_budget。
    • write_scratch_file / read_scratch_file:
      • 文件位于 $GROK_HOME/sessions/<项目>/<会话>/workflows/<调用>/scratch。
      • 参考限制:单个文件名、每个文件 10 MiB、最多 64 个文件、总计 64 MiB、拒绝符号链接、原子写入。
    • git_diff_since(commit):先检查提交哈希,20 秒超时(超时会杀掉 git),输出上限 256 KiB。
    • 并发与预算:
      • 同时运行上限可用 [subagents] workflow_max_concurrent 或 GROK_WORKFLOW_MAX_CONCURRENT_AGENTS 配置(环境变量优先;默认 32,按机器核数收紧),codsh --rust inspect 会显示。
      • 这个上限与累计的 agent_budget 相互独立:比上限更宽的并行组会排队,每一项仍计入预算;超出剩余预算的并行组整体拒绝,一个子代理也不启动。
      • 每次运行最多启动 2048 个代理(含重试)。
    • 失败与清理:
      • 失败或被取消的子代理返回 success: false;被宿主拒绝的子代理(未知或已禁用的类型)在 parallel() 结果中为 ();从未启动的子代理不会被标为成功。
      • 取消时,排队中的子代理不会启动;运行中的子代理以 cancelled 结束。
      • 引擎异常退出时报 workflow_engine_failed,所有子代理随之结束。
      • 保持打开的契约子代理在运行结束、失败或取消时全部关闭。
    • resume_from 仍明确拒绝。

    验证(全部只在 Linux 上)

    • cargo test -p codsh-rust:570 通过 / 3 失败。3 个都是已知的既有失败(2 个 filesystem_sandbox、1 个 voice 假服务器测试),与本票无关。
      • workflow 过滤:28/28。
    • 其余 workspace crate:1043 通过 / 0 失败。
    • clippy(-A dead_code -A clippy::needless_return)无告警;cargo fmt --check 通过。
    • pnpm test:2408 通过 / 1 失败(91 个文件)。失败的是已知的 reference-evidence.spec.mjs 5 秒超时。
    • scripts/rust-workflow.spec.mjs:22/22,与 rust-subagents.spec.mjs 合计 35/35,rebase 前连跑 3 次。用真实 dsh 子代理和受控 mock 模型覆盖:
      • schema:一次通过、同一子代理重试后通过、重试后仍失败、无效 schema 拒绝;
      • 上限 2 下 5 个并行子代理实测峰值为 2;预算与上限相互独立;超预算的并行组整体拒绝;
      • 失败混合;取消时排队项不启动;杀掉引擎后无残留子代理;
      • scratch 路径与 git_diff_since;
      • 权限入口:ask 模式批准/拒绝、deny 规则、capability_mode、禁用类型;原有的 deny:Agent、allow 列表和 --no-subagents。
    • pnpm run build:rust 通过(含许可证检查)。
    • 以下 PTY 测试在 rebase 后全部通过:workflow(新增 headless 场景:config 上限 2、环境变量上限 3、schema 重试、scratch 文件)、subagent、background、worktree、queue、plan、plugin-content。

    未验证

    • macOS、Windows。

    未实现 / 已知限制

    • resume_from 未实现:dsh 子代理结束后即被释放,也没有用已结束会话为新子代理提供种子的接口。
    • tokens_used 仍为 0。
    • 开启 isolation_worktree 的契约子代理,其 worktree 说明只出现在任务视图的结束事件里,不会附在返回给脚本的结果中。
    • 引擎的操作数与大小限制不是安全沙箱。

    main、npm 和默认版本都没有改动。

    后续:#183 的两个前置任务(#152、#182)现已全部关闭,可以开始。#184 仍等待 #183。

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