Skip to content

Support uploading any file type, not just images#3

Merged
xqft merged 4 commits intomainfrom
feature/generic-file-uploads
Mar 10, 2026
Merged

Support uploading any file type, not just images#3
xqft merged 4 commits intomainfrom
feature/generic-file-uploads

Conversation

@xqft
Copy link
Copy Markdown
Owner

@xqft xqft commented Mar 10, 2026

Summary

  • Extends the upload system from image-only (PNG/JPEG/GIF/WebP) to support PDFs, text files, CSVs, JSON, ZIP archives, Office docs, audio/video, and more (~30 MIME types)
  • Images render inline as before; non-image files appear as styled download link cards with the original filename (e.g. [📎 report.pdf](/uploads/abc.pdf))
  • MCP bridge updated so agents can upload any file type and pass an optional filename parameter
  • Max file size bumped from 5MB to 10MB

Changes

File What changed
lib/hive/media.ex Expanded @allowed_types to ~30 MIME types, added @ext_map for extension lookup, image_type?/1 helper, optional filename kwarg
lib/hive_web/live/chat_live.ex allow_upload accepts :any, file icon + name preview for non-images, format_attachments_markdown/1 differentiates images vs files
sdk/hive_mcp_bridge.js Removed image-only enum on media_type, added optional filename param, updated descriptions
lib/hive_web/controllers/tools_controller.ex Passes filename option through to Media.save, updated error message
assets/css/app.css File preview card in composer, styled download links for /uploads/ URLs in messages
assets/js/app.js File download links open in new tab (skip lightbox)
test/hive/media_test.exs Tests for PDF, text, CSV, JSON, ZIP, markdown, octet-stream, ext_for/2, image_type?/1
test/hive_web/controllers/tools_controller_test.exs Tests for uploading PDF, text, CSV, ZIP via API; view_image for non-image files
e2e/file-upload.spec.ts Playwright e2e: image thumbnail preview, file icon preview, cancel upload, mixed file types

Test plan

  • mix test test/hive/media_test.exs — unit tests for all new file types
  • mix test test/hive_web/controllers/tools_controller_test.exs — API integration tests
  • npx playwright test e2e/file-upload.spec.ts — e2e upload flow
  • Manual: upload a PDF/CSV/ZIP via the chat composer, verify preview shows filename
  • Manual: send message with file attachment, verify download link appears in chat
  • Manual: click download link, verify file opens in new tab
  • Manual: agent uses upload_media MCP tool with media_type: 'application/pdf'

🤖 Generated with Claude Code

hive-lead and others added 3 commits March 10, 2026 00:46
Extends the upload system from image-only to general file uploads
(PDFs, text, archives, code, docs, etc.). Images render inline as
before; non-image files appear as styled download links with the
original filename.

Changes:
- Media: expand allowed MIME types, add ext_for map, bump limit to 10MB
- ChatLive: accept any file type, show file icon + name for non-images
- MCP bridge: remove image-only enum, add optional filename param
- ToolsController: pass filename option, update error messages
- CSS: file preview cards in composer and download link styling
- JS: open file download links in new tab (skip lightbox)
- Tests: unit tests for all new file types, e2e Playwright tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Separate the default value header from the clause bodies to
satisfy the Elixir compiler (warnings-as-errors clean).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, save/3 guarded against a whitelist of ~40 MIME types
and rejected anything else. Now any file type is accepted — the
only rejection is on file size (>10MB). The ext_map and filename
fallback still provide good extension detection for unknown types.

Also fixes invalid `E` regex modifier in config/dev.exs that
prevented compilation on Elixir <1.16.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@xqft
Copy link
Copy Markdown
Owner Author

xqft commented Mar 10, 2026

Latest update: Removed MIME type allowlist entirely

Commit: d314dcc — Accept any MIME type in Media.save/3, remove allowlist gate

Changes

  • lib/hive/media.ex: Removed the when media_type in @allowed_types guard from save/3. Now accepts ANY file type — only rejects on file size (>10MB). The @ext_map still provides extensions for known types; unknown types fall back to filename extension, then .bin.
  • config/dev.exs: Fixed invalid E regex modifier that prevented compilation on Elixir <1.16.
  • Tests updated: Replaced type-rejection tests with acceptance tests for unknown MIME types (application/x-executable, text/x-python, custom types).

Test results

All 211 tests + 13 properties pass.

What this means

Previously the system supported ~40 whitelisted MIME types. Now it truly supports any file type.py, .rs, .ex, .parquet, .wasm, anything. The extension detection is smart: known MIME → ext_map → filename extension → .bin.

🤖 Generated with Claude Code

The message form was missing phx-change, which meant LiveView's
LiveFileUpload hook never called trackFiles() on file input changes.
Uploads appeared broken in both the browser and Playwright e2e tests.

- Add phx-change="validate" to the message form
- Add no-op validate handler for form change events
- Update e2e spec with triggerLiveViewUpload helper that re-dispatches
  change events for LiveView compatibility

Co-Authored-By: hive-dev <noreply@hive.dev>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@xqft xqft merged commit a275d81 into main Mar 10, 2026
4 of 5 checks passed
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