@warlock.js/ai-xai 5.28.0 → 5.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,18 @@ All notable changes to `@warlock.js/ai-xai` are documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
6
6
 
7
+ ## 5.30.0 - 2026-10-16
8
+
9
+ ### Changed
10
+
11
+ - Lockstep release; package APIs are unchanged.
12
+
13
+ ## 5.29.0 - 2026-10-01
14
+
15
+ ### Changed
16
+
17
+ - Lockstep release; package APIs are unchanged. Skills refer to other topics by name instead of file paths, so cross-references keep working after `agent-kit` copies them into an app.
18
+
7
19
  ## 5.28.0 - 2026-10-01
8
20
 
9
21
  ### Changed
package/cjs/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  let _warlock_js_ai_openai = require("@warlock.js/ai-openai");
3
3
 
4
- //#region ../ai-xai/src/known-models.ts
4
+ //#region ../../packages/ai-xai/src/known-models.ts
5
5
  /**
6
6
  * Capability inference for xAI Grok model ids.
7
7
  *
@@ -95,7 +95,7 @@ function inferReasoningCapability(modelId) {
95
95
  }
96
96
 
97
97
  //#endregion
98
- //#region ../ai-xai/src/sdk.ts
98
+ //#region ../../packages/ai-xai/src/sdk.ts
99
99
  /**
100
100
  * The xAI OpenAI-compatible base URL. xAI exposes Chat Completions at
101
101
  * `POST /v1/chat/completions` on this host, so the whole adapter rides
package/cjs/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["OpenAISDK"],"sources":["../../../../../../ai-xai/src/known-models.ts","../../../../../../ai-xai/src/sdk.ts"],"sourcesContent":["/**\n * Capability inference for xAI Grok model ids.\n *\n * xAI speaks the OpenAI Chat Completions protocol, so the wire-level\n * adapter is `OpenAISDK`. But Grok model names (`grok-4`,\n * `grok-2-vision`, …) don't match OpenAI's `gpt-*` / `o*` prefixes, so\n * OpenAI's own inference lists would mis-classify every Grok model as\n * non-vision / non-reasoning. This module supplies xAI's OWN name lists\n * and the `XaiSDK` wrapper injects the resulting capability flags into\n * each `OpenAIModelConfig` before delegating, so the right capabilities\n * are set even though the names aren't OpenAI names.\n *\n * All lists are matched as a prefix so dated / `-latest` / `-fast`\n * variants (`grok-4-0709`, `grok-2-vision-latest`,\n * `grok-3-mini-beta`) are covered without enumerating every release\n * tag. Devs can always override per-model via\n * `xai.model({ name, vision: true | false, reasoning: true | false })`\n * — explicit config wins over inference in either direction.\n */\n\n/**\n * Model-name prefixes for Grok families that accept image input\n * (vision) on the OpenAI-compatible Chat Completions endpoint.\n *\n * - `grok-4` is natively multimodal (text + image input).\n * - `grok-2-vision` is the dedicated image-understanding Grok 2 model.\n *\n * Text-only families (`grok-3`, `grok-3-mini`, the base `grok-2`\n * text model) are intentionally excluded so passing an image\n * attachment to them surfaces a clear, agent-side capability error\n * rather than an opaque xAI 400.\n */\nexport const XAI_VISION_MODEL_PREFIXES = [\"grok-4\", \"grok-2-vision\"] as const;\n\n/**\n * Model-name prefixes for Grok families that expose internal reasoning\n * and accept reasoning controls (e.g. `reasoning_effort`) on the\n * OpenAI-compatible Chat Completions endpoint.\n *\n * - `grok-4` is a reasoning-first model (it always reasons).\n * - `grok-3-mini` is the \"think\" variant of Grok 3 and reasons; the\n * full-size `grok-3` does not, so it is deliberately NOT covered by\n * the `grok-3-mini` prefix.\n */\nexport const XAI_REASONING_MODEL_PREFIXES = [\"grok-4\", \"grok-3-mini\"] as const;\n\n/**\n * A convenience list of the current public Grok chat model ids, handy\n * for menus, validation, and docs. Not exhaustive of every dated alias\n * xAI publishes — pass any id through `xai.model({ name })`; the prefix\n * inference above handles dated / `-latest` variants.\n *\n * @example\n * XAI_CHAT_MODELS.includes(\"grok-4\"); // → true\n */\nexport const XAI_CHAT_MODELS = [\n \"grok-4\",\n \"grok-3\",\n \"grok-3-mini\",\n \"grok-2-vision\",\n \"grok-2\",\n] as const;\n\n/**\n * Infer whether a given Grok model id supports vision based on xAI's\n * known-prefix list. Unknown ids default to `false` so that passing an\n * image attachment to an unsupported model surfaces a clear,\n * agent-side capability error instead of an opaque xAI 400.\n *\n * @example\n * inferVisionCapability(\"grok-4\"); // → true\n * inferVisionCapability(\"grok-2-vision-latest\"); // → true\n * inferVisionCapability(\"grok-3\"); // → false\n * inferVisionCapability(\"grok-3-mini\"); // → false\n */\nexport function inferVisionCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return XAI_VISION_MODEL_PREFIXES.some((prefix) => normalized.startsWith(prefix));\n}\n\n/**\n * Infer whether a given Grok model id is a reasoning model based on\n * xAI's known-prefix list. Unknown ids default to `false` so the\n * adapter never forwards an unsupported reasoning param to a\n * non-reasoning model.\n *\n * @example\n * inferReasoningCapability(\"grok-4\"); // → true\n * inferReasoningCapability(\"grok-3-mini\"); // → true\n * inferReasoningCapability(\"grok-3\"); // → false\n * inferReasoningCapability(\"grok-2-vision\"); // → false\n */\nexport function inferReasoningCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return XAI_REASONING_MODEL_PREFIXES.some((prefix) => normalized.startsWith(prefix));\n}\n","import type {\n EmbedderContract,\n ImageModelContract,\n ModelContract,\n ModelPricing,\n SDKAdapterContract,\n} from \"@warlock.js/ai\";\nimport { OpenAISDK } from \"@warlock.js/ai-openai\";\nimport type {\n XaiEmbedderConfig,\n XaiImageConfig,\n XaiModelConfig,\n XaiSDKConfig,\n} from \"./config.type\";\nimport { inferReasoningCapability, inferVisionCapability } from \"./known-models\";\n\n/**\n * The xAI OpenAI-compatible base URL. xAI exposes Chat Completions at\n * `POST /v1/chat/completions` on this host, so the whole adapter rides\n * on the OpenAI wire protocol.\n */\nconst XAI_BASE_URL = \"https://api.x.ai/v1\";\n\n/**\n * The default `provider` label stamped on every model this SDK\n * produces. Surfaces on `ModelContract.provider`, `AgentReport.model`,\n * logs, and any provider-aware middleware.\n */\nconst XAI_PROVIDER = \"xai\";\n\n/**\n * xAI Grok-backed implementation of `SDKAdapterContract`.\n *\n * **Role.** The package entry point for xAI's Grok models. xAI speaks\n * the OpenAI Chat Completions protocol, so `XaiSDK` is a *thin wrapper*\n * over the already-battle-tested {@link OpenAISDK} from\n * `@warlock.js/ai-openai` — NOT a reimplementation. It constructs one\n * internal `OpenAISDK` pointed at xAI's `baseURL` and labeled\n * `provider: \"xai\"`, then delegates `model()` / `embedder()` /\n * `image()` / `count()` to it. Construct one SDK per account and reuse\n * it everywhere.\n *\n * **Responsibility.**\n * - Owns: the xAI defaults (`baseURL` → `https://api.x.ai/v1`,\n * `provider` → `\"xai\"`) and this provider's OWN capability inference.\n * Grok model names (`grok-4`, `grok-2-vision`, …) don't match\n * OpenAI's `gpt-*` / `o*` prefixes, so before delegating `model()`\n * the wrapper injects the `vision` / `reasoning` flags inferred from\n * xAI's name lists (see `known-models.ts`). Because explicit config\n * wins over OpenAI's inference inside `OpenAIModel`, the produced\n * `ModelContract` carries the correct Grok capabilities.\n * - Does NOT own: the wire protocol, request/response mapping,\n * streaming, tool-call accumulation, error wrapping, or pricing\n * resolution — all of that is the wrapped `OpenAISDK`'s job and is\n * reused verbatim.\n *\n * Modeled as a class (see §4.2 of code-style.md — \"long-lived state\n * across many calls\"): it holds one live `OpenAISDK` (which in turn\n * holds one live `OpenAI` client), fronted by FP usage like the other\n * adapters.\n *\n * @example\n * const xai = new XaiSDK({ apiKey: process.env.XAI_API_KEY! });\n * const model = xai.model({ name: \"grok-4\", temperature: 0.7 });\n * const myAgent = ai.agent({ model });\n *\n * @example\n * // Compose into an `ai.xai` namespace for ergonomic agent wiring.\n * const ai = { agent, tool, systemPrompt, xai: new XaiSDK({ apiKey }) };\n * const fast = ai.agent({ model: ai.xai.model({ name: \"grok-3-mini\" }) });\n */\nexport class XaiSDK implements SDKAdapterContract {\n /**\n * The wrapped OpenAI-compatible adapter doing the actual wire work.\n * Constructed once with xAI's `baseURL` + `provider` and the caller's\n * `apiKey` / client options, then reused for every produced model,\n * embedder, and image model.\n */\n private readonly openai: OpenAISDK;\n\n /**\n * Optional SDK-level pricing registry, kept so `model()` can resolve\n * a per-model entry while still applying this provider's default\n * capability inference. The wrapped `OpenAISDK` also resolves\n * pricing, but we surface it here for parity and to keep the default\n * baseURL/provider injection in one place.\n */\n private readonly pricing?: Record<string, ModelPricing>;\n\n public constructor(config: XaiSDKConfig) {\n const { baseURL, provider, ...rest } = config;\n\n // Inject xAI's defaults — `baseURL` → the xAI OpenAI-compatible\n // endpoint, `provider` → \"xai\" — while still letting the caller\n // override either (e.g. a corporate proxy or a relabeled gateway).\n this.openai = new OpenAISDK({\n ...rest,\n baseURL: baseURL ?? XAI_BASE_URL,\n provider: provider ?? XAI_PROVIDER,\n });\n\n this.pricing = config.pricing;\n }\n\n /**\n * Build a `ModelContract` for a Grok model. Delegates to the wrapped\n * `OpenAISDK.model()` after injecting this provider's OWN capability\n * inference: `vision` and `reasoning` are resolved from xAI's\n * name-prefix lists (see `known-models.ts`) unless the caller set them\n * explicitly. Because explicit config wins over OpenAI's inference\n * inside `OpenAIModel`, the returned model self-identifies as\n * `provider: \"xai\"` and carries Grok's real capabilities even though\n * the model name isn't an OpenAI name.\n *\n * Pricing resolution is left to the wrapped adapter: per-model\n * `config.pricing` wins, otherwise the SDK-level registry entry keyed\n * by `config.name`, otherwise `undefined` (no cost computed).\n *\n * @example\n * xai.model({ name: \"grok-4\" }); // vision + reasoning auto-true\n * xai.model({ name: \"grok-3-mini\" }); // reasoning auto-true, vision false\n */\n public model(config: XaiModelConfig): ModelContract {\n return this.openai.model({\n ...config,\n // xAI names don't match OpenAI's vision/reasoning prefixes, so we\n // resolve them here and pass explicit flags through — explicit\n // config always wins over the OpenAI adapter's own inference.\n vision: config.vision ?? inferVisionCapability(config.name),\n reasoning: config.reasoning ?? inferReasoningCapability(config.name),\n });\n }\n\n /**\n * Rough token-count estimate. Delegates straight to the wrapped\n * `OpenAISDK.count()` (the shared character-heuristic from the core\n * package — offline, good for budgeting/quota guards, not billing).\n */\n public async count(text: string, model?: string): Promise<number> {\n return this.openai.count(text, model);\n }\n\n /**\n * Build an `EmbedderContract` by delegating to the wrapped\n * `OpenAISDK.embedder()`.\n *\n * NOTE: xAI does not currently expose a public embeddings endpoint, so\n * this is wired for protocol parity but a call to `embed()` /\n * `embedMany()` will fail upstream. Point an embedder at a dedicated\n * embeddings provider (e.g. `@warlock.js/ai-openai`) for vectors.\n */\n public embedder(config: XaiEmbedderConfig): EmbedderContract {\n return this.openai.embedder(config);\n }\n\n /**\n * Build an `ImageModelContract` by delegating to the wrapped\n * `OpenAISDK.image()` for use with `ai.image({ model, prompt })`.\n * Pricing resolution mirrors `model()` (per-model `pricing` > SDK\n * registry > `undefined`).\n */\n public image(config: XaiImageConfig): ImageModelContract {\n return this.openai.image(config);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,MAAa,4BAA4B,CAAC,UAAU,eAAe;;;;;;;;;;;AAYnE,MAAa,+BAA+B,CAAC,UAAU,aAAa;;;;;;;;;;AAWpE,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;;;AAcA,SAAgB,sBAAsB,SAA0B;CAC9D,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,0BAA0B,MAAM,WAAW,WAAW,WAAW,MAAM,CAAC;AACjF;;;;;;;;;;;;;AAcA,SAAgB,yBAAyB,SAA0B;CACjE,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,6BAA6B,MAAM,WAAW,WAAW,WAAW,MAAM,CAAC;AACpF;;;;;;;;;AC5EA,MAAM,eAAe;;;;;;AAOrB,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CrB,IAAa,SAAb,MAAkD;CAkBhD,AAAO,YAAY,QAAsB;EACvC,MAAM,EAAE,SAAS,UAAU,GAAG,SAAS;EAKvC,KAAK,SAAS,IAAIA,gCAAU;GAC1B,GAAG;GACH,SAAS,WAAW;GACpB,UAAU,YAAY;EACxB,CAAC;EAED,KAAK,UAAU,OAAO;CACxB;;;;;;;;;;;;;;;;;;;CAoBA,AAAO,MAAM,QAAuC;EAClD,OAAO,KAAK,OAAO,MAAM;GACvB,GAAG;GAIH,QAAQ,OAAO,UAAU,sBAAsB,OAAO,IAAI;GAC1D,WAAW,OAAO,aAAa,yBAAyB,OAAO,IAAI;EACrE,CAAC;CACH;;;;;;CAOA,MAAa,MAAM,MAAc,OAAiC;EAChE,OAAO,KAAK,OAAO,MAAM,MAAM,KAAK;CACtC;;;;;;;;;;CAWA,AAAO,SAAS,QAA6C;EAC3D,OAAO,KAAK,OAAO,SAAS,MAAM;CACpC;;;;;;;CAQA,AAAO,MAAM,QAA4C;EACvD,OAAO,KAAK,OAAO,MAAM,MAAM;CACjC;AACF"}
1
+ {"version":3,"file":"index.cjs","names":["OpenAISDK"],"sources":["../../../../../../../packages/ai-xai/src/known-models.ts","../../../../../../../packages/ai-xai/src/sdk.ts"],"sourcesContent":["/**\n * Capability inference for xAI Grok model ids.\n *\n * xAI speaks the OpenAI Chat Completions protocol, so the wire-level\n * adapter is `OpenAISDK`. But Grok model names (`grok-4`,\n * `grok-2-vision`, …) don't match OpenAI's `gpt-*` / `o*` prefixes, so\n * OpenAI's own inference lists would mis-classify every Grok model as\n * non-vision / non-reasoning. This module supplies xAI's OWN name lists\n * and the `XaiSDK` wrapper injects the resulting capability flags into\n * each `OpenAIModelConfig` before delegating, so the right capabilities\n * are set even though the names aren't OpenAI names.\n *\n * All lists are matched as a prefix so dated / `-latest` / `-fast`\n * variants (`grok-4-0709`, `grok-2-vision-latest`,\n * `grok-3-mini-beta`) are covered without enumerating every release\n * tag. Devs can always override per-model via\n * `xai.model({ name, vision: true | false, reasoning: true | false })`\n * — explicit config wins over inference in either direction.\n */\n\n/**\n * Model-name prefixes for Grok families that accept image input\n * (vision) on the OpenAI-compatible Chat Completions endpoint.\n *\n * - `grok-4` is natively multimodal (text + image input).\n * - `grok-2-vision` is the dedicated image-understanding Grok 2 model.\n *\n * Text-only families (`grok-3`, `grok-3-mini`, the base `grok-2`\n * text model) are intentionally excluded so passing an image\n * attachment to them surfaces a clear, agent-side capability error\n * rather than an opaque xAI 400.\n */\nexport const XAI_VISION_MODEL_PREFIXES = [\"grok-4\", \"grok-2-vision\"] as const;\n\n/**\n * Model-name prefixes for Grok families that expose internal reasoning\n * and accept reasoning controls (e.g. `reasoning_effort`) on the\n * OpenAI-compatible Chat Completions endpoint.\n *\n * - `grok-4` is a reasoning-first model (it always reasons).\n * - `grok-3-mini` is the \"think\" variant of Grok 3 and reasons; the\n * full-size `grok-3` does not, so it is deliberately NOT covered by\n * the `grok-3-mini` prefix.\n */\nexport const XAI_REASONING_MODEL_PREFIXES = [\"grok-4\", \"grok-3-mini\"] as const;\n\n/**\n * A convenience list of the current public Grok chat model ids, handy\n * for menus, validation, and docs. Not exhaustive of every dated alias\n * xAI publishes — pass any id through `xai.model({ name })`; the prefix\n * inference above handles dated / `-latest` variants.\n *\n * @example\n * XAI_CHAT_MODELS.includes(\"grok-4\"); // → true\n */\nexport const XAI_CHAT_MODELS = [\n \"grok-4\",\n \"grok-3\",\n \"grok-3-mini\",\n \"grok-2-vision\",\n \"grok-2\",\n] as const;\n\n/**\n * Infer whether a given Grok model id supports vision based on xAI's\n * known-prefix list. Unknown ids default to `false` so that passing an\n * image attachment to an unsupported model surfaces a clear,\n * agent-side capability error instead of an opaque xAI 400.\n *\n * @example\n * inferVisionCapability(\"grok-4\"); // → true\n * inferVisionCapability(\"grok-2-vision-latest\"); // → true\n * inferVisionCapability(\"grok-3\"); // → false\n * inferVisionCapability(\"grok-3-mini\"); // → false\n */\nexport function inferVisionCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return XAI_VISION_MODEL_PREFIXES.some((prefix) => normalized.startsWith(prefix));\n}\n\n/**\n * Infer whether a given Grok model id is a reasoning model based on\n * xAI's known-prefix list. Unknown ids default to `false` so the\n * adapter never forwards an unsupported reasoning param to a\n * non-reasoning model.\n *\n * @example\n * inferReasoningCapability(\"grok-4\"); // → true\n * inferReasoningCapability(\"grok-3-mini\"); // → true\n * inferReasoningCapability(\"grok-3\"); // → false\n * inferReasoningCapability(\"grok-2-vision\"); // → false\n */\nexport function inferReasoningCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return XAI_REASONING_MODEL_PREFIXES.some((prefix) => normalized.startsWith(prefix));\n}\n","import type {\n EmbedderContract,\n ImageModelContract,\n ModelContract,\n ModelPricing,\n SDKAdapterContract,\n} from \"@warlock.js/ai\";\nimport { OpenAISDK } from \"@warlock.js/ai-openai\";\nimport type {\n XaiEmbedderConfig,\n XaiImageConfig,\n XaiModelConfig,\n XaiSDKConfig,\n} from \"./config.type\";\nimport { inferReasoningCapability, inferVisionCapability } from \"./known-models\";\n\n/**\n * The xAI OpenAI-compatible base URL. xAI exposes Chat Completions at\n * `POST /v1/chat/completions` on this host, so the whole adapter rides\n * on the OpenAI wire protocol.\n */\nconst XAI_BASE_URL = \"https://api.x.ai/v1\";\n\n/**\n * The default `provider` label stamped on every model this SDK\n * produces. Surfaces on `ModelContract.provider`, `AgentReport.model`,\n * logs, and any provider-aware middleware.\n */\nconst XAI_PROVIDER = \"xai\";\n\n/**\n * xAI Grok-backed implementation of `SDKAdapterContract`.\n *\n * **Role.** The package entry point for xAI's Grok models. xAI speaks\n * the OpenAI Chat Completions protocol, so `XaiSDK` is a *thin wrapper*\n * over the already-battle-tested {@link OpenAISDK} from\n * `@warlock.js/ai-openai` — NOT a reimplementation. It constructs one\n * internal `OpenAISDK` pointed at xAI's `baseURL` and labeled\n * `provider: \"xai\"`, then delegates `model()` / `embedder()` /\n * `image()` / `count()` to it. Construct one SDK per account and reuse\n * it everywhere.\n *\n * **Responsibility.**\n * - Owns: the xAI defaults (`baseURL` → `https://api.x.ai/v1`,\n * `provider` → `\"xai\"`) and this provider's OWN capability inference.\n * Grok model names (`grok-4`, `grok-2-vision`, …) don't match\n * OpenAI's `gpt-*` / `o*` prefixes, so before delegating `model()`\n * the wrapper injects the `vision` / `reasoning` flags inferred from\n * xAI's name lists (see `known-models.ts`). Because explicit config\n * wins over OpenAI's inference inside `OpenAIModel`, the produced\n * `ModelContract` carries the correct Grok capabilities.\n * - Does NOT own: the wire protocol, request/response mapping,\n * streaming, tool-call accumulation, error wrapping, or pricing\n * resolution — all of that is the wrapped `OpenAISDK`'s job and is\n * reused verbatim.\n *\n * Modeled as a class (see §4.2 of code-style.md — \"long-lived state\n * across many calls\"): it holds one live `OpenAISDK` (which in turn\n * holds one live `OpenAI` client), fronted by FP usage like the other\n * adapters.\n *\n * @example\n * const xai = new XaiSDK({ apiKey: process.env.XAI_API_KEY! });\n * const model = xai.model({ name: \"grok-4\", temperature: 0.7 });\n * const myAgent = ai.agent({ model });\n *\n * @example\n * // Compose into an `ai.xai` namespace for ergonomic agent wiring.\n * const ai = { agent, tool, systemPrompt, xai: new XaiSDK({ apiKey }) };\n * const fast = ai.agent({ model: ai.xai.model({ name: \"grok-3-mini\" }) });\n */\nexport class XaiSDK implements SDKAdapterContract {\n /**\n * The wrapped OpenAI-compatible adapter doing the actual wire work.\n * Constructed once with xAI's `baseURL` + `provider` and the caller's\n * `apiKey` / client options, then reused for every produced model,\n * embedder, and image model.\n */\n private readonly openai: OpenAISDK;\n\n /**\n * Optional SDK-level pricing registry, kept so `model()` can resolve\n * a per-model entry while still applying this provider's default\n * capability inference. The wrapped `OpenAISDK` also resolves\n * pricing, but we surface it here for parity and to keep the default\n * baseURL/provider injection in one place.\n */\n private readonly pricing?: Record<string, ModelPricing>;\n\n public constructor(config: XaiSDKConfig) {\n const { baseURL, provider, ...rest } = config;\n\n // Inject xAI's defaults — `baseURL` → the xAI OpenAI-compatible\n // endpoint, `provider` → \"xai\" — while still letting the caller\n // override either (e.g. a corporate proxy or a relabeled gateway).\n this.openai = new OpenAISDK({\n ...rest,\n baseURL: baseURL ?? XAI_BASE_URL,\n provider: provider ?? XAI_PROVIDER,\n });\n\n this.pricing = config.pricing;\n }\n\n /**\n * Build a `ModelContract` for a Grok model. Delegates to the wrapped\n * `OpenAISDK.model()` after injecting this provider's OWN capability\n * inference: `vision` and `reasoning` are resolved from xAI's\n * name-prefix lists (see `known-models.ts`) unless the caller set them\n * explicitly. Because explicit config wins over OpenAI's inference\n * inside `OpenAIModel`, the returned model self-identifies as\n * `provider: \"xai\"` and carries Grok's real capabilities even though\n * the model name isn't an OpenAI name.\n *\n * Pricing resolution is left to the wrapped adapter: per-model\n * `config.pricing` wins, otherwise the SDK-level registry entry keyed\n * by `config.name`, otherwise `undefined` (no cost computed).\n *\n * @example\n * xai.model({ name: \"grok-4\" }); // vision + reasoning auto-true\n * xai.model({ name: \"grok-3-mini\" }); // reasoning auto-true, vision false\n */\n public model(config: XaiModelConfig): ModelContract {\n return this.openai.model({\n ...config,\n // xAI names don't match OpenAI's vision/reasoning prefixes, so we\n // resolve them here and pass explicit flags through — explicit\n // config always wins over the OpenAI adapter's own inference.\n vision: config.vision ?? inferVisionCapability(config.name),\n reasoning: config.reasoning ?? inferReasoningCapability(config.name),\n });\n }\n\n /**\n * Rough token-count estimate. Delegates straight to the wrapped\n * `OpenAISDK.count()` (the shared character-heuristic from the core\n * package — offline, good for budgeting/quota guards, not billing).\n */\n public async count(text: string, model?: string): Promise<number> {\n return this.openai.count(text, model);\n }\n\n /**\n * Build an `EmbedderContract` by delegating to the wrapped\n * `OpenAISDK.embedder()`.\n *\n * NOTE: xAI does not currently expose a public embeddings endpoint, so\n * this is wired for protocol parity but a call to `embed()` /\n * `embedMany()` will fail upstream. Point an embedder at a dedicated\n * embeddings provider (e.g. `@warlock.js/ai-openai`) for vectors.\n */\n public embedder(config: XaiEmbedderConfig): EmbedderContract {\n return this.openai.embedder(config);\n }\n\n /**\n * Build an `ImageModelContract` by delegating to the wrapped\n * `OpenAISDK.image()` for use with `ai.image({ model, prompt })`.\n * Pricing resolution mirrors `model()` (per-model `pricing` > SDK\n * registry > `undefined`).\n */\n public image(config: XaiImageConfig): ImageModelContract {\n return this.openai.image(config);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,MAAa,4BAA4B,CAAC,UAAU,eAAe;;;;;;;;;;;AAYnE,MAAa,+BAA+B,CAAC,UAAU,aAAa;;;;;;;;;;AAWpE,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;;;AAcA,SAAgB,sBAAsB,SAA0B;CAC9D,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,0BAA0B,MAAM,WAAW,WAAW,WAAW,MAAM,CAAC;AACjF;;;;;;;;;;;;;AAcA,SAAgB,yBAAyB,SAA0B;CACjE,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,6BAA6B,MAAM,WAAW,WAAW,WAAW,MAAM,CAAC;AACpF;;;;;;;;;AC5EA,MAAM,eAAe;;;;;;AAOrB,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CrB,IAAa,SAAb,MAAkD;CAkBhD,AAAO,YAAY,QAAsB;EACvC,MAAM,EAAE,SAAS,UAAU,GAAG,SAAS;EAKvC,KAAK,SAAS,IAAIA,gCAAU;GAC1B,GAAG;GACH,SAAS,WAAW;GACpB,UAAU,YAAY;EACxB,CAAC;EAED,KAAK,UAAU,OAAO;CACxB;;;;;;;;;;;;;;;;;;;CAoBA,AAAO,MAAM,QAAuC;EAClD,OAAO,KAAK,OAAO,MAAM;GACvB,GAAG;GAIH,QAAQ,OAAO,UAAU,sBAAsB,OAAO,IAAI;GAC1D,WAAW,OAAO,aAAa,yBAAyB,OAAO,IAAI;EACrE,CAAC;CACH;;;;;;CAOA,MAAa,MAAM,MAAc,OAAiC;EAChE,OAAO,KAAK,OAAO,MAAM,MAAM,KAAK;CACtC;;;;;;;;;;CAWA,AAAO,SAAS,QAA6C;EAC3D,OAAO,KAAK,OAAO,SAAS,MAAM;CACpC;;;;;;;CAQA,AAAO,MAAM,QAA4C;EACvD,OAAO,KAAK,OAAO,MAAM,MAAM;CACjC;AACF"}
@@ -1,7 +1,7 @@
1
1
  import { OpenAISDKConfig } from "@warlock.js/ai-openai";
2
2
  import { EmbedderConfig, ImageModelConfig, ModelConfig } from "@warlock.js/ai";
3
3
 
4
- //#region ../ai-xai/src/config.type.d.ts
4
+ //#region ../../packages/ai-xai/src/config.type.d.ts
5
5
  /**
6
6
  * Configuration for the xAI Grok SDK adapter.
7
7
  *
@@ -1 +1 @@
1
- {"version":3,"file":"config.type.d.mts","names":[],"sources":["../../../../../../ai-xai/src/config.type.ts"],"mappings":";;;;;;AAwCA;;;;AAA0C;AAkB1C;;;;;;;;;AAyBkB;AAelB;;;;AAA8C;AAa9C;;;;AAA6C;;;;;;KAvEjC,YAAA,GAAe,eAAe;;;;;;;;;;;;;;;;;KAkB9B,cAAA,GAAiB,WAAW;;;;;;;;EAQtC,MAAA;;;;;;;;;EASA,SAAA;;;;;;;;EAQA,gBAAA;AAAA;;;;;;;;;;;;;KAeU,iBAAA,GAAoB,cAAc;;;;;;;;;;;;KAalC,cAAA,GAAiB,gBAAgB"}
1
+ {"version":3,"file":"config.type.d.mts","names":[],"sources":["../../../../../../../packages/ai-xai/src/config.type.ts"],"mappings":";;;;;;AAwCA;;;;AAA0C;AAkB1C;;;;;;;;;AAyBkB;AAelB;;;;AAA8C;AAa9C;;;;AAA6C;;;;;;KAvEjC,YAAA,GAAe,eAAe;;;;;;;;;;;;;;;;;KAkB9B,cAAA,GAAiB,WAAW;;;;;;;;EAQtC,MAAA;;;;;;;;;EASA,SAAA;;;;;;;;EAQA,gBAAA;AAAA;;;;;;;;;;;;;KAeU,iBAAA,GAAoB,cAAc;;;;;;;;;;;;KAalC,cAAA,GAAiB,gBAAgB"}
@@ -1,4 +1,4 @@
1
- //#region ../ai-xai/src/known-models.d.ts
1
+ //#region ../../packages/ai-xai/src/known-models.d.ts
2
2
  /**
3
3
  * Capability inference for xAI Grok model ids.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"known-models.d.mts","names":[],"sources":["../../../../../../ai-xai/src/known-models.ts"],"mappings":";;AAgCA;;;;AAA6E;AAY7E;;;;AAA8E;AAW9E;;;;AAMU;AAcV;;;;AAAqD;AAkBrD;;;;AAAwD;;;;;;cA7D3C,yBAAA;;;;;;;;;;;cAYA,4BAAA;;;;;;;;;;cAWA,eAAA;;;;;;;;;;;;;iBAoBG,qBAAA,CAAsB,OAAe;;;;;;;;;;;;;iBAkBrC,wBAAA,CAAyB,OAAe"}
1
+ {"version":3,"file":"known-models.d.mts","names":[],"sources":["../../../../../../../packages/ai-xai/src/known-models.ts"],"mappings":";;AAgCA;;;;AAA6E;AAY7E;;;;AAA8E;AAW9E;;;;AAMU;AAcV;;;;AAAqD;AAkBrD;;;;AAAwD;;;;;;cA7D3C,yBAAA;;;;;;;;;;;cAYA,4BAAA;;;;;;;;;;cAWA,eAAA;;;;;;;;;;;;;iBAoBG,qBAAA,CAAsB,OAAe;;;;;;;;;;;;;iBAkBrC,wBAAA,CAAyB,OAAe"}
@@ -1,4 +1,4 @@
1
- //#region ../ai-xai/src/known-models.ts
1
+ //#region ../../packages/ai-xai/src/known-models.ts
2
2
  /**
3
3
  * Capability inference for xAI Grok model ids.
4
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"known-models.mjs","names":[],"sources":["../../../../../../ai-xai/src/known-models.ts"],"sourcesContent":["/**\n * Capability inference for xAI Grok model ids.\n *\n * xAI speaks the OpenAI Chat Completions protocol, so the wire-level\n * adapter is `OpenAISDK`. But Grok model names (`grok-4`,\n * `grok-2-vision`, …) don't match OpenAI's `gpt-*` / `o*` prefixes, so\n * OpenAI's own inference lists would mis-classify every Grok model as\n * non-vision / non-reasoning. This module supplies xAI's OWN name lists\n * and the `XaiSDK` wrapper injects the resulting capability flags into\n * each `OpenAIModelConfig` before delegating, so the right capabilities\n * are set even though the names aren't OpenAI names.\n *\n * All lists are matched as a prefix so dated / `-latest` / `-fast`\n * variants (`grok-4-0709`, `grok-2-vision-latest`,\n * `grok-3-mini-beta`) are covered without enumerating every release\n * tag. Devs can always override per-model via\n * `xai.model({ name, vision: true | false, reasoning: true | false })`\n * — explicit config wins over inference in either direction.\n */\n\n/**\n * Model-name prefixes for Grok families that accept image input\n * (vision) on the OpenAI-compatible Chat Completions endpoint.\n *\n * - `grok-4` is natively multimodal (text + image input).\n * - `grok-2-vision` is the dedicated image-understanding Grok 2 model.\n *\n * Text-only families (`grok-3`, `grok-3-mini`, the base `grok-2`\n * text model) are intentionally excluded so passing an image\n * attachment to them surfaces a clear, agent-side capability error\n * rather than an opaque xAI 400.\n */\nexport const XAI_VISION_MODEL_PREFIXES = [\"grok-4\", \"grok-2-vision\"] as const;\n\n/**\n * Model-name prefixes for Grok families that expose internal reasoning\n * and accept reasoning controls (e.g. `reasoning_effort`) on the\n * OpenAI-compatible Chat Completions endpoint.\n *\n * - `grok-4` is a reasoning-first model (it always reasons).\n * - `grok-3-mini` is the \"think\" variant of Grok 3 and reasons; the\n * full-size `grok-3` does not, so it is deliberately NOT covered by\n * the `grok-3-mini` prefix.\n */\nexport const XAI_REASONING_MODEL_PREFIXES = [\"grok-4\", \"grok-3-mini\"] as const;\n\n/**\n * A convenience list of the current public Grok chat model ids, handy\n * for menus, validation, and docs. Not exhaustive of every dated alias\n * xAI publishes — pass any id through `xai.model({ name })`; the prefix\n * inference above handles dated / `-latest` variants.\n *\n * @example\n * XAI_CHAT_MODELS.includes(\"grok-4\"); // → true\n */\nexport const XAI_CHAT_MODELS = [\n \"grok-4\",\n \"grok-3\",\n \"grok-3-mini\",\n \"grok-2-vision\",\n \"grok-2\",\n] as const;\n\n/**\n * Infer whether a given Grok model id supports vision based on xAI's\n * known-prefix list. Unknown ids default to `false` so that passing an\n * image attachment to an unsupported model surfaces a clear,\n * agent-side capability error instead of an opaque xAI 400.\n *\n * @example\n * inferVisionCapability(\"grok-4\"); // → true\n * inferVisionCapability(\"grok-2-vision-latest\"); // → true\n * inferVisionCapability(\"grok-3\"); // → false\n * inferVisionCapability(\"grok-3-mini\"); // → false\n */\nexport function inferVisionCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return XAI_VISION_MODEL_PREFIXES.some((prefix) => normalized.startsWith(prefix));\n}\n\n/**\n * Infer whether a given Grok model id is a reasoning model based on\n * xAI's known-prefix list. Unknown ids default to `false` so the\n * adapter never forwards an unsupported reasoning param to a\n * non-reasoning model.\n *\n * @example\n * inferReasoningCapability(\"grok-4\"); // → true\n * inferReasoningCapability(\"grok-3-mini\"); // → true\n * inferReasoningCapability(\"grok-3\"); // → false\n * inferReasoningCapability(\"grok-2-vision\"); // → false\n */\nexport function inferReasoningCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return XAI_REASONING_MODEL_PREFIXES.some((prefix) => normalized.startsWith(prefix));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,MAAa,4BAA4B,CAAC,UAAU,eAAe;;;;;;;;;;;AAYnE,MAAa,+BAA+B,CAAC,UAAU,aAAa;;;;;;;;;;AAWpE,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;;;AAcA,SAAgB,sBAAsB,SAA0B;CAC9D,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,0BAA0B,MAAM,WAAW,WAAW,WAAW,MAAM,CAAC;AACjF;;;;;;;;;;;;;AAcA,SAAgB,yBAAyB,SAA0B;CACjE,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,6BAA6B,MAAM,WAAW,WAAW,WAAW,MAAM,CAAC;AACpF"}
1
+ {"version":3,"file":"known-models.mjs","names":[],"sources":["../../../../../../../packages/ai-xai/src/known-models.ts"],"sourcesContent":["/**\n * Capability inference for xAI Grok model ids.\n *\n * xAI speaks the OpenAI Chat Completions protocol, so the wire-level\n * adapter is `OpenAISDK`. But Grok model names (`grok-4`,\n * `grok-2-vision`, …) don't match OpenAI's `gpt-*` / `o*` prefixes, so\n * OpenAI's own inference lists would mis-classify every Grok model as\n * non-vision / non-reasoning. This module supplies xAI's OWN name lists\n * and the `XaiSDK` wrapper injects the resulting capability flags into\n * each `OpenAIModelConfig` before delegating, so the right capabilities\n * are set even though the names aren't OpenAI names.\n *\n * All lists are matched as a prefix so dated / `-latest` / `-fast`\n * variants (`grok-4-0709`, `grok-2-vision-latest`,\n * `grok-3-mini-beta`) are covered without enumerating every release\n * tag. Devs can always override per-model via\n * `xai.model({ name, vision: true | false, reasoning: true | false })`\n * — explicit config wins over inference in either direction.\n */\n\n/**\n * Model-name prefixes for Grok families that accept image input\n * (vision) on the OpenAI-compatible Chat Completions endpoint.\n *\n * - `grok-4` is natively multimodal (text + image input).\n * - `grok-2-vision` is the dedicated image-understanding Grok 2 model.\n *\n * Text-only families (`grok-3`, `grok-3-mini`, the base `grok-2`\n * text model) are intentionally excluded so passing an image\n * attachment to them surfaces a clear, agent-side capability error\n * rather than an opaque xAI 400.\n */\nexport const XAI_VISION_MODEL_PREFIXES = [\"grok-4\", \"grok-2-vision\"] as const;\n\n/**\n * Model-name prefixes for Grok families that expose internal reasoning\n * and accept reasoning controls (e.g. `reasoning_effort`) on the\n * OpenAI-compatible Chat Completions endpoint.\n *\n * - `grok-4` is a reasoning-first model (it always reasons).\n * - `grok-3-mini` is the \"think\" variant of Grok 3 and reasons; the\n * full-size `grok-3` does not, so it is deliberately NOT covered by\n * the `grok-3-mini` prefix.\n */\nexport const XAI_REASONING_MODEL_PREFIXES = [\"grok-4\", \"grok-3-mini\"] as const;\n\n/**\n * A convenience list of the current public Grok chat model ids, handy\n * for menus, validation, and docs. Not exhaustive of every dated alias\n * xAI publishes — pass any id through `xai.model({ name })`; the prefix\n * inference above handles dated / `-latest` variants.\n *\n * @example\n * XAI_CHAT_MODELS.includes(\"grok-4\"); // → true\n */\nexport const XAI_CHAT_MODELS = [\n \"grok-4\",\n \"grok-3\",\n \"grok-3-mini\",\n \"grok-2-vision\",\n \"grok-2\",\n] as const;\n\n/**\n * Infer whether a given Grok model id supports vision based on xAI's\n * known-prefix list. Unknown ids default to `false` so that passing an\n * image attachment to an unsupported model surfaces a clear,\n * agent-side capability error instead of an opaque xAI 400.\n *\n * @example\n * inferVisionCapability(\"grok-4\"); // → true\n * inferVisionCapability(\"grok-2-vision-latest\"); // → true\n * inferVisionCapability(\"grok-3\"); // → false\n * inferVisionCapability(\"grok-3-mini\"); // → false\n */\nexport function inferVisionCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return XAI_VISION_MODEL_PREFIXES.some((prefix) => normalized.startsWith(prefix));\n}\n\n/**\n * Infer whether a given Grok model id is a reasoning model based on\n * xAI's known-prefix list. Unknown ids default to `false` so the\n * adapter never forwards an unsupported reasoning param to a\n * non-reasoning model.\n *\n * @example\n * inferReasoningCapability(\"grok-4\"); // → true\n * inferReasoningCapability(\"grok-3-mini\"); // → true\n * inferReasoningCapability(\"grok-3\"); // → false\n * inferReasoningCapability(\"grok-2-vision\"); // → false\n */\nexport function inferReasoningCapability(modelId: string): boolean {\n const normalized = modelId.toLowerCase();\n\n return XAI_REASONING_MODEL_PREFIXES.some((prefix) => normalized.startsWith(prefix));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,MAAa,4BAA4B,CAAC,UAAU,eAAe;;;;;;;;;;;AAYnE,MAAa,+BAA+B,CAAC,UAAU,aAAa;;;;;;;;;;AAWpE,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;AACF;;;;;;;;;;;;;AAcA,SAAgB,sBAAsB,SAA0B;CAC9D,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,0BAA0B,MAAM,WAAW,WAAW,WAAW,MAAM,CAAC;AACjF;;;;;;;;;;;;;AAcA,SAAgB,yBAAyB,SAA0B;CACjE,MAAM,aAAa,QAAQ,YAAY;CAEvC,OAAO,6BAA6B,MAAM,WAAW,WAAW,WAAW,MAAM,CAAC;AACpF"}
package/esm/sdk.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { XaiEmbedderConfig, XaiImageConfig, XaiModelConfig, XaiSDKConfig } from "./config.type.mjs";
2
2
  import { EmbedderContract, ImageModelContract, ModelContract, SDKAdapterContract } from "@warlock.js/ai";
3
3
 
4
- //#region ../ai-xai/src/sdk.d.ts
4
+ //#region ../../packages/ai-xai/src/sdk.d.ts
5
5
  /**
6
6
  * xAI Grok-backed implementation of `SDKAdapterContract`.
7
7
  *
package/esm/sdk.d.mts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.mts","names":[],"sources":["../../../../../../ai-xai/src/sdk.ts"],"mappings":";;;;;;AAuEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0F0D;;cA1F7C,MAAA,YAAkB,kBAAA;;;;;;;mBAOZ,MAAA;;;;;;;;mBASA,OAAA;cAEE,MAAA,EAAQ,YAAA;;;;;;;;;;;;;;;;;;;EAiCpB,KAAA,CAAM,MAAA,EAAQ,cAAA,GAAiB,aAAA;;;;;;EAgBzB,KAAA,CAAM,IAAA,UAAc,KAAA,YAAiB,OAAA;;;;;;;;;;EAa3C,QAAA,CAAS,MAAA,EAAQ,iBAAA,GAAoB,gBAAA;;;;;;;EAUrC,KAAA,CAAM,MAAA,EAAQ,cAAA,GAAiB,kBAAA;AAAA"}
1
+ {"version":3,"file":"sdk.d.mts","names":[],"sources":["../../../../../../../packages/ai-xai/src/sdk.ts"],"mappings":";;;;;;AAuEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0F0D;;cA1F7C,MAAA,YAAkB,kBAAA;;;;;;;mBAOZ,MAAA;;;;;;;;mBASA,OAAA;cAEE,MAAA,EAAQ,YAAA;;;;;;;;;;;;;;;;;;;EAiCpB,KAAA,CAAM,MAAA,EAAQ,cAAA,GAAiB,aAAA;;;;;;EAgBzB,KAAA,CAAM,IAAA,UAAc,KAAA,YAAiB,OAAA;;;;;;;;;;EAa3C,QAAA,CAAS,MAAA,EAAQ,iBAAA,GAAoB,gBAAA;;;;;;;EAUrC,KAAA,CAAM,MAAA,EAAQ,cAAA,GAAiB,kBAAA;AAAA"}
package/esm/sdk.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { inferReasoningCapability, inferVisionCapability } from "./known-models.mjs";
2
2
  import { OpenAISDK } from "@warlock.js/ai-openai";
3
3
 
4
- //#region ../ai-xai/src/sdk.ts
4
+ //#region ../../packages/ai-xai/src/sdk.ts
5
5
  /**
6
6
  * The xAI OpenAI-compatible base URL. xAI exposes Chat Completions at
7
7
  * `POST /v1/chat/completions` on this host, so the whole adapter rides
package/esm/sdk.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.mjs","names":[],"sources":["../../../../../../ai-xai/src/sdk.ts"],"sourcesContent":["import type {\n EmbedderContract,\n ImageModelContract,\n ModelContract,\n ModelPricing,\n SDKAdapterContract,\n} from \"@warlock.js/ai\";\nimport { OpenAISDK } from \"@warlock.js/ai-openai\";\nimport type {\n XaiEmbedderConfig,\n XaiImageConfig,\n XaiModelConfig,\n XaiSDKConfig,\n} from \"./config.type\";\nimport { inferReasoningCapability, inferVisionCapability } from \"./known-models\";\n\n/**\n * The xAI OpenAI-compatible base URL. xAI exposes Chat Completions at\n * `POST /v1/chat/completions` on this host, so the whole adapter rides\n * on the OpenAI wire protocol.\n */\nconst XAI_BASE_URL = \"https://api.x.ai/v1\";\n\n/**\n * The default `provider` label stamped on every model this SDK\n * produces. Surfaces on `ModelContract.provider`, `AgentReport.model`,\n * logs, and any provider-aware middleware.\n */\nconst XAI_PROVIDER = \"xai\";\n\n/**\n * xAI Grok-backed implementation of `SDKAdapterContract`.\n *\n * **Role.** The package entry point for xAI's Grok models. xAI speaks\n * the OpenAI Chat Completions protocol, so `XaiSDK` is a *thin wrapper*\n * over the already-battle-tested {@link OpenAISDK} from\n * `@warlock.js/ai-openai` — NOT a reimplementation. It constructs one\n * internal `OpenAISDK` pointed at xAI's `baseURL` and labeled\n * `provider: \"xai\"`, then delegates `model()` / `embedder()` /\n * `image()` / `count()` to it. Construct one SDK per account and reuse\n * it everywhere.\n *\n * **Responsibility.**\n * - Owns: the xAI defaults (`baseURL` → `https://api.x.ai/v1`,\n * `provider` → `\"xai\"`) and this provider's OWN capability inference.\n * Grok model names (`grok-4`, `grok-2-vision`, …) don't match\n * OpenAI's `gpt-*` / `o*` prefixes, so before delegating `model()`\n * the wrapper injects the `vision` / `reasoning` flags inferred from\n * xAI's name lists (see `known-models.ts`). Because explicit config\n * wins over OpenAI's inference inside `OpenAIModel`, the produced\n * `ModelContract` carries the correct Grok capabilities.\n * - Does NOT own: the wire protocol, request/response mapping,\n * streaming, tool-call accumulation, error wrapping, or pricing\n * resolution — all of that is the wrapped `OpenAISDK`'s job and is\n * reused verbatim.\n *\n * Modeled as a class (see §4.2 of code-style.md — \"long-lived state\n * across many calls\"): it holds one live `OpenAISDK` (which in turn\n * holds one live `OpenAI` client), fronted by FP usage like the other\n * adapters.\n *\n * @example\n * const xai = new XaiSDK({ apiKey: process.env.XAI_API_KEY! });\n * const model = xai.model({ name: \"grok-4\", temperature: 0.7 });\n * const myAgent = ai.agent({ model });\n *\n * @example\n * // Compose into an `ai.xai` namespace for ergonomic agent wiring.\n * const ai = { agent, tool, systemPrompt, xai: new XaiSDK({ apiKey }) };\n * const fast = ai.agent({ model: ai.xai.model({ name: \"grok-3-mini\" }) });\n */\nexport class XaiSDK implements SDKAdapterContract {\n /**\n * The wrapped OpenAI-compatible adapter doing the actual wire work.\n * Constructed once with xAI's `baseURL` + `provider` and the caller's\n * `apiKey` / client options, then reused for every produced model,\n * embedder, and image model.\n */\n private readonly openai: OpenAISDK;\n\n /**\n * Optional SDK-level pricing registry, kept so `model()` can resolve\n * a per-model entry while still applying this provider's default\n * capability inference. The wrapped `OpenAISDK` also resolves\n * pricing, but we surface it here for parity and to keep the default\n * baseURL/provider injection in one place.\n */\n private readonly pricing?: Record<string, ModelPricing>;\n\n public constructor(config: XaiSDKConfig) {\n const { baseURL, provider, ...rest } = config;\n\n // Inject xAI's defaults — `baseURL` → the xAI OpenAI-compatible\n // endpoint, `provider` → \"xai\" — while still letting the caller\n // override either (e.g. a corporate proxy or a relabeled gateway).\n this.openai = new OpenAISDK({\n ...rest,\n baseURL: baseURL ?? XAI_BASE_URL,\n provider: provider ?? XAI_PROVIDER,\n });\n\n this.pricing = config.pricing;\n }\n\n /**\n * Build a `ModelContract` for a Grok model. Delegates to the wrapped\n * `OpenAISDK.model()` after injecting this provider's OWN capability\n * inference: `vision` and `reasoning` are resolved from xAI's\n * name-prefix lists (see `known-models.ts`) unless the caller set them\n * explicitly. Because explicit config wins over OpenAI's inference\n * inside `OpenAIModel`, the returned model self-identifies as\n * `provider: \"xai\"` and carries Grok's real capabilities even though\n * the model name isn't an OpenAI name.\n *\n * Pricing resolution is left to the wrapped adapter: per-model\n * `config.pricing` wins, otherwise the SDK-level registry entry keyed\n * by `config.name`, otherwise `undefined` (no cost computed).\n *\n * @example\n * xai.model({ name: \"grok-4\" }); // vision + reasoning auto-true\n * xai.model({ name: \"grok-3-mini\" }); // reasoning auto-true, vision false\n */\n public model(config: XaiModelConfig): ModelContract {\n return this.openai.model({\n ...config,\n // xAI names don't match OpenAI's vision/reasoning prefixes, so we\n // resolve them here and pass explicit flags through — explicit\n // config always wins over the OpenAI adapter's own inference.\n vision: config.vision ?? inferVisionCapability(config.name),\n reasoning: config.reasoning ?? inferReasoningCapability(config.name),\n });\n }\n\n /**\n * Rough token-count estimate. Delegates straight to the wrapped\n * `OpenAISDK.count()` (the shared character-heuristic from the core\n * package — offline, good for budgeting/quota guards, not billing).\n */\n public async count(text: string, model?: string): Promise<number> {\n return this.openai.count(text, model);\n }\n\n /**\n * Build an `EmbedderContract` by delegating to the wrapped\n * `OpenAISDK.embedder()`.\n *\n * NOTE: xAI does not currently expose a public embeddings endpoint, so\n * this is wired for protocol parity but a call to `embed()` /\n * `embedMany()` will fail upstream. Point an embedder at a dedicated\n * embeddings provider (e.g. `@warlock.js/ai-openai`) for vectors.\n */\n public embedder(config: XaiEmbedderConfig): EmbedderContract {\n return this.openai.embedder(config);\n }\n\n /**\n * Build an `ImageModelContract` by delegating to the wrapped\n * `OpenAISDK.image()` for use with `ai.image({ model, prompt })`.\n * Pricing resolution mirrors `model()` (per-model `pricing` > SDK\n * registry > `undefined`).\n */\n public image(config: XaiImageConfig): ImageModelContract {\n return this.openai.image(config);\n }\n}\n"],"mappings":";;;;;;;;;AAqBA,MAAM,eAAe;;;;;;AAOrB,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CrB,IAAa,SAAb,MAAkD;CAkBhD,AAAO,YAAY,QAAsB;EACvC,MAAM,EAAE,SAAS,UAAU,GAAG,SAAS;EAKvC,KAAK,SAAS,IAAI,UAAU;GAC1B,GAAG;GACH,SAAS,WAAW;GACpB,UAAU,YAAY;EACxB,CAAC;EAED,KAAK,UAAU,OAAO;CACxB;;;;;;;;;;;;;;;;;;;CAoBA,AAAO,MAAM,QAAuC;EAClD,OAAO,KAAK,OAAO,MAAM;GACvB,GAAG;GAIH,QAAQ,OAAO,UAAU,sBAAsB,OAAO,IAAI;GAC1D,WAAW,OAAO,aAAa,yBAAyB,OAAO,IAAI;EACrE,CAAC;CACH;;;;;;CAOA,MAAa,MAAM,MAAc,OAAiC;EAChE,OAAO,KAAK,OAAO,MAAM,MAAM,KAAK;CACtC;;;;;;;;;;CAWA,AAAO,SAAS,QAA6C;EAC3D,OAAO,KAAK,OAAO,SAAS,MAAM;CACpC;;;;;;;CAQA,AAAO,MAAM,QAA4C;EACvD,OAAO,KAAK,OAAO,MAAM,MAAM;CACjC;AACF"}
1
+ {"version":3,"file":"sdk.mjs","names":[],"sources":["../../../../../../../packages/ai-xai/src/sdk.ts"],"sourcesContent":["import type {\n EmbedderContract,\n ImageModelContract,\n ModelContract,\n ModelPricing,\n SDKAdapterContract,\n} from \"@warlock.js/ai\";\nimport { OpenAISDK } from \"@warlock.js/ai-openai\";\nimport type {\n XaiEmbedderConfig,\n XaiImageConfig,\n XaiModelConfig,\n XaiSDKConfig,\n} from \"./config.type\";\nimport { inferReasoningCapability, inferVisionCapability } from \"./known-models\";\n\n/**\n * The xAI OpenAI-compatible base URL. xAI exposes Chat Completions at\n * `POST /v1/chat/completions` on this host, so the whole adapter rides\n * on the OpenAI wire protocol.\n */\nconst XAI_BASE_URL = \"https://api.x.ai/v1\";\n\n/**\n * The default `provider` label stamped on every model this SDK\n * produces. Surfaces on `ModelContract.provider`, `AgentReport.model`,\n * logs, and any provider-aware middleware.\n */\nconst XAI_PROVIDER = \"xai\";\n\n/**\n * xAI Grok-backed implementation of `SDKAdapterContract`.\n *\n * **Role.** The package entry point for xAI's Grok models. xAI speaks\n * the OpenAI Chat Completions protocol, so `XaiSDK` is a *thin wrapper*\n * over the already-battle-tested {@link OpenAISDK} from\n * `@warlock.js/ai-openai` — NOT a reimplementation. It constructs one\n * internal `OpenAISDK` pointed at xAI's `baseURL` and labeled\n * `provider: \"xai\"`, then delegates `model()` / `embedder()` /\n * `image()` / `count()` to it. Construct one SDK per account and reuse\n * it everywhere.\n *\n * **Responsibility.**\n * - Owns: the xAI defaults (`baseURL` → `https://api.x.ai/v1`,\n * `provider` → `\"xai\"`) and this provider's OWN capability inference.\n * Grok model names (`grok-4`, `grok-2-vision`, …) don't match\n * OpenAI's `gpt-*` / `o*` prefixes, so before delegating `model()`\n * the wrapper injects the `vision` / `reasoning` flags inferred from\n * xAI's name lists (see `known-models.ts`). Because explicit config\n * wins over OpenAI's inference inside `OpenAIModel`, the produced\n * `ModelContract` carries the correct Grok capabilities.\n * - Does NOT own: the wire protocol, request/response mapping,\n * streaming, tool-call accumulation, error wrapping, or pricing\n * resolution — all of that is the wrapped `OpenAISDK`'s job and is\n * reused verbatim.\n *\n * Modeled as a class (see §4.2 of code-style.md — \"long-lived state\n * across many calls\"): it holds one live `OpenAISDK` (which in turn\n * holds one live `OpenAI` client), fronted by FP usage like the other\n * adapters.\n *\n * @example\n * const xai = new XaiSDK({ apiKey: process.env.XAI_API_KEY! });\n * const model = xai.model({ name: \"grok-4\", temperature: 0.7 });\n * const myAgent = ai.agent({ model });\n *\n * @example\n * // Compose into an `ai.xai` namespace for ergonomic agent wiring.\n * const ai = { agent, tool, systemPrompt, xai: new XaiSDK({ apiKey }) };\n * const fast = ai.agent({ model: ai.xai.model({ name: \"grok-3-mini\" }) });\n */\nexport class XaiSDK implements SDKAdapterContract {\n /**\n * The wrapped OpenAI-compatible adapter doing the actual wire work.\n * Constructed once with xAI's `baseURL` + `provider` and the caller's\n * `apiKey` / client options, then reused for every produced model,\n * embedder, and image model.\n */\n private readonly openai: OpenAISDK;\n\n /**\n * Optional SDK-level pricing registry, kept so `model()` can resolve\n * a per-model entry while still applying this provider's default\n * capability inference. The wrapped `OpenAISDK` also resolves\n * pricing, but we surface it here for parity and to keep the default\n * baseURL/provider injection in one place.\n */\n private readonly pricing?: Record<string, ModelPricing>;\n\n public constructor(config: XaiSDKConfig) {\n const { baseURL, provider, ...rest } = config;\n\n // Inject xAI's defaults — `baseURL` → the xAI OpenAI-compatible\n // endpoint, `provider` → \"xai\" — while still letting the caller\n // override either (e.g. a corporate proxy or a relabeled gateway).\n this.openai = new OpenAISDK({\n ...rest,\n baseURL: baseURL ?? XAI_BASE_URL,\n provider: provider ?? XAI_PROVIDER,\n });\n\n this.pricing = config.pricing;\n }\n\n /**\n * Build a `ModelContract` for a Grok model. Delegates to the wrapped\n * `OpenAISDK.model()` after injecting this provider's OWN capability\n * inference: `vision` and `reasoning` are resolved from xAI's\n * name-prefix lists (see `known-models.ts`) unless the caller set them\n * explicitly. Because explicit config wins over OpenAI's inference\n * inside `OpenAIModel`, the returned model self-identifies as\n * `provider: \"xai\"` and carries Grok's real capabilities even though\n * the model name isn't an OpenAI name.\n *\n * Pricing resolution is left to the wrapped adapter: per-model\n * `config.pricing` wins, otherwise the SDK-level registry entry keyed\n * by `config.name`, otherwise `undefined` (no cost computed).\n *\n * @example\n * xai.model({ name: \"grok-4\" }); // vision + reasoning auto-true\n * xai.model({ name: \"grok-3-mini\" }); // reasoning auto-true, vision false\n */\n public model(config: XaiModelConfig): ModelContract {\n return this.openai.model({\n ...config,\n // xAI names don't match OpenAI's vision/reasoning prefixes, so we\n // resolve them here and pass explicit flags through — explicit\n // config always wins over the OpenAI adapter's own inference.\n vision: config.vision ?? inferVisionCapability(config.name),\n reasoning: config.reasoning ?? inferReasoningCapability(config.name),\n });\n }\n\n /**\n * Rough token-count estimate. Delegates straight to the wrapped\n * `OpenAISDK.count()` (the shared character-heuristic from the core\n * package — offline, good for budgeting/quota guards, not billing).\n */\n public async count(text: string, model?: string): Promise<number> {\n return this.openai.count(text, model);\n }\n\n /**\n * Build an `EmbedderContract` by delegating to the wrapped\n * `OpenAISDK.embedder()`.\n *\n * NOTE: xAI does not currently expose a public embeddings endpoint, so\n * this is wired for protocol parity but a call to `embed()` /\n * `embedMany()` will fail upstream. Point an embedder at a dedicated\n * embeddings provider (e.g. `@warlock.js/ai-openai`) for vectors.\n */\n public embedder(config: XaiEmbedderConfig): EmbedderContract {\n return this.openai.embedder(config);\n }\n\n /**\n * Build an `ImageModelContract` by delegating to the wrapped\n * `OpenAISDK.image()` for use with `ai.image({ model, prompt })`.\n * Pricing resolution mirrors `model()` (per-model `pricing` > SDK\n * registry > `undefined`).\n */\n public image(config: XaiImageConfig): ImageModelContract {\n return this.openai.image(config);\n }\n}\n"],"mappings":";;;;;;;;;AAqBA,MAAM,eAAe;;;;;;AAOrB,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CrB,IAAa,SAAb,MAAkD;CAkBhD,AAAO,YAAY,QAAsB;EACvC,MAAM,EAAE,SAAS,UAAU,GAAG,SAAS;EAKvC,KAAK,SAAS,IAAI,UAAU;GAC1B,GAAG;GACH,SAAS,WAAW;GACpB,UAAU,YAAY;EACxB,CAAC;EAED,KAAK,UAAU,OAAO;CACxB;;;;;;;;;;;;;;;;;;;CAoBA,AAAO,MAAM,QAAuC;EAClD,OAAO,KAAK,OAAO,MAAM;GACvB,GAAG;GAIH,QAAQ,OAAO,UAAU,sBAAsB,OAAO,IAAI;GAC1D,WAAW,OAAO,aAAa,yBAAyB,OAAO,IAAI;EACrE,CAAC;CACH;;;;;;CAOA,MAAa,MAAM,MAAc,OAAiC;EAChE,OAAO,KAAK,OAAO,MAAM,MAAM,KAAK;CACtC;;;;;;;;;;CAWA,AAAO,SAAS,QAA6C;EAC3D,OAAO,KAAK,OAAO,SAAS,MAAM;CACpC;;;;;;;CAQA,AAAO,MAAM,QAA4C;EACvD,OAAO,KAAK,OAAO,MAAM,MAAM;CACjC;AACF"}
package/llms-full.txt CHANGED
@@ -8,12 +8,12 @@
8
8
 
