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