Web Shell 中途插入消息的文件附件机制:qwen-code 会话附件能力深度解析
Web Shell 中途插入消息的文件附件机制qwen-code 会话附件能力深度解析【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-codeWeb Shell 在模型回答进行中插入用户消息mid-turn message时文件不能像图片那样即时进入当前回合而是被注解为输入标注后排队等待下一回合。本文剖析 qwen-code 如何借助 daemon 的session_attachments能力让注解文件走与普通带附件提示完全相同的持久化附件通道实现中途插入消息的即时文件上传、渲染与回收并介绍回退路径与删除清理的源码级实现。问题背景为什么中途插入的文件会卡在下一回合Web Shell 将用户的文件选择转换为两部分一部分是提示文本本身另一部分是文件输入注解input annotation对应 composerTag.ts 中的DaemonInputAnnotation。在设计此功能之前带注解的提示annotated prompt只能等待下一回合才被 daemon 受理而图片却可以随时上传并插入到正在运行的回合中。这种不对称体验的根因是文件附件缺少与图片一致的中途插入通道。设计目标很明确——文件插入必须复用普通带附件提示已有的持久化附件与渲染路径而不是另起炉灶。相关设计文档见 web-shell-mid-turn-file-references.md。核心设计注解文件走上会话附件存储整个机制围绕 daemon 的session_attachments能力展开方案要点如下能力探测当 daemon 在连接能力capabilities中通告session_attachments特性时Web Shell 同时把 composer 文件附件和注解解析出的文件上传到当前会话的附件存储session attachment store。读取约束注解文件通过已选中的可信工作区trusted workspace经由现有的有界工作区文件读取器bounded workspace-file reader读取避免无限制读取导致的内存与带宽风险。载荷结构返回的附件引用attachment reference与图片引用一起随现有中途插入的content载荷发送给 daemon——不引入任何新的 daemon 协议或附件类型。失败回退包含非文件注解的提示、工作区所有权不可用、文件不可读或文件过大等情况继续走普通待处理队列pending queue或在 daemon 受理前恢复到编辑器。能力探测与上传的实现证据在 actions.ts 中promptContentWithUploadedAttachments首先通过getConnection().capabilities?.features.includes(session_attachments)判断是否支持附件上传并检查 session 是否实现了uploadAttachment。当文件存在但不支持上传时直接抛出File attachment upload is not supported随后把可上传的图片与文件分别调用session.uploadAttachment上传成功后才构造携带附件引用的 content。在会话类型定义 types.ts 中可以看到会话客户端需要实现readAttachment、removeAttachment等接口且注释明确提示当提示携带附件块时必须在附加引用前预检 daemon 的session_attachments能力。有界读取注解文件如何被安全地变成附件注解文件不能直接以路径形式发给 daemon而要先读取为 Blob 再上传。这一步复用 artifactUtils.ts 中的readWorkspaceFileAsBlob先statFile获取文件元数据大小、修改时间、类型目录直接拒绝超过maxBytes抛错按WORKSPACE_FILE_BLOB_CHUNK_BYTES分块调用readFileBytes(filePath, { offset, maxBytes })循环读取每次读取后检查isCancelled支持中途取消如用户切换会话或插入被中止。在中途插入流程 useQueuedPrompts.ts 中注解文件列表调用该方法时传入maxBytes: MAX_FILE_ATTACHMENT_DATA_BYTES。该常量定义于 imageIngestion.tsexport const MAX_FILE_ATTACHMENT_DATA_BYTES 8 * 1024 * 1024; // 8 MiB超过该上限的文件会被拒绝转而走普通队列或恢复编辑器这与设计文档oversized files continue through the ordinary pending queue的描述一致。中途插入附件引用随 content 载荷发送文件读取并上传成功后Web Shell 调用sessionActions.enqueueMidTurnMessage把消息加入 daemon 的中途队列。关键实现位于 useQueuedPrompts.tsreturn await sessionActions.enqueueMidTurnMessage( annotated?.displayText ?? trimmed, { signal: abort.signal, messageId: midTurnMessageId, onAdmissionStarted: () { enqueueDispatched true; }, ...(uploadedAttachmentReferences.length 0 ? { content: uploadedAttachmentReferences } : {}), }, );可以看出文本与附件分离enqueueMidTurnMessage的第一个参数是显示文本已剥离注解 token附件引用通过content字段携带。这正是设计文档所述返回的附件引用随现有中途插入的 content 载荷同行。显示文本剥离tokenannotated?.displayText已剔除注解 token因为被引用的文件会以附件行attachment rows形式渲染无需在文本中重复出现。稳定 messageId中途消息使用客户端生成的稳定 IDwebui_前缀的 UUID见 useQueuedPrompts.ts保证传输失败时可通过 reconcile 恢复而非误报拒绝。enqueueMidTurnMessage的 action 封装actions.ts区分了两种路径带 messageId 的新路径直接调用 daemon 的session.enqueueMidTurnMessage失败时抛出错误交由上层 reconcile因为 POST 可能已提交不能简单报拒绝不带 messageId 的旧 daemon 兼容路径失败时静默保留在浏览器队列中等待下一回合仅输出 debug 日志。渲染与会话内回声附件行如何恢复中途插入消息的附件渲染遵循与普通带附件提示一致的原则待处理附件显示在图片预览旁边可在现有的附件预览面板中打开**一致性恢复reconciliation与注入回声injection echo**从与普通带文件提示相同的resource附件引用中恢复附件行。在 useQueuedPrompts.ts 中可以看到队列对 daemon 回传的消息进行解析record[type] resource且携带attachmentId的记录被还原为附件行。此外midTurnInjectedSidechannel.ts 解析 daemon 的mid_turn_message_injected事件时也明确把resource块附件引用视为可渲染内容——说明中途注入事件与附件行恢复是同一套语义。会话切换、页面刷新等场景下附件数据只存在于 daemon 侧的会话附件存储中客户端队列中的附件摘要通过 reconcile 从 daemon 恢复从而保证附件行不会因本地状态丢失而消失。删除清理先删消息再删附件删除一条已排队的中途消息时附件清理有严格的先后顺序与失败语义见 useQueuedPrompts.ts 的removeMidTurnPromptForActionconst result await sessionActions.removeMidTurnMessage( target.midTurnMessageId, { sessionId: target.sessionId }, ); if (result.removed) { await Promise.allSettled( (target.files ?? []).flatMap((file) file.attachmentId ? [ sessionActions.removeAttachment(file.attachmentId, { sessionId: target.sessionId }) ] : [], ), ); }要点如下先删消息后删附件只有 daemon 确认消息被移除result.removed true后才逐个调用removeAttachment清理附件失败保留附件若消息删除失败如消息已被投递或完成附件保持完整——因为排队中或运行中的消息可能仍然需要它们删除失败的用户反馈删除失败时若消息已不在中途队列会通过reportError提示用户并根据会话是否空闲决定直接移除本地行还是标记midTurnFailedAction等待重试。对于进行中的提交midTurnState submitting或正在插入的消息删除会被直接忽略useQueuedPrompts.ts避免在附件上传/注入过程中破坏数据一致性。上传中途失败时已上传成功的附件也会通过removeUploadedAttachments回滚useQueuedPrompts.ts。兼容性旧 daemon 与既有行为设计文档明确了两个兼容性承诺源码中亦有对应实现场景行为源码依据旧 daemon 未通告session_attachments注解提示继续走普通队列下一回合受理actions.ts 能力探测失败时走toDaemonPromptContent内联路径纯图片的中途插入与文本插入行为完全不变useQueuedPrompts.ts 中图片走既有imageList上传分支文件存在但不支持上传抛出File attachment upload is not supportedactions.ts值得注意的细节是上传遇到 404如 daemon 中途重启导致会话附件存储不可用时实现会回退为内联文本/图片模式而非报错actions.ts进一步强化了能降级就不阻塞的兼容策略。同时若会话通告了session_sources能力已接受的附件引用还会注册为会话源session source便于在会话侧边栏等界面展示消息来源actions.ts。总结web-shell-mid-turn-file-references设计让 qwen-code 的 Web Shell 在不引入任何新协议的前提下把中途插入消息的文件附件统一到了会话附件存储体系能力驱动以session_attachments作为功能开关旧 daemon 自然回退有界读取8 MiB 上限 分块读取 可取消避免内存与带宽失控载荷复用附件引用随既有content载荷发送与普通带文件提示共用resource附件引用语义安全删除先删消息、后删附件失败保留杜绝悬挂引用与误删。如果你需要深入这段实现推荐从 useQueuedPrompts.ts中途队列核心状态机、actions.ts附件上传/删除 action与配套测试 useQueuedPrompts.midTurnReconcile.test.tsx、actions.test.ts 入手它们覆盖了中途插入附件的上传、注入、恢复与删除全链路。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →