xAI plugin
The xai plugin gives Genkit access to xAI’s Grok models through xAI’s
OpenAI-compatible chat completions endpoint. Models are named under the xai/ provider prefix.
Configuration
Section titled “Configuration”Add &xai.XAI{} to your plugin list. The plugin reads the API key from the XAI_API_KEY
environment variable.
package main
import ( "context"
"github.com/firebase/genkit/go/genkit" "github.com/firebase/genkit/go/plugins/compat_oai/xai")
func main() { ctx := context.Background()
g := genkit.Init(ctx, genkit.WithPlugins(&xai.XAI{}), genkit.WithDefaultModel("xai/grok-4.6"), )}You must provide an API key from xAI. You can get an API key from your
xAI account settings. Set XAI_API_KEY, or set the APIKey field.
Extra OpenAI client request options ride in Opts, applied after the plugin defaults so they win
on overlap.
import ( "context" "os"
"github.com/firebase/genkit/go/genkit" "github.com/firebase/genkit/go/plugins/compat_oai/xai" "github.com/openai/openai-go/option")
func main() { ctx := context.Background()
g := genkit.Init(ctx, genkit.WithPlugins(&xai.XAI{ APIKey: os.Getenv("MY_XAI_KEY"), Opts: []option.RequestOption{ option.WithBaseURL("https://api.x.ai/v1"), }, }))}genkit.Init panics when neither the APIKey field nor XAI_API_KEY is set. The endpoint
defaults to https://api.x.ai/v1; override it with the XAI_BASE_URL environment variable or
with option.WithBaseURL in Opts.
As always, avoid embedding API keys directly in your code.
Models
Section titled “Models”The plugin registers these Grok models when it initializes:
grok-4.6: the flagship, and the only model xAI documentsxhighreasoning effort forgrok-4.5grok-4.3: the long-context modelgrok-4.20-0309-reasoninggrok-4.20-0309-non-reasoninggrok-build-0.1: the agentic coding model, also served asgrok-code-fast-1
That list is a starting point rather than a limit. Any other Grok model ID resolves on demand and
takes the plugin’s defaults, so a model xAI releases later works without a Genkit upgrade.
grok-4.20-multi-agent-0309 is the exception: xAI serves it only through the Responses API, and
chat completions rejects it.
Structured output combined with tools is a Grok 4 family capability. grok-build-0.1 and any
dynamically resolved model advertise structured output without tools, so a request that carries
both falls back to schema instructions in the prompt.
xai.ModelRef pairs a model ID with a typed xai.ChatConfig, so the config is checked where you
write it and validated against the model’s schema before the request goes out.
resp, err := genkit.Generate(ctx, g, ai.WithModel(xai.ModelRef("grok-4.6", &xai.ChatConfig{ ReasoningEffort: xai.ReasoningEffortLow, MaxOutputTokens: 1024, })), ai.WithPrompt("Explain reinforcement learning in two sentences."),)if err != nil { log.Fatalf("could not generate: %v", err)}
fmt.Println(resp.Text())The ID passed to ModelRef works bare or provider-prefixed. You can also name a model as a string
with ai.WithModelName("xai/grok-4.6") or genkit.WithDefaultModel, and pass the config
separately with ai.WithConfig(&xai.ChatConfig{...}). The
xAI sample runs this as
a streaming flow you can call from the Dev UI.
Generation config
Section titled “Generation config”xai.ChatConfig carries the generation fields xAI accepts plus its own request controls:
| Field | Type | Notes |
|---|---|---|
Temperature | *float64 | Randomness of token selection, 0 to 2. |
TopP | *float64 | Nucleus sampling threshold. xAI documents no range for it. |
MaxOutputTokens | int | Sent as the API’s max_completion_tokens; xAI deprecated max_tokens. |
StopSequences | []string | Up to four. Reasoning models do not support them. |
FrequencyPenalty | *float64 | -2 to 2. Reasoning models do not support it. |
PresencePenalty | *float64 | -2 to 2. Reasoning models do not support it. |
LogProbs | *bool | Requests log probabilities for the output tokens. |
TopLogProbs | *int | 0 to 8. Requires LogProbs. |
Seed | *int | Makes generation reproducible on a best-effort basis. |
ReasoningEffort | xai.ReasoningEffort | none, low, medium, high, or xhigh. Which levels a model takes is the model’s to decide. |
ParallelToolCalls | *bool | false caps the model at one tool call per response. |
User | string | Identifies the end user a request is made for, which xAI uses to detect abuse. |
PromptCacheKey | string | Routes requests sharing a prompt prefix to the same backend. Hits come back as resp.Usage.CachedContentTokens. |
ServiceTier | xai.ServiceTier | default, or priority for faster scheduling at a higher rate. |
Pointer fields separate unset from a deliberate zero. n and deferred are deliberately absent:
Genkit reads only the first completion choice, and a deferred request answers with an ID to poll
rather than a completion.
ChatConfig also embeds compat_oai.RequestConfig, which every plugin in the family shares: a
per-request APIKey, a Version pin, and an Extra map whose keys ride to the wire verbatim
under xAI’s own names. See the
OpenAI-compatible plugin page.
Correcting what the plugin knows about a model
Section titled “Correcting what the plugin knows about a model”Every Grok model works without an entry in Models. Supply one only to correct or extend the
capabilities the plugin resolves, most often for a model released after your Genkit version.
Fields left at their zero value keep what the plugin resolved.
g := genkit.Init(ctx, genkit.WithPlugins(&xai.XAI{ Models: map[string]ai.ModelOptions{ "grok-4.5": { Supports: &ai.ModelSupports{ Multiturn: true, Tools: true, SystemRole: true, Media: true, }, }, },}))Response behavior
Section titled “Response behavior”Reasoning text, streamed token usage, cached prompt tokens, and mid-generation provider failures are handled the same way for every plugin in this family. See the OpenAI-compatible plugin page.