qwen-code 会话附件引用(Session Attachment References)设计解析:从 base64 内联到文件名引用的存储与生命周期

发布时间:2026/9/13 22:53:20

qwen-code 会话附件引用(Session Attachment References)设计解析:从 base64 内联到文件名引用的存储与生命周期 qwen-code 会话附件引用Session Attachment References设计解析从 base64 内联到文件名引用的存储与生命周期【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code导读本文以 qwen-code 设计文档 docs/design/session-attachment-references.md 为骨架系统讲解 daemon 如何将图片与任意文件字节落盘到会话附件目录、以文件名引用attachment reference替代 base64/字节内联从而避免在 daemon 请求、队列、事件与回放replay数据中重复携带大体积负载的设计。读完本文你将掌握附件引用的数据结构与命名规则、存储位置与所有权模型、8 MiB 单文件上限等边界约束以及session_attachments能力与/session/:id/attachmentsHTTP 路由在 TypeScript SDK 与 web-shell 中的真实调用形态。背景问题内联负载带来的重复膨胀在引入附件引用之前图片 base64 与文件字节会被直接嵌入 daemon 的请求体、消息队列、事件流和会话回放数据中。同一份附件在「上传 → 排队 → 转发给 ACP 子进程 → 会话记录回放」的每一跳都会被复制一份产生以下问题负载重复膨胀同一字节在多份请求/事件中反复出现内存与网络开销随链路长度线性放大回放困难附件需要在 daemon 重启后仍可预览内联字节若只存在于进程内存中重启即丢失无统一出处不同客户端各自携带字节缺少单一可信来源single source of truth。设计文档给出的解法非常直接daemon 将图片和任意文件字节写入 workspace runtime 的附件目录只返回一个基于文件名的引用后续所有链路传递的都是这个轻量引用。核心数据结构基于文件名的附件引用daemon 在存储附件后返回如下引用对象{ type: image | resource; attachmentId: string; mimeType: string; size: number; }各字段含义字段说明typeimage图片或resource任意文件资源attachmentId附件在存储目录中的文件名即引用本身mimeType附件 MIME 类型如image/png、application/pdfsize附件字节大小这一结构在 TypeScript SDK 中有完全对应的类型定义见 packages/sdk-typescript/src/daemon/types.ts#L4676-L4681export type DaemonSessionAttachmentReference Recordstring, unknown { type: image | resource; attachmentId: string; mimeType: string; size: number; };配套的读取结果类型为DaemonSessionAttachmentData{ data: string; mimeType: string }data 为 base64 字符串见 packages/sdk-typescript/src/daemon/types.ts#L4683-L4686。命名规则与去重attachmentId 就是存储文件名没有独立的 ID 体系重名文件采用平台通用约定追加序号name (1).ext、name (2).ext以此类推不存在内存中的附件索引也没有 sidecar 元数据MIME 类型与大小在读取时直接从存储文件推导从而避免了索引与实际文件之间的一致性维护成本。引用在链路中的流转Prompt 与 mid-turn API 将引用对象随队列、事件、会话记录元数据transcript metadata一起传递但只有真正向 ACP 子进程派发dispatch时才由 bridge 解析引用——即「引用轻量传递、字节延迟物化」。TypeScript 会话客户端通过带鉴权的附件路由authenticated attachment route读取同一份引用用于预览与回放渲染文本类资源解析为 ACP text其他文件格式解析为 ACP blob原始字节不会在浏览器中被解码或改写。对应实现中上传与解析的桥接逻辑位于 packages/channels/base/src/DaemonChannelBridge.ts含removeAttachment钩子、session_attachments能力预检与按批次扇出上传、以及不支持该能力时的图片内联降级路径浏览器侧的预览/回放水合逻辑见 packages/web-shell/client/daemon/session/actions.ts 与 packages/web-shell/client/daemon/session/types.ts。存储位置与所有权模型存储路径附件落盘于 workspace runtime 的附件目录~/.qwen/tmp/workspace-hash/attachments/session-id/其中workspace-hash是 workspace 的哈希标识session-id是会话 ID使用自定义 runtime 目录时路径等价替换。所有权与鉴权resolved live-session owner 与客户端授权保护每一次上传upload、读取read与移除remove操作关闭 daemon 或客户端断开连接只关闭文件句柄不会删除文件——附件是持久化资源不随连接生命周期消失永久删除会话时其附件目录一并移除避免孤儿文件残留。生命周期策略刻意从简设计上刻意排除了常见的复杂回收机制无 TTL附件不设过期时间无 sweeper没有后台清扫任务无 retained-media cache不维护媒体缓存无重启重建索引daemon 重启不需要重建任何附件索引。这与「无内存索引、无 sidecar 元数据」的设计一脉相承附件就是普通文件文件名即 ID状态完全可由文件系统自身表达。大小限制与配额单个附件上限 8 MiB8 * 1024 * 1024字节会话没有累计附件大小或数量上限。在源码中单文件上限常量定义为SESSION_ATTACHMENT_MAX_ITEM_BYTES 8 * 1024 * 1024另有SESSION_ATTACHMENT_MAX_NAME_BYTES 255限制文件名长度见 packages/acp-bridge/src/sessionAttachments.ts#L13-L14。同一文件中还定义了受支持的图片 MIME 类型集合image/bmp、image/gif、image/jpeg、image/png、image/webp。能力声明与统一 HTTP 接口能力session_attachments统一能力标识为session_attachments在 serve 能力表中声明为v1起可用见 packages/cli/src/serve/capabilities.ts#L57-L58。HTTP 表面/session/:id/attachments统一 HTTP 路由为/session/:id/attachments不存在session_media、/media或mediaId之类的兼容路径——设计上明确只保留一套接口。TypeScript SDK 在 packages/sdk-typescript/src/daemon/DaemonClient.ts 中提供了四个对应的客户端方法方法HTTP 路由作用uploadSessionAttachment(sessionId, data, name, mimeType, opts?)POST /session/:id/attachments?namename上传字节请求体为原始字节流Content-Type即附件 MIME返回引用对象readSessionAttachment(sessionId, attachmentId, opts?)GET /session/:id/attachments/:attachmentId读取附件内容返回{ data: base64, mimeType }listSessionAttachments(sessionId, opts?)GET /session/:id/attachments按上传顺序列出该会话当前存储的全部附件引用removeSessionAttachment(sessionId, attachmentId, opts?)DELETE /session/:id/attachments/:attachmentId删除附件返回{ removed: boolean }从实现细节可以印证设计中的几个要点引用即文件名上传 URL 以 query 参数name携带原始文件名daemon 据此落盘并返回attachmentId即存储文件名见 DaemonClient.ts#L4080-L4102读取时推导 MIME 与大小读取响应的mimeType直接取自响应头content-type缺失时回退为application/octet-stream见 DaemonClient.ts#L4128-L4163浏览器兼容读取实现将Uint8Array分块每块0x8000字节再btoa编码避免超出引擎参数上限注释明确说明该包同时面向 Node 与浏览器环境mid-turn 预检enqueueMidTurnMessage的文档注释提示调用方应先预检session_attachments能力旧 daemon 会忽略 media 字段并丢弃图片内容见 DaemonClient.ts#L4212-L4229。web-shell 会话层将这四个方法进一步封装为uploadAttachment/readAttachment/listAttachments/removeAttachment含read_attachment、remove_attachment等权限动作并会在附加附件块前预检能力见 packages/web-shell/client/daemon/session/types.ts#L565-L581 与 packages/web-shell/client/daemon/session/actions.ts#L2546-L2625。实现层面的安全加固目录防替换校验虽然设计文档保持简洁但从实现可以看到一层额外的持久化安全措施附件存储目录被包装为DurableAttachmentDirectory通过持有目录句柄并校验dev设备号与inoinode 号来检测目录是否被替换如符号链接攻击或目录被删除重建校验失败时抛出Session attachment parent directory changed.见 packages/acp-bridge/src/sessionAttachments.ts#L23-L71。这层校验与文档「resolved live-session owner 和客户端授权保护每一次上传、读取、移除」的所有权要求互相配合共同构成附件读写的安全边界。小结引用式附件设计的取舍会话附件引用方案的核心取舍可以概括为以文件名替代字节内联让队列、事件与回放数据只携带轻量引用字节只存在于磁盘与最终物化环节文件系统即状态无索引、无 sidecar、无 TTL、无重建生命周期完全由会话删除驱动换来极低的维护复杂度边界清晰单文件 8 MiB、文件名 255 字节上限、统一session_attachments能力与/session/:id/attachments路由且不保留任何旧式/media兼容路径。对需要集成 qwen-code daemon 的客户端而言接入路径非常明确预检session_attachments能力 → 通过POST /session/:id/attachments上传并拿到attachmentId→ 在 prompt/mid-turn 内容块中携带引用 → 需要预览或回放时通过GET路由按 ID 读取、按需DELETE。相关类型定义、客户端方法与桥接实现均可在 packages/sdk-typescript/src/daemon、packages/acp-bridge/src/sessionAttachments.ts 与 packages/channels/base/src/DaemonChannelBridge.ts 中进一步查阅。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/13 23:48:22

POD与DMD全解析:从流场数据提取时空模态的Python实现

简介:面向流体力学与信号处理学习者的POD与DMD算法速览包,聚焦本征正交分解与动态模态分解的原理及MATLAB实现,适合需要快速理解流场降维和动力学特征提取的初学者或研究人员。压缩包内共3个文件,其中POD_DMD.m为可直接运行的MATL…

2026/9/13 23:48:22

2012年的ezcaddll.dll怎么处理?依赖分析与冲突修复指南

简介:面向 CAD 软件开发者的 EzCAD DLL 库详解资料,专为需要快速集成图形绘制、几何计算、工程图标注等功能的 C 开发者准备。资源为 rar 压缩包,仅 2 个文件,体积 180KB,轻量且聚焦:.h 头文件声明了 EzCAD…

2026/9/13 23:48:22

WorkBuddy连接全攻略:从SSH到数据库的排查方法

1. 连接的本质:WorkBuddy在开发链路里到底在连什么如果你用过WorkBuddy,大概率有过这种经历:下载装好了,界面也打开了,模型也能聊,可真到干活的时候——连远程服务器连不上,连数据库超时&#x…

2026/9/13 23:48:22

C++异常的认识与实践

目录 一. 异常的概念 二. 异常的抛出和捕获 2.1 代码示例: 三. 栈展开 四. 查找匹配的代码处理 4.1 代码示例 五. 异常重新抛出 5.1 代码示例:网络请求重试 六. 异常安全问题 6.1 代码示例: 七. 异常规范 八. C的标准库的异常 一…

2026/9/13 23:48:22

Kimi LeetCode 71. 简化路径 C语言实现

LeetCode 71. 简化路径 (C 语言) 思路:与栈的思路一致。path 参数可写,直接在原串上原地分割,用一个指针数组 stack 保存各目录名的起始位置,最后原地拼接结果。 char* simplifyPath(char* path) {int len strlen(path);// 最多 len/2 1 个目录名,外加哨兵 \0char** stack (…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/13 11:18:28

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码