/** * Inbound file transport. Discord messages can carry attachments; this turns * them into AG-UI multimodal message content the agent's model can read — * images as binary data parts and plain text/CSV/JSON/etc. as decoded `text` * parts — downloading each from its public CDN URL (no auth required). * * The AgentContentPart union is intentionally identical to bot-slack's so the * agent sees the same multimodal input shape across both adapters. */ /** The subset of a Discord attachment we use. */ export interface DiscordAttachmentRef { /** CDN URL — publicly fetchable, no auth header needed. */ url: string; /** Original filename, used for extension-based MIME fallback. */ name: string; /** MIME type reported by Discord (may be null/undefined for some uploads). */ contentType?: string | null; /** Byte length reported by Discord. Used to gate the size cap pre-fetch. */ size: number; } /** A base64 data source, shared by every binary media part. */ export type MediaDataSource = { type: "data"; value: string; mimeType: string; }; /** * AG-UI multimodal content parts — SAME shape as bot-slack emits so the agent * sees identical multimodal input across both adapters. * * Binary media (image/audio/video/document) is passed straight through as a * data part; the agent's model decides what it can actually consume. Most * models read images and PDFs; far fewer accept audio or video. The bridge * stays transport-only and does not gate on model capability. */ export type AgentContentPart = { type: "text"; text: string; } | { type: "image"; source: MediaDataSource; } | { type: "audio"; source: MediaDataSource; } | { type: "video"; source: MediaDataSource; } | { type: "document"; source: MediaDataSource; }; /** Tunables for inbound file handling (all optional; sane defaults). */ export interface FileDeliveryConfig { /** * Skip a single file larger than this many bytes without fetching it. * Default 10 MiB. */ maxBytes?: number; /** * Truncate decoded text files to this many bytes before injecting them into * the prompt (keeps a large text upload from blowing the token budget). * Default 200 KiB. */ maxTextBytes?: number; /** * Process at most this many attachments per message. Extra attachments beyond * this cap are ignored without fetching, bounding the multimodal payload / * token budget a single message can inject. Default 5. */ maxFiles?: number; /** * Inject a custom fetch implementation (for testing or environments without * the global `fetch`). */ fetchImpl?: typeof fetch; } /** * Download Discord message attachments and convert them to AG-UI content parts. * * Files whose reported size exceeds `maxBytes` are skipped WITHOUT fetching; * the actual downloaded byte length is re-checked against the same cap after * fetching. Images map to an image part; text/* MIME types and text-named * files (.txt, .csv, .json, .md, .log, .tsv, .yaml) — including ones reported * with a generic binary MIME like application/octet-stream — map to a text * part (truncated to `maxTextBytes`); other binary content is skipped with a * short text note explaining why (bot-slack parity), so the model knows a file * was dropped. * * At most `maxFiles` attachments (default 5) are processed; any beyond that cap * are ignored without fetching, bounding the multimodal payload a single * message can inject. */ export declare function buildFileContentParts(attachments: readonly DiscordAttachmentRef[], cfg?: FileDeliveryConfig): Promise; //# sourceMappingURL=download-files.d.ts.map