@tanstack/ai-grok 0.14.1 → 0.14.3
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/package.json +4 -4
- package/dist/esm/adapters/image.d.ts +0 -89
- package/dist/esm/adapters/image.js +0 -205
- package/dist/esm/adapters/image.js.map +0 -1
- package/dist/esm/adapters/summarize.d.ts +0 -51
- package/dist/esm/adapters/summarize.js +0 -20
- package/dist/esm/adapters/summarize.js.map +0 -1
- package/dist/esm/adapters/text.d.ts +0 -76
- package/dist/esm/adapters/text.js +0 -44
- package/dist/esm/adapters/text.js.map +0 -1
- package/dist/esm/adapters/transcription.d.ts +0 -84
- package/dist/esm/adapters/transcription.js +0 -122
- package/dist/esm/adapters/transcription.js.map +0 -1
- package/dist/esm/adapters/tts.d.ts +0 -70
- package/dist/esm/adapters/tts.js +0 -142
- package/dist/esm/adapters/tts.js.map +0 -1
- package/dist/esm/adapters/video.d.ts +0 -128
- package/dist/esm/adapters/video.js +0 -237
- package/dist/esm/adapters/video.js.map +0 -1
- package/dist/esm/audio/transcription-provider-options.d.ts +0 -41
- package/dist/esm/audio/tts-provider-options.d.ts +0 -42
- package/dist/esm/image/image-provider-options.d.ts +0 -133
- package/dist/esm/image/image-provider-options.js +0 -76
- package/dist/esm/image/image-provider-options.js.map +0 -1
- package/dist/esm/index.d.ts +0 -16
- package/dist/esm/index.js +0 -40
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/message-types.d.ts +0 -64
- package/dist/esm/model-meta.d.ts +0 -99
- package/dist/esm/model-meta.js +0 -58
- package/dist/esm/model-meta.js.map +0 -1
- package/dist/esm/realtime/adapter.d.ts +0 -21
- package/dist/esm/realtime/adapter.js +0 -823
- package/dist/esm/realtime/adapter.js.map +0 -1
- package/dist/esm/realtime/index.d.ts +0 -4
- package/dist/esm/realtime/token.d.ts +0 -22
- package/dist/esm/realtime/token.js +0 -75
- package/dist/esm/realtime/token.js.map +0 -1
- package/dist/esm/realtime/types.d.ts +0 -95
- package/dist/esm/text/text-provider-options.d.ts +0 -54
- package/dist/esm/tools/index.d.ts +0 -45
- package/dist/esm/tools/index.js +0 -113
- package/dist/esm/tools/index.js.map +0 -1
- package/dist/esm/utils/audio.d.ts +0 -23
- package/dist/esm/utils/audio.js +0 -172
- package/dist/esm/utils/audio.js.map +0 -1
- package/dist/esm/utils/client.d.ts +0 -14
- package/dist/esm/utils/client.js +0 -21
- package/dist/esm/utils/client.js.map +0 -1
- package/dist/esm/utils/index.d.ts +0 -4
- package/dist/esm/utils/schema-converter.d.ts +0 -2
- package/dist/esm/video/video-provider-options.d.ts +0 -135
- package/dist/esm/video/video-provider-options.js +0 -67
- package/dist/esm/video/video-provider-options.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai-grok",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.3",
|
|
4
4
|
"description": "xAI Grok adapter for TanStack AI chat, image generation, realtime, and structured outputs.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,16 +51,16 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"openai": "^6.41.0",
|
|
53
53
|
"@tanstack/ai-utils": "0.3.0",
|
|
54
|
-
"@tanstack/openai-base": "0.9.
|
|
54
|
+
"@tanstack/openai-base": "0.9.3"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@vitest/coverage-v8": "4.0.14",
|
|
58
58
|
"vite": "^7.3.3",
|
|
59
|
-
"@tanstack/ai": "0.
|
|
59
|
+
"@tanstack/ai": "0.36.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"zod": "^4.0.0",
|
|
63
|
-
"@tanstack/ai": "^0.
|
|
63
|
+
"@tanstack/ai": "^0.36.0"
|
|
64
64
|
},
|
|
65
65
|
"scripts": {
|
|
66
66
|
"build": "vite build",
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { default as OpenAI } from 'openai';
|
|
2
|
-
import { BaseImageAdapter } from '@tanstack/ai/adapters';
|
|
3
|
-
import { ImageGenerationOptions, ImageGenerationResult } from '@tanstack/ai';
|
|
4
|
-
import { GrokImageModel } from '../model-meta.js';
|
|
5
|
-
import { GrokImageModelInputModalitiesByName, GrokImageModelProviderOptionsByName, GrokImageModelSizeByName, GrokImageProviderOptions } from '../image/image-provider-options.js';
|
|
6
|
-
import { GrokClientConfig } from '../utils.js';
|
|
7
|
-
/**
|
|
8
|
-
* Configuration for Grok image adapter
|
|
9
|
-
*/
|
|
10
|
-
export interface GrokImageConfig extends GrokClientConfig {
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Grok Image Generation Adapter
|
|
14
|
-
*
|
|
15
|
-
* Tree-shakeable adapter for Grok image generation functionality.
|
|
16
|
-
* Supports the legacy grok-2-image-1212 model (text-to-image via the
|
|
17
|
-
* OpenAI-compat endpoint) and the grok-imagine image models, which also
|
|
18
|
-
* accept image prompt parts for image-conditioned generation via xAI's
|
|
19
|
-
* `/v1/images/edits` endpoint (up to 3 source images).
|
|
20
|
-
*
|
|
21
|
-
* Features:
|
|
22
|
-
* - Model-specific type-safe provider options
|
|
23
|
-
* - Size / aspect-ratio validation per model
|
|
24
|
-
* - Number of images validation
|
|
25
|
-
*/
|
|
26
|
-
export declare class GrokImageAdapter<TModel extends GrokImageModel> extends BaseImageAdapter<TModel, GrokImageProviderOptions, GrokImageModelProviderOptionsByName, GrokImageModelSizeByName, GrokImageModelInputModalitiesByName> {
|
|
27
|
-
readonly kind: "image";
|
|
28
|
-
readonly name: "grok";
|
|
29
|
-
protected client: OpenAI;
|
|
30
|
-
private readonly clientConfig;
|
|
31
|
-
constructor(config: GrokImageConfig, model: TModel);
|
|
32
|
-
generateImages(options: ImageGenerationOptions<GrokImageProviderOptions>): Promise<ImageGenerationResult>;
|
|
33
|
-
/**
|
|
34
|
-
* Image-conditioned generation via xAI's Imagine API.
|
|
35
|
-
*
|
|
36
|
-
* The `/v1/images/edits` endpoint takes `application/json` (the OpenAI
|
|
37
|
-
* SDK's `images.edit()` sends `multipart/form-data`, which xAI rejects),
|
|
38
|
-
* so this path issues the request directly. One input is sent as
|
|
39
|
-
* `image: { url }`; multiple inputs (up to 3) as `images: [{ url }, ...]`,
|
|
40
|
-
* addressed by xAI in the order they are sent. The prompt text is sent
|
|
41
|
-
* verbatim — no referencing markers are injected.
|
|
42
|
-
*/
|
|
43
|
-
private editImages;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Creates a Grok image adapter with explicit API key.
|
|
47
|
-
* Type resolution happens here at the call site.
|
|
48
|
-
*
|
|
49
|
-
* @param model - The model name (e.g., 'grok-2-image-1212')
|
|
50
|
-
* @param apiKey - Your xAI API key
|
|
51
|
-
* @param config - Optional additional configuration
|
|
52
|
-
* @returns Configured Grok image adapter instance with resolved types
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* ```typescript
|
|
56
|
-
* const adapter = createGrokImage('grok-2-image-1212', "xai-...");
|
|
57
|
-
*
|
|
58
|
-
* const result = await generateImage({
|
|
59
|
-
* adapter,
|
|
60
|
-
* prompt: 'A cute baby sea otter'
|
|
61
|
-
* });
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
export declare function createGrokImage<TModel extends GrokImageModel>(model: TModel, apiKey: string, config?: Omit<GrokImageConfig, 'apiKey'>): GrokImageAdapter<TModel>;
|
|
65
|
-
/**
|
|
66
|
-
* Creates a Grok image adapter with automatic API key detection from environment variables.
|
|
67
|
-
* Type resolution happens here at the call site.
|
|
68
|
-
*
|
|
69
|
-
* Looks for `XAI_API_KEY` in:
|
|
70
|
-
* - `process.env` (Node.js)
|
|
71
|
-
* - `window.env` (Browser with injected env)
|
|
72
|
-
*
|
|
73
|
-
* @param model - The model name (e.g., 'grok-2-image-1212')
|
|
74
|
-
* @param config - Optional configuration (excluding apiKey which is auto-detected)
|
|
75
|
-
* @returns Configured Grok image adapter instance with resolved types
|
|
76
|
-
* @throws Error if XAI_API_KEY is not found in environment
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* ```typescript
|
|
80
|
-
* // Automatically uses XAI_API_KEY from environment
|
|
81
|
-
* const adapter = grokImage('grok-2-image-1212');
|
|
82
|
-
*
|
|
83
|
-
* const result = await generateImage({
|
|
84
|
-
* adapter,
|
|
85
|
-
* prompt: 'A beautiful sunset over mountains'
|
|
86
|
-
* });
|
|
87
|
-
* ```
|
|
88
|
-
*/
|
|
89
|
-
export declare function grokImage<TModel extends GrokImageModel>(model: TModel, config?: Omit<GrokImageConfig, 'apiKey'>): GrokImageAdapter<TModel>;
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import OpenAI from "openai";
|
|
2
|
-
import { resolveMediaPrompt } from "@tanstack/ai";
|
|
3
|
-
import { BaseImageAdapter } from "@tanstack/ai/adapters";
|
|
4
|
-
import { toRunErrorPayload } from "@tanstack/ai/adapter-internals";
|
|
5
|
-
import { buildImagesUsage } from "@tanstack/openai-base";
|
|
6
|
-
import { generateId } from "@tanstack/ai-utils";
|
|
7
|
-
import { withGrokDefaults, getGrokApiKeyFromEnv } from "../utils/client.js";
|
|
8
|
-
import { isGrokImagineImageModel, validatePrompt, validateImageSize, validateNumberOfImages, parseGrokImagineSize } from "../image/image-provider-options.js";
|
|
9
|
-
const MAX_EDIT_IMAGES = 3;
|
|
10
|
-
function imagineSizeParams(size) {
|
|
11
|
-
if (!size) return {};
|
|
12
|
-
const parsed = parseGrokImagineSize(size);
|
|
13
|
-
if (!parsed) return {};
|
|
14
|
-
return {
|
|
15
|
-
aspect_ratio: parsed.aspectRatio,
|
|
16
|
-
...parsed.resolution !== void 0 && { resolution: parsed.resolution }
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
function imagePartToUrl(part) {
|
|
20
|
-
if (part.source.type === "url") return part.source.value;
|
|
21
|
-
return `data:${part.source.mimeType};base64,${part.source.value}`;
|
|
22
|
-
}
|
|
23
|
-
class GrokImageAdapter extends BaseImageAdapter {
|
|
24
|
-
kind = "image";
|
|
25
|
-
name = "grok";
|
|
26
|
-
client;
|
|
27
|
-
clientConfig;
|
|
28
|
-
constructor(config, model) {
|
|
29
|
-
super(model, {});
|
|
30
|
-
this.clientConfig = withGrokDefaults(config);
|
|
31
|
-
this.client = new OpenAI(this.clientConfig);
|
|
32
|
-
}
|
|
33
|
-
async generateImages(options) {
|
|
34
|
-
const { model, numberOfImages, size, modelOptions } = options;
|
|
35
|
-
const resolved = resolveMediaPrompt(options.prompt);
|
|
36
|
-
const prompt = resolved.text;
|
|
37
|
-
if (resolved.videos.length > 0 || resolved.audios.length > 0) {
|
|
38
|
-
throw new Error(
|
|
39
|
-
`grok.generateImages does not support video / audio prompt parts on model ${model}.`
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
if (resolved.images.length > 0) {
|
|
43
|
-
if (!isGrokImagineImageModel(model)) {
|
|
44
|
-
throw new Error(
|
|
45
|
-
`grok: model "${model}" does not support image prompt parts. Image-conditioned generation requires an Imagine API model ('grok-imagine-image' or 'grok-imagine-image-quality').`
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
return await this.editImages(options, resolved);
|
|
49
|
-
}
|
|
50
|
-
validatePrompt({ prompt });
|
|
51
|
-
validateImageSize(model, size);
|
|
52
|
-
validateNumberOfImages(model, numberOfImages);
|
|
53
|
-
const isImagine = isGrokImagineImageModel(model);
|
|
54
|
-
const request = {
|
|
55
|
-
model,
|
|
56
|
-
prompt,
|
|
57
|
-
n: numberOfImages ?? 1,
|
|
58
|
-
...isImagine ? imagineSizeParams(size) : size !== void 0 && {
|
|
59
|
-
size
|
|
60
|
-
},
|
|
61
|
-
stream: false,
|
|
62
|
-
...modelOptions
|
|
63
|
-
};
|
|
64
|
-
try {
|
|
65
|
-
options.logger.request(
|
|
66
|
-
`activity=image provider=${this.name} model=${model} n=${request.n ?? 1} size=${request.size ?? "default"}`,
|
|
67
|
-
{ provider: this.name, model }
|
|
68
|
-
);
|
|
69
|
-
const response = await this.client.images.generate(request);
|
|
70
|
-
const images = (response.data ?? []).flatMap(
|
|
71
|
-
(item) => {
|
|
72
|
-
const revisedPrompt = item.revised_prompt;
|
|
73
|
-
if (item.b64_json) {
|
|
74
|
-
return [
|
|
75
|
-
{
|
|
76
|
-
b64Json: item.b64_json,
|
|
77
|
-
...revisedPrompt !== void 0 && { revisedPrompt }
|
|
78
|
-
}
|
|
79
|
-
];
|
|
80
|
-
}
|
|
81
|
-
if (item.url) {
|
|
82
|
-
return [
|
|
83
|
-
{
|
|
84
|
-
url: item.url,
|
|
85
|
-
...revisedPrompt !== void 0 && { revisedPrompt }
|
|
86
|
-
}
|
|
87
|
-
];
|
|
88
|
-
}
|
|
89
|
-
return [];
|
|
90
|
-
}
|
|
91
|
-
);
|
|
92
|
-
const usage = buildImagesUsage(response.usage);
|
|
93
|
-
return {
|
|
94
|
-
id: generateId(this.name),
|
|
95
|
-
model,
|
|
96
|
-
images,
|
|
97
|
-
...usage ? { usage } : {}
|
|
98
|
-
};
|
|
99
|
-
} catch (error) {
|
|
100
|
-
options.logger.errors(`${this.name}.generateImages fatal`, {
|
|
101
|
-
error: toRunErrorPayload(error, `${this.name}.generateImages failed`),
|
|
102
|
-
source: `${this.name}.generateImages`
|
|
103
|
-
});
|
|
104
|
-
throw error;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Image-conditioned generation via xAI's Imagine API.
|
|
109
|
-
*
|
|
110
|
-
* The `/v1/images/edits` endpoint takes `application/json` (the OpenAI
|
|
111
|
-
* SDK's `images.edit()` sends `multipart/form-data`, which xAI rejects),
|
|
112
|
-
* so this path issues the request directly. One input is sent as
|
|
113
|
-
* `image: { url }`; multiple inputs (up to 3) as `images: [{ url }, ...]`,
|
|
114
|
-
* addressed by xAI in the order they are sent. The prompt text is sent
|
|
115
|
-
* verbatim — no referencing markers are injected.
|
|
116
|
-
*/
|
|
117
|
-
async editImages(options, resolved) {
|
|
118
|
-
const { model, numberOfImages, size, modelOptions, logger } = options;
|
|
119
|
-
const prompt = resolved.text;
|
|
120
|
-
const imageInputs = resolved.images;
|
|
121
|
-
const unsupportedRole = imageInputs.find(
|
|
122
|
-
(part) => part.metadata?.role === "mask" || part.metadata?.role === "control"
|
|
123
|
-
);
|
|
124
|
-
if (unsupportedRole) {
|
|
125
|
-
throw new Error(
|
|
126
|
-
`grok: the Imagine API has no ${unsupportedRole.metadata?.role} input; only source/reference images are supported.`
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
if (imageInputs.length > MAX_EDIT_IMAGES) {
|
|
130
|
-
throw new Error(
|
|
131
|
-
`grok: model "${model}" accepts at most ${MAX_EDIT_IMAGES} source images; received ${imageInputs.length}.`
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
validatePrompt({ prompt });
|
|
135
|
-
validateImageSize(model, size);
|
|
136
|
-
validateNumberOfImages(model, numberOfImages);
|
|
137
|
-
const urls = imageInputs.map((part) => imagePartToUrl(part));
|
|
138
|
-
const request = {
|
|
139
|
-
model,
|
|
140
|
-
prompt,
|
|
141
|
-
...urls.length === 1 ? { image: { url: urls[0] } } : { images: urls.map((url) => ({ url })) },
|
|
142
|
-
...numberOfImages !== void 0 && { n: numberOfImages },
|
|
143
|
-
...imagineSizeParams(size),
|
|
144
|
-
...modelOptions
|
|
145
|
-
};
|
|
146
|
-
try {
|
|
147
|
-
logger.request(
|
|
148
|
-
`activity=image provider=${this.name} model=${model} edit images=${urls.length}`,
|
|
149
|
-
{ provider: this.name, model }
|
|
150
|
-
);
|
|
151
|
-
const response = await fetch(
|
|
152
|
-
`${this.clientConfig.baseURL}/images/edits`,
|
|
153
|
-
{
|
|
154
|
-
method: "POST",
|
|
155
|
-
headers: {
|
|
156
|
-
"Content-Type": "application/json",
|
|
157
|
-
Authorization: `Bearer ${this.clientConfig.apiKey}`
|
|
158
|
-
},
|
|
159
|
-
body: JSON.stringify(request)
|
|
160
|
-
}
|
|
161
|
-
);
|
|
162
|
-
if (!response.ok) {
|
|
163
|
-
const body = await response.text();
|
|
164
|
-
throw new Error(
|
|
165
|
-
`grok: image edit request failed (${response.status} ${response.statusText}): ${body}`
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
const result = await response.json();
|
|
169
|
-
const images = (result.data ?? []).flatMap(
|
|
170
|
-
(item) => {
|
|
171
|
-
if (item.b64_json) return [{ b64Json: item.b64_json }];
|
|
172
|
-
if (item.url) return [{ url: item.url }];
|
|
173
|
-
return [];
|
|
174
|
-
}
|
|
175
|
-
);
|
|
176
|
-
if (images.length === 0) {
|
|
177
|
-
throw new Error("grok: image edit response contained no images");
|
|
178
|
-
}
|
|
179
|
-
return {
|
|
180
|
-
id: generateId(this.name),
|
|
181
|
-
model,
|
|
182
|
-
images
|
|
183
|
-
};
|
|
184
|
-
} catch (error) {
|
|
185
|
-
logger.errors(`${this.name}.generateImages fatal`, {
|
|
186
|
-
error: toRunErrorPayload(error, `${this.name}.generateImages failed`),
|
|
187
|
-
source: `${this.name}.generateImages`
|
|
188
|
-
});
|
|
189
|
-
throw error;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
function createGrokImage(model, apiKey, config) {
|
|
194
|
-
return new GrokImageAdapter({ apiKey, ...config }, model);
|
|
195
|
-
}
|
|
196
|
-
function grokImage(model, config) {
|
|
197
|
-
const apiKey = getGrokApiKeyFromEnv();
|
|
198
|
-
return createGrokImage(model, apiKey, config);
|
|
199
|
-
}
|
|
200
|
-
export {
|
|
201
|
-
GrokImageAdapter,
|
|
202
|
-
createGrokImage,
|
|
203
|
-
grokImage
|
|
204
|
-
};
|
|
205
|
-
//# sourceMappingURL=image.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"image.js","sources":["../../../src/adapters/image.ts"],"sourcesContent":["import OpenAI from 'openai'\nimport { resolveMediaPrompt } from '@tanstack/ai'\nimport { BaseImageAdapter } from '@tanstack/ai/adapters'\nimport { toRunErrorPayload } from '@tanstack/ai/adapter-internals'\nimport { buildImagesUsage } from '@tanstack/openai-base'\nimport { generateId } from '@tanstack/ai-utils'\nimport { getGrokApiKeyFromEnv, withGrokDefaults } from '../utils/client'\nimport {\n isGrokImagineImageModel,\n parseGrokImagineSize,\n validateImageSize,\n validateNumberOfImages,\n validatePrompt,\n} from '../image/image-provider-options'\nimport type {\n GeneratedImage,\n ImageGenerationOptions,\n ImageGenerationResult,\n ImagePart,\n MediaInputMetadata,\n ResolvedMediaPrompt,\n} from '@tanstack/ai'\nimport type OpenAI_SDK from 'openai'\nimport type { GrokImageModel } from '../model-meta'\nimport type {\n GrokImageModelInputModalitiesByName,\n GrokImageModelProviderOptionsByName,\n GrokImageModelSizeByName,\n GrokImageProviderOptions,\n} from '../image/image-provider-options'\nimport type { GrokClientConfig } from '../utils'\n\n/**\n * Configuration for Grok image adapter\n */\nexport interface GrokImageConfig extends GrokClientConfig {}\n\n/** Maximum source images accepted by xAI's image edit endpoint. */\nconst MAX_EDIT_IMAGES = 3\n\n/**\n * Maps the generic `size` option onto Imagine API parameters: the\n * \"aspectRatio_resolution\" template (\"16:9_2k\") splits into `aspect_ratio`\n * and optional `resolution` request fields.\n */\nfunction imagineSizeParams(size: string | undefined): {\n aspect_ratio?: string\n resolution?: string\n} {\n if (!size) return {}\n const parsed = parseGrokImagineSize(size)\n if (!parsed) return {}\n return {\n aspect_ratio: parsed.aspectRatio,\n ...(parsed.resolution !== undefined && { resolution: parsed.resolution }),\n }\n}\n\n/**\n * Convert a TanStack ImagePart to the URL string accepted by xAI's edit\n * endpoint: public URLs pass through (fetched by xAI's servers), data\n * sources become base64 data URIs.\n */\nfunction imagePartToUrl(part: ImagePart<MediaInputMetadata>): string {\n if (part.source.type === 'url') return part.source.value\n return `data:${part.source.mimeType};base64,${part.source.value}`\n}\n\n/** Response shape of xAI's `/v1/images/edits` endpoint. */\ninterface GrokImageEditResponse {\n data?: Array<{\n url?: string | null\n b64_json?: string | null\n mime_type?: string\n }>\n}\n\n/**\n * Grok Image Generation Adapter\n *\n * Tree-shakeable adapter for Grok image generation functionality.\n * Supports the legacy grok-2-image-1212 model (text-to-image via the\n * OpenAI-compat endpoint) and the grok-imagine image models, which also\n * accept image prompt parts for image-conditioned generation via xAI's\n * `/v1/images/edits` endpoint (up to 3 source images).\n *\n * Features:\n * - Model-specific type-safe provider options\n * - Size / aspect-ratio validation per model\n * - Number of images validation\n */\nexport class GrokImageAdapter<\n TModel extends GrokImageModel,\n> extends BaseImageAdapter<\n TModel,\n GrokImageProviderOptions,\n GrokImageModelProviderOptionsByName,\n GrokImageModelSizeByName,\n GrokImageModelInputModalitiesByName\n> {\n override readonly kind = 'image' as const\n readonly name = 'grok' as const\n\n protected client: OpenAI\n private readonly clientConfig: GrokImageConfig\n\n constructor(config: GrokImageConfig, model: TModel) {\n super(model, {})\n this.clientConfig = withGrokDefaults(config)\n this.client = new OpenAI(this.clientConfig)\n }\n\n async generateImages(\n options: ImageGenerationOptions<GrokImageProviderOptions>,\n ): Promise<ImageGenerationResult> {\n const { model, numberOfImages, size, modelOptions } = options\n\n const resolved = resolveMediaPrompt(options.prompt)\n const prompt = resolved.text\n\n if (resolved.videos.length > 0 || resolved.audios.length > 0) {\n throw new Error(\n `grok.generateImages does not support video / audio prompt parts on model ${model}.`,\n )\n }\n\n if (resolved.images.length > 0) {\n if (!isGrokImagineImageModel(model)) {\n throw new Error(\n `grok: model \"${model}\" does not support image prompt parts. ` +\n `Image-conditioned generation requires an Imagine API model ` +\n `('grok-imagine-image' or 'grok-imagine-image-quality').`,\n )\n }\n return await this.editImages(options, resolved)\n }\n\n validatePrompt({ prompt, model })\n validateImageSize(model, size)\n validateNumberOfImages(model, numberOfImages)\n\n // grok-imagine models are aspect-ratio sized: the generic `size` option\n // carries an \"aspectRatio_resolution\" template (e.g. '16:9_2k', like\n // Gemini native image models) and maps to the Imagine API's\n // `aspect_ratio` / `resolution` parameters instead of OpenAI-style `size`.\n const isImagine = isGrokImagineImageModel(model)\n const request = {\n model,\n prompt,\n n: numberOfImages ?? 1,\n ...(isImagine\n ? imagineSizeParams(size)\n : size !== undefined && {\n size: size,\n }),\n stream: false,\n ...modelOptions,\n } as OpenAI_SDK.Images.ImageGenerateParamsNonStreaming\n\n try {\n options.logger.request(\n `activity=image provider=${this.name} model=${model} n=${request.n ?? 1} size=${request.size ?? 'default'}`,\n { provider: this.name, model },\n )\n const response = await this.client.images.generate(request)\n\n const images: Array<GeneratedImage> = (response.data ?? []).flatMap(\n (item): Array<GeneratedImage> => {\n const revisedPrompt = item.revised_prompt\n if (item.b64_json) {\n return [\n {\n b64Json: item.b64_json,\n ...(revisedPrompt !== undefined && { revisedPrompt }),\n },\n ]\n }\n if (item.url) {\n return [\n {\n url: item.url,\n ...(revisedPrompt !== undefined && { revisedPrompt }),\n },\n ]\n }\n return []\n },\n )\n\n const usage = buildImagesUsage(response.usage)\n\n return {\n id: generateId(this.name),\n model,\n images,\n ...(usage ? { usage } : {}),\n }\n } catch (error: unknown) {\n options.logger.errors(`${this.name}.generateImages fatal`, {\n error: toRunErrorPayload(error, `${this.name}.generateImages failed`),\n source: `${this.name}.generateImages`,\n })\n throw error\n }\n }\n\n /**\n * Image-conditioned generation via xAI's Imagine API.\n *\n * The `/v1/images/edits` endpoint takes `application/json` (the OpenAI\n * SDK's `images.edit()` sends `multipart/form-data`, which xAI rejects),\n * so this path issues the request directly. One input is sent as\n * `image: { url }`; multiple inputs (up to 3) as `images: [{ url }, ...]`,\n * addressed by xAI in the order they are sent. The prompt text is sent\n * verbatim — no referencing markers are injected.\n */\n private async editImages(\n options: ImageGenerationOptions<GrokImageProviderOptions>,\n resolved: ResolvedMediaPrompt,\n ): Promise<ImageGenerationResult> {\n const { model, numberOfImages, size, modelOptions, logger } = options\n const prompt = resolved.text\n const imageInputs = resolved.images\n\n const unsupportedRole = imageInputs.find(\n (part) =>\n part.metadata?.role === 'mask' || part.metadata?.role === 'control',\n )\n if (unsupportedRole) {\n throw new Error(\n `grok: the Imagine API has no ${unsupportedRole.metadata?.role} input; ` +\n `only source/reference images are supported.`,\n )\n }\n if (imageInputs.length > MAX_EDIT_IMAGES) {\n throw new Error(\n `grok: model \"${model}\" accepts at most ${MAX_EDIT_IMAGES} source images; received ${imageInputs.length}.`,\n )\n }\n\n validatePrompt({ prompt, model })\n validateImageSize(model, size)\n validateNumberOfImages(model, numberOfImages)\n\n const urls = imageInputs.map((part) => imagePartToUrl(part))\n const request: Record<string, unknown> = {\n model,\n prompt,\n ...(urls.length === 1\n ? { image: { url: urls[0] } }\n : { images: urls.map((url) => ({ url })) }),\n ...(numberOfImages !== undefined && { n: numberOfImages }),\n ...imagineSizeParams(size),\n ...modelOptions,\n }\n\n try {\n logger.request(\n `activity=image provider=${this.name} model=${model} edit images=${urls.length}`,\n { provider: this.name, model },\n )\n\n const response = await fetch(\n `${this.clientConfig.baseURL}/images/edits`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.clientConfig.apiKey}`,\n },\n body: JSON.stringify(request),\n },\n )\n if (!response.ok) {\n const body = await response.text()\n throw new Error(\n `grok: image edit request failed (${response.status} ${response.statusText}): ${body}`,\n )\n }\n\n const result = (await response.json()) as GrokImageEditResponse\n const images: Array<GeneratedImage> = (result.data ?? []).flatMap(\n (item): Array<GeneratedImage> => {\n if (item.b64_json) return [{ b64Json: item.b64_json }]\n if (item.url) return [{ url: item.url }]\n return []\n },\n )\n if (images.length === 0) {\n throw new Error('grok: image edit response contained no images')\n }\n\n return {\n id: generateId(this.name),\n model,\n images,\n }\n } catch (error: unknown) {\n logger.errors(`${this.name}.generateImages fatal`, {\n error: toRunErrorPayload(error, `${this.name}.generateImages failed`),\n source: `${this.name}.generateImages`,\n })\n throw error\n }\n }\n}\n\n/**\n * Creates a Grok image adapter with explicit API key.\n * Type resolution happens here at the call site.\n *\n * @param model - The model name (e.g., 'grok-2-image-1212')\n * @param apiKey - Your xAI API key\n * @param config - Optional additional configuration\n * @returns Configured Grok image adapter instance with resolved types\n *\n * @example\n * ```typescript\n * const adapter = createGrokImage('grok-2-image-1212', \"xai-...\");\n *\n * const result = await generateImage({\n * adapter,\n * prompt: 'A cute baby sea otter'\n * });\n * ```\n */\nexport function createGrokImage<TModel extends GrokImageModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<GrokImageConfig, 'apiKey'>,\n): GrokImageAdapter<TModel> {\n return new GrokImageAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Grok image 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-2-image-1212')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Grok image 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 = grokImage('grok-2-image-1212');\n *\n * const result = await generateImage({\n * adapter,\n * prompt: 'A beautiful sunset over mountains'\n * });\n * ```\n */\nexport function grokImage<TModel extends GrokImageModel>(\n model: TModel,\n config?: Omit<GrokImageConfig, 'apiKey'>,\n): GrokImageAdapter<TModel> {\n const apiKey = getGrokApiKeyFromEnv()\n return createGrokImage(model, apiKey, config)\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { ChatStreamSummarizeAdapter, InferTextProviderOptions } from '@tanstack/ai/adapters';
|
|
2
|
-
import { GrokTextAdapter } from './text.js';
|
|
3
|
-
import { GROK_CHAT_MODELS } from '../model-meta.js';
|
|
4
|
-
import { GrokClientConfig } from '../utils.js';
|
|
5
|
-
/**
|
|
6
|
-
* Configuration for Grok summarize adapter
|
|
7
|
-
*/
|
|
8
|
-
export interface GrokSummarizeConfig extends GrokClientConfig {
|
|
9
|
-
}
|
|
10
|
-
/** Model type for Grok summarization */
|
|
11
|
-
export type GrokSummarizeModel = (typeof GROK_CHAT_MODELS)[number];
|
|
12
|
-
/**
|
|
13
|
-
* Creates a Grok summarize adapter with explicit API key.
|
|
14
|
-
* Type resolution happens here at the call site.
|
|
15
|
-
*
|
|
16
|
-
* @param model - The model name (e.g., 'grok-build-0.1')
|
|
17
|
-
* @param apiKey - Your xAI API key
|
|
18
|
-
* @param config - Optional additional configuration
|
|
19
|
-
* @returns Configured Grok summarize adapter instance with resolved types
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```typescript
|
|
23
|
-
* const adapter = createGrokSummarize('grok-build-0.1', "xai-...");
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
export declare function createGrokSummarize<TModel extends GrokSummarizeModel>(model: TModel, apiKey: string, config?: Omit<GrokSummarizeConfig, 'apiKey'>): ChatStreamSummarizeAdapter<TModel, InferTextProviderOptions<GrokTextAdapter<TModel>>>;
|
|
27
|
-
/**
|
|
28
|
-
* Creates a Grok summarize adapter with automatic API key detection from environment variables.
|
|
29
|
-
* Type resolution happens here at the call site.
|
|
30
|
-
*
|
|
31
|
-
* Looks for `XAI_API_KEY` in:
|
|
32
|
-
* - `process.env` (Node.js)
|
|
33
|
-
* - `window.env` (Browser with injected env)
|
|
34
|
-
*
|
|
35
|
-
* @param model - The model name (e.g., 'grok-build-0.1')
|
|
36
|
-
* @param config - Optional configuration (excluding apiKey which is auto-detected)
|
|
37
|
-
* @returns Configured Grok summarize adapter instance with resolved types
|
|
38
|
-
* @throws Error if XAI_API_KEY is not found in environment
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* ```typescript
|
|
42
|
-
* // Automatically uses XAI_API_KEY from environment
|
|
43
|
-
* const adapter = grokSummarize('grok-build-0.1');
|
|
44
|
-
*
|
|
45
|
-
* await summarize({
|
|
46
|
-
* adapter,
|
|
47
|
-
* text: "Long article text..."
|
|
48
|
-
* });
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
export declare function grokSummarize<TModel extends GrokSummarizeModel>(model: TModel, config?: Omit<GrokSummarizeConfig, 'apiKey'>): ChatStreamSummarizeAdapter<TModel, InferTextProviderOptions<GrokTextAdapter<TModel>>>;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { ChatStreamSummarizeAdapter } from "@tanstack/ai/adapters";
|
|
2
|
-
import "@tanstack/ai-utils";
|
|
3
|
-
import { getGrokApiKeyFromEnv } from "../utils/client.js";
|
|
4
|
-
import "@tanstack/openai-base";
|
|
5
|
-
import { GrokTextAdapter } from "./text.js";
|
|
6
|
-
function createGrokSummarize(model, apiKey, config) {
|
|
7
|
-
return new ChatStreamSummarizeAdapter(
|
|
8
|
-
new GrokTextAdapter({ apiKey, ...config }, model),
|
|
9
|
-
model,
|
|
10
|
-
"grok"
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
function grokSummarize(model, config) {
|
|
14
|
-
return createGrokSummarize(model, getGrokApiKeyFromEnv(), config);
|
|
15
|
-
}
|
|
16
|
-
export {
|
|
17
|
-
createGrokSummarize,
|
|
18
|
-
grokSummarize
|
|
19
|
-
};
|
|
20
|
-
//# sourceMappingURL=summarize.js.map
|
|
@@ -1 +0,0 @@
|
|
|
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,76 +0,0 @@
|
|
|
1
|
-
import { OpenAIBaseResponsesTextAdapter } from '@tanstack/openai-base';
|
|
2
|
-
import { GROK_CHAT_MODELS, GrokChatModelToolCapabilitiesByName, ResolveInputModalities, ResolveProviderOptions } from '../model-meta.js';
|
|
3
|
-
import { Modality, TextOptions } from '@tanstack/ai';
|
|
4
|
-
import { GrokMessageMetadataByModality } from '../message-types.js';
|
|
5
|
-
import { GrokClientConfig } from '../utils.js';
|
|
6
|
-
import { ResponseCreateParams } from 'openai/resources/responses/responses';
|
|
7
|
-
/**
|
|
8
|
-
* Resolve tool capabilities for a specific Grok model.
|
|
9
|
-
*/
|
|
10
|
-
type ResolveToolCapabilities<TModel extends string> = TModel extends keyof GrokChatModelToolCapabilitiesByName ? NonNullable<GrokChatModelToolCapabilitiesByName[TModel]> : readonly [];
|
|
11
|
-
/**
|
|
12
|
-
* Configuration for Grok text adapter
|
|
13
|
-
*/
|
|
14
|
-
export interface GrokTextConfig extends GrokClientConfig {
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Alias for TextProviderOptions for external use
|
|
18
|
-
*/
|
|
19
|
-
export type { ExternalTextProviderOptions as GrokTextProviderOptions } from '../text/text-provider-options.js';
|
|
20
|
-
/**
|
|
21
|
-
* Grok Text (Chat) Adapter
|
|
22
|
-
*
|
|
23
|
-
* Tree-shakeable adapter for Grok chat/text completion functionality.
|
|
24
|
-
* Uses xAI's OpenAI-compatible Responses API.
|
|
25
|
-
*
|
|
26
|
-
* Delegates implementation to {@link OpenAIBaseResponsesTextAdapter}
|
|
27
|
-
* from `@tanstack/openai-base` and threads Grok-specific tool-capability
|
|
28
|
-
* typing through the 5th generic of the base class.
|
|
29
|
-
*/
|
|
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
|
-
readonly kind: "text";
|
|
32
|
-
readonly name: "grok";
|
|
33
|
-
constructor(config: GrokTextConfig, model: TModel);
|
|
34
|
-
protected mapOptionsToRequest(options: TextOptions<TProviderOptions>): Omit<ResponseCreateParams, 'stream'>;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Creates a Grok text adapter with explicit API key.
|
|
38
|
-
* Type resolution happens here at the call site.
|
|
39
|
-
*
|
|
40
|
-
* @param model - The model name (e.g., 'grok-build-0.1')
|
|
41
|
-
* @param apiKey - Your xAI API key
|
|
42
|
-
* @param config - Optional additional configuration
|
|
43
|
-
* @returns Configured Grok text adapter instance with resolved types
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* ```typescript
|
|
47
|
-
* const adapter = createGrokText('grok-build-0.1', "xai-...");
|
|
48
|
-
* // adapter has type-safe providerOptions for grok-build-0.1
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
export declare function createGrokText<TModel extends (typeof GROK_CHAT_MODELS)[number]>(model: TModel, apiKey: string, config?: Omit<GrokTextConfig, 'apiKey'>): GrokTextAdapter<TModel>;
|
|
52
|
-
/**
|
|
53
|
-
* Creates a Grok text adapter with automatic API key detection from environment variables.
|
|
54
|
-
* Type resolution happens here at the call site.
|
|
55
|
-
*
|
|
56
|
-
* Looks for `XAI_API_KEY` in:
|
|
57
|
-
* - `process.env` (Node.js)
|
|
58
|
-
* - `window.env` (Browser with injected env)
|
|
59
|
-
*
|
|
60
|
-
* @param model - The model name (e.g., 'grok-build-0.1')
|
|
61
|
-
* @param config - Optional configuration (excluding apiKey which is auto-detected)
|
|
62
|
-
* @returns Configured Grok text adapter instance with resolved types
|
|
63
|
-
* @throws Error if XAI_API_KEY is not found in environment
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* ```typescript
|
|
67
|
-
* // Automatically uses XAI_API_KEY from environment
|
|
68
|
-
* const adapter = grokText('grok-build-0.1');
|
|
69
|
-
*
|
|
70
|
-
* const stream = chat({
|
|
71
|
-
* adapter,
|
|
72
|
-
* messages: [{ role: "user", content: "Hello!" }]
|
|
73
|
-
* });
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
export declare function grokText<TModel extends (typeof GROK_CHAT_MODELS)[number]>(model: TModel, config?: Omit<GrokTextConfig, 'apiKey'>): GrokTextAdapter<TModel>;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import OpenAI from "openai";
|
|
2
|
-
import { OpenAIBaseResponsesTextAdapter } from "@tanstack/openai-base";
|
|
3
|
-
import { withGrokDefaults, getGrokApiKeyFromEnv } from "../utils/client.js";
|
|
4
|
-
import { convertToolsToProviderFormat } from "../tools/index.js";
|
|
5
|
-
class GrokTextAdapter extends OpenAIBaseResponsesTextAdapter {
|
|
6
|
-
kind = "text";
|
|
7
|
-
name = "grok";
|
|
8
|
-
constructor(config, model) {
|
|
9
|
-
super(model, "grok", new OpenAI(withGrokDefaults(config)));
|
|
10
|
-
}
|
|
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
|
-
);
|
|
20
|
-
}
|
|
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
|
-
};
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function createGrokText(model, apiKey, config) {
|
|
33
|
-
return new GrokTextAdapter({ apiKey, ...config }, model);
|
|
34
|
-
}
|
|
35
|
-
function grokText(model, config) {
|
|
36
|
-
const apiKey = getGrokApiKeyFromEnv();
|
|
37
|
-
return createGrokText(model, apiKey, config);
|
|
38
|
-
}
|
|
39
|
-
export {
|
|
40
|
-
GrokTextAdapter,
|
|
41
|
-
createGrokText,
|
|
42
|
-
grokText
|
|
43
|
-
};
|
|
44
|
-
//# sourceMappingURL=text.js.map
|
|
@@ -1 +0,0 @@
|
|
|
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;"}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { BaseTranscriptionAdapter } from '@tanstack/ai/adapters';
|
|
2
|
-
import { TranscriptionOptions, TranscriptionResult, TranscriptionWord } from '@tanstack/ai';
|
|
3
|
-
import { GrokTranscriptionModel } from '../model-meta.js';
|
|
4
|
-
import { GrokTranscriptionProviderOptions } from '../audio/transcription-provider-options.js';
|
|
5
|
-
/**
|
|
6
|
-
* Grok-specific extension of `TranscriptionWord` that surfaces the extra
|
|
7
|
-
* fields xAI returns when diarization / confidence are enabled. The base
|
|
8
|
-
* cross-provider `TranscriptionWord` contract doesn't include these, so
|
|
9
|
-
* callers who know they're using Grok can narrow with:
|
|
10
|
-
*
|
|
11
|
-
* ```ts
|
|
12
|
-
* const words = result.words as Array<GrokTranscriptionWord> | undefined
|
|
13
|
-
* ```
|
|
14
|
-
*/
|
|
15
|
-
export interface GrokTranscriptionWord extends TranscriptionWord {
|
|
16
|
-
/** Model confidence for the word, when xAI returns one. */
|
|
17
|
-
confidence?: number;
|
|
18
|
-
/** Speaker index, populated when `modelOptions.diarize === true`. */
|
|
19
|
-
speaker?: number;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Configuration for the Grok transcription adapter.
|
|
23
|
-
*
|
|
24
|
-
* Uses direct `fetch` rather than the OpenAI SDK because xAI's `/v1/stt`
|
|
25
|
-
* endpoint is not OpenAI-compatible.
|
|
26
|
-
*/
|
|
27
|
-
export interface GrokTranscriptionConfig {
|
|
28
|
-
apiKey: string;
|
|
29
|
-
baseURL?: string;
|
|
30
|
-
/** Additional headers to merge into every request (e.g., test IDs). */
|
|
31
|
-
defaultHeaders?: Record<string, string>;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Grok Speech-to-Text Adapter.
|
|
35
|
-
*
|
|
36
|
-
* Talks to `POST {baseURL}/stt` per
|
|
37
|
-
* https://docs.x.ai/developers/rest-api-reference/inference/voice
|
|
38
|
-
*/
|
|
39
|
-
export declare class GrokTranscriptionAdapter<TModel extends GrokTranscriptionModel> extends BaseTranscriptionAdapter<TModel, GrokTranscriptionProviderOptions> {
|
|
40
|
-
readonly name: "grok";
|
|
41
|
-
private readonly apiKey;
|
|
42
|
-
private readonly baseURL;
|
|
43
|
-
private readonly defaultHeaders;
|
|
44
|
-
constructor(config: GrokTranscriptionConfig, model: TModel);
|
|
45
|
-
transcribe(options: TranscriptionOptions<GrokTranscriptionProviderOptions>): Promise<TranscriptionResult>;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Build the multipart/form-data body for `POST /v1/stt`, coercing SDK-level
|
|
49
|
-
* model options into xAI's wire format (booleans as `'true'`/`'false'`
|
|
50
|
-
* strings, numeric fields stringified, etc.).
|
|
51
|
-
*
|
|
52
|
-
* Wire-field mapping:
|
|
53
|
-
* - `modelOptions.inverse_text_normalization` → `format` (xAI's chosen
|
|
54
|
-
* wire-field name for the ITN boolean; the SDK surfaces it under the
|
|
55
|
-
* clearer `inverse_text_normalization` key).
|
|
56
|
-
* - `modelOptions.audio_format`, `sample_rate`, `multichannel`, `channels`,
|
|
57
|
-
* `diarize` map to same-named form fields.
|
|
58
|
-
*/
|
|
59
|
-
export declare function buildTranscriptionFormData(options: {
|
|
60
|
-
file: File;
|
|
61
|
-
language: string | undefined;
|
|
62
|
-
modelOptions: GrokTranscriptionProviderOptions | undefined;
|
|
63
|
-
}): FormData;
|
|
64
|
-
/**
|
|
65
|
-
* Creates a Grok transcription adapter with an explicit API key.
|
|
66
|
-
*
|
|
67
|
-
* @example
|
|
68
|
-
* ```typescript
|
|
69
|
-
* const adapter = createGrokTranscription('grok-stt', 'xai-...')
|
|
70
|
-
* const result = await generateTranscription({
|
|
71
|
-
* adapter,
|
|
72
|
-
* audio: audioFile,
|
|
73
|
-
* language: 'en',
|
|
74
|
-
* })
|
|
75
|
-
* ```
|
|
76
|
-
*/
|
|
77
|
-
export declare function createGrokTranscription<TModel extends GrokTranscriptionModel>(model: TModel, apiKey: string, config?: Omit<GrokTranscriptionConfig, 'apiKey'>): GrokTranscriptionAdapter<TModel>;
|
|
78
|
-
/**
|
|
79
|
-
* Creates a Grok transcription adapter, reading the API key from
|
|
80
|
-
* `XAI_API_KEY` in the environment.
|
|
81
|
-
*
|
|
82
|
-
* @throws Error if `XAI_API_KEY` is not set.
|
|
83
|
-
*/
|
|
84
|
-
export declare function grokTranscription<TModel extends GrokTranscriptionModel>(model: TModel, config?: Omit<GrokTranscriptionConfig, 'apiKey'>): GrokTranscriptionAdapter<TModel>;
|