Skip to content

feat(web): binary file attachments for Ask#1375

Draft
whoisthey wants to merge 6 commits into
whoisthey/text-file-attachmentsfrom
whoisthey/binary-file-attachments
Draft

feat(web): binary file attachments for Ask#1375
whoisthey wants to merge 6 commits into
whoisthey/text-file-attachmentsfrom
whoisthey/binary-file-attachments

Conversation

@whoisthey

@whoisthey whoisthey commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Adds support for binary (image) file attachments in Ask Sourcebot, building on the inline-text attachment work in the base branch. Users can attach PNG/JPEG/WebP/GIF images (drag-and-drop or file picker) to a chat message; the bytes are uploaded to app-mediated blob storage and sent to vision-capable models as native image content. Unlike text attachments, image bytes never travel in the messages JSON — they're referenced by id and served through an access-controlled route.

This is an enterprise (ee) feature, gated by the ask entitlement.

What's included

Data model & storage

  • New Attachment model + ChatAttachment join table + AttachmentStatus (PENDINGCOMMITTED) enum, with migration. Attachments are uploaded before any chat exists and linked to chats via ChatAttachment, keeping access purely chat-derived.
  • StorageBackend abstraction with a LocalFsStorageBackend (bytes under DATA_CACHE_DIR/attachments); an S3 driver is planned as a follow-up.
  • New blob variant on the AttachmentData discriminated union (references stored bytes by id; bytes stay out of message JSON).

Upload & serving

  • POST /api/ee/chat/attachments: authenticated (no anonymous uploads), entitlement-gated, validates content type by magic bytes (not client MIME/extension; SVG intentionally excluded), enforces a server-side size cap, and returns the attachmentId. Images upload on select.
  • Commit-on-send: commitMessageAttachments links referenced blobs to the chat and flips PENDING → COMMITTED, rejecting forged/unauthorized ids before the agent runs.
  • GET /api/ee/chat/{chatId}/attachments/{attachmentId}: serves bytes only when the caller can view the chat and a ChatAttachment link exists; sets X-Content-Type-Options: nosniff and a header-safe Content-Disposition.

Agent / model integration

  • Server-authoritative image capability resolution (from the models.dev catalog); the client signal is never trusted.
  • resolveLatestTurnImages loads bytes from storage for the latest user turn (only for blobs linked to that chat) and buildUserModelMessage attaches native image content parts. Image bytes are only sent on the turn they were added; a short marker is left when images are dropped (older turn or a text-only model).

Client UI

  • Image attach affordance is gated on the selected model's image capability; the file picker / drag-overlay accept includes image types only when supported.
  • Pending-image tray pill with thumbnail, upload status (uploading / uploaded / error), on-hover preview, and a full viewer dialog. Submit is blocked while uploads are in flight.
  • Preview cache so a just-sent image renders its preview instantly instead of 404ing on the serving route during the brief pre-commit window.

Lifecycle & cleanup

  • Orphan pruner (backend worker) periodically deletes PENDING (uploaded-but-never-sent) blobs older than a TTL, along with their bytes.
  • Deleting a chat sweeps blobs left with zero links; duplicating a chat copies the attachment links (metadata only, no byte copy).

Config / observability

  • New env vars: SOURCEBOT_CHAT_ATTACHMENT_MAX_IMAGE_BYTES (default 10 MiB) and SOURCEBOT_CHAT_ATTACHMENT_ORPHAN_TTL_HOURS (default 24, 0 disables). Documented in environment-variables.mdx.
  • New analytics: chat_attachment_uploaded, chat_attachment_degraded.

@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7aa5f8af-e1c6-4b6b-8823-bbebb4e0391a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch whoisthey/binary-file-attachments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

1 participant