- Updated OpenRouter integration to accept an array of image URLs - Updated ImagePicker to use the `multiple` attribute natively - Added `appendImagesDeduped` for handling client-side image deduplication - Enhanced clipboard pasting to extract multiple images at once - Rendered multiple images in a horizontal thumbnail strip in the AIToolbar - Added tests to cover multi-image logic and AI request mapping
48 lines
1.2 KiB
TypeScript
48 lines
1.2 KiB
TypeScript
/**
|
|
* Pure helper that builds the OpenRouter chat messages array for a multimodal
|
|
* AI-event request.
|
|
*
|
|
* Extracted from the API route so it can be unit-tested without mocking HTTP.
|
|
*/
|
|
|
|
type TextPart = { type: "text"; text: string };
|
|
type ImageUrlPart = { type: "image_url"; imageUrl: { url: string } };
|
|
type ContentPart = TextPart | ImageUrlPart;
|
|
|
|
type Message =
|
|
| { role: "system"; content: string }
|
|
| { role: "user"; content: ContentPart[] };
|
|
|
|
/**
|
|
* Builds a 2-message array:
|
|
* [0] system → the system prompt string
|
|
* [1] user → [text part, ...image_url parts (one per image)]
|
|
*
|
|
* @param systemPrompt Instruction string for the model
|
|
* @param prompt Optional text from the user
|
|
* @param images Array of base64 data URLs
|
|
*/
|
|
export function buildMultimodalMessages(
|
|
systemPrompt: string,
|
|
prompt: string | undefined,
|
|
images: string[],
|
|
): Message[] {
|
|
const userContent: ContentPart[] = [
|
|
{
|
|
type: "text",
|
|
text: prompt || "Extract all calendar events from these images.",
|
|
},
|
|
...images.map(
|
|
(url): ImageUrlPart => ({
|
|
type: "image_url",
|
|
imageUrl: { url },
|
|
}),
|
|
),
|
|
];
|
|
|
|
return [
|
|
{ role: "system", content: systemPrompt },
|
|
{ role: "user", content: userContent },
|
|
];
|
|
}
|