@tanstack/ai-grok 0.12.4 → 0.14.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/README.md CHANGED
@@ -28,11 +28,10 @@ export XAI_API_KEY="xai-..."
28
28
  import { grokText } from '@tanstack/ai-grok'
29
29
  import { generate } from '@tanstack/ai'
30
30
 
31
- const adapter = grokText()
31
+ const adapter = grokText('grok-build-0.1')
32
32
 
33
33
  const result = await generate({
34
34
  adapter,
35
- model: 'grok-3',
36
35
  messages: [
37
36
  { role: 'user', content: 'Explain quantum computing in simple terms' },
38
37
  ],
@@ -47,11 +46,10 @@ console.log(result.text)
47
46
  import { grokSummarize } from '@tanstack/ai-grok'
48
47
  import { summarize } from '@tanstack/ai'
49
48
 
50
- const adapter = grokSummarize()
49
+ const adapter = grokSummarize('grok-build-0.1')
51
50
 
52
51
  const result = await summarize({
53
52
  adapter,
54
- model: 'grok-3',
55
53
  text: 'Long article text...',
56
54
  style: 'bullet-points',
57
55
  })
@@ -83,27 +81,17 @@ console.log(result.images[0].url)
83
81
  ```typescript
84
82
  import { createGrokText } from '@tanstack/ai-grok'
85
83
 
86
- const adapter = createGrokText('xai-your-api-key-here')
84
+ const adapter = createGrokText('grok-build-0.1', 'xai-your-api-key-here')
87
85
  ```
88
86
 
89
- ## Supported Models
87
+ ## Supported Chat Models
90
88
 
91
- ### Chat Models
92
-
93
- - `grok-4` - Latest flagship model
94
- - `grok-3` - Previous generation model
95
- - `grok-3-mini` - Smaller, faster model
96
- - `grok-4-fast` - Fast inference model
97
- - `grok-4.1-fast` - Production-focused fast model
98
- - `grok-2-vision-1212` - Vision-capable model (text + image input)
99
-
100
- ### Image Models
101
-
102
- - `grok-2-image-1212` - Image generation model
89
+ - `grok-build-0.1` - Build-focused reasoning model with text + image input
90
+ - `grok-4.3` - Reasoning, structured outputs, tool calling, text + image input
103
91
 
104
92
  ## Features
105
93
 
106
- - ✅ Streaming chat completions
94
+ - ✅ Streaming chat via xAI Responses API
107
95
  - ✅ Structured output (JSON Schema)
108
96
  - ✅ Function/tool calling
109
97
  - ✅ Multimodal input (text + images for vision models)
@@ -13,14 +13,14 @@ export type GrokSummarizeModel = (typeof GROK_CHAT_MODELS)[number];
13
13
  * Creates a Grok summarize adapter with explicit API key.
14
14
  * Type resolution happens here at the call site.
15
15
  *
16
- * @param model - The model name (e.g., 'grok-3', 'grok-4')
16
+ * @param model - The model name (e.g., 'grok-build-0.1')
17
17
  * @param apiKey - Your xAI API key
18
18
  * @param config - Optional additional configuration
19
19
  * @returns Configured Grok summarize adapter instance with resolved types
20
20
  *
21
21
  * @example
22
22
  * ```typescript
23
- * const adapter = createGrokSummarize('grok-3', "xai-...");
23
+ * const adapter = createGrokSummarize('grok-build-0.1', "xai-...");
24
24
  * ```
25
25
  */
26
26
  export declare function createGrokSummarize<TModel extends GrokSummarizeModel>(model: TModel, apiKey: string, config?: Omit<GrokSummarizeConfig, 'apiKey'>): ChatStreamSummarizeAdapter<TModel, InferTextProviderOptions<GrokTextAdapter<TModel>>>;
@@ -32,7 +32,7 @@ export declare function createGrokSummarize<TModel extends GrokSummarizeModel>(m
32
32
  * - `process.env` (Node.js)
33
33
  * - `window.env` (Browser with injected env)
34
34
  *
35
- * @param model - The model name (e.g., 'grok-3', 'grok-4')
35
+ * @param model - The model name (e.g., 'grok-build-0.1')
36
36
  * @param config - Optional configuration (excluding apiKey which is auto-detected)
37
37
  * @returns Configured Grok summarize adapter instance with resolved types
38
38
  * @throws Error if XAI_API_KEY is not found in environment
@@ -40,7 +40,7 @@ export declare function createGrokSummarize<TModel extends GrokSummarizeModel>(m
40
40
  * @example
41
41
  * ```typescript
42
42
  * // Automatically uses XAI_API_KEY from environment
43
- * const adapter = grokSummarize('grok-3');
43
+ * const adapter = grokSummarize('grok-build-0.1');
44
44
  *
45
45
  * await summarize({
46
46
  * adapter,
@@ -1 +1 @@
1
- {"version":3,"file":"summarize.js","sources":["../../../src/adapters/summarize.ts"],"sourcesContent":["import { ChatStreamSummarizeAdapter } from '@tanstack/ai/adapters'\nimport { getGrokApiKeyFromEnv } from '../utils'\nimport { GrokTextAdapter } from './text'\nimport type { InferTextProviderOptions } from '@tanstack/ai/adapters'\nimport type { GROK_CHAT_MODELS } from '../model-meta'\nimport type { GrokClientConfig } from '../utils'\n\n/**\n * Configuration for Grok summarize adapter\n */\nexport interface GrokSummarizeConfig extends GrokClientConfig {}\n\n/** Model type for Grok summarization */\nexport type GrokSummarizeModel = (typeof GROK_CHAT_MODELS)[number]\n\n/**\n * Creates a Grok summarize adapter with explicit API key.\n * Type resolution happens here at the call site.\n *\n * @param model - The model name (e.g., 'grok-3', 'grok-4')\n * @param apiKey - Your xAI API key\n * @param config - Optional additional configuration\n * @returns Configured Grok summarize adapter instance with resolved types\n *\n * @example\n * ```typescript\n * const adapter = createGrokSummarize('grok-3', \"xai-...\");\n * ```\n */\nexport function createGrokSummarize<TModel extends GrokSummarizeModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<GrokSummarizeConfig, 'apiKey'>,\n): ChatStreamSummarizeAdapter<\n TModel,\n InferTextProviderOptions<GrokTextAdapter<TModel>>\n> {\n return new ChatStreamSummarizeAdapter(\n new GrokTextAdapter({ apiKey, ...config }, model),\n model,\n 'grok',\n )\n}\n\n/**\n * Creates a Grok summarize adapter with automatic API key detection from environment variables.\n * Type resolution happens here at the call site.\n *\n * Looks for `XAI_API_KEY` in:\n * - `process.env` (Node.js)\n * - `window.env` (Browser with injected env)\n *\n * @param model - The model name (e.g., 'grok-3', 'grok-4')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Grok summarize adapter instance with resolved types\n * @throws Error if XAI_API_KEY is not found in environment\n *\n * @example\n * ```typescript\n * // Automatically uses XAI_API_KEY from environment\n * const adapter = grokSummarize('grok-3');\n *\n * await summarize({\n * adapter,\n * text: \"Long article text...\"\n * });\n * ```\n */\nexport function grokSummarize<TModel extends GrokSummarizeModel>(\n model: TModel,\n config?: Omit<GrokSummarizeConfig, 'apiKey'>,\n): ChatStreamSummarizeAdapter<\n TModel,\n InferTextProviderOptions<GrokTextAdapter<TModel>>\n> {\n return createGrokSummarize(model, getGrokApiKeyFromEnv(), config)\n}\n"],"names":[],"mappings":";;;;;AA6BO,SAAS,oBACd,OACA,QACA,QAIA;AACA,SAAO,IAAI;AAAA,IACT,IAAI,gBAAgB,EAAE,QAAQ,GAAG,OAAA,GAAU,KAAK;AAAA,IAChD;AAAA,IACA;AAAA,EAAA;AAEJ;AA0BO,SAAS,cACd,OACA,QAIA;AACA,SAAO,oBAAoB,OAAO,qBAAA,GAAwB,MAAM;AAClE;"}
1
+ {"version":3,"file":"summarize.js","sources":["../../../src/adapters/summarize.ts"],"sourcesContent":["import { ChatStreamSummarizeAdapter } from '@tanstack/ai/adapters'\nimport { getGrokApiKeyFromEnv } from '../utils'\nimport { GrokTextAdapter } from './text'\nimport type { InferTextProviderOptions } from '@tanstack/ai/adapters'\nimport type { GROK_CHAT_MODELS } from '../model-meta'\nimport type { GrokClientConfig } from '../utils'\n\n/**\n * Configuration for Grok summarize adapter\n */\nexport interface GrokSummarizeConfig extends GrokClientConfig {}\n\n/** Model type for Grok summarization */\nexport type GrokSummarizeModel = (typeof GROK_CHAT_MODELS)[number]\n\n/**\n * Creates a Grok summarize adapter with explicit API key.\n * Type resolution happens here at the call site.\n *\n * @param model - The model name (e.g., 'grok-build-0.1')\n * @param apiKey - Your xAI API key\n * @param config - Optional additional configuration\n * @returns Configured Grok summarize adapter instance with resolved types\n *\n * @example\n * ```typescript\n * const adapter = createGrokSummarize('grok-build-0.1', \"xai-...\");\n * ```\n */\nexport function createGrokSummarize<TModel extends GrokSummarizeModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<GrokSummarizeConfig, 'apiKey'>,\n): ChatStreamSummarizeAdapter<\n TModel,\n InferTextProviderOptions<GrokTextAdapter<TModel>>\n> {\n return new ChatStreamSummarizeAdapter(\n new GrokTextAdapter({ apiKey, ...config }, model),\n model,\n 'grok',\n )\n}\n\n/**\n * Creates a Grok summarize adapter with automatic API key detection from environment variables.\n * Type resolution happens here at the call site.\n *\n * Looks for `XAI_API_KEY` in:\n * - `process.env` (Node.js)\n * - `window.env` (Browser with injected env)\n *\n * @param model - The model name (e.g., 'grok-build-0.1')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Grok summarize adapter instance with resolved types\n * @throws Error if XAI_API_KEY is not found in environment\n *\n * @example\n * ```typescript\n * // Automatically uses XAI_API_KEY from environment\n * const adapter = grokSummarize('grok-build-0.1');\n *\n * await summarize({\n * adapter,\n * text: \"Long article text...\"\n * });\n * ```\n */\nexport function grokSummarize<TModel extends GrokSummarizeModel>(\n model: TModel,\n config?: Omit<GrokSummarizeConfig, 'apiKey'>,\n): ChatStreamSummarizeAdapter<\n TModel,\n InferTextProviderOptions<GrokTextAdapter<TModel>>\n> {\n return createGrokSummarize(model, getGrokApiKeyFromEnv(), config)\n}\n"],"names":[],"mappings":";;;;;AA6BO,SAAS,oBACd,OACA,QACA,QAIA;AACA,SAAO,IAAI;AAAA,IACT,IAAI,gBAAgB,EAAE,QAAQ,GAAG,OAAA,GAAU,KAAK;AAAA,IAChD;AAAA,IACA;AAAA,EAAA;AAEJ;AA0BO,SAAS,cACd,OACA,QAIA;AACA,SAAO,oBAAoB,OAAO,qBAAA,GAAwB,MAAM;AAClE;"}
@@ -1,9 +1,9 @@
1
- import { default as OpenAI } from 'openai';
2
- import { OpenAIBaseChatCompletionsTextAdapter } from '@tanstack/openai-base';
1
+ import { OpenAIBaseResponsesTextAdapter } from '@tanstack/openai-base';
3
2
  import { GROK_CHAT_MODELS, GrokChatModelToolCapabilitiesByName, ResolveInputModalities, ResolveProviderOptions } from '../model-meta.js';
4
- import { Modality } from '@tanstack/ai';
3
+ import { Modality, TextOptions } from '@tanstack/ai';
5
4
  import { GrokMessageMetadataByModality } from '../message-types.js';
6
5
  import { GrokClientConfig } from '../utils.js';
6
+ import { ResponseCreateParams } from 'openai/resources/responses/responses';
7
7
  /**
8
8
  * Resolve tool capabilities for a specific Grok model.
9
9
  */
@@ -21,49 +21,31 @@ export type { ExternalTextProviderOptions as GrokTextProviderOptions } from '../
21
21
  * Grok Text (Chat) Adapter
22
22
  *
23
23
  * Tree-shakeable adapter for Grok chat/text completion functionality.
24
- * Uses OpenAI-compatible Chat Completions API (not Responses API).
24
+ * Uses xAI's OpenAI-compatible Responses API.
25
25
  *
26
- * Delegates implementation to {@link OpenAIBaseChatCompletionsTextAdapter}
26
+ * Delegates implementation to {@link OpenAIBaseResponsesTextAdapter}
27
27
  * from `@tanstack/openai-base` and threads Grok-specific tool-capability
28
28
  * typing through the 5th generic of the base class.
29
29
  */
30
- export declare class GrokTextAdapter<TModel extends (typeof GROK_CHAT_MODELS)[number], TProviderOptions extends Record<string, any> = ResolveProviderOptions<TModel>, TInputModalities extends ReadonlyArray<Modality> = ResolveInputModalities<TModel>, TToolCapabilities extends ReadonlyArray<string> = ResolveToolCapabilities<TModel>> extends OpenAIBaseChatCompletionsTextAdapter<TModel, TProviderOptions, TInputModalities, GrokMessageMetadataByModality, TToolCapabilities> {
30
+ export declare class GrokTextAdapter<TModel extends (typeof GROK_CHAT_MODELS)[number], TProviderOptions extends Record<string, unknown> = ResolveProviderOptions<TModel>, TInputModalities extends ReadonlyArray<Modality> = ResolveInputModalities<TModel>, TToolCapabilities extends ReadonlyArray<string> = ResolveToolCapabilities<TModel>> extends OpenAIBaseResponsesTextAdapter<TModel, TProviderOptions, TInputModalities, GrokMessageMetadataByModality, TToolCapabilities> {
31
31
  readonly kind: "text";
32
32
  readonly name: "grok";
33
33
  constructor(config: GrokTextConfig, model: TModel);
34
- /**
35
- * Surfaces xAI reasoning deltas on Grok reasoning models. The DeepSeek-style
36
- * convention puts the chain-of-thought on `delta.reasoning_content`; some
37
- * Grok variants also populate `delta.reasoning`. Reading both keeps
38
- * reasoning flowing through the base's REASONING_* lifecycle for both
39
- * `chatStream` and `structuredOutputStream`.
40
- */
41
- protected extractReasoning(chunk: OpenAI.Chat.Completions.ChatCompletionChunk): {
42
- text: string;
43
- } | undefined;
44
- /**
45
- * Grok's combined tools + schema support is gated to the Grok 4 family
46
- * per xAI's structured-output docs; Grok 2 / 3 reject the combination.
47
- * The wiring on the wire is already correct (inherits the OpenAI Chat
48
- * Completions `response_format: json_schema` attach from the base
49
- * adapter); this override just narrows the capability claim to the
50
- * supported model family.
51
- */
52
- supportsCombinedToolsAndSchema(): boolean;
34
+ protected mapOptionsToRequest(options: TextOptions<TProviderOptions>): Omit<ResponseCreateParams, 'stream'>;
53
35
  }
54
36
  /**
55
37
  * Creates a Grok text adapter with explicit API key.
56
38
  * Type resolution happens here at the call site.
57
39
  *
58
- * @param model - The model name (e.g., 'grok-3', 'grok-4')
40
+ * @param model - The model name (e.g., 'grok-build-0.1')
59
41
  * @param apiKey - Your xAI API key
60
42
  * @param config - Optional additional configuration
61
43
  * @returns Configured Grok text adapter instance with resolved types
62
44
  *
63
45
  * @example
64
46
  * ```typescript
65
- * const adapter = createGrokText('grok-3', "xai-...");
66
- * // adapter has type-safe providerOptions for grok-3
47
+ * const adapter = createGrokText('grok-build-0.1', "xai-...");
48
+ * // adapter has type-safe providerOptions for grok-build-0.1
67
49
  * ```
68
50
  */
69
51
  export declare function createGrokText<TModel extends (typeof GROK_CHAT_MODELS)[number]>(model: TModel, apiKey: string, config?: Omit<GrokTextConfig, 'apiKey'>): GrokTextAdapter<TModel>;
@@ -75,7 +57,7 @@ export declare function createGrokText<TModel extends (typeof GROK_CHAT_MODELS)[
75
57
  * - `process.env` (Node.js)
76
58
  * - `window.env` (Browser with injected env)
77
59
  *
78
- * @param model - The model name (e.g., 'grok-3', 'grok-4')
60
+ * @param model - The model name (e.g., 'grok-build-0.1')
79
61
  * @param config - Optional configuration (excluding apiKey which is auto-detected)
80
62
  * @returns Configured Grok text adapter instance with resolved types
81
63
  * @throws Error if XAI_API_KEY is not found in environment
@@ -83,7 +65,7 @@ export declare function createGrokText<TModel extends (typeof GROK_CHAT_MODELS)[
83
65
  * @example
84
66
  * ```typescript
85
67
  * // Automatically uses XAI_API_KEY from environment
86
- * const adapter = grokText('grok-3');
68
+ * const adapter = grokText('grok-build-0.1');
87
69
  *
88
70
  * const stream = chat({
89
71
  * adapter,
@@ -1,38 +1,32 @@
1
1
  import OpenAI from "openai";
2
- import { OpenAIBaseChatCompletionsTextAdapter } from "@tanstack/openai-base";
2
+ import { OpenAIBaseResponsesTextAdapter } from "@tanstack/openai-base";
3
3
  import { withGrokDefaults, getGrokApiKeyFromEnv } from "../utils/client.js";
4
- import { GROK_COMBINED_TOOLS_AND_SCHEMA_MODELS } from "../model-meta.js";
5
- class GrokTextAdapter extends OpenAIBaseChatCompletionsTextAdapter {
4
+ import { convertToolsToProviderFormat } from "../tools/index.js";
5
+ class GrokTextAdapter extends OpenAIBaseResponsesTextAdapter {
6
6
  kind = "text";
7
7
  name = "grok";
8
8
  constructor(config, model) {
9
9
  super(model, "grok", new OpenAI(withGrokDefaults(config)));
10
10
  }
11
- /**
12
- * Surfaces xAI reasoning deltas on Grok reasoning models. The DeepSeek-style
13
- * convention puts the chain-of-thought on `delta.reasoning_content`; some
14
- * Grok variants also populate `delta.reasoning`. Reading both keeps
15
- * reasoning flowing through the base's REASONING_* lifecycle for both
16
- * `chatStream` and `structuredOutputStream`.
17
- */
18
- extractReasoning(chunk) {
19
- const delta = chunk.choices[0]?.delta;
20
- const raw = delta?.reasoning_content ?? delta?.reasoning;
21
- if (typeof raw === "string" && raw.length > 0) {
22
- return { text: raw };
11
+ mapOptionsToRequest(options) {
12
+ const { tools: _baseTools, ...request } = super.mapOptionsToRequest({
13
+ ...options,
14
+ tools: void 0
15
+ });
16
+ if (this.model === "grok-build-0.1" && request.reasoning !== void 0) {
17
+ throw new Error(
18
+ "grok-build-0.1 does not support reasoning modelOptions; omit reasoning for this model."
19
+ );
23
20
  }
24
- return void 0;
25
- }
26
- /**
27
- * Grok's combined tools + schema support is gated to the Grok 4 family
28
- * per xAI's structured-output docs; Grok 2 / 3 reject the combination.
29
- * The wiring on the wire is already correct (inherits the OpenAI Chat
30
- * Completions `response_format: json_schema` attach from the base
31
- * adapter); this override just narrows the capability claim to the
32
- * supported model family.
33
- */
34
- supportsCombinedToolsAndSchema() {
35
- return GROK_COMBINED_TOOLS_AND_SCHEMA_MODELS.has(this.model);
21
+ const tools = options.tools ? convertToolsToProviderFormat(options.tools) : void 0;
22
+ return {
23
+ ...request,
24
+ // xAI recommends encrypted reasoning for reasoning-capable Responses
25
+ // requests; callers can still override either field in modelOptions.
26
+ store: request.store ?? false,
27
+ include: request.include ?? ["reasoning.encrypted_content"],
28
+ ...tools && tools.length > 0 && { tools }
29
+ };
36
30
  }
37
31
  }
38
32
  function createGrokText(model, apiKey, config) {
@@ -1 +1 @@
1
- {"version":3,"file":"text.js","sources":["../../../src/adapters/text.ts"],"sourcesContent":["import OpenAI from 'openai'\nimport { OpenAIBaseChatCompletionsTextAdapter } from '@tanstack/openai-base'\nimport { getGrokApiKeyFromEnv, withGrokDefaults } from '../utils/client'\nimport { GROK_COMBINED_TOOLS_AND_SCHEMA_MODELS } from '../model-meta'\nimport type {\n GROK_CHAT_MODELS,\n GrokChatModelToolCapabilitiesByName,\n ResolveInputModalities,\n ResolveProviderOptions,\n} from '../model-meta'\nimport type { Modality } from '@tanstack/ai'\nimport type { GrokMessageMetadataByModality } from '../message-types'\nimport type { GrokClientConfig } from '../utils'\n\n/**\n * Resolve tool capabilities for a specific Grok model.\n */\ntype ResolveToolCapabilities<TModel extends string> =\n TModel extends keyof GrokChatModelToolCapabilitiesByName\n ? NonNullable<GrokChatModelToolCapabilitiesByName[TModel]>\n : readonly []\n\n/**\n * Configuration for Grok text adapter\n */\nexport interface GrokTextConfig extends GrokClientConfig {}\n\n/**\n * Alias for TextProviderOptions for external use\n */\nexport type { ExternalTextProviderOptions as GrokTextProviderOptions } from '../text/text-provider-options'\n\n/**\n * Grok Text (Chat) Adapter\n *\n * Tree-shakeable adapter for Grok chat/text completion functionality.\n * Uses OpenAI-compatible Chat Completions API (not Responses API).\n *\n * Delegates implementation to {@link OpenAIBaseChatCompletionsTextAdapter}\n * from `@tanstack/openai-base` and threads Grok-specific tool-capability\n * typing through the 5th generic of the base class.\n */\nexport class GrokTextAdapter<\n TModel extends (typeof GROK_CHAT_MODELS)[number],\n TProviderOptions extends Record<string, any> = ResolveProviderOptions<TModel>,\n TInputModalities extends ReadonlyArray<Modality> =\n ResolveInputModalities<TModel>,\n TToolCapabilities extends ReadonlyArray<string> =\n ResolveToolCapabilities<TModel>,\n> extends OpenAIBaseChatCompletionsTextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n GrokMessageMetadataByModality,\n TToolCapabilities\n> {\n override readonly kind = 'text' as const\n override readonly name = 'grok' as const\n\n constructor(config: GrokTextConfig, model: TModel) {\n super(model, 'grok', new OpenAI(withGrokDefaults(config)))\n }\n\n /**\n * Surfaces xAI reasoning deltas on Grok reasoning models. The DeepSeek-style\n * convention puts the chain-of-thought on `delta.reasoning_content`; some\n * Grok variants also populate `delta.reasoning`. Reading both keeps\n * reasoning flowing through the base's REASONING_* lifecycle for both\n * `chatStream` and `structuredOutputStream`.\n */\n protected override extractReasoning(\n chunk: OpenAI.Chat.Completions.ChatCompletionChunk,\n ): { text: string } | undefined {\n const delta = chunk.choices[0]?.delta as\n | { reasoning?: unknown; reasoning_content?: unknown }\n | undefined\n const raw = delta?.reasoning_content ?? delta?.reasoning\n if (typeof raw === 'string' && raw.length > 0) {\n return { text: raw }\n }\n return undefined\n }\n\n /**\n * Grok's combined tools + schema support is gated to the Grok 4 family\n * per xAI's structured-output docs; Grok 2 / 3 reject the combination.\n * The wiring on the wire is already correct (inherits the OpenAI Chat\n * Completions `response_format: json_schema` attach from the base\n * adapter); this override just narrows the capability claim to the\n * supported model family.\n */\n override supportsCombinedToolsAndSchema(): boolean {\n return GROK_COMBINED_TOOLS_AND_SCHEMA_MODELS.has(this.model)\n }\n}\n\n/**\n * Creates a Grok text adapter with explicit API key.\n * Type resolution happens here at the call site.\n *\n * @param model - The model name (e.g., 'grok-3', 'grok-4')\n * @param apiKey - Your xAI API key\n * @param config - Optional additional configuration\n * @returns Configured Grok text adapter instance with resolved types\n *\n * @example\n * ```typescript\n * const adapter = createGrokText('grok-3', \"xai-...\");\n * // adapter has type-safe providerOptions for grok-3\n * ```\n */\nexport function createGrokText<\n TModel extends (typeof GROK_CHAT_MODELS)[number],\n>(\n model: TModel,\n apiKey: string,\n config?: Omit<GrokTextConfig, 'apiKey'>,\n): GrokTextAdapter<TModel> {\n return new GrokTextAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Grok text adapter with automatic API key detection from environment variables.\n * Type resolution happens here at the call site.\n *\n * Looks for `XAI_API_KEY` in:\n * - `process.env` (Node.js)\n * - `window.env` (Browser with injected env)\n *\n * @param model - The model name (e.g., 'grok-3', 'grok-4')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Grok text adapter instance with resolved types\n * @throws Error if XAI_API_KEY is not found in environment\n *\n * @example\n * ```typescript\n * // Automatically uses XAI_API_KEY from environment\n * const adapter = grokText('grok-3');\n *\n * const stream = chat({\n * adapter,\n * messages: [{ role: \"user\", content: \"Hello!\" }]\n * });\n * ```\n */\nexport function grokText<TModel extends (typeof GROK_CHAT_MODELS)[number]>(\n model: TModel,\n config?: Omit<GrokTextConfig, 'apiKey'>,\n): GrokTextAdapter<TModel> {\n const apiKey = getGrokApiKeyFromEnv()\n return createGrokText(model, apiKey, config)\n}\n"],"names":[],"mappings":";;;;AA0CO,MAAM,wBAOH,qCAMR;AAAA,EACkB,OAAO;AAAA,EACP,OAAO;AAAA,EAEzB,YAAY,QAAwB,OAAe;AACjD,UAAM,OAAO,QAAQ,IAAI,OAAO,iBAAiB,MAAM,CAAC,CAAC;AAAA,EAC3D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASmB,iBACjB,OAC8B;AAC9B,UAAM,QAAQ,MAAM,QAAQ,CAAC,GAAG;AAGhC,UAAM,MAAM,OAAO,qBAAqB,OAAO;AAC/C,QAAI,OAAO,QAAQ,YAAY,IAAI,SAAS,GAAG;AAC7C,aAAO,EAAE,MAAM,IAAA;AAAA,IACjB;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUS,iCAA0C;AACjD,WAAO,sCAAsC,IAAI,KAAK,KAAK;AAAA,EAC7D;AACF;AAiBO,SAAS,eAGd,OACA,QACA,QACyB;AACzB,SAAO,IAAI,gBAAgB,EAAE,QAAQ,GAAG,OAAA,GAAU,KAAK;AACzD;AA0BO,SAAS,SACd,OACA,QACyB;AACzB,QAAM,SAAS,qBAAA;AACf,SAAO,eAAe,OAAO,QAAQ,MAAM;AAC7C;"}
1
+ {"version":3,"file":"text.js","sources":["../../../src/adapters/text.ts"],"sourcesContent":["import OpenAI from 'openai'\nimport { OpenAIBaseResponsesTextAdapter } from '@tanstack/openai-base'\nimport { getGrokApiKeyFromEnv, withGrokDefaults } from '../utils/client'\nimport { convertToolsToProviderFormat } from '../tools'\nimport type {\n GROK_CHAT_MODELS,\n GrokChatModelToolCapabilitiesByName,\n ResolveInputModalities,\n ResolveProviderOptions,\n} from '../model-meta'\nimport type { Modality, TextOptions } from '@tanstack/ai'\nimport type { GrokMessageMetadataByModality } from '../message-types'\nimport type { GrokClientConfig } from '../utils'\nimport type { ResponseCreateParams } from 'openai/resources/responses/responses'\n\n/**\n * Resolve tool capabilities for a specific Grok model.\n */\ntype ResolveToolCapabilities<TModel extends string> =\n TModel extends keyof GrokChatModelToolCapabilitiesByName\n ? NonNullable<GrokChatModelToolCapabilitiesByName[TModel]>\n : readonly []\n\n/**\n * Configuration for Grok text adapter\n */\nexport interface GrokTextConfig extends GrokClientConfig {}\n\n/**\n * Alias for TextProviderOptions for external use\n */\nexport type { ExternalTextProviderOptions as GrokTextProviderOptions } from '../text/text-provider-options'\n\n/**\n * Grok Text (Chat) Adapter\n *\n * Tree-shakeable adapter for Grok chat/text completion functionality.\n * Uses xAI's OpenAI-compatible Responses API.\n *\n * Delegates implementation to {@link OpenAIBaseResponsesTextAdapter}\n * from `@tanstack/openai-base` and threads Grok-specific tool-capability\n * typing through the 5th generic of the base class.\n */\nexport class GrokTextAdapter<\n TModel extends (typeof GROK_CHAT_MODELS)[number],\n TProviderOptions extends Record<string, unknown> =\n ResolveProviderOptions<TModel>,\n TInputModalities extends ReadonlyArray<Modality> =\n ResolveInputModalities<TModel>,\n TToolCapabilities extends ReadonlyArray<string> =\n ResolveToolCapabilities<TModel>,\n> extends OpenAIBaseResponsesTextAdapter<\n TModel,\n TProviderOptions,\n TInputModalities,\n GrokMessageMetadataByModality,\n TToolCapabilities\n> {\n override readonly kind = 'text' as const\n override readonly name = 'grok' as const\n\n constructor(config: GrokTextConfig, model: TModel) {\n super(model, 'grok', new OpenAI(withGrokDefaults(config)))\n }\n\n protected override mapOptionsToRequest(\n options: TextOptions<TProviderOptions>,\n ): Omit<ResponseCreateParams, 'stream'> {\n const { tools: _baseTools, ...request } = super.mapOptionsToRequest({\n ...options,\n tools: undefined,\n })\n void _baseTools\n\n if (this.model === 'grok-build-0.1' && request.reasoning !== undefined) {\n throw new Error(\n 'grok-build-0.1 does not support reasoning modelOptions; omit reasoning for this model.',\n )\n }\n\n const tools = options.tools\n ? convertToolsToProviderFormat(options.tools)\n : undefined\n\n return {\n ...request,\n // xAI recommends encrypted reasoning for reasoning-capable Responses\n // requests; callers can still override either field in modelOptions.\n store: request.store ?? false,\n include: request.include ?? ['reasoning.encrypted_content'],\n ...(tools &&\n tools.length > 0 && { tools: tools as ResponseCreateParams['tools'] }),\n }\n }\n}\n\n/**\n * Creates a Grok text adapter with explicit API key.\n * Type resolution happens here at the call site.\n *\n * @param model - The model name (e.g., 'grok-build-0.1')\n * @param apiKey - Your xAI API key\n * @param config - Optional additional configuration\n * @returns Configured Grok text adapter instance with resolved types\n *\n * @example\n * ```typescript\n * const adapter = createGrokText('grok-build-0.1', \"xai-...\");\n * // adapter has type-safe providerOptions for grok-build-0.1\n * ```\n */\nexport function createGrokText<\n TModel extends (typeof GROK_CHAT_MODELS)[number],\n>(\n model: TModel,\n apiKey: string,\n config?: Omit<GrokTextConfig, 'apiKey'>,\n): GrokTextAdapter<TModel> {\n return new GrokTextAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Grok text adapter with automatic API key detection from environment variables.\n * Type resolution happens here at the call site.\n *\n * Looks for `XAI_API_KEY` in:\n * - `process.env` (Node.js)\n * - `window.env` (Browser with injected env)\n *\n * @param model - The model name (e.g., 'grok-build-0.1')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Grok text adapter instance with resolved types\n * @throws Error if XAI_API_KEY is not found in environment\n *\n * @example\n * ```typescript\n * // Automatically uses XAI_API_KEY from environment\n * const adapter = grokText('grok-build-0.1');\n *\n * const stream = chat({\n * adapter,\n * messages: [{ role: \"user\", content: \"Hello!\" }]\n * });\n * ```\n */\nexport function grokText<TModel extends (typeof GROK_CHAT_MODELS)[number]>(\n model: TModel,\n config?: Omit<GrokTextConfig, 'apiKey'>,\n): GrokTextAdapter<TModel> {\n const apiKey = getGrokApiKeyFromEnv()\n return createGrokText(model, apiKey, config)\n}\n"],"names":[],"mappings":";;;;AA2CO,MAAM,wBAQH,+BAMR;AAAA,EACkB,OAAO;AAAA,EACP,OAAO;AAAA,EAEzB,YAAY,QAAwB,OAAe;AACjD,UAAM,OAAO,QAAQ,IAAI,OAAO,iBAAiB,MAAM,CAAC,CAAC;AAAA,EAC3D;AAAA,EAEmB,oBACjB,SACsC;AACtC,UAAM,EAAE,OAAO,YAAY,GAAG,QAAA,IAAY,MAAM,oBAAoB;AAAA,MAClE,GAAG;AAAA,MACH,OAAO;AAAA,IAAA,CACR;AAGD,QAAI,KAAK,UAAU,oBAAoB,QAAQ,cAAc,QAAW;AACtE,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAEA,UAAM,QAAQ,QAAQ,QAClB,6BAA6B,QAAQ,KAAK,IAC1C;AAEJ,WAAO;AAAA,MACL,GAAG;AAAA;AAAA;AAAA,MAGH,OAAO,QAAQ,SAAS;AAAA,MACxB,SAAS,QAAQ,WAAW,CAAC,6BAA6B;AAAA,MAC1D,GAAI,SACF,MAAM,SAAS,KAAK,EAAE,MAAA;AAAA,IAA8C;AAAA,EAE1E;AACF;AAiBO,SAAS,eAGd,OACA,QACA,QACyB;AACzB,SAAO,IAAI,gBAAgB,EAAE,QAAQ,GAAG,OAAA,GAAU,KAAK;AACzD;AA0BO,SAAS,SACd,OACA,QACyB;AACzB,QAAM,SAAS,qBAAA;AACf,SAAO,eAAe,OAAO,QAAQ,MAAM;AAC7C;"}
@@ -0,0 +1,128 @@
1
+ import { BaseVideoAdapter, DurationOptions } from '@tanstack/ai/adapters';
2
+ import { VideoGenerationOptions, VideoJobResult, VideoStatusResult, VideoUrlResult } from '@tanstack/ai';
3
+ import { GrokVideoModel } from '../model-meta.js';
4
+ import { GrokVideoModelDurationByName, GrokVideoModelInputModalitiesByName, GrokVideoModelProviderOptionsByName, GrokVideoModelSizeByName, GrokVideoProviderOptions } from '../video/video-provider-options.js';
5
+ import { GrokClientConfig } from '../utils.js';
6
+ /**
7
+ * Configuration for Grok video adapter.
8
+ *
9
+ * @experimental Video generation is an experimental feature and may change.
10
+ */
11
+ export interface GrokVideoConfig extends GrokClientConfig {
12
+ }
13
+ /**
14
+ * Grok Video Generation Adapter (xAI Imagine API)
15
+ *
16
+ * Tree-shakeable adapter for the grok-imagine video models using the
17
+ * async jobs/polling architecture: create a generation request, poll it,
18
+ * then read the completed video URL.
19
+ *
20
+ * `grok-imagine-video` (v1.0) supports text-to-video and image-to-video.
21
+ * `grok-imagine-video-1.5` is image-to-video only — every request needs an
22
+ * image prompt part as the starting frame, and the adapter rejects a
23
+ * text-only prompt with a clear error rather than a raw API 400.
24
+ *
25
+ * The Imagine video endpoints are not part of the OpenAI SDK surface (and
26
+ * xAI rejects the SDK's multipart paths), so requests are plain JSON calls
27
+ * issued with the configured `fetch` (or the global one).
28
+ *
29
+ * @experimental Video generation is an experimental feature and may change.
30
+ *
31
+ * Features:
32
+ * - Async job-based video generation (1–15 second clips with audio)
33
+ * - Aspect-ratio sizing via the "aspectRatio_resolution" size template
34
+ * (e.g. '16:9_720p'), consistent with the grok-imagine image models
35
+ * - Image-to-video via an `image` prompt part (starting frame URL or data URI)
36
+ * - Usage reporting: billed seconds (`unitsBilled`) and exact cost
37
+ */
38
+ export declare class GrokVideoAdapter<TModel extends GrokVideoModel> extends BaseVideoAdapter<TModel, GrokVideoProviderOptions, GrokVideoModelProviderOptionsByName, GrokVideoModelSizeByName, GrokVideoModelInputModalitiesByName, GrokVideoModelDurationByName> {
39
+ readonly name: "grok";
40
+ private readonly clientConfig;
41
+ constructor(config: GrokVideoConfig, model: TModel);
42
+ private get fetch();
43
+ private request;
44
+ /**
45
+ * Reads the error message out of an Imagine API error body
46
+ * (`{"code": "...", "error": "..."}`), falling back to the raw text.
47
+ */
48
+ private errorMessage;
49
+ createVideoJob(options: VideoGenerationOptions<GrokVideoProviderOptions, GrokVideoModelSizeByName[TModel], GrokVideoModelDurationByName[TModel]>): Promise<VideoJobResult>;
50
+ private retrieveJob;
51
+ getVideoStatus(jobId: string): Promise<VideoStatusResult>;
52
+ getVideoUrl(jobId: string): Promise<VideoUrlResult>;
53
+ /**
54
+ * Maps Imagine API job statuses onto the generic video status set. The
55
+ * API reports 'pending' while queued/generating (with a numeric
56
+ * `progress`), then a terminal 'done' / 'failed' / 'expired'.
57
+ */
58
+ protected mapStatus(apiStatus: string | undefined): 'pending' | 'processing' | 'completed' | 'failed';
59
+ /**
60
+ * Both grok-imagine video models accept a continuous 1–15 integer-second
61
+ * range. Consumers can use this to render UI without provider knowledge.
62
+ */
63
+ availableDurations(): DurationOptions<GrokVideoModelDurationByName[TModel]>;
64
+ /**
65
+ * Coerce a raw seconds value to the closest valid duration (clamped to
66
+ * [1, 15] and rounded to whole seconds).
67
+ */
68
+ snapDuration(seconds: number): GrokVideoModelDurationByName[TModel] | undefined;
69
+ }
70
+ /**
71
+ * Creates a Grok video adapter with an explicit API key.
72
+ * Type resolution happens here at the call site.
73
+ *
74
+ * @experimental Video generation is an experimental feature and may change.
75
+ *
76
+ * @param model - The model name (e.g., 'grok-imagine-video')
77
+ * @param apiKey - Your xAI API key
78
+ * @param config - Optional additional configuration
79
+ * @returns Configured Grok video adapter instance with resolved types
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * // grok-imagine-video (v1.0) supports text-to-video.
84
+ * const adapter = createGrokVideo('grok-imagine-video', 'xai-...');
85
+ *
86
+ * const { jobId } = await generateVideo({
87
+ * adapter,
88
+ * prompt: 'A beautiful sunset over the ocean',
89
+ * size: '16:9_720p',
90
+ * duration: 5
91
+ * });
92
+ * ```
93
+ */
94
+ export declare function createGrokVideo<TModel extends GrokVideoModel>(model: TModel, apiKey: string, config?: Omit<GrokVideoConfig, 'apiKey'>): GrokVideoAdapter<TModel>;
95
+ /**
96
+ * Creates a Grok video adapter with automatic API key detection from environment variables.
97
+ * Type resolution happens here at the call site.
98
+ *
99
+ * Looks for `XAI_API_KEY` in:
100
+ * - `process.env` (Node.js)
101
+ * - `window.env` (Browser with injected env)
102
+ *
103
+ * @experimental Video generation is an experimental feature and may change.
104
+ *
105
+ * @param model - The model name (e.g., 'grok-imagine-video-1.5')
106
+ * @param config - Optional configuration (excluding apiKey which is auto-detected)
107
+ * @returns Configured Grok video adapter instance with resolved types
108
+ * @throws Error if XAI_API_KEY is not found in environment
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * // Automatically uses XAI_API_KEY from environment
113
+ * const adapter = grokVideo('grok-imagine-video-1.5');
114
+ *
115
+ * // Image-to-video only: the prompt must carry a starting-frame image part.
116
+ * const { jobId } = await generateVideo({
117
+ * adapter,
118
+ * prompt: [
119
+ * { type: 'text', content: 'Make the cat start playing the piano' },
120
+ * { type: 'image', source: { type: 'url', value: 'https://example.com/cat.png' } },
121
+ * ],
122
+ * });
123
+ *
124
+ * // Poll for status
125
+ * const status = await getVideoJobStatus({ adapter, jobId });
126
+ * ```
127
+ */
128
+ export declare function grokVideo<TModel extends GrokVideoModel>(model: TModel, config?: Omit<GrokVideoConfig, 'apiKey'>): GrokVideoAdapter<TModel>;