Problem
When a user uploads a non-image, non-audio file (e.g. .txt, .py, .pdf, .json) in Discord, openab silently skips it — the agent never sees the file at all.
Current attachment routing:
image/* → download + resize + base64 → ACP image content block ✅
audio/* → STT transcript → text content block ✅
- everything else → skipped ❌
Proposed solution
Download the file to a temp directory on disk and include the path in a text content block. Agents that have file-reading tools (e.g. Claude Code's Read tool) can then access the file contents.
[Attached file: script.py (text/x-python, 1234 bytes) — saved to /tmp/discord-uploads/123456_script.py]
Implementation notes
- Use the existing
HTTP_CLIENT for downloading
- Save to
/tmp/discord-uploads/{attachment_id}_{sanitized_filename}
- 25 MB size limit (consistent with Discord's upload limit)
- Clean up after prompt completes — collect file paths during download,
remove_file after stream_prompt returns
- Return
(ContentBlock, PathBuf) from the download function so the caller can track paths for cleanup
Considerations
- This approach is agent-agnostic at the transport level (it's just a text content block), but the agent needs a file-reading tool to actually use it
- Could be gated behind a config flag if not all agent presets benefit from it
- The temp directory is ephemeral (cleared on pod restart), which is fine since files only need to exist during prompt processing
Problem
When a user uploads a non-image, non-audio file (e.g.
.txt,.py,.pdf,.json) in Discord, openab silently skips it — the agent never sees the file at all.Current attachment routing:
image/*→ download + resize + base64 → ACP image content block ✅audio/*→ STT transcript → text content block ✅Proposed solution
Download the file to a temp directory on disk and include the path in a text content block. Agents that have file-reading tools (e.g. Claude Code's
Readtool) can then access the file contents.Implementation notes
HTTP_CLIENTfor downloading/tmp/discord-uploads/{attachment_id}_{sanitized_filename}remove_fileafterstream_promptreturns(ContentBlock, PathBuf)from the download function so the caller can track paths for cleanupConsiderations