@tanstack/ai-grok 0.14.8 → 0.14.10

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 (36) hide show
  1. package/dist/esm/adapters/image.js +228 -193
  2. package/dist/esm/adapters/image.js.map +1 -1
  3. package/dist/esm/adapters/summarize.js +49 -12
  4. package/dist/esm/adapters/summarize.js.map +1 -1
  5. package/dist/esm/adapters/text.js +82 -38
  6. package/dist/esm/adapters/text.js.map +1 -1
  7. package/dist/esm/adapters/transcription.js +133 -114
  8. package/dist/esm/adapters/transcription.js.map +1 -1
  9. package/dist/esm/adapters/tts.js +147 -130
  10. package/dist/esm/adapters/tts.js.map +1 -1
  11. package/dist/esm/adapters/video.js +275 -226
  12. package/dist/esm/adapters/video.js.map +1 -1
  13. package/dist/esm/image/image-provider-options.js +64 -66
  14. package/dist/esm/image/image-provider-options.js.map +1 -1
  15. package/dist/esm/index.js +3 -31
  16. package/dist/esm/model-meta.js +149 -47
  17. package/dist/esm/model-meta.js.map +1 -1
  18. package/dist/esm/realtime/adapter.js +729 -812
  19. package/dist/esm/realtime/adapter.js.map +1 -1
  20. package/dist/esm/realtime/index.js +3 -0
  21. package/dist/esm/realtime/token.js +78 -72
  22. package/dist/esm/realtime/token.js.map +1 -1
  23. package/dist/esm/tools/index.js +57 -96
  24. package/dist/esm/tools/index.js.map +1 -1
  25. package/dist/esm/utils/audio.js +116 -162
  26. package/dist/esm/utils/audio.js.map +1 -1
  27. package/dist/esm/utils/client.js +22 -16
  28. package/dist/esm/utils/client.js.map +1 -1
  29. package/dist/esm/utils/index.js +5 -0
  30. package/dist/esm/utils/schema-converter.js +2 -0
  31. package/dist/esm/video/video-provider-options.js +83 -57
  32. package/dist/esm/video/video-provider-options.js.map +1 -1
  33. package/package.json +8 -8
  34. package/src/realtime/adapter.ts +1 -1
  35. package/src/utils/audio.ts +1 -1
  36. package/dist/esm/index.js.map +0 -1
