This adds a minimal, in-memory file upload capability wired to the chat composer and a Next.js API route.
- UI (
src/components/Composer.tsx):onUploadFileprop:(file: { id: string; file: File }) => Promise<unknown>- Hidden native file input + Attach button (design system) with paperclip icon
- Upload state chips with statuses: Uploading → Uploaded
- Cross button on each chip to remove files before sending
- Send button disabled while any file is uploading
- On submit, uploaded files are included in the message
contextand local upload state is cleared
- API:
POST /api/files(src/app/api/files/route.ts) acceptsmultipart/form-datawith one or morefilefields and optionalid- Files are stored in-memory as text (using
File.text()) - In-memory store:
src/app/api/files/fileStore.tswithaddFile,removeFile,getFile,listFiles POST /api/chat(src/app/api/chat/route.ts) includesread_filetool in the system prompt
- Endpoint:
POST /api/files - Body:
multipart/form-datafile: one or more file partsid(optional): client-generated ID to correlate UI with server state
- Response:
{ files: Array<{ id, name, type, size }> } - Storage: in-memory, text-only; not persisted, cleared on server restart
- This approach is only suitable for text-based files like CSV, JSON, etc.
- In-memory store is not suitable for production (no persistence, no limits)
- Consider size limits, validation, and auth for real-world use