Skip to content

fix(attachments): send SVG inputs as files instead of model images - #969

Merged
vastsa merged 4 commits into
vastsa:mainfrom
inorilzy:fix/svg-attachment-input-946
Sep 23, 2026
Merged

vastsa merged 4 commits into
vastsa:mainfrom
inorilzy:fix/svg-attachment-input-946

Conversation

@inorilzy

@inorilzy inorilzy commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Closes #946

问题与修复

在上游 3d9c3498fb9fdb1bfec81158f6dbfa7dfa150b42 独立复现:无扩展名、MIME 为 image/svg+xml 的剪贴板附件被保存为 .bin,并标记为 image。发送准备与历史恢复随后只按视觉能力判断是否内联,没有排除 SVG。

本 PR 保留 SVG 源文件并使用安全文件回退,不引入栅格化或新依赖:

  • shared 中统一识别 SVG MIME(忽略大小写及参数)及 .svg 文件名/路径,优先于旧的 kind: image 或冲突的位图 MIME。
  • 剪贴板与原生文件导入将 SVG 分类为文件;无扩展名的 SVG 补充 .svg,原始字节保持不变。
  • Electron main 在发送边界再次检查:SVG 不产生 inlineData,使用现有安全 @path 引用;旧内容寻址 SVG 重试时复制到所属会话 scratch 的 replayed/ 目录。
  • 将现有历史附件恢复逻辑抽出为可测试的 attachment-history.ts。恢复旧会话时也将 SVG 作为文件,并清除旧的临时图片数据,引用缺失或越界时亦如此;不改写数据库、不删除原附件。
  • 其他图片的既有分类、视觉能力判断、内联大小限制和路径权限检查不变;不引入声称适配所有服务商的位图白名单。

本地定向验证

新增 apps/desktop/test/svg-attachments.test.mjs,覆盖剪贴板、原生选择器服务、项目路径附件、混合 SVG/PNG、旧附件重试、历史恢复、过期图片数据、非视觉模型、越界/符号链接及非 SVG 图片回归。

  • 修复前的 11 项回归:10 项失败、1 项通过。
  • 修复后:node --experimental-strip-types --test apps/desktop/test/svg-attachments.test.mjs,16/16 通过,0 skipped。
  • 原有大图片保护测试的 8 条源码断言独立执行通过;对应测试改为检查抽出的历史模块,没有删除断言。
  • git diff --check、测试文件语法检查和 6 个变更 TypeScript 文件的类型剥离语法检查通过。后者不是 TypeScript 类型检查。
  • 初始代码提交的 10 个发布文件逐一核对了远端与本地 Git blob SHA;后续三个提交仅补充中文源规格说明及中英文导航,共增加 4 行文档,生产代码和测试未变。

本地环境限制

容器无法解析 GitHub 域名,不能正常克隆或安装工作区依赖。通过已授权 GitHub 接口读取源码并核对 blob SHA 后建立隔离源码工作树,使用现有 Node v22.16.0(低于仓库要求的 22.19)及未提交的临时最小 shared 导出模块执行上述定向测试。该模块使用原有文件引用格式化逻辑、错误码、大小上限,并加载本次实际 SVG helper。因此,本地结果不是完整工作区或真实桌面运行结果。

GitHub Actions 验证

初始代码提交 bfec2b8 的 CI run 已确认以下步骤通过:

  • 工作区 JS 构建(包括 shared、agent-runtime、Electron 桌面及文档构建)
  • Desktop TypeScript 类型检查
  • Lint 和架构检查
  • Rust host-core format/lint/test job

初轮单元测试在文档检查处失败,明确原因是新中文页缺少“英文源规格”说明,以及两份 NAV 未收录新页面。这些遗漏已在 f2db87f、df4e558、b322ce7 补齐,未改变生产代码。当前 head 的 CI、Docs check 和 PR base 已触发;更新本说明时仍在排队/运行,不声明最终 CI 或全量单元测试已通过。

文档与 Draft 原因

新增中英文 svg-attachment-input.md 并加入各自 NAV,记录传输约定及 E2E-ATTACHMENTS-svg-file-fallback 验收场景。

NOT RUN: 本地完整工作区构建/类型检查/全量测试、Electron → main → sidecar → 模拟 provider 的完整端到端测试、真实服务商兼容测试。服务层回归不能替代桌面 E2E;该场景还需同步至主 E2E 计划和追踪矩阵。PR 保持 Draft,不声明可直接合并。

没有修改协议、存储 schema、模型配置、主分支或其他贡献者的分支。

Use a shared SVG classification for clipboard imports, prompt preparation,
and restored history. Preserve SVG bytes as safe file references, including
legacy content-store attachments, without changing raster image transport.

Add targeted service regressions and document the remaining desktop E2E gate.
@inorilzy
inorilzy marked this pull request as ready for review September 23, 2026 15:23
@inorilzy

Copy link
Copy Markdown
Contributor Author
image 已修复

@vastsa
vastsa merged commit 1bc1a5d into vastsa:main Sep 23, 2026
4 checks passed
vastsa added a commit that referenced this pull request Sep 23, 2026
- ADR 0255: mention devkit author-time check (#944)
- 08-component-spec: cross-reference SVG file-only classification (#969)
- e2e-test-plan: register E2E-ATTACHMENTS-svg-file-fallback scenario (#969)
- zh-CN 08-component-spec: mirror SVG exclusion rule (#969)
- zh-CN 09-interaction-patterns: add §3.4 queued send with promoted-row
  cancel semantics (#965)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] SVG 矢量图被作为模型图片输入发送,导致不支持该格式的模型返回 400

2 participants