@ai-sdk/luma 1.0.0-canary.9 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,494 @@
1
1
  # @ai-sdk/luma
2
2
 
3
+ ## 1.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [90d212f]
8
+ - @ai-sdk/provider-utils@3.0.1
9
+
10
+ ## 1.0.0
11
+
12
+ ### Major Changes
13
+
14
+ - d5f588f: AI SDK 5
15
+ - 516be5b: ### Move Image Model Settings into generate options
16
+
17
+ Image Models no longer have settings. Instead, `maxImagesPerCall` can be passed directly to `generateImage()`. All other image settings can be passed to `providerOptions[provider]`.
18
+
19
+ Before
20
+
21
+ ```js
22
+ await generateImage({
23
+ model: luma.image('photon-flash-1', {
24
+ maxImagesPerCall: 5,
25
+ pollIntervalMillis: 500,
26
+ }),
27
+ prompt,
28
+ n: 10,
29
+ });
30
+ ```
31
+
32
+ After
33
+
34
+ ```js
35
+ await generateImage({
36
+ model: luma.image('photon-flash-1'),
37
+ prompt,
38
+ n: 10,
39
+ maxImagesPerCall: 5,
40
+ providerOptions: {
41
+ luma: { pollIntervalMillis: 5 },
42
+ },
43
+ });
44
+ ```
45
+
46
+ Pull Request: https://github.com/vercel/ai/pull/6180
47
+
48
+ ### Patch Changes
49
+
50
+ - eb173f1: chore (providers): remove model shorthand deprecation warnings
51
+ - d9209ca: fix (image-model): `specificationVersion: v1` -> `v2`
52
+ - 9301f86: refactor (image-model): rename `ImageModelV1` to `ImageModelV2`
53
+ - d1a034f: feature: using Zod 4 for internal stuff
54
+ - 205077b: fix: improve Zod compatibility
55
+ - Updated dependencies [a571d6e]
56
+ - Updated dependencies [742b7be]
57
+ - Updated dependencies [e7fcc86]
58
+ - Updated dependencies [7cddb72]
59
+ - Updated dependencies [ccce59b]
60
+ - Updated dependencies [e2b9e4b]
61
+ - Updated dependencies [95857aa]
62
+ - Updated dependencies [45c1ea2]
63
+ - Updated dependencies [6f6bb89]
64
+ - Updated dependencies [060370c]
65
+ - Updated dependencies [dc714f3]
66
+ - Updated dependencies [b5da06a]
67
+ - Updated dependencies [d1a1aa1]
68
+ - Updated dependencies [63f9e9b]
69
+ - Updated dependencies [5d142ab]
70
+ - Updated dependencies [d5f588f]
71
+ - Updated dependencies [e025824]
72
+ - Updated dependencies [0571b98]
73
+ - Updated dependencies [b6b43c7]
74
+ - Updated dependencies [4fef487]
75
+ - Updated dependencies [48d257a]
76
+ - Updated dependencies [0c0c0b3]
77
+ - Updated dependencies [0d2c085]
78
+ - Updated dependencies [40acf9b]
79
+ - Updated dependencies [9222aeb]
80
+ - Updated dependencies [e2aceaf]
81
+ - Updated dependencies [411e483]
82
+ - Updated dependencies [8ba77a7]
83
+ - Updated dependencies [7b3ae3f]
84
+ - Updated dependencies [a166433]
85
+ - Updated dependencies [26735b5]
86
+ - Updated dependencies [443d8ec]
87
+ - Updated dependencies [a8c8bd5]
88
+ - Updated dependencies [abf9a79]
89
+ - Updated dependencies [14c9410]
90
+ - Updated dependencies [e86be6f]
91
+ - Updated dependencies [9bf7291]
92
+ - Updated dependencies [2e13791]
93
+ - Updated dependencies [9f95b35]
94
+ - Updated dependencies [66962ed]
95
+ - Updated dependencies [0d06df6]
96
+ - Updated dependencies [472524a]
97
+ - Updated dependencies [dd3ff01]
98
+ - Updated dependencies [d9c98f4]
99
+ - Updated dependencies [05d2819]
100
+ - Updated dependencies [9301f86]
101
+ - Updated dependencies [0a87932]
102
+ - Updated dependencies [c4a2fec]
103
+ - Updated dependencies [957b739]
104
+ - Updated dependencies [79457bd]
105
+ - Updated dependencies [a3f768e]
106
+ - Updated dependencies [7435eb5]
107
+ - Updated dependencies [8aa9e20]
108
+ - Updated dependencies [4617fab]
109
+ - Updated dependencies [ac34802]
110
+ - Updated dependencies [0054544]
111
+ - Updated dependencies [cb68df0]
112
+ - Updated dependencies [ad80501]
113
+ - Updated dependencies [68ecf2f]
114
+ - Updated dependencies [9e9c809]
115
+ - Updated dependencies [32831c6]
116
+ - Updated dependencies [6dc848c]
117
+ - Updated dependencies [6b98118]
118
+ - Updated dependencies [d0f9495]
119
+ - Updated dependencies [63d791d]
120
+ - Updated dependencies [87b828f]
121
+ - Updated dependencies [3f2f00c]
122
+ - Updated dependencies [bfdca8d]
123
+ - Updated dependencies [0ff02bb]
124
+ - Updated dependencies [7979f7f]
125
+ - Updated dependencies [39a4fab]
126
+ - Updated dependencies [44f4aba]
127
+ - Updated dependencies [9bd5ab5]
128
+ - Updated dependencies [57edfcb]
129
+ - Updated dependencies [faf8446]
130
+ - Updated dependencies [7ea4132]
131
+ - Updated dependencies [d1a034f]
132
+ - Updated dependencies [5c56081]
133
+ - Updated dependencies [fd65bc6]
134
+ - Updated dependencies [023ba40]
135
+ - Updated dependencies [ea7a7c9]
136
+ - Updated dependencies [26535e0]
137
+ - Updated dependencies [e030615]
138
+ - Updated dependencies [5e57fae]
139
+ - Updated dependencies [393138b]
140
+ - Updated dependencies [c57e248]
141
+ - Updated dependencies [88a8ee5]
142
+ - Updated dependencies [41fa418]
143
+ - Updated dependencies [205077b]
144
+ - Updated dependencies [71f938d]
145
+ - Updated dependencies [3795467]
146
+ - Updated dependencies [28a5ed5]
147
+ - Updated dependencies [7182d14]
148
+ - Updated dependencies [c1e6647]
149
+ - Updated dependencies [1766ede]
150
+ - Updated dependencies [811dff3]
151
+ - Updated dependencies [f10304b]
152
+ - Updated dependencies [dd5fd43]
153
+ - Updated dependencies [33f4a6a]
154
+ - Updated dependencies [383cbfa]
155
+ - Updated dependencies [27deb4d]
156
+ - Updated dependencies [c4df419]
157
+ - @ai-sdk/provider-utils@3.0.0
158
+ - @ai-sdk/provider@2.0.0
159
+
160
+ ## 1.0.0-beta.10
161
+
162
+ ### Patch Changes
163
+
164
+ - Updated dependencies [88a8ee5]
165
+ - @ai-sdk/provider-utils@3.0.0-beta.10
166
+
167
+ ## 1.0.0-beta.9
168
+
169
+ ### Patch Changes
170
+
171
+ - Updated dependencies [27deb4d]
172
+ - @ai-sdk/provider@2.0.0-beta.2
173
+ - @ai-sdk/provider-utils@3.0.0-beta.9
174
+
175
+ ## 1.0.0-beta.8
176
+
177
+ ### Patch Changes
178
+
179
+ - eb173f1: chore (providers): remove model shorthand deprecation warnings
180
+ - Updated dependencies [dd5fd43]
181
+ - @ai-sdk/provider-utils@3.0.0-beta.8
182
+
183
+ ## 1.0.0-beta.7
184
+
185
+ ### Patch Changes
186
+
187
+ - Updated dependencies [e7fcc86]
188
+ - @ai-sdk/provider-utils@3.0.0-beta.7
189
+
190
+ ## 1.0.0-beta.6
191
+
192
+ ### Patch Changes
193
+
194
+ - Updated dependencies [ac34802]
195
+ - @ai-sdk/provider-utils@3.0.0-beta.6
196
+
197
+ ## 1.0.0-beta.5
198
+
199
+ ### Patch Changes
200
+
201
+ - Updated dependencies [57edfcb]
202
+ - Updated dependencies [383cbfa]
203
+ - @ai-sdk/provider-utils@3.0.0-beta.5
204
+
205
+ ## 1.0.0-beta.4
206
+
207
+ ### Patch Changes
208
+
209
+ - 205077b: fix: improve Zod compatibility
210
+ - Updated dependencies [205077b]
211
+ - @ai-sdk/provider-utils@3.0.0-beta.4
212
+
213
+ ## 1.0.0-beta.3
214
+
215
+ ### Patch Changes
216
+
217
+ - Updated dependencies [05d2819]
218
+ - @ai-sdk/provider-utils@3.0.0-beta.3
219
+
220
+ ## 1.0.0-beta.2
221
+
222
+ ### Patch Changes
223
+
224
+ - d1a034f: feature: using Zod 4 for internal stuff
225
+ - Updated dependencies [0571b98]
226
+ - Updated dependencies [39a4fab]
227
+ - Updated dependencies [d1a034f]
228
+ - @ai-sdk/provider-utils@3.0.0-beta.2
229
+
230
+ ## 1.0.0-beta.1
231
+
232
+ ### Patch Changes
233
+
234
+ - Updated dependencies [742b7be]
235
+ - Updated dependencies [7cddb72]
236
+ - Updated dependencies [ccce59b]
237
+ - Updated dependencies [e2b9e4b]
238
+ - Updated dependencies [45c1ea2]
239
+ - Updated dependencies [e025824]
240
+ - Updated dependencies [0d06df6]
241
+ - Updated dependencies [472524a]
242
+ - Updated dependencies [dd3ff01]
243
+ - Updated dependencies [7435eb5]
244
+ - Updated dependencies [cb68df0]
245
+ - Updated dependencies [bfdca8d]
246
+ - Updated dependencies [44f4aba]
247
+ - Updated dependencies [023ba40]
248
+ - Updated dependencies [5e57fae]
249
+ - Updated dependencies [71f938d]
250
+ - Updated dependencies [28a5ed5]
251
+ - @ai-sdk/provider@2.0.0-beta.1
252
+ - @ai-sdk/provider-utils@3.0.0-beta.1
253
+
254
+ ## 1.0.0-alpha.15
255
+
256
+ ### Patch Changes
257
+
258
+ - Updated dependencies [48d257a]
259
+ - Updated dependencies [8ba77a7]
260
+ - @ai-sdk/provider@2.0.0-alpha.15
261
+ - @ai-sdk/provider-utils@3.0.0-alpha.15
262
+
263
+ ## 1.0.0-alpha.14
264
+
265
+ ### Patch Changes
266
+
267
+ - Updated dependencies [b5da06a]
268
+ - Updated dependencies [63f9e9b]
269
+ - Updated dependencies [2e13791]
270
+ - @ai-sdk/provider@2.0.0-alpha.14
271
+ - @ai-sdk/provider-utils@3.0.0-alpha.14
272
+
273
+ ## 1.0.0-alpha.13
274
+
275
+ ### Patch Changes
276
+
277
+ - Updated dependencies [68ecf2f]
278
+ - @ai-sdk/provider@2.0.0-alpha.13
279
+ - @ai-sdk/provider-utils@3.0.0-alpha.13
280
+
281
+ ## 1.0.0-alpha.12
282
+
283
+ ### Patch Changes
284
+
285
+ - Updated dependencies [e2aceaf]
286
+ - @ai-sdk/provider@2.0.0-alpha.12
287
+ - @ai-sdk/provider-utils@3.0.0-alpha.12
288
+
289
+ ## 1.0.0-alpha.11
290
+
291
+ ### Patch Changes
292
+
293
+ - Updated dependencies [c1e6647]
294
+ - @ai-sdk/provider@2.0.0-alpha.11
295
+ - @ai-sdk/provider-utils@3.0.0-alpha.11
296
+
297
+ ## 1.0.0-alpha.10
298
+
299
+ ### Patch Changes
300
+
301
+ - Updated dependencies [c4df419]
302
+ - @ai-sdk/provider@2.0.0-alpha.10
303
+ - @ai-sdk/provider-utils@3.0.0-alpha.10
304
+
305
+ ## 1.0.0-alpha.9
306
+
307
+ ### Patch Changes
308
+
309
+ - Updated dependencies [811dff3]
310
+ - @ai-sdk/provider@2.0.0-alpha.9
311
+ - @ai-sdk/provider-utils@3.0.0-alpha.9
312
+
313
+ ## 1.0.0-alpha.8
314
+
315
+ ### Patch Changes
316
+
317
+ - Updated dependencies [4fef487]
318
+ - Updated dependencies [9222aeb]
319
+ - @ai-sdk/provider-utils@3.0.0-alpha.8
320
+ - @ai-sdk/provider@2.0.0-alpha.8
321
+
322
+ ## 1.0.0-alpha.7
323
+
324
+ ### Patch Changes
325
+
326
+ - Updated dependencies [5c56081]
327
+ - @ai-sdk/provider@2.0.0-alpha.7
328
+ - @ai-sdk/provider-utils@3.0.0-alpha.7
329
+
330
+ ## 1.0.0-alpha.6
331
+
332
+ ### Patch Changes
333
+
334
+ - Updated dependencies [0d2c085]
335
+ - @ai-sdk/provider@2.0.0-alpha.6
336
+ - @ai-sdk/provider-utils@3.0.0-alpha.6
337
+
338
+ ## 1.0.0-alpha.4
339
+
340
+ ### Patch Changes
341
+
342
+ - Updated dependencies [dc714f3]
343
+ - @ai-sdk/provider@2.0.0-alpha.4
344
+ - @ai-sdk/provider-utils@3.0.0-alpha.4
345
+
346
+ ## 1.0.0-alpha.3
347
+
348
+ ### Patch Changes
349
+
350
+ - Updated dependencies [6b98118]
351
+ - @ai-sdk/provider@2.0.0-alpha.3
352
+ - @ai-sdk/provider-utils@3.0.0-alpha.3
353
+
354
+ ## 1.0.0-alpha.2
355
+
356
+ ### Patch Changes
357
+
358
+ - Updated dependencies [26535e0]
359
+ - @ai-sdk/provider@2.0.0-alpha.2
360
+ - @ai-sdk/provider-utils@3.0.0-alpha.2
361
+
362
+ ## 1.0.0-alpha.1
363
+
364
+ ### Patch Changes
365
+
366
+ - Updated dependencies [3f2f00c]
367
+ - @ai-sdk/provider@2.0.0-alpha.1
368
+ - @ai-sdk/provider-utils@3.0.0-alpha.1
369
+
370
+ ## 1.0.0-canary.19
371
+
372
+ ### Patch Changes
373
+
374
+ - Updated dependencies [faf8446]
375
+ - @ai-sdk/provider-utils@3.0.0-canary.19
376
+
377
+ ## 1.0.0-canary.18
378
+
379
+ ### Patch Changes
380
+
381
+ - Updated dependencies [40acf9b]
382
+ - @ai-sdk/provider-utils@3.0.0-canary.18
383
+
384
+ ## 1.0.0-canary.17
385
+
386
+ ### Major Changes
387
+
388
+ - 516be5b: ### Move Image Model Settings into generate options
389
+
390
+ Image Models no longer have settings. Instead, `maxImagesPerCall` can be passed directly to `generateImage()`. All other image settings can be passed to `providerOptions[provider]`.
391
+
392
+ Before
393
+
394
+ ```js
395
+ await generateImage({
396
+ model: luma.image('photon-flash-1', {
397
+ maxImagesPerCall: 5,
398
+ pollIntervalMillis: 500,
399
+ }),
400
+ prompt,
401
+ n: 10,
402
+ });
403
+ ```
404
+
405
+ After
406
+
407
+ ```js
408
+ await generateImage({
409
+ model: luma.image('photon-flash-1'),
410
+ prompt,
411
+ n: 10,
412
+ maxImagesPerCall: 5,
413
+ providerOptions: {
414
+ luma: { pollIntervalMillis: 5 },
415
+ },
416
+ });
417
+ ```
418
+
419
+ Pull Request: https://github.com/vercel/ai/pull/6180
420
+
421
+ ### Patch Changes
422
+
423
+ - Updated dependencies [ea7a7c9]
424
+ - @ai-sdk/provider-utils@3.0.0-canary.17
425
+
426
+ ## 1.0.0-canary.16
427
+
428
+ ### Patch Changes
429
+
430
+ - Updated dependencies [87b828f]
431
+ - @ai-sdk/provider-utils@3.0.0-canary.16
432
+
433
+ ## 1.0.0-canary.15
434
+
435
+ ### Patch Changes
436
+
437
+ - Updated dependencies [a571d6e]
438
+ - Updated dependencies [a8c8bd5]
439
+ - Updated dependencies [7979f7f]
440
+ - Updated dependencies [41fa418]
441
+ - @ai-sdk/provider-utils@3.0.0-canary.15
442
+ - @ai-sdk/provider@2.0.0-canary.14
443
+
444
+ ## 1.0.0-canary.14
445
+
446
+ ### Patch Changes
447
+
448
+ - Updated dependencies [957b739]
449
+ - Updated dependencies [9bd5ab5]
450
+ - @ai-sdk/provider-utils@3.0.0-canary.14
451
+ - @ai-sdk/provider@2.0.0-canary.13
452
+
453
+ ## 1.0.0-canary.13
454
+
455
+ ### Patch Changes
456
+
457
+ - d9209ca: fix (image-model): `specificationVersion: v1` -> `v2`
458
+ - Updated dependencies [7b3ae3f]
459
+ - Updated dependencies [0ff02bb]
460
+ - @ai-sdk/provider@2.0.0-canary.12
461
+ - @ai-sdk/provider-utils@3.0.0-canary.13
462
+
463
+ ## 1.0.0-canary.12
464
+
465
+ ### Patch Changes
466
+
467
+ - Updated dependencies [9bf7291]
468
+ - Updated dependencies [4617fab]
469
+ - Updated dependencies [e030615]
470
+ - @ai-sdk/provider@2.0.0-canary.11
471
+ - @ai-sdk/provider-utils@3.0.0-canary.12
472
+
473
+ ## 1.0.0-canary.11
474
+
475
+ ### Patch Changes
476
+
477
+ - 9301f86: refactor (image-model): rename `ImageModelV1` to `ImageModelV2`
478
+ - Updated dependencies [66962ed]
479
+ - Updated dependencies [9301f86]
480
+ - Updated dependencies [a3f768e]
481
+ - @ai-sdk/provider-utils@3.0.0-canary.11
482
+ - @ai-sdk/provider@2.0.0-canary.10
483
+
484
+ ## 1.0.0-canary.10
485
+
486
+ ### Patch Changes
487
+
488
+ - Updated dependencies [e86be6f]
489
+ - @ai-sdk/provider@2.0.0-canary.9
490
+ - @ai-sdk/provider-utils@3.0.0-canary.10
491
+
3
492
  ## 1.0.0-canary.9
