@tanstack/ai-grok 0.14.11 → 0.16.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 (39) hide show
  1. package/dist/esm/adapters/image.js +2 -2
  2. package/dist/esm/adapters/image.js.map +1 -1
  3. package/dist/esm/adapters/transcription.js +4 -0
  4. package/dist/esm/adapters/transcription.js.map +1 -1
  5. package/dist/esm/adapters/tts.js +2 -1
  6. package/dist/esm/adapters/tts.js.map +1 -1
  7. package/dist/esm/adapters/video.d.ts +34 -12
  8. package/dist/esm/adapters/video.js +134 -30
  9. package/dist/esm/adapters/video.js.map +1 -1
  10. package/dist/esm/image/image-provider-options.d.ts +17 -2
  11. package/dist/esm/image/image-provider-options.js.map +1 -1
  12. package/dist/esm/index.d.ts +3 -3
  13. package/dist/esm/index.js +2 -2
  14. package/dist/esm/model-meta.d.ts +49 -3
  15. package/dist/esm/model-meta.js +110 -8
  16. package/dist/esm/model-meta.js.map +1 -1
  17. package/dist/esm/realtime/adapter.js +17 -16
  18. package/dist/esm/realtime/adapter.js.map +1 -1
  19. package/dist/esm/realtime/token.d.ts +1 -1
  20. package/dist/esm/realtime/token.js +3 -2
  21. package/dist/esm/realtime/token.js.map +1 -1
  22. package/dist/esm/realtime/types.d.ts +1 -1
  23. package/dist/esm/tools/index.js +2 -0
  24. package/dist/esm/tools/index.js.map +1 -1
  25. package/dist/esm/video/video-provider-options.d.ts +131 -21
  26. package/dist/esm/video/video-provider-options.js +36 -10
  27. package/dist/esm/video/video-provider-options.js.map +1 -1
  28. package/package.json +6 -6
  29. package/src/adapters/image.ts +2 -1
  30. package/src/adapters/transcription.ts +2 -1
  31. package/src/adapters/video.ts +321 -53
  32. package/src/image/image-provider-options.ts +18 -2
  33. package/src/index.ts +7 -0
  34. package/src/model-meta.ts +109 -6
  35. package/src/realtime/adapter.ts +3 -2
  36. package/src/realtime/token.ts +4 -2
  37. package/src/realtime/types.ts +1 -1
  38. package/src/tools/index.ts +2 -0
  39. package/src/video/video-provider-options.ts +198 -34
