feat(bots): 建立统一 Bot 运行时与会话基座 - #2829
Draft
zqchris wants to merge 57 commits into
Draft
Conversation
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com> # Conflicts: # apps/desktop/drizzle/meta/_journal.json # apps/desktop/src/main/im/shared/__tests__/stopCommandRouting.test.ts # apps/desktop/src/main/im/shared/messageHandler.ts # apps/desktop/src/main/im/shared/slashCommands.ts # packages/lizi-im/src/channelIM.ts
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>
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>
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>
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>
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>
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>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com> # Conflicts: # apps/desktop/src/main/bootstrap-electron.ts # docs/product-rules/telegram-bot-parity.md # packages/maker-core/src/agents/base-agent.ts
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>
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>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Round flat-tint avatars from a registered 9-hue token family (light/dark), auto-assigned per bot name; legacy avatarColor values map without migration - One-screen create dialog: template cards incl. custom, inline avatar picker, role text optional behind a collapsed section; jargon aside removed - IM-style sidebar rows: latest-message preview with live refresh, relative time, hover gear entry; healthy state no longer draws an icon - Settings reorganized into 7 grouped tabs with deep links; identity first, renew/lifecycle/portability demoted to Advanced Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Reserved cindy://avatar/ namespace renders the official character art; picker offers it first, auto-assignment still yields emoji only - Assistant template becomes the standard Cindy bot: brand name + official avatar on the neutral fill, zero required configuration - Mobile read-only roster degrades the sentinel to the generic bot emoji Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Eight bundled character portraits (generated with the user's image model against the official Cindy artwork as style reference) join the reserved cindy://avatar/ namespace; picker gains a Characters section - New bots default to a hash-assigned character instead of an emoji - Fix main IPC 16-char avatar cap that rejected every sentinel value, including the standard Cindy assistant template - Register the Bot avatar artwork surface in DESIGN.md; unknown sentinels degrade to the initial fallback Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Automation tab is list-first: routines read like a scheduled-task list with human schedule labels, run-now, and an enable switch per row - Creating a routine asks only what to do and when; name auto-derives, engine knobs (project, delivery, notes space, limits) move behind a collapsed Advanced section with working defaults - Empty state offers three clickable routine examples - Notifications tab copy rewritten in plain language; counts hidden until events exist; toggle uses the shared Switch Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Settings persist automatically: text debounced 1.2s with blur flush, discrete picks coalesce instantly; dirty-check against the last committed baseline, serialized in-flight commits, flush on leave/unmount/bot switch - Bottom cancel/save bar removed; header shows transient saving/saved state and an inline retry on failure - Profile-apply prompt now surfaces when leaving settings instead of mid-edit; form hydrates per bot id so in-flight saves cannot clobber edits - Archived bots stay read-only (autosave disabled entirely) Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Owner-scoped local read positions; existing list IPC accepts an optional lastReadAtByBotId map and returns per-bot assistant-message unread counts via the indexed canonical-chat query (same visibility rules as previews) - Sidebar rows bold name and preview when unread and show a count pill (99+ cap); inbox attention demotes to a dot while unread counts lead - Opening a bot's chat marks it read and keeps it read while watching; device-link remote projections stay unread-free Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- 647 locale strings across desktop and mobile: zh-CN 伙伴 / zh-TW 夥伴 / en teammate(s) / ja 仲間 / ko 동료, with per-language particle and naturalness handling - IM-platform bots (Telegram/Feishu/Discord tokens, @Botfather, GitHub App) keep the word Bot - different concept, excluded case by case - New proposed glossary entry records the scope and the platform-bot distinction; keys, routes, identifiers and wire formats unchanged Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Capabilities tab becomes a plain-language chip wall: act (trust), work on a schedule, and one chip per connectable channel (greyed with a connect hint when no account); harness/model/skills/toolsets/MCP/other-task access move verbatim under an Advanced expert section - Memory switch removed from primary UI (recovery row only for bots stored off); teammate delegation intentionally not chipped - the engine gates it on trust already - New teammates default to trusted via one shared leaf constant (renderer is the authoritative layer); stored bots keep their setting - Trusted teammates show an icon-only warning badge in the sidebar and settings header; clicking it jumps to the act chip - Fix: channel migration/rollback dialogs rendered only inside the channels tab branch; mounting from elsewhere silently no-oped Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Regenerate the bots migration on the latest chain per the collision rule: upstream took 0092, so our schema intent is re-emitted as 0093_bots_runtime_foundation (idempotent DDL; the right_sidebar_tabs singleton index stays in the guarded companion because legacy lineages lack that table). Dropped the duplicate sessions.codex_plan_json ALTER that upstream's 0092 snapshot regression would have replayed twice. Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Create dialog becomes the approved roster: six persona teammates (Cindy, Xiaochai, Melody, Benben, Xingxing, Ashu) with first-person intros; picking a card creates immediately, custom card keeps the minimal name+avatar flow, import sinks to a quiet footer link - New teammates greet you: idempotent renderer-side welcome message (fixed clientId, only into a provably empty canonical chat) - Teammate chats show the avatar beside assistant bubbles and hide the permission chip and model selector in the composer (config lives on) - Sidebar rows drop the hover gear and the trusted badge; settings entry moves to the header lockup and gear; global Settings gains a 伙伴 section (notification prefs, import/export) Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Settings collapse from seven tabs to the approved four blocks (who they are / what they can do / what they know / their schedule) plus a quiet Advanced expander holding every engine-facing control; old tab deep links map to anchors - Guided three-step persona wizard compiles into a fenced persona block inside identitySource (real prompt material in template voice) and round-trips its own selections without touching hand-written text - Memories list reads the bot's real maker-memory scope via three minimal read/delete IPC handlers on the existing engine store; learned-skills block ships as an empty state for the growth batch - Ability wall states built-ins as facts; channel connect list enforces one IM per teammate (UI gate; legacy multi-connections stay honest) - Creating a routine no longer requires enabling automation first Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Keep both sides in ChatInput (bot mentions + unified model draft select), keep the bot-session guard alongside upstream's optimistic title preview in sessionsStore, retain the branch readOnly gating over upstream's reflowed conditions, and adopt upstream's broadened skill-projection refresh. Wrap the delegation back button in the managed Tip to satisfy upstream's new icon-tooltip contract. Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Delegations render as live inline collaboration cards (joined header, breathing status, ticking elapsed, collapse to a summary line) anchored by structured agent_meta on the existing mirror messages; unmarked legacy mirrors keep rendering as plain text - Completed results render as guest bubbles with the teammate's avatar and a neutral guest tag; both card and bubble open the other task, and the target-side mirror links back to the requesting task - New interject channel: nudge or amend a queued/waiting/running delegation from the parent (ownership double-checked, terminal states refused, busy child queues per existing session semantics, the nudge leaves a trace in the parent); exposed as an IPC handler and an interject_bot_delegation MCP tool for chained orchestration - Chained hand-off covered by an integration test (plan -> design relay reading the previous result, interjecting mid-run) - Fix nested-delegation recovery picking an anchor or nudge as the result; keep collaboration anchors out of list previews and titles Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- File outputs in teammate chats render as typed deliverable cards (document/sheet/image/deck/other; images get real thumbnails) with open and view-in-library actions reusing the existing open paths; delegation artifacts on collaboration cards use the same card - New read-only bots:artifacts projection aggregates three sources per teammate - delegation output artifacts, tool_use created files, and message attachments - deduped across sources with existence checks, caps, and honest truncation; protocol refs never resolve disk paths - New bot-artifacts right-sidebar tab: counts, type filter chips, two-column grid, empty/remote/truncated states; teammate sessions land on it by default while the delegations tab coexists - deliverable registered as a proposed glossary term (交付物/成果物/산출물) Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Teammate replies whose turn wrote memory end with a faint growth note (sparkle + '记住了:<title>', merged per turn, final-bubble only); clicking opens the teammate's settings with the matching list briefly highlighted; derived purely from the existing memory_write tool_use rows - no engine change, no new IPC - Learned skills ride the same memory scope via a learned- slug convention: entries split into a 'TA 学会的' list beside memories, one fetch feeding both lists with synchronized deletes - One constant line added to the bot capability context prompt teaching the learned- convention (bot sessions only; declared as a system-prompt change for review per maker-core rules) Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
…rsona ack, typing hint - Roster becomes a main-area page at /bots/roster (sidebar stays); the benefit-card pitch page and the modal dialog are gone; first run lands straight on the roster; ?add=1 deep links redirect - Register the missing status token family the bot surfaces referenced (error/success/info + soft danger, per-mode contrast-checked) with regression guards; blue unread badge token registered per DESIGN §10 - Screenshot-audited fixes: settings header aligned to its content column, roster CTA follows the first joinable card, IM-blocked hint only where actionable, persona wizard selected state no longer collides with the focus ring, growth list separator joins cleanly - Persona wizard now returns to the conversation and the teammate acknowledges its new voice (idempotent injection per persona fingerprint, 9 copies x 5 locales); collaboration card exposes the result summary; interject carries an idempotency key end to end - Sidebar rows show a typing hint while the teammate's turn runs (island activity mirror, no new IPC), 40px avatars, no health column; history view gets bubble avatars; deliverable cards show real sizes Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Keep both sides where each added fields or tests at the same anchor (dispatcher route flags, list_sessions deps, xdt-helper history deps with session context plus upstream's session queue, bot delegation test alongside the new queue test reconstructed from both stages); adopt upstream's isDbClientNotReadyError handling and the reworked steer CAS flow with our bot-input gate retained ahead of it. Related gate: 2068 test files pass; exit 1 stems solely from upstream's known updateService process.exit unhandled rejection (reproduced on clean baseline). Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Child sessions inherit the target teammate's execution config (providerId/effort/fastMode); missing providerId made children fall to the implicit default route and die AGENT_NOT_READY whenever the target used a custom or subscription source - the delegation then hung in waiting retries forever, which is exactly the field-observed 'target never runs, result never returns' - Dispatch failures are classified: non-self-healing causes (signed out, provider not ready) terminate the delegation immediately, abort the child, and deliver the human-readable reason back to the requester's conversation instead of spinning; restart-resume follows the same rule instead of hanging until the 30-minute timeout - delegate_to_bot may now return status 'failed' synchronously so the requesting model knows the job was not placed - New end-to-end runtime suite stubs only the model process: dispatch, DB rows, outbox, and events are real; the old state-machine suites are annotated for what they do not cover Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
…itches - Model/permission selectors return to teammate composers (per-teammate model choice is a real need); all five controls now write back to the bot Profile so Renew no longer reverts composer changes - Sidebar rows drop the ghost trailing column; spacing now matches the approved prototype numerically, locked by a static baseline test - Other-task access dropdown removed (delegation never consulted it); automation is standard - the capability flag normalizes to true at every read site, and the runner's hard throw for legacy false rows is gone; the schedule tab no longer toggles anything behind your back - Channel rows connect in place: real deep links into each channel's existing settings section (all seven have UIs), no more go-elsewhere hints; the duplicate advanced chip wall is deleted along with the dead trusted badge and its helper - The automation trust gate stays (it is real: three enforcement points, reachable control in the composer) with copy that points at the actual permission selector wording Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- PI teammates wrote memories into the project store while their prompt and the settings list read the bot store - memoryScopeKey now travels through the PI spawn config and environment ctx (regression sentinel: dropping the key writes into project memory and the test goes red); remote Claude Code sessions get the same key through the remote MCP ctx - The bot memory capability only narrows: when the global maker-memory engine is off, the prompt stops promising a memory the tools cannot reach, and the runtime no longer reads an index that would throw - Read-only project index entries are labeled as excerpts the teammate cannot open, and the bot memory section states it is the teammate's own - End-to-end chain suite (real manager, real sqlite, real MCP server over in-memory transport): form/store/isolate/recall/search/list-parity/ delete/clear plus signed-out fail-closed behavior Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- Background text becomes a first-class editable section: the persona wizard owns only its marker block, the backstory body has its own read/edit surface through autosave (the hidden overwrite-everything escape hatch is gone) - Templates ship seed memories - the role's own opening work notes, not invented user facts - written idempotently by slug into the real bot memory store, visible and deletable; the footnote only claims built-in notes when they exist, with an idempotent backfill link when a template's seeds are missing - Custom creation gains an AI role generator: one-line role description drives a one-shot structured draft (name, backstory, tone, seed notes, avatar, greeting) over the existing title-one-shot channel, presented as an editable preview; four failure classes each speak up, manual path always remains; skill/MCP auto-config deliberately not shipped (machine-specific catalogs + silent capability narrowing - plan on file) - Every creation path now honors the roster promise that a new teammate greets you: generated teammates use their drafted greeting (only while the name is unchanged), hand-made ones a generic line Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
~120 visible affordances audited against their actual wiring:
- Deleted 9 fakes, incl. the notification banner/sound/DND rows nothing
ever read, a zero-callsite summary component with its 22 dead strings,
and budget/depth inputs that persisted values no code path consumed
(now gated behind the collaboration setting that makes them real)
- Wired 6, incl. deliverable-card open failures now surfacing a toast,
the interpolation-less greeting that said literally {{name}}, the one
routine entry point that skipped automation normalization, and the
destructive delete dialog pre-selecting workspace recycling
- Detached sidebar window gets the six bot channels its preload never
projected (guarded parity test both ways: projection equal, no write
channels leaked); SSH-remote tool advertisement now uses the same
allowlist predicate the executor always enforced - the defect was
advertising wider than execution, not a dead allowlist
- 3 state displays stopped lying (unfindable delegation rows, cross-
session status bleed, timeouts reported as failures); 7 copy promises
rewritten to what the engine actually does, in five locales
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Keep both fanout groups in the preload; reinstate the teammates section in settings at upstream's new nesting next to the notifications section (our duplicated app-behavior copy dropped - upstream reindented it); PI launch args merge the managed-package resources with our bot skill policy filter replacing launchSkillPaths as the --skill source at its original position, and listAgentSkills keeps our remote-host branch in front of upstream's managed-package-aware body. PI suite 541 green; related gate: 2098 files pass, exit 1 is the known updateService unhandled-rejection baseline. Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com> # Conflicts: # apps/desktop/src/main/localDb/__tests__/conversationSearch.test.ts # apps/desktop/src/main/localDb/conversationSearch.ts # apps/desktop/src/renderer/features/cc-agent/SessionContentHeader.tsx
- 伙伴会话里工程 diff 卡整张让位:checkpoint 新建文件并入交付物卡候选, 编辑/删除仍排除;普通任务行为逐字节不变 - 命令产物识别补盲:--print-to-pdf= / --screenshot= / soffice --convert-to / wkhtmltopdf / weasyprint / 输出选项后的相对路径,均带读入不误报反例 - 会话头部新增可见「交付物」入口,直达右栏仓库 tab - csv/tsv 交付物卡渲染真实数据迷你表(peekFileHeader 64KB 上限,失败回退图标) - 仓库聚合与对话内卡改用同一套识别实现(shared/commandOutputPaths), 补齐命令产物与 checkpoint 新建两路来源 Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- per-bot 技能存储(userData/bot-skills,slug 净化+防穿越+64KiB/100 条上限) - cindy_helper 新增 save_bot_skill / list_bot_skills,归属由 callerSessionId 反查,不收 botId 夹带 - 会话挂载:pi 走 --skill(排在 explicitSkillPaths 最前,四组顺序不变), claude-code 走 local plugin 根;remote 会话不注入本机路径;自有技能恒挂载、 不进 allowlist 冻结口径(刚学会仍能 resume) - bot 会话 prompt 新增沉淀约定:先查重再保存,记步骤不记结论 - 「TA 学会的」改列真技能(展开正文/确认删除),learned- 笔记保留为独立分组; 「✦ 学会了」尾注复用记忆尾注通路,点击跳设置高亮 - 已知缺口如实标注:codex harness 无 per-session 技能路径注入通道,暂不挂载 Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
- 回传断裂根因四件套:回程 lazy-resume 补 providerId;空 result 回读子任务 最后一条 assistant;子委派继承上级 max_depth;deliverCompletion 早退打 warn - 目标侧渲染同源实时协作卡(呼吸点/秒数/看工作过程),侧栏显示工作中 - 完成镜像瘦身:结论+结构化交付物,不复读任务全文 - 委派模板不再传递发起方目录,产物走 BotOutputArtifact - 右栏修复:ensure-singleton 白名单补 bot-artifacts + 0094 单例索引, 注册并行化,头部按钮失败可见提示 - 伙伴任务空态改交付物/协同语义,工程面板收起 Signed-off-by: Chris <4436110+zqchris@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
这次改了什么
摘要
把 Cindy 现有的任务、IM Bot 和自动化能力收敛成统一的 Cindy Bots 产品:Bot 默认是本地长期助手,Telegram、飞书、Slack 等是后挂 Channel;每个 Bot 拥有版本化身份、真实主任务、独立能力与记忆、状态变迁收件匣、Automation、Bot 间委派、项目/worktree、历史与可靠投递。
本 PR 复用 Hermes Bot Mode 的 Profile / SOUL / USER / runtime snapshot 分层,不由 UI 临时拼 system prompt;同时保留 Cindy 各 IM adapter 对引用、卡片、thread/topic、附件、群历史、托管方式和回执的差异。
这是长期累积的主动 Draft。当前 Bot 侧已经具备统一状态模型的消费端口、逻辑订阅、持久收件匣、heartbeat-turn / inbox-only 激活策略,以及零配置 Guardian Heartbeat(健康检查零 token;只在失联、漏事件或无人认领时合成异常并复用同一消费入口),但权威状态类型与 subscribe 出口由会话控制面 Draft #2804 提供。本 PR 不再从 turn 完成、标题 patch 或散落 status 字段自造事实;#2804 必须先合,本 PR 再对齐其最终公共类型与出口。
真实 IM、真实 Automation、真实 Bot 委派、真实旧库迁移、北极星总控闭环和双端视觉尚未验收,因此当前不能合并、不会转 Ready。
2026-08-17 已重新 fetch 并以 merge(非 rebase)合入当时最新的
upstream/main,当前主干已是本分支祖先;应用 migration 集已追平到 0093,解决旧分支构建打不开已升级验收库的问题。另提供固定、无需登录的离线验收沙箱cindy-bots-offline-demo,由当前 checkout 的完整 migration 链现建数据库,不复制任何正式 userData、登录态或授权。变更类型
feat新功能fix缺陷修复refactor/perf重构或性能优化docs/test/chore文档、测试或工程维护范围
已包含
stale-running/expected-event-missing/unclaimed-decision合成事件并持久指纹去重。none / observe / coordinate会话控制权限声明,以及控制 Bot 在处理通知前先查当前事实和队列的运行时规则。deliveryKey + opId,不可寻址时失败关闭,不串到本地账号。list_tools核对当前工具面,不在 prompt 中穷举具体工具名。目标 Bot 尚无主任务时,委派链会先创建真实主任务;委派请求和成功/失败/取消/超时终态同步投影到委派时冻结的目标主任务,完整执行仍保留在独立子任务,Renew 不会把请求与结果拆到新旧两个任务,恢复和重复终态按稳定 client ID 去重。@Bot:候选只显示当前 Bot 之外的活跃 Bot,发送后持久保留 Bot ID/名称与委派或接力语义;旧客户端仍能读取消息正文中的cindy://bot/<id>链接并安全忽略未知引用元数据。listBotDelegations与onBotDelegationChanged推送,不新增 IPC,带 dataOwnerGeneration 守卫。?settings=1&tab=<id>可深链),身份提前、Renew 与生命周期/可移植性沉入「高级」。主进程仅扩展 bots 列表只读投影(canonical 会话最新可见消息预览,复用普通任务侧栏同一套可见性规则与索引)。cindy://avatar/命名空间,桌面端渲染官方人物形象(账号头像同款资产,圆裁),头像选择器可选;「助理」模板升级为标准 Cindy 助手(品牌名 Cindy + 官方头像,零必填配置);移动端只读列表遇到该命名空间优雅回退为通用 emoji。cindy://avatar/preset/<id>命名空间;选择器新增「角色」区(官方 Cindy 第一格);新建 Bot 默认按名字 hash 分配角色而非 emoji;未知哨兵值回退首字母兜底,不出破图不漏原始字符串;头像艺术表面已按 DESIGN.md 既有登记模式补登记(含官方头像)。附带修复:主进程 IPC 的 avatar 16 字符上限会拒绝全部哨兵值(标准 Cindy 模板此前实际无法创建),放宽到 64 并保持拒绝 URL/大块数据。updateBotProfile载荷与主进程零改动。0093_bots_runtime_foundation(幂等 DDL;right_sidebar_tabs 单例索引保留在带守卫的 companion,因老世系回放到此处该表尚不存在);并剔除一条上游 0092 快照回退导致会被重复回放的sessions.codex_plan_jsonALTER。db:validate 与全部 migration 回放测试通过。⚠ 已知上游问题待上报:upstream 0092_fixed_zeigeist 的快照丢失了 0091 companion 加的 codex_plan_json 列,任何人在 main 上生成下一条 migration 都会复踩。learned-slug 约定复用同一记忆分域,与「TA 记得的」并列、同步删除。system prompt 改动声明(maker-core 规则要求显式评审):bot 能力上下文提示新增一句常量文本教伙伴用 learned- 前缀记录可复用做法——仅 bot 会话、无会话变量、不影响普通任务;删除该句则「TA 学会的」永为空(有测试锁定该联动)。@Bot、旧客户端兼容和错误恢复路径。不包含 / 明确依赖
合并依赖顺序:会话控制面 Draft feat: 让 cindy_helper 可查看会话排队消息 #2804 先合,本 PR 后合。
feat: 让 cindy_helper 可查看会话排队消息 #2804 尚未提供最终统一状态类型和 subscribe 出口,因此当前没有权威状态 source 接入;不能声称“任意任务状态变迁 → Bot 收件匣”的真实闭环已完成。
feat: 让 cindy_helper 可查看会话排队消息 #2804 落地后,本 PR 必须把临时
BotObservedSessionState/BotSessionStateTransitionSourceadapter 到其最终导出类型,并绑定真实 subscribe 出口。真正的查状态、查队列、派活、插话和停止由 feat: 让 cindy_helper 可查看会话排队消息 #2804 的
cindy_helper工具逐次鉴权;本 PR 已完成 Bot 侧权限声明与预留接线,不把依赖冒充为真实控制 E2E。不修改独立服务端仓库;服务端 relay 的真实组合行为留给现场验收。
不把不同 IM adapter 强行改成同一种消息实现;无法同源的能力按明确 degraded/unsupported 行为和用户可见说明处理。
不新增 Mobile 原生依赖、原生配置或 runtime fingerprint。
不宣称五项真实环境验收已经完成。
用户可见变化:左侧新增 Bots 固定目录;Bot 是有长期身份、状态收件匣、Automation、委派和可挂 IM 的长期助手,而不是换皮任务。创建默认本地 Bot,IM Channel 后续按需挂载;能力受限时显示具体原因。
是否存在 breaking change:无静默 breaking。0092/0093 只新增表和索引,不改写旧 IM 表;旧代码遇到新 schema 必须按现有兼容守卫失败关闭。要退回旧安装版时,使用迁移前数据库备份,详见
docs/product-rules/cindy-bots-compatibility.md。北极星上手体验剧本
running且超过阈值无活动,或进入待决策但无人认领;确认 Guardian 仅唤醒一次,同一异常不重复投递,监管集合清空后 timer 自动停止。今天实踩的“任务停在待总控几小时但没人知道”必须在第 2—4 步被消灭;若状态变迁未进入收件匣、Bot 未激活或无法重新查询事实,本 PR 不得转 Ready。该剧本当前等待 #2804 接入和 Chris 在场实测。
UI 变化
docs/design-rules/DESIGN.md:语义 token、零阴影、标准圆角和间距、主题遮罩、标准任务对话、Light/Dark 双模式。docs/product-rules/task-and-conversation-naming.md:面向用户使用“任务 / 对话 / 消息”的既有边界。@面板:选择其它 Bot 后形成原生 mention chip,并沿消息队列、历史和重试链持久保留目标身份;Bot 任务加载失败留在原页面显示可操作错误态。离线验收沙箱
固定沙箱名:
cindy-bots-offline-demo。当前分支根目录执行:默认生成到:
后续仅由 Chris 或总控在明确授权后启动;本批没有启动:
无需登录即可离线查看:
control模板的总控身份、头像、职责与能力。inbox-only)。种库脚本默认拒绝覆盖现有目录;
--replace也只接受带本脚本所有权标记的演示目录,避免误删其它 userData。怎么验证的
已验证
本批 merge 最新主干后又完成:
此前本 Draft 的
pnpm check:i18n-glossary结果仍保持通过;本批没有修改词汇表。本轮 P0/P1 收口(合入 2026-08-17 最新
upstream/main后)再次验证:回归覆盖包括:添加向导不会被任务路由自动关闭;默认人格与三个预置人格都会获得同一 Bot 能力自知;能力说明要求先发现工具面再回答;委派目标无主任务时自动创建主任务,目标主任务可直接看到请求与终态结果,完整子任务仍独立归档;成功、失败、取消、超时、执行中 Renew、重复 settle 与重启恢复均有回归;标准 ChatInput 的结构化
@Bot引用可序列化、投影、排队、历史展示和旧客户端降级;Bot 任务加载失败可重试且不静默跳转;长错误与投递内容可完整查看。本轮 Bots 标准化重设计验证(commit 72cee3b):
上一轮「Bot 委派进行中」状态条验证:
上一轮委派记录可见性修复验证:
手工验证
本批只实际运行了离线种库与数据库完整性检查,没有打开客户端。按约束没有启动 Dev、Electron、Vite、CDP 或任何客户端进程,也没有读取或修改模型授权、登录态或正式 userData。固定演示沙箱已用当前 migration 0093 重建;旧的本任务生成沙箱副本已移入废纸篓。
离线 UI 验收(无需登录)
Chris 或总控使用上面的固定命令启动后,可直接完成 Bot 目录、三种 Bot 状态、模板身份、主任务、事件时间线、历史任务、投递成功/失败/恢复、空态和错误态的 Desktop Light / Dark 目检。所有演示项都来自隔离 profile,不需要登录,不会碰正式版授权。
需活账号待验
需 Chris 真实环境待验(不强制要求登录)
风险
风险分类
影响与回滚
BotSessionStateTransitionSource.readSnapshot合同,未绑定真实 source;此前没有 fallback producer,避免两套任务事实再次分叉。coordinate只代表 Bot 的授权上限,不代表绕过cindy_helper的逐次鉴权。提交前检查
git commit -s,见 DCO)