9
9
  ---
10
10
  name: setup-xai
11
- description: 'Wire @warlock.js/ai-xai — new XaiSDK({apiKey, baseURL?, provider?, pricing?}) for xAI Grok, .model({name, vision?, reasoning?, structuredOutput?}) for a ModelContract, .embedder({name, dimensions?}) and .image({name, pricing?}) delegated to the OpenAI-compatible adapter. Thin wrapper over OpenAISDK: uses the xAI OpenAI-compatible endpoint (https://api.x.ai/v1) and injects xAI''s own vision/reasoning inference so Grok names resolve to the right capabilities. Triggers: `XaiSDK`, `grok`, `grok-4`, `grok-3`, `grok-3-mini`, `grok-2-vision`, `.model`, `x.ai`, `api.x.ai`, `XAI_API_KEY`, `reasoning_effort` on Grok, "wire xai/grok into a warlock agent", "configure grok-4", "use grok reasoning effort", "send an image to grok-4 / grok-2-vision"; typical import `import { XaiSDK } from "@warlock.js/ai-xai"`. Skip: agent wiring — `@warlock.js/ai/run-ai-agent/SKILL.md`; the underlying OpenAI-compatible adapter and its full capability/streaming/error surface — `@warlock.js/ai-openai/skills/setup-openai/SKILL.md`; adapter comparison — `@warlock.js/ai/pick-ai-provider/SKILL.md`; competing adapters `@warlock.js/ai-anthropic`, `@warlock.js/ai-google`, `@warlock.js/ai-ollama`; raw `openai` SDK pointed at x.ai by hand.'
11
+ description: 'Wire @warlock.js/ai-xai — new XaiSDK({apiKey, baseURL?, provider?, pricing?}) for xAI Grok, .model({name, vision?, reasoning?, structuredOutput?}) for a ModelContract, .embedder({name, dimensions?}) and .image({name, pricing?}) delegated to the OpenAI-compatible adapter. Thin wrapper over OpenAISDK: uses the xAI OpenAI-compatible endpoint (https://api.x.ai/v1) and injects xAI''s own vision/reasoning inference so Grok names resolve to the right capabilities. Triggers: `XaiSDK`, `grok`, `grok-4`, `grok-3`, `grok-3-mini`, `grok-2-vision`, `.model`, `x.ai`, `api.x.ai`, `XAI_API_KEY`, `reasoning_effort` on Grok, "wire xai/grok into a warlock agent", "configure grok-4", "use grok reasoning effort", "send an image to grok-4 / grok-2-vision"; typical import `import { XaiSDK } from "@warlock.js/ai-xai"`. Skip: agent wiring — the `run-ai-agent` topic of the `warlock-js-ai` skill; the underlying OpenAI-compatible adapter and its full capability/streaming/error surface — the `setup-openai` topic of the `warlock-js-ai-openai` skill; adapter comparison — the `pick-ai-provider` topic of the `warlock-js-ai` skill; competing adapters `@warlock.js/ai-anthropic`, `@warlock.js/ai-google`, `@warlock.js/ai-ollama`; raw `openai` SDK pointed at x.ai by hand.'
12
12
  ---