@@ -1,67 +1,93 @@
1
- const GROK_VIDEO_ASPECT_RATIOS = [
2
- "1:1",
3
- "16:9",
4
- "9:16",
5
- "4:3",
6
- "3:4",
7
- "3:2",
8
- "2:3"
1
+ //#region src/video/video-provider-options.ts
2
+ var GROK_VIDEO_ASPECT_RATIOS = [
3
+ "1:1",
4
+ "16:9",
5
+ "9:16",
6
+ "4:3",
7
+ "3:4",
8
+ "3:2",
9
+ "2:3"
9
10
  ];
10
- const GROK_VIDEO_RESOLUTIONS = ["480p", "720p", "1080p"];
11
- const GROK_VIDEO_MIN_DURATION = 1;
12
- const GROK_VIDEO_MAX_DURATION = 15;
11
+ var GROK_VIDEO_RESOLUTIONS = [
12
+ "480p",
13
+ "720p",
14
+ "1080p"
15
+ ];
16
+ /**
17
+ * Parses a grok video size string into its components.
18
+ * Format: "aspectRatio" or "aspectRatio_resolution",
19
+ * e.g. "16:9_720p" → { aspectRatio: "16:9", resolution: "720p" }.
20
+ * Returns undefined when the string doesn't match the template.
21
+ */
13
22
  function parseGrokVideoSize(size) {
14
- const match = size.match(/^([\d.]+:[\d.]+)(?:_(.+))?$/);
15
- const [, aspectRatio, resolution] = match ?? [];
16
- if (aspectRatio === void 0) return void 0;
17
- return { aspectRatio, ...resolution !== void 0 && { resolution } };
23
+ const [, aspectRatio, resolution] = size.match(/^([\d.]+:[\d.]+)(?:_(.+))?$/) ?? [];
24
+ if (aspectRatio === void 0) return void 0;
25
+ return {
26
+ aspectRatio,
27
+ ...resolution !== void 0 && { resolution }
28
+ };
18
29
  }
30
+ /**
31
+ * Validate the `size` template for a given grok video model.
32
+ *
33
+ * @experimental Video generation is an experimental feature and may change.
34
+ */
19
35
  function validateVideoSize(model, size) {
20
- if (size === void 0) return;
21
- const parsed = parseGrokVideoSize(size);
22
- if (!parsed || !GROK_VIDEO_ASPECT_RATIOS.includes(parsed.aspectRatio)) {
23
- throw new Error(
24
- `Size "${size}" is not supported by model "${model}". Expected "aspectRatio" or "aspectRatio_resolution" (e.g. "16:9_720p") with aspect ratio one of: ${GROK_VIDEO_ASPECT_RATIOS.join(", ")}`
25
- );
26
- }
27
- if (parsed.resolution !== void 0 && !GROK_VIDEO_RESOLUTIONS.includes(parsed.resolution)) {
28
- throw new Error(
29
- `Resolution "${parsed.resolution}" is not supported by model "${model}". Supported resolutions: ${GROK_VIDEO_RESOLUTIONS.join(", ")}`
30
- );
31
- }
36
+ if (size === void 0) return;
37
+ const parsed = parseGrokVideoSize(size);
38
+ if (!parsed || !GROK_VIDEO_ASPECT_RATIOS.includes(parsed.aspectRatio)) throw new Error(`Size "${size}" is not supported by model "${model}". Expected "aspectRatio" or "aspectRatio_resolution" (e.g. "16:9_720p") with aspect ratio one of: ${GROK_VIDEO_ASPECT_RATIOS.join(", ")}`);
39
+ if (parsed.resolution !== void 0 && !GROK_VIDEO_RESOLUTIONS.includes(parsed.resolution)) throw new Error(`Resolution "${parsed.resolution}" is not supported by model "${model}". Supported resolutions: ${GROK_VIDEO_RESOLUTIONS.join(", ")}`);
32
40
  }
33
- const GROK_VIDEO_DURATIONS = {
34
- "grok-imagine-video": {
35
- kind: "range",
36
- min: GROK_VIDEO_MIN_DURATION,
37
- max: GROK_VIDEO_MAX_DURATION,
38
- step: 1,
39
- unit: "seconds"
40
- },
41
- "grok-imagine-video-1.5": {
42
- kind: "range",
43
- min: GROK_VIDEO_MIN_DURATION,
44
- max: GROK_VIDEO_MAX_DURATION,
45
- step: 1,
46
- unit: "seconds"
47
- }
41
+ /**
42
+ * Runtime duration table backing `availableDurations()` / `snapDuration()`.
43
+ * Both grok-imagine video models accept the same continuous 1–15 integer-second
44
+ * range.
45
+ *
46
+ * @experimental Video generation is an experimental feature and may change.
47
+ */
48
+ var GROK_VIDEO_DURATIONS = {
49
+ "grok-imagine-video": {
50
+ kind: "range",
51
+ min: 1,
52
+ max: 15,
53
+ step: 1,
54
+ unit: "seconds"
55
+ },
56
+ "grok-imagine-video-1.5": {
57
+ kind: "range",
58
+ min: 1,
59
+ max: 15,
60
+ step: 1,
61
+ unit: "seconds"
62
+ }
48
63
  };
64
+ /**
65
+ * Look up the duration options for a grok video model.
66
+ *
67
+ * @experimental Video generation is an experimental feature and may change.
68
+ */
49
69
  function getGrokVideoDurationOptions(model) {
50
- return GROK_VIDEO_DURATIONS[model];
70
+ return GROK_VIDEO_DURATIONS[model];
51
71
  }
52
- const GROK_VIDEO_IMAGE_TO_VIDEO_ONLY = /* @__PURE__ */ new Set([
53
- "grok-imagine-video-1.5"
54
- ]);
72
+ /**
73
+ * Models that only support image-to-video — a starting-frame image is
74
+ * required and text-to-video is rejected by the Imagine API. Used by the
75
+ * adapter to fail fast with a clear message instead of surfacing the raw
76
+ * "Text-to-video is not supported for this model" 400.
77
+ *
78
+ * @experimental Video generation is an experimental feature and may change.
79
+ */
80
+ var GROK_VIDEO_IMAGE_TO_VIDEO_ONLY = /* @__PURE__ */ new Set(["grok-imagine-video-1.5"]);
81
+ /**
82
+ * True when the model only supports image-to-video (a starting frame is
83
+ * required).
84
+ *
85
+ * @experimental Video generation is an experimental feature and may change.
86
+ */
55
87
  function isImageToVideoOnlyModel(model) {
56
- return GROK_VIDEO_IMAGE_TO_VIDEO_ONLY.has(model);
88
+ return GROK_VIDEO_IMAGE_TO_VIDEO_ONLY.has(model);
57
89
  }
58
- export {
59
- GROK_VIDEO_DURATIONS,
60
- GROK_VIDEO_MAX_DURATION,
61
- GROK_VIDEO_MIN_DURATION,
62
- getGrokVideoDurationOptions,
63
- isImageToVideoOnlyModel,
64
- parseGrokVideoSize,
65
- validateVideoSize
66
- };
67
- //# sourceMappingURL=video-provider-options.js.map
90
+ //#endregion
91
+ export { GROK_VIDEO_DURATIONS, getGrokVideoDurationOptions, isImageToVideoOnlyModel, parseGrokVideoSize, validateVideoSize };
92
+
93
+ //# sourceMappingURL=video-provider-options.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"video-provider-options.js","sources":["../../../src/video/video-provider-options.ts"],"sourcesContent":["/**\n * Grok Video Generation Provider Options (xAI Imagine API)\n *\n * Based on https://docs.x.ai/docs/guides/video-generations\n *\n * @experimental Video generation is an experimental feature and may change.\n */\n\nimport type { DurationOptions } from '@tanstack/ai/adapters'\nimport type { GrokVideoModel } from '../model-meta'\n\n/**\n * Aspect ratios accepted by the grok-imagine video models.\n *\n * Note: this is a narrower set than the grok-imagine image models — the\n * video endpoint rejects the phone-screen ratios ('9:19.5', '9:20', …) and\n * 'auto'.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoAspectRatio =\n | '1:1'\n | '16:9'\n | '9:16'\n | '4:3'\n | '3:4'\n | '3:2'\n | '2:3'\n\n/**\n * Resolution tiers for the grok-imagine video models.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoResolution = '480p' | '720p' | '1080p'\n\n/**\n * Size strings for grok-imagine video models. The Imagine API is\n * aspect-ratio based rather than pixel-size based; like the grok-imagine\n * image models, the generic `size` option uses an\n * `aspectRatio_resolution` template (\"16:9_720p\") — the resolution suffix\n * is optional (\"16:9\" uses the API default).\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoSize =\n | GrokVideoAspectRatio\n | `${GrokVideoAspectRatio}_${GrokVideoResolution}`\n\nconst GROK_VIDEO_ASPECT_RATIOS: ReadonlyArray<string> = [\n '1:1',\n '16:9',\n '9:16',\n '4:3',\n '3:4',\n '3:2',\n '2:3',\n]\n\nconst GROK_VIDEO_RESOLUTIONS: ReadonlyArray<string> = ['480p', '720p', '1080p']\n\n/**\n * Video duration limits enforced by the Imagine API (seconds).\n */\nexport const GROK_VIDEO_MIN_DURATION = 1\nexport const GROK_VIDEO_MAX_DURATION = 15\n\n/**\n * Parses a grok video size string into its components.\n * Format: \"aspectRatio\" or \"aspectRatio_resolution\",\n * e.g. \"16:9_720p\" → { aspectRatio: \"16:9\", resolution: \"720p\" }.\n * Returns undefined when the string doesn't match the template.\n */\nexport function parseGrokVideoSize(\n size: string,\n): { aspectRatio: string; resolution?: string } | undefined {\n const match = size.match(/^([\\d.]+:[\\d.]+)(?:_(.+))?$/)\n const [, aspectRatio, resolution] = match ?? []\n if (aspectRatio === undefined) return undefined\n return { aspectRatio, ...(resolution !== undefined && { resolution }) }\n}\n\n/**\n * Validate the `size` template for a given grok video model.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport function validateVideoSize(\n model: string,\n size?: string,\n): asserts size is GrokVideoSize | undefined {\n if (size === undefined) return\n const parsed = parseGrokVideoSize(size)\n if (!parsed || !GROK_VIDEO_ASPECT_RATIOS.includes(parsed.aspectRatio)) {\n throw new Error(\n `Size \"${size}\" is not supported by model \"${model}\". Expected ` +\n `\"aspectRatio\" or \"aspectRatio_resolution\" (e.g. \"16:9_720p\") with ` +\n `aspect ratio one of: ${GROK_VIDEO_ASPECT_RATIOS.join(', ')}`,\n )\n }\n if (\n parsed.resolution !== undefined &&\n !GROK_VIDEO_RESOLUTIONS.includes(parsed.resolution)\n ) {\n throw new Error(\n `Resolution \"${parsed.resolution}\" is not supported by model \"${model}\". ` +\n `Supported resolutions: ${GROK_VIDEO_RESOLUTIONS.join(', ')}`,\n )\n }\n}\n\n/**\n * Per-model duration type. The Imagine API accepts any integer second in the\n * 1–15 range, so this is a continuous range expressed as `number` (a literal\n * union can't represent it). `snapDuration()` coerces a raw seconds value into\n * the valid range at runtime.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoModelDurationByName = {\n 'grok-imagine-video': number\n 'grok-imagine-video-1.5': number\n}\n\n/**\n * Runtime duration table backing `availableDurations()` / `snapDuration()`.\n * Both grok-imagine video models accept the same continuous 1–15 integer-second\n * range.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport const GROK_VIDEO_DURATIONS: {\n readonly [TModel in GrokVideoModel]: DurationOptions<\n GrokVideoModelDurationByName[TModel]\n >\n} = {\n 'grok-imagine-video': {\n kind: 'range',\n min: GROK_VIDEO_MIN_DURATION,\n max: GROK_VIDEO_MAX_DURATION,\n step: 1,\n unit: 'seconds',\n },\n 'grok-imagine-video-1.5': {\n kind: 'range',\n min: GROK_VIDEO_MIN_DURATION,\n max: GROK_VIDEO_MAX_DURATION,\n step: 1,\n unit: 'seconds',\n },\n}\n\n/**\n * Look up the duration options for a grok video model.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport function getGrokVideoDurationOptions<TModel extends GrokVideoModel>(\n model: TModel,\n): DurationOptions<GrokVideoModelDurationByName[TModel]> {\n return GROK_VIDEO_DURATIONS[model]\n}\n\n/**\n * Provider-specific options for grok video generation. These map directly\n * onto the Imagine API request body and take precedence over the generic\n * `size` / `duration` options when both are provided.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport interface GrokVideoProviderOptions {\n /**\n * Output aspect ratio.\n */\n aspect_ratio?: GrokVideoAspectRatio\n\n /**\n * Output resolution tier.\n */\n resolution?: GrokVideoResolution\n\n /**\n * Video duration in integer seconds (1–15).\n */\n duration?: number\n}\n\n/**\n * Type-only map from model name to its specific provider options.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoModelProviderOptionsByName = {\n 'grok-imagine-video': GrokVideoProviderOptions\n 'grok-imagine-video-1.5': GrokVideoProviderOptions\n}\n\n/**\n * Type-only map from model name to its supported `size` strings.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoModelSizeByName = {\n 'grok-imagine-video': GrokVideoSize\n 'grok-imagine-video-1.5': GrokVideoSize\n}\n\n/**\n * Type-only map from model name to the non-text prompt modalities it accepts.\n * Both models accept an `image` prompt part as the starting frame:\n * `grok-imagine-video` (v1.0) does text-to-video and image-to-video, while\n * `grok-imagine-video-1.5` is image-to-video only (the image is required).\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoModelInputModalitiesByName = {\n 'grok-imagine-video': readonly ['image']\n 'grok-imagine-video-1.5': readonly ['image']\n}\n\n/**\n * Models that only support image-to-video — a starting-frame image is\n * required and text-to-video is rejected by the Imagine API. Used by the\n * adapter to fail fast with a clear message instead of surfacing the raw\n * \"Text-to-video is not supported for this model\" 400.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nconst GROK_VIDEO_IMAGE_TO_VIDEO_ONLY: ReadonlySet<string> = new Set([\n 'grok-imagine-video-1.5',\n])\n\n/**\n * True when the model only supports image-to-video (a starting frame is\n * required).\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport function isImageToVideoOnlyModel(model: string): boolean {\n return GROK_VIDEO_IMAGE_TO_VIDEO_ONLY.has(model)\n}\n"],"names":[],"mappings":"AAiDA,MAAM,2BAAkD;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,yBAAgD,CAAC,QAAQ,QAAQ,OAAO;AAKvE,MAAM,0BAA0B;AAChC,MAAM,0BAA0B;AAQhC,SAAS,mBACd,MAC0D;AAC1D,QAAM,QAAQ,KAAK,MAAM,6BAA6B;AACtD,QAAM,GAAG,aAAa,UAAU,IAAI,SAAS,CAAA;AAC7C,MAAI,gBAAgB,OAAW,QAAO;AACtC,SAAO,EAAE,aAAa,GAAI,eAAe,UAAa,EAAE,aAAW;AACrE;AAOO,SAAS,kBACd,OACA,MAC2C;AAC3C,MAAI,SAAS,OAAW;AACxB,QAAM,SAAS,mBAAmB,IAAI;AACtC,MAAI,CAAC,UAAU,CAAC,yBAAyB,SAAS,OAAO,WAAW,GAAG;AACrE,UAAM,IAAI;AAAA,MACR,SAAS,IAAI,gCAAgC,KAAK,sGAExB,yBAAyB,KAAK,IAAI,CAAC;AAAA,IAAA;AAAA,EAEjE;AACA,MACE,OAAO,eAAe,UACtB,CAAC,uBAAuB,SAAS,OAAO,UAAU,GAClD;AACA,UAAM,IAAI;AAAA,MACR,eAAe,OAAO,UAAU,gCAAgC,KAAK,6BACzC,uBAAuB,KAAK,IAAI,CAAC;AAAA,IAAA;AAAA,EAEjE;AACF;AAsBO,MAAM,uBAIT;AAAA,EACF,sBAAsB;AAAA,IACpB,MAAM;AAAA,IACN,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,EAAA;AAAA,EAER,0BAA0B;AAAA,IACxB,MAAM;AAAA,IACN,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,EAAA;AAEV;AAOO,SAAS,4BACd,OACuD;AACvD,SAAO,qBAAqB,KAAK;AACnC;AAmEA,MAAM,qDAA0D,IAAI;AAAA,EAClE;AACF,CAAC;AAQM,SAAS,wBAAwB,OAAwB;AAC9D,SAAO,+BAA+B,IAAI,KAAK;AACjD;"}
1
+ {"version":3,"file":"video-provider-options.js","names":[],"sources":["../../../src/video/video-provider-options.ts"],"sourcesContent":["/**\n * Grok Video Generation Provider Options (xAI Imagine API)\n *\n * Based on https://docs.x.ai/docs/guides/video-generations\n *\n * @experimental Video generation is an experimental feature and may change.\n */\n\nimport type { DurationOptions } from '@tanstack/ai/adapters'\nimport type { GrokVideoModel } from '../model-meta'\n\n/**\n * Aspect ratios accepted by the grok-imagine video models.\n *\n * Note: this is a narrower set than the grok-imagine image models — the\n * video endpoint rejects the phone-screen ratios ('9:19.5', '9:20', …) and\n * 'auto'.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoAspectRatio =\n | '1:1'\n | '16:9'\n | '9:16'\n | '4:3'\n | '3:4'\n | '3:2'\n | '2:3'\n\n/**\n * Resolution tiers for the grok-imagine video models.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoResolution = '480p' | '720p' | '1080p'\n\n/**\n * Size strings for grok-imagine video models. The Imagine API is\n * aspect-ratio based rather than pixel-size based; like the grok-imagine\n * image models, the generic `size` option uses an\n * `aspectRatio_resolution` template (\"16:9_720p\") — the resolution suffix\n * is optional (\"16:9\" uses the API default).\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoSize =\n | GrokVideoAspectRatio\n | `${GrokVideoAspectRatio}_${GrokVideoResolution}`\n\nconst GROK_VIDEO_ASPECT_RATIOS: ReadonlyArray<string> = [\n '1:1',\n '16:9',\n '9:16',\n '4:3',\n '3:4',\n '3:2',\n '2:3',\n]\n\nconst GROK_VIDEO_RESOLUTIONS: ReadonlyArray<string> = ['480p', '720p', '1080p']\n\n/**\n * Video duration limits enforced by the Imagine API (seconds).\n */\nexport const GROK_VIDEO_MIN_DURATION = 1\nexport const GROK_VIDEO_MAX_DURATION = 15\n\n/**\n * Parses a grok video size string into its components.\n * Format: \"aspectRatio\" or \"aspectRatio_resolution\",\n * e.g. \"16:9_720p\" → { aspectRatio: \"16:9\", resolution: \"720p\" }.\n * Returns undefined when the string doesn't match the template.\n */\nexport function parseGrokVideoSize(\n size: string,\n): { aspectRatio: string; resolution?: string } | undefined {\n const match = size.match(/^([\\d.]+:[\\d.]+)(?:_(.+))?$/)\n const [, aspectRatio, resolution] = match ?? []\n if (aspectRatio === undefined) return undefined\n return { aspectRatio, ...(resolution !== undefined && { resolution }) }\n}\n\n/**\n * Validate the `size` template for a given grok video model.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport function validateVideoSize(\n model: string,\n size?: string,\n): asserts size is GrokVideoSize | undefined {\n if (size === undefined) return\n const parsed = parseGrokVideoSize(size)\n if (!parsed || !GROK_VIDEO_ASPECT_RATIOS.includes(parsed.aspectRatio)) {\n throw new Error(\n `Size \"${size}\" is not supported by model \"${model}\". Expected ` +\n `\"aspectRatio\" or \"aspectRatio_resolution\" (e.g. \"16:9_720p\") with ` +\n `aspect ratio one of: ${GROK_VIDEO_ASPECT_RATIOS.join(', ')}`,\n )\n }\n if (\n parsed.resolution !== undefined &&\n !GROK_VIDEO_RESOLUTIONS.includes(parsed.resolution)\n ) {\n throw new Error(\n `Resolution \"${parsed.resolution}\" is not supported by model \"${model}\". ` +\n `Supported resolutions: ${GROK_VIDEO_RESOLUTIONS.join(', ')}`,\n )\n }\n}\n\n/**\n * Per-model duration type. The Imagine API accepts any integer second in the\n * 1–15 range, so this is a continuous range expressed as `number` (a literal\n * union can't represent it). `snapDuration()` coerces a raw seconds value into\n * the valid range at runtime.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoModelDurationByName = {\n 'grok-imagine-video': number\n 'grok-imagine-video-1.5': number\n}\n\n/**\n * Runtime duration table backing `availableDurations()` / `snapDuration()`.\n * Both grok-imagine video models accept the same continuous 1–15 integer-second\n * range.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport const GROK_VIDEO_DURATIONS: {\n readonly [TModel in GrokVideoModel]: DurationOptions<\n GrokVideoModelDurationByName[TModel]\n >\n} = {\n 'grok-imagine-video': {\n kind: 'range',\n min: GROK_VIDEO_MIN_DURATION,\n max: GROK_VIDEO_MAX_DURATION,\n step: 1,\n unit: 'seconds',\n },\n 'grok-imagine-video-1.5': {\n kind: 'range',\n min: GROK_VIDEO_MIN_DURATION,\n max: GROK_VIDEO_MAX_DURATION,\n step: 1,\n unit: 'seconds',\n },\n}\n\n/**\n * Look up the duration options for a grok video model.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport function getGrokVideoDurationOptions<TModel extends GrokVideoModel>(\n model: TModel,\n): DurationOptions<GrokVideoModelDurationByName[TModel]> {\n return GROK_VIDEO_DURATIONS[model]\n}\n\n/**\n * Provider-specific options for grok video generation. These map directly\n * onto the Imagine API request body and take precedence over the generic\n * `size` / `duration` options when both are provided.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport interface GrokVideoProviderOptions {\n /**\n * Output aspect ratio.\n */\n aspect_ratio?: GrokVideoAspectRatio\n\n /**\n * Output resolution tier.\n */\n resolution?: GrokVideoResolution\n\n /**\n * Video duration in integer seconds (1–15).\n */\n duration?: number\n}\n\n/**\n * Type-only map from model name to its specific provider options.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoModelProviderOptionsByName = {\n 'grok-imagine-video': GrokVideoProviderOptions\n 'grok-imagine-video-1.5': GrokVideoProviderOptions\n}\n\n/**\n * Type-only map from model name to its supported `size` strings.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoModelSizeByName = {\n 'grok-imagine-video': GrokVideoSize\n 'grok-imagine-video-1.5': GrokVideoSize\n}\n\n/**\n * Type-only map from model name to the non-text prompt modalities it accepts.\n * Both models accept an `image` prompt part as the starting frame:\n * `grok-imagine-video` (v1.0) does text-to-video and image-to-video, while\n * `grok-imagine-video-1.5` is image-to-video only (the image is required).\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport type GrokVideoModelInputModalitiesByName = {\n 'grok-imagine-video': readonly ['image']\n 'grok-imagine-video-1.5': readonly ['image']\n}\n\n/**\n * Models that only support image-to-video — a starting-frame image is\n * required and text-to-video is rejected by the Imagine API. Used by the\n * adapter to fail fast with a clear message instead of surfacing the raw\n * \"Text-to-video is not supported for this model\" 400.\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nconst GROK_VIDEO_IMAGE_TO_VIDEO_ONLY: ReadonlySet<string> = new Set([\n 'grok-imagine-video-1.5',\n])\n\n/**\n * True when the model only supports image-to-video (a starting frame is\n * required).\n *\n * @experimental Video generation is an experimental feature and may change.\n */\nexport function isImageToVideoOnlyModel(model: string): boolean {\n return GROK_VIDEO_IMAGE_TO_VIDEO_ONLY.has(model)\n}\n"],"mappings":";AAiDA,IAAM,2BAAkD;CACtD;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,IAAM,yBAAgD;CAAC;CAAQ;CAAQ;AAAO;;;;;;;AAc9E,SAAgB,mBACd,MAC0D;CAE1D,MAAM,GAAG,aAAa,cADR,KAAK,MAAM,6BACW,KAAS,CAAC;CAC9C,IAAI,gBAAgB,KAAA,GAAW,OAAO,KAAA;CACtC,OAAO;EAAE;EAAa,GAAI,eAAe,KAAA,KAAa,EAAE,WAAW;CAAG;AACxE;;;;;;AAOA,SAAgB,kBACd,OACA,MAC2C;CAC3C,IAAI,SAAS,KAAA,GAAW;CACxB,MAAM,SAAS,mBAAmB,IAAI;CACtC,IAAI,CAAC,UAAU,CAAC,yBAAyB,SAAS,OAAO,WAAW,GAClE,MAAM,IAAI,MACR,SAAS,KAAK,+BAA+B,MAAM,qGAEzB,yBAAyB,KAAK,IAAI,GAC9D;CAEF,IACE,OAAO,eAAe,KAAA,KACtB,CAAC,uBAAuB,SAAS,OAAO,UAAU,GAElD,MAAM,IAAI,MACR,eAAe,OAAO,WAAW,+BAA+B,MAAM,4BAC1C,uBAAuB,KAAK,IAAI,GAC9D;AAEJ;;;;;;;;AAsBA,IAAa,uBAIT;CACF,sBAAsB;EACpB,MAAM;EACN,KAAA;EACA,KAAA;EACA,MAAM;EACN,MAAM;CACR;CACA,0BAA0B;EACxB,MAAM;EACN,KAAA;EACA,KAAA;EACA,MAAM;EACN,MAAM;CACR;AACF;;;;;;AAOA,SAAgB,4BACd,OACuD;CACvD,OAAO,qBAAqB;AAC9B;;;;;;;;;AAmEA,IAAM,iDAAsD,IAAI,IAAI,CAClE,wBACF,CAAC;;;;;;;AAQD,SAAgB,wBAAwB,OAAwB;CAC9D,OAAO,+BAA+B,IAAI,KAAK;AACjD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/ai-grok",
3
- "version": "0.14.8",
3
+ "version": "0.14.10",
4
4
  "description": "xAI Grok adapter for TanStack AI chat, image generation, realtime, and structured outputs.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -50,24 +50,24 @@
50
50
  ],
51
51
  "dependencies": {
52
52
  "openai": "^6.41.0",
53
- "@tanstack/ai-utils": "0.3.1",
54
- "@tanstack/openai-base": "0.9.8"
53
+ "@tanstack/ai-utils": "0.4.0",
54
+ "@tanstack/openai-base": "0.9.10"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@vitest/coverage-v8": "4.0.14",
58
- "vite": "^7.3.3",
59
- "@tanstack/ai": "0.41.0"
58
+ "vite": "^8.1.4",
59
+ "@tanstack/ai": "0.43.0"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "zod": "^4.0.0",
63
- "@tanstack/ai": "^0.41.0"
63
+ "@tanstack/ai": "^0.43.0"
64
64
  },
65
65
  "scripts": {
66
66
  "build": "vite build",
67
67
  "clean": "premove ./build ./dist",
68
- "lint:fix": "eslint ./src --fix",
68
+ "lint:fix": "oxlint src --type-aware --fix",
69
69
  "test:build": "publint --strict",
70
- "test:eslint": "eslint ./src",
70
+ "test:oxlint": "oxlint src --type-aware",
71
71
  "test:lib": "vitest run",
72
72
  "test:lib:dev": "pnpm test:lib --watch",
73
73
  "test:types": "tsc"
@@ -252,7 +252,7 @@ async function createWebRTCConnection(
252
252
  // doesn't end up as "[object Event]".
253
253
  // `onerror` always fires with an Event (often an RTCErrorEvent), so we
254
254
  // can read it via the untyped helpers without first proving object-ness.
255
- // eslint-disable-next-line no-restricted-syntax -- RTCErrorEvent is a typed DOM class that does not structurally overlap Record<string, unknown>; we duck-type it via readObject/readString
255
+ // oxlint-disable-next-line eslint-js/no-restricted-syntax -- RTCErrorEvent is a typed DOM class that does not structurally overlap Record<string, unknown>; we duck-type it via readObject/readString
256
256
  const errorRecord = error as unknown as Record<string, unknown>
257
257
  const rtcError = readObject(errorRecord, 'error')
258
258
  const msg =
@@ -194,7 +194,7 @@ export function arrayBufferToBase64(buffer: ArrayBuffer): string {
194
194
  const end = Math.min(i + chunkSize, bytes.length)
195
195
  binary += String.fromCharCode.apply(
196
196
  null,
197
- // eslint-disable-next-line no-restricted-syntax -- TS lib types String.fromCharCode.apply as Array<number> but runtime accepts any ArrayLike
197
+ // oxlint-disable-next-line eslint-js/no-restricted-syntax -- TS lib types String.fromCharCode.apply as Array<number> but runtime accepts any ArrayLike
198
198
  bytes.subarray(i, end) as unknown as Array<number>,
199
199
  )
200
200
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;"}