4
493
 
5
494
  ### Patch Changes
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AI SDK - Luma Provider
2
2
 
3
- The **Luma provider** for the [AI SDK](https://sdk.vercel.ai/docs) contains support for Luma AI's state-of-the-art image generation models - Photon and Photon Flash.
3
+ The **Luma provider** for the [AI SDK](https://ai-sdk.dev/docs) contains support for Luma AI's state-of-the-art image generation models - Photon and Photon Flash.
4
4
 
5
5
  ## About Luma Photon Models
6
6
 
@@ -49,4 +49,4 @@ console.log(`Image saved to ${filename}`);
49
49
 
50
50
  ## Documentation
51
51
 
52
- Please check out the **[Luma provider](https://sdk.vercel.ai/providers/ai-sdk-providers/luma)** for more information.
52
+ Please check out the **[Luma provider](https://ai-sdk.dev/providers/ai-sdk-providers/luma)** for more information.
package/dist/index.d.mts CHANGED
@@ -1,33 +1,8 @@
1
- import { ProviderV2, ImageModelV1 } from '@ai-sdk/provider';
1
+ import { ProviderV2, ImageModelV2 } from '@ai-sdk/provider';
2
2
  import { FetchFunction } from '@ai-sdk/provider-utils';
3
- import { z } from 'zod';
3
+ import { z } from 'zod/v4';
4
4
 
5
5
  type LumaImageModelId = 'photon-1' | 'photon-flash-1' | (string & {});
6
- /**
7
- Configuration settings for Luma image generation.
8
-
9
- Since the Luma API processes images through an asynchronous queue system, these
10
- settings allow you to tune the polling behavior when waiting for image
11
- generation to complete.
12
- */
13
- interface LumaImageSettings {
14
- /**
15
- Override the maximum number of images per call (default 1)
16
- */
17
- maxImagesPerCall?: number;
18
- /**
19
- Override the polling interval in milliseconds (default 500). This controls how
20
- frequently the API is checked for completed images while they are being
21
- processed in Luma's queue.
22
- */
23
- pollIntervalMillis?: number;
24
- /**
25
- Override the maximum number of polling attempts (default 120). Since image
26
- generation is queued and processed asynchronously, this limits how long to wait
27
- for results before timing out.
28
- */
29
- maxPollAttempts?: number;
30
- }
31
6
 
32
7
  interface LumaProviderSettings {
33
8
  /**
@@ -53,11 +28,11 @@ interface LumaProvider extends ProviderV2 {
53
28
  /**
54
29
  Creates a model for image generation.
55
30
  */
56
- image(modelId: LumaImageModelId, settings?: LumaImageSettings): ImageModelV1;
31
+ image(modelId: LumaImageModelId): ImageModelV2;
57
32
  /**
58
33
  Creates a model for image generation.
59
34
  */
60
- imageModel(modelId: LumaImageModelId, settings?: LumaImageSettings): ImageModelV1;
35
+ imageModel(modelId: LumaImageModelId): ImageModelV2;
61
36
  }
62
37
  declare function createLuma(options?: LumaProviderSettings): LumaProvider;
63
38
  declare const luma: LumaProvider;
@@ -65,54 +40,14 @@ declare const luma: LumaProvider;
65
40
  declare const lumaErrorSchema: z.ZodObject<{
66
41
  detail: z.ZodArray<z.ZodObject<{
67
42
  type: z.ZodString;
68
- loc: z.ZodArray<z.ZodString, "many">;
43
+ loc: z.ZodArray<z.ZodString>;
69
44
  msg: z.ZodString;
70
45
  input: z.ZodString;
71
46
  ctx: z.ZodOptional<z.ZodNullable<z.ZodObject<{
72
47
  expected: z.ZodString;
73
- }, "strip", z.ZodTypeAny, {
74
- expected: string;
75
- }, {
76
- expected: string;
77
- }>>>;
78
- }, "strip", z.ZodTypeAny, {
79
- type: string;
80
- loc: string[];
81
- msg: string;
82
- input: string;
83
- ctx?: {
84
- expected: string;
85
- } | null | undefined;
86
- }, {
87
- type: string;
88
- loc: string[];
89
- msg: string;
90
- input: string;
91
- ctx?: {
92
- expected: string;
93
- } | null | undefined;
94
- }>, "many">;
95
- }, "strip", z.ZodTypeAny, {
96
- detail: {
97
- type: string;
98
- loc: string[];
99
- msg: string;
100
- input: string;
101
- ctx?: {
102
- expected: string;
103
- } | null | undefined;
104
- }[];
105
- }, {
106
- detail: {
107
- type: string;
108
- loc: string[];
109
- msg: string;
110
- input: string;
111
- ctx?: {
112
- expected: string;
113
- } | null | undefined;
114
- }[];
115
- }>;
48
+ }, z.core.$strip>>>;
49
+ }, z.core.$strip>>;
50
+ }, z.core.$strip>;
116
51
  type LumaErrorData = z.infer<typeof lumaErrorSchema>;
117
52
 
118
53
  export { type LumaErrorData, type LumaProvider, type LumaProviderSettings, createLuma, luma };
package/dist/index.d.ts CHANGED
@@ -1,33 +1,8 @@
1
- import { ProviderV2, ImageModelV1 } from '@ai-sdk/provider';
1
+ import { ProviderV2, ImageModelV2 } from '@ai-sdk/provider';
2
2
  import { FetchFunction } from '@ai-sdk/provider-utils';
3
- import { z } from 'zod';
3
+ import { z } from 'zod/v4';
4
4
 
5
5
  type LumaImageModelId = 'photon-1' | 'photon-flash-1' | (string & {});
6
- /**
7
- Configuration settings for Luma image generation.
8
-
9
- Since the Luma API processes images through an asynchronous queue system, these
10
- settings allow you to tune the polling behavior when waiting for image
11
- generation to complete.
12
- */
13
- interface LumaImageSettings {
14
- /**
15
- Override the maximum number of images per call (default 1)
16
- */
17
- maxImagesPerCall?: number;
18
- /**
19
- Override the polling interval in milliseconds (default 500). This controls how
20
- frequently the API is checked for completed images while they are being
21
- processed in Luma's queue.
22
- */
23
- pollIntervalMillis?: number;
24
- /**
25
- Override the maximum number of polling attempts (default 120). Since image
26
- generation is queued and processed asynchronously, this limits how long to wait
27
- for results before timing out.
28
- */
29
- maxPollAttempts?: number;
30
- }
31
6
 
32
7
  interface LumaProviderSettings {
33
8
  /**
@@ -53,11 +28,11 @@ interface LumaProvider extends ProviderV2 {
53
28
  /**
54
29
  Creates a model for image generation.
55
30
  */
56
- image(modelId: LumaImageModelId, settings?: LumaImageSettings): ImageModelV1;
31
+ image(modelId: LumaImageModelId): ImageModelV2;
57
32
  /**
58
33
  Creates a model for image generation.
59
34
  */
60
- imageModel(modelId: LumaImageModelId, settings?: LumaImageSettings): ImageModelV1;
35
+ imageModel(modelId: LumaImageModelId): ImageModelV2;
61
36
  }
62
37
  declare function createLuma(options?: LumaProviderSettings): LumaProvider;
63
38
  declare const luma: LumaProvider;
@@ -65,54 +40,14 @@ declare const luma: LumaProvider;
65
40
  declare const lumaErrorSchema: z.ZodObject<{
66
41
  detail: z.ZodArray<z.ZodObject<{
67
42
  type: z.ZodString;
68
- loc: z.ZodArray<z.ZodString, "many">;
43
+ loc: z.ZodArray<z.ZodString>;
69
44
  msg: z.ZodString;
70
45
  input: z.ZodString;
71
46
  ctx: z.ZodOptional<z.ZodNullable<z.ZodObject<{
72
47
  expected: z.ZodString;
73
- }, "strip", z.ZodTypeAny, {
74
- expected: string;
75
- }, {
76
- expected: string;
77
- }>>>;
78
- }, "strip", z.ZodTypeAny, {
79
- type: string;
80
- loc: string[];
81
- msg: string;
82
- input: string;
83
- ctx?: {
84
- expected: string;
85
- } | null | undefined;
86
- }, {
87
- type: string;
88
- loc: string[];
89
- msg: string;
90
- input: string;
91
- ctx?: {
92
- expected: string;
93
- } | null | undefined;
94
- }>, "many">;
95
- }, "strip", z.ZodTypeAny, {
96
- detail: {
97
- type: string;
98
- loc: string[];
99
- msg: string;
100
- input: string;
101
- ctx?: {
102
- expected: string;
103
- } | null | undefined;
104
- }[];
105
- }, {
106
- detail: {
107
- type: string;
108
- loc: string[];
109
- msg: string;
110
- input: string;
111
- ctx?: {
112
- expected: string;
113
- } | null | undefined;
114
- }[];
115
- }>;
48
+ }, z.core.$strip>>>;
49
+ }, z.core.$strip>>;
50
+ }, z.core.$strip>;
116
51
  type LumaErrorData = z.infer<typeof lumaErrorSchema>;
