Skip to content

Commit d12acd3

Browse files
committed
Update image ref resolution to use conversation order
File reference resolver now maps image refs (e.g. image_1, image_2) to user-uploaded images in chronological order across the entire conversation, rather than only the latest user message. Updated tool prompt instructions to clarify this behavior for users.
1 parent b7c8256 commit d12acd3

File tree

2 files changed

+17
-30
lines changed

2 files changed

+17
-30
lines changed

src/lib/server/textGeneration/mcp/fileRefs.ts

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,46 +24,33 @@ const IMAGE_REF_KIND: RefKind = {
2424
const DEFAULT_REF_KINDS: RefKind[] = [IMAGE_REF_KIND];
2525

2626
/**
27-
* Build a resolver that maps short ref strings (e.g. "image_1") to the
28-
* corresponding file payload for the latest user message containing files of
29-
* the allowed kinds. Currently only images are exposed to end users, but the
30-
* plumbing supports additional kinds later.
27+
* Build a resolver that maps short ref strings (e.g. "image_1", "image_2") to the
28+
* corresponding file payload across the whole conversation in chronological
29+
* order of user uploads. (image_1 = first user-uploaded image, image_2 = second, etc.)
30+
* Currently only images are exposed to end users, but the plumbing supports
31+
* additional kinds later.
3132
*/
3233
export function buildFileRefResolver(
3334
messages: EndpointMessage[],
3435
refKinds: RefKind[] = DEFAULT_REF_KINDS
3536
): FileRefResolver | undefined {
3637
if (!Array.isArray(refKinds) || refKinds.length === 0) return undefined;
3738

38-
// Find the newest user message that has at least one matching file
39-
let lastUserWithFiles: EndpointMessage | undefined;
40-
for (let i = messages.length - 1; i >= 0; i -= 1) {
41-
const msg = messages[i];
39+
// Bucket matched files by ref kind preserving conversation order (oldest -> newest)
40+
const buckets = new Map<RefKind, FileRefPayload[]>();
41+
for (const msg of messages) {
4242
if (msg.from !== "user") continue;
43-
const hasMatch = (msg.files ?? []).some((file) => {
44-
const mime = file?.mime;
45-
return refKinds.some((kind) => kind.matches(mime ?? ""));
46-
});
47-
if (hasMatch) {
48-
lastUserWithFiles = msg;
49-
break;
43+
for (const file of msg.files ?? []) {
44+
const mime = file?.mime ?? "";
45+
const kind = refKinds.find((k) => k.matches(mime));
46+
if (!kind) continue;
47+
const payload: FileRefPayload = { name: file.name, mime, base64: file.value };
48+
const arr = buckets.get(kind) ?? [];
49+
arr.push(payload);
50+
buckets.set(kind, arr);
5051
}
5152
}
5253

53-
if (!lastUserWithFiles) return undefined;
54-
55-
// Bucket matched files by ref kind while preserving order within the message
56-
const buckets = new Map<RefKind, FileRefPayload[]>();
57-
for (const file of lastUserWithFiles.files ?? []) {
58-
const mime = file?.mime ?? "";
59-
const kind = refKinds.find((k) => k.matches(mime));
60-
if (!kind) continue;
61-
const payload: FileRefPayload = { name: file.name, mime, base64: file.value };
62-
const arr = buckets.get(kind) ?? [];
63-
arr.push(payload);
64-
buckets.set(kind, arr);
65-
}
66-
6754
if (buckets.size === 0) return undefined;
6855

6956
const resolver: FileRefResolver = (ref) => {

src/lib/server/textGeneration/utils/toolPrompt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ export function buildToolPreprompt(tools: OpenAiTool[]): string {
1616
`Today's date: ${currentDate}.`,
1717
`If a tool generates an image, you can inline it directly: ![alt text](image_url).`,
1818
`If a tool needs to operate on an image, set its image input parameter (for example, "input_image") to an image reference string.`,
19-
`Use "image_1", "image_2", etc. to point to a specific image from a user message with images. You can also reuse a direct image URL from a prior tool result instead of pasting new base64 data.`,
19+
`Use "image_1", "image_2", etc. where the number equals the chronological order of user-uploaded images in this conversation (image_1 = first image uploaded, image_2 = second, and so on). You can also reuse a direct image URL from a prior tool result instead of pasting new base64 data.`,
2020
].join(" ");
2121
}

0 commit comments

Comments
 (0)