Skip to content

Commit 3b59c87

Browse files
committed
require json output for tool results
1 parent 72c617a commit 3b59c87

File tree

5 files changed

+53
-79
lines changed

5 files changed

+53
-79
lines changed

.agents/types/util-types.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,15 @@ export type ToolCallPart = {
7474
providerExecuted?: boolean
7575
}
7676

77-
export type ToolResultOutput =
78-
| {
79-
type: 'json'
80-
value: JSONValue
81-
}
82-
| {
83-
type: 'media'
84-
data: string
85-
mediaType: string
86-
}
77+
export type MediaToolResultOutputSchema = {
78+
data: string
79+
mediaType: string
80+
}
81+
82+
export type ToolResultOutput = {
83+
value: JSONValue
84+
media?: MediaToolResultOutputSchema[]
85+
}
8786

8887
// ===== Message Types =====
8988
type AuxiliaryData = {

common/src/templates/initial-agents-dir/types/util-types.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,15 @@ export type ToolCallPart = {
7474
providerExecuted?: boolean
7575
}
7676

77-
export type ToolResultOutput =
78-
| {
79-
type: 'json'
80-
value: JSONValue
81-
}
82-
| {
83-
type: 'media'
84-
data: string
85-
mediaType: string
86-
}
77+
export type MediaToolResultOutputSchema = {
78+
data: string
79+
mediaType: string
80+
}
81+
82+
export type ToolResultOutput = {
83+
value: JSONValue
84+
media?: MediaToolResultOutputSchema[]
85+
}
8786

8887
// ===== Message Types =====
8988
type AuxiliaryData = {

common/src/types/messages/codebuff-message.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export type ToolMessage = {
4141
role: 'tool'
4242
toolCallId: string
4343
toolName: string
44-
content: ToolResultOutput[]
44+
content: ToolResultOutput
4545
} & AuxiliaryMessageData
4646

4747
export type Message =

common/src/types/messages/content-part.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,16 @@ export const toolCallPartSchema = z.object({
4545
})
4646
export type ToolCallPart = z.infer<typeof toolCallPartSchema>
4747

48-
export const toolResultOutputSchema = z.discriminatedUnion('type', [
49-
z.object({
50-
type: z.literal('json'),
51-
value: jsonValueSchema,
52-
}),
53-
z.object({
54-
type: z.literal('media'),
55-
data: z.string(),
56-
mediaType: z.string(),
57-
}),
58-
])
48+
export const mediaToolResultOutputSchema = z.object({
49+
data: z.string(),
50+
mediaType: z.string(),
51+
})
52+
export type MediaToolResultOutputSchema = z.infer<
53+
typeof mediaToolResultOutputSchema
54+
>
55+
56+
export const toolResultOutputSchema = z.object({
57+
value: jsonValueSchema,
58+
media: mediaToolResultOutputSchema.array().optional(),
59+
})
5960
export type ToolResultOutput = z.infer<typeof toolResultOutputSchema>

common/src/util/messages.ts

Lines changed: 22 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { cloneDeep, has, isEqual } from 'lodash'
22

3-
import type { JSONValue } from '../types/json'
43
import type {
54
AssistantMessage,
65
AuxiliaryMessageData,
@@ -9,7 +8,6 @@ import type {
98
ToolMessage,
109
UserMessage,
1110
} from '../types/messages/codebuff-message'
12-
import type { ToolResultOutput } from '../types/messages/content-part'
1311
import type { ProviderMetadata } from '../types/messages/provider-metadata'
1412
import type {
1513
AssistantModelMessage,
@@ -119,25 +117,31 @@ function assistantToCodebuffMessage(
119117
function convertToolResultMessage(
120118
message: ToolMessage,
121119
): ModelMessageWithAuxiliaryData[] {
122-
return message.content.map((c) => {
123-
if (c.type === 'json') {
124-
return cloneDeep<ToolModelMessage>({
125-
...message,
126-
role: 'tool',
127-
content: [{ ...message, output: c, type: 'tool-result' }],
128-
})
129-
}
130-
if (c.type === 'media') {
131-
return cloneDeep<UserMessage>({
120+
const messages: ModelMessageWithAuxiliaryData[] = [
121+
cloneDeep<ToolModelMessage>({
122+
...message,
123+
role: 'tool',
124+
content: [
125+
{
126+
...message,
127+
output: { type: 'json', value: message.content.value },
128+
type: 'tool-result',
129+
},
130+
],
131+
}),
132+
]
133+
134+
for (const c of message.content.media ?? []) {
135+
messages.push(
136+
cloneDeep<UserMessage>({
132137
...message,
133138
role: 'user',
134139
content: [{ type: 'file', data: c.data, mediaType: c.mediaType }],
135-
})
136-
}
137-
c satisfies never
138-
const cAny = c as any
139-
throw new Error(`Invalid tool output type: ${cAny.type}`)
140-
})
140+
}),
141+
)
142+
}
143+
144+
return messages
141145
}
142146

143147
function convertToolMessage(message: Message): ModelMessageWithAuxiliaryData[] {
@@ -411,32 +415,3 @@ export function assistantMessage(
411415
content: assistantContent(params),
412416
}
413417
}
414-
415-
export function jsonToolResult<T extends JSONValue>(
416-
value: T,
417-
): [
418-
Extract<ToolResultOutput, { type: 'json' }> & {
419-
value: T
420-
},
421-
] {
422-
return [
423-
{
424-
type: 'json',
425-
value,
426-
},
427-
]
428-
}
429-
430-
export function mediaToolResult(params: {
431-
data: string
432-
mediaType: string
433-
}): [Extract<ToolResultOutput, { type: 'media' }>] {
434-
const { data, mediaType } = params
435-
return [
436-
{
437-
type: 'media',
438-
data,
439-
mediaType,
440-
},
441-
]
442-
}

0 commit comments

Comments
 (0)