Attachments
Send item pictures, PDFs, and text files to a model with Request.Attach.
Attach files to a request when the model should read an image or document along with the prompt. Attachments go with the next user message.
Describe an item picture
Item.Picture is a media set, so pass the media id of the picture you want:
OpenAI: Codeunit "AIOS OpenAI";
Client: Codeunit "AIOS Client";
Request: Record "AIOS Chat Request";
Result: Codeunit "AIOS Generate Result";
Item: Record Item;
ApiKey: SecretText;
begin
Item.Get('1000');
if Item.Picture.Count() = 0 then
Error('Item %1 has no picture.', Item."No.");
Request.SetSystemMessage('You write product copy for Business Central item cards.');
Request.SetPrompt('Write a two-sentence webshop description for this item image.');
Request.Attach(Item.Picture.Item(1));
Result := Client.GenerateText(OpenAI.Model('gpt-5.6-sol', ApiKey), Request);
end;
The model must accept images. Choose a vision-capable model id from your provider.
Attach from a stream or blob
For files that are not already in Tenant Media, pass the content with its media type and a file name:
Request: Record "AIOS Chat Request";
TempBlob: Codeunit "Temp Blob";
begin
// TempBlob holds a PDF, for example an exported sales invoice
Request.SetPrompt('List the invoice lines and the total amount.');
Request.Attach(TempBlob, 'application/pdf', 'invoice-103001.pdf');
Result := Client.GenerateText(Model, Request);
end;
Attach overloads
| Overload | Use for |
|---|---|
Attach(MediaId) | A picture from a Media or MediaSet field, such as Item.Picture.Item(1) |
Attach(MediaId, Filename) | The same, with an explicit file name |
Attach(TenantMedia) / Attach(TenantMedia, Filename) | A "Tenant Media" record you already loaded. The media type comes from the record |
Attach(InStream, MediaType, Filename) | Content from a stream, such as an uploaded file |
Attach(TempBlob, MediaType, Filename) | Content in a "Temp Blob" |
Attach(Base64, MediaType, Filename) | Base64 text without a data: prefix |
MediaType is a standard type such as image/png, application/pdf, or text/plain. Text types (text/...) are sent to the model as plain text, with the file name as a heading.
HasAttachments() tells you whether files are waiting for the next message, and ClearAttachments() removes them.
Provider support
| Content | Anthropic | OpenAI, OpenCode Zen, OpenAI Compatible |
|---|---|---|
Images (image/...) | Yes | Yes, when the model supports vision |
PDF (application/pdf) | Yes | Sent as a file. Support depends on the endpoint and model |
Text (text/...) | Yes | Yes |
| Other types | Error that names the media type | Sent as a file. Support depends on the endpoint and model |
Anthropic raises the error when GenerateText runs, not when you call Attach. For the other providers, check the model documentation before relying on file input.
Limits
| Limit | Value |
|---|---|
| Attachments per request | 10 |
| Size per attachment | About 7.5 MB |
| Empty content or empty media type | Not allowed |
Attach raises an error as soon as a limit is exceeded, before any model call. Providers may apply lower limits of their own.
Attachments in a conversation
Attachments go with the prompt you set with SetPrompt. If you attach without setting a new prompt and the history ends with a user message, the attachment joins that message instead. See Conversations.
Test without a provider
"AIOS Mock" ignores attachments and accepts any media type, so you can run the code that builds the request in a test:
Mock: Codeunit "AIOS Mock";
Client: Codeunit "AIOS Client";
Request: Record "AIOS Chat Request";
Base64Convert: Codeunit "Base64 Convert";
Result: Codeunit "AIOS Generate Result";
begin
Mock.SetNextResponse('Summary: short note about shipping.');
Request.SetPrompt('Summarize the attached note.');
Request.Attach(Base64Convert.ToBase64('Ship by Friday. PO-1042.'), 'text/plain', 'note.txt');
Result := Client.GenerateText(Mock.Model('mock-model'), Request);
end;