@tanstack/ai-grok 0.0.1 → 0.1.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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +113 -28
  3. package/dist/esm/adapters/image.d.ts +77 -0
  4. package/dist/esm/adapters/image.js +63 -0
  5. package/dist/esm/adapters/image.js.map +1 -0
  6. package/dist/esm/adapters/summarize.d.ts +75 -0
  7. package/dist/esm/adapters/summarize.js +81 -0
  8. package/dist/esm/adapters/summarize.js.map +1 -0
  9. package/dist/esm/adapters/text.d.ts +96 -0
  10. package/dist/esm/adapters/text.js +300 -0
  11. package/dist/esm/adapters/text.js.map +1 -0
  12. package/dist/esm/image/image-provider-options.d.ts +66 -0
  13. package/dist/esm/image/image-provider-options.js +39 -0
  14. package/dist/esm/image/image-provider-options.js.map +1 -0
  15. package/dist/esm/index.d.ts +7 -0
  16. package/dist/esm/index.js +18 -0
  17. package/dist/esm/index.js.map +1 -0
  18. package/dist/esm/message-types.d.ts +64 -0
  19. package/dist/esm/model-meta.d.ts +223 -0
  20. package/dist/esm/model-meta.js +47 -0
  21. package/dist/esm/model-meta.js.map +1 -0
  22. package/dist/esm/text/text-provider-options.d.ts +66 -0
  23. package/dist/esm/text/text-provider-options.js +6 -0
  24. package/dist/esm/text/text-provider-options.js.map +1 -0
  25. package/dist/esm/tools/function-tool.d.ts +15 -0
  26. package/dist/esm/tools/function-tool.js +27 -0
  27. package/dist/esm/tools/function-tool.js.map +1 -0
  28. package/dist/esm/tools/index.d.ts +2 -0
  29. package/dist/esm/tools/tool-converter.d.ts +7 -0
  30. package/dist/esm/tools/tool-converter.js +10 -0
  31. package/dist/esm/tools/tool-converter.js.map +1 -0
  32. package/dist/esm/utils/client.d.ts +18 -0
  33. package/dist/esm/utils/client.js +26 -0
  34. package/dist/esm/utils/client.js.map +1 -0
  35. package/dist/esm/utils/index.d.ts +2 -0
  36. package/dist/esm/utils/schema-converter.d.ts +24 -0
  37. package/dist/esm/utils/schema-converter.js +71 -0
  38. package/dist/esm/utils/schema-converter.js.map +1 -0
  39. package/package.json +50 -7
  40. package/src/adapters/image.ts +176 -0
  41. package/src/adapters/summarize.ts +174 -0
  42. package/src/adapters/text.ts +506 -0
  43. package/src/image/image-provider-options.ts +118 -0
  44. package/src/index.ts +55 -0
  45. package/src/message-types.ts +67 -0
  46. package/src/model-meta.ts +298 -0
  47. package/src/text/text-provider-options.ts +77 -0
  48. package/src/tools/function-tool.ts +45 -0
  49. package/src/tools/index.ts +5 -0
  50. package/src/tools/tool-converter.ts +17 -0
  51. package/src/utils/client.ts +45 -0
  52. package/src/utils/index.ts +10 -0
  53. package/src/utils/schema-converter.ts +110 -0