117
52
 
118
53
  export { type LumaErrorData, type LumaProvider, type LumaProviderSettings, createLuma, luma };
package/dist/index.js CHANGED
@@ -32,26 +32,21 @@ var import_provider_utils2 = require("@ai-sdk/provider-utils");
32
32
  // src/luma-image-model.ts
33
33
  var import_provider = require("@ai-sdk/provider");
34
34
  var import_provider_utils = require("@ai-sdk/provider-utils");
35
- var import_zod = require("zod");
35
+ var import_v4 = require("zod/v4");
36
36
  var DEFAULT_POLL_INTERVAL_MILLIS = 500;
37
37
  var DEFAULT_MAX_POLL_ATTEMPTS = 6e4 / DEFAULT_POLL_INTERVAL_MILLIS;
38
38
  var LumaImageModel = class {
39
- constructor(modelId, settings, config) {
39
+ constructor(modelId, config) {
40
40
  this.modelId = modelId;
41
- this.settings = settings;
42
41
  this.config = config;
43
- this.specificationVersion = "v1";
44
- var _a, _b;
45
- this.pollIntervalMillis = (_a = settings.pollIntervalMillis) != null ? _a : DEFAULT_POLL_INTERVAL_MILLIS;
46
- this.maxPollAttempts = (_b = settings.maxPollAttempts) != null ? _b : DEFAULT_MAX_POLL_ATTEMPTS;
42
+ this.specificationVersion = "v2";
43
+ this.maxImagesPerCall = 1;
44
+ this.pollIntervalMillis = DEFAULT_POLL_INTERVAL_MILLIS;
45
+ this.maxPollAttempts = DEFAULT_MAX_POLL_ATTEMPTS;
47
46
  }
48
47
  get provider() {
49
48
  return this.config.provider;
50
49
  }
51
- get maxImagesPerCall() {
52
- var _a;
53
- return (_a = this.settings.maxImagesPerCall) != null ? _a : 1;
54
- }
55
50
  async doGenerate({
56
51
  prompt,
57
52
  n,
@@ -78,7 +73,8 @@ var LumaImageModel = class {
78
73
  details: "This model does not support the `size` option. Use `aspectRatio` instead."
79
74
  });
80
75
  }
81
- const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
76
+ const { pollIntervalMillis, maxPollAttempts, ...providerRequestOptions } = (_a = providerOptions.luma) != null ? _a : {};
77
+ const currentDate = (_d = (_c = (_b = this.config._internal) == null ? void 0 : _b.currentDate) == null ? void 0 : _c.call(_b)) != null ? _d : /* @__PURE__ */ new Date();
82
78
  const fullHeaders = (0, import_provider_utils.combineHeaders)(this.config.headers(), headers);
83
79
  const { value: generationResponse, responseHeaders } = await (0, import_provider_utils.postJsonToApi)({
84
80
  url: this.getLumaGenerationsUrl(),
@@ -87,7 +83,7 @@ var LumaImageModel = class {
87
83
  prompt,
88
84
  ...aspectRatio ? { aspect_ratio: aspectRatio } : {},
89
85
  model: this.modelId,
90
- ...(_d = providerOptions.luma) != null ? _d : {}
86
+ ...providerRequestOptions
91
87
  },
92
88
  abortSignal,
93
89
  fetch: this.config.fetch,
@@ -99,7 +95,8 @@ var LumaImageModel = class {
99
95
  const imageUrl = await this.pollForImageUrl(
100
96
  generationResponse.id,
101
97
  fullHeaders,
102
- abortSignal
98
+ abortSignal,
99
+ providerOptions.luma
103
100
  );
104
101
  const downloadedImage = await this.downloadImage(imageUrl, abortSignal);
105
102
  return {
@@ -112,11 +109,12 @@ var LumaImageModel = class {
112
109
  }
113
110
  };
114
111
  }
115
- async pollForImageUrl(generationId, headers, abortSignal) {
116
- var _a;
117
- let attemptCount = 0;
112
+ async pollForImageUrl(generationId, headers, abortSignal, imageSettings) {
113
+ var _a, _b, _c;
118
114
  const url = this.getLumaGenerationsUrl(generationId);
119
- for (let i = 0; i < this.maxPollAttempts; i++) {
115
+ const maxPollAttempts = (_a = imageSettings == null ? void 0 : imageSettings.maxPollAttempts) != null ? _a : this.maxPollAttempts;
116
+ const pollIntervalMillis = (_b = imageSettings == null ? void 0 : imageSettings.pollIntervalMillis) != null ? _b : this.pollIntervalMillis;
117
+ for (let i = 0; i < maxPollAttempts; i++) {
120
118
  const { value: statusResponse } = await (0, import_provider_utils.getFromApi)({
121
119
  url,
122
120
  headers,
@@ -129,7 +127,7 @@ var LumaImageModel = class {
129
127
  });
130
128
  switch (statusResponse.state) {
131
129
  case "completed":
132
- if (!((_a = statusResponse.assets) == null ? void 0 : _a.image)) {
130
+ if (!((_c = statusResponse.assets) == null ? void 0 : _c.image)) {
133
131
  throw new import_provider.InvalidResponseDataError({
134
132
  data: statusResponse,
135
133
  message: `Image generation completed but no image was found.`
@@ -142,7 +140,7 @@ var LumaImageModel = class {
142
140
  message: `Image generation failed.`
143
141
  });
144
142
  }
145
- await (0, import_provider_utils.delay)(this.pollIntervalMillis);
143
+ await (0, import_provider_utils.delay)(pollIntervalMillis);
146
144
  }
147
145
  throw new Error(
148
146
  `Image generation timed out after ${this.maxPollAttempts} attempts.`
@@ -173,24 +171,24 @@ var LumaImageModel = class {
173
171
  return response;
174
172
  }
175
173
  };
176
- var lumaGenerationResponseSchema = import_zod.z.object({
177
- id: import_zod.z.string(),
178
- state: import_zod.z.enum(["queued", "dreaming", "completed", "failed"]),
179
- failure_reason: import_zod.z.string().nullish(),
180
- assets: import_zod.z.object({
181
- image: import_zod.z.string()
174
+ var lumaGenerationResponseSchema = import_v4.z.object({
175
+ id: import_v4.z.string(),
176
+ state: import_v4.z.enum(["queued", "dreaming", "completed", "failed"]),
177
+ failure_reason: import_v4.z.string().nullish(),
178
+ assets: import_v4.z.object({
179
+ image: import_v4.z.string()
182
180
  // URL of the generated image
183
181
  }).nullish()
184
182
  });
185
- var lumaErrorSchema = import_zod.z.object({
186
- detail: import_zod.z.array(
187
- import_zod.z.object({
188
- type: import_zod.z.string(),
189
- loc: import_zod.z.array(import_zod.z.string()),
190
- msg: import_zod.z.string(),
191
- input: import_zod.z.string(),
192
- ctx: import_zod.z.object({
193
- expected: import_zod.z.string()
183
+ var lumaErrorSchema = import_v4.z.object({
184
+ detail: import_v4.z.array(
185
+ import_v4.z.object({
186
+ type: import_v4.z.string(),
187
+ loc: import_v4.z.array(import_v4.z.string()),
188
+ msg: import_v4.z.string(),
189
+ input: import_v4.z.string(),
190
+ ctx: import_v4.z.object({
191
+ expected: import_v4.z.string()
194
192
  }).nullish()
195
193
  })
196
194
  )
@@ -209,7 +207,7 @@ function createLuma(options = {}) {
209
207
  })}`,
210
208
  ...options.headers
211
209
  });
212
- const createImageModel = (modelId, settings = {}) => new LumaImageModel(modelId, settings, {
210
+ const createImageModel = (modelId) => new LumaImageModel(modelId, {
213
211
  provider: "luma.image",
214
212
  baseURL: baseURL != null ? baseURL : defaultBaseURL,
215
213
  headers: getHeaders,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/luma-provider.ts","../src/luma-image-model.ts"],"sourcesContent":["export { createLuma, luma } from './luma-provider';\nexport type { LumaProvider, LumaProviderSettings } from './luma-provider';\nexport type { LumaErrorData } from './luma-image-model';\n","import { ImageModelV1, NoSuchModelError, ProviderV2 } from '@ai-sdk/provider';\nimport {\n FetchFunction,\n loadApiKey,\n withoutTrailingSlash,\n} from '@ai-sdk/provider-utils';\nimport { LumaImageModel } from './luma-image-model';\nimport { LumaImageModelId, LumaImageSettings } from './luma-image-settings';\n\nexport interface LumaProviderSettings {\n /**\nLuma API key. Default value is taken from the `LUMA_API_KEY` environment\nvariable.\n */\n apiKey?: string;\n /**\nBase URL for the API calls.\n */\n baseURL?: string;\n /**\nCustom headers to include in the requests.\n */\n headers?: Record<string, string>;\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface LumaProvider extends ProviderV2 {\n /**\nCreates a model for image generation.\n */\n image(modelId: LumaImageModelId, settings?: LumaImageSettings): ImageModelV1;\n\n /**\nCreates a model for image generation.\n */\n imageModel(\n modelId: LumaImageModelId,\n settings?: LumaImageSettings,\n ): ImageModelV1;\n}\n\nconst defaultBaseURL = 'https://api.lumalabs.ai';\n\nexport function createLuma(options: LumaProviderSettings = {}): LumaProvider {\n const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL);\n const getHeaders = () => ({\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'LUMA_API_KEY',\n description: 'Luma',\n })}`,\n ...options.headers,\n });\n\n const createImageModel = (\n modelId: LumaImageModelId,\n settings: LumaImageSettings = {},\n ) =>\n new LumaImageModel(modelId, settings, {\n provider: 'luma.image',\n baseURL: baseURL ?? defaultBaseURL,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n return {\n image: createImageModel,\n imageModel: createImageModel,\n languageModel: () => {\n throw new NoSuchModelError({\n modelId: 'languageModel',\n modelType: 'languageModel',\n });\n },\n textEmbeddingModel: () => {\n throw new NoSuchModelError({\n modelId: 'textEmbeddingModel',\n modelType: 'textEmbeddingModel',\n });\n },\n };\n}\n\nexport const luma = createLuma();\n","import {\n ImageModelV1,\n ImageModelV1CallWarning,\n InvalidResponseDataError,\n} from '@ai-sdk/provider';\nimport {\n FetchFunction,\n combineHeaders,\n createBinaryResponseHandler,\n createJsonResponseHandler,\n createJsonErrorResponseHandler,\n createStatusCodeErrorResponseHandler,\n delay,\n getFromApi,\n postJsonToApi,\n} from '@ai-sdk/provider-utils';\nimport { LumaImageSettings } from './luma-image-settings';\nimport { z } from 'zod';\n\nconst DEFAULT_POLL_INTERVAL_MILLIS = 500;\nconst DEFAULT_MAX_POLL_ATTEMPTS = 60000 / DEFAULT_POLL_INTERVAL_MILLIS;\n\ninterface LumaImageModelConfig {\n provider: string;\n baseURL: string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class LumaImageModel implements ImageModelV1 {\n readonly specificationVersion = 'v1';\n\n private readonly pollIntervalMillis: number;\n private readonly maxPollAttempts: number;\n\n get provider(): string {\n return this.config.provider;\n }\n\n get maxImagesPerCall(): number {\n return this.settings.maxImagesPerCall ?? 1;\n }\n\n constructor(\n readonly modelId: string,\n private readonly settings: LumaImageSettings,\n private readonly config: LumaImageModelConfig,\n ) {\n this.pollIntervalMillis =\n settings.pollIntervalMillis ?? DEFAULT_POLL_INTERVAL_MILLIS;\n this.maxPollAttempts =\n settings.maxPollAttempts ?? DEFAULT_MAX_POLL_ATTEMPTS;\n }\n\n async doGenerate({\n prompt,\n n,\n size,\n aspectRatio,\n seed,\n providerOptions,\n headers,\n abortSignal,\n }: Parameters<ImageModelV1['doGenerate']>[0]): Promise<\n Awaited<ReturnType<ImageModelV1['doGenerate']>>\n > {\n const warnings: Array<ImageModelV1CallWarning> = [];\n\n if (seed != null) {\n warnings.push({\n type: 'unsupported-setting',\n setting: 'seed',\n details: 'This model does not support the `seed` option.',\n });\n }\n\n if (size != null) {\n warnings.push({\n type: 'unsupported-setting',\n setting: 'size',\n details:\n 'This model does not support the `size` option. Use `aspectRatio` instead.',\n });\n }\n\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const fullHeaders = combineHeaders(this.config.headers(), headers);\n const { value: generationResponse, responseHeaders } = await postJsonToApi({\n url: this.getLumaGenerationsUrl(),\n headers: fullHeaders,\n body: {\n prompt,\n ...(aspectRatio ? { aspect_ratio: aspectRatio } : {}),\n model: this.modelId,\n ...(providerOptions.luma ?? {}),\n },\n abortSignal,\n fetch: this.config.fetch,\n failedResponseHandler: this.createLumaErrorHandler(),\n successfulResponseHandler: createJsonResponseHandler(\n lumaGenerationResponseSchema,\n ),\n });\n\n const imageUrl = await this.pollForImageUrl(\n generationResponse.id,\n fullHeaders,\n abortSignal,\n );\n\n const downloadedImage = await this.downloadImage(imageUrl, abortSignal);\n\n return {\n images: [downloadedImage],\n warnings,\n response: {\n modelId: this.modelId,\n timestamp: currentDate,\n headers: responseHeaders,\n },\n };\n }\n\n private async pollForImageUrl(\n generationId: string,\n headers: Record<string, string | undefined>,\n abortSignal: AbortSignal | undefined,\n ): Promise<string> {\n let attemptCount = 0;\n const url = this.getLumaGenerationsUrl(generationId);\n for (let i = 0; i < this.maxPollAttempts; i++) {\n const { value: statusResponse } = await getFromApi({\n url,\n headers,\n abortSignal,\n fetch: this.config.fetch,\n failedResponseHandler: this.createLumaErrorHandler(),\n successfulResponseHandler: createJsonResponseHandler(\n lumaGenerationResponseSchema,\n ),\n });\n\n switch (statusResponse.state) {\n case 'completed':\n if (!statusResponse.assets?.image) {\n throw new InvalidResponseDataError({\n data: statusResponse,\n message: `Image generation completed but no image was found.`,\n });\n }\n return statusResponse.assets.image;\n case 'failed':\n throw new InvalidResponseDataError({\n data: statusResponse,\n message: `Image generation failed.`,\n });\n }\n await delay(this.pollIntervalMillis);\n }\n\n throw new Error(\n `Image generation timed out after ${this.maxPollAttempts} attempts.`,\n );\n }\n\n private createLumaErrorHandler() {\n return createJsonErrorResponseHandler({\n errorSchema: lumaErrorSchema,\n errorToMessage: (error: LumaErrorData) =>\n error.detail[0].msg ?? 'Unknown error',\n });\n }\n\n private getLumaGenerationsUrl(generationId?: string) {\n return `${this.config.baseURL}/dream-machine/v1/generations/${\n generationId ?? 'image'\n }`;\n }\n\n private async downloadImage(\n url: string,\n abortSignal: AbortSignal | undefined,\n ): Promise<Uint8Array> {\n const { value: response } = await getFromApi({\n url,\n // No specific headers should be needed for this request as it's a\n // generated image provided by Luma.\n abortSignal,\n failedResponseHandler: createStatusCodeErrorResponseHandler(),\n successfulResponseHandler: createBinaryResponseHandler(),\n fetch: this.config.fetch,\n });\n return response;\n }\n}\n\n// limited version of the schema, focussed on what is needed for the implementation\n// this approach limits breakages when the API changes and increases efficiency\nconst lumaGenerationResponseSchema = z.object({\n id: z.string(),\n state: z.enum(['queued', 'dreaming', 'completed', 'failed']),\n failure_reason: z.string().nullish(),\n assets: z\n .object({\n image: z.string(), // URL of the generated image\n })\n .nullish(),\n});\n\nconst lumaErrorSchema = z.object({\n detail: z.array(\n z.object({\n type: z.string(),\n loc: z.array(z.string()),\n msg: z.string(),\n input: z.string(),\n ctx: z\n .object({\n expected: z.string(),\n })\n .nullish(),\n }),\n ),\n});\n\nexport type LumaErrorData = z.infer<typeof lumaErrorSchema>;\n"],"mappings":"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","names":["import_provider","import_provider_utils"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/luma-provider.ts","../src/luma-image-model.ts"],"sourcesContent":["export { createLuma, luma } from './luma-provider';\nexport type { LumaProvider, LumaProviderSettings } from './luma-provider';\nexport type { LumaErrorData } from './luma-image-model';\n","import { ImageModelV2, NoSuchModelError, ProviderV2 } from '@ai-sdk/provider';\nimport {\n FetchFunction,\n loadApiKey,\n withoutTrailingSlash,\n} from '@ai-sdk/provider-utils';\nimport { LumaImageModel } from './luma-image-model';\nimport { LumaImageModelId } from './luma-image-settings';\n\nexport interface LumaProviderSettings {\n /**\nLuma API key. Default value is taken from the `LUMA_API_KEY` environment\nvariable.\n */\n apiKey?: string;\n /**\nBase URL for the API calls.\n */\n baseURL?: string;\n /**\nCustom headers to include in the requests.\n */\n headers?: Record<string, string>;\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface LumaProvider extends ProviderV2 {\n /**\nCreates a model for image generation.\n */\n image(modelId: LumaImageModelId): ImageModelV2;\n\n /**\nCreates a model for image generation.\n */\n imageModel(modelId: LumaImageModelId): ImageModelV2;\n}\n\nconst defaultBaseURL = 'https://api.lumalabs.ai';\n\nexport function createLuma(options: LumaProviderSettings = {}): LumaProvider {\n const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL);\n const getHeaders = () => ({\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'LUMA_API_KEY',\n description: 'Luma',\n })}`,\n ...options.headers,\n });\n\n const createImageModel = (modelId: LumaImageModelId) =>\n new LumaImageModel(modelId, {\n provider: 'luma.image',\n baseURL: baseURL ?? defaultBaseURL,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n return {\n image: createImageModel,\n imageModel: createImageModel,\n languageModel: () => {\n throw new NoSuchModelError({\n modelId: 'languageModel',\n modelType: 'languageModel',\n });\n },\n textEmbeddingModel: () => {\n throw new NoSuchModelError({\n modelId: 'textEmbeddingModel',\n modelType: 'textEmbeddingModel',\n });\n },\n };\n}\n\nexport const luma = createLuma();\n","import {\n ImageModelV2,\n ImageModelV2CallWarning,\n InvalidResponseDataError,\n} from '@ai-sdk/provider';\nimport {\n FetchFunction,\n combineHeaders,\n createBinaryResponseHandler,\n createJsonResponseHandler,\n createJsonErrorResponseHandler,\n createStatusCodeErrorResponseHandler,\n delay,\n getFromApi,\n postJsonToApi,\n} from '@ai-sdk/provider-utils';\nimport { LumaImageSettings } from './luma-image-settings';\nimport { z } from 'zod/v4';\n\nconst DEFAULT_POLL_INTERVAL_MILLIS = 500;\nconst DEFAULT_MAX_POLL_ATTEMPTS = 60000 / DEFAULT_POLL_INTERVAL_MILLIS;\n\ninterface LumaImageModelConfig {\n provider: string;\n baseURL: string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class LumaImageModel implements ImageModelV2 {\n readonly specificationVersion = 'v2';\n readonly maxImagesPerCall = 1;\n readonly pollIntervalMillis = DEFAULT_POLL_INTERVAL_MILLIS;\n readonly maxPollAttempts = DEFAULT_MAX_POLL_ATTEMPTS;\n\n get provider(): string {\n return this.config.provider;\n }\n\n constructor(\n readonly modelId: string,\n private readonly config: LumaImageModelConfig,\n ) {}\n\n async doGenerate({\n prompt,\n n,\n size,\n aspectRatio,\n seed,\n providerOptions,\n headers,\n abortSignal,\n }: Parameters<ImageModelV2['doGenerate']>[0]): Promise<\n Awaited<ReturnType<ImageModelV2['doGenerate']>>\n > {\n const warnings: Array<ImageModelV2CallWarning> = [];\n\n if (seed != null) {\n warnings.push({\n type: 'unsupported-setting',\n setting: 'seed',\n details: 'This model does not support the `seed` option.',\n });\n }\n\n if (size != null) {\n warnings.push({\n type: 'unsupported-setting',\n setting: 'size',\n details:\n 'This model does not support the `size` option. Use `aspectRatio` instead.',\n });\n }\n\n // remove non-request options from providerOptions\n const { pollIntervalMillis, maxPollAttempts, ...providerRequestOptions } =\n providerOptions.luma ?? {};\n\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const fullHeaders = combineHeaders(this.config.headers(), headers);\n const { value: generationResponse, responseHeaders } = await postJsonToApi({\n url: this.getLumaGenerationsUrl(),\n headers: fullHeaders,\n body: {\n prompt,\n ...(aspectRatio ? { aspect_ratio: aspectRatio } : {}),\n model: this.modelId,\n ...providerRequestOptions,\n },\n abortSignal,\n fetch: this.config.fetch,\n failedResponseHandler: this.createLumaErrorHandler(),\n successfulResponseHandler: createJsonResponseHandler(\n lumaGenerationResponseSchema,\n ),\n });\n\n const imageUrl = await this.pollForImageUrl(\n generationResponse.id,\n fullHeaders,\n abortSignal,\n providerOptions.luma,\n );\n\n const downloadedImage = await this.downloadImage(imageUrl, abortSignal);\n\n return {\n images: [downloadedImage],\n warnings,\n response: {\n modelId: this.modelId,\n timestamp: currentDate,\n headers: responseHeaders,\n },\n };\n }\n\n private async pollForImageUrl(\n generationId: string,\n headers: Record<string, string | undefined>,\n abortSignal: AbortSignal | undefined,\n imageSettings?: LumaImageSettings,\n ): Promise<string> {\n const url = this.getLumaGenerationsUrl(generationId);\n const maxPollAttempts =\n imageSettings?.maxPollAttempts ?? this.maxPollAttempts;\n const pollIntervalMillis =\n imageSettings?.pollIntervalMillis ?? this.pollIntervalMillis;\n\n for (let i = 0; i < maxPollAttempts; i++) {\n const { value: statusResponse } = await getFromApi({\n url,\n headers,\n abortSignal,\n fetch: this.config.fetch,\n failedResponseHandler: this.createLumaErrorHandler(),\n successfulResponseHandler: createJsonResponseHandler(\n lumaGenerationResponseSchema,\n ),\n });\n\n switch (statusResponse.state) {\n case 'completed':\n if (!statusResponse.assets?.image) {\n throw new InvalidResponseDataError({\n data: statusResponse,\n message: `Image generation completed but no image was found.`,\n });\n }\n return statusResponse.assets.image;\n case 'failed':\n throw new InvalidResponseDataError({\n data: statusResponse,\n message: `Image generation failed.`,\n });\n }\n await delay(pollIntervalMillis);\n }\n\n throw new Error(\n `Image generation timed out after ${this.maxPollAttempts} attempts.`,\n );\n }\n\n private createLumaErrorHandler() {\n return createJsonErrorResponseHandler({\n errorSchema: lumaErrorSchema,\n errorToMessage: (error: LumaErrorData) =>\n error.detail[0].msg ?? 'Unknown error',\n });\n }\n\n private getLumaGenerationsUrl(generationId?: string) {\n return `${this.config.baseURL}/dream-machine/v1/generations/${\n generationId ?? 'image'\n }`;\n }\n\n private async downloadImage(\n url: string,\n abortSignal: AbortSignal | undefined,\n ): Promise<Uint8Array> {\n const { value: response } = await getFromApi({\n url,\n // No specific headers should be needed for this request as it's a\n // generated image provided by Luma.\n abortSignal,\n failedResponseHandler: createStatusCodeErrorResponseHandler(),\n successfulResponseHandler: createBinaryResponseHandler(),\n fetch: this.config.fetch,\n });\n return response;\n }\n}\n\n// limited version of the schema, focussed on what is needed for the implementation\n// this approach limits breakages when the API changes and increases efficiency\nconst lumaGenerationResponseSchema = z.object({\n id: z.string(),\n state: z.enum(['queued', 'dreaming', 'completed', 'failed']),\n failure_reason: z.string().nullish(),\n assets: z\n .object({\n image: z.string(), // URL of the generated image\n })\n .nullish(),\n});\n\nconst lumaErrorSchema = z.object({\n detail: z.array(\n z.object({\n type: z.string(),\n loc: z.array(z.string()),\n msg: z.string(),\n input: z.string(),\n ctx: z\n .object({\n expected: z.string(),\n })\n .nullish(),\n }),\n ),\n});\n\nexport type LumaErrorData = z.infer<typeof lumaErrorSchema>;\n"],"mappings":"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","names":["import_provider","import_provider_utils"]}
package/dist/index.mjs CHANGED
@@ -19,26 +19,21 @@ import {
19
19
  getFromApi,
20
20
  postJsonToApi
21
21
  } from "@ai-sdk/provider-utils";
22
- import { z } from "zod";
22
+ import { z } from "zod/v4";
23
23
  var DEFAULT_POLL_INTERVAL_MILLIS = 500;
24
24
  var DEFAULT_MAX_POLL_ATTEMPTS = 6e4 / DEFAULT_POLL_INTERVAL_MILLIS;
25
25
  var LumaImageModel = class {
26
- constructor(modelId, settings, config) {
26
+ constructor(modelId, config) {
27
27
  this.modelId = modelId;
28
- this.settings = settings;
29
28
  this.config = config;
30
- this.specificationVersion = "v1";
31
- var _a, _b;
32
- this.pollIntervalMillis = (_a = settings.pollIntervalMillis) != null ? _a : DEFAULT_POLL_INTERVAL_MILLIS;
33
- this.maxPollAttempts = (_b = settings.maxPollAttempts) != null ? _b : DEFAULT_MAX_POLL_ATTEMPTS;
29
+ this.specificationVersion = "v2";
30
+ this.maxImagesPerCall = 1;
31
+ this.pollIntervalMillis = DEFAULT_POLL_INTERVAL_MILLIS;
32
+ this.maxPollAttempts = DEFAULT_MAX_POLL_ATTEMPTS;
34
33
  }
35
34
  get provider() {
36
35
  return this.config.provider;
37
36
  }
38
- get maxImagesPerCall() {
39
- var _a;
40
- return (_a = this.settings.maxImagesPerCall) != null ? _a : 1;
41
- }
42
37
  async doGenerate({
43
38
  prompt,
44
39
  n,
@@ -65,7 +60,8 @@ var LumaImageModel = class {
65
60
  details: "This model does not support the `size` option. Use `aspectRatio` instead."
66
61
  });
67
62
  }
68
- const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
63
+ const { pollIntervalMillis, maxPollAttempts, ...providerRequestOptions } = (_a = providerOptions.luma) != null ? _a : {};
64
+ const currentDate = (_d = (_c = (_b = this.config._internal) == null ? void 0 : _b.currentDate) == null ? void 0 : _c.call(_b)) != null ? _d : /* @__PURE__ */ new Date();
69
65
  const fullHeaders = combineHeaders(this.config.headers(), headers);
70
66
  const { value: generationResponse, responseHeaders } = await postJsonToApi({
71
67
  url: this.getLumaGenerationsUrl(),
@@ -74,7 +70,7 @@ var LumaImageModel = class {
74
70
  prompt,
75
71
  ...aspectRatio ? { aspect_ratio: aspectRatio } : {},
76
72
  model: this.modelId,
77
- ...(_d = providerOptions.luma) != null ? _d : {}
73
+ ...providerRequestOptions
78
74
  },
79
75
  abortSignal,
80
76
  fetch: this.config.fetch,
@@ -86,7 +82,8 @@ var LumaImageModel = class {
86
82
  const imageUrl = await this.pollForImageUrl(
87
83
  generationResponse.id,
88
84
  fullHeaders,
89
- abortSignal
85
+ abortSignal,
86
+ providerOptions.luma
90
87
  );
91
88
  const downloadedImage = await this.downloadImage(imageUrl, abortSignal);
92
89
  return {
@@ -99,11 +96,12 @@ var LumaImageModel = class {
99
96
  }
100
97
  };
101
98
  }
102
- async pollForImageUrl(generationId, headers, abortSignal) {
103
- var _a;
104
- let attemptCount = 0;
99
+ async pollForImageUrl(generationId, headers, abortSignal, imageSettings) {
100
+ var _a, _b, _c;
105
101
  const url = this.getLumaGenerationsUrl(generationId);
106
- for (let i = 0; i < this.maxPollAttempts; i++) {
102
+ const maxPollAttempts = (_a = imageSettings == null ? void 0 : imageSettings.maxPollAttempts) != null ? _a : this.maxPollAttempts;
103
+ const pollIntervalMillis = (_b = imageSettings == null ? void 0 : imageSettings.pollIntervalMillis) != null ? _b : this.pollIntervalMillis;
104
+ for (let i = 0; i < maxPollAttempts; i++) {
107
105
  const { value: statusResponse } = await getFromApi({
108
106
  url,
109
107
  headers,
@@ -116,7 +114,7 @@ var LumaImageModel = class {
116
114
  });
117
115
  switch (statusResponse.state) {
118
116
  case "completed":
119
- if (!((_a = statusResponse.assets) == null ? void 0 : _a.image)) {
117
+ if (!((_c = statusResponse.assets) == null ? void 0 : _c.image)) {
120
118
  throw new InvalidResponseDataError({
121
119
  data: statusResponse,
122
120
  message: `Image generation completed but no image was found.`
@@ -129,7 +127,7 @@ var LumaImageModel = class {
129
127
  message: `Image generation failed.`
130
128
  });
131
129
  }
132
- await delay(this.pollIntervalMillis);
130
+ await delay(pollIntervalMillis);
133
131
  }
134
132
  throw new Error(
135
133
  `Image generation timed out after ${this.maxPollAttempts} attempts.`
@@ -196,7 +194,7 @@ function createLuma(options = {}) {
196
194
  })}`,
197
195
  ...options.headers
198
196
  });
199
- const createImageModel = (modelId, settings = {}) => new LumaImageModel(modelId, settings, {
197
+ const createImageModel = (modelId) => new LumaImageModel(modelId, {
200
198
  provider: "luma.image",
201
199
  baseURL: baseURL != null ? baseURL : defaultBaseURL,
202
200
  headers: getHeaders,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/luma-provider.ts","../src/luma-image-model.ts"],"sourcesContent":["import { ImageModelV1, NoSuchModelError, ProviderV2 } from '@ai-sdk/provider';\nimport {\n FetchFunction,\n loadApiKey,\n withoutTrailingSlash,\n} from '@ai-sdk/provider-utils';\nimport { LumaImageModel } from './luma-image-model';\nimport { LumaImageModelId, LumaImageSettings } from './luma-image-settings';\n\nexport interface LumaProviderSettings {\n /**\nLuma API key. Default value is taken from the `LUMA_API_KEY` environment\nvariable.\n */\n apiKey?: string;\n /**\nBase URL for the API calls.\n */\n baseURL?: string;\n /**\nCustom headers to include in the requests.\n */\n headers?: Record<string, string>;\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface LumaProvider extends ProviderV2 {\n /**\nCreates a model for image generation.\n */\n image(modelId: LumaImageModelId, settings?: LumaImageSettings): ImageModelV1;\n\n /**\nCreates a model for image generation.\n */\n imageModel(\n modelId: LumaImageModelId,\n settings?: LumaImageSettings,\n ): ImageModelV1;\n}\n\nconst defaultBaseURL = 'https://api.lumalabs.ai';\n\nexport function createLuma(options: LumaProviderSettings = {}): LumaProvider {\n const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL);\n const getHeaders = () => ({\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'LUMA_API_KEY',\n description: 'Luma',\n })}`,\n ...options.headers,\n });\n\n const createImageModel = (\n modelId: LumaImageModelId,\n settings: LumaImageSettings = {},\n ) =>\n new LumaImageModel(modelId, settings, {\n provider: 'luma.image',\n baseURL: baseURL ?? defaultBaseURL,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n return {\n image: createImageModel,\n imageModel: createImageModel,\n languageModel: () => {\n throw new NoSuchModelError({\n modelId: 'languageModel',\n modelType: 'languageModel',\n });\n },\n textEmbeddingModel: () => {\n throw new NoSuchModelError({\n modelId: 'textEmbeddingModel',\n modelType: 'textEmbeddingModel',\n });\n },\n };\n}\n\nexport const luma = createLuma();\n","import {\n ImageModelV1,\n ImageModelV1CallWarning,\n InvalidResponseDataError,\n} from '@ai-sdk/provider';\nimport {\n FetchFunction,\n combineHeaders,\n createBinaryResponseHandler,\n createJsonResponseHandler,\n createJsonErrorResponseHandler,\n createStatusCodeErrorResponseHandler,\n delay,\n getFromApi,\n postJsonToApi,\n} from '@ai-sdk/provider-utils';\nimport { LumaImageSettings } from './luma-image-settings';\nimport { z } from 'zod';\n\nconst DEFAULT_POLL_INTERVAL_MILLIS = 500;\nconst DEFAULT_MAX_POLL_ATTEMPTS = 60000 / DEFAULT_POLL_INTERVAL_MILLIS;\n\ninterface LumaImageModelConfig {\n provider: string;\n baseURL: string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class LumaImageModel implements ImageModelV1 {\n readonly specificationVersion = 'v1';\n\n private readonly pollIntervalMillis: number;\n private readonly maxPollAttempts: number;\n\n get provider(): string {\n return this.config.provider;\n }\n\n get maxImagesPerCall(): number {\n return this.settings.maxImagesPerCall ?? 1;\n }\n\n constructor(\n readonly modelId: string,\n private readonly settings: LumaImageSettings,\n private readonly config: LumaImageModelConfig,\n ) {\n this.pollIntervalMillis =\n settings.pollIntervalMillis ?? DEFAULT_POLL_INTERVAL_MILLIS;\n this.maxPollAttempts =\n settings.maxPollAttempts ?? DEFAULT_MAX_POLL_ATTEMPTS;\n }\n\n async doGenerate({\n prompt,\n n,\n size,\n aspectRatio,\n seed,\n providerOptions,\n headers,\n abortSignal,\n }: Parameters<ImageModelV1['doGenerate']>[0]): Promise<\n Awaited<ReturnType<ImageModelV1['doGenerate']>>\n > {\n const warnings: Array<ImageModelV1CallWarning> = [];\n\n if (seed != null) {\n warnings.push({\n type: 'unsupported-setting',\n setting: 'seed',\n details: 'This model does not support the `seed` option.',\n });\n }\n\n if (size != null) {\n warnings.push({\n type: 'unsupported-setting',\n setting: 'size',\n details:\n 'This model does not support the `size` option. Use `aspectRatio` instead.',\n });\n }\n\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const fullHeaders = combineHeaders(this.config.headers(), headers);\n const { value: generationResponse, responseHeaders } = await postJsonToApi({\n url: this.getLumaGenerationsUrl(),\n headers: fullHeaders,\n body: {\n prompt,\n ...(aspectRatio ? { aspect_ratio: aspectRatio } : {}),\n model: this.modelId,\n ...(providerOptions.luma ?? {}),\n },\n abortSignal,\n fetch: this.config.fetch,\n failedResponseHandler: this.createLumaErrorHandler(),\n successfulResponseHandler: createJsonResponseHandler(\n lumaGenerationResponseSchema,\n ),\n });\n\n const imageUrl = await this.pollForImageUrl(\n generationResponse.id,\n fullHeaders,\n abortSignal,\n );\n\n const downloadedImage = await this.downloadImage(imageUrl, abortSignal);\n\n return {\n images: [downloadedImage],\n warnings,\n response: {\n modelId: this.modelId,\n timestamp: currentDate,\n headers: responseHeaders,\n },\n };\n }\n\n private async pollForImageUrl(\n generationId: string,\n headers: Record<string, string | undefined>,\n abortSignal: AbortSignal | undefined,\n ): Promise<string> {\n let attemptCount = 0;\n const url = this.getLumaGenerationsUrl(generationId);\n for (let i = 0; i < this.maxPollAttempts; i++) {\n const { value: statusResponse } = await getFromApi({\n url,\n headers,\n abortSignal,\n fetch: this.config.fetch,\n failedResponseHandler: this.createLumaErrorHandler(),\n successfulResponseHandler: createJsonResponseHandler(\n lumaGenerationResponseSchema,\n ),\n });\n\n switch (statusResponse.state) {\n case 'completed':\n if (!statusResponse.assets?.image) {\n throw new InvalidResponseDataError({\n data: statusResponse,\n message: `Image generation completed but no image was found.`,\n });\n }\n return statusResponse.assets.image;\n case 'failed':\n throw new InvalidResponseDataError({\n data: statusResponse,\n message: `Image generation failed.`,\n });\n }\n await delay(this.pollIntervalMillis);\n }\n\n throw new Error(\n `Image generation timed out after ${this.maxPollAttempts} attempts.`,\n );\n }\n\n private createLumaErrorHandler() {\n return createJsonErrorResponseHandler({\n errorSchema: lumaErrorSchema,\n errorToMessage: (error: LumaErrorData) =>\n error.detail[0].msg ?? 'Unknown error',\n });\n }\n\n private getLumaGenerationsUrl(generationId?: string) {\n return `${this.config.baseURL}/dream-machine/v1/generations/${\n generationId ?? 'image'\n }`;\n }\n\n private async downloadImage(\n url: string,\n abortSignal: AbortSignal | undefined,\n ): Promise<Uint8Array> {\n const { value: response } = await getFromApi({\n url,\n // No specific headers should be needed for this request as it's a\n // generated image provided by Luma.\n abortSignal,\n failedResponseHandler: createStatusCodeErrorResponseHandler(),\n successfulResponseHandler: createBinaryResponseHandler(),\n fetch: this.config.fetch,\n });\n return response;\n }\n}\n\n// limited version of the schema, focussed on what is needed for the implementation\n// this approach limits breakages when the API changes and increases efficiency\nconst lumaGenerationResponseSchema = z.object({\n id: z.string(),\n state: z.enum(['queued', 'dreaming', 'completed', 'failed']),\n failure_reason: z.string().nullish(),\n assets: z\n .object({\n image: z.string(), // URL of the generated image\n })\n .nullish(),\n});\n\nconst lumaErrorSchema = z.object({\n detail: z.array(\n z.object({\n type: z.string(),\n loc: z.array(z.string()),\n msg: z.string(),\n input: z.string(),\n ctx: z\n .object({\n expected: z.string(),\n })\n .nullish(),\n }),\n ),\n});\n\nexport type LumaErrorData = z.infer<typeof lumaErrorSchema>;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/luma-provider.ts","../src/luma-image-model.ts"],"sourcesContent":["import { ImageModelV2, NoSuchModelError, ProviderV2 } from '@ai-sdk/provider';\nimport {\n FetchFunction,\n loadApiKey,\n withoutTrailingSlash,\n} from '@ai-sdk/provider-utils';\nimport { LumaImageModel } from './luma-image-model';\nimport { LumaImageModelId } from './luma-image-settings';\n\nexport interface LumaProviderSettings {\n /**\nLuma API key. Default value is taken from the `LUMA_API_KEY` environment\nvariable.\n */\n apiKey?: string;\n /**\nBase URL for the API calls.\n */\n baseURL?: string;\n /**\nCustom headers to include in the requests.\n */\n headers?: Record<string, string>;\n /**\nCustom fetch implementation. You can use it as a middleware to intercept requests,\nor to provide a custom fetch implementation for e.g. testing.\n */\n fetch?: FetchFunction;\n}\n\nexport interface LumaProvider extends ProviderV2 {\n /**\nCreates a model for image generation.\n */\n image(modelId: LumaImageModelId): ImageModelV2;\n\n /**\nCreates a model for image generation.\n */\n imageModel(modelId: LumaImageModelId): ImageModelV2;\n}\n\nconst defaultBaseURL = 'https://api.lumalabs.ai';\n\nexport function createLuma(options: LumaProviderSettings = {}): LumaProvider {\n const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL);\n const getHeaders = () => ({\n Authorization: `Bearer ${loadApiKey({\n apiKey: options.apiKey,\n environmentVariableName: 'LUMA_API_KEY',\n description: 'Luma',\n })}`,\n ...options.headers,\n });\n\n const createImageModel = (modelId: LumaImageModelId) =>\n new LumaImageModel(modelId, {\n provider: 'luma.image',\n baseURL: baseURL ?? defaultBaseURL,\n headers: getHeaders,\n fetch: options.fetch,\n });\n\n return {\n image: createImageModel,\n imageModel: createImageModel,\n languageModel: () => {\n throw new NoSuchModelError({\n modelId: 'languageModel',\n modelType: 'languageModel',\n });\n },\n textEmbeddingModel: () => {\n throw new NoSuchModelError({\n modelId: 'textEmbeddingModel',\n modelType: 'textEmbeddingModel',\n });\n },\n };\n}\n\nexport const luma = createLuma();\n","import {\n ImageModelV2,\n ImageModelV2CallWarning,\n InvalidResponseDataError,\n} from '@ai-sdk/provider';\nimport {\n FetchFunction,\n combineHeaders,\n createBinaryResponseHandler,\n createJsonResponseHandler,\n createJsonErrorResponseHandler,\n createStatusCodeErrorResponseHandler,\n delay,\n getFromApi,\n postJsonToApi,\n} from '@ai-sdk/provider-utils';\nimport { LumaImageSettings } from './luma-image-settings';\nimport { z } from 'zod/v4';\n\nconst DEFAULT_POLL_INTERVAL_MILLIS = 500;\nconst DEFAULT_MAX_POLL_ATTEMPTS = 60000 / DEFAULT_POLL_INTERVAL_MILLIS;\n\ninterface LumaImageModelConfig {\n provider: string;\n baseURL: string;\n headers: () => Record<string, string>;\n fetch?: FetchFunction;\n _internal?: {\n currentDate?: () => Date;\n };\n}\n\nexport class LumaImageModel implements ImageModelV2 {\n readonly specificationVersion = 'v2';\n readonly maxImagesPerCall = 1;\n readonly pollIntervalMillis = DEFAULT_POLL_INTERVAL_MILLIS;\n readonly maxPollAttempts = DEFAULT_MAX_POLL_ATTEMPTS;\n\n get provider(): string {\n return this.config.provider;\n }\n\n constructor(\n readonly modelId: string,\n private readonly config: LumaImageModelConfig,\n ) {}\n\n async doGenerate({\n prompt,\n n,\n size,\n aspectRatio,\n seed,\n providerOptions,\n headers,\n abortSignal,\n }: Parameters<ImageModelV2['doGenerate']>[0]): Promise<\n Awaited<ReturnType<ImageModelV2['doGenerate']>>\n > {\n const warnings: Array<ImageModelV2CallWarning> = [];\n\n if (seed != null) {\n warnings.push({\n type: 'unsupported-setting',\n setting: 'seed',\n details: 'This model does not support the `seed` option.',\n });\n }\n\n if (size != null) {\n warnings.push({\n type: 'unsupported-setting',\n setting: 'size',\n details:\n 'This model does not support the `size` option. Use `aspectRatio` instead.',\n });\n }\n\n // remove non-request options from providerOptions\n const { pollIntervalMillis, maxPollAttempts, ...providerRequestOptions } =\n providerOptions.luma ?? {};\n\n const currentDate = this.config._internal?.currentDate?.() ?? new Date();\n const fullHeaders = combineHeaders(this.config.headers(), headers);\n const { value: generationResponse, responseHeaders } = await postJsonToApi({\n url: this.getLumaGenerationsUrl(),\n headers: fullHeaders,\n body: {\n prompt,\n ...(aspectRatio ? { aspect_ratio: aspectRatio } : {}),\n model: this.modelId,\n ...providerRequestOptions,\n },\n abortSignal,\n fetch: this.config.fetch,\n failedResponseHandler: this.createLumaErrorHandler(),\n successfulResponseHandler: createJsonResponseHandler(\n lumaGenerationResponseSchema,\n ),\n });\n\n const imageUrl = await this.pollForImageUrl(\n generationResponse.id,\n fullHeaders,\n abortSignal,\n providerOptions.luma,\n );\n\n const downloadedImage = await this.downloadImage(imageUrl, abortSignal);\n\n return {\n images: [downloadedImage],\n warnings,\n response: {\n modelId: this.modelId,\n timestamp: currentDate,\n headers: responseHeaders,\n },\n };\n }\n\n private async pollForImageUrl(\n generationId: string,\n headers: Record<string, string | undefined>,\n abortSignal: AbortSignal | undefined,\n imageSettings?: LumaImageSettings,\n ): Promise<string> {\n const url = this.getLumaGenerationsUrl(generationId);\n const maxPollAttempts =\n imageSettings?.maxPollAttempts ?? this.maxPollAttempts;\n const pollIntervalMillis =\n imageSettings?.pollIntervalMillis ?? this.pollIntervalMillis;\n\n for (let i = 0; i < maxPollAttempts; i++) {\n const { value: statusResponse } = await getFromApi({\n url,\n headers,\n abortSignal,\n fetch: this.config.fetch,\n failedResponseHandler: this.createLumaErrorHandler(),\n successfulResponseHandler: createJsonResponseHandler(\n lumaGenerationResponseSchema,\n ),\n });\n\n switch (statusResponse.state) {\n case 'completed':\n if (!statusResponse.assets?.image) {\n throw new InvalidResponseDataError({\n data: statusResponse,\n message: `Image generation completed but no image was found.`,\n });\n }\n return statusResponse.assets.image;\n case 'failed':\n throw new InvalidResponseDataError({\n data: statusResponse,\n message: `Image generation failed.`,\n });\n }\n await delay(pollIntervalMillis);\n }\n\n throw new Error(\n `Image generation timed out after ${this.maxPollAttempts} attempts.`,\n );\n }\n\n private createLumaErrorHandler() {\n return createJsonErrorResponseHandler({\n errorSchema: lumaErrorSchema,\n errorToMessage: (error: LumaErrorData) =>\n error.detail[0].msg ?? 'Unknown error',\n });\n }\n\n private getLumaGenerationsUrl(generationId?: string) {\n return `${this.config.baseURL}/dream-machine/v1/generations/${\n generationId ?? 'image'\n }`;\n }\n\n private async downloadImage(\n url: string,\n abortSignal: AbortSignal | undefined,\n ): Promise<Uint8Array> {\n const { value: response } = await getFromApi({\n url,\n // No specific headers should be needed for this request as it's a\n // generated image provided by Luma.\n abortSignal,\n failedResponseHandler: createStatusCodeErrorResponseHandler(),\n successfulResponseHandler: createBinaryResponseHandler(),\n fetch: this.config.fetch,\n });\n return response;\n }\n}\n\n// limited version of the schema, focussed on what is needed for the implementation\n// this approach limits breakages when the API changes and increases efficiency\nconst lumaGenerationResponseSchema = z.object({\n id: z.string(),\n state: z.enum(['queued', 'dreaming', 'completed', 'failed']),\n failure_reason: z.string().nullish(),\n assets: z\n .object({\n image: z.string(), // URL of the generated image\n })\n .nullish(),\n});\n\nconst lumaErrorSchema = z.object({\n detail: z.array(\n z.object({\n type: z.string(),\n loc: z.array(z.string()),\n msg: z.string(),\n input: z.string(),\n ctx: z\n .object({\n expected: z.string(),\n })\n .nullish(),\n }),\n ),\n});\n\nexport type LumaErrorData = z.infer<typeof lumaErrorSchema>;\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/luma",
3
- "version": "1.0.0-canary.9",
3
+ "version": "1.0.1",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -19,18 +19,18 @@
19
19
  }
20
20
  },
21
21
  "dependencies": {
22
- "@ai-sdk/provider": "2.0.0-canary.8",
23
- "@ai-sdk/provider-utils": "3.0.0-canary.9"
22
+ "@ai-sdk/provider": "2.0.0",
23
+ "@ai-sdk/provider-utils": "3.0.1"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/node": "20.17.24",
27
27
  "tsup": "^8",
28
28
  "typescript": "5.8.3",
29
- "zod": "3.23.8",
29
+ "zod": "3.25.76",
30
30
  "@vercel/ai-tsconfig": "0.0.0"
31
31
  },
32
32
  "peerDependencies": {
33
- "zod": "^3.0.0"
33
+ "zod": "^3.25.76 || ^4"
34
34
  },
35
35
  "engines": {
36
36
  "node": ">=18"
@@ -38,7 +38,7 @@
38
38
  "publishConfig": {
39
39
  "access": "public"
40
40
  },
41
- "homepage": "https://sdk.vercel.ai/docs",
41
+ "homepage": "https://ai-sdk.dev/docs",
42
42
  "repository": {
43
43
  "type": "git",
44
44
  "url": "git+https://github.com/vercel/ai.git"