Tools
Streaming & Synchronous Requests
Agentic requests can be executed in either streaming or synchronous mode. This page covers both approaches and how to use them effectively.
Streaming Mode (Recommended)
We strongly recommend using streaming mode when using agentic tool calling. It provides:
- Real-time observability of tool calls as they happen
- Immediate feedback during potentially long-running requests
- Reasoning token counts as the model thinks
Streaming Example
import { xai } from '@ai-sdk/xai';
import { streamText } from 'ai';
const { fullStream } = streamText({
model: xai.responses('grok-4.7'),
prompt: 'What are the latest updates from SpaceXSI?',
tools: {
web_search: xai.tools.webSearch(),
x_search: xai.tools.xSearch(),
code_execution: xai.tools.codeExecution(),
},
});
for await (const part of fullStream) {
if (part.type === 'tool-call') {
console.log(`Calling tool: ${part.toolName}`);
} else if (part.type === 'text-delta') {
process.stdout.write(part.text);
} else if (part.type === 'source' && part.sourceType === 'url') {
console.log(`Citation: ${part.url}`);
}
}Synchronous Mode
For simpler use cases or when you want to wait for the complete agentic workflow to finish before processing the response, you can use synchronous requests:
import { xai } from '@ai-sdk/xai';
import { generateText } from 'ai';
// Synchronous request - waits for complete response
const { text, sources } = await generateText({
model: xai.responses('grok-4.7'),
prompt: 'What is the latest update from SpaceXSI?',
tools: {
web_search: xai.tools.webSearch(),
x_search: xai.tools.xSearch(),
code_execution: xai.tools.codeExecution(),
},
});
console.log('Final Response:');
console.log(text);
console.log('\nCitations:');
console.log(sources);Synchronous requests will wait for the entire agentic process to complete before returning. This is simpler for basic use cases but provides less visibility into intermediate steps.
Using Tools with Responses API
We also support using the Responses API in both streaming and non-streaming modes:
import os
from openai import OpenAI
api_key = os.getenv("XAI_API_KEY")
client = OpenAI(
api_key=api_key,
base_url="https://api.x.ai/v1",
)
response = client.responses.create(
model="grok-4.7",
input=[
{
"role": "user",
"content": "what is the latest update from SpaceXSI?",
},
],
tools=[
{
"type": "web_search",
},
{
"type": "x_search",
},
],
)
print(response)Accessing Tool Outputs
By default, server-side tool call outputs are not returned since they can be large. However, you can opt-in to receive them:
xAI SDK
| Tool | Value for include field |
|---|---|
"web_search" | "web_search_call_output" |
"x_search" | "x_search_call_output" |
"code_execution" | "code_execution_call_output" |
"collections_search" | "collections_search_call_output" |
"attachment_search" | "attachment_search_call_output" |
"mcp" | "mcp_call_output" |
Python
import os
from xai_sdk import Client
from xai_sdk.chat import user
from xai_sdk.tools import code_execution
client = Client(api_key=os.getenv("XAI_API_KEY"))
chat = client.chat.create(
model="grok-4.7",
tools=[
code_execution(),
],
include=["code_execution_call_output"],
)
chat.append(user("What is the 100th Fibonacci number?"))
# stream or sample the response...Responses API
| Tool | Responses API tool name | Value for include field |
|---|---|---|
"web_search" | "web_search" | "web_search_call.action.sources" |
"code_execution" | "code_interpreter" | "code_interpreter_call.outputs" |
"collections_search" | "file_search" | "file_search_call.results" |
"mcp" | "mcp" | Always returned in Responses API |
Last updated: October 10, 2026