@adonis-agora/agent
Version:
Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.
106 lines • 4.62 kB
TypeScript
import type { MessageAttachment } from '../../../index.js';
import type { AgentBackend, UploadAttachmentOptions } from '../backend.js';
/** Where one staged file stands. `rejected` never uploaded (validation); `error` can be retried. */
export type StagedAttachmentStatus = 'uploading' | 'ready' | 'error' | 'rejected';
export interface StagedAttachment {
/** Local id, stable for the item's life — use it as the React key and for `remove`/`retry`. */
id: string;
file: File;
name: string;
size: number;
type: string;
status: StagedAttachmentStatus;
/** 0..1 while uploading (0 until the backend reports progress), 1 once ready. */
progress: number;
/** Why it was rejected or failed. */
error?: string;
/** What the server returned — present once `ready`. */
attachment?: MessageAttachment;
/** An object URL for image previews (revoked on remove/unmount), when the runtime has one. */
previewUrl?: string;
}
/** Why a file was turned away before any upload. */
export type AttachmentRejection = 'type' | 'size' | 'count';
export interface UseAttachmentsOptions {
/**
* Upload one file — defaults to `backend.uploadAttachment`. Resolve with what the server
* answered; honour `signal` so `remove` can cancel; call `onProgress(0..1)` if you can.
*/
upload?: (file: File, options: UploadAttachmentOptions) => Promise<MessageAttachment>;
/** Used for the default `upload`. Default: the enclosing `<AgentProvider>`'s. */
backend?: AgentBackend;
/**
* `<input accept>` grammar: `'image/*,.pdf'` or `['image/*', 'application/pdf']`. Default: the
* server's allowed content types (`GET <base>/config`).
*/
accept?: string | readonly string[];
/** Per-file ceiling, in bytes. Default: the server's (`GET <base>/config`). */
maxBytes?: number;
/**
* How many files may be staged at once (rejected ones do not count). Default: how many one
* message may carry, per the server (`GET <base>/config`).
*/
maxFiles?: number;
/** Words for a rejection; default English. */
describeRejection?: (reason: AttachmentRejection, file: File) => string;
}
export interface AttachmentsState {
items: StagedAttachment[];
/** Stage files: validate, then upload each that passes. */
add: (files: Iterable<File> | ArrayLike<File> | null | undefined) => void;
/** Drop an item, cancelling its upload. */
remove: (id: string) => void;
/** Upload a failed item again. */
retry: (id: string) => void;
/** Drop everything — call after a send. */
clear: () => void;
/** An upload is still running — hold the send button. */
isUploading: boolean;
/** What to send: the ready uploads, in order, as the `{ mediaId }` refs `POST <base>/chat` takes. */
refs: Array<{
mediaId: string;
}>;
/** Props for a hidden `<input type="file">`: `accept`, `multiple`, `onChange`. */
inputProps: {
type: 'file';
accept: string | undefined;
multiple: boolean;
onChange: (event: {
currentTarget: HTMLInputElement;
}) => void;
};
/** Handlers for any element that should take dropped files. */
dropZoneProps: {
onDragEnter: (event: DragLikeEvent) => void;
onDragOver: (event: DragLikeEvent) => void;
onDragLeave: (event: DragLikeEvent) => void;
onDrop: (event: DragLikeEvent) => void;
};
/** Files are being dragged over the drop zone — for a highlight. */
isDragging: boolean;
/** Paste handler for the composer: stages pasted files (screenshots), leaves text alone. */
onPaste: (event: ClipboardLikeEvent) => void;
}
/** The slice of a React/DOM drag event these handlers read. */
export interface DragLikeEvent {
dataTransfer: DataTransfer | null;
preventDefault: () => void;
}
/** The slice of a React/DOM clipboard event `onPaste` reads. */
export interface ClipboardLikeEvent {
clipboardData: DataTransfer | null;
preventDefault: () => void;
}
/**
* Staged attachments for a composer, headless: validation (`accept`, `maxBytes`, `maxFiles`),
* one upload per file with progress and cancel, retry, previews, and the event handlers for a file
* input, a drop zone and paste — no markup, no styles. Send `refs` with the
* message, then `clear()`:
*
* ```ts
* await chat.sendMessage({ text }, { body: { attachments: files.refs } });
* files.clear();
* ```
*/
export declare function useAttachments(options?: UseAttachmentsOptions): AttachmentsState;
//# sourceMappingURL=use-attachments.d.ts.map