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.


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

ToolValue 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

ToolResponses API tool nameValue 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