xAI provider
Standalone — usable in any Node project, no
@warlock.js/corerequired.
@warlock.js/ai-xai is the provider adapter for xAI’s Grok models. xAI
speaks the OpenAI Chat Completions protocol, so XaiSDK is a thin wrapper
over the OpenAI adapter: it constructs one
internal OpenAISDK pointed at https://api.x.ai/v1 and labeled
provider: "xai", then delegates everything to it — while injecting xAI’s own
capability inference so Grok model names resolve to the right vision and
reasoning flags.
You get a vendor-neutral ModelContract — the same shape every agent,
workflow, and supervisor already speaks.
Install
Section titled “Install”npm install @warlock.js/ai @warlock.js/ai-xaiyarn add @warlock.js/ai @warlock.js/ai-xaipnpm add @warlock.js/ai @warlock.js/ai-xaiConstruct
Section titled “Construct”XaiSDK is a class holding a long-lived wrapped client. Build it once at boot
and reuse it everywhere — every model it produces shares the same connection
pool, auth, and rate-limit state.
import { XaiSDK } from "@warlock.js/ai-xai";
const xai = new XaiSDK({ apiKey: process.env.XAI_API_KEY! });baseURLdefaults tohttps://api.x.ai/v1(the xAI OpenAI-compatible endpoint). Override only to target a proxy/gateway.providerdefaults to"xai"and flows through toModelContract.provider,AgentReport.model.provider, and logs. Set it to relabel a gateway upstream.- Every other upstream client option (
timeout,maxRetries,defaultHeaders,fetch, …) is forwarded verbatim to the wrapped client.
const xai = new XaiSDK({ apiKey: process.env.XAI_API_KEY!, baseURL: "https://my-gateway.internal/xai", provider: "xai-gateway",});First call
Section titled “First call”Build a model, hand it to an agent, run it. execute() never throws —
failures land in error as a typed AIError.
import { ai } from "@warlock.js/ai";import { XaiSDK } from "@warlock.js/ai-xai";
const xai = new XaiSDK({ apiKey: process.env.XAI_API_KEY! });
const assistant = ai.agent({ model: xai.model({ name: "grok-4" }), systemPrompt: "You are a concise senior TypeScript engineer.",});
const { text, usage, error } = await assistant.execute("Why use generics?");
if (error) { console.warn(error.code, error.category);} else { console.log(text, usage.total);}Use as a model
Section titled “Use as a model”xai.model({ name: "grok-4" }); // vision + reasoning auto-truexai.model({ name: "grok-3-mini" }); // reasoning auto-true, vision falsexai.model({ name: "grok-2-vision" }); // vision auto-truexai.model({ name: "grok-4", temperature: 0.2 }); // sampling controlsxai.model({ name: "grok-3", vision: true }); // explicit capability overrideReturns a ModelContract you pass straight into any agent, workflow, or
supervisor.
Models and capabilities
Section titled “Models and capabilities”This adapter ships xAI’s own name lists — Grok ids don’t match OpenAI’s
gpt-* / o* prefixes. Capabilities are injected per model before delegating;
an explicit value always wins over inference.
| Model | vision | reasoning |
|---|---|---|
grok-4 | true | true (reasoning-first) |
grok-3 | false | false |
grok-3-mini | false | true (the “think” variant) |
grok-2-vision | true | false |
grok-2 | false | false |
vision— inferredtruefor thegrok-4andgrok-2-visionprefixes;falseotherwise.reasoning— inferredtrueforgrok-4andgrok-3-mini; drives whetherreasoning.effortis forwarded asreasoning_efforton the wire.structuredOutput/promptCachingand the image/PDF/audio wire mapping all come from the wrapped OpenAI adapter unchanged.
Override vision, reasoning, or structuredOutput explicitly via
.model({ name, vision?, reasoning?, structuredOutput? }).
Reasoning effort
Section titled “Reasoning effort”grok-4 and grok-3-mini are reasoning-capable. reasoning.effort
("low" | "medium" | "high") maps verbatim to the OpenAI-compatible
reasoning_effort param. When capabilities.reasoning is false (e.g.
grok-3), the option is dropped — the adapter never forwards it. Pin
reasoning: true to force it for a custom/gateway id.
const model = xai.model({ name: "grok-4" }); // reasoning auto-trueawait model.complete(messages, { reasoning: { effort: "high" } }); // → reasoning_effort: "high"Vision
Section titled “Vision”Image attachments reach the wire only on a vision-capable model (grok-4,
grok-2-vision); the agent’s modality gate throws otherwise. Mapping to
OpenAI image_url parts is identical to the OpenAI adapter.
const model = xai.model({ name: "grok-4" });
const response = await model.complete([ { role: "user", content: [ { type: "text", text: "What's in this photo?" }, { type: "image", source: { url: "https://example.com/cat.jpg" } }, ], },]);Pricing and usage
Section titled “Pricing and usage”Every response reports token usage (input, output, total). To turn
tokens into money, attach a pricing registry — keyed by model name, in USD
per million tokens (input, output, optional cachedInput / cachedOutput).
Resolution is delegated: per-model pricing > SDK registry > undefined (no
cost computed).
const xai = new XaiSDK({ apiKey: process.env.XAI_API_KEY!, pricing: { "grok-4": { input: 3, output: 15 }, "grok-3-mini": { input: 0.3, output: 0.5 }, },});
const { usage } = await ai.agent({ model: xai.model({ name: "grok-4" }) }).execute("hi");usage.cost; // per-channel USD breakdown of this run, or undefined when unpricedEmbeddings and images
Section titled “Embeddings and images”xAI does not currently expose a public embeddings endpoint.
xai.embedder({...}) is wired for protocol parity, but a call to embed() /
embedMany() fails upstream — point an embedder at a dedicated provider like
OpenAI for vectors.
xai.image({...}) delegates to the wrapped OpenAI Images adapter, which only
recognizes gpt-image-* / dall-e-* ids and rejects anything else at
construction. xAI’s image generation (“Grok Imagine”) is a separate, non-
OpenAI-Images-compatible surface, so use the
OpenAI provider’s image() for OpenAI-Images
generation.
See also
Section titled “See also”- OpenAI provider — the wrapped adapter; full wire / streaming / structured-output / multipart surface applies here.
@warlock.js/ai— the agent, tool, and system-prompt surface these models plug into.- For provider-specific notes and the latest model ids, see the
setup-xaiskill.