showcase/shell-docs/src/content/docs/channels/files-and-multimodality.mdx
When a user drops an image, PDF, or other file into the chat, it arrives on
the message as contentParts. Merge those parts into the agent's prompt and
the agent can read them.
channel.onMessage(async ({ thread, message }) => {
await thread.runAgent({
prompt: message.contentParts?.length
? [
// the user's instruction, if any
...(message.text ? [{ type: "text" as const, text: message.text }] : []),
// the uploaded files
...message.contentParts,
]
: message.text,
});
});
message.contentParts is an array of typed parts. File bytes come base64
encoded on source.value.
type AgentContentPart =
| { type: "text"; text: string }
| { type: "image"; source: { type: "data"; value: string; mimeType: string } }
| { type: "audio"; source: { type: "data"; value: string; mimeType: string } }
| { type: "video"; source: { type: "data"; value: string; mimeType: string } }
| { type: "document"; source: { type: "data"; value: string; mimeType: string } };
So "summarize this PDF" with an attached file arrives as a text part plus a
document part. An image the agent should look at arrives as an image part.
Post a file to the thread with thread.postFile:
await thread.postFile({
bytes: pngBuffer, // Buffer or Uint8Array
filename: "chart.png",
title: "Revenue by month",
altText: "A bar chart of revenue for the last 12 months",
});
This is how a bot returns a generated chart or report.
Each direct adapter takes a files option (FileDeliveryConfig) to cap
incoming files. A managed channel applies the platform's own limits.
Pass files on the adapter when you connect a platform directly, and let your
editor's types show the available caps:
import { whatsapp } from "@copilotkit/channels/whatsapp";
whatsapp({
// ...credentials
files: {
/* caps for incoming files, see FileDeliveryConfig */
},
});