Skip to content

feat(webui): add file attachment support to WebSocket channel#3361

Open
dividduang wants to merge 1 commit intoHKUDS:mainfrom
dividduang:feat/webui-file-attachment
Open

feat(webui): add file attachment support to WebSocket channel#3361
dividduang wants to merge 1 commit intoHKUDS:mainfrom
dividduang:feat/webui-file-attachment

Conversation

@dividduang
Copy link
Copy Markdown

Summary

  • Add file attachment upload capability to the webui composer (paperclip button)
  • Files are encoded as base64 data URLs in the WebSocket message envelope
  • Backend decodes, saves to disk, and passes media paths to the agent loop
  • Enforce per-file (10MB), per-message (25MB total), and count (20) limits

Changes

Backend (nanobot/channels/websocket.py):

  • Add _save_media_data_urls() static method: base64 data URLs → on-disk files
  • Extend _dispatch_envelope to handle optional media field in message envelopes
  • Allow empty content when media is present

Frontend (webui/src/):

  • ThreadComposer.tsx: Add paperclip attachment button, file input, preview badges with remove
  • ThreadShell.tsx: Support media in welcome (hero) send flow
  • useNanobotStream.ts: Pass media through to NanobotClient
  • nanobot-client.ts: Accept optional media parameter in sendMessage
  • types.ts: Add media?: string[] to Outbound message type
  • i18n keys added for en and zh-CN
  • Tests updated for new sendMessage signature

Test plan

  • All 25 existing tests pass
  • TypeScript compiles without errors
  • Manual test: attach file → send → agent receives and reads file
  • Attachment preview shows file name with remove button
  • Send button enables when only attachment (no text)
  • Both hero and thread composer modes support attachments

🤖 Generated with Claude Code

Users can now attach files to messages in the webui composer. Files are
encoded as base64 data URLs in the WebSocket message envelope, decoded
and saved server-side by the WebSocket channel, then passed to the agent
loop as media paths.

Backend:
- Add _save_media_data_urls() to WebSocketChannel for base64 → disk
- Extend _dispatch_envelope to handle optional "media" field
- Enforce per-file (10MB), per-message (25MB), and count (20) limits

Frontend:
- Add paperclip attachment button to ThreadComposer
- Read files as base64 data URLs, show preview badges with remove
- Pass media through useNanobotStream → NanobotClient → WS
- Support attachments in both thread and hero (welcome) composer modes
- Add i18n keys for attach/remove in en and zh-CN

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@dividduang dividduang force-pushed the feat/webui-file-attachment branch from b870e29 to c2cd63c Compare April 21, 2026 13:50
@Re-bin
Copy link
Copy Markdown
Collaborator

Re-bin commented Apr 21, 2026

Thanks for the PR ;)

Marked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants