File Uploads in Umbraco.AI
4 min read
File uploads have landed in Umbraco.AI. While the most visible change is in Copilot — where you can now drag and drop documents directly into the chat — the feature runs deeper than that. File upload support has been added to the Agent endpoints, and a new file processing middleware sits at the core IChatClient level, meaning any code that uses the Umbraco.AI chat APIs benefits from file handling automatically.
Let’s start with the bit you’ll see first.
Uploading Files in Copilot
Getting files into Copilot is straightforward. You can either drag and drop files onto the chat input, or click the attachment button to browse your file system. Multiple files can be uploaded at once, and you’ll see a preview of each file before sending your message — image files show a thumbnail, while documents appear as a compact chip showing the filename.
Once attached, files are sent along with your message and the AI can reference their contents when responding. This is particularly useful when you want to ask questions about a document, have the AI summarise content, or use a file as context for generating or editing content in Umbraco.
Supported File Types
Umbraco.AI processes uploaded files in two ways depending on their type.
Text Extraction (Office Documents)
For Office documents, Umbraco.AI automatically extracts the text content and passes it to the AI model as structured text. This means the AI can read and reason about the full document contents. The following formats are supported out of the box:
- Word documents (
.docx) — paragraph text with heading levels preserved - Excel spreadsheets (
.xlsx) — cell data extracted with table structure intact - PowerPoint presentations (
.pptx) — slide text content extracted
The extraction is smart about structure too. Headings in Word documents are converted to markdown headers, tables are rendered as markdown tables, and Excel data retains its tabular format. There’s a generous 100,000 character limit per file, so even large documents are handled comfortably.
Pass-Through (Images & PDFs)
Images and PDFs are passed directly to the AI model in their original binary form. Modern large language models can natively understand these formats, so no server-side extraction is needed:
- Images (
.png,.jpg,.gif,.webp, etc.) — visual content understood natively by the model - PDFs (
.pdf) — pages read and interpreted directly by the model
This means you can upload a screenshot of a design mockup, a photo of a whiteboard, or a PDF brief and ask the AI to work with it directly.
Validation
File uploads respect your existing Umbraco content settings. The same extension allow/block lists that govern media uploads in the CMS are applied here too, so your security policies are enforced consistently. There’s also a 10 MB size limit per file.
Under the Hood
While Copilot is the most visible consumer, the file handling is built as layered infrastructure that works across the stack.
File Processing Middleware
At the lowest level, file processing is implemented as an IChatClient middleware — AIFileProcessingChatClient. This means any chat interaction that flows through Umbraco.AI’s chat client pipeline gets file processing for free, whether it originates from Copilot, a custom Agent, or your own C# code calling the chat APIs directly.
When a message contains file data (as DataContent), the middleware checks for a registered handler that can process that MIME type. If one is found, the file’s binary content is extracted into text and substituted into the message before it reaches the AI model. If no handler matches, the file is passed through as-is — which is exactly what you want for images and PDFs that models can interpret natively.
Agent Endpoint Support
The Agent layer adds file lifecycle management on top of this. When files are uploaded through the AG-UI protocol, they’re stored server-side with a unique ID scoped to the conversation thread. Subsequent messages can reference files by ID rather than re-uploading them, keeping payloads lean. A background cleanup job handles expiring old files automatically.
This means if you’re building your own Agent-based experiences — not just using Copilot — file uploads work out of the box through the standard Agent endpoints.
Adding Support for More File Types
The file processing system is fully extensible. If you need to support additional file formats — say CSV, HTML, or a proprietary format — you can add your own file processing handler.
The extension point is the IAIFileProcessingHandler interface:
public class CsvFileProcessingHandler : IAIFileProcessingHandler
{
public bool CanHandle(string mimeType)
=> mimeType == "text/csv";
public async Task<AIFileProcessingResult> ProcessAsync(
ReadOnlyMemory<byte> data,
string mimeType,
string? filename,
CancellationToken cancellationToken = default)
{
var text = Encoding.UTF8.GetString(data.Span);
// Parse and format CSV content...
return new AIFileProcessingResult { Text = text };
}
}
Register it in a Composer and you’re done:
public class MyComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.AIFileProcessingHandlers()
.Append<CsvFileProcessingHandler>();
}
}
Handlers are evaluated in order — the first handler that returns true from CanHandle processes the file. You can use InsertBefore<>() or InsertAfter<>() to control ordering if needed, just like any other Umbraco collection builder.
Because this hooks into the core middleware, custom handlers work everywhere — Copilot, Agents, and direct API usage alike.
What’s Next
File uploads are the first step in making Umbraco.AI a more capable document-aware platform. We’re excited to see what the community builds with the extensible handler system — if you create a handler for a common file format, consider sharing it as a package!
Until next time 👋