13
13
 
14
14
  # `@warlock.js/ai-xai`
15
15
 
16
- Provider adapter for xAI's **Grok** models. xAI speaks the OpenAI Chat Completions protocol, so `XaiSDK` is a **thin wrapper** over [`OpenAISDK`](../../../ai-openai/skills/setup-openai/SKILL.md) — it does not reimplement the wire layer. It constructs one internal `OpenAISDK` pointed at xAI's `baseURL` and labeled `provider: "xai"`, then delegates `model()` / `embedder()` / `image()` / `count()`, injecting xAI's own capability inference so Grok model names resolve correctly. Pair with `@warlock.js/ai` for the agent / tool / system-prompt surface.
16
+ Provider adapter for xAI's **Grok** models. xAI speaks the OpenAI Chat Completions protocol, so `XaiSDK` is a **thin wrapper** over `OpenAISDK` (the `setup-openai` topic of the `warlock-js-ai-openai` skill) — it does not reimplement the wire layer. It constructs one internal `OpenAISDK` pointed at xAI's `baseURL` and labeled `provider: "xai"`, then delegates `model()` / `embedder()` / `image()` / `count()`, injecting xAI's own capability inference so Grok model names resolve correctly. Pair with `@warlock.js/ai` for the agent / tool / system-prompt surface.
17
17
 
