@ai-sdk/prodia 2.0.52 → 2.0.53
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/dist/index.d.ts +75 -68
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +776 -1021
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -1,1047 +1,802 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
NoSuchModelError
|
|
4
|
-
} from "@ai-sdk/provider";
|
|
5
|
-
import {
|
|
6
|
-
loadApiKey,
|
|
7
|
-
withoutTrailingSlash,
|
|
8
|
-
withUserAgentSuffix
|
|
9
|
-
} from "@ai-sdk/provider-utils";
|
|
10
|
-
|
|
11
|
-
// src/prodia-image-model.ts
|
|
12
|
-
import {
|
|
13
|
-
combineHeaders,
|
|
14
|
-
parseJSON,
|
|
15
|
-
parseProviderOptions,
|
|
16
|
-
postToApi,
|
|
17
|
-
resolve,
|
|
18
|
-
serializeModelOptions,
|
|
19
|
-
WORKFLOW_SERIALIZE,
|
|
20
|
-
WORKFLOW_DESERIALIZE,
|
|
21
|
-
zodSchema as zodSchema2
|
|
22
|
-
} from "@ai-sdk/provider-utils";
|
|
23
|
-
|
|
24
|
-
// src/prodia-api.ts
|
|
25
|
-
import {
|
|
26
|
-
createJsonErrorResponseHandler
|
|
27
|
-
} from "@ai-sdk/provider-utils";
|
|
1
|
+
import { NoSuchModelError, UnsupportedFunctionalityError } from "@ai-sdk/provider";
|
|
2
|
+
import { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE, combineHeaders, convertBase64ToUint8Array, createJsonErrorResponseHandler, detectMediaType, downloadBlob, generateId, getTopLevelMediaType, isCustomReasoning, isFullMediaType, lazySchema, loadApiKey, parseJSON, parseProviderOptions, postFormDataToApi, postToApi, resolve, serializeModelOptions, withUserAgentSuffix, withoutTrailingSlash, zodSchema } from "@ai-sdk/provider-utils";
|
|
28
3
|
import { z } from "zod/v4";
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
product: z.string(),
|
|
46
|
-
dollars: z.number()
|
|
47
|
-
}).nullish()
|
|
4
|
+
//#region src/prodia-api.ts
|
|
5
|
+
const prodiaJobResultSchema = z.object({
|
|
6
|
+
id: z.string(),
|
|
7
|
+
created_at: z.string().optional(),
|
|
8
|
+
updated_at: z.string().optional(),
|
|
9
|
+
expires_at: z.string().optional(),
|
|
10
|
+
state: z.object({ current: z.string() }).optional(),
|
|
11
|
+
config: z.looseObject({ seed: z.number().optional() }).optional(),
|
|
12
|
+
metrics: z.object({
|
|
13
|
+
elapsed: z.number().optional(),
|
|
14
|
+
ips: z.number().optional()
|
|
15
|
+
}).optional(),
|
|
16
|
+
price: z.object({
|
|
17
|
+
product: z.string(),
|
|
18
|
+
dollars: z.number()
|
|
19
|
+
}).nullish()
|
|
48
20
|
});
|
|
49
21
|
function buildProdiaProviderMetadata(jobResult) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
iterationsPerSecond: jobResult.metrics.ips
|
|
60
|
-
},
|
|
61
|
-
...jobResult.created_at != null && {
|
|
62
|
-
createdAt: jobResult.created_at
|
|
63
|
-
},
|
|
64
|
-
...jobResult.updated_at != null && {
|
|
65
|
-
updatedAt: jobResult.updated_at
|
|
66
|
-
},
|
|
67
|
-
...jobResult.price?.dollars != null && {
|
|
68
|
-
dollars: jobResult.price.dollars
|
|
69
|
-
}
|
|
70
|
-
};
|
|
22
|
+
return {
|
|
23
|
+
jobId: jobResult.id,
|
|
24
|
+
...jobResult.config?.seed != null && { seed: jobResult.config.seed },
|
|
25
|
+
...jobResult.metrics?.elapsed != null && { elapsed: jobResult.metrics.elapsed },
|
|
26
|
+
...jobResult.metrics?.ips != null && { iterationsPerSecond: jobResult.metrics.ips },
|
|
27
|
+
...jobResult.created_at != null && { createdAt: jobResult.created_at },
|
|
28
|
+
...jobResult.updated_at != null && { updatedAt: jobResult.updated_at },
|
|
29
|
+
...jobResult.price?.dollars != null && { dollars: jobResult.price.dollars }
|
|
30
|
+
};
|
|
71
31
|
}
|
|
72
32
|
function parseMultipart(data, boundary) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const headerStr = new TextDecoder().decode(headerBytes);
|
|
130
|
-
const headers = {};
|
|
131
|
-
for (const line of headerStr.split(/\r?\n/)) {
|
|
132
|
-
const colonIdx = line.indexOf(":");
|
|
133
|
-
if (colonIdx > 0) {
|
|
134
|
-
const key = line.slice(0, colonIdx).trim().toLowerCase();
|
|
135
|
-
const value = line.slice(colonIdx + 1).trim();
|
|
136
|
-
headers[key] = value;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
let bodyStart = headerEnd + 2;
|
|
140
|
-
if (partData[headerEnd] === 13) {
|
|
141
|
-
bodyStart = headerEnd + 4;
|
|
142
|
-
}
|
|
143
|
-
const body = partData.slice(bodyStart);
|
|
144
|
-
parts.push({ headers, body });
|
|
145
|
-
}
|
|
146
|
-
return parts;
|
|
33
|
+
const parts = [];
|
|
34
|
+
const boundaryBytes = new TextEncoder().encode(`--${boundary}`);
|
|
35
|
+
const endBoundaryBytes = new TextEncoder().encode(`--${boundary}--`);
|
|
36
|
+
const positions = [];
|
|
37
|
+
for (let i = 0; i <= data.length - boundaryBytes.length; i++) {
|
|
38
|
+
let match = true;
|
|
39
|
+
for (let j = 0; j < boundaryBytes.length; j++) if (data[i + j] !== boundaryBytes[j]) {
|
|
40
|
+
match = false;
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
if (match) positions.push(i);
|
|
44
|
+
}
|
|
45
|
+
for (let i = 0; i < positions.length - 1; i++) {
|
|
46
|
+
const start = positions[i] + boundaryBytes.length;
|
|
47
|
+
const end = positions[i + 1];
|
|
48
|
+
let isEndBoundary = true;
|
|
49
|
+
for (let j = 0; j < endBoundaryBytes.length && isEndBoundary; j++) if (data[positions[i] + j] !== endBoundaryBytes[j]) isEndBoundary = false;
|
|
50
|
+
if (isEndBoundary && positions[i] + endBoundaryBytes.length <= data.length) continue;
|
|
51
|
+
let partStart = start;
|
|
52
|
+
if (data[partStart] === 13 && data[partStart + 1] === 10) partStart += 2;
|
|
53
|
+
else if (data[partStart] === 10) partStart += 1;
|
|
54
|
+
let partEnd = end;
|
|
55
|
+
if (data[partEnd - 2] === 13 && data[partEnd - 1] === 10) partEnd -= 2;
|
|
56
|
+
else if (data[partEnd - 1] === 10) partEnd -= 1;
|
|
57
|
+
const partData = data.slice(partStart, partEnd);
|
|
58
|
+
let headerEnd = -1;
|
|
59
|
+
for (let j = 0; j < partData.length - 3; j++) {
|
|
60
|
+
if (partData[j] === 13 && partData[j + 1] === 10 && partData[j + 2] === 13 && partData[j + 3] === 10) {
|
|
61
|
+
headerEnd = j;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
if (partData[j] === 10 && partData[j + 1] === 10) {
|
|
65
|
+
headerEnd = j;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (headerEnd === -1) continue;
|
|
70
|
+
const headerBytes = partData.slice(0, headerEnd);
|
|
71
|
+
const headerStr = new TextDecoder().decode(headerBytes);
|
|
72
|
+
const headers = {};
|
|
73
|
+
for (const line of headerStr.split(/\r?\n/)) {
|
|
74
|
+
const colonIdx = line.indexOf(":");
|
|
75
|
+
if (colonIdx > 0) {
|
|
76
|
+
const key = line.slice(0, colonIdx).trim().toLowerCase();
|
|
77
|
+
headers[key] = line.slice(colonIdx + 1).trim();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
let bodyStart = headerEnd + 2;
|
|
81
|
+
if (partData[headerEnd] === 13) bodyStart = headerEnd + 4;
|
|
82
|
+
const body = partData.slice(bodyStart);
|
|
83
|
+
parts.push({
|
|
84
|
+
headers,
|
|
85
|
+
body
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return parts;
|
|
147
89
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
90
|
+
const prodiaErrorSchema = z.object({
|
|
91
|
+
message: z.string().optional(),
|
|
92
|
+
detail: z.unknown().optional(),
|
|
93
|
+
error: z.string().optional()
|
|
152
94
|
});
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
return errorField ?? message ?? "Unknown Prodia error";
|
|
167
|
-
}
|
|
95
|
+
const prodiaFailedResponseHandler = createJsonErrorResponseHandler({
|
|
96
|
+
errorSchema: prodiaErrorSchema,
|
|
97
|
+
errorToMessage: (error) => {
|
|
98
|
+
const parsed = prodiaErrorSchema.safeParse(error);
|
|
99
|
+
if (!parsed.success) return "Unknown Prodia error";
|
|
100
|
+
const { message, detail, error: errorField } = parsed.data;
|
|
101
|
+
if (typeof detail === "string") return detail;
|
|
102
|
+
if (detail != null) try {
|
|
103
|
+
return JSON.stringify(detail);
|
|
104
|
+
} catch {}
|
|
105
|
+
return errorField ?? message ?? "Unknown Prodia error";
|
|
106
|
+
}
|
|
168
107
|
});
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
"origami",
|
|
190
|
-
"photographic",
|
|
191
|
-
"pixel-art",
|
|
192
|
-
"texture",
|
|
193
|
-
"craft-clay"
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/prodia-image-model-options.ts
|
|
110
|
+
const stylePresets = [
|
|
111
|
+
"3d-model",
|
|
112
|
+
"analog-film",
|
|
113
|
+
"anime",
|
|
114
|
+
"cinematic",
|
|
115
|
+
"comic-book",
|
|
116
|
+
"digital-art",
|
|
117
|
+
"enhance",
|
|
118
|
+
"fantasy-art",
|
|
119
|
+
"isometric",
|
|
120
|
+
"line-art",
|
|
121
|
+
"low-poly",
|
|
122
|
+
"neon-punk",
|
|
123
|
+
"origami",
|
|
124
|
+
"photographic",
|
|
125
|
+
"pixel-art",
|
|
126
|
+
"texture",
|
|
127
|
+
"craft-clay"
|
|
194
128
|
];
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
)
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
const { value: multipartResult, responseHeaders } = await postToApi({
|
|
318
|
-
url: `${this.config.baseURL}/job?price=true`,
|
|
319
|
-
headers: {
|
|
320
|
-
...combinedHeaders,
|
|
321
|
-
Accept: "multipart/form-data; image/png",
|
|
322
|
-
"Content-Type": "application/json"
|
|
323
|
-
},
|
|
324
|
-
body: {
|
|
325
|
-
content: JSON.stringify(body),
|
|
326
|
-
values: body
|
|
327
|
-
},
|
|
328
|
-
failedResponseHandler: prodiaFailedResponseHandler,
|
|
329
|
-
successfulResponseHandler: createMultipartResponseHandler(),
|
|
330
|
-
abortSignal: options.abortSignal,
|
|
331
|
-
fetch: this.config.fetch
|
|
332
|
-
});
|
|
333
|
-
const { jobResult, imageBytes } = multipartResult;
|
|
334
|
-
return {
|
|
335
|
-
images: [imageBytes],
|
|
336
|
-
warnings,
|
|
337
|
-
providerMetadata: {
|
|
338
|
-
prodia: {
|
|
339
|
-
images: [buildProdiaProviderMetadata(jobResult)]
|
|
340
|
-
}
|
|
341
|
-
},
|
|
342
|
-
response: {
|
|
343
|
-
modelId: this.modelId,
|
|
344
|
-
timestamp: currentDate,
|
|
345
|
-
headers: responseHeaders
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
}
|
|
129
|
+
const prodiaImageModelOptionsSchema = lazySchema(() => zodSchema(z.object({
|
|
130
|
+
/**
|
|
131
|
+
* Amount of computational iterations to run. More is typically higher quality.
|
|
132
|
+
*/
|
|
133
|
+
steps: z.number().int().min(1).max(4).optional(),
|
|
134
|
+
/**
|
|
135
|
+
* Width of the output image in pixels.
|
|
136
|
+
*/
|
|
137
|
+
width: z.number().int().min(256).max(1920).optional(),
|
|
138
|
+
/**
|
|
139
|
+
* Height of the output image in pixels.
|
|
140
|
+
*/
|
|
141
|
+
height: z.number().int().min(256).max(1920).optional(),
|
|
142
|
+
/**
|
|
143
|
+
* Apply a visual theme to your output image.
|
|
144
|
+
*/
|
|
145
|
+
stylePreset: z.enum(stylePresets).optional(),
|
|
146
|
+
/**
|
|
147
|
+
* Augment the output with a LoRa model.
|
|
148
|
+
*/
|
|
149
|
+
loras: z.array(z.string()).max(3).optional(),
|
|
150
|
+
/**
|
|
151
|
+
* When using JPEG output, return a progressive JPEG.
|
|
152
|
+
*/
|
|
153
|
+
progressive: z.boolean().optional()
|
|
154
|
+
})));
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region src/prodia-image-model.ts
|
|
157
|
+
var ProdiaImageModel = class ProdiaImageModel {
|
|
158
|
+
get provider() {
|
|
159
|
+
return this.config.provider;
|
|
160
|
+
}
|
|
161
|
+
static [WORKFLOW_SERIALIZE](model) {
|
|
162
|
+
return serializeModelOptions({
|
|
163
|
+
modelId: model.modelId,
|
|
164
|
+
config: model.config
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
static [WORKFLOW_DESERIALIZE](options) {
|
|
168
|
+
return new ProdiaImageModel(options.modelId, options.config);
|
|
169
|
+
}
|
|
170
|
+
constructor(modelId, config) {
|
|
171
|
+
this.modelId = modelId;
|
|
172
|
+
this.config = config;
|
|
173
|
+
this.specificationVersion = "v4";
|
|
174
|
+
this.maxImagesPerCall = 1;
|
|
175
|
+
this.supportsFileInputs = false;
|
|
176
|
+
this.supportsMaskInputs = false;
|
|
177
|
+
}
|
|
178
|
+
async getArgs({ prompt, size, seed, providerOptions }) {
|
|
179
|
+
const warnings = [];
|
|
180
|
+
const prodiaOptions = await parseProviderOptions({
|
|
181
|
+
provider: "prodia",
|
|
182
|
+
providerOptions,
|
|
183
|
+
schema: prodiaImageModelOptionsSchema
|
|
184
|
+
});
|
|
185
|
+
let width;
|
|
186
|
+
let height;
|
|
187
|
+
if (size) {
|
|
188
|
+
const [widthStr, heightStr] = size.split("x");
|
|
189
|
+
width = Number(widthStr);
|
|
190
|
+
height = Number(heightStr);
|
|
191
|
+
if (!widthStr || !heightStr || !Number.isFinite(width) || !Number.isFinite(height)) {
|
|
192
|
+
warnings.push({
|
|
193
|
+
type: "unsupported",
|
|
194
|
+
feature: "size",
|
|
195
|
+
details: `Invalid size format: ${size}. Expected format: WIDTHxHEIGHT (e.g., 1024x1024)`
|
|
196
|
+
});
|
|
197
|
+
width = void 0;
|
|
198
|
+
height = void 0;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const jobConfig = { prompt };
|
|
202
|
+
if (prodiaOptions?.width !== void 0) jobConfig.width = prodiaOptions.width;
|
|
203
|
+
else if (width !== void 0) jobConfig.width = width;
|
|
204
|
+
if (prodiaOptions?.height !== void 0) jobConfig.height = prodiaOptions.height;
|
|
205
|
+
else if (height !== void 0) jobConfig.height = height;
|
|
206
|
+
if (seed !== void 0) jobConfig.seed = seed;
|
|
207
|
+
if (prodiaOptions?.steps !== void 0) jobConfig.steps = prodiaOptions.steps;
|
|
208
|
+
if (prodiaOptions?.stylePreset !== void 0) jobConfig.style_preset = prodiaOptions.stylePreset;
|
|
209
|
+
if (prodiaOptions?.loras !== void 0 && prodiaOptions.loras.length > 0) jobConfig.loras = prodiaOptions.loras;
|
|
210
|
+
if (prodiaOptions?.progressive !== void 0) jobConfig.progressive = prodiaOptions.progressive;
|
|
211
|
+
return {
|
|
212
|
+
body: {
|
|
213
|
+
type: this.modelId,
|
|
214
|
+
config: jobConfig
|
|
215
|
+
},
|
|
216
|
+
warnings
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
async doGenerate(options) {
|
|
220
|
+
const { body, warnings } = await this.getArgs(options);
|
|
221
|
+
const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
|
|
222
|
+
const combinedHeaders = combineHeaders(this.config.headers ? await resolve(this.config.headers) : void 0, options.headers);
|
|
223
|
+
const { value: multipartResult, responseHeaders } = await postToApi({
|
|
224
|
+
url: `${this.config.baseURL}/job?price=true`,
|
|
225
|
+
headers: {
|
|
226
|
+
...combinedHeaders,
|
|
227
|
+
Accept: "multipart/form-data; image/png",
|
|
228
|
+
"Content-Type": "application/json"
|
|
229
|
+
},
|
|
230
|
+
body: {
|
|
231
|
+
content: JSON.stringify(body),
|
|
232
|
+
values: body
|
|
233
|
+
},
|
|
234
|
+
failedResponseHandler: prodiaFailedResponseHandler,
|
|
235
|
+
successfulResponseHandler: createMultipartResponseHandler(),
|
|
236
|
+
abortSignal: options.abortSignal,
|
|
237
|
+
fetch: this.config.fetch
|
|
238
|
+
});
|
|
239
|
+
const { jobResult, imageBytes } = multipartResult;
|
|
240
|
+
return {
|
|
241
|
+
images: [imageBytes],
|
|
242
|
+
warnings,
|
|
243
|
+
providerMetadata: { prodia: { images: [buildProdiaProviderMetadata(jobResult)] } },
|
|
244
|
+
response: {
|
|
245
|
+
modelId: this.modelId,
|
|
246
|
+
timestamp: currentDate,
|
|
247
|
+
headers: responseHeaders
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
}
|
|
349
251
|
};
|
|
350
252
|
function createMultipartResponseHandler() {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
if (!jobResult) {
|
|
387
|
-
throw new Error("Prodia multipart response missing job part");
|
|
388
|
-
}
|
|
389
|
-
if (!imageBytes) {
|
|
390
|
-
throw new Error("Prodia multipart response missing output image");
|
|
391
|
-
}
|
|
392
|
-
return {
|
|
393
|
-
value: { jobResult, imageBytes },
|
|
394
|
-
responseHeaders
|
|
395
|
-
};
|
|
396
|
-
};
|
|
253
|
+
return async ({ response }) => {
|
|
254
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
255
|
+
const responseHeaders = {};
|
|
256
|
+
response.headers.forEach((value, key) => {
|
|
257
|
+
responseHeaders[key] = value;
|
|
258
|
+
});
|
|
259
|
+
const boundaryMatch = contentType.match(/boundary=([^\s;]+)/);
|
|
260
|
+
if (!boundaryMatch) throw new Error(`Prodia response missing multipart boundary in content-type: ${contentType}`);
|
|
261
|
+
const boundary = boundaryMatch[1];
|
|
262
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
263
|
+
const parts = parseMultipart(new Uint8Array(arrayBuffer), boundary);
|
|
264
|
+
let jobResult;
|
|
265
|
+
let imageBytes;
|
|
266
|
+
for (const part of parts) {
|
|
267
|
+
const contentDisposition = part.headers["content-disposition"] ?? "";
|
|
268
|
+
const partContentType = part.headers["content-type"] ?? "";
|
|
269
|
+
if (contentDisposition.includes("name=\"job\"")) {
|
|
270
|
+
const jsonStr = new TextDecoder().decode(part.body);
|
|
271
|
+
jobResult = await parseJSON({
|
|
272
|
+
text: jsonStr,
|
|
273
|
+
schema: zodSchema(prodiaJobResultSchema)
|
|
274
|
+
});
|
|
275
|
+
} else if (contentDisposition.includes("name=\"output\"")) imageBytes = part.body;
|
|
276
|
+
else if (partContentType.startsWith("image/")) imageBytes = part.body;
|
|
277
|
+
}
|
|
278
|
+
if (!jobResult) throw new Error("Prodia multipart response missing job part");
|
|
279
|
+
if (!imageBytes) throw new Error("Prodia multipart response missing output image");
|
|
280
|
+
return {
|
|
281
|
+
value: {
|
|
282
|
+
jobResult,
|
|
283
|
+
imageBytes
|
|
284
|
+
},
|
|
285
|
+
responseHeaders
|
|
286
|
+
};
|
|
287
|
+
};
|
|
397
288
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
)
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
cacheRead: void 0,
|
|
653
|
-
cacheWrite: void 0
|
|
654
|
-
},
|
|
655
|
-
outputTokens: {
|
|
656
|
-
total: void 0,
|
|
657
|
-
text: void 0,
|
|
658
|
-
reasoning: void 0
|
|
659
|
-
}
|
|
660
|
-
},
|
|
661
|
-
warnings,
|
|
662
|
-
providerMetadata: {
|
|
663
|
-
prodia: buildProdiaProviderMetadata(jobResult)
|
|
664
|
-
},
|
|
665
|
-
response: {
|
|
666
|
-
modelId: this.modelId,
|
|
667
|
-
timestamp: currentDate,
|
|
668
|
-
headers: responseHeaders
|
|
669
|
-
}
|
|
670
|
-
};
|
|
671
|
-
}
|
|
672
|
-
async doStream(options) {
|
|
673
|
-
const result = await this.doGenerate(options);
|
|
674
|
-
const stream = new ReadableStream({
|
|
675
|
-
start(controller) {
|
|
676
|
-
controller.enqueue({
|
|
677
|
-
type: "stream-start",
|
|
678
|
-
warnings: result.warnings
|
|
679
|
-
});
|
|
680
|
-
controller.enqueue({
|
|
681
|
-
type: "response-metadata",
|
|
682
|
-
modelId: result.response?.modelId,
|
|
683
|
-
timestamp: result.response?.timestamp
|
|
684
|
-
});
|
|
685
|
-
for (const part of result.content) {
|
|
686
|
-
if (part.type === "text") {
|
|
687
|
-
const id = generateId();
|
|
688
|
-
controller.enqueue({ type: "text-start", id });
|
|
689
|
-
controller.enqueue({
|
|
690
|
-
type: "text-delta",
|
|
691
|
-
id,
|
|
692
|
-
delta: part.text
|
|
693
|
-
});
|
|
694
|
-
controller.enqueue({ type: "text-end", id });
|
|
695
|
-
} else if (part.type === "file") {
|
|
696
|
-
controller.enqueue({
|
|
697
|
-
type: "file",
|
|
698
|
-
mediaType: part.mediaType,
|
|
699
|
-
data: part.data
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
controller.enqueue({
|
|
704
|
-
type: "finish",
|
|
705
|
-
usage: result.usage,
|
|
706
|
-
finishReason: result.finishReason,
|
|
707
|
-
providerMetadata: result.providerMetadata
|
|
708
|
-
});
|
|
709
|
-
controller.close();
|
|
710
|
-
}
|
|
711
|
-
});
|
|
712
|
-
return {
|
|
713
|
-
stream,
|
|
714
|
-
response: {
|
|
715
|
-
headers: result.response?.headers
|
|
716
|
-
}
|
|
717
|
-
};
|
|
718
|
-
}
|
|
289
|
+
//#endregion
|
|
290
|
+
//#region src/prodia-language-model-options.ts
|
|
291
|
+
const prodiaLanguageModelOptionsSchema = lazySchema(() => zodSchema(z.object({
|
|
292
|
+
/**
|
|
293
|
+
* Aspect ratio for the output image.
|
|
294
|
+
*/
|
|
295
|
+
aspectRatio: z.enum([
|
|
296
|
+
"1:1",
|
|
297
|
+
"2:3",
|
|
298
|
+
"3:2",
|
|
299
|
+
"4:5",
|
|
300
|
+
"5:4",
|
|
301
|
+
"4:7",
|
|
302
|
+
"7:4",
|
|
303
|
+
"9:16",
|
|
304
|
+
"16:9",
|
|
305
|
+
"9:21",
|
|
306
|
+
"21:9"
|
|
307
|
+
]).optional() })));
|
|
308
|
+
//#endregion
|
|
309
|
+
//#region src/prodia-language-model.ts
|
|
310
|
+
var ProdiaLanguageModel = class ProdiaLanguageModel {
|
|
311
|
+
get provider() {
|
|
312
|
+
return this.config.provider;
|
|
313
|
+
}
|
|
314
|
+
static [WORKFLOW_SERIALIZE](model) {
|
|
315
|
+
return serializeModelOptions({
|
|
316
|
+
modelId: model.modelId,
|
|
317
|
+
config: model.config
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
static [WORKFLOW_DESERIALIZE](options) {
|
|
321
|
+
return new ProdiaLanguageModel(options.modelId, options.config);
|
|
322
|
+
}
|
|
323
|
+
constructor(modelId, config) {
|
|
324
|
+
this.modelId = modelId;
|
|
325
|
+
this.config = config;
|
|
326
|
+
this.specificationVersion = "v4";
|
|
327
|
+
this.supportedUrls = {};
|
|
328
|
+
}
|
|
329
|
+
async doGenerate(options) {
|
|
330
|
+
const warnings = [];
|
|
331
|
+
if (options.temperature !== void 0) warnings.push({
|
|
332
|
+
type: "unsupported",
|
|
333
|
+
feature: "temperature"
|
|
334
|
+
});
|
|
335
|
+
if (options.topP !== void 0) warnings.push({
|
|
336
|
+
type: "unsupported",
|
|
337
|
+
feature: "topP"
|
|
338
|
+
});
|
|
339
|
+
if (options.topK !== void 0) warnings.push({
|
|
340
|
+
type: "unsupported",
|
|
341
|
+
feature: "topK"
|
|
342
|
+
});
|
|
343
|
+
if (options.seed !== void 0) warnings.push({
|
|
344
|
+
type: "unsupported",
|
|
345
|
+
feature: "seed"
|
|
346
|
+
});
|
|
347
|
+
if (options.maxOutputTokens !== void 0) warnings.push({
|
|
348
|
+
type: "unsupported",
|
|
349
|
+
feature: "maxOutputTokens"
|
|
350
|
+
});
|
|
351
|
+
if (options.stopSequences !== void 0) warnings.push({
|
|
352
|
+
type: "unsupported",
|
|
353
|
+
feature: "stopSequences"
|
|
354
|
+
});
|
|
355
|
+
if (options.presencePenalty !== void 0) warnings.push({
|
|
356
|
+
type: "unsupported",
|
|
357
|
+
feature: "presencePenalty"
|
|
358
|
+
});
|
|
359
|
+
if (options.frequencyPenalty !== void 0) warnings.push({
|
|
360
|
+
type: "unsupported",
|
|
361
|
+
feature: "frequencyPenalty"
|
|
362
|
+
});
|
|
363
|
+
if (options.tools !== void 0 && options.tools.length > 0) warnings.push({
|
|
364
|
+
type: "unsupported",
|
|
365
|
+
feature: "tools"
|
|
366
|
+
});
|
|
367
|
+
if (options.toolChoice !== void 0) warnings.push({
|
|
368
|
+
type: "unsupported",
|
|
369
|
+
feature: "toolChoice"
|
|
370
|
+
});
|
|
371
|
+
if (options.responseFormat !== void 0 && options.responseFormat.type !== "text") warnings.push({
|
|
372
|
+
type: "unsupported",
|
|
373
|
+
feature: "responseFormat"
|
|
374
|
+
});
|
|
375
|
+
if (isCustomReasoning(options.reasoning)) warnings.push({
|
|
376
|
+
type: "unsupported",
|
|
377
|
+
feature: "reasoning",
|
|
378
|
+
details: "This provider does not support reasoning configuration."
|
|
379
|
+
});
|
|
380
|
+
const prodiaOptions = await parseProviderOptions({
|
|
381
|
+
provider: "prodia",
|
|
382
|
+
providerOptions: options.providerOptions,
|
|
383
|
+
schema: prodiaLanguageModelOptionsSchema
|
|
384
|
+
});
|
|
385
|
+
let prompt = "";
|
|
386
|
+
let systemMessage = "";
|
|
387
|
+
for (const message of options.prompt) if (message.role === "system") systemMessage = message.content;
|
|
388
|
+
for (let i = options.prompt.length - 1; i >= 0; i--) {
|
|
389
|
+
const message = options.prompt[i];
|
|
390
|
+
if (message.role === "user") {
|
|
391
|
+
for (const part of message.content) if (part.type === "text") prompt += (prompt ? "\n" : "") + part.text;
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (systemMessage) prompt = systemMessage + "\n" + prompt;
|
|
396
|
+
let imageBytes;
|
|
397
|
+
let imageMediaType = "image/png";
|
|
398
|
+
for (let i = options.prompt.length - 1; i >= 0; i--) {
|
|
399
|
+
const message = options.prompt[i];
|
|
400
|
+
if (message.role === "user") {
|
|
401
|
+
for (const part of message.content) if (part.type === "file" && getTopLevelMediaType(part.mediaType) === "image") {
|
|
402
|
+
switch (part.data.type) {
|
|
403
|
+
case "reference": throw new UnsupportedFunctionalityError({ functionality: "file parts with provider references" });
|
|
404
|
+
case "text": throw new UnsupportedFunctionalityError({ functionality: "text file parts" });
|
|
405
|
+
case "data":
|
|
406
|
+
if (part.data.data instanceof Uint8Array) imageBytes = part.data.data;
|
|
407
|
+
else imageBytes = convertBase64ToUint8Array(part.data.data);
|
|
408
|
+
break;
|
|
409
|
+
case "url": {
|
|
410
|
+
const arrayBuffer = await (await (this.config.fetch ?? globalThis.fetch)(part.data.url.toString())).arrayBuffer();
|
|
411
|
+
imageBytes = new Uint8Array(arrayBuffer);
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (isFullMediaType(part.mediaType)) imageMediaType = part.mediaType;
|
|
416
|
+
else if (imageBytes !== void 0) {
|
|
417
|
+
const detected = detectMediaType({
|
|
418
|
+
data: imageBytes,
|
|
419
|
+
topLevelType: getTopLevelMediaType(part.mediaType)
|
|
420
|
+
});
|
|
421
|
+
if (detected !== void 0) imageMediaType = detected;
|
|
422
|
+
}
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
const jobConfig = {
|
|
429
|
+
prompt,
|
|
430
|
+
include_messages: true
|
|
431
|
+
};
|
|
432
|
+
if (prodiaOptions?.aspectRatio !== void 0) jobConfig.aspect_ratio = prodiaOptions.aspectRatio;
|
|
433
|
+
const body = {
|
|
434
|
+
type: this.modelId,
|
|
435
|
+
config: jobConfig
|
|
436
|
+
};
|
|
437
|
+
const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
|
|
438
|
+
const combinedHeaders = combineHeaders(this.config.headers ? await resolve(this.config.headers) : void 0, options.headers);
|
|
439
|
+
const formData = new FormData();
|
|
440
|
+
formData.append("job", new Blob([JSON.stringify(body)], { type: "application/json" }), "job.json");
|
|
441
|
+
if (imageBytes) {
|
|
442
|
+
const fileExtension = imageMediaType === "image/png" ? ".png" : imageMediaType === "image/jpeg" ? ".jpg" : imageMediaType === "image/webp" ? ".webp" : "";
|
|
443
|
+
formData.append("input", new Blob([imageBytes], { type: imageMediaType }), "input" + fileExtension);
|
|
444
|
+
}
|
|
445
|
+
const { value: multipartResult, responseHeaders } = await postFormDataToApi({
|
|
446
|
+
url: `${this.config.baseURL}/job?price=true`,
|
|
447
|
+
headers: {
|
|
448
|
+
...combinedHeaders,
|
|
449
|
+
Accept: "multipart/form-data"
|
|
450
|
+
},
|
|
451
|
+
formData,
|
|
452
|
+
failedResponseHandler: prodiaFailedResponseHandler,
|
|
453
|
+
successfulResponseHandler: createLanguageMultipartResponseHandler(),
|
|
454
|
+
abortSignal: options.abortSignal,
|
|
455
|
+
fetch: this.config.fetch
|
|
456
|
+
});
|
|
457
|
+
const { jobResult, textContent, fileContent } = multipartResult;
|
|
458
|
+
const content = [];
|
|
459
|
+
if (textContent !== void 0) content.push({
|
|
460
|
+
type: "text",
|
|
461
|
+
text: textContent
|
|
462
|
+
});
|
|
463
|
+
for (const file of fileContent) content.push({
|
|
464
|
+
type: "file",
|
|
465
|
+
mediaType: file.mediaType,
|
|
466
|
+
data: {
|
|
467
|
+
type: "data",
|
|
468
|
+
data: file.data
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
return {
|
|
472
|
+
content,
|
|
473
|
+
finishReason: {
|
|
474
|
+
unified: "stop",
|
|
475
|
+
raw: void 0
|
|
476
|
+
},
|
|
477
|
+
usage: {
|
|
478
|
+
inputTokens: {
|
|
479
|
+
total: void 0,
|
|
480
|
+
noCache: void 0,
|
|
481
|
+
cacheRead: void 0,
|
|
482
|
+
cacheWrite: void 0
|
|
483
|
+
},
|
|
484
|
+
outputTokens: {
|
|
485
|
+
total: void 0,
|
|
486
|
+
text: void 0,
|
|
487
|
+
reasoning: void 0
|
|
488
|
+
}
|
|
489
|
+
},
|
|
490
|
+
warnings,
|
|
491
|
+
providerMetadata: { prodia: buildProdiaProviderMetadata(jobResult) },
|
|
492
|
+
response: {
|
|
493
|
+
modelId: this.modelId,
|
|
494
|
+
timestamp: currentDate,
|
|
495
|
+
headers: responseHeaders
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
async doStream(options) {
|
|
500
|
+
const result = await this.doGenerate(options);
|
|
501
|
+
return {
|
|
502
|
+
stream: new ReadableStream({ start(controller) {
|
|
503
|
+
controller.enqueue({
|
|
504
|
+
type: "stream-start",
|
|
505
|
+
warnings: result.warnings
|
|
506
|
+
});
|
|
507
|
+
controller.enqueue({
|
|
508
|
+
type: "response-metadata",
|
|
509
|
+
modelId: result.response?.modelId,
|
|
510
|
+
timestamp: result.response?.timestamp
|
|
511
|
+
});
|
|
512
|
+
for (const part of result.content) if (part.type === "text") {
|
|
513
|
+
const id = generateId();
|
|
514
|
+
controller.enqueue({
|
|
515
|
+
type: "text-start",
|
|
516
|
+
id
|
|
517
|
+
});
|
|
518
|
+
controller.enqueue({
|
|
519
|
+
type: "text-delta",
|
|
520
|
+
id,
|
|
521
|
+
delta: part.text
|
|
522
|
+
});
|
|
523
|
+
controller.enqueue({
|
|
524
|
+
type: "text-end",
|
|
525
|
+
id
|
|
526
|
+
});
|
|
527
|
+
} else if (part.type === "file") controller.enqueue({
|
|
528
|
+
type: "file",
|
|
529
|
+
mediaType: part.mediaType,
|
|
530
|
+
data: part.data
|
|
531
|
+
});
|
|
532
|
+
controller.enqueue({
|
|
533
|
+
type: "finish",
|
|
534
|
+
usage: result.usage,
|
|
535
|
+
finishReason: result.finishReason,
|
|
536
|
+
providerMetadata: result.providerMetadata
|
|
537
|
+
});
|
|
538
|
+
controller.close();
|
|
539
|
+
} }),
|
|
540
|
+
response: { headers: result.response?.headers }
|
|
541
|
+
};
|
|
542
|
+
}
|
|
719
543
|
};
|
|
720
544
|
function createLanguageMultipartResponseHandler() {
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
if (!jobResult) {
|
|
763
|
-
throw new Error("Prodia multipart response missing job part");
|
|
764
|
-
}
|
|
765
|
-
return {
|
|
766
|
-
value: { jobResult, textContent, fileContent },
|
|
767
|
-
responseHeaders
|
|
768
|
-
};
|
|
769
|
-
};
|
|
545
|
+
return async ({ response }) => {
|
|
546
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
547
|
+
const responseHeaders = {};
|
|
548
|
+
response.headers.forEach((value, key) => {
|
|
549
|
+
responseHeaders[key] = value;
|
|
550
|
+
});
|
|
551
|
+
const boundaryMatch = contentType.match(/boundary=([^\s;]+)/);
|
|
552
|
+
if (!boundaryMatch) throw new Error(`Prodia response missing multipart boundary in content-type: ${contentType}`);
|
|
553
|
+
const boundary = boundaryMatch[1];
|
|
554
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
555
|
+
const parts = parseMultipart(new Uint8Array(arrayBuffer), boundary);
|
|
556
|
+
let jobResult;
|
|
557
|
+
let textContent;
|
|
558
|
+
const fileContent = [];
|
|
559
|
+
for (const part of parts) {
|
|
560
|
+
const contentDisposition = part.headers["content-disposition"] ?? "";
|
|
561
|
+
const partContentType = part.headers["content-type"] ?? "";
|
|
562
|
+
if (contentDisposition.includes("name=\"job\"")) {
|
|
563
|
+
const jsonStr = new TextDecoder().decode(part.body);
|
|
564
|
+
jobResult = await parseJSON({
|
|
565
|
+
text: jsonStr,
|
|
566
|
+
schema: zodSchema(prodiaJobResultSchema)
|
|
567
|
+
});
|
|
568
|
+
} else if (contentDisposition.includes("name=\"output\"")) {
|
|
569
|
+
if (partContentType.startsWith("text/") || contentDisposition.includes(".txt")) textContent = new TextDecoder().decode(part.body);
|
|
570
|
+
else if (partContentType.startsWith("image/")) fileContent.push({
|
|
571
|
+
mediaType: partContentType,
|
|
572
|
+
data: part.body
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
if (!jobResult) throw new Error("Prodia multipart response missing job part");
|
|
577
|
+
return {
|
|
578
|
+
value: {
|
|
579
|
+
jobResult,
|
|
580
|
+
textContent,
|
|
581
|
+
fileContent
|
|
582
|
+
},
|
|
583
|
+
responseHeaders
|
|
584
|
+
};
|
|
585
|
+
};
|
|
770
586
|
}
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
postToApi as postToApi2,
|
|
781
|
-
resolve as resolve3,
|
|
782
|
-
zodSchema as zodSchema6
|
|
783
|
-
} from "@ai-sdk/provider-utils";
|
|
784
|
-
|
|
785
|
-
// src/prodia-video-model-options.ts
|
|
786
|
-
import {
|
|
787
|
-
lazySchema as lazySchema3,
|
|
788
|
-
zodSchema as zodSchema5
|
|
789
|
-
} from "@ai-sdk/provider-utils";
|
|
790
|
-
import { z as z4 } from "zod/v4";
|
|
791
|
-
var prodiaVideoModelOptionsSchema = lazySchema3(
|
|
792
|
-
() => zodSchema5(
|
|
793
|
-
z4.object({
|
|
794
|
-
/**
|
|
795
|
-
* Video resolution (e.g. "480p", "720p").
|
|
796
|
-
*/
|
|
797
|
-
resolution: z4.string().optional()
|
|
798
|
-
})
|
|
799
|
-
)
|
|
800
|
-
);
|
|
801
|
-
|
|
802
|
-
// src/prodia-video-model.ts
|
|
587
|
+
//#endregion
|
|
588
|
+
//#region src/prodia-video-model-options.ts
|
|
589
|
+
const prodiaVideoModelOptionsSchema = lazySchema(() => zodSchema(z.object({
|
|
590
|
+
/**
|
|
591
|
+
* Video resolution (e.g. "480p", "720p").
|
|
592
|
+
*/
|
|
593
|
+
resolution: z.string().optional() })));
|
|
594
|
+
//#endregion
|
|
595
|
+
//#region src/prodia-video-model.ts
|
|
803
596
|
var ProdiaVideoModel = class {
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
});
|
|
888
|
-
multipartResult = result.value;
|
|
889
|
-
responseHeaders = result.responseHeaders;
|
|
890
|
-
}
|
|
891
|
-
const { jobResult, videoBytes, videoMediaType } = multipartResult;
|
|
892
|
-
return {
|
|
893
|
-
videos: [
|
|
894
|
-
{
|
|
895
|
-
type: "binary",
|
|
896
|
-
data: videoBytes,
|
|
897
|
-
mediaType: videoMediaType
|
|
898
|
-
}
|
|
899
|
-
],
|
|
900
|
-
warnings,
|
|
901
|
-
providerMetadata: {
|
|
902
|
-
prodia: {
|
|
903
|
-
videos: [buildProdiaProviderMetadata(jobResult)]
|
|
904
|
-
}
|
|
905
|
-
},
|
|
906
|
-
response: {
|
|
907
|
-
modelId: this.modelId,
|
|
908
|
-
timestamp: currentDate,
|
|
909
|
-
headers: responseHeaders
|
|
910
|
-
}
|
|
911
|
-
};
|
|
912
|
-
}
|
|
597
|
+
get provider() {
|
|
598
|
+
return this.config.provider;
|
|
599
|
+
}
|
|
600
|
+
constructor(modelId, config) {
|
|
601
|
+
this.modelId = modelId;
|
|
602
|
+
this.config = config;
|
|
603
|
+
this.specificationVersion = "v4";
|
|
604
|
+
this.maxVideosPerCall = 1;
|
|
605
|
+
}
|
|
606
|
+
async doGenerate(options) {
|
|
607
|
+
const warnings = [];
|
|
608
|
+
const prodiaOptions = await parseProviderOptions({
|
|
609
|
+
provider: "prodia",
|
|
610
|
+
providerOptions: options.providerOptions,
|
|
611
|
+
schema: prodiaVideoModelOptionsSchema
|
|
612
|
+
});
|
|
613
|
+
const jobConfig = {};
|
|
614
|
+
if (options.prompt !== void 0) jobConfig.prompt = options.prompt;
|
|
615
|
+
if (options.seed !== void 0) jobConfig.seed = options.seed;
|
|
616
|
+
if (prodiaOptions?.resolution !== void 0) jobConfig.resolution = prodiaOptions.resolution;
|
|
617
|
+
const body = {
|
|
618
|
+
type: this.modelId,
|
|
619
|
+
config: jobConfig
|
|
620
|
+
};
|
|
621
|
+
const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
|
|
622
|
+
const combinedHeaders = combineHeaders(await resolve(this.config.headers), options.headers);
|
|
623
|
+
let multipartResult;
|
|
624
|
+
let responseHeaders;
|
|
625
|
+
if (options.image) {
|
|
626
|
+
const imageData = await resolveVideoFileData(options.image, options.abortSignal);
|
|
627
|
+
const formData = new FormData();
|
|
628
|
+
formData.append("job", new Blob([JSON.stringify(body)], { type: "application/json" }), "job.json");
|
|
629
|
+
formData.append("input", new Blob([imageData.bytes], { type: imageData.mediaType }), "input" + getExtension(imageData.mediaType));
|
|
630
|
+
const result = await postFormDataToApi({
|
|
631
|
+
url: `${this.config.baseURL}/job?price=true`,
|
|
632
|
+
headers: {
|
|
633
|
+
...combinedHeaders,
|
|
634
|
+
Accept: "multipart/form-data; video/mp4"
|
|
635
|
+
},
|
|
636
|
+
formData,
|
|
637
|
+
failedResponseHandler: prodiaFailedResponseHandler,
|
|
638
|
+
successfulResponseHandler: createVideoMultipartResponseHandler(),
|
|
639
|
+
abortSignal: options.abortSignal,
|
|
640
|
+
fetch: this.config.fetch
|
|
641
|
+
});
|
|
642
|
+
multipartResult = result.value;
|
|
643
|
+
responseHeaders = result.responseHeaders;
|
|
644
|
+
} else {
|
|
645
|
+
const result = await postToApi({
|
|
646
|
+
url: `${this.config.baseURL}/job?price=true`,
|
|
647
|
+
headers: {
|
|
648
|
+
...combinedHeaders,
|
|
649
|
+
Accept: "multipart/form-data; video/mp4",
|
|
650
|
+
"Content-Type": "application/json"
|
|
651
|
+
},
|
|
652
|
+
body: {
|
|
653
|
+
content: JSON.stringify(body),
|
|
654
|
+
values: body
|
|
655
|
+
},
|
|
656
|
+
failedResponseHandler: prodiaFailedResponseHandler,
|
|
657
|
+
successfulResponseHandler: createVideoMultipartResponseHandler(),
|
|
658
|
+
abortSignal: options.abortSignal,
|
|
659
|
+
fetch: this.config.fetch
|
|
660
|
+
});
|
|
661
|
+
multipartResult = result.value;
|
|
662
|
+
responseHeaders = result.responseHeaders;
|
|
663
|
+
}
|
|
664
|
+
const { jobResult, videoBytes, videoMediaType } = multipartResult;
|
|
665
|
+
return {
|
|
666
|
+
videos: [{
|
|
667
|
+
type: "binary",
|
|
668
|
+
data: videoBytes,
|
|
669
|
+
mediaType: videoMediaType
|
|
670
|
+
}],
|
|
671
|
+
warnings,
|
|
672
|
+
providerMetadata: { prodia: { videos: [buildProdiaProviderMetadata(jobResult)] } },
|
|
673
|
+
response: {
|
|
674
|
+
modelId: this.modelId,
|
|
675
|
+
timestamp: currentDate,
|
|
676
|
+
headers: responseHeaders
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
}
|
|
913
680
|
};
|
|
914
681
|
function createVideoMultipartResponseHandler() {
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
}
|
|
958
|
-
if (!videoBytes) {
|
|
959
|
-
throw new Error("Prodia multipart response missing output video");
|
|
960
|
-
}
|
|
961
|
-
return {
|
|
962
|
-
value: { jobResult, videoBytes, videoMediaType },
|
|
963
|
-
responseHeaders
|
|
964
|
-
};
|
|
965
|
-
};
|
|
682
|
+
return async ({ response }) => {
|
|
683
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
684
|
+
const responseHeaders = {};
|
|
685
|
+
response.headers.forEach((value, key) => {
|
|
686
|
+
responseHeaders[key] = value;
|
|
687
|
+
});
|
|
688
|
+
const boundaryMatch = contentType.match(/boundary=([^\s;]+)/);
|
|
689
|
+
if (!boundaryMatch) throw new Error(`Prodia response missing multipart boundary in content-type: ${contentType}`);
|
|
690
|
+
const boundary = boundaryMatch[1];
|
|
691
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
692
|
+
const parts = parseMultipart(new Uint8Array(arrayBuffer), boundary);
|
|
693
|
+
let jobResult;
|
|
694
|
+
let videoBytes;
|
|
695
|
+
let videoMediaType = "video/mp4";
|
|
696
|
+
for (const part of parts) {
|
|
697
|
+
const contentDisposition = part.headers["content-disposition"] ?? "";
|
|
698
|
+
const partContentType = part.headers["content-type"] ?? "";
|
|
699
|
+
if (contentDisposition.includes("name=\"job\"")) {
|
|
700
|
+
const jsonStr = new TextDecoder().decode(part.body);
|
|
701
|
+
jobResult = await parseJSON({
|
|
702
|
+
text: jsonStr,
|
|
703
|
+
schema: zodSchema(prodiaJobResultSchema)
|
|
704
|
+
});
|
|
705
|
+
} else if (contentDisposition.includes("name=\"output\"")) {
|
|
706
|
+
videoBytes = part.body;
|
|
707
|
+
if (partContentType.startsWith("video/")) videoMediaType = partContentType;
|
|
708
|
+
} else if (partContentType.startsWith("video/")) {
|
|
709
|
+
videoBytes = part.body;
|
|
710
|
+
videoMediaType = partContentType;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
if (!jobResult) throw new Error("Prodia multipart response missing job part");
|
|
714
|
+
if (!videoBytes) throw new Error("Prodia multipart response missing output video");
|
|
715
|
+
return {
|
|
716
|
+
value: {
|
|
717
|
+
jobResult,
|
|
718
|
+
videoBytes,
|
|
719
|
+
videoMediaType
|
|
720
|
+
},
|
|
721
|
+
responseHeaders
|
|
722
|
+
};
|
|
723
|
+
};
|
|
966
724
|
}
|
|
967
725
|
async function resolveVideoFileData(file, abortSignal) {
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
726
|
+
if (file.type === "file") return {
|
|
727
|
+
bytes: typeof file.data === "string" ? convertBase64ToUint8Array(file.data) : file.data,
|
|
728
|
+
mediaType: file.mediaType
|
|
729
|
+
};
|
|
730
|
+
const blob = await downloadBlob(file.url, { abortSignal });
|
|
731
|
+
const arrayBuffer = await blob.arrayBuffer();
|
|
732
|
+
const mediaType = blob.type || "application/octet-stream";
|
|
733
|
+
return {
|
|
734
|
+
bytes: new Uint8Array(arrayBuffer),
|
|
735
|
+
mediaType
|
|
736
|
+
};
|
|
976
737
|
}
|
|
977
738
|
function getExtension(mediaType) {
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
return map[mediaType] ?? "";
|
|
739
|
+
return {
|
|
740
|
+
"image/png": ".png",
|
|
741
|
+
"image/jpeg": ".jpg",
|
|
742
|
+
"image/webp": ".webp",
|
|
743
|
+
"video/mp4": ".mp4",
|
|
744
|
+
"video/webm": ".webm"
|
|
745
|
+
}[mediaType] ?? "";
|
|
986
746
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
747
|
+
//#endregion
|
|
748
|
+
//#region src/version.ts
|
|
749
|
+
const VERSION = "2.0.53";
|
|
750
|
+
//#endregion
|
|
751
|
+
//#region src/prodia-provider.ts
|
|
752
|
+
const defaultBaseURL = "https://inference.prodia.com/v2";
|
|
993
753
|
function createProdia(options = {}) {
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
embeddingModel,
|
|
1038
|
-
textEmbeddingModel: embeddingModel
|
|
1039
|
-
};
|
|
754
|
+
const baseURL = withoutTrailingSlash(options.baseURL ?? defaultBaseURL);
|
|
755
|
+
const getHeaders = () => withUserAgentSuffix({
|
|
756
|
+
Authorization: `Bearer ${loadApiKey({
|
|
757
|
+
apiKey: options.apiKey,
|
|
758
|
+
environmentVariableName: "PRODIA_TOKEN",
|
|
759
|
+
description: "Prodia"
|
|
760
|
+
})}`,
|
|
761
|
+
...options.headers
|
|
762
|
+
}, `ai-sdk-prodia/${VERSION}`);
|
|
763
|
+
const createImageModel = (modelId) => new ProdiaImageModel(modelId, {
|
|
764
|
+
provider: "prodia.image",
|
|
765
|
+
baseURL: baseURL ?? defaultBaseURL,
|
|
766
|
+
headers: getHeaders,
|
|
767
|
+
fetch: options.fetch
|
|
768
|
+
});
|
|
769
|
+
const createLanguageModel = (modelId) => new ProdiaLanguageModel(modelId, {
|
|
770
|
+
provider: "prodia.language",
|
|
771
|
+
baseURL: baseURL ?? defaultBaseURL,
|
|
772
|
+
headers: getHeaders,
|
|
773
|
+
fetch: options.fetch
|
|
774
|
+
});
|
|
775
|
+
const createVideoModel = (modelId) => new ProdiaVideoModel(modelId, {
|
|
776
|
+
provider: "prodia.video",
|
|
777
|
+
baseURL: baseURL ?? defaultBaseURL,
|
|
778
|
+
headers: getHeaders,
|
|
779
|
+
fetch: options.fetch
|
|
780
|
+
});
|
|
781
|
+
const embeddingModel = (modelId) => {
|
|
782
|
+
throw new NoSuchModelError({
|
|
783
|
+
modelId,
|
|
784
|
+
modelType: "embeddingModel"
|
|
785
|
+
});
|
|
786
|
+
};
|
|
787
|
+
return {
|
|
788
|
+
specificationVersion: "v4",
|
|
789
|
+
languageModel: createLanguageModel,
|
|
790
|
+
imageModel: createImageModel,
|
|
791
|
+
image: createImageModel,
|
|
792
|
+
videoModel: createVideoModel,
|
|
793
|
+
video: createVideoModel,
|
|
794
|
+
embeddingModel,
|
|
795
|
+
textEmbeddingModel: embeddingModel
|
|
796
|
+
};
|
|
1040
797
|
}
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
prodia
|
|
1046
|
-
};
|
|
798
|
+
const prodia = createProdia();
|
|
799
|
+
//#endregion
|
|
800
|
+
export { VERSION, createProdia, prodia };
|
|
801
|
+
|
|
1047
802
|
//# sourceMappingURL=index.js.map
|