-
Notifications
You must be signed in to change notification settings - Fork 3.4k
fix(xai): support Responses API streaming events and custom_tool_call type #10523
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
gr2m
merged 2 commits into
vercel:main
from
baturyilmaz:fix/xai-responses-api-validation
Nov 25, 2025
Merged
fix(xai): support Responses API streaming events and custom_tool_call type #10523
gr2m
merged 2 commits into
vercel:main
from
baturyilmaz:fix/xai-responses-api-validation
Nov 25, 2025
+106
−18
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Collaborator
|
can you please resolve the conflict? |
Collaborator
|
see also #10497 |
… 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.
e65f5ed to
26f44c6
Compare
Make name, arguments, input, and call_id fields optional in toolCallSchema to match xAI API behavior during in_progress states. Add explicit ?? '' fallbacks in language model code for clear, maintainable handling of missing fields. Add custom_tool_call handling in both doGenerate and doStream methods, using the input field (instead of arguments) for custom tool calls per the API specification.
26f44c6 to
f7e041a
Compare
Contributor
Author
|
this pr is related to following issue: #10607 |
gr2m
approved these changes
Nov 25, 2025
Collaborator
gr2m
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you Batur, I confirmed the problem and your fix. Congratulations on landing your first contribution to the AI SDK!
vercel-ai-sdk bot
pushed a commit
that referenced
this pull request
Nov 25, 2025
… type (#10523) 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(). ## Background The xAI Responses API with server-side tools (`web_search`, `x_search`, `code_execution`) was failing with validation errors when using the Vercel AI SDK: ``` AI_TypeValidationError: Invalid JSON response Error: No matching discriminator for output[].type ``` **Root cause**: The xAI API returns response formats that were not included in the SDK's Zod validation schemas: 1. **`custom_tool_call` type** - Server-side tool calls use this type instead of the standard tool call types 2. **Streaming progress events** - Events like `response.web_search_call.in_progress`, `response.web_search_call.searching`, `response.web_search_call.completed` were not recognized 3. **Optional fields during execution** - During `in_progress` state, fields like `name`, `arguments`, `call_id` are undefined 4. **Different field names** - `custom_tool_call` uses `input` field instead of `arguments` ## Summary Updated `packages/xai/src/responses/xai-responses-api.ts` to support the complete xAI Responses API format: ### 1. Added `custom_tool_call` Type Support **Type definition** (`XaiResponsesToolCall`): ```typescript export type XaiResponsesToolCall = { type: | 'function_call' | 'web_search_call' | 'x_search_call' | 'code_interpreter_call' | 'custom_tool_call'; // ✅ Added id: string; call_id?: string; // ✅ Made optional name?: string; // ✅ Made optional arguments?: string; // ✅ Made optional input?: string; // ✅ Added for custom_tool_call status: string; action?: any; // ✅ Added for in_progress state }; ``` **Schema** (`outputItemSchema`): ```typescript z.object({ type: z.literal('custom_tool_call'), ...toolCallSchema.shape, }), ``` ### 2. Made Tool Call Fields Optional Updated `toolCallSchema` to handle in-progress states where fields are undefined: ```typescript const toolCallSchema = z.object({ name: z.string().optional(), // Was required arguments: z.string().optional(), // Was required input: z.string().optional(), // ✅ New (for custom_tool_call) call_id: z.string().optional(), // Was required id: z.string(), status: z.string(), action: z.any().optional(), // ✅ New (for in_progress state) }); ``` ### 3. Added 12 Streaming Event Types Added to `xaiResponsesChunkSchema` for complete tool execution lifecycle: **Web Search:** - `response.web_search_call.in_progress` - `response.web_search_call.searching` - `response.web_search_call.completed` **X Search:** - `response.x_search_call.in_progress` - `response.x_search_call.searching` - `response.x_search_call.completed` **Code Execution:** - `response.code_execution_call.in_progress` - `response.code_execution_call.executing` - `response.code_execution_call.completed` **Code Interpreter:** - `response.code_interpreter_call.in_progress` - `response.code_interpreter_call.executing` - `response.code_interpreter_call.completed` ## Manual Verification Tested all server-side tools with both `generateText()` and `streamText()` to ensure end-to-end functionality: ### ✅ Web Search Tool ```typescript import { xai } from '@ai-sdk/xai'; import { generateText } from 'ai'; const { text, sources } = await generateText({ model: xai.responses('grok-4-fast'), prompt: 'What are the latest developments in AI?', tools: { web_search: xai.tools.webSearch(), }, }); console.log(text); // Comprehensive response console.log(sources); // Array of URL citations ``` **Result**: ✅ Returned comprehensive response with 14 URL citations, no validation errors ### ✅ X Search Tool ```typescript import { xai } from '@ai-sdk/xai'; import { generateText } from 'ai'; const { text, sources } = await generateText({ model: xai.responses('grok-4-fast'), prompt: 'What are people saying about AI on X this week?', tools: { x_search: xai.tools.xSearch({ allowedXHandles: ['elonmusk', 'xai'], fromDate: '2025-11-18', toDate: '2025-11-24', enableImageUnderstanding: true, enableVideoUnderstanding: true, }), }, }); console.log(text); // Analysis of X discussions console.log(sources); // Array of X post citations ``` **Result**: ✅ Returned analysis with 16 X post citations, all streaming events properly handled ### ✅ Code Execution Tool ```typescript import { xai } from '@ai-sdk/xai'; import { generateText } from 'ai'; const { text } = await generateText({ model: xai.responses('grok-4-fast'), prompt: 'Calculate the factorial of 20 using Python', tools: { code_execution: xai.tools.codeExecution(), }, }); console.log(text); // Result with code execution details ``` **Result**: ✅ Computed result with execution details, no validation errors ### ✅ Multiple Tools with Streaming ```typescript import { xai } from '@ai-sdk/xai'; import { streamText } from 'ai'; const { fullStream, usage: usagePromise } = streamText({ model: xai.responses('grok-4-fast'), system: 'You are an AI research assistant.', tools: { web_search: xai.tools.webSearch(), x_search: xai.tools.xSearch(), code_execution: xai.tools.codeExecution(), }, prompt: 'Research prompt caching in LLMs and explain how it reduces costs', }); const sources = new Set<string>(); let lastToolName = ''; for await (const event of fullStream) { switch (event.type) { case 'tool-call': lastToolName = event.toolName; if (event.providerExecuted) { console.log(`[Calling ${event.toolName} on server...]`); } break; case 'tool-result': console.log(`[${lastToolName} completed]`); break; case 'text-delta': process.stdout.write(event.text); break; case 'source': if (event.sourceType === 'url') { sources.add(event.url); } break; } } const usage = await usagePromise; console.log(`\nSources used: ${sources.size}`); console.log(`Token usage: ${usage.inputTokens} input, ${usage.outputTokens} output`); ``` **Result**: ✅ Full streaming response with web searches, real-time progress updates, and source citations. All streaming events (`tool-call`, `tool-result`, `text-delta`, `source`) work correctly. **Summary of manual testing:** - ✅ All three tool types (web_search, x_search, code_execution) work without validation errors - ✅ Both `generateText()` and `streamText()` work correctly - ✅ Source citations are properly parsed and returned - ✅ Streaming progress events are handled correctly - ✅ No "Invalid JSON response" or "No matching discriminator" errors ## Related issues closes #10607
Contributor
|
✅ Backport PR created: #10610 |
vercel-ai-sdk bot
added a commit
that referenced
this pull request
Nov 25, 2025
…_tool_call type (#10610) This is an automated backport of #10523 to the release-v5.0 branch. FYI @baturyilmaz Co-authored-by: Batur <[email protected]>
4 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Add missing schema validation for xAI Responses API server-side tools:
Fixes validation errors ('Invalid JSON response', 'No matching discriminator') when using xai.responses() with xai.tools.webSearch(), xai.tools.xSearch(), or xai.tools.codeExecution().
Background
The xAI Responses API with server-side tools (
web_search,x_search,code_execution) was failing with validation errors when using the Vercel AI SDK:Root cause: The xAI API returns response formats that were not included in the SDK's Zod validation schemas:
custom_tool_calltype - Server-side tool calls use this type instead of the standard tool call typesresponse.web_search_call.in_progress,response.web_search_call.searching,response.web_search_call.completedwere not recognizedin_progressstate, fields likename,arguments,call_idare undefinedcustom_tool_callusesinputfield instead ofargumentsSummary
Updated
packages/xai/src/responses/xai-responses-api.tsto support the complete xAI Responses API format:1. Added
custom_tool_callType SupportType definition (
XaiResponsesToolCall):Schema (
outputItemSchema):2. Made Tool Call Fields Optional
Updated
toolCallSchemato handle in-progress states where fields are undefined:3. Added 12 Streaming Event Types
Added to
xaiResponsesChunkSchemafor complete tool execution lifecycle:Web Search:
response.web_search_call.in_progressresponse.web_search_call.searchingresponse.web_search_call.completedX Search:
response.x_search_call.in_progressresponse.x_search_call.searchingresponse.x_search_call.completedCode Execution:
response.code_execution_call.in_progressresponse.code_execution_call.executingresponse.code_execution_call.completedCode Interpreter:
response.code_interpreter_call.in_progressresponse.code_interpreter_call.executingresponse.code_interpreter_call.completedManual Verification
Tested all server-side tools with both
generateText()andstreamText()to ensure end-to-end functionality:✅ Web Search Tool
Result: ✅ Returned comprehensive response with 14 URL citations, no validation errors
✅ X Search Tool
Result: ✅ Returned analysis with 16 X post citations, all streaming events properly handled
✅ Code Execution Tool
Result: ✅ Computed result with execution details, no validation errors
✅ Multiple Tools with Streaming
Result: ✅ Full streaming response with web searches, real-time progress updates, and source citations. All streaming events (
tool-call,tool-result,text-delta,source) work correctly.Summary of manual testing:
generateText()andstreamText()work correctlyChecklist
pnpm changesetin the project root)Related issues
closes #10607