Skip to content

Commit 9210549

Browse files
committed
fix: wrap first text part in user_message tags for multipart content
Ensures consistent XML framing when content contains both text and images by wrapping only the first text part in <user_message> tags.
1 parent a0dcffc commit 9210549

File tree

1 file changed

+16
-11
lines changed

1 file changed

+16
-11
lines changed

packages/agent-runtime/src/util/messages.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,24 +34,29 @@ export function asUserMessage(str: string): string {
3434
}
3535

3636
/**
37-
* Combines prompt, params, and content into a unified message content structure
37+
* Combines prompt, params, and content into a unified message content structure.
38+
* Always wraps the first text part in <user_message> tags for consistent XML framing.
3839
*/
3940
export function buildUserMessageContent(
4041
prompt: string | undefined,
4142
params: Record<string, any> | undefined,
4243
content?: Array<TextPart | ImagePart>,
4344
): Array<TextPart | ImagePart> {
44-
// If we have content, return it as-is (client should have already combined prompt + content)
45+
// If we have content array (e.g., text + images)
4546
if (content && content.length > 0) {
46-
if (content.length === 1 && content[0].type === 'text') {
47-
return [
48-
{
49-
type: 'text',
50-
text: asUserMessage(content[0].text),
51-
},
52-
]
53-
}
54-
return content
47+
// Find the first text part and wrap it in <user_message> tags
48+
let hasWrappedText = false
49+
const wrappedContent = content.map((part) => {
50+
if (part.type === 'text' && !hasWrappedText) {
51+
hasWrappedText = true
52+
return {
53+
type: 'text' as const,
54+
text: asUserMessage(part.text),
55+
}
56+
}
57+
return part
58+
})
59+
return wrappedContent
5560
}
5661

5762
// Only prompt/params, combine and return as simple text

0 commit comments

Comments
 (0)