Skip to content

feat: inline text/plain attachments into prompt (long-message support) #287

@ruan330

Description

@ruan330

Description

Add support for text/plain file attachments by inlining them into the ACP prompt as text content blocks.

Discord automatically converts messages longer than 2,000 characters into a .txt file attachment. When this happens, the agent receives an empty prompt — the actual content is in the attachment, which openab currently skips.

Use Case

Users pasting long text (logs, articles, code) for summarization or analysis. This is the most common non-image attachment scenario in practice.

Current attachment routing:

Discord message with attachment
         │
         ▼
    content_type?
    ├── audio/*    → download → STT transcribe → prompt text  ✅
    ├── image/*    → download → resize → base64 → ImageContent ✅
    └── */*        → silently skipped                          ❌
             ▲
             └── text/plain lands here (.txt from long messages)

Proposed Solution

Add one branch to the existing attachment routing: detect text/plain, download the content, and inline it as a text content block — the same pattern STT uses for audio.

Discord message with attachment
         │
         ▼
    content_type?
    ├── audio/*      → download → STT transcribe → prompt text  ✅
    ├── text/plain   → download → decode UTF-8   → prompt text  ✅  ← NEW
    ├── image/*      → download → resize → base64 → ImageContent ✅
    └── */*          → skipped (future: #254)

No external API needed (unlike STT). Pure HTTP download + UTF-8 decode.

Implementation notes:

  • Check content_type == "text/plain" (Discord sets this for auto-generated .txt)
  • Size guard: skip files > 128 KB to avoid flooding the context window (128 KB ≈ ~130k chars ≈ well within model limits; configurable later)
  • Inject as [Attached text: {filename} ({size})]\n{content} so the agent knows it came from an attachment
  • ~15 lines of code, mirrors the STT download pattern

Related:

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions