@ai-sdk/luma 3.0.0-beta.3 → 3.0.0-beta.31
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 +247 -8
- package/README.md +2 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +132 -121
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
- package/src/index.ts +2 -2
- package/src/luma-image-model-options.ts +71 -0
- package/src/luma-image-model.ts +32 -75
- package/src/luma-provider.ts +11 -7
- package/dist/index.d.mts +0 -76
- package/dist/index.mjs +0 -399
- package/dist/index.mjs.map +0 -1
package/src/luma-image-model.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ImageModelV3,
|
|
3
|
-
ImageModelV3File,
|
|
4
|
-
SharedV3Warning,
|
|
5
2
|
InvalidResponseDataError,
|
|
3
|
+
type ImageModelV4,
|
|
4
|
+
type ImageModelV4File,
|
|
5
|
+
type SharedV4Warning,
|
|
6
6
|
} from '@ai-sdk/provider';
|
|
7
7
|
import {
|
|
8
|
-
FetchFunction,
|
|
9
8
|
combineHeaders,
|
|
10
9
|
createBinaryResponseHandler,
|
|
11
10
|
createJsonResponseHandler,
|
|
@@ -14,12 +13,16 @@ import {
|
|
|
14
13
|
delay,
|
|
15
14
|
getFromApi,
|
|
16
15
|
postJsonToApi,
|
|
17
|
-
InferSchema,
|
|
18
16
|
lazySchema,
|
|
19
17
|
parseProviderOptions,
|
|
20
18
|
zodSchema,
|
|
19
|
+
serializeModelOptions,
|
|
20
|
+
WORKFLOW_SERIALIZE,
|
|
21
|
+
WORKFLOW_DESERIALIZE,
|
|
22
|
+
type FetchFunction,
|
|
21
23
|
} from '@ai-sdk/provider-utils';
|
|
22
|
-
import {
|
|
24
|
+
import { lumaImageModelOptionsSchema } from './luma-image-model-options';
|
|
25
|
+
import type { LumaReferenceType } from './luma-image-settings';
|
|
23
26
|
import { z } from 'zod/v4';
|
|
24
27
|
|
|
25
28
|
const DEFAULT_POLL_INTERVAL_MILLIS = 500;
|
|
@@ -28,15 +31,15 @@ const DEFAULT_MAX_POLL_ATTEMPTS = 60000 / DEFAULT_POLL_INTERVAL_MILLIS;
|
|
|
28
31
|
interface LumaImageModelConfig {
|
|
29
32
|
provider: string;
|
|
30
33
|
baseURL: string;
|
|
31
|
-
headers
|
|
34
|
+
headers?: () => Record<string, string>;
|
|
32
35
|
fetch?: FetchFunction;
|
|
33
36
|
_internal?: {
|
|
34
37
|
currentDate?: () => Date;
|
|
35
38
|
};
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
export class LumaImageModel implements
|
|
39
|
-
readonly specificationVersion = '
|
|
41
|
+
export class LumaImageModel implements ImageModelV4 {
|
|
42
|
+
readonly specificationVersion = 'v4';
|
|
40
43
|
readonly maxImagesPerCall = 1;
|
|
41
44
|
readonly pollIntervalMillis = DEFAULT_POLL_INTERVAL_MILLIS;
|
|
42
45
|
readonly maxPollAttempts = DEFAULT_MAX_POLL_ATTEMPTS;
|
|
@@ -45,6 +48,20 @@ export class LumaImageModel implements ImageModelV3 {
|
|
|
45
48
|
return this.config.provider;
|
|
46
49
|
}
|
|
47
50
|
|
|
51
|
+
static [WORKFLOW_SERIALIZE](model: LumaImageModel) {
|
|
52
|
+
return serializeModelOptions({
|
|
53
|
+
modelId: model.modelId,
|
|
54
|
+
config: model.config,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
59
|
+
modelId: string;
|
|
60
|
+
config: LumaImageModelConfig;
|
|
61
|
+
}) {
|
|
62
|
+
return new LumaImageModel(options.modelId, options.config);
|
|
63
|
+
}
|
|
64
|
+
|
|
48
65
|
constructor(
|
|
49
66
|
readonly modelId: string,
|
|
50
67
|
private readonly config: LumaImageModelConfig,
|
|
@@ -52,7 +69,6 @@ export class LumaImageModel implements ImageModelV3 {
|
|
|
52
69
|
|
|
53
70
|
async doGenerate({
|
|
54
71
|
prompt,
|
|
55
|
-
n,
|
|
56
72
|
size,
|
|
57
73
|
aspectRatio,
|
|
58
74
|
seed,
|
|
@@ -61,10 +77,10 @@ export class LumaImageModel implements ImageModelV3 {
|
|
|
61
77
|
abortSignal,
|
|
62
78
|
files,
|
|
63
79
|
mask,
|
|
64
|
-
}: Parameters<
|
|
65
|
-
Awaited<ReturnType<
|
|
80
|
+
}: Parameters<ImageModelV4['doGenerate']>[0]): Promise<
|
|
81
|
+
Awaited<ReturnType<ImageModelV4['doGenerate']>>
|
|
66
82
|
> {
|
|
67
|
-
const warnings: Array<
|
|
83
|
+
const warnings: Array<SharedV4Warning> = [];
|
|
68
84
|
|
|
69
85
|
if (seed != null) {
|
|
70
86
|
warnings.push({
|
|
@@ -108,7 +124,7 @@ export class LumaImageModel implements ImageModelV3 {
|
|
|
108
124
|
);
|
|
109
125
|
|
|
110
126
|
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
|
|
111
|
-
const fullHeaders = combineHeaders(this.config.headers(), headers);
|
|
127
|
+
const fullHeaders = combineHeaders(this.config.headers?.(), headers);
|
|
112
128
|
const { value: generationResponse, responseHeaders } = await postJsonToApi({
|
|
113
129
|
url: this.getLumaGenerationsUrl(),
|
|
114
130
|
headers: fullHeaders,
|
|
@@ -206,8 +222,8 @@ export class LumaImageModel implements ImageModelV3 {
|
|
|
206
222
|
}
|
|
207
223
|
|
|
208
224
|
private getEditingOptions(
|
|
209
|
-
files:
|
|
210
|
-
mask:
|
|
225
|
+
files: ImageModelV4File[] | undefined,
|
|
226
|
+
mask: ImageModelV4File | undefined,
|
|
211
227
|
referenceType: LumaReferenceType = 'image',
|
|
212
228
|
imageConfigs: Array<{ weight?: number | null; id?: string | null }> = [],
|
|
213
229
|
): Record<string, unknown> {
|
|
@@ -380,62 +396,3 @@ export type LumaErrorData = z.infer<typeof lumaErrorSchema>;
|
|
|
380
396
|
*
|
|
381
397
|
* @see https://docs.lumalabs.ai/docs/image-generation
|
|
382
398
|
*/
|
|
383
|
-
export const lumaImageModelOptionsSchema = lazySchema(() =>
|
|
384
|
-
zodSchema(
|
|
385
|
-
z
|
|
386
|
-
.object({
|
|
387
|
-
/**
|
|
388
|
-
* The type of image reference to use when providing input images.
|
|
389
|
-
* - `image`: Guide generation using reference images (up to 4). Default.
|
|
390
|
-
* - `style`: Apply a specific style from reference image(s).
|
|
391
|
-
* - `character`: Create consistent characters from reference images (up to 4).
|
|
392
|
-
* - `modify_image`: Transform a single input image with prompt guidance.
|
|
393
|
-
*/
|
|
394
|
-
referenceType: z
|
|
395
|
-
.enum(['image', 'style', 'character', 'modify_image'])
|
|
396
|
-
.nullish(),
|
|
397
|
-
|
|
398
|
-
/**
|
|
399
|
-
* Per-image configuration array. Each entry corresponds to an image in `prompt.images`.
|
|
400
|
-
* Allows setting individual weights for each reference image.
|
|
401
|
-
*/
|
|
402
|
-
images: z
|
|
403
|
-
.array(
|
|
404
|
-
z.object({
|
|
405
|
-
/**
|
|
406
|
-
* The weight of this image's influence on the generation.
|
|
407
|
-
* - For `image`: Higher weight = closer to reference (default: 0.85)
|
|
408
|
-
* - For `style`: Higher weight = stronger style influence (default: 0.8)
|
|
409
|
-
* - For `modify_image`: Higher weight = closer to input, lower = more creative (default: 1.0)
|
|
410
|
-
*/
|
|
411
|
-
weight: z.number().min(0).max(1).nullish(),
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* The identity name for character references.
|
|
415
|
-
* Used with `character` to specify which identity group the image belongs to.
|
|
416
|
-
* Luma supports multiple identities (e.g., 'identity0', 'identity1') for generating
|
|
417
|
-
* images with multiple consistent characters.
|
|
418
|
-
* Default: 'identity0'
|
|
419
|
-
*/
|
|
420
|
-
id: z.string().nullish(),
|
|
421
|
-
}),
|
|
422
|
-
)
|
|
423
|
-
.nullish(),
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* Override the polling interval in milliseconds (default 500).
|
|
427
|
-
*/
|
|
428
|
-
pollIntervalMillis: z.number().nullish(),
|
|
429
|
-
|
|
430
|
-
/**
|
|
431
|
-
* Override the maximum number of polling attempts (default 120).
|
|
432
|
-
*/
|
|
433
|
-
maxPollAttempts: z.number().nullish(),
|
|
434
|
-
})
|
|
435
|
-
.passthrough(),
|
|
436
|
-
),
|
|
437
|
-
);
|
|
438
|
-
|
|
439
|
-
export type LumaImageModelOptions = InferSchema<
|
|
440
|
-
typeof lumaImageModelOptionsSchema
|
|
441
|
-
>;
|
package/src/luma-provider.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import { ImageModelV3, NoSuchModelError, ProviderV3 } from '@ai-sdk/provider';
|
|
2
1
|
import {
|
|
3
|
-
|
|
2
|
+
NoSuchModelError,
|
|
3
|
+
type ImageModelV4,
|
|
4
|
+
type ProviderV4,
|
|
5
|
+
} from '@ai-sdk/provider';
|
|
6
|
+
import {
|
|
4
7
|
loadApiKey,
|
|
5
8
|
withoutTrailingSlash,
|
|
6
9
|
withUserAgentSuffix,
|
|
10
|
+
type FetchFunction,
|
|
7
11
|
} from '@ai-sdk/provider-utils';
|
|
8
12
|
import { LumaImageModel } from './luma-image-model';
|
|
9
|
-
import { LumaImageModelId } from './luma-image-settings';
|
|
13
|
+
import type { LumaImageModelId } from './luma-image-settings';
|
|
10
14
|
import { VERSION } from './version';
|
|
11
15
|
|
|
12
16
|
export interface LumaProviderSettings {
|
|
@@ -30,16 +34,16 @@ export interface LumaProviderSettings {
|
|
|
30
34
|
fetch?: FetchFunction;
|
|
31
35
|
}
|
|
32
36
|
|
|
33
|
-
export interface LumaProvider extends
|
|
37
|
+
export interface LumaProvider extends ProviderV4 {
|
|
34
38
|
/**
|
|
35
39
|
* Creates a model for image generation.
|
|
36
40
|
*/
|
|
37
|
-
image(modelId: LumaImageModelId):
|
|
41
|
+
image(modelId: LumaImageModelId): ImageModelV4;
|
|
38
42
|
|
|
39
43
|
/**
|
|
40
44
|
* Creates a model for image generation.
|
|
41
45
|
*/
|
|
42
|
-
imageModel(modelId: LumaImageModelId):
|
|
46
|
+
imageModel(modelId: LumaImageModelId): ImageModelV4;
|
|
43
47
|
|
|
44
48
|
/**
|
|
45
49
|
* @deprecated Use `embeddingModel` instead.
|
|
@@ -80,7 +84,7 @@ export function createLuma(options: LumaProviderSettings = {}): LumaProvider {
|
|
|
80
84
|
};
|
|
81
85
|
|
|
82
86
|
return {
|
|
83
|
-
specificationVersion: '
|
|
87
|
+
specificationVersion: 'v4' as const,
|
|
84
88
|
image: createImageModel,
|
|
85
89
|
imageModel: createImageModel,
|
|
86
90
|
languageModel: (modelId: string) => {
|
package/dist/index.d.mts
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { ProviderV3, ImageModelV3 } from '@ai-sdk/provider';
|
|
2
|
-
import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
|
|
3
|
-
import { FetchFunction, InferSchema } from '@ai-sdk/provider-utils';
|
|
4
|
-
import { z } from 'zod/v4';
|
|
5
|
-
|
|
6
|
-
type LumaImageModelId = 'photon-1' | 'photon-flash-1' | (string & {});
|
|
7
|
-
|
|
8
|
-
interface LumaProviderSettings {
|
|
9
|
-
/**
|
|
10
|
-
* Luma API key. Default value is taken from the `LUMA_API_KEY` environment
|
|
11
|
-
* variable.
|
|
12
|
-
*/
|
|
13
|
-
apiKey?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Base URL for the API calls.
|
|
16
|
-
*/
|
|
17
|
-
baseURL?: string;
|
|
18
|
-
/**
|
|
19
|
-
* Custom headers to include in the requests.
|
|
20
|
-
*/
|
|
21
|
-
headers?: Record<string, string>;
|
|
22
|
-
/**
|
|
23
|
-
* Custom fetch implementation. You can use it as a middleware to intercept requests,
|
|
24
|
-
* or to provide a custom fetch implementation for e.g. testing.
|
|
25
|
-
*/
|
|
26
|
-
fetch?: FetchFunction;
|
|
27
|
-
}
|
|
28
|
-
interface LumaProvider extends ProviderV3 {
|
|
29
|
-
/**
|
|
30
|
-
* Creates a model for image generation.
|
|
31
|
-
*/
|
|
32
|
-
image(modelId: LumaImageModelId): ImageModelV3;
|
|
33
|
-
/**
|
|
34
|
-
* Creates a model for image generation.
|
|
35
|
-
*/
|
|
36
|
-
imageModel(modelId: LumaImageModelId): ImageModelV3;
|
|
37
|
-
/**
|
|
38
|
-
* @deprecated Use `embeddingModel` instead.
|
|
39
|
-
*/
|
|
40
|
-
textEmbeddingModel(modelId: string): never;
|
|
41
|
-
}
|
|
42
|
-
declare function createLuma(options?: LumaProviderSettings): LumaProvider;
|
|
43
|
-
declare const luma: LumaProvider;
|
|
44
|
-
|
|
45
|
-
declare const lumaErrorSchema: z.ZodObject<{
|
|
46
|
-
detail: z.ZodArray<z.ZodObject<{
|
|
47
|
-
type: z.ZodString;
|
|
48
|
-
loc: z.ZodArray<z.ZodString>;
|
|
49
|
-
msg: z.ZodString;
|
|
50
|
-
input: z.ZodString;
|
|
51
|
-
ctx: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
52
|
-
expected: z.ZodString;
|
|
53
|
-
}, z.core.$strip>>>;
|
|
54
|
-
}, z.core.$strip>>;
|
|
55
|
-
}, z.core.$strip>;
|
|
56
|
-
type LumaErrorData = z.infer<typeof lumaErrorSchema>;
|
|
57
|
-
/**
|
|
58
|
-
* Provider options schema for Luma image generation.
|
|
59
|
-
*
|
|
60
|
-
* @see https://docs.lumalabs.ai/docs/image-generation
|
|
61
|
-
*/
|
|
62
|
-
declare const lumaImageModelOptionsSchema: _ai_sdk_provider_utils.LazySchema<{
|
|
63
|
-
[x: string]: unknown;
|
|
64
|
-
referenceType?: "image" | "style" | "character" | "modify_image" | null | undefined;
|
|
65
|
-
images?: {
|
|
66
|
-
weight?: number | null | undefined;
|
|
67
|
-
id?: string | null | undefined;
|
|
68
|
-
}[] | null | undefined;
|
|
69
|
-
pollIntervalMillis?: number | null | undefined;
|
|
70
|
-
maxPollAttempts?: number | null | undefined;
|
|
71
|
-
}>;
|
|
72
|
-
type LumaImageModelOptions = InferSchema<typeof lumaImageModelOptionsSchema>;
|
|
73
|
-
|
|
74
|
-
declare const VERSION: string;
|
|
75
|
-
|
|
76
|
-
export { type LumaErrorData, type LumaImageModelOptions, type LumaImageModelOptions as LumaImageProviderOptions, type LumaProvider, type LumaProviderSettings, VERSION, createLuma, luma };
|
package/dist/index.mjs
DELETED
|
@@ -1,399 +0,0 @@
|
|
|
1
|
-
// src/luma-provider.ts
|
|
2
|
-
import { NoSuchModelError } from "@ai-sdk/provider";
|
|
3
|
-
import {
|
|
4
|
-
loadApiKey,
|
|
5
|
-
withoutTrailingSlash,
|
|
6
|
-
withUserAgentSuffix
|
|
7
|
-
} from "@ai-sdk/provider-utils";
|
|
8
|
-
|
|
9
|
-
// src/luma-image-model.ts
|
|
10
|
-
import {
|
|
11
|
-
InvalidResponseDataError
|
|
12
|
-
} from "@ai-sdk/provider";
|
|
13
|
-
import {
|
|
14
|
-
combineHeaders,
|
|
15
|
-
createBinaryResponseHandler,
|
|
16
|
-
createJsonResponseHandler,
|
|
17
|
-
createJsonErrorResponseHandler,
|
|
18
|
-
createStatusCodeErrorResponseHandler,
|
|
19
|
-
delay,
|
|
20
|
-
getFromApi,
|
|
21
|
-
postJsonToApi,
|
|
22
|
-
lazySchema,
|
|
23
|
-
parseProviderOptions,
|
|
24
|
-
zodSchema
|
|
25
|
-
} from "@ai-sdk/provider-utils";
|
|
26
|
-
import { z } from "zod/v4";
|
|
27
|
-
var DEFAULT_POLL_INTERVAL_MILLIS = 500;
|
|
28
|
-
var DEFAULT_MAX_POLL_ATTEMPTS = 6e4 / DEFAULT_POLL_INTERVAL_MILLIS;
|
|
29
|
-
var LumaImageModel = class {
|
|
30
|
-
constructor(modelId, config) {
|
|
31
|
-
this.modelId = modelId;
|
|
32
|
-
this.config = config;
|
|
33
|
-
this.specificationVersion = "v3";
|
|
34
|
-
this.maxImagesPerCall = 1;
|
|
35
|
-
this.pollIntervalMillis = DEFAULT_POLL_INTERVAL_MILLIS;
|
|
36
|
-
this.maxPollAttempts = DEFAULT_MAX_POLL_ATTEMPTS;
|
|
37
|
-
}
|
|
38
|
-
get provider() {
|
|
39
|
-
return this.config.provider;
|
|
40
|
-
}
|
|
41
|
-
async doGenerate({
|
|
42
|
-
prompt,
|
|
43
|
-
n,
|
|
44
|
-
size,
|
|
45
|
-
aspectRatio,
|
|
46
|
-
seed,
|
|
47
|
-
providerOptions,
|
|
48
|
-
headers,
|
|
49
|
-
abortSignal,
|
|
50
|
-
files,
|
|
51
|
-
mask
|
|
52
|
-
}) {
|
|
53
|
-
var _a, _b, _c;
|
|
54
|
-
const warnings = [];
|
|
55
|
-
if (seed != null) {
|
|
56
|
-
warnings.push({
|
|
57
|
-
type: "unsupported",
|
|
58
|
-
feature: "seed",
|
|
59
|
-
details: "This model does not support the `seed` option."
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
if (size != null) {
|
|
63
|
-
warnings.push({
|
|
64
|
-
type: "unsupported",
|
|
65
|
-
feature: "size",
|
|
66
|
-
details: "This model does not support the `size` option. Use `aspectRatio` instead."
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
const lumaOptions = await parseProviderOptions({
|
|
70
|
-
provider: "luma",
|
|
71
|
-
providerOptions,
|
|
72
|
-
schema: lumaImageModelOptionsSchema
|
|
73
|
-
});
|
|
74
|
-
const {
|
|
75
|
-
pollIntervalMillis,
|
|
76
|
-
maxPollAttempts,
|
|
77
|
-
referenceType,
|
|
78
|
-
images: imageConfigs,
|
|
79
|
-
...providerRequestOptions
|
|
80
|
-
} = lumaOptions != null ? lumaOptions : {};
|
|
81
|
-
const editingOptions = this.getEditingOptions(
|
|
82
|
-
files,
|
|
83
|
-
mask,
|
|
84
|
-
referenceType != null ? referenceType : void 0,
|
|
85
|
-
imageConfigs != null ? imageConfigs : []
|
|
86
|
-
);
|
|
87
|
-
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
88
|
-
const fullHeaders = combineHeaders(this.config.headers(), headers);
|
|
89
|
-
const { value: generationResponse, responseHeaders } = await postJsonToApi({
|
|
90
|
-
url: this.getLumaGenerationsUrl(),
|
|
91
|
-
headers: fullHeaders,
|
|
92
|
-
body: {
|
|
93
|
-
prompt,
|
|
94
|
-
...aspectRatio ? { aspect_ratio: aspectRatio } : {},
|
|
95
|
-
model: this.modelId,
|
|
96
|
-
...editingOptions,
|
|
97
|
-
...providerRequestOptions
|
|
98
|
-
},
|
|
99
|
-
abortSignal,
|
|
100
|
-
fetch: this.config.fetch,
|
|
101
|
-
failedResponseHandler: this.createLumaErrorHandler(),
|
|
102
|
-
successfulResponseHandler: createJsonResponseHandler(
|
|
103
|
-
lumaGenerationResponseSchema
|
|
104
|
-
)
|
|
105
|
-
});
|
|
106
|
-
const imageUrl = await this.pollForImageUrl(
|
|
107
|
-
generationResponse.id,
|
|
108
|
-
fullHeaders,
|
|
109
|
-
abortSignal,
|
|
110
|
-
{
|
|
111
|
-
pollIntervalMillis: pollIntervalMillis != null ? pollIntervalMillis : void 0,
|
|
112
|
-
maxPollAttempts: maxPollAttempts != null ? maxPollAttempts : void 0
|
|
113
|
-
}
|
|
114
|
-
);
|
|
115
|
-
const downloadedImage = await this.downloadImage(imageUrl, abortSignal);
|
|
116
|
-
return {
|
|
117
|
-
images: [downloadedImage],
|
|
118
|
-
warnings,
|
|
119
|
-
response: {
|
|
120
|
-
modelId: this.modelId,
|
|
121
|
-
timestamp: currentDate,
|
|
122
|
-
headers: responseHeaders
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
async pollForImageUrl(generationId, headers, abortSignal, pollSettings) {
|
|
127
|
-
var _a, _b, _c;
|
|
128
|
-
const url = this.getLumaGenerationsUrl(generationId);
|
|
129
|
-
const maxPollAttempts = (_a = pollSettings == null ? void 0 : pollSettings.maxPollAttempts) != null ? _a : this.maxPollAttempts;
|
|
130
|
-
const pollIntervalMillis = (_b = pollSettings == null ? void 0 : pollSettings.pollIntervalMillis) != null ? _b : this.pollIntervalMillis;
|
|
131
|
-
for (let i = 0; i < maxPollAttempts; i++) {
|
|
132
|
-
const { value: statusResponse } = await getFromApi({
|
|
133
|
-
url,
|
|
134
|
-
headers,
|
|
135
|
-
abortSignal,
|
|
136
|
-
fetch: this.config.fetch,
|
|
137
|
-
failedResponseHandler: this.createLumaErrorHandler(),
|
|
138
|
-
successfulResponseHandler: createJsonResponseHandler(
|
|
139
|
-
lumaGenerationResponseSchema
|
|
140
|
-
)
|
|
141
|
-
});
|
|
142
|
-
switch (statusResponse.state) {
|
|
143
|
-
case "completed":
|
|
144
|
-
if (!((_c = statusResponse.assets) == null ? void 0 : _c.image)) {
|
|
145
|
-
throw new InvalidResponseDataError({
|
|
146
|
-
data: statusResponse,
|
|
147
|
-
message: `Image generation completed but no image was found.`
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
return statusResponse.assets.image;
|
|
151
|
-
case "failed":
|
|
152
|
-
throw new InvalidResponseDataError({
|
|
153
|
-
data: statusResponse,
|
|
154
|
-
message: `Image generation failed.`
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
await delay(pollIntervalMillis);
|
|
158
|
-
}
|
|
159
|
-
throw new Error(
|
|
160
|
-
`Image generation timed out after ${this.maxPollAttempts} attempts.`
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
createLumaErrorHandler() {
|
|
164
|
-
return createJsonErrorResponseHandler({
|
|
165
|
-
errorSchema: lumaErrorSchema,
|
|
166
|
-
errorToMessage: (error) => {
|
|
167
|
-
var _a;
|
|
168
|
-
return (_a = error.detail[0].msg) != null ? _a : "Unknown error";
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
getEditingOptions(files, mask, referenceType = "image", imageConfigs = []) {
|
|
173
|
-
var _a, _b, _c, _d;
|
|
174
|
-
const options = {};
|
|
175
|
-
if (mask != null) {
|
|
176
|
-
throw new Error(
|
|
177
|
-
"Luma AI does not support mask-based image editing. Use the prompt to describe the changes you want to make, along with `prompt.images` containing the source image URL."
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
if (files == null || files.length === 0) {
|
|
181
|
-
return options;
|
|
182
|
-
}
|
|
183
|
-
for (const file of files) {
|
|
184
|
-
if (file.type !== "url") {
|
|
185
|
-
throw new Error(
|
|
186
|
-
"Luma AI only supports URL-based images. Please provide image URLs using `prompt.images` with publicly accessible URLs. Base64 and Uint8Array data are not supported."
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
const defaultWeights = {
|
|
191
|
-
image: 0.85,
|
|
192
|
-
style: 0.8,
|
|
193
|
-
character: 1,
|
|
194
|
-
// Not used, but defined for completeness
|
|
195
|
-
modify_image: 1
|
|
196
|
-
};
|
|
197
|
-
switch (referenceType) {
|
|
198
|
-
case "image": {
|
|
199
|
-
if (files.length > 4) {
|
|
200
|
-
throw new Error(
|
|
201
|
-
`Luma AI image supports up to 4 reference images. You provided ${files.length} images.`
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
options.image = files.map((file, index) => {
|
|
205
|
-
var _a2, _b2;
|
|
206
|
-
return {
|
|
207
|
-
url: file.url,
|
|
208
|
-
weight: (_b2 = (_a2 = imageConfigs[index]) == null ? void 0 : _a2.weight) != null ? _b2 : defaultWeights.image
|
|
209
|
-
};
|
|
210
|
-
});
|
|
211
|
-
break;
|
|
212
|
-
}
|
|
213
|
-
case "style": {
|
|
214
|
-
options.style = files.map((file, index) => {
|
|
215
|
-
var _a2, _b2;
|
|
216
|
-
return {
|
|
217
|
-
url: file.url,
|
|
218
|
-
weight: (_b2 = (_a2 = imageConfigs[index]) == null ? void 0 : _a2.weight) != null ? _b2 : defaultWeights.style
|
|
219
|
-
};
|
|
220
|
-
});
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
case "character": {
|
|
224
|
-
const identities = {};
|
|
225
|
-
for (let i = 0; i < files.length; i++) {
|
|
226
|
-
const file = files[i];
|
|
227
|
-
const identityId = (_b = (_a = imageConfigs[i]) == null ? void 0 : _a.id) != null ? _b : "identity0";
|
|
228
|
-
if (!identities[identityId]) {
|
|
229
|
-
identities[identityId] = [];
|
|
230
|
-
}
|
|
231
|
-
identities[identityId].push(file.url);
|
|
232
|
-
}
|
|
233
|
-
for (const [identityId, images] of Object.entries(identities)) {
|
|
234
|
-
if (images.length > 4) {
|
|
235
|
-
throw new Error(
|
|
236
|
-
`Luma AI character supports up to 4 images per identity. Identity '${identityId}' has ${images.length} images.`
|
|
237
|
-
);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
options.character = Object.fromEntries(
|
|
241
|
-
Object.entries(identities).map(([id, images]) => [id, { images }])
|
|
242
|
-
);
|
|
243
|
-
break;
|
|
244
|
-
}
|
|
245
|
-
case "modify_image": {
|
|
246
|
-
if (files.length > 1) {
|
|
247
|
-
throw new Error(
|
|
248
|
-
`Luma AI modify_image only supports a single input image. You provided ${files.length} images.`
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
options.modify_image = {
|
|
252
|
-
url: files[0].url,
|
|
253
|
-
weight: (_d = (_c = imageConfigs[0]) == null ? void 0 : _c.weight) != null ? _d : defaultWeights.modify_image
|
|
254
|
-
};
|
|
255
|
-
break;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
return options;
|
|
259
|
-
}
|
|
260
|
-
getLumaGenerationsUrl(generationId) {
|
|
261
|
-
return `${this.config.baseURL}/dream-machine/v1/generations/${generationId != null ? generationId : "image"}`;
|
|
262
|
-
}
|
|
263
|
-
async downloadImage(url, abortSignal) {
|
|
264
|
-
const { value: response } = await getFromApi({
|
|
265
|
-
url,
|
|
266
|
-
// No specific headers should be needed for this request as it's a
|
|
267
|
-
// generated image provided by Luma.
|
|
268
|
-
abortSignal,
|
|
269
|
-
failedResponseHandler: createStatusCodeErrorResponseHandler(),
|
|
270
|
-
successfulResponseHandler: createBinaryResponseHandler(),
|
|
271
|
-
fetch: this.config.fetch
|
|
272
|
-
});
|
|
273
|
-
return response;
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
var lumaGenerationResponseSchema = lazySchema(
|
|
277
|
-
() => zodSchema(
|
|
278
|
-
z.object({
|
|
279
|
-
id: z.string(),
|
|
280
|
-
state: z.enum(["queued", "dreaming", "completed", "failed"]),
|
|
281
|
-
failure_reason: z.string().nullish(),
|
|
282
|
-
assets: z.object({
|
|
283
|
-
image: z.string()
|
|
284
|
-
// URL of the generated image
|
|
285
|
-
}).nullish()
|
|
286
|
-
})
|
|
287
|
-
)
|
|
288
|
-
);
|
|
289
|
-
var lumaErrorSchema = z.object({
|
|
290
|
-
detail: z.array(
|
|
291
|
-
z.object({
|
|
292
|
-
type: z.string(),
|
|
293
|
-
loc: z.array(z.string()),
|
|
294
|
-
msg: z.string(),
|
|
295
|
-
input: z.string(),
|
|
296
|
-
ctx: z.object({
|
|
297
|
-
expected: z.string()
|
|
298
|
-
}).nullish()
|
|
299
|
-
})
|
|
300
|
-
)
|
|
301
|
-
});
|
|
302
|
-
var lumaImageModelOptionsSchema = lazySchema(
|
|
303
|
-
() => zodSchema(
|
|
304
|
-
z.object({
|
|
305
|
-
/**
|
|
306
|
-
* The type of image reference to use when providing input images.
|
|
307
|
-
* - `image`: Guide generation using reference images (up to 4). Default.
|
|
308
|
-
* - `style`: Apply a specific style from reference image(s).
|
|
309
|
-
* - `character`: Create consistent characters from reference images (up to 4).
|
|
310
|
-
* - `modify_image`: Transform a single input image with prompt guidance.
|
|
311
|
-
*/
|
|
312
|
-
referenceType: z.enum(["image", "style", "character", "modify_image"]).nullish(),
|
|
313
|
-
/**
|
|
314
|
-
* Per-image configuration array. Each entry corresponds to an image in `prompt.images`.
|
|
315
|
-
* Allows setting individual weights for each reference image.
|
|
316
|
-
*/
|
|
317
|
-
images: z.array(
|
|
318
|
-
z.object({
|
|
319
|
-
/**
|
|
320
|
-
* The weight of this image's influence on the generation.
|
|
321
|
-
* - For `image`: Higher weight = closer to reference (default: 0.85)
|
|
322
|
-
* - For `style`: Higher weight = stronger style influence (default: 0.8)
|
|
323
|
-
* - For `modify_image`: Higher weight = closer to input, lower = more creative (default: 1.0)
|
|
324
|
-
*/
|
|
325
|
-
weight: z.number().min(0).max(1).nullish(),
|
|
326
|
-
/**
|
|
327
|
-
* The identity name for character references.
|
|
328
|
-
* Used with `character` to specify which identity group the image belongs to.
|
|
329
|
-
* Luma supports multiple identities (e.g., 'identity0', 'identity1') for generating
|
|
330
|
-
* images with multiple consistent characters.
|
|
331
|
-
* Default: 'identity0'
|
|
332
|
-
*/
|
|
333
|
-
id: z.string().nullish()
|
|
334
|
-
})
|
|
335
|
-
).nullish(),
|
|
336
|
-
/**
|
|
337
|
-
* Override the polling interval in milliseconds (default 500).
|
|
338
|
-
*/
|
|
339
|
-
pollIntervalMillis: z.number().nullish(),
|
|
340
|
-
/**
|
|
341
|
-
* Override the maximum number of polling attempts (default 120).
|
|
342
|
-
*/
|
|
343
|
-
maxPollAttempts: z.number().nullish()
|
|
344
|
-
}).passthrough()
|
|
345
|
-
)
|
|
346
|
-
);
|
|
347
|
-
|
|
348
|
-
// src/version.ts
|
|
349
|
-
var VERSION = true ? "3.0.0-beta.3" : "0.0.0-test";
|
|
350
|
-
|
|
351
|
-
// src/luma-provider.ts
|
|
352
|
-
var defaultBaseURL = "https://api.lumalabs.ai";
|
|
353
|
-
function createLuma(options = {}) {
|
|
354
|
-
var _a;
|
|
355
|
-
const baseURL = withoutTrailingSlash((_a = options.baseURL) != null ? _a : defaultBaseURL);
|
|
356
|
-
const getHeaders = () => withUserAgentSuffix(
|
|
357
|
-
{
|
|
358
|
-
Authorization: `Bearer ${loadApiKey({
|
|
359
|
-
apiKey: options.apiKey,
|
|
360
|
-
environmentVariableName: "LUMA_API_KEY",
|
|
361
|
-
description: "Luma"
|
|
362
|
-
})}`,
|
|
363
|
-
...options.headers
|
|
364
|
-
},
|
|
365
|
-
`ai-sdk/luma/${VERSION}`
|
|
366
|
-
);
|
|
367
|
-
const createImageModel = (modelId) => new LumaImageModel(modelId, {
|
|
368
|
-
provider: "luma.image",
|
|
369
|
-
baseURL: baseURL != null ? baseURL : defaultBaseURL,
|
|
370
|
-
headers: getHeaders,
|
|
371
|
-
fetch: options.fetch
|
|
372
|
-
});
|
|
373
|
-
const embeddingModel = (modelId) => {
|
|
374
|
-
throw new NoSuchModelError({
|
|
375
|
-
modelId,
|
|
376
|
-
modelType: "embeddingModel"
|
|
377
|
-
});
|
|
378
|
-
};
|
|
379
|
-
return {
|
|
380
|
-
specificationVersion: "v3",
|
|
381
|
-
image: createImageModel,
|
|
382
|
-
imageModel: createImageModel,
|
|
383
|
-
languageModel: (modelId) => {
|
|
384
|
-
throw new NoSuchModelError({
|
|
385
|
-
modelId,
|
|
386
|
-
modelType: "languageModel"
|
|
387
|
-
});
|
|
388
|
-
},
|
|
389
|
-
embeddingModel,
|
|
390
|
-
textEmbeddingModel: embeddingModel
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
var luma = createLuma();
|
|
394
|
-
export {
|
|
395
|
-
VERSION,
|
|
396
|
-
createLuma,
|
|
397
|
-
luma
|
|
398
|
-
};
|
|
399
|
-
//# sourceMappingURL=index.mjs.map
|