# xAI (Grok) Provider Guide
xAI's Grok models provide powerful reasoning capabilities with real-time web search through Live Search integration.
## Configuration
Set your xAI API key:
```bash
# Add to .env file (automatically loaded)
XAI_API_KEY=xai-...
```
Or use in-memory storage:
```elixir
ReqLLM.put_key(:xai_api_key, "xai-...")
```
## Supported Models
xAI Grok models:
- `grok-4` - Latest and most capable
- `grok-3-mini`, `grok-3-mini-fast` - Efficient with reasoning support
- `grok-2-1212`, `grok-2-vision-1212` - Previous generation with vision
- `grok-beta` - Beta features
See the full list with `mix req_llm.model_sync xai`.
## Basic Usage
```elixir
# Simple text generation
{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  "Explain quantum computing"
)
# Streaming
{:ok, stream_response} = ReqLLM.stream_text(
  "xai:grok-4",
  "Write a story"
)
ReqLLM.StreamResponse.tokens(stream_response)
|> Stream.each(&IO.write/1)
|> Stream.run()
```
## Provider-Specific Options
### Max Completion Tokens
Preferred over `max_tokens` for Grok-4 models:
```elixir
{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  "Long explanation",
  provider_options: [max_completion_tokens: 2000]
)
```
**Note**: ReqLLM automatically translates `max_tokens` to `max_completion_tokens` for models that require it.
### Live Search
Enable real-time web search capabilities:
```elixir
{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  "What are today's top tech headlines?",
  provider_options: [
    search_parameters: %{
      mode: "auto",              # auto, always, or never
      max_sources: 5,            # Maximum sources to cite
      date_range: "recent",      # recent, week, month, year
      citations: true            # Include citations in response
    }
  ]
)
```
Search modes:
- `"auto"` - Search when beneficial (default)
- `"always"` - Always search
- `"never"` - Disable search
**Note**: Live Search incurs additional costs per source retrieved.
### Reasoning Effort
Control reasoning level (grok-3-mini models only):
```elixir
{:ok, response} = ReqLLM.generate_text(
  "xai:grok-3-mini",
  "Complex problem",
  provider_options: [reasoning_effort: "high"]
)
```
Levels: `"low"`, `"medium"`, `"high"`
**Note**: Only supported for grok-3-mini and grok-3-mini-fast models.
### Parallel Tool Calls
Control whether multiple tools can be called simultaneously:
```elixir
{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  "Check weather in multiple cities",
  tools: [weather_tool],
  provider_options: [parallel_tool_calls: true]  # Default
)
```
### Structured Output Mode
xAI supports two modes for structured outputs:
```elixir
schema = [
  name: [type: :string, required: true],
  age: [type: :integer, required: true]
]
# Auto mode (recommended) - automatic selection
{:ok, response} = ReqLLM.generate_object(
  "xai:grok-4",
  "Generate a person",
  schema,
  provider_options: [xai_structured_output_mode: :auto]
)
# JSON schema mode - uses native response_format (models >= grok-2-1212)
{:ok, response} = ReqLLM.generate_object(
  "xai:grok-4",
  "Generate a person",
  schema,
  provider_options: [xai_structured_output_mode: :json_schema]
)
# Tool strict mode - uses strict tool calling (fallback for older models)
{:ok, response} = ReqLLM.generate_object(
  "xai:grok-2",
  "Generate a person",
  schema,
  provider_options: [xai_structured_output_mode: :tool_strict]
)
```
Modes:
- `:auto` - Automatic selection based on model (default)
- `:json_schema` - Native structured outputs (requires grok-2-1212+)
- `:tool_strict` - Strict tool calling fallback
### Stream Options
Configure streaming behavior:
```elixir
{:ok, stream_response} = ReqLLM.stream_text(
  "xai:grok-4",
  "Story",
  provider_options: [
    stream_options: %{include_usage: true}
  ]
)
```
## Complete Example with Live Search
```elixir
import ReqLLM.Context
context = Context.new([
  system("You are a helpful assistant with access to real-time web search"),
  user("Summarize today's news about AI developments")
])
{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  context,
  temperature: 0.7,
  max_tokens: 1500,
  provider_options: [
    search_parameters: %{
      mode: "always",
      max_sources: 10,
      date_range: "recent",
      citations: true
    },
    parallel_tool_calls: true
  ]
)
text = ReqLLM.Response.text(response)
usage = response.usage
IO.puts(text)
IO.puts("Cost: $#{usage.total_cost}")
```
## Tool Calling
Grok supports function calling:
```elixir
tools = [
  ReqLLM.tool(
    name: "get_weather",
    description: "Get weather for a location",
    parameter_schema: [
      location: [type: :string, required: true]
    ],
    callback: {WeatherAPI, :fetch}
  ),
  ReqLLM.tool(
    name: "get_stock_price",
    description: "Get stock price",
    parameter_schema: [
      symbol: [type: :string, required: true]
    ],
    callback: {StockAPI, :fetch}
  )
]
{:ok, response} = ReqLLM.generate_text(
  "xai:grok-4",
  "What's the weather in NYC and the price of AAPL?",
  tools: tools,
  provider_options: [parallel_tool_calls: true]  # Can call both tools at once
)
```
## Structured Output
Grok models support native structured outputs (grok-2-1212 and newer):
```elixir
schema = [
  title: [type: :string, required: true],
  summary: [type: :string, required: true],
  tags: [type: {:list, :string}],
  confidence: [type: :float]
]
{:ok, response} = ReqLLM.generate_object(
  "xai:grok-4",
  "Analyze this article and extract structured data",
  schema
)
data = ReqLLM.Response.object(response)
```
### Schema Constraints
xAI's native structured outputs have limitations:
**Not Supported:**
- `minLength`/`maxLength` for strings
- `minItems`/`maxItems`/`minContains`/`maxContains` for arrays
- `pattern` constraints
- `allOf` (must be expanded/flattened)
**Supported:**
- `anyOf`
- `additionalProperties: false` (enforced on root)
ReqLLM automatically sanitizes schemas to comply with these constraints.
## Model-Specific Notes
### Grok-4 Models
- Do NOT support `stop`, `presence_penalty`, or `frequency_penalty`
- Use `max_completion_tokens` instead of `max_tokens`
- Support native structured outputs
### Grok-3-mini Models
- Support `reasoning_effort` parameter
- Efficient for cost-sensitive applications
- Good balance of speed and quality
### Grok-2 Models (1212+)
- Support native structured outputs
- Support vision (grok-2-vision-1212)
- Previous generation capabilities
## Vision Support
Grok vision models support image analysis:
```elixir
import ReqLLM.Context
alias ReqLLM.Message.ContentPart
context = Context.new([
  user([
    ContentPart.text("Describe this image"),
    ContentPart.image_url("https://example.com/photo.jpg")
  ])
])
{:ok, response} = ReqLLM.generate_text(
  "xai:grok-2-vision-1212",
  context
)
```
## Error Handling
```elixir
case ReqLLM.generate_text("xai:grok-4", "Hello") do
  {:ok, response} -> 
    handle_success(response)
    
  {:error, error} -> 
    IO.puts("Error: #{error.message}")
end
```
## Cost Considerations
1. **Live Search**: Each source retrieved adds cost
2. **Model Selection**: grok-3-mini more cost-effective than grok-4
3. **Token Limits**: Set appropriate `max_completion_tokens` to control costs
## Resources
- [xAI API Documentation](https://docs.x.ai/)
- [Grok Models](https://x.ai/grok)
- [Pricing](https://x.ai/api)