feat: 让 cindy_helper 可查看会话排队消息 - #2804
Conversation
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
|
| Filename | Overview |
|---|---|
| apps/desktop/src/main/maker-ipc/agent-input-coordinator.ts | 新增队列检查投影及 steer generation、request token、lineage 和 session identity 守卫;先前报告的迟到清理与幽灵消息路径已被覆盖。 |
| apps/desktop/src/main/maker-ipc/sessionQueueInspection.ts | 将 pending、可逆 active turn 和 direct steer 合并为稳定去重的队列检查结果,并正确标记 consuming。 |
| packages/maker-core/src/agents/claude-code/index.ts | Claude steer 增加转换后的活动检查,但自动 continuation 不推进 Session generation,旧 steer 仍可跨入 continuation。 |
| packages/maker-core/src/session.ts | Session 为 send/steer 引入 turn generation 校验,但 generation 仅由显式 send 推进,无法区分 Claude SDK 自动 continuation。 |
| apps/desktop/src/main/maker-ipc/sessionControlService.ts | 控制服务在异步消息构造前后绑定 Session identity 与 generation,但其有效性依赖 provider 的每轮 generation 推进。 |
| apps/desktop/src/main/agent-island/service.ts | 暴露统一活动快照和 transition 订阅,并继续使用 Agent Island 状态机作为 live 状态源。 |
Sequence Diagram
sequenceDiagram
participant Helper as cindy_helper
participant Control as Desktop控制服务
participant Session as maker-core Session
participant Claude as Claude adapter
participant Queue as Claude inputQueue
Helper->>Control: steer_session
Control->>Session: 捕获Session与turnGeneration
Session->>Claude: steer
Claude->>Claude: await toClaudeSdkContent
Note over Claude: 原turn结束
Claude->>Claude: task_notification触发beginNewTurn
Note over Session: Session.turnGeneration未推进
Claude->>Queue: 旧steer写入continuation
Comments Outside Diff (1)
-
packages/maker-core/src/agents/claude-code/index.ts, line 5445-5457 (link)当 turn A 的
steer等待toClaudeSdkContent转换期间结束、随后task_notification启动自动 continuation 时,continuation 不经过Session.send,因此不会推进控制面校验使用的turnGeneration;这里看到turnInFlight已恢复为true后仍将旧插话写入共享inputQueue,导致 continuation 消费属于 turn A 的消息。Context Used: 使用和PR描述相同的语言进行评论 (source)
Knowledge Base Used: maker-core Agent Abstraction and Codex Implementation
Prompt To Fix With AI
This is a comment left during a code review. Path: packages/maker-core/src/agents/claude-code/index.ts Line: 5445-5457 Comment: **自动续跑仍接收旧插话** 当 turn A 的 `steer` 等待 `toClaudeSdkContent` 转换期间结束、随后 `task_notification` 启动自动 continuation 时,continuation 不经过 `Session.send`,因此不会推进控制面校验使用的 `turnGeneration`;这里看到 `turnInFlight` 已恢复为 `true` 后仍将旧插话写入共享 `inputQueue`,导致 continuation 消费属于 turn A 的消息。 **Context Used:** 使用和PR描述相同的语言进行评论 ([source](https://app.greptile.com/review/custom-context?memory=instruction-0)) **Knowledge Base Used:** [maker-core Agent Abstraction and Codex Implementation](https://app.greptile.com/xindong/-/custom-context/knowledge-base/makecindy/cindy/-/docs/maker-core-agents.md) --- For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Prompt To Fix All With AI
### Issue 1
packages/maker-core/src/agents/claude-code/index.ts:5445-5457
**自动续跑仍接收旧插话**
当 turn A 的 `steer` 等待 `toClaudeSdkContent` 转换期间结束、随后 `task_notification` 启动自动 continuation 时,continuation 不经过 `Session.send`,因此不会推进控制面校验使用的 `turnGeneration`;这里看到 `turnInFlight` 已恢复为 `true` 后仍将旧插话写入共享 `inputQueue`,导致 continuation 消费属于 turn A 的消息。
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (27): Last reviewed commit: "fix(desktop): persist steers accepted af..." | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c81bd0c3d4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7352fffdb1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@zqchris 👋 这个 PR 还有 1 条 review conversation 没 resolve(apps/desktop/src/main/localDb/agentInputQueueSnapshots.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4042b7ec5a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b1027aa6fa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 48a9d7dbeb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 81e1801633
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 503b9145e4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 21bb09b6c1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c88efd90cf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 20f514f0ac
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
MagicLizi
left a comment
There was a problem hiding this comment.
审查结果:P1 × 1
P1: list_sessions 批量查询排队数时单条会话异常会打断整批响应
位置: apps/desktop/src/main/maker-ipc/sessionQueueInspection.ts (resolveSessionQueueCounts → listSessionQueuedCounts → list_sessions)
问题: list_sessions 现在对返回页中每个 session 都调用 listSessionQueuedCounts。如果某个 session 的 coordinator 处于 live-but-not-yet-queue-restored 状态(AgentInputCoordinator.getQueueInspectionIfRestored 会抛),或 SQLite 里 queue-snapshot 行损坏(loadAgentInputQueueSnapshotCounts 会抛),整个 list_sessions 调用会硬失败(返回 INTERNAL 错误),而不是仅对该条 session 降级为 0 或省略排队数。
建议: 在 resolveSessionQueueCounts(或其调用处)对单条 session 的 queue-count 查询做 try-catch,失败时降级为 null/0,而不是让一条有问题的 session 拖垮整页查询。
其他方面(read path 权限模型、update/cancel/steer 的 callerSessionId 绑定、跨 session 信息隔离)审查通过,无新增安全问题。
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 79014749df
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@zqchris 👋 这个 PR 还有 2 条 review conversation 没 resolve(apps/desktop/src/main/maker-ipc/agent-input-coordinator.ts / packages/maker-core/src/agents/codex/index.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
MagicLizi
left a comment
There was a problem hiding this comment.
审查通过 — 0 P0,1 P1(已确认为设计意图)。
P1 注意事项(不阻断):steerSession/stopSessionTurn/getSessionRuntime 无调用方归属检查(任意本地会话可通过 cindy_helper 控制兄弟会话)。经核实 capabilities.ts 明确记载此为本地信任域设计,与已有 list_session_queue 无归属门控一致。建议在 PR 上补一条产品/安全确认评论。
其余实现精心覆盖了 turn-generation/session-identity 竞态、graceful-stop safe-point 逻辑、队列检查的数据最小化投影。测试充分。
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 517150755e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@zqchris 👋 这个 PR 还有 1 条 review conversation 没 resolve(apps/desktop/src/main/maker-ipc/agent-input-coordinator.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。 如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。 |
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
|
会话排队消息观测终于闭环了——从队列快照到实时 steer、分代防赛,整套控制面做得干净利落。 |
这次改了什么
摘要
把
cindy_helper从只能投递消息扩展为本机任意 session 的完整「会话控制面」:调用方可以查看目标 session 的待处理输入和统一运行状态,修正或撤回自己尚未被消费的消息,在活动 turn 内高优先级插话,并请求 turn 在工具安全边界优雅停止。这五项共同解决“跨 session 发出控制意图后无法确认、修正或安全干预”的同一个用户结果;任一项缺失都会留下不可观察或不可恢复的控制盲区,因此作为一个完整能力交付。
变更类型
feat新功能fix缺陷修复refactor/perf重构或性能优化docs/test/chore文档、测试或工程维护范围
list_session_queue(session_id)返回来源、入队时间、正文摘要和 consuming 状态;list_sessions返回轻量queuedCountupdate_session_queued_message/cancel_session_queued_message只允许操作当前 session 经send_to_session投递、且尚未进入 consuming 的消息steer_session严格走 provider 原生 same-turn steer;没有活动 turn、能力不支持或输入边界拒绝时明确失败,不降级为下一 turnstop_session_turn等当前并行工具结果全部回到安全边界后发送 provider 软中断;超时或失败返回unconfirmed,不关闭 transport、不重建 session、不硬杀进程get_session_runtime共用,状态变迁暴露订阅钩子cindy_helper新增上述只读/控制工具;所有失败均返回结构化错误,不伪造受理,也不把插话静默降级成普通排队消息架构与 turn 热路径侵入点
idle / running / needs-interaction / completed / error,并维护 turn 开始时间、最后活动时间与无正文动作摘要。本 PR 不让 maker-core 平行维护同一组状态字段。title:*key,新增状态不要求各消费方复制枚举分支。sessions.status、turn 时间边界、clear boundary 和安全的 error 尾标构造同一模型。冷读只取元数据与尾态,不物化正文。get_session_runtime读取 Desktop main 的统一投影;maker-core 仅追加当前 turn generation 与 graceful-stop 状态这类控制 facet。优雅停止的 active tool / interaction 计数继续作为控制状态机内部事实,不再对外充当另一套 session status。sessionQueueControl;steer 与 graceful-stop 只在既有 turn 热路径增加 generation、安全点和 provider 软中断守卫,不改变消息消费语义。queuedCount在 SQLite 内完成合法形状、scheduler、clear boundary 和已落库clientId过滤,不把正文物化或长期保留到内存;恢复入口使用相同判据并 fail-closed。UI 变化
为何必须触碰 UI 文件
状态探针不能另造一套运行状态,必须与用户已经在侧栏看到的运行中、正常结束、错误结束和等待决策状态共用同一事实源。侧栏状态链路涉及的七个 renderer 文件正是原有散装状态推导、消费和回归所在:
AutomationSessionGroupItem.tsx、SessionCard.tsx、SessionItem.tsx、sidebarRightStatus.ts、agentIslandActivity.ts,以及对应的sidebarAttentionBadge.test.ts、sessionCardReviewRegressions.test.ts。因此,本 PR 必须把这些消费点的数据源统一切换到projectSidebarSessionActivity投影;否则状态探针与侧栏仍可能对同一 session 给出两套结论。这不是新增或重做 UI,而是观感零变化的数据源重构:颜色、图标、布局、状态优先级、呼吸动效和用户可见文案均保持不变。行为一致性回归覆盖本地与 device-linked 远程会话、运行态与错误尾态并存、urgency-only、重启或通知清零等组合;其中
sidebarAttentionBadge.test.ts验证远程活动镜像与错误/运行 facet 的组合,sessionCardReviewRegressions.test.ts验证本地和远程列表项都消费同一投影。docs/design-rules/DESIGN.md的既有语义 token 与运行态动效,不新增视觉规则怎么验证的
自动验证
当前状态投影回归:
最新 review 修复验证:
覆盖的关键边界包括:普通排队、direct steer、active turn consuming 投影;只允许修改/撤回本人消息;消息已消费与竞态丢失;无活动 turn、能力不支持、策略阻断和迟到 generation;并行工具、权限/Ask/计划确认安全点;软停止幂等、失败与超时;terminal/close 状态清理;MCP/dynamic interaction 与真实 active item 关联、歧义 fail-closed、completed/迟到 updated 不复活;冷快照清空边界、scheduler、已落库消息去重和损坏快照 fail-closed;统一状态的 live/cold 投影、turn 重新开始计时、无正文摘要与 transition 订阅取消。
VITE_CINDY_AUTH_REGION=global pnpm test:unit:related:脚本因packages/maker-shared/package.json变更回退全量。runner 406 passed / 1 skipped;Desktop 25827 passed / 5 skipped,仅ghostInstallReceipt.test.ts2 条 macOS 主干基线失败;其余 workspace(含 maker-core 与 Pi RPC resource discovery)全部通过。两条失败来自readBoundedFileNoFollowSync用未 realpath 的/var/...containWithin 根比对/private/var/...文件而 fail-closed;相关实现和测试与upstream/main完全一致,不属于本 PR 的会话控制面改动。另,本机apps/desktop/.env为 CN 区域;Global orphan-reaper 用例在显式VITE_CINDY_AUTH_REGION=global下 13/13 通过。maker-core 核心指标实测(§3.4)
usage-tracker.test.ts10 tests。observeTurnControl位于前台事件出口,可能增加每事件开销;provider queue 到 listener 的状态变迁也位于热路径。runtimeActivity: "snapshot",必须保留原事件内容,同时只排除其 active-tool 生命周期。tool_use、真实update_plan仍有对应tool_result、snapshot 不占用 graceful-stop safe point。thread/start、thread/resume、system/developer instructions、MCP/dynamic tool definitions diff,并运行 Codex index 485 tests。手工验证
未启动 Desktop dev 实例;控制路径通过 MCP tool registration / handler → Desktop control service → maker-core adapter 的集成测试覆盖。侧栏无视觉变化,仅替换状态数据来源。
未执行的验证
风险
风险分类
影响与回滚
cindy_helper、Desktop main 会话输入协调、Agent Island/侧栏状态投影、maker-core turn 生命周期及 Claude Code / Codex / Pi adapter 的软停止能力。sessions、messages与 queue snapshot 数据;无 schema 或 migration 变更。冷计数按批次在 SQLite 内聚合,损坏快照拒绝计数。cindy-protocol或 device-link wire breaking change。senderSessionId;规范状态、transition 与探针不含 prompt 正文、工具参数或凭证。提交前检查
git commit -s,见 DCO)