@ai-sdk/prodia 2.0.0-beta.22 → 2.0.0-beta.24

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