@ai-sdk/prodia 2.0.0-beta.5 → 2.0.0-beta.54

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.
@@ -1,31 +1,37 @@
1
- import type {
2
- LanguageModelV4,
3
- LanguageModelV4CallOptions,
4
- LanguageModelV4Content,
5
- LanguageModelV4StreamPart,
6
- SharedV4Warning,
1
+ import {
2
+ UnsupportedFunctionalityError,
3
+ type LanguageModelV4,
4
+ type LanguageModelV4CallOptions,
5
+ type LanguageModelV4Content,
6
+ type LanguageModelV4StreamPart,
7
+ type SharedV4Warning,
7
8
  } from '@ai-sdk/provider';
8
- import type { InferSchema } from '@ai-sdk/provider-utils';
9
9
  import {
10
10
  combineHeaders,
11
+ isCustomReasoning,
11
12
  convertBase64ToUint8Array,
13
+ detectMediaType,
12
14
  generateId,
13
- lazySchema,
15
+ getTopLevelMediaType,
16
+ isFullMediaType,
14
17
  parseJSON,
15
18
  parseProviderOptions,
16
19
  postFormDataToApi,
17
20
  resolve,
21
+ serializeModelOptions,
22
+ WORKFLOW_SERIALIZE,
23
+ WORKFLOW_DESERIALIZE,
18
24
  zodSchema,
19
25
  } from '@ai-sdk/provider-utils';
20
- import { z } from 'zod/v4';
21
- import type { ProdiaModelConfig } from './prodia-api';
22
26
  import {
23
27
  buildProdiaProviderMetadata,
24
28
  parseMultipart,
25
29
  prodiaFailedResponseHandler,
26
30
  prodiaJobResultSchema,
31
+ type ProdiaJobResult,
32
+ type ProdiaModelConfig,
27
33
  } from './prodia-api';
28
- import type { ProdiaJobResult } from './prodia-api';
34
+ import { prodiaLanguageModelOptionsSchema } from './prodia-language-model-options';
29
35
  import type { ProdiaLanguageModelId } from './prodia-language-model-settings';
30
36
 
31
37
  export class ProdiaLanguageModel implements LanguageModelV4 {
@@ -36,6 +42,20 @@ export class ProdiaLanguageModel implements LanguageModelV4 {
36
42
  return this.config.provider;
37
43
  }
38
44
 
45
+ static [WORKFLOW_SERIALIZE](model: ProdiaLanguageModel) {
46
+ return serializeModelOptions({
47
+ modelId: model.modelId,
48
+ config: model.config,
49
+ });
50
+ }
51
+
52
+ static [WORKFLOW_DESERIALIZE](options: {
53
+ modelId: ProdiaLanguageModelId;
54
+ config: ProdiaModelConfig;
55
+ }) {
56
+ return new ProdiaLanguageModel(options.modelId, options.config);
57
+ }
58
+
39
59
  constructor(
40
60
  readonly modelId: ProdiaLanguageModelId,
41
61
  private readonly config: ProdiaModelConfig,
@@ -79,6 +99,14 @@ export class ProdiaLanguageModel implements LanguageModelV4 {
79
99
  warnings.push({ type: 'unsupported', feature: 'responseFormat' });
80
100
  }
81
101
 
102
+ if (isCustomReasoning(options.reasoning)) {
103
+ warnings.push({
104
+ type: 'unsupported',
105
+ feature: 'reasoning',
106
+ details: 'This provider does not support reasoning configuration.',
107
+ });
108
+ }
109
+
82
110
  const prodiaOptions = await parseProviderOptions({
83
111
  provider: 'prodia',
84
112
  providerOptions: options.providerOptions,
@@ -116,19 +144,48 @@ export class ProdiaLanguageModel implements LanguageModelV4 {
116
144
  const message = options.prompt[i];
117
145
  if (message.role === 'user') {
118
146
  for (const part of message.content) {
119
- if (part.type === 'file' && part.mediaType.startsWith('image/')) {
120
- if (part.data instanceof Uint8Array) {
121
- imageBytes = part.data;
122
- } else if (typeof part.data === 'string') {
123
- // base64 encoded
124
- imageBytes = convertBase64ToUint8Array(part.data);
125
- } else if (part.data instanceof URL) {
126
- const fetchFn = this.config.fetch ?? globalThis.fetch;
127
- const response = await fetchFn(part.data.toString());
128
- const arrayBuffer = await response.arrayBuffer();
129
- imageBytes = new Uint8Array(arrayBuffer);
147
+ if (
148
+ part.type === 'file' &&
149
+ getTopLevelMediaType(part.mediaType) === 'image'
150
+ ) {
151
+ switch (part.data.type) {
152
+ case 'reference': {
153
+ throw new UnsupportedFunctionalityError({
154
+ functionality: 'file parts with provider references',
155
+ });
156
+ }
157
+ case 'text': {
158
+ throw new UnsupportedFunctionalityError({
159
+ functionality: 'text file parts',
160
+ });
161
+ }
162
+ case 'data': {
163
+ if (part.data.data instanceof Uint8Array) {
164
+ imageBytes = part.data.data;
165
+ } else {
166
+ imageBytes = convertBase64ToUint8Array(part.data.data);
167
+ }
168
+ break;
169
+ }
170
+ case 'url': {
171
+ const fetchFn = this.config.fetch ?? globalThis.fetch;
172
+ const response = await fetchFn(part.data.url.toString());
173
+ const arrayBuffer = await response.arrayBuffer();
174
+ imageBytes = new Uint8Array(arrayBuffer);
175
+ break;
176
+ }
177
+ }
178
+ if (isFullMediaType(part.mediaType)) {
179
+ imageMediaType = part.mediaType;
180
+ } else if (imageBytes !== undefined) {
181
+ const detected = detectMediaType({
182
+ data: imageBytes,
183
+ topLevelType: getTopLevelMediaType(part.mediaType),
184
+ });
185
+ if (detected !== undefined) {
186
+ imageMediaType = detected;
187
+ }
130
188
  }
131
- imageMediaType = part.mediaType;
132
189
  break;
133
190
  }
134
191
  }
@@ -152,7 +209,7 @@ export class ProdiaLanguageModel implements LanguageModelV4 {
152
209
 
153
210
  const currentDate = this.config._internal?.currentDate?.() ?? new Date();
154
211
  const combinedHeaders = combineHeaders(
155
- await resolve(this.config.headers),
212
+ this.config.headers ? await resolve(this.config.headers) : undefined,
156
213
  options.headers,
157
214
  );
158
215
 
@@ -164,7 +221,7 @@ export class ProdiaLanguageModel implements LanguageModelV4 {
164
221
  'job.json',
165
222
  );
166
223
  if (imageBytes) {
167
- const ext =
224
+ const fileExtension =
168
225
  imageMediaType === 'image/png'
169
226
  ? '.png'
170
227
  : imageMediaType === 'image/jpeg'
@@ -175,7 +232,7 @@ export class ProdiaLanguageModel implements LanguageModelV4 {
175
232
  formData.append(
176
233
  'input',
177
234
  new Blob([imageBytes], { type: imageMediaType }),
178
- 'input' + ext,
235
+ 'input' + fileExtension,
179
236
  );
180
237
  }
181
238
 
@@ -204,7 +261,7 @@ export class ProdiaLanguageModel implements LanguageModelV4 {
204
261
  content.push({
205
262
  type: 'file',
206
263
  mediaType: file.mediaType,
207
- data: file.data,
264
+ data: { type: 'data', data: file.data },
208
265
  });
209
266
  }
210
267
 
@@ -291,35 +348,6 @@ export class ProdiaLanguageModel implements LanguageModelV4 {
291
348
  }
292
349
  }
293
350
 
294
- export const prodiaLanguageModelOptionsSchema = lazySchema(() =>
295
- zodSchema(
296
- z.object({
297
- /**
298
- * Aspect ratio for the output image.
299
- */
300
- aspectRatio: z
301
- .enum([
302
- '1:1',
303
- '2:3',
304
- '3:2',
305
- '4:5',
306
- '5:4',
307
- '4:7',
308
- '7:4',
309
- '9:16',
310
- '16:9',
311
- '9:21',
312
- '21:9',
313
- ])
314
- .optional(),
315
- }),
316
- ),
317
- );
318
-
319
- export type ProdiaLanguageModelOptions = InferSchema<
320
- typeof prodiaLanguageModelOptionsSchema
321
- >;
322
-
323
351
  interface LanguageMultipartResult {
324
352
  jobResult: ProdiaJobResult;
325
353
  textContent: string | undefined;
@@ -1,15 +1,15 @@
1
1
  import {
2
+ NoSuchModelError,
2
3
  type Experimental_VideoModelV4,
3
4
  type ImageModelV4,
4
5
  type LanguageModelV4,
5
- NoSuchModelError,
6
6
  type ProviderV4,
7
7
  } from '@ai-sdk/provider';
8
- import type { FetchFunction } from '@ai-sdk/provider-utils';
9
8
  import {
10
9
  loadApiKey,
11
10
  withoutTrailingSlash,
12
11
  withUserAgentSuffix,
12
+ type FetchFunction,
13
13
  } from '@ai-sdk/provider-utils';
14
14
  import { ProdiaImageModel } from './prodia-image-model';
15
15
  import type { ProdiaImageModelId } from './prodia-image-settings';
@@ -0,0 +1,21 @@
1
+ import {
2
+ lazySchema,
3
+ zodSchema,
4
+ type InferSchema,
5
+ } from '@ai-sdk/provider-utils';
6
+ import { z } from 'zod/v4';
7
+
8
+ export const prodiaVideoModelOptionsSchema = lazySchema(() =>
9
+ zodSchema(
10
+ z.object({
11
+ /**
12
+ * Video resolution (e.g. "480p", "720p").
13
+ */
14
+ resolution: z.string().optional(),
15
+ }),
16
+ ),
17
+ );
18
+
19
+ export type ProdiaVideoModelOptions = InferSchema<
20
+ typeof prodiaVideoModelOptionsSchema
21
+ >;
@@ -2,12 +2,10 @@ import type {
2
2
  Experimental_VideoModelV4,
3
3
  SharedV4Warning,
4
4
  } from '@ai-sdk/provider';
5
- import type { InferSchema } from '@ai-sdk/provider-utils';
6
- import type { FetchFunction } from '@ai-sdk/provider-utils';
7
5
  import {
8
6
  combineHeaders,
9
7
  convertBase64ToUint8Array,
10
- lazySchema,
8
+ downloadBlob,
11
9
  parseJSON,
12
10
  parseProviderOptions,
13
11
  postFormDataToApi,
@@ -15,15 +13,15 @@ import {
15
13
  resolve,
16
14
  zodSchema,
17
15
  } from '@ai-sdk/provider-utils';
18
- import { z } from 'zod/v4';
19
- import type { ProdiaModelConfig } from './prodia-api';
20
16
  import {
21
17
  buildProdiaProviderMetadata,
22
18
  parseMultipart,
23
19
  prodiaFailedResponseHandler,
24
20
  prodiaJobResultSchema,
21
+ type ProdiaJobResult,
22
+ type ProdiaModelConfig,
25
23
  } from './prodia-api';
26
- import type { ProdiaJobResult } from './prodia-api';
24
+ import { prodiaVideoModelOptionsSchema } from './prodia-video-model-options';
27
25
  import type { ProdiaVideoModelId } from './prodia-video-model-settings';
28
26
 
29
27
  export class ProdiaVideoModel implements Experimental_VideoModelV4 {
@@ -84,7 +82,7 @@ export class ProdiaVideoModel implements Experimental_VideoModelV4 {
84
82
  // img2vid: multipart form-data request
85
83
  const imageData = await resolveVideoFileData(
86
84
  options.image,
87
- this.config.fetch,
85
+ options.abortSignal,
88
86
  );
89
87
  const formData = new FormData();
90
88
  formData.append(
@@ -161,21 +159,6 @@ export class ProdiaVideoModel implements Experimental_VideoModelV4 {
161
159
  }
162
160
  }
163
161
 
164
- export const prodiaVideoModelOptionsSchema = lazySchema(() =>
165
- zodSchema(
166
- z.object({
167
- /**
168
- * Video resolution (e.g. "480p", "720p").
169
- */
170
- resolution: z.string().optional(),
171
- }),
172
- ),
173
- );
174
-
175
- export type ProdiaVideoModelOptions = InferSchema<
176
- typeof prodiaVideoModelOptionsSchema
177
- >;
178
-
179
162
  interface VideoMultipartResult {
180
163
  jobResult: ProdiaJobResult;
181
164
  videoBytes: Uint8Array;
@@ -253,7 +236,7 @@ async function resolveVideoFileData(
253
236
  file: NonNullable<
254
237
  Parameters<Experimental_VideoModelV4['doGenerate']>[0]['image']
255
238
  >,
256
- fetchFunction?: FetchFunction,
239
+ abortSignal?: AbortSignal,
257
240
  ): Promise<{ bytes: Uint8Array; mediaType: string }> {
258
241
  if (file.type === 'file') {
259
242
  const data =
@@ -262,11 +245,12 @@ async function resolveVideoFileData(
262
245
  : file.data;
263
246
  return { bytes: data, mediaType: file.mediaType };
264
247
  }
265
- // URL type - fetch the data
266
- const response = await (fetchFunction ?? globalThis.fetch)(file.url);
267
- const arrayBuffer = await response.arrayBuffer();
268
- const mediaType =
269
- response.headers.get('content-type') ?? 'application/octet-stream';
248
+ // URL type - download via downloadBlob so the user-supplied URL is routed
249
+ // through the SSRF guard (validateDownloadUrl) instead of being fetched
250
+ // directly, preventing requests to private/internal addresses.
251
+ const blob = await downloadBlob(file.url, { abortSignal });
252
+ const arrayBuffer = await blob.arrayBuffer();
253
+ const mediaType = blob.type || 'application/octet-stream';
270
254
  return { bytes: new Uint8Array(arrayBuffer), mediaType };
271
255
  }
272
256
 
package/dist/index.d.mts DELETED
@@ -1,90 +0,0 @@
1
- import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
2
- import { InferSchema, FetchFunction } from '@ai-sdk/provider-utils';
3
- import { ProviderV4, LanguageModelV4, ImageModelV4, Experimental_VideoModelV4 } from '@ai-sdk/provider';
4
-
5
- /**
6
- * Prodia job types for image generation.
7
- */
8
- type ProdiaImageModelId = 'inference.flux-fast.schnell.txt2img.v2' | 'inference.flux.schnell.txt2img.v2' | (string & {});
9
-
10
- declare const prodiaImageModelOptionsSchema: _ai_sdk_provider_utils.LazySchema<{
11
- steps?: number | undefined;
12
- width?: number | undefined;
13
- height?: number | undefined;
14
- stylePreset?: "3d-model" | "analog-film" | "anime" | "cinematic" | "comic-book" | "digital-art" | "enhance" | "fantasy-art" | "isometric" | "line-art" | "low-poly" | "neon-punk" | "origami" | "photographic" | "pixel-art" | "texture" | "craft-clay" | undefined;
15
- loras?: string[] | undefined;
16
- progressive?: boolean | undefined;
17
- }>;
18
- type ProdiaImageModelOptions = InferSchema<typeof prodiaImageModelOptionsSchema>;
19
-
20
- /**
21
- * Prodia job types for language model (multimodal img2img).
22
- */
23
- type ProdiaLanguageModelId = 'inference.nano-banana.img2img.v2' | (string & {});
24
-
25
- declare const prodiaLanguageModelOptionsSchema: _ai_sdk_provider_utils.LazySchema<{
26
- aspectRatio?: "1:1" | "2:3" | "3:2" | "4:5" | "5:4" | "4:7" | "7:4" | "9:16" | "16:9" | "9:21" | "21:9" | undefined;
27
- }>;
28
- type ProdiaLanguageModelOptions = InferSchema<typeof prodiaLanguageModelOptionsSchema>;
29
-
30
- /**
31
- * Prodia job types for video generation.
32
- */
33
- type ProdiaVideoModelId = 'inference.wan2-2.lightning.txt2vid.v0' | 'inference.wan2-2.lightning.img2vid.v0' | (string & {});
34
-
35
- declare const prodiaVideoModelOptionsSchema: _ai_sdk_provider_utils.LazySchema<{
36
- resolution?: string | undefined;
37
- }>;
38
- type ProdiaVideoModelOptions = InferSchema<typeof prodiaVideoModelOptionsSchema>;
39
-
40
- interface ProdiaProviderSettings {
41
- /**
42
- * Prodia API key. Default value is taken from the `PRODIA_TOKEN` environment variable.
43
- */
44
- apiKey?: string;
45
- /**
46
- * Base URL for the API calls. Defaults to `https://inference.prodia.com/v2`.
47
- */
48
- baseURL?: string;
49
- /**
50
- * Custom headers to include in the requests.
51
- */
52
- headers?: Record<string, string>;
53
- /**
54
- * Custom fetch implementation. You can use it as a middleware to intercept
55
- * requests, or to provide a custom fetch implementation for e.g. testing.
56
- */
57
- fetch?: FetchFunction;
58
- }
59
- interface ProdiaProvider extends ProviderV4 {
60
- /**
61
- * Creates a language model for multimodal generation (img2img with text+image output).
62
- */
63
- languageModel(modelId: ProdiaLanguageModelId): LanguageModelV4;
64
- /**
65
- * Creates a model for image generation.
66
- */
67
- image(modelId: ProdiaImageModelId): ImageModelV4;
68
- /**
69
- * Creates a model for image generation.
70
- */
71
- imageModel(modelId: ProdiaImageModelId): ImageModelV4;
72
- /**
73
- * Creates a model for video generation.
74
- */
75
- video(modelId: ProdiaVideoModelId): Experimental_VideoModelV4;
76
- /**
77
- * Creates a model for video generation.
78
- */
79
- videoModel(modelId: ProdiaVideoModelId): Experimental_VideoModelV4;
80
- /**
81
- * @deprecated Use `embeddingModel` instead.
82
- */
83
- textEmbeddingModel(modelId: string): never;
84
- }
85
- declare function createProdia(options?: ProdiaProviderSettings): ProdiaProvider;
86
- declare const prodia: ProdiaProvider;
87
-
88
- declare const VERSION: string;
89
-
90
- export { type ProdiaImageModelId, type ProdiaImageModelOptions, type ProdiaImageModelOptions as ProdiaImageProviderOptions, type ProdiaLanguageModelId, type ProdiaLanguageModelOptions, type ProdiaProvider, type ProdiaProviderSettings, type ProdiaVideoModelId, type ProdiaVideoModelOptions, VERSION, createProdia, prodia };