Repository navigation
fix(ui): cite chat attachments by their own name - #6896
Conversation
|
Verdict: Approve with suggestions Answers about a file attached in chat will now cite a readable form of the file's name, such as
Real-world evidenceN/A here: no evidence bundle was produced for this run. Part of this verdict rests on static review alone. The PR description has its own evidence: a main-vs-branch table of upload names and citations, and the upload endpoint's new 🔍 Technical detailsIssues 🟡 Follow-up: cite the user's exact name, not the sanitized stem ( 🟢 Stale comment ( Checks run outside the diff
Strengths
|
Summary
Answers about a file attached with the + button now cite the file's own name instead of GAIA's internal upload ID:
According to kestrel-plan.pdf, page 1:rather thanAccording to f27f4885-cec8-4161-9dbd-ebc8a3c25005.pdf, page 1:.Why
The agent only ever saw the upload copy's random name, so that's what it cited, and users couldn't tell which file an answer came from.
Linked issue
Closes #5183
Changes
src/gaia/upload_names.py, the one place that knows the naming. Attachments are stored as<12 hex>_<name><ext>, and the prefix is removed for display only when the file is directly insidechat/uploads.upload_fileuses the new name./api/files/uploadstill returnsfilename,original_nameandurl, butfilenameis no longer a UUID.query_specific_filecites the readable name in its instruction and messages.fileandsource_fileskeep the exact path, so the file can still be opened.Decisions to check
_sanitize_stem: the triage comment suggested reusing it fromdocuments.py, but it keeps spaces and parentheses.UPLOAD_LINK_REstops at a space or), andUPLOAD_URL_REinmarkdown.tsonly serves ASCII letters, digits,.,_and-, soQ3 plan (final).pdfwould stop working as a link. This keeps only those characters.UPLOAD_URL_RErequires.<uuid>.pdfcopies from before this change don't match, so they keep their full name.Limits
_, soQ3 plan (final).pdfis cited asQ3_plan_final.pdf.attachment.pdf. The original name still appears on the link and in the turn summary.query_documentsstill asks for the full path, as it does for every document. That path now ends in a readable name, with the prefix.Test plan
Run in a clean
python:3.12-slimcontainer, with.[ui]and the test tools installed:pytest tests/unit/chat/ui/test_upload_names.py tests/unit/chat/ui/test_upload_links.py tests/unit/chat/ui/test_attachment_scope.py tests/unit/chat/ui/test_upload_serving.py tests/unit/chat/ui/test_media_upload.py tests/unit/chat/ui/test_sse_handler.py tests/unit/chat/ui/test_turn_summary.py tests/unit/test_rag_citation_instruction.py tests/unit/test_rag_file_resolution.py tests/integration/test_files_router.py: 604 passed, 1 skipped.black --checkandisort --check-onlyon the changed files: clean.pytest tests/unit: 35,021 passed. It was run with.[ui]only and without git history, so it also had 96 failures and 523 errors. Many were missing test tools. I reran the 95 affected test files with those tools installed: 25 failures, none in the files this PR changes. Most also fail onmain, and the rest need git history, which my container's copy didn't have.Not run:
python util/lint.py --all, the web UI tests, and a real model. The last means this confirms the instruction sent to the model, not a model's actual answer.Evidence
The same upload and
query_specific_filesteps, onmainand on this branch:mainkestrel-plan.txt368b4401-2336-47a7-9c69-31a64dce33ee.txtkestrel-plan.txt25da2dcd4869_kestrel-plan.txtQ3 plan (final).txt38152cd4-d404-4bb2-a928-d9cd8cc22a64.txtQ3_plan_final.txt19bab3a67092_Q3_plan_final.txt-draft.txtcc50ebe6-f0d4-4c66-9c15-0acbd1800208.txtdraft.txt174b21ed143a_draft.txtتقرير.txt08688a4d-3d5a-4a81-91d2-c6a5305e210c.txtattachment.txt5ac458ed0c96_attachment.txtThe step label changes from
Indexed <uploads>/368b4401-….txt (1 chunks)toIndexed kestrel-plan.txt (1 chunks). On both versions, every file still resolves through the agent's link handling and matchesUPLOAD_URL_RE./api/files/uploadreturns the newfilenameform, shown above.Checklist
Closes #N/Fixes #N/Refs #N).python util/lint.py --all,pytest tests/unit/). Partly:black,isortandpytest tests/unit/as described above, notutil/lint.py.