feat(maker-core): add optional Grok Build ACP harness - #3479
Conversation
|
| Filename | Overview |
|---|---|
| packages/maker-core/src/agents/grok-build/index.ts | 实现 Grok Build 会话初始化、ACP 事件转换、权限响应、首事件派发确认和失败清理;此前生命周期问题在当前实现中已修复。 |
| packages/maker-core/src/agents/grok-build/auto-review-policy.ts | 将 ACP 工具映射到共用 Auto-review,并在拒绝选项缺失时返回 null 以保持 fail-closed。 |
| packages/maker-core/src/agents/grok-build/stdio-transport.ts | 实现 Grok ACP 子进程 stdio transport,并在 SIGTERM 无效时定时升级为 SIGKILL。 |
| apps/desktop/src/main/maker-host/grok-build-host.ts | 根据 PATH 可选注册 Grok Build,接入 CLI 登录、API key 认证探测和本地进程监控。 |
| apps/desktop/src/shared/agentKindConversion.ts | 将 grok-build 纳入 Maker 与数据库 agent kind 的双向转换,避免会话静默归类为 Claude Code。 |
| packages/maker-core/src/agents/grok-build/tests/grok-build-session.test.ts | 覆盖初始化失败清理、首个更新确认派发以及 prompt 更新前后失败语义。 |
| packages/maker-core/src/agents/grok-build/tests/grok-build-stdio-transport.test.ts | 覆盖忽略 SIGTERM 时升级 SIGKILL,以及正常退出时不误发 SIGKILL。 |
Sequence Diagram
sequenceDiagram
participant UI as Cindy UI
participant Maker as Maker
participant Grok as GrokBuildAgent
participant ACP as grok agent stdio
UI->>Maker: 创建 grok-build 会话
Maker->>Grok: startSession()
Grok->>ACP: initialize + session/new
UI->>Maker: send(message)
Maker->>Grok: send()
Grok->>ACP: session/prompt
ACP-->>Grok: 首个 session/update
Grok-->>Maker: 确认 turn 已接收
ACP-->>Grok: 后续事件或终态
Grok-->>Maker: 标准化 AgentEvent
Maker-->>UI: 状态、文本、工具及终态事件
Reviews (2): Last reviewed commit: "fix(grok-build): resolve the grok binary..." | Re-trigger Greptile
|
关于 #3027 上 bot 的判断:那段里「不要为了包一层 Grok 模型 再造第四套 loop」我同意,也不是本 PR 在做的事。 #3027 原文更像「Pi 上的 Grok 体验」(SuperGrok / xAI API 当模型来源)。那个路径 Cindy 已经有了: 本 PR 接的是独立 runtime:Grok Build(本机
Pi + xAI Responses 表达不了 Grok Build 自己的 plan / 并行 subagent / worktree,也复用不了本机已登录的 Grok Build 会话。没有 所以:#3027 的 Pi profile 建议可以继续单独做;本 PR 回答的是 bot 那句「先补契约再决定是否新增 agentKind」。 |
|
@yuchenlin 👋 这个 PR 还有 1 条 review conversation 没 resolve(packages/maker-core/src/agents/grok-build/auto-review-policy.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
|
这个 PR 需要维护者确认后才能继续落地。 它新增了可选的 Grok Build ACP harness,并改到新建任务 / 设置 / 调度等用户可见入口,同时带规则文档和跨包契约,不属于存量 bugfix。 请维护者直接在本 PR 上 Approve;如果范围或交互需要改,请 Request Changes。确认方式见讨论 issue:#3480 |
Greptile on makecindy#3479 — deny without reject_* cancels instead of picking allow; startSession closes ACP on init failure; SIGKILL after SIGTERM uses exit, not child.killed; send returns on turn acceptance not prompt completion. Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
|
命中 UI 路径(apps/desktop/src/renderer/cindy-brain/GhostErrandPrefs.tsx / apps/desktop/src/renderer/components/icons/GrokBuildMark.tsx / apps/desktop/src/renderer/components/new-chat/PermissionSelector.tsx 等)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范 |
|
更新一轮,把 CI 全红的原因和一批编译期不报、运行期串台的问题一起收掉了。两个新 commit:
验证(命令与结果在 description 里):desktop / mobile typecheck 0 error;五个 i18n 与守门脚本全 PASS;maker-core grok-build 30、maker-shared 972、model-providers 670、lizi-mcps 671、mobile 3896 全通过。desktop 全量有 10 个文件失败,逐个在不含本 PR 任何改动的分支上跑同一组,9 个以完全相同的报错失败(DB harness 漂移 + BillingPage 日期格式化),第 10 个单独跑通过,是并发超时抖动——与本 PR 无关。 description 已按模板重写,「UI 变化」附了新身份标识的 HTML 复现与引用的规范章节(§10 语义豁免色 / §4 / §11),风险段补了 SQLite 数据形态与降级口径(旧版本读到 还需要维护者拍板的两处,我没有替你们决定:
|
|
@yuchenlin 👋 这个 PR 目前与 请在本地 merge 最新的 |
|
@MagicLizi 冲突已解决, 冲突本身只有一处、是 import 顺序: merge 之后又跑了一遍全套校验,发现 main 的新代码与本 PR 拓宽的
merge 后复验: 顺带记一个基线数据:把 |
|
@greptile-apps 回一下那条 Confidence 1/5 的判断——四条阻塞项都是针对首个 commit 1. deny 回退可能 fail open(auto-review-policy.ts) return behavior === 'allow' ? options[0]?.optionId ?? null : null; // auto-review-policy.ts:94调用方把 if (!optionId) return { outcome: { outcome: 'cancelled' as const } }; // index.ts:373测试: 2. 初始化失败遗留子进程(index.ts) } catch (err) {
...
await client.close('startSession failed'); // index.ts:258-260测试: 3. 误用 child.killed 导致 SIGKILL 升级失效(stdio-transport.ts) try { child.kill('SIGTERM'); } catch { /* already gone */ } // :160
... try { child.kill('SIGKILL'); } catch { /* already gone */ } // :152测试: 4. send 等完整 turn 才算 acceptance 另外这一轮还修了四类你当时没看到的问题(CI 在更早的 现在全流水线绿: |
MagicLizi
left a comment
There was a problem hiding this comment.
Thanks For the New Featrue ~ I think Can GoOn
MagicLizi
left a comment
There was a problem hiding this comment.
Grok Build 作为可选 runtime 已经能创建/选择,但几条真实 IPC 入口仍按三家 harness 拒绝,用户走不通。请先补齐这些门,再 rebase 当前 main(账号切换 API 会被这版 preload 删掉)。
P1×4(均已对照 head f358156 复核):
-
apps/desktop/src/main/maker-ipc/register.ts:13680 —
requireQueuedMessage仍只认claude-code|codex|pi。Composer 发送走INPUT_ENQUEUE,grok-build 会话会INVALID_PARAMS。请把'grok-build'纳入校验,并加 enqueue/send 测试。 -
apps/desktop/src/main/maker-ipc/register.ts:2084 — 本地
requireAgentKind仍是三值,却被GET_CAPABILITIES/LIST_AGENT_COMMANDS/LIST_AGENT_SKILLS/SCAN_AT_RESOURCES/LIST_CUSTOMIZATIONS使用;renderergetCapabilities('grok-build')已接线。权限模式、rewind/fork、模型、/命令、@资源都加载失败。请拆出「仅草稿三家」与完整AgentKind两套 helper。 -
apps/desktop/src/main/maker-ipc/authHandlers.ts:21 —
AGENT_KINDS仍是三家,但useVendorAuthGate会maker.auth.triggerLogin('grok-build')。未认证弹窗无法启动grok login。请把'grok-build'加进 IPC 枚举(device-code/ownerId 可继续只给 Codex)。 -
apps/desktop/src/preload/preload.ts:1868 — 相对当前
origin/main,本 PR 会删掉authListAccounts/authSyncAccounts/authSwitchAccount/authBeginAddAccount/authCancelAddAccount(#3505 已在 main)。与 Grok Build 无关,合进去会拆掉账号切换桥。请 rebase/merge 当前 main 并保留这些方法。
修完后不需要逐条回复本评论;push 新 commit 即可,下一轮会重审。
Register AgentKind 'grok-build' as a Pi-style optional runtime. Detect the local grok CLI on PATH, speak ACP over `grok agent stdio`, and leave Claude Code / Codex / Pi untouched when grok is missing. Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
Greptile on makecindy#3479 — deny without reject_* cancels instead of picking allow; startSession closes ACP on init failure; SIGKILL after SIGTERM uses exit, not child.killed; send returns on turn acceptance not prompt completion. Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
…ype gaps - add the 16 missing zh-TW keys so the five common.json files match again - run the fake grok ACP server through a generated sh wrapper on the current node instead of a bun shebang; skip the group on Windows like the Pi tests - keep grok-build out of the mobile new-session fail-open list: it only exists when the controlled device has grok on PATH - widen the mobile agent-kind unions, the vendor icon and the label helpers so a grok-build session is not rendered as Claude Code - fix the grok-build type gaps tsc caught: thought block ctx key, ACP toolCall and content narrowing, turn-accept state across closures Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
…implied Widening AgentKind to a fourth runtime left ~106 desktop type errors that CI never reported: verify-checks failed at check-i18n and stopped before typecheck. Fixing them surfaced silent mislabels too. - persist the real kind: agentKindConversion mapped anything unknown to 'cc', so a Grok Build session was written to sessions.agent_kind as Claude Code and read back as Claude Code. Same class of bug in the auto-title target, the context-rebuild card stamp and the task summary. - render the real identity: VendorIcon now draws the GrokBuildMark this PR added but never wired up, and MobileVendorIcon stops announcing a Grok Build session as Claude Code. - fail closed where the runtime cannot follow: rewind and fork refuse a grok-build session instead of falling through to the Claude checkpoint and message-uuid paths; the model plane, reference prices and catalog seeds keep their three-agent shape and exclude it explicitly. - widen the local duplicates of the agent unions everywhere else, so the desktop typecheck is clean again Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
Merging main surfaced two places where the widened AgentKind leaked into domains grok-build does not belong to: the XD gateway model projection (a server protocol type that mirrors ModelAccessGatewayModel) and the new-chat product default tuple seeds (provider-routed models only). Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
…ath rules resolveGrokBinaryFromPath took the delimiter from the injected platform but joined with the host's path module, so a posix PATH fixture produced backslash candidates on Windows and the lookup returned null. Pick both the delimiter and the join from the same platform, and cover the Windows .cmd shim that npm installs. Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
Composer send, capabilities/commands/skills/@/customizations, and auth login still rejected anything outside the original three harnesses. Split the wire helpers: session-facing gates accept the full AgentKind union (including grok-build); New Maker draft slots stay three-vendor. Auth triggerLogin can now start `grok login`; device-code and ownerId remain Codex-only. Signed-off-by: Bill Yuchen Lin <10104354+yuchenlin@users.noreply.github.com>
f358156 to
f22311e
Compare
这些问题已在当前 head 的后续 commit 中修复(格式门/安全门已通过),自动 dismiss 旧的 CHANGES_REQUESTED 以解除合并阻塞。
这次改了什么
摘要
把 xAI Grok Build(本机
grokCLI)做成 Cindy 的第四个可选 runtime(AgentKind = 'grok-build'),装配方式对齐 Pi 的buildXAgent() | null:PATH 上没有grok时不注册、选择器隐藏,Claude Code / Codex / Pi 不受影响。协议是 ACP(
grok agent stdio,JSON-RPC 2.0 带jsonrpc: "2.0"),不是 Pi RPC,也不是把目录里的xai/grok-*模型当成本需求。权限档从严到宽为[ask, auto, bypassPermissions]:ask 走 ACP 审批;auto 走 Cindy 共用 Auto-review(不用 grok 的--always-approve/autoMode);bypass 才grok agent --always-approve stdio且_meta.yoloMode: true。探测只看 PATH,不读~/.grok/auth.json,不复用 SuperGrok OAuth,不钉 CDN 二进制。后两个 commit 补的是「把 AgentKind 拓宽这件事做完」:首版把共享
AgentKind联合类型加了第四个成员,但依赖它的调用点没跟上,pnpm --filter desktop typecheck有 106 个错误——CI 没报出来是因为 verify-checks 在更早的check:i18n就失败退出了,压根没跑到 typecheck。修的过程中还翻出几处编译期不报、运行期串台的问题,见「范围」。变更类型
feat新功能范围
GrokBuildAgent+ ACP stdio 客户端 / translator / PATH 探测 / Auto-review 映射;desktopbuildGrokBuildAgent()可选注册;AgentKind / SELECTABLE_VENDORS / 五语 i18n;探测与 ACP fixture 单测;docs/dev-rules/grok-build-harness.mdagentKindConversion此前把任何未知值映射成'cc',grok-build 会话会被写进sessions.agent_kind变成 Claude Code、读回来也是 Claude Code。同一类还有自动起名目标、上下文重建卡片打标、任务摘要三处(都是编译期不报的静默串台)VendorIcon真正画上本 PR 新加却一直没接线的GrokBuildMark;mobileMobileVendorIcon不再把 grok-build 会话读成 Claude Code;右侧栏资源占用行新增agent-grok-buildGrokBuildAgent声明rewind/fork不支持,rewind / fork 入口显式拒绝 grok-build 会话,而不是落进「非 codex/pi 即 Claude」的分支去回滚一个没有 checkpoint 的会话'claude-code' | 'codex' | 'pi'副本,凡属级联的一律接回共享类型;模型面(model plane)、参考价、目录默认种子这类 grok-build 确实不参与的子系统,保持三档并显式排除~/.grok/auth.json或 SuperGrok OAuth 当本 harness 登录;把 grok-build 加进VALID_AGENTS;嵌入 Grok TUI;one-shotgrok -p;MCPsend_to_session/create_worker的agent_kindzod 枚举(能不能让模型把活派给 grok-build 是产品决定,本轮只对齐ControlWorkerAgent这个结果侧类型)XAI_API_KEY)时,新建对话引擎选择器多出 Grok Build;该会话在侧栏 / 模型选择器 / 资源占用里显示自己的身份标识而不是 Claude 的UI 变化
新增的可见元素只有 Grok Build 的身份标识(图标 + 徽标底色 + 资源行文案),没有新布局、没有改任何既有组件的形状。下面是静态 HTML 复现,SVG path 与
GrokBuildMark.tsx是同一份:engine-badge-grok-build(#6b7280)与既有engine-badge-cc / codex / pi同类,是表达「这一行挂在哪个引擎上」的身份色,light / dark 同值是有意决策,不表达界面明暗层次;themes/__tests__/tokenRegistry.test.ts的守护测试已把第四个 token 纳入,组件只经var(--engine-badge-grok-build)消费,不留 hex 副本。DESIGN.md §4「Select & Dropdown」与 §14.4「容器形变」——沿用既有PermissionSelector/AgentSelect,只补第四个 vendor 项,容器与交互零改动。DESIGN.md §11「Voice & Content」——权限档文案走 i18n 五语,品牌名Grok Build不翻译。图标取色沿用侧栏既有约定(idle Stone 灰 / running Thinking Orange / 选中态与文字同色),不引入新色。怎么验证的
自动验证
desktop 全量里有 10 个文件失败。逐个在不含本 PR 任何改动的分支(
fix/mobile-work-group-tool-row-i18n,同样基于近期 main)上跑同一组文件,9 个以完全相同的报错失败(dbClient.tx is not a function、no such column: list_preview/codex_plan_json的 DB harness 漂移,来自性能提交51bed2719;以及 BillingPage 的日期格式化),第 10 个codexExecFunctionAdapter.e2e单独跑在本分支通过,是全量并发下的超时抖动。结论:与本 PR 无关。grok-build-session.test.ts这轮也修了跨平台问题:假 grok ACP server 原本靠#!/usr/bin/env bun的 shebang 启动,CI runner 上没有 bun,四个用例全挂在 exit 127。现在改成生成一个 sh wrapper 显式 exec 当前 node,Windows 按仓库既有约定(Pi 侧同款)跳过整组。实测把 bun 从 PATH 摘掉后四个用例照常通过。手工验证
不涉及(本机没有 grok CLI,跑不了真实 ACP 联调)。建议审阅者:PATH 无 grok 时确认 CC / Codex / Pi 正常;安装并
grok login后确认选择器出现 Grok Build、建出的会话在侧栏显示 Grok Build 图标、sessions.agent_kind落的是grok-build。未执行的验证
grok-build-session.test.ts在 Windows 跳过,理由同 Pi:spawn 不过 shell 起不了 .cmd wrapper)风险
风险分类
影响与回滚
sessions.agent_kind是无约束的text,drizzle 侧几处 text 枚举是类型层的,不进drizzle/meta/*_snapshot.json,db:check无漂移。数据形态上的唯一变化是:grok-build 会话会真的写入'grok-build'这个值(此前会被静默写成'cc')。agent_kind='grok-build'会被旧版dbToMakerAgentKind回落成claude-code—— 会话仍可打开、按 Claude 解析,不会损坏数据,但引擎标识会显示成 Claude Code。这是「新值 + 旧读取端」的固有代价,不是本 PR 新引入的读取路径缺陷。提交前检查
Fixes #3328
Related #3027