fix(desktop): declare a mode for Bot sessions - #4213
Conversation
f013205 to
45a2eba
Compare
Explore is a boundary a product mode confers, not one a caller may request directly, so the Bot adapter's bare `permissionMode: 'explore'` was rejected and no Bot conversation could open a session. Bot is such a mode, and it carries no name of its own so a Session still reads as the platform that opened it. `session.create.mode` accepts a value it did not before, and a Host that predates it answers `Invalid Session start mode`, so the compatibility epoch moves with it. Generated-by: Claude Code
`sessions:create` dropped the requested name whenever a mode was present, which held only while every mode carried a name of its own. The Host already resolves that precedence, so the name goes to it either way. Generated-by: Claude Code
The registry was born with Deep Research as its only member, so it lived in that module. `bot` is a sibling, not a Deep Research detail, and nobody looks for Bot permissions in a file named for Deep Research. Generated-by: Claude Code
45a2eba to
a6a5147
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Thanks for tracing this through the packaged Bot path. I verified that the problem is real: platform delivery remains healthy, but every Bot conversation fails before Session persistence because the adapter directly requests explore without declaring a product mode.
The fix follows the right authority boundary. A Bot now declares the bot product intent, while the Runtime Host remains the only place that materializes its reserved label and explore permission. That is cleaner than exempting caller-supplied bot labels from validation. Moving the generic mode registry out of deep-research.ts also removes a misleading ownership boundary rather than creating a second registry, and making the mode name optional is the minimum change needed to preserve Feishu/Telegram/WeCom-generated Session names. Deep Research still keeps its Host-owned fixed name.
I found no P0/P1 issues and no user-visible UI/UX change in this diff. The exact head's required test check is green. Approved at a6a5147aaf0801a24718d25dbe9b6c90f7c6ea99; the PR is currently conflicting with main, so it still needs a rebase and exact-head incremental confirmation before merge.
AI-assisted review (OpenAI Codex). I verified the packaged reproduction evidence, create contract, production adapter/coordinator composition, registry ownership, and focused tests.
中文对照
感谢你沿着打包后的 Bot 链路定位问题。我确认问题真实存在:平台收发连接是健康的,但 Bot adapter 直接请求 explore、又没有声明产品 mode,因此所有 Bot 对话都会在 Session 持久化前被 Host 拒绝。
这次修复守住了正确的 authority:Bot 只声明 bot 产品意图,由 Runtime Host 唯一负责生成保留 label 和 explore 权限;这比按调用方传入的 bot label 绕过校验更干净。把通用 mode registry 从 deep-research.ts 移到中立模块,也是在修正 owner,而不是增加第二份 registry。mode name 变为可选,是保留飞书/Telegram/企业微信生成的 Session 名所需的最小变化;Deep Research 仍由 Host 强制使用固定名称。
未发现 P0/P1,也没有用户可见的 UI/UX 变化。当前 exact head 的 required test 已通过。已批准 a6a5147aaf0801a24718d25dbe9b6c90f7c6ea99;但 PR 目前与 main 冲突,仍需 rebase,并在新 head 上做增量确认后才能合并。
本次为 AI 辅助审查(OpenAI Codex)。我核对了打包环境复现证据、create contract、生产 adapter/coordinator 组合、registry owner 和聚焦测试。
Fixes #4193
Every Bot conversation (Feishu, Telegram, WeCom) answers
Maka 暂时无法处理这条消息:机器人对话处理失败and no session is ever created, while the platform connection itself stays healthy.Root cause:
exploreis a boundary a product mode confers, not one a caller may request directly (create-session-input.ts), but the Bot adapter requested it directly —permissionMode: 'explore'with nomode.prepareCreaterejects that, and the rejection matches no category ingeneralizedErrorMessage, so the Bot shows the generic fallback and the failure reads like a platform or credentials problem. Desktop chat is unaffected: it starts atask.A Bot session is exactly such a product intent, so
botjoinsSESSION_START_MODE_SPECSand the adapter names it instead of asking forexplore. Unlike Deep Research it carries no name of its own —prepareCreateresolvesmode?.name ?? input.name, and a fixed spec name would flatten飞书 任务/Telegram 任务into one label — soSessionStartModeSpec.namebecomes optional. Itsmode:botlabel is reserved for free, sinceprepareCreatealready refuses caller-supplied mode labels.The registry itself moves from
deep-research.tstosession-start-mode.ts. It was born there when Deep Research was its only member;botis a sibling, not a Deep Research detail, and nobody looks for Bot permissions in a file named for Deep Research. Pure move — the importers that only wanted the generic symbols follow the new path.A mode without a name of its own also exposed a sibling defect:
sessions:createdropped the requested name whenever a mode was present, which held only while every mode carried one. It now forwards the name either way and leaves the precedence to the Host. The Bot adapter talks to the Host directly and never took that path, so this is a contract repair, not a second user-visible bug.Deliberately not covered:
bot-incoming-main.tsstill swallowsinvalid_requestinto机器人对话处理失败, which is what made this take a packaged-app patch to diagnose.updateSessionConfigurationstill admitsexplorewith no mode — the pathprepareSessionuses to re-arm a bound Bot session.Before / after, session creation with the input the Feishu Bot actually sends:
Both regressions are guarded where they were rejected — at the coordinator and at the IPC handler. The Bot adapter's own test never reached either: its fake client returns a session without entering
prepareCreate, which is why this shipped.Generative tooling: Claude Code (Opus 5) wrote this change; commits carry a
Generated-bytrailer.