Skip to content

Commit e65f5ed

Browse files
committed
fix(xai): support Responses API streaming events and custom_tool_call type
Add missing schema validation for xAI Responses API server-side tools: - Add custom_tool_call type to outputItemSchema - Make toolCallSchema fields optional for in_progress states - Add input field for custom_tool_call (vs arguments) - Add action field for in_progress tool execution states - Add 12 streaming event types for tool lifecycle: - web_search_call: in_progress, searching, completed - x_search_call: in_progress, searching, completed - code_execution_call: in_progress, executing, completed - code_interpreter_call: in_progress, executing, completed Fixes validation errors ('Invalid JSON response', 'No matching discriminator') when using xai.responses() with xai.tools.webSearch(), xai.tools.xSearch(), or xai.tools.codeExecution(). Tested with generateText() and streamText() across all tool types.
1 parent 79a8e7f commit e65f5ed

File tree

2 files changed

+81
-7
lines changed

2 files changed

+81
-7
lines changed

.changeset/smooth-ravens-suffer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@ai-sdk/xai': patch
3+
---
4+
5+
Fix Responses API validation errors for server-side tools (web_search, x_search, code_execution). Add missing custom_tool_call type and streaming event schemas.

packages/xai/src/responses/xai-responses-api.ts

Lines changed: 76 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,15 @@ export type XaiResponsesToolCall = {
4848
| 'function_call'
4949
| 'web_search_call'
5050
| 'x_search_call'
51-
| 'code_interpreter_call';
51+
| 'code_interpreter_call'
52+
| 'custom_tool_call';
5253
id: string;
53-
call_id: string;
54-
name: string;
55-
arguments: string;
54+
call_id?: string;
55+
name?: string;
56+
arguments?: string;
57+
input?: string;
5658
status: string;
59+
action?: any;
5760
};
5861

5962
export type XaiResponsesTool =
@@ -105,11 +108,13 @@ const messageContentPartSchema = z.object({
105108
});
106109

107110
const toolCallSchema = z.object({
108-
name: z.string(),
109-
arguments: z.string(),
110-
call_id: z.string(),
111+
name: z.string().optional(),
112+
arguments: z.string().optional(),
113+
input: z.string().optional(),
114+
call_id: z.string().optional(),
111115
id: z.string(),
112116
status: z.string(),
117+
action: z.any().optional(),
113118
});
114119

115120
const outputItemSchema = z.discriminatedUnion('type', [
@@ -137,6 +142,10 @@ const outputItemSchema = z.discriminatedUnion('type', [
137142
type: z.literal('view_x_video_call'),
138143
...toolCallSchema.shape,
139144
}),
145+
z.object({
146+
type: z.literal('custom_tool_call'),
147+
...toolCallSchema.shape,
148+
}),
140149
z.object({
141150
type: z.literal('message'),
142151
role: z.string(),
@@ -239,6 +248,66 @@ export const xaiResponsesChunkSchema = z.union([
239248
annotation_index: z.number(),
240249
annotation: annotationSchema,
241250
}),
251+
z.object({
252+
type: z.literal('response.web_search_call.in_progress'),
253+
item_id: z.string(),
254+
output_index: z.number(),
255+
}),
256+
z.object({
257+
type: z.literal('response.web_search_call.searching'),
258+
item_id: z.string(),
259+
output_index: z.number(),
260+
}),
261+
z.object({
262+
type: z.literal('response.web_search_call.completed'),
263+
item_id: z.string(),
264+
output_index: z.number(),
265+
}),
266+
z.object({
267+
type: z.literal('response.x_search_call.in_progress'),
268+
item_id: z.string(),
269+
output_index: z.number(),
270+
}),
271+
z.object({
272+
type: z.literal('response.x_search_call.searching'),
273+
item_id: z.string(),
274+
output_index: z.number(),
275+
}),
276+
z.object({
277+
type: z.literal('response.x_search_call.completed'),
278+
item_id: z.string(),
279+
output_index: z.number(),
280+
}),
281+
z.object({
282+
type: z.literal('response.code_execution_call.in_progress'),
283+
item_id: z.string(),
284+
output_index: z.number(),
285+
}),
286+
z.object({
287+
type: z.literal('response.code_execution_call.executing'),
288+
item_id: z.string(),
289+
output_index: z.number(),
290+
}),
291+
z.object({
292+
type: z.literal('response.code_execution_call.completed'),
293+
item_id: z.string(),
294+
output_index: z.number(),
295+
}),
296+
z.object({
297+
type: z.literal('response.code_interpreter_call.in_progress'),
298+
item_id: z.string(),
299+
output_index: z.number(),
300+
}),
301+
z.object({
302+
type: z.literal('response.code_interpreter_call.executing'),
303+
item_id: z.string(),
304+
output_index: z.number(),
305+
}),
306+
z.object({
307+
type: z.literal('response.code_interpreter_call.completed'),
308+
item_id: z.string(),
309+
output_index: z.number(),
310+
}),
242311
z.object({
243312
type: z.literal('response.done'),
244313
response: xaiResponsesResponseSchema,

0 commit comments

Comments
 (0)