File Attachments
Enable file uploads by passing an UploadManager, Upload, or any custom AIFileReceiver implementation to the builder via withFileReceiver(). Uploaded files are sent to the LLM as attachments with the next prompt.
Source code
Java
var uploadManager = new UploadManager(this);
var uploadButton = new UploadButton(uploadManager);
var orchestrator = AIOrchestrator
.builder(provider, systemPrompt)
.withMessageList(messageList)
.withInput(messageInput)
.withFileReceiver(uploadManager)
.build();|
Note
|
Upload Handler Conflict
When using UploadManager or Upload, the component must not already have an upload handler or receiver set. The orchestrator installs its own in-memory handler. If one is already set, an IllegalArgumentException is thrown at build time. This restriction does not apply to custom AIFileReceiver implementations.
|
|
Note
|
Supported Attachment Types
The following MIME type categories are supported: images (image/), text (text/), PDF (application/pdf), audio (audio/), and video (video/). Attachments with other MIME types are silently dropped and not sent to the LLM.
|
|
Note
|
Duplicate File Names
Uploading multiple files with the same name in a single batch throws an IllegalArgumentException. Ensure each file has a unique name.
|
To persist attachment data externally (since attachments are not stored in the conversation history), use the withRequestListener() and withAttachmentClickListener() callbacks:
Source code
Java
var orchestrator = AIOrchestrator
.builder(provider, systemPrompt)
.withMessageList(messageList)
.withInput(messageInput)
.withFileReceiver(uploadManager)
.withRequestListener(event -> {
// Store attachments keyed by message ID
saveAttachments(event.getMessageId(),
event.getAttachments());
})
.withAttachmentClickListener(event -> {
// Retrieve and display the attachment
showAttachment(event.getMessageId(),
event.getAttachmentIndex());
})
.build();The request listener is called on every prompt, just before the LLM request starts — also for messages without attachments, in which case getAttachments() returns an empty list. The same message ID is later available from ChatMessage.messageId() in the conversation history and from the attachment click event, so externally stored attachments can be looked up when the user clicks them or when restoring a saved conversation. See Request & Response Listeners for details on the listener lifecycle.
Sending Attachments Programmatically
Attachments don’t have to come from an upload component. The prompt(String, List<AIAttachment>) overload sends a prompt together with attachments produced in code — generated files, fetched data, or content from other sources. See Tool Calling & Programmatic Prompts.