@ai-sdk/luma 0.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 +9 -0
- package/LICENSE +13 -0
- package/README.md +50 -0
- package/dist/index.d.mts +114 -0
- package/dist/index.d.ts +114 -0
- package/dist/index.js +230 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +215 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +63 -0
package/CHANGELOG.md
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2023 Vercel, Inc.
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# AI SDK - Luma Provider
|
|
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.
|
|
4
|
+
|
|
5
|
+
## About Luma Photon Models
|
|
6
|
+
|
|
7
|
+
Luma Photon and Photon Flash are groundbreaking image generation models that deliver:
|
|
8
|
+
|
|
9
|
+
- Ultra-high quality image generation
|
|
10
|
+
- 10x higher cost efficiency compared to similar models
|
|
11
|
+
- Superior prompt understanding and adherence
|
|
12
|
+
- Unique character consistency capabilities from single reference images
|
|
13
|
+
- Multi-image reference support for precise style matching
|
|
14
|
+
|
|
15
|
+
## Setup
|
|
16
|
+
|
|
17
|
+
The Luma provider is available in the `@ai-sdk/luma` module. You can install it with:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm i @ai-sdk/luma
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Provider Instance
|
|
24
|
+
|
|
25
|
+
You can import the default provider instance `luma` from `@ai-sdk/luma`:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { luma } from '@ai-sdk/luma';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Image Generation Example
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { luma } from '@ai-sdk/luma';
|
|
35
|
+
import { experimental_generateImage as generateImage } from 'ai';
|
|
36
|
+
import fs from 'fs';
|
|
37
|
+
|
|
38
|
+
const { image } = await generateImage({
|
|
39
|
+
model: luma.image('photon'),
|
|
40
|
+
prompt: 'A serene mountain landscape at sunset',
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const filename = `image-${Date.now()}.png`;
|
|
44
|
+
fs.writeFileSync(filename, image.uint8Array);
|
|
45
|
+
console.log(`Image saved to ${filename}`);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Documentation
|
|
49
|
+
|
|
50
|
+
For more detailed information about the Luma models and their capabilities, please visit [Luma AI](https://lumalabs.ai/).
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ImageModelV1 } from '@ai-sdk/provider';
|
|
2
|
+
import { FetchFunction } from '@ai-sdk/provider-utils';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
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
|
+
|
|
32
|
+
interface LumaProviderSettings {
|
|
33
|
+
/**
|
|
34
|
+
Luma API key. Default value is taken from the `LUMA_API_KEY` environment
|
|
35
|
+
variable.
|
|
36
|
+
*/
|
|
37
|
+
apiKey?: string;
|
|
38
|
+
/**
|
|
39
|
+
Base URL for the API calls.
|
|
40
|
+
*/
|
|
41
|
+
baseURL?: string;
|
|
42
|
+
/**
|
|
43
|
+
Custom headers to include in the requests.
|
|
44
|
+
*/
|
|
45
|
+
headers?: Record<string, string>;
|
|
46
|
+
/**
|
|
47
|
+
Custom fetch implementation. You can use it as a middleware to intercept requests,
|
|
48
|
+
or to provide a custom fetch implementation for e.g. testing.
|
|
49
|
+
*/
|
|
50
|
+
fetch?: FetchFunction;
|
|
51
|
+
}
|
|
52
|
+
interface LumaProvider {
|
|
53
|
+
/**
|
|
54
|
+
Creates a model for image generation.
|
|
55
|
+
*/
|
|
56
|
+
image(modelId: LumaImageModelId, settings?: LumaImageSettings): ImageModelV1;
|
|
57
|
+
}
|
|
58
|
+
declare function createLuma(options?: LumaProviderSettings): LumaProvider;
|
|
59
|
+
declare const luma: LumaProvider;
|
|
60
|
+
|
|
61
|
+
declare const lumaErrorSchema: z.ZodObject<{
|
|
62
|
+
detail: z.ZodArray<z.ZodObject<{
|
|
63
|
+
type: z.ZodString;
|
|
64
|
+
loc: z.ZodArray<z.ZodString, "many">;
|
|
65
|
+
msg: z.ZodString;
|
|
66
|
+
input: z.ZodString;
|
|
67
|
+
ctx: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
68
|
+
expected: z.ZodString;
|
|
69
|
+
}, "strip", z.ZodTypeAny, {
|
|
70
|
+
expected: string;
|
|
71
|
+
}, {
|
|
72
|
+
expected: string;
|
|
73
|
+
}>>>;
|
|
74
|
+
}, "strip", z.ZodTypeAny, {
|
|
75
|
+
type: string;
|
|
76
|
+
loc: string[];
|
|
77
|
+
msg: string;
|
|
78
|
+
input: string;
|
|
79
|
+
ctx?: {
|
|
80
|
+
expected: string;
|
|
81
|
+
} | null | undefined;
|
|
82
|
+
}, {
|
|
83
|
+
type: string;
|
|
84
|
+
loc: string[];
|
|
85
|
+
msg: string;
|
|
86
|
+
input: string;
|
|
87
|
+
ctx?: {
|
|
88
|
+
expected: string;
|
|
89
|
+
} | null | undefined;
|
|
90
|
+
}>, "many">;
|
|
91
|
+
}, "strip", z.ZodTypeAny, {
|
|
92
|
+
detail: {
|
|
93
|
+
type: string;
|
|
94
|
+
loc: string[];
|
|
95
|
+
msg: string;
|
|
96
|
+
input: string;
|
|
97
|
+
ctx?: {
|
|
98
|
+
expected: string;
|
|
99
|
+
} | null | undefined;
|
|
100
|
+
}[];
|
|
101
|
+
}, {
|
|
102
|
+
detail: {
|
|
103
|
+
type: string;
|
|
104
|
+
loc: string[];
|
|
105
|
+
msg: string;
|
|
106
|
+
input: string;
|
|
107
|
+
ctx?: {
|
|
108
|
+
expected: string;
|
|
109
|
+
} | null | undefined;
|
|
110
|
+
}[];
|
|
111
|
+
}>;
|
|
112
|
+
type LumaErrorData = z.infer<typeof lumaErrorSchema>;
|
|
113
|
+
|
|
114
|
+
export { type LumaErrorData, type LumaProvider, type LumaProviderSettings, createLuma, luma };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { ImageModelV1 } from '@ai-sdk/provider';
|
|
2
|
+
import { FetchFunction } from '@ai-sdk/provider-utils';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
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
|
+
|
|
32
|
+
interface LumaProviderSettings {
|
|
33
|
+
/**
|
|
34
|
+
Luma API key. Default value is taken from the `LUMA_API_KEY` environment
|
|
35
|
+
variable.
|
|
36
|
+
*/
|
|
37
|
+
apiKey?: string;
|
|
38
|
+
/**
|
|
39
|
+
Base URL for the API calls.
|
|
40
|
+
*/
|
|
41
|
+
baseURL?: string;
|
|
42
|
+
/**
|
|
43
|
+
Custom headers to include in the requests.
|
|
44
|
+
*/
|
|
45
|
+
headers?: Record<string, string>;
|
|
46
|
+
/**
|
|
47
|
+
Custom fetch implementation. You can use it as a middleware to intercept requests,
|
|
48
|
+
or to provide a custom fetch implementation for e.g. testing.
|
|
49
|
+
*/
|
|
50
|
+
fetch?: FetchFunction;
|
|
51
|
+
}
|
|
52
|
+
interface LumaProvider {
|
|
53
|
+
/**
|
|
54
|
+
Creates a model for image generation.
|
|
55
|
+
*/
|
|
56
|
+
image(modelId: LumaImageModelId, settings?: LumaImageSettings): ImageModelV1;
|
|
57
|
+
}
|
|
58
|
+
declare function createLuma(options?: LumaProviderSettings): LumaProvider;
|
|
59
|
+
declare const luma: LumaProvider;
|
|
60
|
+
|
|
61
|
+
declare const lumaErrorSchema: z.ZodObject<{
|
|
62
|
+
detail: z.ZodArray<z.ZodObject<{
|
|
63
|
+
type: z.ZodString;
|
|
64
|
+
loc: z.ZodArray<z.ZodString, "many">;
|
|
65
|
+
msg: z.ZodString;
|
|
66
|
+
input: z.ZodString;
|
|
67
|
+
ctx: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
68
|
+
expected: z.ZodString;
|
|
69
|
+
}, "strip", z.ZodTypeAny, {
|
|
70
|
+
expected: string;
|
|
71
|
+
}, {
|
|
72
|
+
expected: string;
|
|
73
|
+
}>>>;
|
|
74
|
+
}, "strip", z.ZodTypeAny, {
|
|
75
|
+
type: string;
|
|
76
|
+
loc: string[];
|
|
77
|
+
msg: string;
|
|
78
|
+
input: string;
|
|
79
|
+
ctx?: {
|
|
80
|
+
expected: string;
|
|
81
|
+
} | null | undefined;
|
|
82
|
+
}, {
|
|
83
|
+
type: string;
|
|
84
|
+
loc: string[];
|
|
85
|
+
msg: string;
|
|
86
|
+
input: string;
|
|
87
|
+
ctx?: {
|
|
88
|
+
expected: string;
|
|
89
|
+
} | null | undefined;
|
|
90
|
+
}>, "many">;
|
|
91
|
+
}, "strip", z.ZodTypeAny, {
|
|
92
|
+
detail: {
|
|
93
|
+
type: string;
|
|
94
|
+
loc: string[];
|
|
95
|
+
msg: string;
|
|
96
|
+
input: string;
|
|
97
|
+
ctx?: {
|
|
98
|
+
expected: string;
|
|
99
|
+
} | null | undefined;
|
|
100
|
+
}[];
|
|
101
|
+
}, {
|
|
102
|
+
detail: {
|
|
103
|
+
type: string;
|
|
104
|
+
loc: string[];
|
|
105
|
+
msg: string;
|
|
106
|
+
input: string;
|
|
107
|
+
ctx?: {
|
|
108
|
+
expected: string;
|
|
109
|
+
} | null | undefined;
|
|
110
|
+
}[];
|
|
111
|
+
}>;
|
|
112
|
+
type LumaErrorData = z.infer<typeof lumaErrorSchema>;
|
|
113
|
+
|
|
114
|
+
export { type LumaErrorData, type LumaProvider, type LumaProviderSettings, createLuma, luma };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
createLuma: () => createLuma,
|
|
24
|
+
luma: () => luma
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(src_exports);
|
|
27
|
+
|
|
28
|
+
// src/luma-provider.ts
|
|
29
|
+
var import_provider_utils2 = require("@ai-sdk/provider-utils");
|
|
30
|
+
|
|
31
|
+
// src/luma-image-model.ts
|
|
32
|
+
var import_provider = require("@ai-sdk/provider");
|
|
33
|
+
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
34
|
+
var import_zod = require("zod");
|
|
35
|
+
var DEFAULT_POLL_INTERVAL_MILLIS = 500;
|
|
36
|
+
var DEFAULT_MAX_POLL_ATTEMPTS = 6e4 / DEFAULT_POLL_INTERVAL_MILLIS;
|
|
37
|
+
async function delay(delayInMs) {
|
|
38
|
+
return delayInMs == null ? Promise.resolve() : new Promise((resolve) => setTimeout(resolve, delayInMs));
|
|
39
|
+
}
|
|
40
|
+
var LumaImageModel = class {
|
|
41
|
+
constructor(modelId, settings, config) {
|
|
42
|
+
this.modelId = modelId;
|
|
43
|
+
this.settings = settings;
|
|
44
|
+
this.config = config;
|
|
45
|
+
this.specificationVersion = "v1";
|
|
46
|
+
var _a, _b;
|
|
47
|
+
this.pollIntervalMillis = (_a = settings.pollIntervalMillis) != null ? _a : DEFAULT_POLL_INTERVAL_MILLIS;
|
|
48
|
+
this.maxPollAttempts = (_b = settings.maxPollAttempts) != null ? _b : DEFAULT_MAX_POLL_ATTEMPTS;
|
|
49
|
+
}
|
|
50
|
+
get provider() {
|
|
51
|
+
return this.config.provider;
|
|
52
|
+
}
|
|
53
|
+
get maxImagesPerCall() {
|
|
54
|
+
var _a;
|
|
55
|
+
return (_a = this.settings.maxImagesPerCall) != null ? _a : 1;
|
|
56
|
+
}
|
|
57
|
+
async doGenerate({
|
|
58
|
+
prompt,
|
|
59
|
+
n,
|
|
60
|
+
size,
|
|
61
|
+
aspectRatio,
|
|
62
|
+
seed,
|
|
63
|
+
providerOptions,
|
|
64
|
+
headers,
|
|
65
|
+
abortSignal
|
|
66
|
+
}) {
|
|
67
|
+
var _a, _b, _c, _d;
|
|
68
|
+
const warnings = [];
|
|
69
|
+
if (seed != null) {
|
|
70
|
+
warnings.push({
|
|
71
|
+
type: "unsupported-setting",
|
|
72
|
+
setting: "seed",
|
|
73
|
+
details: "This model does not support the `seed` option."
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (size != null) {
|
|
77
|
+
warnings.push({
|
|
78
|
+
type: "unsupported-setting",
|
|
79
|
+
setting: "size",
|
|
80
|
+
details: "This model does not support the `size` option. Use `aspectRatio` instead."
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
84
|
+
const fullHeaders = (0, import_provider_utils.combineHeaders)(this.config.headers(), headers);
|
|
85
|
+
const { value: generationResponse, responseHeaders } = await (0, import_provider_utils.postJsonToApi)({
|
|
86
|
+
url: this.getLumaGenerationsUrl(),
|
|
87
|
+
headers: fullHeaders,
|
|
88
|
+
body: {
|
|
89
|
+
prompt,
|
|
90
|
+
...aspectRatio ? { aspect_ratio: aspectRatio } : {},
|
|
91
|
+
model: this.modelId,
|
|
92
|
+
...(_d = providerOptions.luma) != null ? _d : {}
|
|
93
|
+
},
|
|
94
|
+
abortSignal,
|
|
95
|
+
fetch: this.config.fetch,
|
|
96
|
+
failedResponseHandler: this.createLumaErrorHandler(),
|
|
97
|
+
successfulResponseHandler: (0, import_provider_utils.createJsonResponseHandler)(
|
|
98
|
+
lumaGenerationResponseSchema
|
|
99
|
+
)
|
|
100
|
+
});
|
|
101
|
+
const imageUrl = await this.pollForImageUrl(
|
|
102
|
+
generationResponse.id,
|
|
103
|
+
fullHeaders,
|
|
104
|
+
abortSignal
|
|
105
|
+
);
|
|
106
|
+
const downloadedImage = await this.downloadImage(imageUrl, abortSignal);
|
|
107
|
+
return {
|
|
108
|
+
images: [downloadedImage],
|
|
109
|
+
warnings,
|
|
110
|
+
response: {
|
|
111
|
+
modelId: this.modelId,
|
|
112
|
+
timestamp: currentDate,
|
|
113
|
+
headers: responseHeaders
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async pollForImageUrl(generationId, headers, abortSignal) {
|
|
118
|
+
var _a;
|
|
119
|
+
let attemptCount = 0;
|
|
120
|
+
const url = this.getLumaGenerationsUrl(generationId);
|
|
121
|
+
for (let i = 0; i < this.maxPollAttempts; i++) {
|
|
122
|
+
const { value: statusResponse } = await (0, import_provider_utils.getFromApi)({
|
|
123
|
+
url,
|
|
124
|
+
headers,
|
|
125
|
+
abortSignal,
|
|
126
|
+
fetch: this.config.fetch,
|
|
127
|
+
failedResponseHandler: this.createLumaErrorHandler(),
|
|
128
|
+
successfulResponseHandler: (0, import_provider_utils.createJsonResponseHandler)(
|
|
129
|
+
lumaGenerationResponseSchema
|
|
130
|
+
)
|
|
131
|
+
});
|
|
132
|
+
switch (statusResponse.state) {
|
|
133
|
+
case "completed":
|
|
134
|
+
if (!((_a = statusResponse.assets) == null ? void 0 : _a.image)) {
|
|
135
|
+
throw new import_provider.InvalidResponseDataError({
|
|
136
|
+
data: statusResponse,
|
|
137
|
+
message: `Image generation completed but no image was found.`
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return statusResponse.assets.image;
|
|
141
|
+
case "failed":
|
|
142
|
+
throw new import_provider.InvalidResponseDataError({
|
|
143
|
+
data: statusResponse,
|
|
144
|
+
message: `Image generation failed.`
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
await delay(this.pollIntervalMillis);
|
|
148
|
+
}
|
|
149
|
+
throw new Error(
|
|
150
|
+
`Image generation timed out after ${this.maxPollAttempts} attempts.`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
createLumaErrorHandler() {
|
|
154
|
+
return (0, import_provider_utils.createJsonErrorResponseHandler)({
|
|
155
|
+
errorSchema: lumaErrorSchema,
|
|
156
|
+
errorToMessage: (error) => {
|
|
157
|
+
var _a;
|
|
158
|
+
return (_a = error.detail[0].msg) != null ? _a : "Unknown error";
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
getLumaGenerationsUrl(generationId) {
|
|
163
|
+
return `${this.config.baseURL}/dream-machine/v1/generations/${generationId != null ? generationId : "image"}`;
|
|
164
|
+
}
|
|
165
|
+
async downloadImage(url, abortSignal) {
|
|
166
|
+
const { value: response } = await (0, import_provider_utils.getFromApi)({
|
|
167
|
+
url,
|
|
168
|
+
// No specific headers should be needed for this request as it's a
|
|
169
|
+
// generated image provided by Luma.
|
|
170
|
+
abortSignal,
|
|
171
|
+
failedResponseHandler: (0, import_provider_utils.createStatusCodeErrorResponseHandler)(),
|
|
172
|
+
successfulResponseHandler: (0, import_provider_utils.createBinaryResponseHandler)(),
|
|
173
|
+
fetch: this.config.fetch
|
|
174
|
+
});
|
|
175
|
+
return response;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
var lumaGenerationResponseSchema = import_zod.z.object({
|
|
179
|
+
id: import_zod.z.string(),
|
|
180
|
+
state: import_zod.z.enum(["queued", "dreaming", "completed", "failed"]),
|
|
181
|
+
failure_reason: import_zod.z.string().nullish(),
|
|
182
|
+
assets: import_zod.z.object({
|
|
183
|
+
image: import_zod.z.string()
|
|
184
|
+
// URL of the generated image
|
|
185
|
+
}).nullish()
|
|
186
|
+
});
|
|
187
|
+
var lumaErrorSchema = import_zod.z.object({
|
|
188
|
+
detail: import_zod.z.array(
|
|
189
|
+
import_zod.z.object({
|
|
190
|
+
type: import_zod.z.string(),
|
|
191
|
+
loc: import_zod.z.array(import_zod.z.string()),
|
|
192
|
+
msg: import_zod.z.string(),
|
|
193
|
+
input: import_zod.z.string(),
|
|
194
|
+
ctx: import_zod.z.object({
|
|
195
|
+
expected: import_zod.z.string()
|
|
196
|
+
}).nullish()
|
|
197
|
+
})
|
|
198
|
+
)
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// src/luma-provider.ts
|
|
202
|
+
var defaultBaseURL = "https://api.lumalabs.ai";
|
|
203
|
+
function createLuma(options = {}) {
|
|
204
|
+
var _a;
|
|
205
|
+
const baseURL = (0, import_provider_utils2.withoutTrailingSlash)((_a = options.baseURL) != null ? _a : defaultBaseURL);
|
|
206
|
+
const getHeaders = () => ({
|
|
207
|
+
Authorization: `Bearer ${(0, import_provider_utils2.loadApiKey)({
|
|
208
|
+
apiKey: options.apiKey,
|
|
209
|
+
environmentVariableName: "LUMA_API_KEY",
|
|
210
|
+
description: "Luma"
|
|
211
|
+
})}`,
|
|
212
|
+
...options.headers
|
|
213
|
+
});
|
|
214
|
+
const createImageModel = (modelId, settings = {}) => new LumaImageModel(modelId, settings, {
|
|
215
|
+
provider: "luma.image",
|
|
216
|
+
baseURL: baseURL != null ? baseURL : defaultBaseURL,
|
|
217
|
+
headers: getHeaders,
|
|
218
|
+
fetch: options.fetch
|
|
219
|
+
});
|
|
220
|
+
const provider = (modelId, settings) => createImageModel(modelId, settings);
|
|
221
|
+
provider.image = createImageModel;
|
|
222
|
+
return provider;
|
|
223
|
+
}
|
|
224
|
+
var luma = createLuma();
|
|
225
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
226
|
+
0 && (module.exports = {
|
|
227
|
+
createLuma,
|
|
228
|
+
luma
|
|
229
|
+
});
|
|
230
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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 } 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 {\n /**\nCreates a model for image generation.\n */\n image(modelId: LumaImageModelId, settings?: LumaImageSettings): 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 const provider = (modelId: LumaImageModelId, settings?: LumaImageSettings) =>\n createImageModel(modelId, settings);\n\n provider.image = createImageModel;\n\n return provider as LumaProvider;\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 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\nasync function delay(delayInMs?: number | null): Promise<void> {\n return delayInMs == null\n ? Promise.resolve()\n : new Promise(resolve => setTimeout(resolve, delayInMs));\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_utils"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// src/luma-provider.ts
|
|
2
|
+
import {
|
|
3
|
+
loadApiKey,
|
|
4
|
+
withoutTrailingSlash
|
|
5
|
+
} from "@ai-sdk/provider-utils";
|
|
6
|
+
|
|
7
|
+
// src/luma-image-model.ts
|
|
8
|
+
import {
|
|
9
|
+
InvalidResponseDataError
|
|
10
|
+
} from "@ai-sdk/provider";
|
|
11
|
+
import {
|
|
12
|
+
combineHeaders,
|
|
13
|
+
createBinaryResponseHandler,
|
|
14
|
+
createJsonResponseHandler,
|
|
15
|
+
createJsonErrorResponseHandler,
|
|
16
|
+
createStatusCodeErrorResponseHandler,
|
|
17
|
+
getFromApi,
|
|
18
|
+
postJsonToApi
|
|
19
|
+
} from "@ai-sdk/provider-utils";
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
var DEFAULT_POLL_INTERVAL_MILLIS = 500;
|
|
22
|
+
var DEFAULT_MAX_POLL_ATTEMPTS = 6e4 / DEFAULT_POLL_INTERVAL_MILLIS;
|
|
23
|
+
async function delay(delayInMs) {
|
|
24
|
+
return delayInMs == null ? Promise.resolve() : new Promise((resolve) => setTimeout(resolve, delayInMs));
|
|
25
|
+
}
|
|
26
|
+
var LumaImageModel = class {
|
|
27
|
+
constructor(modelId, settings, config) {
|
|
28
|
+
this.modelId = modelId;
|
|
29
|
+
this.settings = settings;
|
|
30
|
+
this.config = config;
|
|
31
|
+
this.specificationVersion = "v1";
|
|
32
|
+
var _a, _b;
|
|
33
|
+
this.pollIntervalMillis = (_a = settings.pollIntervalMillis) != null ? _a : DEFAULT_POLL_INTERVAL_MILLIS;
|
|
34
|
+
this.maxPollAttempts = (_b = settings.maxPollAttempts) != null ? _b : DEFAULT_MAX_POLL_ATTEMPTS;
|
|
35
|
+
}
|
|
36
|
+
get provider() {
|
|
37
|
+
return this.config.provider;
|
|
38
|
+
}
|
|
39
|
+
get maxImagesPerCall() {
|
|
40
|
+
var _a;
|
|
41
|
+
return (_a = this.settings.maxImagesPerCall) != null ? _a : 1;
|
|
42
|
+
}
|
|
43
|
+
async doGenerate({
|
|
44
|
+
prompt,
|
|
45
|
+
n,
|
|
46
|
+
size,
|
|
47
|
+
aspectRatio,
|
|
48
|
+
seed,
|
|
49
|
+
providerOptions,
|
|
50
|
+
headers,
|
|
51
|
+
abortSignal
|
|
52
|
+
}) {
|
|
53
|
+
var _a, _b, _c, _d;
|
|
54
|
+
const warnings = [];
|
|
55
|
+
if (seed != null) {
|
|
56
|
+
warnings.push({
|
|
57
|
+
type: "unsupported-setting",
|
|
58
|
+
setting: "seed",
|
|
59
|
+
details: "This model does not support the `seed` option."
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (size != null) {
|
|
63
|
+
warnings.push({
|
|
64
|
+
type: "unsupported-setting",
|
|
65
|
+
setting: "size",
|
|
66
|
+
details: "This model does not support the `size` option. Use `aspectRatio` instead."
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
70
|
+
const fullHeaders = combineHeaders(this.config.headers(), headers);
|
|
71
|
+
const { value: generationResponse, responseHeaders } = await postJsonToApi({
|
|
72
|
+
url: this.getLumaGenerationsUrl(),
|
|
73
|
+
headers: fullHeaders,
|
|
74
|
+
body: {
|
|
75
|
+
prompt,
|
|
76
|
+
...aspectRatio ? { aspect_ratio: aspectRatio } : {},
|
|
77
|
+
model: this.modelId,
|
|
78
|
+
...(_d = providerOptions.luma) != null ? _d : {}
|
|
79
|
+
},
|
|
80
|
+
abortSignal,
|
|
81
|
+
fetch: this.config.fetch,
|
|
82
|
+
failedResponseHandler: this.createLumaErrorHandler(),
|
|
83
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
84
|
+
lumaGenerationResponseSchema
|
|
85
|
+
)
|
|
86
|
+
});
|
|
87
|
+
const imageUrl = await this.pollForImageUrl(
|
|
88
|
+
generationResponse.id,
|
|
89
|
+
fullHeaders,
|
|
90
|
+
abortSignal
|
|
91
|
+
);
|
|
92
|
+
const downloadedImage = await this.downloadImage(imageUrl, abortSignal);
|
|
93
|
+
return {
|
|
94
|
+
images: [downloadedImage],
|
|
95
|
+
warnings,
|
|
96
|
+
response: {
|
|
97
|
+
modelId: this.modelId,
|
|
98
|
+
timestamp: currentDate,
|
|
99
|
+
headers: responseHeaders
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
async pollForImageUrl(generationId, headers, abortSignal) {
|
|
104
|
+
var _a;
|
|
105
|
+
let attemptCount = 0;
|
|
106
|
+
const url = this.getLumaGenerationsUrl(generationId);
|
|
107
|
+
for (let i = 0; i < this.maxPollAttempts; i++) {
|
|
108
|
+
const { value: statusResponse } = await getFromApi({
|
|
109
|
+
url,
|
|
110
|
+
headers,
|
|
111
|
+
abortSignal,
|
|
112
|
+
fetch: this.config.fetch,
|
|
113
|
+
failedResponseHandler: this.createLumaErrorHandler(),
|
|
114
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
115
|
+
lumaGenerationResponseSchema
|
|
116
|
+
)
|
|
117
|
+
});
|
|
118
|
+
switch (statusResponse.state) {
|
|
119
|
+
case "completed":
|
|
120
|
+
if (!((_a = statusResponse.assets) == null ? void 0 : _a.image)) {
|
|
121
|
+
throw new InvalidResponseDataError({
|
|
122
|
+
data: statusResponse,
|
|
123
|
+
message: `Image generation completed but no image was found.`
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return statusResponse.assets.image;
|
|
127
|
+
case "failed":
|
|
128
|
+
throw new InvalidResponseDataError({
|
|
129
|
+
data: statusResponse,
|
|
130
|
+
message: `Image generation failed.`
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
await delay(this.pollIntervalMillis);
|
|
134
|
+
}
|
|
135
|
+
throw new Error(
|
|
136
|
+
`Image generation timed out after ${this.maxPollAttempts} attempts.`
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
createLumaErrorHandler() {
|
|
140
|
+
return createJsonErrorResponseHandler({
|
|
141
|
+
errorSchema: lumaErrorSchema,
|
|
142
|
+
errorToMessage: (error) => {
|
|
143
|
+
var _a;
|
|
144
|
+
return (_a = error.detail[0].msg) != null ? _a : "Unknown error";
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
getLumaGenerationsUrl(generationId) {
|
|
149
|
+
return `${this.config.baseURL}/dream-machine/v1/generations/${generationId != null ? generationId : "image"}`;
|
|
150
|
+
}
|
|
151
|
+
async downloadImage(url, abortSignal) {
|
|
152
|
+
const { value: response } = await getFromApi({
|
|
153
|
+
url,
|
|
154
|
+
// No specific headers should be needed for this request as it's a
|
|
155
|
+
// generated image provided by Luma.
|
|
156
|
+
abortSignal,
|
|
157
|
+
failedResponseHandler: createStatusCodeErrorResponseHandler(),
|
|
158
|
+
successfulResponseHandler: createBinaryResponseHandler(),
|
|
159
|
+
fetch: this.config.fetch
|
|
160
|
+
});
|
|
161
|
+
return response;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
var lumaGenerationResponseSchema = z.object({
|
|
165
|
+
id: z.string(),
|
|
166
|
+
state: z.enum(["queued", "dreaming", "completed", "failed"]),
|
|
167
|
+
failure_reason: z.string().nullish(),
|
|
168
|
+
assets: z.object({
|
|
169
|
+
image: z.string()
|
|
170
|
+
// URL of the generated image
|
|
171
|
+
}).nullish()
|
|
172
|
+
});
|
|
173
|
+
var lumaErrorSchema = z.object({
|
|
174
|
+
detail: z.array(
|
|
175
|
+
z.object({
|
|
176
|
+
type: z.string(),
|
|
177
|
+
loc: z.array(z.string()),
|
|
178
|
+
msg: z.string(),
|
|
179
|
+
input: z.string(),
|
|
180
|
+
ctx: z.object({
|
|
181
|
+
expected: z.string()
|
|
182
|
+
}).nullish()
|
|
183
|
+
})
|
|
184
|
+
)
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// src/luma-provider.ts
|
|
188
|
+
var defaultBaseURL = "https://api.lumalabs.ai";
|
|
189
|
+
function createLuma(options = {}) {
|
|
190
|
+
var _a;
|
|
191
|
+
const baseURL = withoutTrailingSlash((_a = options.baseURL) != null ? _a : defaultBaseURL);
|
|
192
|
+
const getHeaders = () => ({
|
|
193
|
+
Authorization: `Bearer ${loadApiKey({
|
|
194
|
+
apiKey: options.apiKey,
|
|
195
|
+
environmentVariableName: "LUMA_API_KEY",
|
|
196
|
+
description: "Luma"
|
|
197
|
+
})}`,
|
|
198
|
+
...options.headers
|
|
199
|
+
});
|
|
200
|
+
const createImageModel = (modelId, settings = {}) => new LumaImageModel(modelId, settings, {
|
|
201
|
+
provider: "luma.image",
|
|
202
|
+
baseURL: baseURL != null ? baseURL : defaultBaseURL,
|
|
203
|
+
headers: getHeaders,
|
|
204
|
+
fetch: options.fetch
|
|
205
|
+
});
|
|
206
|
+
const provider = (modelId, settings) => createImageModel(modelId, settings);
|
|
207
|
+
provider.image = createImageModel;
|
|
208
|
+
return provider;
|
|
209
|
+
}
|
|
210
|
+
var luma = createLuma();
|
|
211
|
+
export {
|
|
212
|
+
createLuma,
|
|
213
|
+
luma
|
|
214
|
+
};
|
|
215
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/luma-provider.ts","../src/luma-image-model.ts"],"sourcesContent":["import { ImageModelV1 } 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 {\n /**\nCreates a model for image generation.\n */\n image(modelId: LumaImageModelId, settings?: LumaImageSettings): 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 const provider = (modelId: LumaImageModelId, settings?: LumaImageSettings) =>\n createImageModel(modelId, settings);\n\n provider.image = createImageModel;\n\n return provider as LumaProvider;\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 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\nasync function delay(delayInMs?: number | null): Promise<void> {\n return delayInMs == null\n ? Promise.resolve()\n : new Promise(resolve => setTimeout(resolve, delayInMs));\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":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ai-sdk/luma",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist/**/*",
|
|
11
|
+
"CHANGELOG.md"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
"./package.json": "./package.json",
|
|
15
|
+
".": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"import": "./dist/index.mjs",
|
|
18
|
+
"require": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@ai-sdk/provider": "1.0.6",
|
|
23
|
+
"@ai-sdk/provider-utils": "2.1.3"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^18",
|
|
27
|
+
"tsup": "^8",
|
|
28
|
+
"typescript": "5.6.3",
|
|
29
|
+
"zod": "3.23.8",
|
|
30
|
+
"@vercel/ai-tsconfig": "0.0.0"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"zod": "^3.0.0"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://sdk.vercel.ai/docs",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "git+https://github.com/vercel/ai.git"
|
|
45
|
+
},
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/vercel/ai/issues"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"ai"
|
|
51
|
+
],
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsup",
|
|
54
|
+
"build:watch": "tsup --watch",
|
|
55
|
+
"clean": "rm -rf dist",
|
|
56
|
+
"lint": "eslint \"./**/*.ts*\"",
|
|
57
|
+
"type-check": "tsc --noEmit",
|
|
58
|
+
"prettier-check": "prettier --check \"./**/*.ts*\"",
|
|
59
|
+
"test": "pnpm test:node && pnpm test:edge",
|
|
60
|
+
"test:edge": "vitest --config vitest.edge.config.js --run",
|
|
61
|
+
"test:node": "vitest --config vitest.node.config.js --run"
|
|
62
|
+
}
|
|
63
|
+
}
|