UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

89 lines • 3.32 kB
/** The {@link MessageFileKind} of a MIME type. */ export function fileKind(mediaType) { const type = mediaType.toLowerCase(); if (type.startsWith('image/')) return 'image'; if (type === 'application/pdf') return 'pdf'; if (type.startsWith('text/') || type === 'application/json') return 'text'; if (type.startsWith('audio/')) return 'audio'; if (type.startsWith('video/')) return 'video'; return 'other'; } function messageFile(url, mediaType, name, mediaId) { const dot = name?.lastIndexOf('.') ?? -1; const file = { url, mediaType, filename: name, kind: fileKind(mediaType), extension: name !== null && dot > 0 ? name.slice(dot + 1).toLowerCase() : null, mediaId, }; return file; } /** * An uploaded attachment as the {@link MessageFile} it is once its message is sent — so a message * still waiting (in the queue, in the composer) draws its files with the same code a sent one does. */ export function attachmentFile(attachment) { return messageFile(attachment.url, attachment.contentType, attachment.name, attachment.mediaId); } /** * The files on a message — the user's attachments (live, or replayed from `StoredMessage.attachments` * by `storedMessageToUiMessage`) and any the model produced — in part order. Data only: pair it with * your own thumbnails/links. */ export function messageFiles(message) { const files = []; for (const part of message.parts) { if (part.type !== 'file') continue; const file = part; const mediaId = file.providerMetadata?.agent?.mediaId; files.push(messageFile(file.url, file.mediaType, file.filename ?? null, typeof mediaId === 'string' ? mediaId : null)); } return files; } /** * Whether `file` matches an `accept` list in the `<input accept>` grammar: MIME types * (`application/pdf`), wildcards (`image/*`) and extensions (`.csv`). An empty list accepts all. */ export function acceptsFile(accept, file) { const rules = (typeof accept === 'string' ? accept.split(',') : (accept ?? [])) .map((rule) => rule.trim().toLowerCase()) .filter((rule) => rule.length > 0); if (rules.length === 0) return true; const type = file.type.toLowerCase(); const name = file.name.toLowerCase(); return rules.some((rule) => { if (rule.startsWith('.')) return name.endsWith(rule); if (rule.endsWith('/*')) return type.startsWith(rule.slice(0, -1)); return type === rule; }); } /** Files carried by a paste — screenshots and copied files. Text-only pastes give `[]`. */ export function filesFromClipboard(data) { if (!data) return []; const files = []; for (const item of Array.from(data.items ?? [])) { if (item.kind !== 'file') continue; const file = item.getAsFile(); if (file !== null) files.push(file); } return files.length > 0 ? files : Array.from(data.files ?? []); } /** Whether a drag carries files (as opposed to text or a link) — gate your drop highlight on it. */ export function dragHasFiles(data) { return Array.from(data?.types ?? []).includes('Files'); } //# sourceMappingURL=files.js.map