18
18
  ## Construction
19
19
 
@@ -55,7 +55,7 @@ This adapter ships xAI's OWN name lists (Grok ids don't match OpenAI's `gpt-*` /
55
55
 
56
56
  - `vision` — inferred `true` for the `grok-4` and `grok-2-vision` prefixes; `false` otherwise.
57
57
  - `reasoning` — inferred `true` for `grok-4` and `grok-3-mini`; drives whether `reasoning.effort` is forwarded as `reasoning_effort` on the wire.
58
- - `structuredOutput` / `promptCaching` and the image/PDF/audio wire mapping all come from the wrapped OpenAI adapter unchanged — see [`setup-openai`](../../../ai-openai/skills/setup-openai/SKILL.md).
58
+ - `structuredOutput` / `promptCaching` and the image/PDF/audio wire mapping all come from the wrapped OpenAI adapter unchanged — see the `setup-openai` topic of the `warlock-js-ai-openai` skill.
59
59
 
60
60
  **Override `vision`, `reasoning`, or `structuredOutput` explicitly** via `.model({ name, vision?, reasoning?, structuredOutput? })`.
61
61
 
@@ -72,11 +72,11 @@ await model.complete(messages, { reasoning: { effort: "high" } }); // → reaso
72
72
 
73
73
  ## Multipart messages (image input)
