Skip to content

fix(desktop): declare a mode for Bot sessions - #4213

Open
orangeCatDeveloper wants to merge 3 commits into
apache:mainfrom
orangeCatDeveloper:fix/bot-session-declared-mode
Open

fix(desktop): declare a mode for Bot sessions#4213
orangeCatDeveloper wants to merge 3 commits into
apache:mainfrom
orangeCatDeveloper:fix/bot-session-declared-mode

Conversation

@orangeCatDeveloper

@orangeCatDeveloper orangeCatDeveloper commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

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: explore is 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 no mode. prepareCreate rejects that, and the rejection matches no category in generalizedErrorMessage, so the Bot shows the generic fallback and the failure reads like a platform or credentials problem. Desktop chat is unaffected: it starts at ask.

A Bot session is exactly such a product intent, so bot joins SESSION_START_MODE_SPECS and the adapter names it instead of asking for explore. Unlike Deep Research it carries no name of its own — prepareCreate resolves mode?.name ?? input.name, and a fixed spec name would flatten 飞书 任务 / Telegram 任务 into one label — so SessionStartModeSpec.name becomes optional. Its mode:bot label is reserved for free, since prepareCreate already refuses caller-supplied mode labels.

The registry itself moves from deep-research.ts to session-start-mode.ts. It was born there when Deep Research was its only member; bot is 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:create dropped 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.ts still swallows invalid_request into 机器人对话处理失败, which is what made this take a packaged-app patch to diagnose. updateSessionConfiguration still admits explore with no mode — the path prepareSession uses to re-arm a bound Bot session.

Before / after, session creation with the input the Feishu Bot actually sends:

BEFORE session.create => {"ok":false,"error":{"code":"invalid_request","message":"Session creation requires a declared mode for explore permission"}}

AFTER  session.create => ok: true persisted: {"name":"飞书 任务","labels":["bot","feishu","mode:bot"],"permissionMode":"explore"}

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-by trailer.

@github-actions github-actions Bot added the effort/S Under 100 readable lines label Aug 29, 2026
@orangeCatDeveloper
orangeCatDeveloper force-pushed the fix/bot-session-declared-mode branch 3 times, most recently from f013205 to 45a2eba Compare August 29, 2026 20:07
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
@orangeCatDeveloper
orangeCatDeveloper force-pushed the fix/bot-session-declared-mode branch from 45a2eba to a6a5147 Compare August 29, 2026 20:11
@orangeCatDeveloper
orangeCatDeveloper marked this pull request as ready for review August 29, 2026 20:34
@github-actions github-actions Bot added effort/M Under 500 readable lines and removed effort/S Under 100 readable lines labels Aug 29, 2026

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 和聚焦测试。

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

Labels

effort/M Under 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Bot (Feishu/Telegram/WeCom) sessions fail with 机器人对话处理失败: runtime host rejects explore sessions without a declared mode

2 participants