fix(chat): stage selected attachments before sending#274
Conversation
Reviewer's Guide by Ameath小爱整理了一条清晰的查看路径,按着看会更顺手一些。 审查聚焦
文件级变更
关联 Issue
Tips and commands
Original review guide in EnglishThe review focused on the production path from
|
There was a problem hiding this comment.
小爱在需要留意的地方补了简短说明,方便逐处确认。
小爱已完成全部变更审查,共发布 2 条行级建议(高风险 0,中风险 1)。
Prompt for AI Agents
请逐项处理以下审查问题;修改前先核实上下文,修改后运行相关测试。
1. 暂存上传仍可提交选项 / Option submission bypasses staging guard
frontend/src/features/chat-stage/ChatStagePage.tsx:589 (RIGHT)
<issue_to_address>submitDisabled 仅作用于 InputLayer。选项出现时输入层仍可见,而 OptionsLayer 的按钮没有读取该状态;因此通过新 picker 发起上传后,用户仍能立刻选择选项并发送 submit-option。该命令与 send-message 共享回合提交路径,上传完成后附件会落入下一条草稿,而不是阻止这次提交。
English: submitDisabled only reaches InputLayer. Options remain enabled during a new picker upload and can immediately submit submit-option; the staged attachment is then added to the next draft after the turn has already advanced.</issue_to_address>
2. 重复选择同一文件会产生重复附件 / Repeated selection bypasses deduplication
frontend/src/features/chat-stage/ChatStagePage.tsx:295 (RIGHT)
<issue_to_address>这里每次选择都会清空 input 并发起新的暂存上传。暂存端点为每个文件生成 UUID 子目录并返回不同的 path,而 mergeChatAttachmentInputs 只按 kind + path 去重。因此重复选择同一文件会显示并发送两份附件,还可能占满 8 个槽位;旧 PathPickerDialog 传入相同原始路径时会被去重。
English: Every repeat selection is staged under a new UUID path, while deduplication uses kind + path. Selecting the same file twice therefore sends two attachments and can consume the attachment limit.</issue_to_address>
|
这一块儿之后可能要重构下,我们现在ChatVisionService里对文件和图片进行区分,边界有点不明确 |
What
data/chat_attachmentsstorage before sendingWhy
The previous picker returned an absolute local path and submitted it directly with
/api/chat/command. The backend intentionally rejects raw paths outside the allowed attachment root, so files selected from Downloads, another drive, or another external folder failed withAttachment path is outside the allowed directory.Drag-and-drop already avoided this failure by calling
/api/chat/attachments/uploadfirst. This change makes the picker buttons use that same established flow.Impact
Users can select images or ordinary files from outside the project. The files are copied into managed attachment storage, and the chat command receives only the staged path. Backend path validation is unchanged, so raw outside paths remain blocked and the security boundary is not expanded.
Checks
pnpm test— 109 files / 717 tests passedpnpm lint:typespnpm format:checkpnpm buildpython -m pytest -q test/unit/core/media/test_chat_attachments.py test/unit/plugins/test_user_input_attachments.py— 12 passedFixes #273
Summary by Ameath
小爱先把这次核对的重点轻轻拎出来,方便快速进入后续内容。
该 PR 将聊天舞台的 Image/File 路径选择器替换为浏览器原生文件选择,并通过既有附件上传端点暂存文件;普通发送按钮和 Enter 在暂存中会禁用。审查发现,选项提交仍能绕过该保护,且重复选择同一文件会作为不同暂存路径重复加入。
Enhancements
File[]交给uploadChatAttachments,返回的受管路径会进入send-messagepayload。InputLayer在附件上传未完成时禁用普通发送按钮和键盘提交。Tests
ChatStagePage测试,覆盖两个选择器、暂存路径及键盘发送竞态。Original summary in English
This PR replaces the chat-stage Image/File path picker with native browser file selection and stages files through the existing upload endpoint; the normal send button and Enter submission are disabled while staging is pending. The review found that option submission still bypasses this protection, and selecting the same file repeatedly adds it multiple times under distinct staged paths.
Enhancements
File[]touploadChatAttachments, and the managed paths are included in thesend-messagepayload.InputLayerdisables the normal send button and keyboard submission until attachment uploads finish.Tests
ChatStagePagetests for both pickers, staged paths, and the keyboard-send race.