74
74
 
75
- 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 — see [`setup-openai`](../../../ai-openai/skills/setup-openai/SKILL.md).
75
+ 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 — see the `setup-openai` topic of the `warlock-js-ai-openai` skill.
76
76
 
77
77
  ## Uses the OpenAI-compatible endpoint
78
78
 
79
- All wire work — request/response mapping, streaming, tool-call accumulation, structured output, usage extraction — is the wrapped `OpenAISDK`'s, unchanged. The wrapper only: (1) sets the xAI `baseURL` + `provider` defaults, and (2) injects xAI's vision/reasoning inference per model. For streaming, structured output, and the full multipart surface, read [`@warlock.js/ai-openai/skills/setup-openai/SKILL.md`](../../../ai-openai/skills/setup-openai/SKILL.md).
79
+ All wire work — request/response mapping, streaming, tool-call accumulation, structured output, usage extraction — is the wrapped `OpenAISDK`'s, unchanged. The wrapper only: (1) sets the xAI `baseURL` + `provider` defaults, and (2) injects xAI's vision/reasoning inference per model. For streaming, structured output, and the full multipart surface, read the `setup-openai` topic of the `warlock-js-ai-openai` skill.
80
80
 
81
81
  ## Embeddings — not available on xAI
82
82
 
@@ -111,7 +111,7 @@ usage.cost; // per-channel USD breakdown of THIS run, or undefined when unpriced
111
111
 
