十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Qwen Code 后台任务通知的会话回放落位机制:`background_notification` 源标记与 Web Shell 系统消息渲染

Qwen Code 后台任务通知的会话回放落位机制:`background_notification` 源标记与 Web Shell 系统消息渲染 Qwen Code 后台任务通知的会话回放落位机制background_notification源标记与 Web Shell 系统消息渲染【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code输出文章Qwen Code 后台任务通知的会话回放落位机制background_notification源标记与 Web Shell 系统消息渲染导读本文围绕设计文档 task-notification-transcript-placement.md 展开剖析 Qwen Code 如何让后台任务完成通知background task notification在实时live与历史回放replay两条路径上保持一致的语义与展示实时路径通过_meta.source background_notification标识这类模型输入model inputs而非用户主动输入的提示词历史回放则把持久化的通知记录投影为同样带源标记的消息并由 Web Shell 转录适配器统一映射为variant: info的系统消息。读完本文你将掌握该机制的完整数据流、源码落点与测试验证方式。一、问题背景后台任务完成通知为什么不能当作用户消息在 Qwen Code 的 daemon 会话模型中后台任务background task / subagent完成时产生的通知内容本质上是模型输入不是用户亲手敲入的 prompt。设计文档明确指出Background task completions are model inputs, not user-authored prompts.问题的关键在历史回放路径上当会话重新打开、daemon 把持久化的 transcript 记录逐条投影出来时旧实现把这些通知记录投影成不带任何标记的普通用户消息history replay previously projected persisted notification records as unmarked user messages。这会导致两个后果语义失真用户在回放视图里会看到一条自己发出的、却从未输入过的消息与实时路径不一致实时路径已经用background_notification源标记区分了这类消息回放路径却没有同步导致同一类内容在两条路径上呈现不同的角色与样式。因此该设计的目标非常明确让历史回放与实时通知共用同一套源标记 系统消息语义。二、实时路径的既有标记_meta.source background_notification在实时链路中后台任务通知在产生时就被打上了源标记。从源码结构看该标记贯穿 daemon 更新、桥接层与 CLI 会话协调器多个环节在 ACP 桥接层的 transcript 回放投影中record.subtype notification的记录会被投影为role: user、且携带extra.source background_notification与qwenDiscreteMessage: true的消息同时保留backgroundTask结构化载荷transcript-replay.tsCLI 的 live 会话协调器会在agent_message_chunk事件流中按source background_notification识别这类文本并通过updateBackgroundTaskId()从_meta.backgroundTask.taskId提取后台任务 ID用于语音/播报等下游处理live-session-coordinator.tscreate-sub-session也依赖update._meta?.source background_notification与backgroundTask.taskId匹配来判定通知归属create-sub-session.ts。可见background_notification是一个跨层约定的源标记常量实时通知从产生到消费全链路都依赖它。三、回放路径的核心变更保留模型输入角色 复刻源标记设计文档给出的回放侧方案可拆解为三层保留持久化的模型输入角色回放投影时不再把通知记录降级为普通用户消息而是沿用记录本身携带的角色语义role: user的模型输入语义补上相同的源标记投影结果附带与实时通知一致的source: background_notification标记沿用结构化任务状态持久化记录若包含已有的结构化 task statuscompleted/failed/cancelled回放与实时使用同一套标签旧记录缺失该状态时回退到通用通知标签。代码层面的落地正是这样在 transcript-replay.ts 的projectUserRecord中record.subtype notification的分支会把backgroundTask从systemPayload里解析出来并连同extra.source background_notification一起写入投影后的消息元数据。也就是说回放投影本身只是加标记、保载荷并没有改变其他消费者对共享回放语义的解读——这正是设计文档强调的without changing shared replay semantics for other consumers。需要留意的是这里的保留 model-input role并不意味着回放消息在 UI 上显示为用户消息。角色保留是数据层语义它仍是模型输入而展示层由 Web Shell 适配器接管见下一节。四、Web Shell 转录适配器统一映射为信息型系统消息真正的展示转换发生在 Web Shell 客户端的转录适配器 transcriptToMessages.ts。适配器定义了判定与取数两个关键函数isBackgroundNotificationBlock(block)检查block.meta?.source background_notificationL338-L343getBackgroundNotificationData(block)从meta.backgroundTask中取出结构化任务数据L345-L350。在块投影主循环中无论是user块还是assistant块只要命中isBackgroundNotificationBlock都会被投影为{ role: system, content: textBlock.text, variant: info, source: background_notification, data: getBackgroundNotificationData(textBlock), timestamp: blockTime, sourceBlockIds: [block.id], }user 分支见 L417-L431assistant 分支见 L489-L502。这段投影同时说明了设计文档中的两个细节from either a user or assistant chunk通知内容可能以 user 块、也可能以 assistant 块的形式出现在 transcript 中适配器对两者一视同仁统一折叠为role: system的系统消息content is rendered unchangedcontent直接透传原始文本展示层不再对文本本身做改写。此外适配器维护了needsNewContentMessage标记遇到通知块时强制开启下一条内容必须新建消息避免通知文本被错误地并入相邻的助手消息L418-L420。五、渲染层语义状态图标 回退标签系统消息组件 SystemMessage.tsx 针对source background_notification走专门的渲染分支L221-L257状态标签映射status completed→system.taskCompletedstatus failed→system.taskFailedstatus cancelled→system.taskCancelled其余/缺失 → 通用system.taskNotification即设计文档所说的older records fall back to a generic notification label语义图标completed用CircleCheckIcon勾、failed用CircleXIcon叉、cancelled用CircleMinusIcon减号、其余用InfoIcon信息音调tonesuccess/error/neutral通过data-tone作用于图标样式结构化文案当backgroundTask数据里带有kind如shell、monitor、agent与status时尝试使用notification.{kind}.{status}的 i18n 文案并注入commandLabel、description、eventCount、droppedLines等变量无法构造时回退到直接渲染原始contentL270-L295。最终渲染为左侧的通知气泡notificationBubble图标与文案并排视觉上与普通用户消息、助手消息明显区分L305-L326。设计文档所述keeps both live and replayed notifications visible on the left即指这类通知始终出现在会话流左侧的信息性气泡中。六、任务状态的另一面turn-notification 上下文的结局判定除 transcript 内的状态标签外通知的结局判定还有一套并行的上下文实现turn-notification-context.ts 定义了TurnNotification.outcome四态completed/failed/ended/cancelledL35-L38。在observe()中turn_complete与turn_error事件被换算为结局turn_error→failedstopReason cancelled→cancelledstopReason end_turn→completed其他 →endedL399-L407。同时它用MAX_RECENT_TURNS 1024上限约束 pending 与 handled 集合防止长时间运行的会话导致通知状态无限膨胀。这层实现回答的是这条后台任务最终怎么结束而 transcript 层的status回答的是这条通知以什么状态落库/回放两者共同构成完整的通知语义。七、测试与验证回放与实时的一致性证据仓库中的测试用例直接印证了设计文档的各项承诺transcriptToMessages.test.ts实时通知渲染为系统消息renders live background task notifications as system messagesL397 起断言role: system、variant: info、source: background_notification回放通知同样渲染为系统消息renders replayed background notifications without task metadataL629 起验证旧记录缺省backgroundTask元数据时仍能正确降级渲染对应设计文档older records fall back to a generic notification label历史状态参数化测试uses an in-range background notification for historical %s statusL223 起对历史状态做参数化覆盖agent 通知投影到工具卡片通知数据会附着到对应 agent 工具消息上L497-L620且非 agent 通知不会被误投影到 agent 工具L596 起。桥接层的回放测试transcript-replay.test.ts与 CLI 侧的background_notification_turn_complete事件测试live-session-coordinator.test.ts进一步覆盖了从 daemon 事件到桥接投影再到协调器处理的完整链路。八、小结一条标记贯穿两条路径总结这套机制的关键设计决策层面实时路径回放路径统一落点数据语义_meta.source background_notification模型输入持久化记录投影时补上相同源标记保留模型输入角色transcript-replay.ts展示映射适配器识别为系统消息适配器识别为系统消息transcriptToMessages.ts状态标签completed/failed/cancelled结构化状态同左旧记录回退通用标签SystemMessage.tsx渲染样式左侧信息气泡 语义图标同左notificationBubbleL305-L326其核心价值在于源标记是唯一的事实来源实时与回放共享同一套消费逻辑既避免了回放时把模型输入伪装成用户输入又保证不同消费者Web Shell、CLI 协调器、子会话对通知语义的解读一致——这也正是设计文档中without changing shared replay semantics for other consumers的工程取舍所在。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表