@@ -0,0 +1,506 @@
1
+ import { BaseTextAdapter } from '@tanstack/ai/adapters'
2
+ import { validateTextProviderOptions } from '../text/text-provider-options'
3
+ import { convertToolsToProviderFormat } from '../tools'
4
+ import {
5
+ createGrokClient,
6
+ generateId,
7
+ getGrokApiKeyFromEnv,
8
+ makeGrokStructuredOutputCompatible,
9
+ transformNullsToUndefined,
10
+ } from '../utils'
11
+ import type {
12
+ GROK_CHAT_MODELS,
13
+ ResolveInputModalities,
14
+ ResolveProviderOptions,
15
+ } from '../model-meta'
16
+ import type {
17
+ StructuredOutputOptions,
18
+ StructuredOutputResult,
19
+ } from '@tanstack/ai/adapters'
20
+ import type OpenAI_SDK from 'openai'
21
+ import type {
22
+ ContentPart,
23
+ ModelMessage,
24
+ StreamChunk,
25
+ TextOptions,
26
+ } from '@tanstack/ai'
27
+ import type { InternalTextProviderOptions } from '../text/text-provider-options'
28
+ import type {
29
+ GrokImageMetadata,
30
+ GrokMessageMetadataByModality,
31
+ } from '../message-types'
32
+ import type { GrokClientConfig } from '../utils'
33
+
34
+ /**
35
+ * Configuration for Grok text adapter
36
+ */
37
+ export interface GrokTextConfig extends GrokClientConfig {}
38
+
39
+ /**
40
+ * Alias for TextProviderOptions for external use
41
+ */
42
+ export type { ExternalTextProviderOptions as GrokTextProviderOptions } from '../text/text-provider-options'
43
+
44
+ /**
45
+ * Grok Text (Chat) Adapter
46
+ *
47
+ * Tree-shakeable adapter for Grok chat/text completion functionality.
48
+ * Uses OpenAI-compatible Chat Completions API (not Responses API).
49
+ */
50
+ export class GrokTextAdapter<
51
+ TModel extends (typeof GROK_CHAT_MODELS)[number],
52
+ > extends BaseTextAdapter<
53
+ TModel,
54
+ ResolveProviderOptions<TModel>,
55
+ ResolveInputModalities<TModel>,
56
+ GrokMessageMetadataByModality
57
+ > {
58
+ readonly kind = 'text' as const
59
+ readonly name = 'grok' as const
60
+
61
+ private client: OpenAI_SDK
62
+
63
+ constructor(config: GrokTextConfig, model: TModel) {
64
+ super({}, model)
65
+ this.client = createGrokClient(config)
66
+ }
67
+
68
+ async *chatStream(
69
+ options: TextOptions<ResolveProviderOptions<TModel>>,
70
+ ): AsyncIterable<StreamChunk> {
71
+ const requestParams = this.mapTextOptionsToGrok(options)
72
+
73
+ try {
74
+ const stream = await this.client.chat.completions.create({
75
+ ...requestParams,
76
+ stream: true,
77
+ })
78
+
79
+ yield* this.processGrokStreamChunks(stream, options)
80
+ } catch (error: unknown) {
81
+ const err = error as Error
82
+ console.error('>>> chatStream: Fatal error during response creation <<<')
83
+ console.error('>>> Error message:', err.message)
84
+ console.error('>>> Error stack:', err.stack)
85
+ console.error('>>> Full error:', err)
86
+ throw error
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Generate structured output using Grok's JSON Schema response format.
92
+ * Uses stream: false to get the complete response in one call.
93
+ *
94
+ * Grok has strict requirements for structured output (via OpenAI-compatible API):
95
+ * - All properties must be in the `required` array
96
+ * - Optional fields should have null added to their type union
97
+ * - additionalProperties must be false for all objects
98
+ *
99
+ * The outputSchema is already JSON Schema (converted in the ai layer).
100
+ * We apply Grok-specific transformations for structured output compatibility.
101
+ */
102
+ async structuredOutput(
103
+ options: StructuredOutputOptions<ResolveProviderOptions<TModel>>,
104
+ ): Promise<StructuredOutputResult<unknown>> {
105
+ const { chatOptions, outputSchema } = options
106
+ const requestParams = this.mapTextOptionsToGrok(chatOptions)
107
+
108
+ // Apply Grok-specific transformations for structured output compatibility
109
+ const jsonSchema = makeGrokStructuredOutputCompatible(
110
+ outputSchema,
111
+ outputSchema.required || [],
112
+ )
113
+
114
+ try {
115
+ const response = await this.client.chat.completions.create({
116
+ ...requestParams,
117
+ stream: false,
118
+ response_format: {
119
+ type: 'json_schema',
120
+ json_schema: {
121
+ name: 'structured_output',
122
+ schema: jsonSchema,
123
+ strict: true,
124
+ },
125
+ },
126
+ })
127
+
128
+ // Extract text content from the response
129
+ const rawText = response.choices[0]?.message.content || ''
130
+
131
+ // Parse the JSON response
132
+ let parsed: unknown
133
+ try {
134
+ parsed = JSON.parse(rawText)
135
+ } catch {
136
+ throw new Error(
137
+ `Failed to parse structured output as JSON. Content: ${rawText.slice(0, 200)}${rawText.length > 200 ? '...' : ''}`,
138
+ )
139
+ }
140
+
141
+ // Transform null values to undefined to match original Zod schema expectations
142
+ // Grok returns null for optional fields we made nullable in the schema
143
+ const transformed = transformNullsToUndefined(parsed)
144
+
145
+ return {
146
+ data: transformed,
147
+ rawText,
148
+ }
149
+ } catch (error: unknown) {
150
+ const err = error as Error
151
+ console.error('>>> structuredOutput: Error during response creation <<<')
152
+ console.error('>>> Error message:', err.message)
153
+ throw error
154
+ }
155
+ }
156
+
157
+ private async *processGrokStreamChunks(
158
+ stream: AsyncIterable<OpenAI_SDK.Chat.Completions.ChatCompletionChunk>,
159
+ options: TextOptions,
160
+ ): AsyncIterable<StreamChunk> {
161
+ let accumulatedContent = ''
162
+ const timestamp = Date.now()
163
+ let responseId = generateId(this.name)
164
+
165
+ // Track tool calls being streamed (arguments come in chunks)
166
+ const toolCallsInProgress = new Map<
167
+ number,
168
+ {
169
+ id: string
170
+ name: string
171
+ arguments: string
172
+ }
173
+ >()
174
+
175
+ try {
176
+ for await (const chunk of stream) {
177
+ responseId = chunk.id || responseId
178
+ const choice = chunk.choices[0]
179
+
180
+ if (!choice) continue
181
+
182
+ const delta = choice.delta
183
+ const deltaContent = delta.content
184
+ const deltaToolCalls = delta.tool_calls
185
+
186
+ // Handle content delta
187
+ if (deltaContent) {
188
+ accumulatedContent += deltaContent
189
+ yield {
190
+ type: 'content',
191
+ id: responseId,
192
+ model: chunk.model || options.model,
193
+ timestamp,
194
+ delta: deltaContent,
195
+ content: accumulatedContent,
196
+ role: 'assistant',
197
+ }
198
+ }
199
+
200
+ // Handle tool calls - they come in as deltas
201
+ if (deltaToolCalls) {
202
+ for (const toolCallDelta of deltaToolCalls) {
203
+ const index = toolCallDelta.index
204
+
205
+ // Initialize or update the tool call in progress
206
+ if (!toolCallsInProgress.has(index)) {
207
+ toolCallsInProgress.set(index, {
208
+ id: toolCallDelta.id || '',
209
+ name: toolCallDelta.function?.name || '',
210
+ arguments: '',
211
+ })
212
+ }
213
+
214
+ const toolCall = toolCallsInProgress.get(index)!
215
+
216
+ // Update with any new data from the delta
217
+ if (toolCallDelta.id) {
218
+ toolCall.id = toolCallDelta.id
219
+ }
220
+ if (toolCallDelta.function?.name) {
221
+ toolCall.name = toolCallDelta.function.name
222
+ }
223
+ if (toolCallDelta.function?.arguments) {
224
+ toolCall.arguments += toolCallDelta.function.arguments
225
+ }
226
+ }
227
+ }
228
+
229
+ // Handle finish reason
230
+ if (choice.finish_reason) {
231
+ // Emit all completed tool calls
232
+ if (
233
+ choice.finish_reason === 'tool_calls' ||
234
+ toolCallsInProgress.size > 0
235
+ ) {
236
+ for (const [index, toolCall] of toolCallsInProgress) {
237
+ yield {
238
+ type: 'tool_call',
239
+ id: responseId,
240
+ model: chunk.model || options.model,
241
+ timestamp,
242
+ index,
243
+ toolCall: {
244
+ id: toolCall.id,
245
+ type: 'function',
246
+ function: {
247
+ name: toolCall.name,
248
+ arguments: toolCall.arguments,
249
+ },
250
+ },
251
+ }
252
+ }
253
+ }
254
+
255
+ yield {
256
+ type: 'done',
257
+ id: responseId,
258
+ model: chunk.model || options.model,
259
+ timestamp,
260
+ usage: chunk.usage
261
+ ? {
262
+ promptTokens: chunk.usage.prompt_tokens || 0,
263
+ completionTokens: chunk.usage.completion_tokens || 0,
264
+ totalTokens: chunk.usage.total_tokens || 0,
265
+ }
266
+ : undefined,
267
+ finishReason:
268
+ choice.finish_reason === 'tool_calls' ||
269
+ toolCallsInProgress.size > 0
270
+ ? 'tool_calls'
271
+ : 'stop',
272
+ }
273
+ }
274
+ }
275
+ } catch (error: unknown) {
276
+ const err = error as Error & { code?: string }
277
+ console.log('[Grok Adapter] Stream ended with error:', err.message)
278
+ yield {
279
+ type: 'error',
280
+ id: responseId,
281
+ model: options.model,
282
+ timestamp,
283
+ error: {
284
+ message: err.message || 'Unknown error occurred',
285
+ code: err.code,
286
+ },
287
+ }
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Maps common options to Grok-specific Chat Completions format
293
+ */
294
+ private mapTextOptionsToGrok(
295
+ options: TextOptions,
296
+ ): OpenAI_SDK.Chat.Completions.ChatCompletionCreateParamsStreaming {
297
+ const modelOptions = options.modelOptions as
298
+ | Omit<
299
+ InternalTextProviderOptions,
300
+ 'max_tokens' | 'tools' | 'temperature' | 'input' | 'top_p'
301
+ >
302
+ | undefined
303
+
304
+ if (modelOptions) {
305
+ validateTextProviderOptions({
306
+ ...modelOptions,
307
+ model: options.model,
308
+ })
309
+ }
310
+
311
+ const tools = options.tools
312
+ ? convertToolsToProviderFormat(options.tools)
313
+ : undefined
314
+
315
+ // Build messages array with system prompts
316
+ const messages: Array<OpenAI_SDK.Chat.Completions.ChatCompletionMessageParam> =
317
+ []
318
+
319
+ // Add system prompts first
320
+ if (options.systemPrompts && options.systemPrompts.length > 0) {
321
+ messages.push({
322
+ role: 'system',
323
+ content: options.systemPrompts.join('\n'),
324
+ })
325
+ }
326
+
327
+ // Convert messages
328
+ for (const message of options.messages) {
329
+ messages.push(this.convertMessageToGrok(message))
330
+ }
331
+
332
+ return {
333
+ model: options.model,
334
+ messages,
335
+ temperature: options.temperature,
336
+ max_tokens: options.maxTokens,
337
+ top_p: options.topP,
338
+ tools: tools as Array<OpenAI_SDK.Chat.Completions.ChatCompletionTool>,
339
+ stream: true,
340
+ stream_options: { include_usage: true },
341
+ }
342
+ }
343
+
344
+ private convertMessageToGrok(
345
+ message: ModelMessage,
346
+ ): OpenAI_SDK.Chat.Completions.ChatCompletionMessageParam {
347
+ // Handle tool messages
348
+ if (message.role === 'tool') {
349
+ return {
350
+ role: 'tool',
351
+ tool_call_id: message.toolCallId || '',
352
+ content:
353
+ typeof message.content === 'string'
354
+ ? message.content
355
+ : JSON.stringify(message.content),
356
+ }
357
+ }
358
+
359
+ // Handle assistant messages
360
+ if (message.role === 'assistant') {
361
+ const toolCalls = message.toolCalls?.map((tc) => ({
362
+ id: tc.id,
363
+ type: 'function' as const,
364
+ function: {
365
+ name: tc.function.name,
366
+ arguments:
367
+ typeof tc.function.arguments === 'string'
368
+ ? tc.function.arguments
369
+ : JSON.stringify(tc.function.arguments),
370
+ },
371
+ }))
372
+
373
+ return {
374
+ role: 'assistant',
375
+ content: this.extractTextContent(message.content),
376
+ ...(toolCalls && toolCalls.length > 0 ? { tool_calls: toolCalls } : {}),
377
+ }
378
+ }
379
+
380
+ // Handle user messages - support multimodal content
381
+ const contentParts = this.normalizeContent(message.content)
382
+
383
+ // If only text, use simple string format
384
+ if (contentParts.length === 1 && contentParts[0]?.type === 'text') {
385
+ return {
386
+ role: 'user',
387
+ content: contentParts[0].content,
388
+ }
389
+ }
390
+
391
+ // Otherwise, use array format for multimodal
392
+ const parts: Array<OpenAI_SDK.Chat.Completions.ChatCompletionContentPart> =
393
+ []
394
+ for (const part of contentParts) {
395
+ if (part.type === 'text') {
396
+ parts.push({ type: 'text', text: part.content })
397
+ } else if (part.type === 'image') {
398
+ const imageMetadata = part.metadata as GrokImageMetadata | undefined
399
+ parts.push({
400
+ type: 'image_url',
401
+ image_url: {
402
+ url: part.source.value,
403
+ detail: imageMetadata?.detail || 'auto',
404
+ },
405
+ })
406
+ }
407
+ }
408
+
409
+ return {
410
+ role: 'user',
411
+ content: parts.length > 0 ? parts : '',
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Normalizes message content to an array of ContentPart.
417
+ * Handles backward compatibility with string content.
418
+ */
419
+ private normalizeContent(
420
+ content: string | null | Array<ContentPart>,
421
+ ): Array<ContentPart> {
422
+ if (content === null) {
423
+ return []
424
+ }
425
+ if (typeof content === 'string') {
426
+ return [{ type: 'text', content: content }]
427
+ }
428
+ return content
429
+ }
430
+
431
+ /**
432
+ * Extracts text content from a content value that may be string, null, or ContentPart array.
433
+ */
434
+ private extractTextContent(
435
+ content: string | null | Array<ContentPart>,
436
+ ): string {
437
+ if (content === null) {
438
+ return ''
439
+ }
440
+ if (typeof content === 'string') {
441
+ return content
442
+ }
443
+ // It's an array of ContentPart
444
+ return content
445
+ .filter((p) => p.type === 'text')
446
+ .map((p) => p.content)
447
+ .join('')
448
+ }
449
+ }
450
+
451
+ /**
452
+ * Creates a Grok text adapter with explicit API key.
453
+ * Type resolution happens here at the call site.
454
+ *
455
+ * @param model - The model name (e.g., 'grok-3', 'grok-4')
456
+ * @param apiKey - Your xAI API key
457
+ * @param config - Optional additional configuration
458
+ * @returns Configured Grok text adapter instance with resolved types
459
+ *
460
+ * @example
461
+ * ```typescript
462
+ * const adapter = createGrokText('grok-3', "xai-...");
463
+ * // adapter has type-safe providerOptions for grok-3
464
+ * ```
465
+ */
466
+ export function createGrokText<
467
+ TModel extends (typeof GROK_CHAT_MODELS)[number],
468
+ >(
469
+ model: TModel,
470
+ apiKey: string,
471
+ config?: Omit<GrokTextConfig, 'apiKey'>,
472
+ ): GrokTextAdapter<TModel> {
473
+ return new GrokTextAdapter({ apiKey, ...config }, model)
474
+ }
475
+
476
+ /**
477
+ * Creates a Grok text adapter with automatic API key detection from environment variables.
478
+ * Type resolution happens here at the call site.
479
+ *
480
+ * Looks for `XAI_API_KEY` in:
481
+ * - `process.env` (Node.js)
482
+ * - `window.env` (Browser with injected env)
483
+ *
484
+ * @param model - The model name (e.g., 'grok-3', 'grok-4')
485
+ * @param config - Optional configuration (excluding apiKey which is auto-detected)
486
+ * @returns Configured Grok text adapter instance with resolved types
487
+ * @throws Error if XAI_API_KEY is not found in environment
488
+ *
489
+ * @example
490
+ * ```typescript
491
+ * // Automatically uses XAI_API_KEY from environment
492
+ * const adapter = grokText('grok-3');
493
+ *
494
+ * const stream = chat({
495
+ * adapter,
496
+ * messages: [{ role: "user", content: "Hello!" }]
497
+ * });
498
+ * ```
499
+ */
500
+ export function grokText<TModel extends (typeof GROK_CHAT_MODELS)[number]>(
501
+ model: TModel,
502
+ config?: Omit<GrokTextConfig, 'apiKey'>,
503
+ ): GrokTextAdapter<TModel> {
504
+ const apiKey = getGrokApiKeyFromEnv()
505
+ return createGrokText(model, apiKey, config)
506
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Grok Image Generation Provider Options
3
+ *
4
+ * These are provider-specific options for Grok image generation.
5
+ * Grok uses the grok-2-image-1212 model for image generation.
6
+ */
7
+
8
+ /**
9
+ * Supported sizes for grok-2-image-1212 model
10
+ */
11
+ export type GrokImageSize = '1024x1024' | '1536x1024' | '1024x1536'
12
+
13
+ /**
14
+ * Base provider options for Grok image models
15
+ */
16
+ export interface GrokImageBaseProviderOptions {
17
+ /**
18
+ * A unique identifier representing your end-user.
19
+ * Can help xAI to monitor and detect abuse.
20
+ */
21
+ user?: string
22
+ }
23
+
24
+ /**
25
+ * Provider options for grok-2-image-1212 model
26
+ */
27
+ export interface GrokImageProviderOptions extends GrokImageBaseProviderOptions {
28
+ /**
29
+ * The quality of the image.
30
+ * @default 'standard'
31
+ */
32
+ quality?: 'standard' | 'hd'
33
+
34
+ /**
35
+ * The format in which generated images are returned.
36
+ * URLs are only valid for 60 minutes after generation.
37
+ * @default 'url'
38
+ */
39
+ response_format?: 'url' | 'b64_json'
40
+ }
41
+
42
+ /**
43
+ * Type-only map from model name to its specific provider options.
44
+ */
45
+ export type GrokImageModelProviderOptionsByName = {
46
+ 'grok-2-image-1212': GrokImageProviderOptions
47
+ }
48
+
49
+ /**
50
+ * Type-only map from model name to its supported sizes.
51
+ */
52
+ export type GrokImageModelSizeByName = {
53
+ 'grok-2-image-1212': GrokImageSize
54
+ }
55
+
56
+ /**
57
+ * Internal options interface for validation
58
+ */
59
+ interface ImageValidationOptions {
60
+ prompt: string
61
+ model: string
62
+ }
63
+
64
+ /**
65
+ * Validates that the provided size is supported by the model.
66
+ * Throws a descriptive error if the size is not supported.
67
+ */
68
+ export function validateImageSize(
69
+ model: string,
70
+ size: string | undefined,
71
+ ): void {
72
+ if (!size) return
73
+
74
+ const validSizes: Record<string, Array<string>> = {
75
+ 'grok-2-image-1212': ['1024x1024', '1536x1024', '1024x1536'],
76
+ }
77
+
78
+ const modelSizes = validSizes[model]
79
+ if (!modelSizes) {
80
+ throw new Error(`Unknown image model: ${model}`)
81
+ }
82
+
83
+ if (!modelSizes.includes(size)) {
84
+ throw new Error(
85
+ `Size "${size}" is not supported by model "${model}". ` +
86
+ `Supported sizes: ${modelSizes.join(', ')}`,
87
+ )
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Validates that the number of images is within bounds for the model.
93
+ */
94
+ export function validateNumberOfImages(
95
+ _model: string,
96
+ numberOfImages: number | undefined,
97
+ ): void {
98
+ if (numberOfImages === undefined) return
99
+
100
+ // grok-2-image-1212 supports 1-10 images per request
101
+ if (numberOfImages < 1 || numberOfImages > 10) {
102
+ throw new Error(
103
+ `Number of images must be between 1 and 10. Requested: ${numberOfImages}`,
104
+ )
105
+ }
106
+ }
107
+
108
+ export const validatePrompt = (options: ImageValidationOptions) => {
109
+ if (options.prompt.length === 0) {
110
+ throw new Error('Prompt cannot be empty.')
111
+ }
112
+ // Grok image model supports up to 4000 characters
113
+ if (options.prompt.length > 4000) {
114
+ throw new Error(
115
+ 'For grok-2-image-1212, prompt length must be less than or equal to 4000 characters.',
116
+ )
117
+ }
118
+ }
package/src/index.ts ADDED
@@ -0,0 +1,55 @@
1
+ // ============================================================================
2
+ // New Tree-Shakeable Adapters (Recommended)
3
+ // ============================================================================
4
+
5
+ // Text (Chat) adapter - for chat/text completion
6
+ export {
7
+ GrokTextAdapter,
8
+ createGrokText,
9
+ grokText,
10
+ type GrokTextConfig,
11
+ type GrokTextProviderOptions,
12
+ } from './adapters/text'
13
+
14
+ // Summarize adapter - for text summarization
15
+ export {
16
+ GrokSummarizeAdapter,
17
+ createGrokSummarize,
18
+ grokSummarize,
19
+ type GrokSummarizeConfig,
20
+ type GrokSummarizeProviderOptions,
21
+ type GrokSummarizeModel,
22
+ } from './adapters/summarize'
23
+
24
+ // Image adapter - for image generation
25
+ export {
26
+ GrokImageAdapter,
27
+ createGrokImage,
28
+ grokImage,
29
+ type GrokImageConfig,
30
+ type GrokImageModel,
31
+ } from './adapters/image'
32
+ export type {
33
+ GrokImageProviderOptions,
34
+ GrokImageModelProviderOptionsByName,
35
+ } from './image/image-provider-options'
36
+
37
+ // ============================================================================
38
+ // Type Exports
39
+ // ============================================================================
40
+
41
+ export type {
42
+ GrokChatModelProviderOptionsByName,
43
+ GrokModelInputModalitiesByName,
44
+ ResolveProviderOptions,
45
+ ResolveInputModalities,
46
+ } from './model-meta'
47
+ export { GROK_CHAT_MODELS, GROK_IMAGE_MODELS } from './model-meta'
48
+ export type {
49
+ GrokTextMetadata,
50
+ GrokImageMetadata,
51
+ GrokAudioMetadata,
52
+ GrokVideoMetadata,
53
+ GrokDocumentMetadata,
54
+ GrokMessageMetadataByModality,
55
+ } from './message-types'