112
112
  ## Errors
113
113
 
114
- Raw xAI / OpenAI-SDK errors are wrapped into the typed `@warlock.js/ai` `AIError` hierarchy by the wrapped adapter's error wrapper (dispatch keys on `APIError.status + code`). See [`@warlock.js/ai/handle-ai-errors/SKILL.md`](@warlock.js/ai/handle-ai-errors/SKILL.md).
114
+ Raw xAI / OpenAI-SDK errors are wrapped into the typed `@warlock.js/ai` `AIError` hierarchy by the wrapped adapter's error wrapper (dispatch keys on `APIError.status + code`). See the `handle-ai-errors` topic of the `warlock-js-ai` skill.
115
115
 
116
116
  ## When NOT to use this skill
117
117
 
@@ -120,9 +120,9 @@ Raw xAI / OpenAI-SDK errors are wrapped into the typed `@warlock.js/ai` `AIError
120
120
 
121
121
  ## See also
122
122
 
123
- - [`@warlock.js/ai-openai/skills/setup-openai/SKILL.md`](../../../ai-openai/skills/setup-openai/SKILL.md) — the wrapped adapter; full wire / streaming / structured-output / multipart surface
124
- - [`@warlock.js/ai/run-ai-agent/SKILL.md`](@warlock.js/ai/run-ai-agent/SKILL.md) — passing the model into `ai.agent({...})`
125
- - [`@warlock.js/ai/pick-ai-provider/SKILL.md`](@warlock.js/ai/pick-ai-provider/SKILL.md) — adapter comparison
123
+ - The `setup-openai` topic of the `warlock-js-ai-openai` skill — the wrapped adapter; full wire / streaming / structured-output / multipart surface
124
+ - The `run-ai-agent` topic of the `warlock-js-ai` skill — passing the model into `ai.agent({...})`
125
+ - The `pick-ai-provider` topic of the `warlock-js-ai` skill — adapter comparison
126
126
  ```