@@ -1 +1 @@
1
- {"version":3,"file":"video.js","names":[],"sources":["../../../src/adapters/video.ts"],"sourcesContent":["import { resolveMediaPrompt } from '@tanstack/ai'\nimport { BaseVideoAdapter, snapToDurationOption } from '@tanstack/ai/adapters'\nimport { toRunErrorPayload } from '@tanstack/ai/adapter-internals'\nimport { getGrokApiKeyFromEnv, withGrokDefaults } from '../utils/client'\nimport {\n getGrokVideoDurationOptions,\n isImageToVideoOnlyModel,\n parseGrokVideoSize,\n validateVideoSize,\n} from '../video/video-provider-options'\nimport type { DurationOptions } from '@tanstack/ai/adapters'\nimport type {\n ImagePart,\n MediaInputMetadata,\n TokenUsage,\n VideoGenerationOptions,\n VideoJobResult,\n VideoStatusResult,\n VideoUrlResult,\n} from '@tanstack/ai'\nimport type { GrokVideoModel } from '../model-meta'\nimport type {\n GrokVideoModelDurationByName,\n GrokVideoModelInputModalitiesByName,\n GrokVideoModelProviderOptionsByName,\n GrokVideoModelSizeByName,\n GrokVideoProviderOptions,\n} from '../video/video-provider-options'\nimport type { GrokClientConfig } from '../utils/client'\n\n/**\n * Configuration for Grok video adapter.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport interface GrokVideoConfig extends GrokClientConfig {}\n\n/**\n * xAI bills video generation in \"USD ticks\": 10^10 ticks per US dollar\n * (e.g. one grok-imagine-video-1.5 second costs $0.08 = 800_000_000 ticks).\n */\nconst USD_TICKS_PER_DOLLAR = 10_000_000_000\n\n/** Response of POST /v1/videos/generations. */\ninterface GrokVideoCreateResponse {\n request_id?: string\n}\n\n/** Response of GET /v1/videos/{request_id}. */\ninterface GrokVideoStatusResponse {\n status?: string\n progress?: number\n model?: string\n video?: {\n url?: string\n duration?: number\n }\n usage?: {\n cost_in_usd_ticks?: number\n }\n error?: string\n}\n\n/**\n * Convert a TanStack ImagePart to the URL string accepted by xAI's Imagine\n * video 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\nfunction buildGrokVideoUsage(\n response: GrokVideoStatusResponse,\n): TokenUsage | undefined {\n const seconds = response.video?.duration\n const ticks = response.usage?.cost_in_usd_ticks\n if (seconds === undefined && ticks === undefined) return undefined\n return {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n ...(seconds !== undefined && { unitsBilled: seconds }),\n ...(ticks !== undefined && { cost: ticks / USD_TICKS_PER_DOLLAR }),\n }\n}\n\n/**\n * Grok Video Generation Adapter (xAI Imagine API)\n *\n * Tree-shakeable adapter for the grok-imagine video models using the\n * async jobs/polling architecture: create a generation request, poll it,\n * then read the completed video URL.\n *\n * `grok-imagine-video` (v1.0) supports text-to-video and image-to-video.\n * `grok-imagine-video-1.5` is image-to-video only — every request needs an\n * image prompt part as the starting frame, and the adapter rejects a\n * text-only prompt with a clear error rather than a raw API 400.\n *\n * The Imagine video endpoints are not part of the OpenAI SDK surface (and\n * xAI rejects the SDK's multipart paths), so requests are plain JSON calls\n * issued with the configured `fetch` (or the global one).\n *\n * @experimental Video generation is an experimental feature and may change.\n *\n * Features:\n * - Async job-based video generation (1–15 second clips with audio)\n * - Aspect-ratio sizing via the \"aspectRatio_resolution\" size template\n * (e.g. '16:9_720p'), consistent with the grok-imagine image models\n * - Image-to-video via an `image` prompt part (starting frame URL or data URI)\n * - Usage reporting: billed seconds (`unitsBilled`) and exact cost\n */\nexport class GrokVideoAdapter<\n TModel extends GrokVideoModel,\n> extends BaseVideoAdapter<\n TModel,\n GrokVideoProviderOptions,\n GrokVideoModelProviderOptionsByName,\n GrokVideoModelSizeByName,\n GrokVideoModelInputModalitiesByName,\n GrokVideoModelDurationByName\n> {\n readonly name = 'grok' as const\n\n private readonly clientConfig: GrokVideoConfig\n\n constructor(config: GrokVideoConfig, model: TModel) {\n super({}, model)\n this.clientConfig = withGrokDefaults(config)\n }\n\n private get fetch(): (\n input: string,\n init?: RequestInit,\n ) => Promise<Response> {\n return this.clientConfig.fetch ?? fetch\n }\n\n private async request(\n path: string,\n init?: Omit<RequestInit, 'headers'>,\n ): Promise<Response> {\n return await this.fetch(`${this.clientConfig.baseURL}${path}`, {\n ...init,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.clientConfig.apiKey}`,\n },\n })\n }\n\n /**\n * Reads the error message out of an Imagine API error body\n * (`{\"code\": \"...\", \"error\": \"...\"}`), falling back to the raw text.\n */\n private async errorMessage(response: Response): Promise<string> {\n const body = await response.text()\n try {\n const parsed: unknown = JSON.parse(body)\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n 'error' in parsed &&\n typeof parsed.error === 'string'\n ) {\n return parsed.error\n }\n } catch {\n // not JSON — fall through to the raw body\n }\n return body\n }\n\n async createVideoJob(\n options: VideoGenerationOptions<\n GrokVideoProviderOptions,\n GrokVideoModelSizeByName[TModel],\n GrokVideoModelDurationByName[TModel]\n >,\n ): Promise<VideoJobResult> {\n const { model, size, modelOptions, logger } = options\n\n validateVideoSize(model, size)\n\n // Coerce the requested duration into the model's valid range (1–15s,\n // integer) instead of rejecting it — `snapDuration` clamps and rounds.\n // modelOptions wins over the generic `duration`, mirroring the size\n // precedence below.\n const rawDuration = modelOptions?.duration ?? options.duration\n const duration =\n rawDuration !== undefined ? this.snapDuration(rawDuration) : undefined\n\n // The interleaved prompt decomposes into verbatim text plus typed media\n // buckets. The Imagine video endpoint takes a text prompt and an optional\n // starting frame; reject the modalities it can't consume.\n const resolved = resolveMediaPrompt(options.prompt)\n if (resolved.videos.length > 0) {\n throw new Error(\n `${this.name}.createVideoJob does not support video prompt parts (model: ${model}).`,\n )\n }\n if (resolved.audios.length > 0) {\n throw new Error(\n `${this.name}.createVideoJob does not support audio prompt parts (model: ${model}).`,\n )\n }\n // grok-imagine-video-1.5 is image-to-video only — text-to-video is\n // rejected by the API, so fail fast with a clear, actionable message\n // pointing at the model that does support text-to-video.\n if (resolved.images.length === 0 && isImageToVideoOnlyModel(model)) {\n throw new Error(\n `${this.name}: ${model} does not support text-to-video — it is image-to-video only. ` +\n `Include an image prompt part as the starting frame, or use 'grok-imagine-video' for text-to-video.`,\n )\n }\n if (resolved.images.length > 1) {\n throw new Error(\n `${this.name}: ${model} accepts at most one starting-frame image; received ${resolved.images.length}.`,\n )\n }\n\n // Image-to-video: the single image prompt part becomes the starting frame\n // and the prompt text describes the desired motion. URL sources are\n // fetched by xAI's servers; data sources are sent as base64 data URIs.\n const [startFrame] = resolved.images\n\n // The generic `size` option carries an \"aspectRatio_resolution\" template\n // (e.g. '16:9_720p') and maps to the Imagine API's `aspect_ratio` /\n // `resolution` parameters; explicit modelOptions win over the template.\n const parsedSize = size !== undefined ? parseGrokVideoSize(size) : undefined\n const request = {\n model,\n prompt: resolved.text,\n ...(startFrame && { image: { url: imagePartToUrl(startFrame) } }),\n ...(parsedSize && {\n aspect_ratio: parsedSize.aspectRatio,\n ...(parsedSize.resolution !== undefined && {\n resolution: parsedSize.resolution,\n }),\n }),\n ...modelOptions,\n // Spread after modelOptions so the snapped duration is authoritative\n // (modelOptions.duration is folded into `duration` via snapDuration above).\n ...(duration !== undefined && { duration }),\n }\n\n try {\n logger.request(\n `activity=video.create provider=${this.name} model=${model} size=${size ?? 'default'} duration=${duration ?? 'default'}`,\n { provider: this.name, model },\n )\n\n const response = await this.request('/videos/generations', {\n method: 'POST',\n body: JSON.stringify(request),\n })\n if (!response.ok) {\n throw new Error(\n `grok: video generation request failed (${response.status} ${response.statusText}): ${await this.errorMessage(response)}`,\n )\n }\n\n const result = (await response.json()) as GrokVideoCreateResponse\n if (!result.request_id) {\n throw new Error(\n 'grok: video generation response contained no request_id',\n )\n }\n return { jobId: result.request_id, model }\n } catch (error: unknown) {\n logger.errors(`${this.name}.createVideoJob fatal`, {\n error: toRunErrorPayload(error, `${this.name}.createVideoJob failed`),\n source: `${this.name}.createVideoJob`,\n })\n throw error\n }\n }\n\n private async retrieveJob(jobId: string): Promise<GrokVideoStatusResponse> {\n const response = await this.request(`/videos/${jobId}`)\n if (!response.ok) {\n const error = new Error(\n `grok: video status request failed (${response.status} ${response.statusText}): ${await this.errorMessage(response)}`,\n )\n ;(error as { status?: number }).status = response.status\n throw error\n }\n return (await response.json()) as GrokVideoStatusResponse\n }\n\n async getVideoStatus(jobId: string): Promise<VideoStatusResult> {\n let response: GrokVideoStatusResponse\n try {\n response = await this.retrieveJob(jobId)\n } catch (error) {\n if ((error as { status?: number }).status === 404) {\n return { jobId, status: 'failed', error: 'Job not found' }\n }\n throw error\n }\n\n return {\n jobId,\n status: this.mapStatus(response.status),\n ...(response.progress !== undefined && { progress: response.progress }),\n ...(response.error !== undefined && { error: response.error }),\n }\n }\n\n async getVideoUrl(jobId: string): Promise<VideoUrlResult> {\n let response: GrokVideoStatusResponse\n try {\n response = await this.retrieveJob(jobId)\n } catch (error) {\n if ((error as { status?: number }).status === 404) {\n throw new Error(`Video job not found: ${jobId}`)\n }\n throw error\n }\n\n const status = this.mapStatus(response.status)\n if (status === 'failed') {\n throw new Error(\n `Video generation failed${response.error ? `: ${response.error}` : ''}. Job ID: ${jobId}`,\n )\n }\n const url = response.video?.url\n if (!url) {\n throw new Error(\n `Video is not ready for download. Check status first. Job ID: ${jobId}`,\n )\n }\n\n const usage = buildGrokVideoUsage(response)\n return {\n jobId,\n url,\n ...(usage && { usage }),\n }\n }\n\n /**\n * Maps Imagine API job statuses onto the generic video status set. The\n * API reports 'pending' while queued/generating (with a numeric\n * `progress`), then a terminal 'done' / 'failed' / 'expired'.\n */\n protected mapStatus(\n apiStatus: string | undefined,\n ): 'pending' | 'processing' | 'completed' | 'failed' {\n switch (apiStatus) {\n case 'pending':\n case 'queued':\n return 'pending'\n case 'done':\n case 'completed':\n case 'succeeded':\n return 'completed'\n case 'failed':\n case 'expired':\n case 'error':\n case 'cancelled':\n return 'failed'\n case undefined:\n default:\n return 'processing'\n }\n }\n\n /**\n * Both grok-imagine video models accept a continuous 1–15 integer-second\n * range. Consumers can use this to render UI without provider knowledge.\n */\n override availableDurations(): DurationOptions<\n GrokVideoModelDurationByName[TModel]\n > {\n return getGrokVideoDurationOptions(this.model)\n }\n\n /**\n * Coerce a raw seconds value to the closest valid duration (clamped to\n * [1, 15] and rounded to whole seconds).\n */\n override snapDuration(\n seconds: number,\n ): GrokVideoModelDurationByName[TModel] | undefined {\n return snapToDurationOption(seconds, this.availableDurations())\n }\n}\n\n/**\n * Creates a Grok video adapter with an explicit API key.\n * Type resolution happens here at the call site.\n *\n * @experimental Video generation is an experimental feature and may change.\n *\n * @param model - The model name (e.g., 'grok-imagine-video')\n * @param apiKey - Your xAI API key\n * @param config - Optional additional configuration\n * @returns Configured Grok video adapter instance with resolved types\n *\n * @example\n * ```typescript\n * // grok-imagine-video (v1.0) supports text-to-video.\n * const adapter = createGrokVideo('grok-imagine-video', 'xai-...');\n *\n * const { jobId } = await generateVideo({\n * adapter,\n * prompt: 'A beautiful sunset over the ocean',\n * size: '16:9_720p',\n * duration: 5\n * });\n * ```\n */\nexport function createGrokVideo<TModel extends GrokVideoModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<GrokVideoConfig, 'apiKey'>,\n): GrokVideoAdapter<TModel> {\n return new GrokVideoAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Grok video 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 * @experimental Video generation is an experimental feature and may change.\n *\n * @param model - The model name (e.g., 'grok-imagine-video-1.5')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Grok video 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 = grokVideo('grok-imagine-video-1.5');\n *\n * // Image-to-video only: the prompt must carry a starting-frame image part.\n * const { jobId } = await generateVideo({\n * adapter,\n * prompt: [\n * { type: 'text', content: 'Make the cat start playing the piano' },\n * { type: 'image', source: { type: 'url', value: 'https://example.com/cat.png' } },\n * ],\n * });\n *\n * // Poll for status\n * const status = await getVideoJobStatus({ adapter, jobId });\n * ```\n */\nexport function grokVideo<TModel extends GrokVideoModel>(\n model: TModel,\n config?: Omit<GrokVideoConfig, 'apiKey'>,\n): GrokVideoAdapter<TModel> {\n const apiKey = getGrokApiKeyFromEnv()\n return createGrokVideo(model, apiKey, config)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"video.js","names":[],"sources":["../../../src/adapters/video.ts"],"sourcesContent":["import { resolveMediaPrompt } from '@tanstack/ai'\nimport { BaseVideoAdapter, snapToDurationOption } from '@tanstack/ai/adapters'\nimport { toRunErrorPayload } from '@tanstack/ai/adapter-internals'\nimport { getGrokApiKeyFromEnv, withGrokDefaults } from '../utils/client'\nimport {\n GROK_VIDEO_MAX_REFERENCE_AUDIOS,\n GROK_VIDEO_MAX_REFERENCE_IMAGES,\n getGrokVideoDurationOptions,\n isGrokVideoReferenceModel,\n isGrokVideoSourceModel,\n parseGrokVideoSize,\n validateVideoSize,\n} from '../video/video-provider-options'\nimport type { DurationOptions } from '@tanstack/ai/adapters'\nimport type {\n ImagePart,\n MediaInputMetadata,\n TokenUsage,\n VideoGenerationOptions,\n VideoJobResult,\n VideoPart,\n VideoStatusResult,\n VideoUrlResult,\n} from '@tanstack/ai'\nimport type { GrokVideoModel } from '../model-meta'\nimport type {\n GrokVideoModelDurationByName,\n GrokVideoModelInputModalitiesByName,\n GrokVideoModelProviderOptionsByName,\n GrokVideoModelSizeByName,\n GrokVideoRuntimeOptions,\n} from '../video/video-provider-options'\nimport type { GrokClientConfig } from '../utils/client'\n\n/**\n * Configuration for Grok video adapter.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport interface GrokVideoConfig extends GrokClientConfig {}\n\n/**\n * xAI bills video generation in \"USD ticks\": 10^10 ticks per US dollar\n * (e.g. one grok-imagine-video-1.5 second costs $0.08 = 800_000_000 ticks).\n */\nconst USD_TICKS_PER_DOLLAR = 10_000_000_000\n\n/** Response of the POST /v1/videos/{generations,edits,extensions} endpoints. */\ninterface GrokVideoCreateResponse {\n request_id?: string\n}\n\n/** Response of GET /v1/videos/{request_id}. */\ninterface GrokVideoStatusResponse {\n status?: string\n progress?: number\n model?: string\n video?: {\n url?: string\n duration?: number\n }\n usage?: {\n cost_in_usd_ticks?: number\n }\n error?: string\n}\n\n/**\n * Convert a TanStack image / video part to the URL string accepted by xAI's\n * Imagine video endpoints: public URLs pass through (fetched by xAI's\n * servers), data sources become base64 data URIs.\n */\nfunction mediaPartToUrl(\n part: ImagePart<MediaInputMetadata> | VideoPart<MediaInputMetadata>,\n): string {\n if (part.source.type === 'url') return part.source.value\n return `data:${part.source.mimeType};base64,${part.source.value}`\n}\n\nfunction buildGrokVideoUsage(\n response: GrokVideoStatusResponse,\n): TokenUsage | undefined {\n const seconds = response.video?.duration\n const ticks = response.usage?.cost_in_usd_ticks\n if (seconds === undefined && ticks === undefined) return undefined\n return {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n ...(seconds !== undefined && {\n billed: { quantity: seconds, unit: 'seconds' },\n unitsBilled: seconds,\n }),\n ...(ticks !== undefined && { cost: ticks / USD_TICKS_PER_DOLLAR }),\n }\n}\n\n/**\n * Grok Video Generation Adapter (xAI Imagine API)\n *\n * Tree-shakeable adapter for the grok-imagine video models using the\n * async jobs/polling architecture: create a generation request, poll it,\n * then read the completed video URL.\n *\n * Both models support text-to-video and image-to-video;\n * `grok-imagine-video-1.5` is xAI's documented default and adds native\n * 1080p generation plus reference-to-video inputs. Source-video edit\n * and extend are `grok-imagine-video` only.\n *\n * The Imagine video endpoints are not part of the OpenAI SDK surface (and\n * xAI rejects the SDK's multipart paths), so requests are plain JSON calls\n * issued with the configured `fetch` (or the global one).\n *\n * @experimental Video generation is an experimental feature and may change.\n *\n * Features:\n * - Async job-based video generation (1–15 second clips with audio)\n * - Aspect-ratio sizing via the \"aspectRatio_resolution\" size template\n * (e.g. '16:9_720p'), consistent with the grok-imagine image models\n * - Image-to-video via an `image` prompt part (starting frame URL or data URI)\n * - Reference-to-video via image prompt parts with\n * `metadata.role: 'reference'` or `'character'` (→ `reference_images`)\n * and preset voices via `modelOptions.reference_audios`\n * (grok-imagine-video-1.5 only)\n * - Video editing / extension on `grok-imagine-video` via a source\n * `video` prompt part and `modelOptions.mode: 'edit' | 'extend'`\n * (`/v1/videos/edits` / `/v1/videos/extensions`; in extend mode\n * `duration` is the added tail)\n * - Usage reporting: billed seconds (`usage.billed`) and exact cost\n */\nexport class GrokVideoAdapter<\n TModel extends GrokVideoModel,\n> extends BaseVideoAdapter<\n TModel,\n GrokVideoModelProviderOptionsByName[TModel],\n GrokVideoModelProviderOptionsByName,\n GrokVideoModelSizeByName,\n GrokVideoModelInputModalitiesByName,\n GrokVideoModelDurationByName\n> {\n readonly name = 'grok' as const\n\n private readonly clientConfig: GrokVideoConfig\n\n constructor(config: GrokVideoConfig, model: TModel) {\n super({}, model)\n this.clientConfig = withGrokDefaults(config)\n }\n\n private get fetch(): (\n input: string,\n init?: RequestInit,\n ) => Promise<Response> {\n return this.clientConfig.fetch ?? fetch\n }\n\n private async request(\n path: string,\n init?: Omit<RequestInit, 'headers'>,\n ): Promise<Response> {\n return await this.fetch(`${this.clientConfig.baseURL}${path}`, {\n ...init,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.clientConfig.apiKey}`,\n },\n })\n }\n\n /**\n * Reads the error message out of an Imagine API error body\n * (`{\"code\": \"...\", \"error\": \"...\"}`), falling back to the raw text.\n */\n private async errorMessage(response: Response): Promise<string> {\n const body = await response.text()\n try {\n const parsed: unknown = JSON.parse(body)\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n 'error' in parsed &&\n typeof parsed.error === 'string'\n ) {\n return parsed.error\n }\n } catch {\n // not JSON — fall through to the raw body\n }\n return body\n }\n\n async createVideoJob(\n options: VideoGenerationOptions<\n GrokVideoModelProviderOptionsByName[TModel],\n GrokVideoModelSizeByName[TModel],\n GrokVideoModelDurationByName[TModel]\n >,\n ): Promise<VideoJobResult> {\n const { model, size, modelOptions, logger } = options\n\n // `mode` is a routing hint for this adapter, not an API field — strip it\n // before the remaining options are spread onto the request body. The\n // per-model map narrows what callers can pass, but modelOptions often\n // arrives as deserialized JSON, so the adapter handles the widest option\n // surface (the 1.5 shape) uniformly and gates by model at runtime.\n const { mode, ...wireOptions } = (modelOptions ??\n {}) as GrokVideoRuntimeOptions\n\n // `mode` is typed 'edit' | 'extend' but reaches us untrusted from JSON\n // callers. An unrecognised value must not fall through to the\n // generations endpoint with a source-video body — that would silently\n // run (and bill) a generation the caller never asked for.\n if (mode !== undefined && mode !== 'edit' && mode !== 'extend') {\n throw new Error(\n `${this.name}: unknown modelOptions.mode '${String(mode)}'. ` +\n `Expected 'edit' or 'extend'.`,\n )\n }\n\n // The interleaved prompt decomposes into verbatim text plus typed media\n // buckets. Reference audio is voice-id based (not an audio file), so\n // audio prompt parts have no request field to land in.\n const resolved = resolveMediaPrompt(options.prompt)\n if (resolved.audios.length > 0) {\n throw new Error(\n `${this.name}.createVideoJob does not support audio prompt parts (model: ${model}). ` +\n `To reference a preset voice, pass modelOptions.reference_audios ` +\n `(e.g. [{ voice_id: 'eve' }]).`,\n )\n }\n\n // A video prompt part is the source clip for edit / extension mode.\n // Those endpoints are grok-imagine-video only — 1.5 has no video input.\n if (\n !isGrokVideoSourceModel(model) &&\n (mode !== undefined || resolved.videos.length > 0)\n ) {\n throw new Error(\n `${this.name}: ${model} does not support video editing or extension. ` +\n `Use 'grok-imagine-video' for /v1/videos/edits and /v1/videos/extensions.`,\n )\n }\n\n // The mode must be chosen explicitly because the two endpoints have\n // different semantics (edit rewrites the clip, extend appends\n // `duration` seconds).\n if (resolved.videos.length > 1) {\n throw new Error(\n `${this.name}: ${model} accepts at most one source video; received ${resolved.videos.length}.`,\n )\n }\n const [sourceVideo] = resolved.videos\n if (sourceVideo && mode === undefined) {\n throw new Error(\n `${this.name}: a video prompt part needs modelOptions.mode set to ` +\n `'edit' (rewrite the clip) or 'extend' (append to it).`,\n )\n }\n if (!sourceVideo && mode !== undefined) {\n throw new Error(\n `${this.name}: modelOptions.mode '${mode}' requires a video prompt ` +\n `part carrying the source clip.`,\n )\n }\n\n if (mode !== undefined && sourceVideo) {\n return await this.createSourceVideoJob({\n model,\n mode,\n sourceVideo,\n resolved,\n wireOptions,\n size,\n genericDuration: options.duration,\n logger,\n })\n }\n\n validateVideoSize(model, size)\n\n // Pull the specially-handled keys out of the wire options: `duration`\n // is folded into the snapped value below, and the reference fields are\n // re-added explicitly so a JSON-serialized `null` or empty array reads\n // as \"unset\" instead of leaking onto the wire.\n const {\n duration: rawOptionDuration,\n reference_images: explicitReferenceImages,\n reference_audios: referenceAudios,\n ...generationOptions\n } = wireOptions\n\n // Coerce the requested duration into the model's valid range (1–15s,\n // integer) instead of rejecting it — `snapDuration` clamps and rounds.\n // modelOptions wins over the generic `duration`, mirroring the size\n // precedence below.\n const rawDuration = rawOptionDuration ?? options.duration\n const duration =\n rawDuration != null ? this.snapDuration(rawDuration) : undefined\n\n // Image parts split by role: un-roled / 'start_frame' images become the\n // starting frame (image-to-video); 'reference' / 'character' images\n // become reference_images (reference-to-video). The Imagine API has no\n // mask / control / end-frame inputs. Unknown role strings (possible via\n // JSON callers) throw rather than silently dropping the part.\n const startFrames: Array<ImagePart<MediaInputMetadata>> = []\n const referenceImages: Array<{ url: string }> = []\n for (const part of resolved.images) {\n const role = part.metadata?.role\n switch (role) {\n case 'mask':\n case 'control':\n case 'end_frame':\n throw new Error(\n `${this.name}: the Imagine video API has no '${role}' image ` +\n `input on model ${model}. Use an un-roled / 'start_frame' ` +\n `image as the starting frame, or 'reference' images.`,\n )\n case 'reference':\n case 'character':\n referenceImages.push({ url: mediaPartToUrl(part) })\n break\n case 'start_frame':\n case undefined:\n startFrames.push(part)\n break\n default:\n throw new Error(\n `${this.name}: unknown image metadata.role '${String(role)}'. ` +\n `Expected 'start_frame', 'reference', or 'character'.`,\n )\n }\n }\n if (startFrames.length > 1) {\n throw new Error(\n `${this.name}: ${model} accepts at most one starting-frame image; received ${startFrames.length}. ` +\n `Use metadata.role: 'reference' for reference-to-video inputs.`,\n )\n }\n // Explicit modelOptions.reference_images replaces the part-derived list\n // (an explicit empty array means \"none\").\n const finalReferenceImages =\n explicitReferenceImages ??\n (referenceImages.length > 0 ? referenceImages : undefined)\n const referenceImageCount = finalReferenceImages?.length ?? 0\n const referenceAudioCount = referenceAudios?.length ?? 0\n const hasReference = referenceImageCount > 0 || referenceAudioCount > 0\n\n // Reference inputs are a grok-imagine-video-1.5 feature. The per-model\n // options map already hides the fields from other models at compile\n // time; this runtime gate covers prompt-part roles and untyped callers.\n if (!isGrokVideoReferenceModel(model) && hasReference) {\n throw new Error(\n `${this.name}: ${model} does not support reference-to-video inputs. ` +\n `Use 'grok-imagine-video-1.5' for reference_images / reference_audios.`,\n )\n }\n if (referenceAudioCount > GROK_VIDEO_MAX_REFERENCE_AUDIOS) {\n throw new Error(\n `${this.name}: ${model} accepts at most ${GROK_VIDEO_MAX_REFERENCE_AUDIOS} reference voices; received ${referenceAudioCount}.`,\n )\n }\n if (referenceImageCount > GROK_VIDEO_MAX_REFERENCE_IMAGES) {\n throw new Error(\n `${this.name}: ${model} accepts at most ${GROK_VIDEO_MAX_REFERENCE_IMAGES} reference images; received ${referenceImageCount}.`,\n )\n }\n\n // Image-to-video: the single image prompt part becomes the starting frame\n // and the prompt text describes the desired motion. URL sources are\n // fetched by xAI's servers; data sources are sent as base64 data URIs.\n const [startFrame] = startFrames\n\n // xAI rejects `image` + `reference_images` / `reference_audios` as a\n // 400: only one of image-to-video or reference-to-video can be active.\n if (startFrame && hasReference) {\n throw new Error(\n `${this.name}: image-to-video and reference-to-video cannot be combined. ` +\n `Use a starting-frame image, or reference images / voices, not both.`,\n )\n }\n\n // The generic `size` option carries an \"aspectRatio_resolution\" template\n // (e.g. '16:9_720p') and maps to the Imagine API's `aspect_ratio` /\n // `resolution` parameters; explicit modelOptions win over the template\n // (including `reference_images`, which replaces the part-derived list).\n const parsedSize = size !== undefined ? parseGrokVideoSize(size) : undefined\n const resolvedResolution =\n generationOptions.resolution ?? parsedSize?.resolution\n if (hasReference && resolvedResolution === '1080p') {\n throw new Error(\n `${this.name}: reference-to-video is capped at 720p on ${model}.`,\n )\n }\n const request = {\n model,\n prompt: resolved.text,\n ...(startFrame && { image: { url: mediaPartToUrl(startFrame) } }),\n ...(referenceImageCount > 0 && {\n reference_images: finalReferenceImages,\n }),\n ...(referenceAudioCount > 0 && {\n reference_audios: referenceAudios,\n }),\n ...(parsedSize && {\n aspect_ratio: parsedSize.aspectRatio,\n ...(parsedSize.resolution !== undefined && {\n resolution: parsedSize.resolution,\n }),\n }),\n // The remaining options spread after the size template so explicit\n // aspect_ratio / resolution win over it; duration and the reference\n // fields were destructured out above and re-added normalized.\n ...generationOptions,\n ...(duration !== undefined && { duration }),\n }\n\n return await this.postVideoJob('/videos/generations', request, {\n model,\n logger,\n logLine: `activity=video.create provider=${this.name} model=${model} mode=generate size=${size ?? 'default'} duration=${duration ?? 'default'}`,\n })\n }\n\n /**\n * Build and post an edit / extension request. Both endpoints take only\n * `model`, `prompt`, and the source `video` (plus `duration` — the length\n * of the added tail — for extensions): output geometry is inherited from\n * the source clip, capped at 720p, and edit outputs also inherit the\n * source length. Rather than sending fields the API documents as ignored,\n * the inapplicable options are rejected with actionable errors.\n */\n private async createSourceVideoJob(args: {\n model: string\n mode: 'edit' | 'extend'\n sourceVideo: VideoPart<MediaInputMetadata>\n resolved: ReturnType<typeof resolveMediaPrompt>\n wireOptions: Omit<GrokVideoRuntimeOptions, 'mode'>\n size: string | undefined\n genericDuration: number | undefined\n logger: VideoGenerationOptions<GrokVideoRuntimeOptions>['logger']\n }): Promise<VideoJobResult> {\n const { model, mode, sourceVideo, resolved, wireOptions, logger } = args\n const endpoint = mode === 'edit' ? '/videos/edits' : '/videos/extensions'\n\n if (resolved.images.length > 0) {\n throw new Error(\n `${this.name}: '${mode}' mode takes only the source video — image ` +\n `prompt parts are not supported by ${endpoint}.`,\n )\n }\n\n // Pull every generation-only key out of the wire options so nothing can\n // leak into the edit/extend body via the spread below. JSON-serialized\n // `null` values (a common \"unset\" encoding) are treated as absent;\n // actual values are rejected with actionable errors.\n const {\n aspect_ratio: aspectRatio,\n resolution,\n duration: modeDuration,\n reference_images: referenceImagesOption,\n reference_audios: referenceAudiosOption,\n ...passthrough\n } = wireOptions\n if (\n (referenceImagesOption?.length ?? 0) > 0 ||\n (referenceAudiosOption?.length ?? 0) > 0\n ) {\n throw new Error(\n `${this.name}: reference inputs are only supported by video ` +\n `generation, not '${mode}' mode.`,\n )\n }\n if (args.size !== undefined || aspectRatio != null || resolution != null) {\n throw new Error(\n `${this.name}: '${mode}' mode does not accept size / aspect_ratio / ` +\n `resolution — the output inherits the source clip's geometry ` +\n `(capped at 720p).`,\n )\n }\n const rawDuration = modeDuration ?? args.genericDuration\n if (mode === 'edit' && rawDuration != null) {\n throw new Error(\n `${this.name}: 'edit' mode does not accept a duration — the output ` +\n `inherits the source clip's length. Use mode 'extend' to append ` +\n `seconds to the clip.`,\n )\n }\n // Extend: the snapped duration is the added-tail length (1–15s).\n const duration =\n rawDuration != null ? this.snapDuration(rawDuration) : undefined\n\n const request = {\n model,\n prompt: resolved.text,\n video: { url: mediaPartToUrl(sourceVideo) },\n ...passthrough,\n ...(duration !== undefined && { duration }),\n }\n\n return await this.postVideoJob(endpoint, request, {\n model,\n logger,\n logLine: `activity=video.create provider=${this.name} model=${model} mode=${mode} duration=${duration ?? 'default'}`,\n })\n }\n\n /**\n * POST a create-job request body to one of the Imagine video endpoints\n * (`/videos/generations`, `/videos/edits`, `/videos/extensions`) and read\n * the `request_id` out of the shared response shape.\n */\n private async postVideoJob(\n endpoint: string,\n request: Record<string, unknown>,\n context: {\n model: string\n logger: VideoGenerationOptions<GrokVideoRuntimeOptions>['logger']\n logLine: string\n },\n ): Promise<VideoJobResult> {\n const { model, logger, logLine } = context\n try {\n logger.request(logLine, { provider: this.name, model })\n\n const response = await this.request(endpoint, {\n method: 'POST',\n body: JSON.stringify(request),\n })\n if (!response.ok) {\n throw new Error(\n `grok: ${endpoint} request failed (${response.status} ${response.statusText}): ${await this.errorMessage(response)}`,\n )\n }\n\n const result = (await response.json()) as GrokVideoCreateResponse\n if (!result.request_id) {\n throw new Error(`grok: ${endpoint} response contained no request_id`)\n }\n return { jobId: result.request_id, model }\n } catch (error: unknown) {\n logger.errors(`${this.name}.createVideoJob fatal`, {\n error: toRunErrorPayload(error, `${this.name}.createVideoJob failed`),\n source: `${this.name}.createVideoJob`,\n })\n throw error\n }\n }\n\n private async retrieveJob(jobId: string): Promise<GrokVideoStatusResponse> {\n const response = await this.request(`/videos/${jobId}`)\n if (!response.ok) {\n const error = new Error(\n `grok: video status request failed (${response.status} ${response.statusText}): ${await this.errorMessage(response)}`,\n )\n ;(error as { status?: number }).status = response.status\n throw error\n }\n return (await response.json()) as GrokVideoStatusResponse\n }\n\n async getVideoStatus(jobId: string): Promise<VideoStatusResult> {\n let response: GrokVideoStatusResponse\n try {\n response = await this.retrieveJob(jobId)\n } catch (error) {\n if ((error as { status?: number }).status === 404) {\n return { jobId, status: 'failed', error: 'Job not found' }\n }\n throw error\n }\n\n return {\n jobId,\n status: this.mapStatus(response.status),\n ...(response.progress !== undefined && { progress: response.progress }),\n ...(response.error !== undefined && { error: response.error }),\n }\n }\n\n async getVideoUrl(jobId: string): Promise<VideoUrlResult> {\n let response: GrokVideoStatusResponse\n try {\n response = await this.retrieveJob(jobId)\n } catch (error) {\n if ((error as { status?: number }).status === 404) {\n throw new Error(`Video job not found: ${jobId}`)\n }\n throw error\n }\n\n const status = this.mapStatus(response.status)\n if (status === 'failed') {\n throw new Error(\n `Video generation failed${response.error ? `: ${response.error}` : ''}. Job ID: ${jobId}`,\n )\n }\n const url = response.video?.url\n if (!url) {\n throw new Error(\n `Video is not ready for download. Check status first. Job ID: ${jobId}`,\n )\n }\n\n const usage = buildGrokVideoUsage(response)\n return {\n jobId,\n url,\n ...(usage && { usage }),\n }\n }\n\n /**\n * Maps Imagine API job statuses onto the generic video status set. The\n * API reports 'pending' while queued/generating (with a numeric\n * `progress`), then a terminal 'done' / 'failed' / 'expired'.\n */\n protected mapStatus(\n apiStatus: string | undefined,\n ): 'pending' | 'processing' | 'completed' | 'failed' {\n switch (apiStatus) {\n case 'pending':\n case 'queued':\n return 'pending'\n case 'done':\n case 'completed':\n case 'succeeded':\n return 'completed'\n case 'failed':\n case 'expired':\n case 'error':\n case 'cancelled':\n return 'failed'\n case undefined:\n default:\n return 'processing'\n }\n }\n\n /**\n * Both grok-imagine video models accept a continuous 1–15 integer-second\n * range. Consumers can use this to render UI without provider knowledge.\n */\n override availableDurations(): DurationOptions<\n GrokVideoModelDurationByName[TModel]\n > {\n return getGrokVideoDurationOptions(this.model)\n }\n\n /**\n * Coerce a raw seconds value to the closest valid duration (clamped to\n * [1, 15] and rounded to whole seconds).\n */\n override snapDuration(\n seconds: number,\n ): GrokVideoModelDurationByName[TModel] | undefined {\n return snapToDurationOption(seconds, this.availableDurations())\n }\n}\n\n/**\n * Creates a Grok video adapter with an explicit API key.\n * Type resolution happens here at the call site.\n *\n * @experimental Video generation is an experimental feature and may change.\n *\n * @param model - The model name (e.g., 'grok-imagine-video-1.5')\n * @param apiKey - Your xAI API key\n * @param config - Optional additional configuration\n * @returns Configured Grok video adapter instance with resolved types\n *\n * @example\n * ```typescript\n * const adapter = createGrokVideo('grok-imagine-video-1.5', 'xai-...');\n *\n * const { jobId } = await generateVideo({\n * adapter,\n * prompt: 'A beautiful sunset over the ocean',\n * size: '16:9_720p',\n * duration: 5\n * });\n * ```\n */\nexport function createGrokVideo<TModel extends GrokVideoModel>(\n model: TModel,\n apiKey: string,\n config?: Omit<GrokVideoConfig, 'apiKey'>,\n): GrokVideoAdapter<TModel> {\n return new GrokVideoAdapter({ apiKey, ...config }, model)\n}\n\n/**\n * Creates a Grok video 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 * @experimental Video generation is an experimental feature and may change.\n *\n * @param model - The model name (e.g., 'grok-imagine-video-1.5')\n * @param config - Optional configuration (excluding apiKey which is auto-detected)\n * @returns Configured Grok video 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 = grokVideo('grok-imagine-video-1.5');\n *\n * // Image-to-video: an optional image prompt part is the starting frame.\n * const { jobId } = await generateVideo({\n * adapter,\n * prompt: [\n * { type: 'text', content: 'Make the cat start playing the piano' },\n * { type: 'image', source: { type: 'url', value: 'https://example.com/cat.png' } },\n * ],\n * });\n *\n * // Poll for status\n * const status = await getVideoJobStatus({ adapter, jobId });\n * ```\n */\nexport function grokVideo<TModel extends GrokVideoModel>(\n model: TModel,\n config?: Omit<GrokVideoConfig, 'apiKey'>,\n): GrokVideoAdapter<TModel> {\n const apiKey = getGrokApiKeyFromEnv()\n return createGrokVideo(model, apiKey, config)\n}\n"],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * Grok Image Generation Provider Options
3
3
  *
4
- * These are provider-specific options for Grok image generation.
5
- * Grok uses the grok-2-image-1212 model for image generation.
4
+ * Provider-specific options for Grok image generation: the aspect-ratio
5
+ * sized Imagine API models (grok-imagine-image, grok-imagine-image-2.0,
6
+ * grok-imagine-image-quality) and the legacy pixel-sized grok-2-image-1212.
6
7
  */
7
8
  /**
8
9
  * Supported sizes for grok-2-image-1212 model
@@ -87,12 +88,24 @@ export interface GrokImagineImageProviderOptions extends GrokImageBaseProviderOp
87
88
  */
88
89
  service_tier?: 'default' | 'priority';
89
90
  }
91
+ /**
92
+ * Provider options for grok-imagine-image-2.0, which adds a generation
93
+ * `quality` knob on top of the shared Imagine options.
94
+ */
95
+ export interface GrokImagineImage2ProviderOptions extends GrokImagineImageProviderOptions {
96
+ /**
97
+ * Generation quality. Only supported by grok-imagine-image-2.0.
98
+ * @default 'medium'
99
+ */
100
+ quality?: 'low' | 'medium';
101
+ }
90
102
  /**
91
103
  * Type-only map from model name to its specific provider options.
92
104
  */
93
105
  export type GrokImageModelProviderOptionsByName = {
94
106
  'grok-2-image-1212': GrokImageProviderOptions;
95
107
  'grok-imagine-image': GrokImagineImageProviderOptions;
108
+ 'grok-imagine-image-2.0': GrokImagineImage2ProviderOptions;
96
109
  'grok-imagine-image-quality': GrokImagineImageProviderOptions;
97
110
  };
98
111
  /**
@@ -101,6 +114,7 @@ export type GrokImageModelProviderOptionsByName = {
101
114
  export type GrokImageModelSizeByName = {
102
115
  'grok-2-image-1212': GrokImageSize;
103
116
  'grok-imagine-image': GrokImagineImageSize;
117
+ 'grok-imagine-image-2.0': GrokImagineImageSize;
104
118
  'grok-imagine-image-quality': GrokImagineImageSize;
105
119
  };
106
120
  /**
@@ -111,6 +125,7 @@ export type GrokImageModelSizeByName = {
111
125
  export type GrokImageModelInputModalitiesByName = {
112
126
  'grok-2-image-1212': readonly [];
113
127
  'grok-imagine-image': readonly ['image'];
128
+ 'grok-imagine-image-2.0': readonly ['image'];
114
129
  'grok-imagine-image-quality': readonly ['image'];
115
130
  };
116
131
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"image-provider-options.js","names":[],"sources":["../../../src/image/image-provider-options.ts"],"sourcesContent":["/**\n * Grok Image Generation Provider Options\n *\n * These are provider-specific options for Grok image generation.\n * Grok uses the grok-2-image-1212 model for image generation.\n */\n\n/**\n * Supported sizes for grok-2-image-1212 model\n */\nexport type GrokImageSize = '1024x1024' | '1536x1024' | '1024x1536'\n\n/**\n * Aspect ratios accepted by the grok-imagine image models.\n */\nexport type GrokImagineAspectRatio =\n | '1:1'\n | '3:4'\n | '4:3'\n | '9:16'\n | '16:9'\n | '2:3'\n | '3:2'\n | '9:19.5'\n | '19.5:9'\n | '9:20'\n | '20:9'\n | '1:2'\n | '2:1'\n | 'auto'\n\n/**\n * Resolution tiers for the grok-imagine image models.\n */\nexport type GrokImagineResolution = '1k' | '2k'\n\n/**\n * Size strings for grok-imagine image models. The Imagine API is\n * aspect-ratio based rather than pixel-size based; like Gemini's native\n * image models, the generic `size` option uses an\n * `aspectRatio_resolution` template (\"16:9_2k\") — the resolution suffix is\n * optional (\"16:9\" uses the API default of 1k).\n */\nexport type GrokImagineImageSize =\n | GrokImagineAspectRatio\n | `${GrokImagineAspectRatio}_${GrokImagineResolution}`\n\nconst GROK_IMAGINE_ASPECT_RATIOS: ReadonlyArray<string> = [\n '1:1',\n '3:4',\n '4:3',\n '9:16',\n '16:9',\n '2:3',\n '3:2',\n '9:19.5',\n '19.5:9',\n '9:20',\n '20:9',\n '1:2',\n '2:1',\n 'auto',\n]\n\nconst GROK_IMAGINE_RESOLUTIONS: ReadonlyArray<string> = ['1k', '2k']\n\n/**\n * Models served by xAI's Imagine API. They are aspect-ratio sized and\n * support image-conditioned generation via `/v1/images/edits`; the legacy\n * grok-2-image-1212 model is pixel-sized and text-to-image only.\n */\nexport function isGrokImagineImageModel(model: string): boolean {\n return model.startsWith('grok-imagine-image')\n}\n\n/**\n * Parses a grok-imagine size string into its components.\n * Format: \"aspectRatio\" or \"aspectRatio_resolution\",\n * e.g. \"16:9_2k\" → { aspectRatio: \"16:9\", resolution: \"2k\" }.\n * Returns undefined when the string doesn't match the template.\n */\nexport function parseGrokImagineSize(\n size: string,\n): { aspectRatio: string; resolution?: string } | undefined {\n const match = size.match(/^([\\d.]+:[\\d.]+|auto)(?:_(.+))?$/)\n const [, aspectRatio, resolution] = match ?? []\n if (aspectRatio === undefined) return undefined\n return { aspectRatio, ...(resolution !== undefined && { resolution }) }\n}\n\n/**\n * Base provider options for Grok image models\n */\nexport interface GrokImageBaseProviderOptions {\n /**\n * A unique identifier representing your end-user.\n * Can help xAI to monitor and detect abuse.\n */\n user?: string\n}\n\n/**\n * Provider options for grok-2-image-1212 model\n */\nexport interface GrokImageProviderOptions extends GrokImageBaseProviderOptions {\n /**\n * The quality of the image.\n * @default 'standard'\n */\n quality?: 'standard' | 'hd'\n\n /**\n * The format in which generated images are returned.\n * URLs are only valid for 60 minutes after generation.\n * @default 'url'\n */\n response_format?: 'url' | 'b64_json'\n}\n\n/**\n * Provider options for the grok-imagine image models (generation and\n * image-conditioned editing via xAI's Imagine API).\n */\nexport interface GrokImagineImageProviderOptions extends GrokImageBaseProviderOptions {\n /**\n * The format in which generated images are returned.\n * @default 'url'\n */\n response_format?: 'url' | 'b64_json'\n\n /**\n * Output resolution.\n * @default '1k'\n */\n resolution?: '1k' | '2k'\n\n /**\n * Processing tier for the request.\n * @default 'default'\n */\n service_tier?: 'default' | 'priority'\n}\n\n/**\n * Type-only map from model name to its specific provider options.\n */\nexport type GrokImageModelProviderOptionsByName = {\n 'grok-2-image-1212': GrokImageProviderOptions\n 'grok-imagine-image': GrokImagineImageProviderOptions\n 'grok-imagine-image-quality': GrokImagineImageProviderOptions\n}\n\n/**\n * Type-only map from model name to its supported sizes.\n */\nexport type GrokImageModelSizeByName = {\n 'grok-2-image-1212': GrokImageSize\n 'grok-imagine-image': GrokImagineImageSize\n 'grok-imagine-image-quality': GrokImagineImageSize\n}\n\n/**\n * Per-model prompt input modalities. Imagine API models accept image parts\n * in the prompt (routed to `/v1/images/edits`, up to 3 images, addressed by\n * xAI in request order); grok-2-image is text-to-image only.\n */\nexport type GrokImageModelInputModalitiesByName = {\n 'grok-2-image-1212': readonly []\n 'grok-imagine-image': readonly ['image']\n 'grok-imagine-image-quality': readonly ['image']\n}\n\n/**\n * Internal options interface for validation\n */\ninterface ImageValidationOptions {\n prompt: string\n model: string\n}\n\n/**\n * Validates that the provided size is supported by the model.\n * Throws a descriptive error if the size is not supported.\n */\nexport function validateImageSize(\n model: string,\n size: string | undefined,\n): void {\n if (!size) return\n\n if (isGrokImagineImageModel(model)) {\n const parsed = parseGrokImagineSize(size)\n if (\n !parsed ||\n !GROK_IMAGINE_ASPECT_RATIOS.includes(parsed.aspectRatio) ||\n (parsed.resolution !== undefined &&\n !GROK_IMAGINE_RESOLUTIONS.includes(parsed.resolution))\n ) {\n throw new Error(\n `Size \"${size}\" is not supported by model \"${model}\". ` +\n `Expected an aspect ratio (${GROK_IMAGINE_ASPECT_RATIOS.join(', ')}) ` +\n `optionally suffixed with a resolution (\"16:9_2k\"; resolutions: ${GROK_IMAGINE_RESOLUTIONS.join(', ')}).`,\n )\n }\n return\n }\n\n const validSizes: Record<string, Array<string>> = {\n 'grok-2-image-1212': ['1024x1024', '1536x1024', '1024x1536'],\n }\n\n const modelSizes = validSizes[model]\n if (!modelSizes) {\n throw new Error(`Unknown image model: ${model}`)\n }\n\n if (!modelSizes.includes(size)) {\n throw new Error(\n `Size \"${size}\" is not supported by model \"${model}\". ` +\n `Supported sizes: ${modelSizes.join(', ')}`,\n )\n }\n}\n\n/**\n * Validates that the number of images is within bounds for the model.\n */\nexport function validateNumberOfImages(\n _model: string,\n numberOfImages: number | undefined,\n): void {\n if (numberOfImages === undefined) return\n\n // grok-2-image-1212 supports 1-10 images per request\n if (numberOfImages < 1 || numberOfImages > 10) {\n throw new Error(\n `Number of images must be between 1 and 10. Requested: ${numberOfImages}`,\n )\n }\n}\n\nexport const validatePrompt = (options: ImageValidationOptions) => {\n if (options.prompt.length === 0) {\n throw new Error('Prompt cannot be empty.')\n }\n // Grok image model supports up to 4000 characters\n if (options.prompt.length > 4000) {\n throw new Error(\n 'For grok-2-image-1212, prompt length must be less than or equal to 4000 characters.',\n )\n }\n}\n"],"mappings":";AA+CA,IAAM,6BAAoD;CACxD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,IAAM,2BAAkD,CAAC,MAAM,IAAI;;;;;;AAOnE,SAAgB,wBAAwB,OAAwB;CAC9D,OAAO,MAAM,WAAW,oBAAoB;AAC9C;;;;;;;AAQA,SAAgB,qBACd,MAC0D;CAE1D,MAAM,GAAG,aAAa,cADR,KAAK,MAAM,kCACW,KAAS,CAAC;CAC9C,IAAI,gBAAgB,KAAA,GAAW,OAAO,KAAA;CACtC,OAAO;EAAE;EAAa,GAAI,eAAe,KAAA,KAAa,EAAE,WAAW;CAAG;AACxE;;;;;AAgGA,SAAgB,kBACd,OACA,MACM;CACN,IAAI,CAAC,MAAM;CAEX,IAAI,wBAAwB,KAAK,GAAG;EAClC,MAAM,SAAS,qBAAqB,IAAI;EACxC,IACE,CAAC,UACD,CAAC,2BAA2B,SAAS,OAAO,WAAW,KACtD,OAAO,eAAe,KAAA,KACrB,CAAC,yBAAyB,SAAS,OAAO,UAAU,GAEtD,MAAM,IAAI,MACR,SAAS,KAAK,+BAA+B,MAAM,+BACpB,2BAA2B,KAAK,IAAI,EAAE,mEACD,yBAAyB,KAAK,IAAI,EAAE,GAC1G;EAEF;CACF;CAMA,MAAM,aAAa,EAHjB,qBAAqB;EAAC;EAAa;EAAa;CAAW,EAG1C,EAAW;CAC9B,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,wBAAwB,OAAO;CAGjD,IAAI,CAAC,WAAW,SAAS,IAAI,GAC3B,MAAM,IAAI,MACR,SAAS,KAAK,+BAA+B,MAAM,sBAC7B,WAAW,KAAK,IAAI,GAC5C;AAEJ;;;;AAKA,SAAgB,uBACd,QACA,gBACM;CACN,IAAI,mBAAmB,KAAA,GAAW;CAGlC,IAAI,iBAAiB,KAAK,iBAAiB,IACzC,MAAM,IAAI,MACR,yDAAyD,gBAC3D;AAEJ;AAEA,IAAa,kBAAkB,YAAoC;CACjE,IAAI,QAAQ,OAAO,WAAW,GAC5B,MAAM,IAAI,MAAM,yBAAyB;CAG3C,IAAI,QAAQ,OAAO,SAAS,KAC1B,MAAM,IAAI,MACR,qFACF;AAEJ"}
1
+ {"version":3,"file":"image-provider-options.js","names":[],"sources":["../../../src/image/image-provider-options.ts"],"sourcesContent":["/**\n * Grok Image Generation Provider Options\n *\n * Provider-specific options for Grok image generation: the aspect-ratio\n * sized Imagine API models (grok-imagine-image, grok-imagine-image-2.0,\n * grok-imagine-image-quality) and the legacy pixel-sized grok-2-image-1212.\n */\n\n/**\n * Supported sizes for grok-2-image-1212 model\n */\nexport type GrokImageSize = '1024x1024' | '1536x1024' | '1024x1536'\n\n/**\n * Aspect ratios accepted by the grok-imagine image models.\n */\nexport type GrokImagineAspectRatio =\n | '1:1'\n | '3:4'\n | '4:3'\n | '9:16'\n | '16:9'\n | '2:3'\n | '3:2'\n | '9:19.5'\n | '19.5:9'\n | '9:20'\n | '20:9'\n | '1:2'\n | '2:1'\n | 'auto'\n\n/**\n * Resolution tiers for the grok-imagine image models.\n */\nexport type GrokImagineResolution = '1k' | '2k'\n\n/**\n * Size strings for grok-imagine image models. The Imagine API is\n * aspect-ratio based rather than pixel-size based; like Gemini's native\n * image models, the generic `size` option uses an\n * `aspectRatio_resolution` template (\"16:9_2k\") — the resolution suffix is\n * optional (\"16:9\" uses the API default of 1k).\n */\nexport type GrokImagineImageSize =\n | GrokImagineAspectRatio\n | `${GrokImagineAspectRatio}_${GrokImagineResolution}`\n\nconst GROK_IMAGINE_ASPECT_RATIOS: ReadonlyArray<string> = [\n '1:1',\n '3:4',\n '4:3',\n '9:16',\n '16:9',\n '2:3',\n '3:2',\n '9:19.5',\n '19.5:9',\n '9:20',\n '20:9',\n '1:2',\n '2:1',\n 'auto',\n]\n\nconst GROK_IMAGINE_RESOLUTIONS: ReadonlyArray<string> = ['1k', '2k']\n\n/**\n * Models served by xAI's Imagine API. They are aspect-ratio sized and\n * support image-conditioned generation via `/v1/images/edits`; the legacy\n * grok-2-image-1212 model is pixel-sized and text-to-image only.\n */\nexport function isGrokImagineImageModel(model: string): boolean {\n return model.startsWith('grok-imagine-image')\n}\n\n/**\n * Parses a grok-imagine size string into its components.\n * Format: \"aspectRatio\" or \"aspectRatio_resolution\",\n * e.g. \"16:9_2k\" → { aspectRatio: \"16:9\", resolution: \"2k\" }.\n * Returns undefined when the string doesn't match the template.\n */\nexport function parseGrokImagineSize(\n size: string,\n): { aspectRatio: string; resolution?: string } | undefined {\n const match = size.match(/^([\\d.]+:[\\d.]+|auto)(?:_(.+))?$/)\n const [, aspectRatio, resolution] = match ?? []\n if (aspectRatio === undefined) return undefined\n return { aspectRatio, ...(resolution !== undefined && { resolution }) }\n}\n\n/**\n * Base provider options for Grok image models\n */\nexport interface GrokImageBaseProviderOptions {\n /**\n * A unique identifier representing your end-user.\n * Can help xAI to monitor and detect abuse.\n */\n user?: string\n}\n\n/**\n * Provider options for grok-2-image-1212 model\n */\nexport interface GrokImageProviderOptions extends GrokImageBaseProviderOptions {\n /**\n * The quality of the image.\n * @default 'standard'\n */\n quality?: 'standard' | 'hd'\n\n /**\n * The format in which generated images are returned.\n * URLs are only valid for 60 minutes after generation.\n * @default 'url'\n */\n response_format?: 'url' | 'b64_json'\n}\n\n/**\n * Provider options for the grok-imagine image models (generation and\n * image-conditioned editing via xAI's Imagine API).\n */\nexport interface GrokImagineImageProviderOptions extends GrokImageBaseProviderOptions {\n /**\n * The format in which generated images are returned.\n * @default 'url'\n */\n response_format?: 'url' | 'b64_json'\n\n /**\n * Output resolution.\n * @default '1k'\n */\n resolution?: '1k' | '2k'\n\n /**\n * Processing tier for the request.\n * @default 'default'\n */\n service_tier?: 'default' | 'priority'\n}\n\n/**\n * Provider options for grok-imagine-image-2.0, which adds a generation\n * `quality` knob on top of the shared Imagine options.\n */\nexport interface GrokImagineImage2ProviderOptions extends GrokImagineImageProviderOptions {\n /**\n * Generation quality. Only supported by grok-imagine-image-2.0.\n * @default 'medium'\n */\n quality?: 'low' | 'medium'\n}\n\n/**\n * Type-only map from model name to its specific provider options.\n */\nexport type GrokImageModelProviderOptionsByName = {\n 'grok-2-image-1212': GrokImageProviderOptions\n 'grok-imagine-image': GrokImagineImageProviderOptions\n 'grok-imagine-image-2.0': GrokImagineImage2ProviderOptions\n 'grok-imagine-image-quality': GrokImagineImageProviderOptions\n}\n\n/**\n * Type-only map from model name to its supported sizes.\n */\nexport type GrokImageModelSizeByName = {\n 'grok-2-image-1212': GrokImageSize\n 'grok-imagine-image': GrokImagineImageSize\n 'grok-imagine-image-2.0': GrokImagineImageSize\n 'grok-imagine-image-quality': GrokImagineImageSize\n}\n\n/**\n * Per-model prompt input modalities. Imagine API models accept image parts\n * in the prompt (routed to `/v1/images/edits`, up to 3 images, addressed by\n * xAI in request order); grok-2-image is text-to-image only.\n */\nexport type GrokImageModelInputModalitiesByName = {\n 'grok-2-image-1212': readonly []\n 'grok-imagine-image': readonly ['image']\n 'grok-imagine-image-2.0': readonly ['image']\n 'grok-imagine-image-quality': readonly ['image']\n}\n\n/**\n * Internal options interface for validation\n */\ninterface ImageValidationOptions {\n prompt: string\n model: string\n}\n\n/**\n * Validates that the provided size is supported by the model.\n * Throws a descriptive error if the size is not supported.\n */\nexport function validateImageSize(\n model: string,\n size: string | undefined,\n): void {\n if (!size) return\n\n if (isGrokImagineImageModel(model)) {\n const parsed = parseGrokImagineSize(size)\n if (\n !parsed ||\n !GROK_IMAGINE_ASPECT_RATIOS.includes(parsed.aspectRatio) ||\n (parsed.resolution !== undefined &&\n !GROK_IMAGINE_RESOLUTIONS.includes(parsed.resolution))\n ) {\n throw new Error(\n `Size \"${size}\" is not supported by model \"${model}\". ` +\n `Expected an aspect ratio (${GROK_IMAGINE_ASPECT_RATIOS.join(', ')}) ` +\n `optionally suffixed with a resolution (\"16:9_2k\"; resolutions: ${GROK_IMAGINE_RESOLUTIONS.join(', ')}).`,\n )\n }\n return\n }\n\n const validSizes: Record<string, Array<string>> = {\n 'grok-2-image-1212': ['1024x1024', '1536x1024', '1024x1536'],\n }\n\n const modelSizes = validSizes[model]\n if (!modelSizes) {\n throw new Error(`Unknown image model: ${model}`)\n }\n\n if (!modelSizes.includes(size)) {\n throw new Error(\n `Size \"${size}\" is not supported by model \"${model}\". ` +\n `Supported sizes: ${modelSizes.join(', ')}`,\n )\n }\n}\n\n/**\n * Validates that the number of images is within bounds for the model.\n */\nexport function validateNumberOfImages(\n _model: string,\n numberOfImages: number | undefined,\n): void {\n if (numberOfImages === undefined) return\n\n // grok-2-image-1212 supports 1-10 images per request\n if (numberOfImages < 1 || numberOfImages > 10) {\n throw new Error(\n `Number of images must be between 1 and 10. Requested: ${numberOfImages}`,\n )\n }\n}\n\nexport const validatePrompt = (options: ImageValidationOptions) => {\n if (options.prompt.length === 0) {\n throw new Error('Prompt cannot be empty.')\n }\n // Grok image model supports up to 4000 characters\n if (options.prompt.length > 4000) {\n throw new Error(\n 'For grok-2-image-1212, prompt length must be less than or equal to 4000 characters.',\n )\n }\n}\n"],"mappings":";AAgDA,IAAM,6BAAoD;CACxD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,IAAM,2BAAkD,CAAC,MAAM,IAAI;;;;;;AAOnE,SAAgB,wBAAwB,OAAwB;CAC9D,OAAO,MAAM,WAAW,oBAAoB;AAC9C;;;;;;;AAQA,SAAgB,qBACd,MAC0D;CAE1D,MAAM,GAAG,aAAa,cADR,KAAK,MAAM,kCACW,KAAS,CAAC;CAC9C,IAAI,gBAAgB,KAAA,GAAW,OAAO,KAAA;CACtC,OAAO;EAAE;EAAa,GAAI,eAAe,KAAA,KAAa,EAAE,WAAW;CAAG;AACxE;;;;;AA+GA,SAAgB,kBACd,OACA,MACM;CACN,IAAI,CAAC,MAAM;CAEX,IAAI,wBAAwB,KAAK,GAAG;EAClC,MAAM,SAAS,qBAAqB,IAAI;EACxC,IACE,CAAC,UACD,CAAC,2BAA2B,SAAS,OAAO,WAAW,KACtD,OAAO,eAAe,KAAA,KACrB,CAAC,yBAAyB,SAAS,OAAO,UAAU,GAEtD,MAAM,IAAI,MACR,SAAS,KAAK,+BAA+B,MAAM,+BACpB,2BAA2B,KAAK,IAAI,EAAE,mEACD,yBAAyB,KAAK,IAAI,EAAE,GAC1G;EAEF;CACF;CAMA,MAAM,aAAa,EAHjB,qBAAqB;EAAC;EAAa;EAAa;CAAW,EAG1C,EAAW;CAC9B,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,wBAAwB,OAAO;CAGjD,IAAI,CAAC,WAAW,SAAS,IAAI,GAC3B,MAAM,IAAI,MACR,SAAS,KAAK,+BAA+B,MAAM,sBAC7B,WAAW,KAAK,IAAI,GAC5C;AAEJ;;;;AAKA,SAAgB,uBACd,QACA,gBACM;CACN,IAAI,mBAAmB,KAAA,GAAW;CAGlC,IAAI,iBAAiB,KAAK,iBAAiB,IACzC,MAAM,IAAI,MACR,yDAAyD,gBAC3D;AAEJ;AAEA,IAAa,kBAAkB,YAAoC;CACjE,IAAI,QAAQ,OAAO,WAAW,GAC5B,MAAM,IAAI,MAAM,yBAAyB;CAG3C,IAAI,QAAQ,OAAO,SAAS,KAC1B,MAAM,IAAI,MACR,qFACF;AAEJ"}
@@ -1,16 +1,16 @@
1
1
  export { GrokTextAdapter, createGrokText, grokText, type GrokTextConfig, type GrokTextProviderOptions, } from './adapters/text.js';
2
2
  export { createGrokSummarize, grokSummarize, type GrokSummarizeConfig, type GrokSummarizeModel, } from './adapters/summarize.js';
3
3
  export { GrokImageAdapter, createGrokImage, grokImage, type GrokImageConfig, } from './adapters/image.js';
4
- export type { GrokImageProviderOptions, GrokImageModelProviderOptionsByName, } from './image/image-provider-options.js';
4
+ export type { GrokImageProviderOptions, GrokImagineImageProviderOptions, GrokImagineImage2ProviderOptions, GrokImageModelProviderOptionsByName, } from './image/image-provider-options.js';
5
5
  export { GrokVideoAdapter, createGrokVideo, grokVideo, type GrokVideoConfig, } from './adapters/video.js';
6
6
  export { GROK_VIDEO_DURATIONS, getGrokVideoDurationOptions, } from './video/video-provider-options.js';
7
- export type { GrokVideoProviderOptions, GrokVideoModelProviderOptionsByName, GrokVideoModelSizeByName, GrokVideoModelDurationByName, GrokVideoAspectRatio, GrokVideoResolution, GrokVideoSize, } from './video/video-provider-options.js';
7
+ export type { GrokVideoMode, GrokVideoBaseProviderOptions, GrokVideoSourceProviderOptions, GrokVideoProviderOptions, GrokVideoRuntimeOptions, GrokVideoModelProviderOptionsByName, GrokVideoModelSizeByName, GrokVideoModelDurationByName, GrokVideoAspectRatio, GrokVideoResolution, GrokVideoSize, } from './video/video-provider-options.js';
8
8
  export { GrokSpeechAdapter, createGrokSpeech, grokSpeech, type GrokSpeechConfig, } from './adapters/tts.js';
9
9
  export type { GrokTTSProviderOptions, GrokTTSVoice, GrokTTSCodec, } from './audio/tts-provider-options.js';
10
10
  export { GrokTranscriptionAdapter, createGrokTranscription, grokTranscription, type GrokTranscriptionConfig, } from './adapters/transcription.js';
11
11
  export type { GrokTranscriptionProviderOptions, GrokSTTAudioFormat, } from './audio/transcription-provider-options.js';
12
12
  export type { GrokChatModelProviderOptionsByName, GrokChatModelToolCapabilitiesByName, GrokModelInputModalitiesByName, ResolveProviderOptions, ResolveInputModalities, GrokChatModel, GrokImageModel, GrokVideoModel, GrokTTSModel, GrokTranscriptionModel, GrokRealtimeModel, } from './model-meta.js';
13
- export { GROK_CHAT_MODELS, GROK_IMAGE_MODELS, GROK_VIDEO_MODELS, GROK_TTS_MODELS, GROK_TRANSCRIPTION_MODELS, GROK_REALTIME_MODELS, } from './model-meta.js';
13
+ export { GROK_CHAT_MODELS, GROK_IMAGE_MODELS, GROK_VIDEO_MODELS, GROK_TTS_MODELS, GROK_TRANSCRIPTION_MODELS, GROK_REALTIME_MODELS, GROK_DEFAULT_REALTIME_MODEL, } from './model-meta.js';
14
14
  export type { GrokTextMetadata, GrokImageMetadata, GrokAudioMetadata, GrokVideoMetadata, GrokDocumentMetadata, GrokMessageMetadataByModality, } from './message-types.js';
15
15
  export { grokRealtimeToken, grokRealtime } from './realtime/index.js';
16
16
  export type { GrokRealtimeVoice, GrokRealtimeTokenOptions, GrokRealtimeOptions, GrokTurnDetection, GrokSemanticVADConfig, GrokServerVADConfig, } from './realtime/index.js';
package/dist/esm/index.js CHANGED
@@ -5,8 +5,8 @@ import { GROK_VIDEO_DURATIONS, getGrokVideoDurationOptions } from "./video/video
5
5
  import { GrokVideoAdapter, createGrokVideo, grokVideo } from "./adapters/video.js";
6
6
  import { GrokSpeechAdapter, createGrokSpeech, grokSpeech } from "./adapters/tts.js";
7
7
  import { GrokTranscriptionAdapter, createGrokTranscription, grokTranscription } from "./adapters/transcription.js";
8
- import { GROK_CHAT_MODELS, GROK_IMAGE_MODELS, GROK_REALTIME_MODELS, GROK_TRANSCRIPTION_MODELS, GROK_TTS_MODELS, GROK_VIDEO_MODELS } from "./model-meta.js";
8
+ import { GROK_CHAT_MODELS, GROK_DEFAULT_REALTIME_MODEL, GROK_IMAGE_MODELS, GROK_REALTIME_MODELS, GROK_TRANSCRIPTION_MODELS, GROK_TTS_MODELS, GROK_VIDEO_MODELS } from "./model-meta.js";
9
9
  import { grokRealtimeToken } from "./realtime/token.js";
10
10
  import { grokRealtime } from "./realtime/adapter.js";
11
11
  import "./realtime/index.js";
12
- export { GROK_CHAT_MODELS, GROK_IMAGE_MODELS, GROK_REALTIME_MODELS, GROK_TRANSCRIPTION_MODELS, GROK_TTS_MODELS, GROK_VIDEO_DURATIONS, GROK_VIDEO_MODELS, GrokImageAdapter, GrokSpeechAdapter, GrokTextAdapter, GrokTranscriptionAdapter, GrokVideoAdapter, createGrokImage, createGrokSpeech, createGrokSummarize, createGrokText, createGrokTranscription, createGrokVideo, getGrokVideoDurationOptions, grokImage, grokRealtime, grokRealtimeToken, grokSpeech, grokSummarize, grokText, grokTranscription, grokVideo };
12
+ export { GROK_CHAT_MODELS, GROK_DEFAULT_REALTIME_MODEL, GROK_IMAGE_MODELS, GROK_REALTIME_MODELS, GROK_TRANSCRIPTION_MODELS, GROK_TTS_MODELS, GROK_VIDEO_DURATIONS, GROK_VIDEO_MODELS, GrokImageAdapter, GrokSpeechAdapter, GrokTextAdapter, GrokTranscriptionAdapter, GrokVideoAdapter, createGrokImage, createGrokSpeech, createGrokSummarize, createGrokText, createGrokTranscription, createGrokVideo, getGrokVideoDurationOptions, grokImage, grokRealtime, grokRealtimeToken, grokSpeech, grokSummarize, grokText, grokTranscription, grokVideo };
@@ -1,4 +1,42 @@
1
1
  import { GrokBuildProviderOptions, GrokTextProviderOptions } from './text/text-provider-options.js';
2
+ declare const GROK_4_5: {
3
+ readonly name: "grok-4.5";
4
+ readonly context_window: 500000;
5
+ readonly supports: {
6
+ readonly input: ["text", "image", "document"];
7
+ readonly output: ["text"];
8
+ readonly capabilities: ["reasoning", "structured_outputs", "tool_calling"];
9
+ readonly tools: readonly [];
10
+ };
11
+ readonly pricing: {
12
+ readonly input: {
13
+ readonly normal: 2;
14
+ readonly cached: 0.3;
15
+ };
16
+ readonly output: {
17
+ readonly normal: 6;
18
+ };
19
+ };
20
+ };
21
+ declare const GROK_4_6: {
22
+ readonly name: "grok-4.6";
23
+ readonly context_window: 500000;
24
+ readonly supports: {
25
+ readonly input: ["text", "image", "document"];
26
+ readonly output: ["text"];
27
+ readonly capabilities: ["reasoning", "structured_outputs", "tool_calling"];
28
+ readonly tools: readonly [];
29
+ };
30
+ readonly pricing: {
31
+ readonly input: {
32
+ readonly normal: 2;
33
+ readonly cached: 0.5;
34
+ };
35
+ readonly output: {
36
+ readonly normal: 6;
37
+ };
38
+ };
39
+ };
2
40
  export type GrokProviderToolKind = 'web_search' | 'x_search' | 'file_search' | 'mcp';
3
41
  declare const GROK_4_3: {
4
42
  readonly name: "grok-4.3";
@@ -41,11 +79,11 @@ declare const GROK_BUILD_0_1: {
41
79
  /**
42
80
  * Grok chat models supported by the Responses adapter.
43
81
  */
44
- export declare const GROK_CHAT_MODELS: readonly ["grok-build-0.1", "grok-4.3"];
82
+ export declare const GROK_CHAT_MODELS: readonly ["grok-4.5", "grok-4.6", "grok-build-0.1", "grok-4.3"];
45
83
  /**
46
84
  * Grok Image Generation Models
47
85
  */
48
- export declare const GROK_IMAGE_MODELS: readonly ["grok-2-image-1212", "grok-imagine-image", "grok-imagine-image-quality"];
86
+ export declare const GROK_IMAGE_MODELS: readonly ["grok-2-image-1212", "grok-imagine-image", "grok-imagine-image-2.0", "grok-imagine-image-quality"];
49
87
  /**
50
88
  * Grok Video Generation Models (xAI Imagine API)
51
89
  *
@@ -54,7 +92,13 @@ export declare const GROK_IMAGE_MODELS: readonly ["grok-2-image-1212", "grok-ima
54
92
  export declare const GROK_VIDEO_MODELS: readonly ["grok-imagine-video", "grok-imagine-video-1.5"];
55
93
  export declare const GROK_TTS_MODELS: readonly ["grok-tts"];
56
94
  export declare const GROK_TRANSCRIPTION_MODELS: readonly ["grok-stt"];
57
- export declare const GROK_REALTIME_MODELS: readonly ["grok-voice-fast-1.0", "grok-voice-think-fast-1.0"];
95
+ export declare const GROK_REALTIME_MODELS: readonly ["grok-voice-think-fast-2.0", "grok-voice-latest", "grok-voice-fast-1.0", "grok-voice-think-fast-1.0"];
96
+ /**
97
+ * Default speech-to-speech model used by the realtime token issuer and the
98
+ * realtime client adapter when no model is specified. Single source of truth
99
+ * so a future default bump cannot leave the two sides disagreeing.
100
+ */
101
+ export declare const GROK_DEFAULT_REALTIME_MODEL: GrokRealtimeModel;
58
102
  export type GrokChatModel = (typeof GROK_CHAT_MODELS)[number];
59
103
  export type GrokImageModel = (typeof GROK_IMAGE_MODELS)[number];
60
104
  export type GrokVideoModel = (typeof GROK_VIDEO_MODELS)[number];
@@ -68,6 +112,8 @@ export type GrokRealtimeModel = (typeof GROK_REALTIME_MODELS)[number];
68
112
  export type GrokModelInputModalitiesByName = {
69
113
  [GROK_4_3.name]: typeof GROK_4_3.supports.input;
70
114
  [GROK_BUILD_0_1.name]: typeof GROK_BUILD_0_1.supports.input;
115
+ [GROK_4_5.name]: typeof GROK_4_5.supports.input;
116
+ [GROK_4_6.name]: typeof GROK_4_6.supports.input;
71
117
  };
72
118
  /**
73
119
  * Type-only map from Grok chat model name to its supported provider tools.
@@ -1,4 +1,54 @@
1
1
  //#region src/model-meta.ts
2
+ var GROK_4_5 = {
3
+ name: "grok-4.5",
4
+ context_window: 5e5,
5
+ supports: {
6
+ input: [
7
+ "text",
8
+ "image",
9
+ "document"
10
+ ],
11
+ output: ["text"],
12
+ capabilities: [
13
+ "reasoning",
14
+ "structured_outputs",
15
+ "tool_calling"
16
+ ],
17
+ tools: []
18
+ },
19
+ pricing: {
20
+ input: {
21
+ normal: 2,
22
+ cached: .3
23
+ },
24
+ output: { normal: 6 }
25
+ }
26
+ };
27
+ var GROK_4_6 = {
28
+ name: "grok-4.6",
29
+ context_window: 5e5,
30
+ supports: {
31
+ input: [
32
+ "text",
33
+ "image",
34
+ "document"
35
+ ],
36
+ output: ["text"],
37
+ capabilities: [
38
+ "reasoning",
39
+ "structured_outputs",
40
+ "tool_calling"
41
+ ],
42
+ tools: []
43
+ },
44
+ pricing: {
45
+ input: {
46
+ normal: 2,
47
+ cached: .5
48
+ },
49
+ output: { normal: 6 }
50
+ }
51
+ };
2
52
  var GROK_RESPONSES_TOOLS = [
3
53
  "web_search",
4
54
  "x_search",
@@ -38,10 +88,25 @@ var GROK_IMAGINE_IMAGE_QUALITY = {
38
88
  output: { normal: .05 }
39
89
  }
40
90
  };
91
+ var GROK_IMAGINE_IMAGE_2_0 = {
92
+ name: "grok-imagine-image-2.0",
93
+ supports: {
94
+ input: ["text", "image"],
95
+ output: ["image"]
96
+ },
97
+ pricing: {
98
+ input: { normal: 0 },
99
+ output: { normal: .04 }
100
+ }
101
+ };
41
102
  var GROK_IMAGINE_VIDEO = {
42
103
  name: "grok-imagine-video",
43
104
  supports: {
44
- input: ["text", "image"],
105
+ input: [
106
+ "text",
107
+ "image",
108
+ "video"
109
+ ],
45
110
  output: ["video", "audio"]
46
111
  },
47
112
  pricing: {
@@ -81,10 +146,7 @@ var GROK_4_3 = {
81
146
  output: { normal: 2.5 }
82
147
  }
83
148
  };
84
- /**
85
- * Grok chat models supported by the Responses adapter.
86
- */
87
- var GROK_CHAT_MODELS = [{
149
+ var GROK_BUILD_0_1 = {
88
150
  name: "grok-build-0.1",
89
151
  context_window: 256e3,
90
152
  supports: {
@@ -104,13 +166,23 @@ var GROK_CHAT_MODELS = [{
104
166
  },
105
167
  output: { normal: 2 }
106
168
  }
107
- }.name, GROK_4_3.name];
169
+ };
170
+ /**
171
+ * Grok chat models supported by the Responses adapter.
172
+ */
173
+ var GROK_CHAT_MODELS = [
174
+ GROK_4_5.name,
175
+ GROK_4_6.name,
176
+ GROK_BUILD_0_1.name,
177
+ GROK_4_3.name
178
+ ];
108
179
  /**
109
180
  * Grok Image Generation Models
110
181
  */
111
182
  var GROK_IMAGE_MODELS = [
112
183
  GROK_2_IMAGE.name,
113
184
  GROK_IMAGINE_IMAGE.name,
185
+ GROK_IMAGINE_IMAGE_2_0.name,
114
186
  GROK_IMAGINE_IMAGE_QUALITY.name
115
187
  ];
116
188
  /**
@@ -142,6 +214,7 @@ var GROK_VOICE_FAST_1 = {
142
214
  tools: []
143
215
  }
144
216
  };
217
+ /** @deprecated xAI has deprecated grok-voice-think-fast-1.0 — use grok-voice-think-fast-2.0. */
145
218
  var GROK_VOICE_THINK_FAST_1 = {
146
219
  name: "grok-voice-think-fast-1.0",
147
220
  supports: {
@@ -151,10 +224,39 @@ var GROK_VOICE_THINK_FAST_1 = {
151
224
  tools: []
152
225
  }
153
226
  };
227
+ var GROK_VOICE_THINK_FAST_2 = {
228
+ name: "grok-voice-think-fast-2.0",
229
+ supports: {
230
+ input: ["audio", "text"],
231
+ output: ["audio", "text"],
232
+ capabilities: ["reasoning", "tool_calling"],
233
+ tools: []
234
+ }
235
+ };
236
+ var GROK_VOICE_LATEST = {
237
+ name: "grok-voice-latest",
238
+ supports: {
239
+ input: ["audio", "text"],
240
+ output: ["audio", "text"],
241
+ capabilities: ["reasoning", "tool_calling"],
242
+ tools: []
243
+ }
244
+ };
154
245
  var GROK_TTS_MODELS = [GROK_TTS.name];
155
246
  var GROK_TRANSCRIPTION_MODELS = [GROK_STT.name];
156
- var GROK_REALTIME_MODELS = [GROK_VOICE_FAST_1.name, GROK_VOICE_THINK_FAST_1.name];
247
+ var GROK_REALTIME_MODELS = [
248
+ GROK_VOICE_THINK_FAST_2.name,
249
+ GROK_VOICE_LATEST.name,
250
+ GROK_VOICE_FAST_1.name,
251
+ GROK_VOICE_THINK_FAST_1.name
252
+ ];
253
+ /**
254
+ * Default speech-to-speech model used by the realtime token issuer and the
255
+ * realtime client adapter when no model is specified. Single source of truth
256
+ * so a future default bump cannot leave the two sides disagreeing.
257
+ */
258
+ var GROK_DEFAULT_REALTIME_MODEL = "grok-voice-think-fast-2.0";
157
259
  //#endregion
158
- export { GROK_CHAT_MODELS, GROK_IMAGE_MODELS, GROK_REALTIME_MODELS, GROK_TRANSCRIPTION_MODELS, GROK_TTS_MODELS, GROK_VIDEO_MODELS };
260
+ export { GROK_CHAT_MODELS, GROK_DEFAULT_REALTIME_MODEL, GROK_IMAGE_MODELS, GROK_REALTIME_MODELS, GROK_TRANSCRIPTION_MODELS, GROK_TTS_MODELS, GROK_VIDEO_MODELS };
159
261
 
160
262
  //# sourceMappingURL=model-meta.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"model-meta.js","names":[],"sources":["../../src/model-meta.ts"],"sourcesContent":["/**\n * Model metadata interface for documentation and type inference\n */\nimport type {\n GrokBuildProviderOptions,\n GrokTextProviderOptions,\n} from './text/text-provider-options'\n\ninterface ModelMeta {\n name: string\n supports: {\n input: Array<'text' | 'image' | 'audio' | 'video' | 'document'>\n output: Array<'text' | 'image' | 'audio' | 'video'>\n capabilities?: Array<'reasoning' | 'tool_calling' | 'structured_outputs'>\n tools?: ReadonlyArray<GrokProviderToolKind>\n }\n max_input_tokens?: number\n max_output_tokens?: number\n context_window?: number\n knowledge_cutoff?: string\n pricing?: {\n input: {\n normal: number\n cached?: number\n }\n output: {\n normal: number\n }\n }\n}\n\nexport type GrokProviderToolKind =\n | 'web_search'\n | 'x_search'\n | 'file_search'\n | 'mcp'\n\nconst GROK_RESPONSES_TOOLS = [\n 'web_search',\n 'x_search',\n 'file_search',\n 'mcp',\n] as const satisfies ReadonlyArray<GrokProviderToolKind>\n\nconst GROK_2_IMAGE = {\n name: 'grok-2-image-1212',\n supports: {\n input: ['text'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0.07,\n },\n output: {\n normal: 0.07,\n },\n },\n} as const satisfies ModelMeta\n\n// Imagine API image models. Pricing is per generated image (output only).\nconst GROK_IMAGINE_IMAGE = {\n name: 'grok-imagine-image',\n supports: {\n input: ['text', 'image'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.02,\n },\n },\n} as const satisfies ModelMeta\n\nconst GROK_IMAGINE_IMAGE_QUALITY = {\n name: 'grok-imagine-image-quality',\n supports: {\n input: ['text', 'image'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.05,\n },\n },\n} as const satisfies ModelMeta\n\n// Imagine API video models. Pricing is per second of generated video\n// (output only); generated videos carry an audio track.\n//\n// grok-imagine-video (v1.0) supports both text-to-video (a starting image is\n// optional) and image-to-video. grok-imagine-video-1.5 is image-to-video\n// only: a starting-frame image is required (the text prompt describes the\n// desired motion) — its text-to-video is rejected by the API.\nconst GROK_IMAGINE_VIDEO = {\n name: 'grok-imagine-video',\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n // per second of video\n normal: 0.05,\n },\n },\n} as const satisfies ModelMeta\n\nconst GROK_IMAGINE_VIDEO_1_5 = {\n name: 'grok-imagine-video-1.5',\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n // per second of video\n normal: 0.08,\n },\n },\n} as const satisfies ModelMeta\n\nconst GROK_4_3 = {\n name: 'grok-4.3',\n context_window: 1_000_000,\n supports: {\n input: ['text', 'image'],\n output: ['text'],\n capabilities: ['reasoning', 'structured_outputs', 'tool_calling'],\n tools: GROK_RESPONSES_TOOLS,\n },\n pricing: {\n input: {\n normal: 1.25,\n cached: 0.2,\n },\n output: {\n normal: 2.5,\n },\n },\n} as const satisfies ModelMeta\n\nconst GROK_BUILD_0_1 = {\n name: 'grok-build-0.1',\n context_window: 256_000,\n supports: {\n input: ['text', 'image'],\n output: ['text'],\n capabilities: ['reasoning', 'structured_outputs', 'tool_calling'],\n tools: GROK_RESPONSES_TOOLS,\n },\n pricing: {\n input: {\n normal: 1,\n cached: 0.2,\n },\n output: {\n normal: 2,\n },\n },\n} as const satisfies ModelMeta\n\n/**\n * Grok chat models supported by the Responses adapter.\n */\nexport const GROK_CHAT_MODELS = [GROK_BUILD_0_1.name, GROK_4_3.name] as const\n\n/**\n * Grok Image Generation Models\n */\nexport const GROK_IMAGE_MODELS = [\n GROK_2_IMAGE.name,\n GROK_IMAGINE_IMAGE.name,\n GROK_IMAGINE_IMAGE_QUALITY.name,\n] as const\n\n/**\n * Grok Video Generation Models (xAI Imagine API)\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport const GROK_VIDEO_MODELS = [\n GROK_IMAGINE_VIDEO.name,\n GROK_IMAGINE_VIDEO_1_5.name,\n] as const\n\n// xAI's `/v1/tts` endpoint is endpoint-addressed and does not take a `model`\n// parameter. This synthetic identifier satisfies the SDK's `TTSOptions.model`\n// contract and provides a stable value for logging and fixture matching.\nconst GROK_TTS = {\n name: 'grok-tts',\n supports: {\n input: ['text'],\n output: ['audio'],\n },\n} as const satisfies ModelMeta\n\n// xAI's `/v1/stt` endpoint is endpoint-addressed and does not take a `model`\n// parameter. This synthetic identifier satisfies the SDK's\n// `TranscriptionOptions.model` contract.\nconst GROK_STT = {\n name: 'grok-stt',\n supports: {\n input: ['audio'],\n output: ['text'],\n },\n} as const satisfies ModelMeta\n\nconst GROK_VOICE_FAST_1 = {\n name: 'grok-voice-fast-1.0',\n supports: {\n input: ['audio', 'text'],\n output: ['audio', 'text'],\n capabilities: ['tool_calling'],\n tools: [] as const,\n },\n} as const satisfies ModelMeta\n\nconst GROK_VOICE_THINK_FAST_1 = {\n name: 'grok-voice-think-fast-1.0',\n supports: {\n input: ['audio', 'text'],\n output: ['audio', 'text'],\n capabilities: ['reasoning', 'tool_calling'],\n tools: [] as const,\n },\n} as const satisfies ModelMeta\n\nexport const GROK_TTS_MODELS = [GROK_TTS.name] as const\n\nexport const GROK_TRANSCRIPTION_MODELS = [GROK_STT.name] as const\n\nexport const GROK_REALTIME_MODELS = [\n GROK_VOICE_FAST_1.name,\n GROK_VOICE_THINK_FAST_1.name,\n] as const\n\nexport type GrokChatModel = (typeof GROK_CHAT_MODELS)[number]\nexport type GrokImageModel = (typeof GROK_IMAGE_MODELS)[number]\nexport type GrokVideoModel = (typeof GROK_VIDEO_MODELS)[number]\nexport type GrokTTSModel = (typeof GROK_TTS_MODELS)[number]\nexport type GrokTranscriptionModel = (typeof GROK_TRANSCRIPTION_MODELS)[number]\nexport type GrokRealtimeModel = (typeof GROK_REALTIME_MODELS)[number]\n\n/**\n * Type-only map from Grok chat model name to its supported input modalities.\n * Used for type inference when constructing multimodal messages.\n */\nexport type GrokModelInputModalitiesByName = {\n [GROK_4_3.name]: typeof GROK_4_3.supports.input\n [GROK_BUILD_0_1.name]: typeof GROK_BUILD_0_1.supports.input\n}\n\n/**\n * Type-only map from Grok chat model name to its supported provider tools.\n * Keeps Grok provider-tool factories type-checked against the models that\n * advertise xAI Responses server-side tools.\n */\nexport type GrokChatModelToolCapabilitiesByName = {\n [GROK_4_3.name]: typeof GROK_4_3.supports.tools\n [GROK_BUILD_0_1.name]: typeof GROK_BUILD_0_1.supports.tools\n}\n\nexport type GrokProviderOptions = GrokTextProviderOptions\n\n/**\n * Type-only map from Grok chat model name to its provider options type.\n */\nexport type GrokChatModelProviderOptionsByName = {\n [GROK_4_3.name]: GrokProviderOptions\n [GROK_BUILD_0_1.name]: GrokBuildProviderOptions\n}\n\n// ===========================\n// Type Resolution Helpers\n// ===========================\n\n/**\n * Resolve provider options for a specific model.\n * If the model has explicit options in the map, use those; otherwise use base options.\n */\nexport type ResolveProviderOptions<TModel extends string> =\n TModel extends keyof GrokChatModelProviderOptionsByName\n ? GrokChatModelProviderOptionsByName[TModel]\n : GrokProviderOptions\n\n/**\n * Resolve input modalities for a specific model.\n * If the model has explicit modalities in the map, use those; otherwise use text only.\n */\nexport type ResolveInputModalities<TModel extends string> =\n TModel extends keyof GrokModelInputModalitiesByName\n ? GrokModelInputModalitiesByName[TModel]\n : readonly ['text']\n"],"mappings":"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"}
1
+ {"version":3,"file":"model-meta.js","names":[],"sources":["../../src/model-meta.ts"],"sourcesContent":["/**\n * Model metadata interface for documentation and type inference\n */\nimport type {\n GrokBuildProviderOptions,\n GrokTextProviderOptions,\n} from './text/text-provider-options'\n\ninterface ModelMeta {\n name: string\n supports: {\n input: Array<'text' | 'image' | 'audio' | 'video' | 'document'>\n output: Array<'text' | 'image' | 'audio' | 'video'>\n capabilities?: Array<'reasoning' | 'tool_calling' | 'structured_outputs'>\n tools?: ReadonlyArray<GrokProviderToolKind>\n }\n max_input_tokens?: number\n max_output_tokens?: number\n context_window?: number\n knowledge_cutoff?: string\n pricing?: {\n input: {\n normal: number\n cached?: number\n }\n output: {\n normal: number\n }\n }\n}\n\nconst GROK_4_5 = {\n name: 'grok-4.5',\n context_window: 500_000,\n supports: {\n input: ['text', 'image', 'document'],\n output: ['text'],\n capabilities: ['reasoning', 'structured_outputs', 'tool_calling'],\n tools: [],\n },\n pricing: {\n input: {\n normal: 2,\n cached: 0.3,\n },\n output: {\n normal: 6,\n },\n },\n} as const satisfies ModelMeta\n\nconst GROK_4_6 = {\n name: 'grok-4.6',\n context_window: 500_000,\n supports: {\n input: ['text', 'image', 'document'],\n output: ['text'],\n capabilities: ['reasoning', 'structured_outputs', 'tool_calling'],\n tools: [],\n },\n pricing: {\n input: {\n normal: 2,\n cached: 0.5,\n },\n output: {\n normal: 6,\n },\n },\n} as const satisfies ModelMeta\n\nexport type GrokProviderToolKind =\n | 'web_search'\n | 'x_search'\n | 'file_search'\n | 'mcp'\n\nconst GROK_RESPONSES_TOOLS = [\n 'web_search',\n 'x_search',\n 'file_search',\n 'mcp',\n] as const satisfies ReadonlyArray<GrokProviderToolKind>\n\nconst GROK_2_IMAGE = {\n name: 'grok-2-image-1212',\n supports: {\n input: ['text'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0.07,\n },\n output: {\n normal: 0.07,\n },\n },\n} as const satisfies ModelMeta\n\n// Imagine API image models. Pricing is per generated image (output only).\nconst GROK_IMAGINE_IMAGE = {\n name: 'grok-imagine-image',\n supports: {\n input: ['text', 'image'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.02,\n },\n },\n} as const satisfies ModelMeta\n\nconst GROK_IMAGINE_IMAGE_QUALITY = {\n name: 'grok-imagine-image-quality',\n supports: {\n input: ['text', 'image'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.05,\n },\n },\n} as const satisfies ModelMeta\n\n// xAI's recommended Imagine image model. Supports the 2.0-only `quality`\n// provider option ('low' | 'medium', default 'medium').\nconst GROK_IMAGINE_IMAGE_2_0 = {\n name: 'grok-imagine-image-2.0',\n supports: {\n input: ['text', 'image'],\n output: ['image'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n normal: 0.04,\n },\n },\n} as const satisfies ModelMeta\n\n// Imagine API video models. Pricing is per second of generated video\n// (output only); generated videos carry an audio track.\n//\n// Both models support text-to-video and image-to-video (a starting-frame\n// image is optional). grok-imagine-video-1.5 is the documented default: it\n// adds native 1080p for text-to-video / image-to-video plus\n// reference-to-video (`reference_images` / `reference_audios`; reference\n// output is capped at 720p). Source-video edit (`/v1/videos/edits`) and\n// extend (`/v1/videos/extensions`) are grok-imagine-video only — xAI's\n// 1.5 model page lists text+image input, not video.\nconst GROK_IMAGINE_VIDEO = {\n name: 'grok-imagine-video',\n supports: {\n input: ['text', 'image', 'video'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n // per second of video\n normal: 0.05,\n },\n },\n} as const satisfies ModelMeta\n\nconst GROK_IMAGINE_VIDEO_1_5 = {\n name: 'grok-imagine-video-1.5',\n supports: {\n input: ['text', 'image'],\n output: ['video', 'audio'],\n },\n pricing: {\n input: {\n normal: 0,\n },\n output: {\n // per second of video\n normal: 0.08,\n },\n },\n} as const satisfies ModelMeta\n\nconst GROK_4_3 = {\n name: 'grok-4.3',\n context_window: 1_000_000,\n supports: {\n input: ['text', 'image'],\n output: ['text'],\n capabilities: ['reasoning', 'structured_outputs', 'tool_calling'],\n tools: GROK_RESPONSES_TOOLS,\n },\n pricing: {\n input: {\n normal: 1.25,\n cached: 0.2,\n },\n output: {\n normal: 2.5,\n },\n },\n} as const satisfies ModelMeta\n\nconst GROK_BUILD_0_1 = {\n name: 'grok-build-0.1',\n context_window: 256_000,\n supports: {\n input: ['text', 'image'],\n output: ['text'],\n capabilities: ['reasoning', 'structured_outputs', 'tool_calling'],\n tools: GROK_RESPONSES_TOOLS,\n },\n pricing: {\n input: {\n normal: 1,\n cached: 0.2,\n },\n output: {\n normal: 2,\n },\n },\n} as const satisfies ModelMeta\n\n/**\n * Grok chat models supported by the Responses adapter.\n */\nexport const GROK_CHAT_MODELS = [\n GROK_4_5.name,\n GROK_4_6.name,\n GROK_BUILD_0_1.name,\n GROK_4_3.name,\n] as const\n\n/**\n * Grok Image Generation Models\n */\nexport const GROK_IMAGE_MODELS = [\n GROK_2_IMAGE.name,\n GROK_IMAGINE_IMAGE.name,\n GROK_IMAGINE_IMAGE_2_0.name,\n GROK_IMAGINE_IMAGE_QUALITY.name,\n] as const\n\n/**\n * Grok Video Generation Models (xAI Imagine API)\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport const GROK_VIDEO_MODELS = [\n GROK_IMAGINE_VIDEO.name,\n GROK_IMAGINE_VIDEO_1_5.name,\n] as const\n\n// xAI's `/v1/tts` endpoint is endpoint-addressed and does not take a `model`\n// parameter. This synthetic identifier satisfies the SDK's `TTSOptions.model`\n// contract and provides a stable value for logging and fixture matching.\nconst GROK_TTS = {\n name: 'grok-tts',\n supports: {\n input: ['text'],\n output: ['audio'],\n },\n} as const satisfies ModelMeta\n\n// xAI's `/v1/stt` endpoint is endpoint-addressed and does not take a `model`\n// parameter. This synthetic identifier satisfies the SDK's\n// `TranscriptionOptions.model` contract.\nconst GROK_STT = {\n name: 'grok-stt',\n supports: {\n input: ['audio'],\n output: ['text'],\n },\n} as const satisfies ModelMeta\n\nconst GROK_VOICE_FAST_1 = {\n name: 'grok-voice-fast-1.0',\n supports: {\n input: ['audio', 'text'],\n output: ['audio', 'text'],\n capabilities: ['tool_calling'],\n tools: [] as const,\n },\n} as const satisfies ModelMeta\n\n/** @deprecated xAI has deprecated grok-voice-think-fast-1.0 — use grok-voice-think-fast-2.0. */\nconst GROK_VOICE_THINK_FAST_1 = {\n name: 'grok-voice-think-fast-1.0',\n supports: {\n input: ['audio', 'text'],\n output: ['audio', 'text'],\n capabilities: ['reasoning', 'tool_calling'],\n tools: [] as const,\n },\n} as const satisfies ModelMeta\n\n// xAI's current recommended speech-to-speech model.\nconst GROK_VOICE_THINK_FAST_2 = {\n name: 'grok-voice-think-fast-2.0',\n supports: {\n input: ['audio', 'text'],\n output: ['audio', 'text'],\n capabilities: ['reasoning', 'tool_calling'],\n tools: [] as const,\n },\n} as const satisfies ModelMeta\n\n// Rolling alias used by xAI's realtime docs examples; always points at the\n// latest speech-to-speech model.\nconst GROK_VOICE_LATEST = {\n name: 'grok-voice-latest',\n supports: {\n input: ['audio', 'text'],\n output: ['audio', 'text'],\n capabilities: ['reasoning', 'tool_calling'],\n tools: [] as const,\n },\n} as const satisfies ModelMeta\n\nexport const GROK_TTS_MODELS = [GROK_TTS.name] as const\n\nexport const GROK_TRANSCRIPTION_MODELS = [GROK_STT.name] as const\n\nexport const GROK_REALTIME_MODELS = [\n GROK_VOICE_THINK_FAST_2.name,\n GROK_VOICE_LATEST.name,\n GROK_VOICE_FAST_1.name,\n GROK_VOICE_THINK_FAST_1.name,\n] as const\n\n/**\n * Default speech-to-speech model used by the realtime token issuer and the\n * realtime client adapter when no model is specified. Single source of truth\n * so a future default bump cannot leave the two sides disagreeing.\n */\nexport const GROK_DEFAULT_REALTIME_MODEL: GrokRealtimeModel =\n 'grok-voice-think-fast-2.0'\n\nexport type GrokChatModel = (typeof GROK_CHAT_MODELS)[number]\nexport type GrokImageModel = (typeof GROK_IMAGE_MODELS)[number]\nexport type GrokVideoModel = (typeof GROK_VIDEO_MODELS)[number]\nexport type GrokTTSModel = (typeof GROK_TTS_MODELS)[number]\nexport type GrokTranscriptionModel = (typeof GROK_TRANSCRIPTION_MODELS)[number]\nexport type GrokRealtimeModel = (typeof GROK_REALTIME_MODELS)[number]\n\n/**\n * Type-only map from Grok chat model name to its supported input modalities.\n * Used for type inference when constructing multimodal messages.\n */\nexport type GrokModelInputModalitiesByName = {\n [GROK_4_3.name]: typeof GROK_4_3.supports.input\n [GROK_BUILD_0_1.name]: typeof GROK_BUILD_0_1.supports.input\n [GROK_4_5.name]: typeof GROK_4_5.supports.input\n [GROK_4_6.name]: typeof GROK_4_6.supports.input\n}\n\n/**\n * Type-only map from Grok chat model name to its supported provider tools.\n * Keeps Grok provider-tool factories type-checked against the models that\n * advertise xAI Responses server-side tools.\n */\nexport type GrokChatModelToolCapabilitiesByName = {\n [GROK_4_3.name]: typeof GROK_4_3.supports.tools\n [GROK_BUILD_0_1.name]: typeof GROK_BUILD_0_1.supports.tools\n}\n\nexport type GrokProviderOptions = GrokTextProviderOptions\n\n/**\n * Type-only map from Grok chat model name to its provider options type.\n */\nexport type GrokChatModelProviderOptionsByName = {\n [GROK_4_3.name]: GrokProviderOptions\n [GROK_BUILD_0_1.name]: GrokBuildProviderOptions\n}\n\n// ===========================\n// Type Resolution Helpers\n// ===========================\n\n/**\n * Resolve provider options for a specific model.\n * If the model has explicit options in the map, use those; otherwise use base options.\n */\nexport type ResolveProviderOptions<TModel extends string> =\n TModel extends keyof GrokChatModelProviderOptionsByName\n ? GrokChatModelProviderOptionsByName[TModel]\n : GrokProviderOptions\n\n/**\n * Resolve input modalities for a specific model.\n * If the model has explicit modalities in the map, use those; otherwise use text only.\n */\nexport type ResolveInputModalities<TModel extends string> =\n TModel extends keyof GrokModelInputModalitiesByName\n ? GrokModelInputModalitiesByName[TModel]\n : readonly ['text']\n"],"mappings":"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"}