127
127
 
128
128
 
package/llms.txt CHANGED
@@ -6,4 +6,4 @@
6
6
 
7
7
  ## Skills
8
8
 
9
- - [setup-xai](@warlock.js/ai-xai/setup-xai/SKILL.md): Wire @warlock.js/ai-xai — new XaiSDK({apiKey, baseURL?, provider?, pricing?}) for xAI Grok, .model({name, vision?, reasoning?, structuredOutput?}) for a ModelContract, .embedder({name, dimensions?}) and .image({name, pricing?}) delegated to the OpenAI-compatible adapter. Thin wrapper over OpenAISDK: uses the xAI OpenAI-compatible endpoint (https://api.x.ai/v1) and injects xAI's own vision/reasoning inference so Grok names resolve to the right capabilities. Triggers: `XaiSDK`, `grok`, `grok-4`, `grok-3`, `grok-3-mini`, `grok-2-vision`, `.model`, `x.ai`, `api.x.ai`, `XAI_API_KEY`, `reasoning_effort` on Grok, "wire xai/grok into a warlock agent", "configure grok-4", "use grok reasoning effort", "send an image to grok-4 / grok-2-vision"; typical import `import { XaiSDK } from "@warlock.js/ai-xai"`. Skip: agent wiring — `@warlock.js/ai/run-ai-agent/SKILL.md`; the underlying OpenAI-compatible adapter and its full capability/streaming/error surface — `@warlock.js/ai-openai/skills/setup-openai/SKILL.md`; adapter comparison — `@warlock.js/ai/pick-ai-provider/SKILL.md`; competing adapters `@warlock.js/ai-anthropic`, `@warlock.js/ai-google`, `@warlock.js/ai-ollama`; raw `openai` SDK pointed at x.ai by hand.
9
+ - [setup-xai](@warlock.js/ai-xai/setup-xai/SKILL.md): Wire @warlock.js/ai-xai — new XaiSDK({apiKey, baseURL?, provider?, pricing?}) for xAI Grok, .model({name, vision?, reasoning?, structuredOutput?}) for a ModelContract, .embedder({name, dimensions?}) and .image({name, pricing?}) delegated to the OpenAI-compatible adapter. Thin wrapper over OpenAISDK: uses the xAI OpenAI-compatible endpoint (https://api.x.ai/v1) and injects xAI's own vision/reasoning inference so Grok names resolve to the right capabilities. Triggers: `XaiSDK`, `grok`, `grok-4`, `grok-3`, `grok-3-mini`, `grok-2-vision`, `.model`, `x.ai`, `api.x.ai`, `XAI_API_KEY`, `reasoning_effort` on Grok, "wire xai/grok into a warlock agent", "configure grok-4", "use grok reasoning effort", "send an image to grok-4 / grok-2-vision"; typical import `import { XaiSDK } from "@warlock.js/ai-xai"`. Skip: agent wiring — the `run-ai-agent` topic of the `warlock-js-ai` skill; the underlying OpenAI-compatible adapter and its full capability/streaming/error surface — the `setup-openai` topic of the `warlock-js-ai-openai` skill; adapter comparison — the `pick-ai-provider` topic of the `warlock-js-ai` skill; competing adapters `@warlock.js/ai-anthropic`, `@warlock.js/ai-google`, `@warlock.js/ai-ollama`; raw `openai` SDK pointed at x.ai by hand.
package/package.json CHANGED
@@ -11,16 +11,17 @@
11
11
  "license": "MIT",
12
12
  "repository": {
13
13
  "type": "git",
14
- "url": "https://github.com/warlockjs/ai-xai"
14
+ "url": "git+https://github.com/warlockjs/framework.git",
15
+ "directory": "packages/ai-xai"
15
16
  },
16
17
  "dependencies": {
17
- "@warlock.js/ai-openai": "5.28.0",
18
- "@warlock.js/logger": "5.28.0"
18
+ "@warlock.js/ai-openai": "5.30.0",
19
+ "@warlock.js/logger": "5.30.0"
19
20
  },
20
21
  "peerDependencies": {
21
- "@warlock.js/ai": "5.28.0"
22
+ "@warlock.js/ai": "5.30.0"
22
23
  },
23
- "version": "5.28.0",
24
+ "version": "5.30.0",
24
25
  "main": "./cjs/index.cjs",
25
26
  "module": "./esm/index.mjs",
26
27
  "types": "./esm/index.d.mts",
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: setup-xai
3
- description: 'Wire @warlock.js/ai-xai — new XaiSDK({apiKey, baseURL?, provider?, pricing?}) for xAI Grok, .model({name, vision?, reasoning?, structuredOutput?}) for a ModelContract, .embedder({name, dimensions?}) and .image({name, pricing?}) delegated to the OpenAI-compatible adapter. Thin wrapper over OpenAISDK: uses the xAI OpenAI-compatible endpoint (https://api.x.ai/v1) and injects xAI''s own vision/reasoning inference so Grok names resolve to the right capabilities. Triggers: `XaiSDK`, `grok`, `grok-4`, `grok-3`, `grok-3-mini`, `grok-2-vision`, `.model`, `x.ai`, `api.x.ai`, `XAI_API_KEY`, `reasoning_effort` on Grok, "wire xai/grok into a warlock agent", "configure grok-4", "use grok reasoning effort", "send an image to grok-4 / grok-2-vision"; typical import `import { XaiSDK } from "@warlock.js/ai-xai"`. Skip: agent wiring — `@warlock.js/ai/run-ai-agent/SKILL.md`; the underlying OpenAI-compatible adapter and its full capability/streaming/error surface — `@warlock.js/ai-openai/skills/setup-openai/SKILL.md`; adapter comparison — `@warlock.js/ai/pick-ai-provider/SKILL.md`; competing adapters `@warlock.js/ai-anthropic`, `@warlock.js/ai-google`, `@warlock.js/ai-ollama`; raw `openai` SDK pointed at x.ai by hand.'
3
+ description: 'Wire @warlock.js/ai-xai — new XaiSDK({apiKey, baseURL?, provider?, pricing?}) for xAI Grok, .model({name, vision?, reasoning?, structuredOutput?}) for a ModelContract, .embedder({name, dimensions?}) and .image({name, pricing?}) delegated to the OpenAI-compatible adapter. Thin wrapper over OpenAISDK: uses the xAI OpenAI-compatible endpoint (https://api.x.ai/v1) and injects xAI''s own vision/reasoning inference so Grok names resolve to the right capabilities. Triggers: `XaiSDK`, `grok`, `grok-4`, `grok-3`, `grok-3-mini`, `grok-2-vision`, `.model`, `x.ai`, `api.x.ai`, `XAI_API_KEY`, `reasoning_effort` on Grok, "wire xai/grok into a warlock agent", "configure grok-4", "use grok reasoning effort", "send an image to grok-4 / grok-2-vision"; typical import `import { XaiSDK } from "@warlock.js/ai-xai"`. Skip: agent wiring — the `run-ai-agent` topic of the `warlock-js-ai` skill; the underlying OpenAI-compatible adapter and its full capability/streaming/error surface — the `setup-openai` topic of the `warlock-js-ai-openai` skill; adapter comparison — the `pick-ai-provider` topic of the `warlock-js-ai` skill; competing adapters `@warlock.js/ai-anthropic`, `@warlock.js/ai-google`, `@warlock.js/ai-ollama`; raw `openai` SDK pointed at x.ai by hand.'
4
4
  ---
5
5
 
6
6
  # `@warlock.js/ai-xai`
7
7
 
8
- Provider adapter for xAI's **Grok** models. xAI speaks the OpenAI Chat Completions protocol, so `XaiSDK` is a **thin wrapper** over [`OpenAISDK`](../../../ai-openai/skills/setup-openai/SKILL.md) — it does not reimplement the wire layer. It constructs one internal `OpenAISDK` pointed at xAI's `baseURL` and labeled `provider: "xai"`, then delegates `model()` / `embedder()` / `image()` / `count()`, injecting xAI's own capability inference so Grok model names resolve correctly. Pair with `@warlock.js/ai` for the agent / tool / system-prompt surface.
8
+ Provider adapter for xAI's **Grok** models. xAI speaks the OpenAI Chat Completions protocol, so `XaiSDK` is a **thin wrapper** over `OpenAISDK` (the `setup-openai` topic of the `warlock-js-ai-openai` skill) — it does not reimplement the wire layer. It constructs one internal `OpenAISDK` pointed at xAI's `baseURL` and labeled `provider: "xai"`, then delegates `model()` / `embedder()` / `image()` / `count()`, injecting xAI's own capability inference so Grok model names resolve correctly. Pair with `@warlock.js/ai` for the agent / tool / system-prompt surface.
9
9
 
10
10
  ## Construction
11
11
 
@@ -47,7 +47,7 @@ This adapter ships xAI's OWN name lists (Grok ids don't match OpenAI's `gpt-*` /
47
47
 
48
48
  - `vision` — inferred `true` for the `grok-4` and `grok-2-vision` prefixes; `false` otherwise.
49
49
  - `reasoning` — inferred `true` for `grok-4` and `grok-3-mini`; drives whether `reasoning.effort` is forwarded as `reasoning_effort` on the wire.
50
- - `structuredOutput` / `promptCaching` and the image/PDF/audio wire mapping all come from the wrapped OpenAI adapter unchanged — see [`setup-openai`](../../../ai-openai/skills/setup-openai/SKILL.md).
50
+ - `structuredOutput` / `promptCaching` and the image/PDF/audio wire mapping all come from the wrapped OpenAI adapter unchanged — see the `setup-openai` topic of the `warlock-js-ai-openai` skill.
51
51
 
52
52
  **Override `vision`, `reasoning`, or `structuredOutput` explicitly** via `.model({ name, vision?, reasoning?, structuredOutput? })`.
53
53
 
@@ -64,11 +64,11 @@ await model.complete(messages, { reasoning: { effort: "high" } }); // → reaso
64
64
 
65
65
  ## Multipart messages (image input)
66
66
 
67
- 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 — see [`setup-openai`](../../../ai-openai/skills/setup-openai/SKILL.md).
67
+ 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 — see the `setup-openai` topic of the `warlock-js-ai-openai` skill.
68
68
 
69
69
  ## Uses the OpenAI-compatible endpoint
70
70
 
71
- All wire work — request/response mapping, streaming, tool-call accumulation, structured output, usage extraction — is the wrapped `OpenAISDK`'s, unchanged. The wrapper only: (1) sets the xAI `baseURL` + `provider` defaults, and (2) injects xAI's vision/reasoning inference per model. For streaming, structured output, and the full multipart surface, read [`@warlock.js/ai-openai/skills/setup-openai/SKILL.md`](../../../ai-openai/skills/setup-openai/SKILL.md).
71
+ All wire work — request/response mapping, streaming, tool-call accumulation, structured output, usage extraction — is the wrapped `OpenAISDK`'s, unchanged. The wrapper only: (1) sets the xAI `baseURL` + `provider` defaults, and (2) injects xAI's vision/reasoning inference per model. For streaming, structured output, and the full multipart surface, read the `setup-openai` topic of the `warlock-js-ai-openai` skill.
72
72
 
73
73
  ## Embeddings — not available on xAI
74
74
 
@@ -103,7 +103,7 @@ usage.cost; // per-channel USD breakdown of THIS run, or undefined when unpriced
103
103
 
104
104
  ## Errors
105
105
 
106
- Raw xAI / OpenAI-SDK errors are wrapped into the typed `@warlock.js/ai` `AIError` hierarchy by the wrapped adapter's error wrapper (dispatch keys on `APIError.status + code`). See [`@warlock.js/ai/handle-ai-errors/SKILL.md`](@warlock.js/ai/handle-ai-errors/SKILL.md).
106
+ Raw xAI / OpenAI-SDK errors are wrapped into the typed `@warlock.js/ai` `AIError` hierarchy by the wrapped adapter's error wrapper (dispatch keys on `APIError.status + code`). See the `handle-ai-errors` topic of the `warlock-js-ai` skill.
107
107
 
108
108
  ## When NOT to use this skill
109
109
 
@@ -112,7 +112,7 @@ Raw xAI / OpenAI-SDK errors are wrapped into the typed `@warlock.js/ai` `AIError
112
112
 
113
113
  ## See also
114
114
 
115
- - [`@warlock.js/ai-openai/skills/setup-openai/SKILL.md`](../../../ai-openai/skills/setup-openai/SKILL.md) — the wrapped adapter; full wire / streaming / structured-output / multipart surface
116
- - [`@warlock.js/ai/run-ai-agent/SKILL.md`](@warlock.js/ai/run-ai-agent/SKILL.md) — passing the model into `ai.agent({...})`
117
- - [`@warlock.js/ai/pick-ai-provider/SKILL.md`](@warlock.js/ai/pick-ai-provider/SKILL.md) — adapter comparison
115
+ - The `setup-openai` topic of the `warlock-js-ai-openai` skill — the wrapped adapter; full wire / streaming / structured-output / multipart surface
116
+ - The `run-ai-agent` topic of the `warlock-js-ai` skill — passing the model into `ai.agent({...})`
117
+ - The `pick-ai-provider` topic of the `warlock-js-ai` skill — adapter comparison
118
118
  ```