@picsart/ai-sdk 6.25.0 → 6.28.0

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.
Files changed (4) hide show
  1. package/README.md +34 -0
  2. package/index.d.ts +63 -10
  3. package/index.js +150 -22
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -235,6 +235,40 @@ catalog.find({ output: 'text' })
235
235
  image/video model throws, and `generate()` throws on a text model — use the matching
236
236
  method for each.
237
237
 
238
+ ## Generic Execution — ai.run()
239
+
240
+ `run()` executes any model by id and answers the task result generically — the
241
+ model-id counterpart of `ai.apis.run()` (which is keyed by API name). It works
242
+ on every model and runs one uniform path: paramConfig validation, vendor payload
243
+ build, workflow execution (sync or async), and the model's `outputSchema` when
244
+ one is declared. The result comes back as-is in `{ result, status, usage, id }` —
245
+ no media-URL or text extraction, no Drive save. Use `generate()`/`generateText()`
246
+ when you want the parsed media/text surfaces; use `run()` when you want the raw
247
+ task result — and for `mode: 'json'` models, `run()` is the only surface:
248
+ structured-output models (judges, evaluators, classifiers) are rejected by
249
+ `generate()`, `generateText()`, and the async lifecycle.
250
+
251
+ The first json model is `typesafe-evaluate` (`Models.TypesafeEvaluate`) — LLM-judge
252
+ evaluation of any content against named questions. Type the result via the `R`
253
+ generic, same as `ai.apis.run()`:
254
+
255
+ ```typescript
256
+ interface EvaluateResult { model: string; answers: Record<string, unknown>; usage: unknown }
257
+
258
+ const { result } = await ai.run<EvaluateResult>(Models.TypesafeEvaluate, {
259
+ state: 'The weather is lovely and everyone is having a great time.',
260
+ questions: {
261
+ is_safe: { type: 'noul', instructions: 'Is this content safe for all audiences?' },
262
+ tone: { type: 'choice', instructions: 'Pick the tone.', options: ['positive', 'neutral', 'negative'] },
263
+ },
264
+ })
265
+ // result: { model: 'jev-1.13.0', answers: { is_safe: …, tone: … }, usage: { input_tokens, output_tokens } }
266
+ ```
267
+
268
+ Question ids are caller-chosen; each question is `noul` (yes/no), `choice`, or
269
+ `score`, with type-specific extras (`options`, bounds — see the
270
+ [TypeSafe docs](https://docs.typesafe.ai/api)) passed through as-is.
271
+
238
272
  ## Voice, Avatar & Template Catalogs
239
273
 
240
274
  Models with catalog-backed params (voices, avatars, effect / caption templates) serve their option lists
package/index.d.ts CHANGED
@@ -1910,6 +1910,13 @@ type ModelInputById = {
1910
1910
  videoUrl: string;
1911
1911
  model?: "Proteus" | "Artemis HQ" | "Artemis MQ" | "Artemis LQ" | "Nyx" | "Nyx Fast" | "Nyx XL" | "Nyx HF" | "Gaia HQ" | "Gaia CG" | "Gaia 2" | "Starlight Precise 2.5" | "Starlight HQ" | "Starlight Mini" | "Starlight Sharp" | "Starlight Fast 2";
1912
1912
  };
1913
+ "typesafe-evaluate": {
1914
+ state: string;
1915
+ questions: Record<string, {
1916
+ type: "noul" | "choice" | "score";
1917
+ instructions: unknown;
1918
+ } & Record<string, unknown>>;
1919
+ };
1913
1920
  "veed-fabric-v1": {
1914
1921
  prompt?: string;
1915
1922
  resolution?: "480p" | "720p";
@@ -2049,6 +2056,8 @@ type ModelInput<M extends TypedModelId> = ModelInputById[M];
2049
2056
  /** IDs of text-generation (LLM) models — narrows generateText(). */
2050
2057
  type TextModelId = "claude-fable-5" | "claude-fable-5-1" | "claude-haiku-4-5" | "claude-opus-4-8" | "claude-opus-5" | "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-sonnet-5" | "eleven-speech-to-text" | "gemini-2.5-flash" | "gemini-3-pro" | "gemini-3.5-flash-lite" | "gemini-3.6-flash" | "gemini-3.7-flash" | "gemini-3.8-flash" | "gpt-4.1-mini" | "gpt-4.1-nano" | "gpt-4o" | "gpt-4o-mini" | "gpt-5" | "gpt-5-mini" | "gpt-5.1" | "gpt-5.2" | "gpt-5.5" | "gpt-5.6-luna" | "gpt-5.6-sol" | "gpt-5.6-terra" | "gpt-6-astra" | "gpt-6-luna" | "gpt-6-sol";
2051
2058
  type TextModelInputById = Pick<ModelInputById, TextModelId>;
2059
+ /** IDs of structured-output (json-mode) models — narrows run()'s result type. */
2060
+ type JsonModelId = "typesafe-evaluate";
2052
2061
 
2053
2062
  interface ParamSchema {
2054
2063
  type: 'string' | 'number' | 'boolean' | 'file';
@@ -2260,18 +2269,34 @@ interface FileDescriptor {
2260
2269
  */
2261
2270
  maxBytes?: number;
2262
2271
  }
2272
+ /** Any value — no validation, generates as `unknown`. Only meaningful as an
2273
+ * ObjectDescriptor's `additionalProperties` (or a nested field): it marks a
2274
+ * pass-through slot whose shape the vendor owns. */
2275
+ interface UnknownDescriptor {
2276
+ kind: 'unknown';
2277
+ }
2263
2278
  interface ObjectDescriptor {
2264
2279
  kind: 'object';
2265
- /** Nested fields use the flat EntryMeta + Descriptor merge — same shape as
2280
+ /** Declared fields — flat EntryMeta + Descriptor merge, same shape as
2266
2281
  * EnumEntry / RangeEntry / etc. Authors can mark a nested field optional
2267
2282
  * by setting `required: false`. Default is required. */
2268
- fields: Record<string, EntryMeta & ParamDescriptor>;
2283
+ fields?: Record<string, EntryMeta & ParamDescriptor>;
2284
+ /**
2285
+ * JSON-Schema-style `additionalProperties`: keys beyond `fields` are
2286
+ * allowed, each value validated against this descriptor. With no `fields`
2287
+ * the object is an open-keyed dictionary (generates `Record<string, V>` —
2288
+ * e.g. question id → question object); alongside `fields` it admits
2289
+ * vendor-defined extras (generates `{ …fields } & Record<string, V>`).
2290
+ * Use `{ kind: 'unknown' }` to pass extras through unvalidated.
2291
+ * Omitted → closed shape: exactly `fields`.
2292
+ */
2293
+ additionalProperties?: ParamDescriptor;
2269
2294
  array?: {
2270
2295
  min?: number;
2271
2296
  max?: number;
2272
2297
  };
2273
2298
  }
2274
- type ParamDescriptor = EnumDescriptor<string> | EnumDescriptor<number> | CatalogDescriptor | RangeDescriptor | BooleanDescriptor | TextDescriptor | FileDescriptor | ObjectDescriptor;
2299
+ type ParamDescriptor = EnumDescriptor<string> | EnumDescriptor<number> | CatalogDescriptor | RangeDescriptor | BooleanDescriptor | TextDescriptor | FileDescriptor | ObjectDescriptor | UnknownDescriptor;
2275
2300
  interface ParamEntry {
2276
2301
  label?: string;
2277
2302
  required?: boolean;
@@ -2306,6 +2331,7 @@ type BooleanEntry = EntryMeta & BooleanDescriptor;
2306
2331
  type TextEntry = EntryMeta & TextDescriptor;
2307
2332
  type FileEntry = EntryMeta & FileDescriptor;
2308
2333
  type ObjectEntry = EntryMeta & ObjectDescriptor;
2334
+ type UnknownEntry = EntryMeta & UnknownDescriptor;
2309
2335
  /** Flat param entry with key — returned by ModelAccessor.params(). */
2310
2336
  type FlatParamEntry = EntryMeta & ParamDescriptor & {
2311
2337
  key: string;
@@ -2433,11 +2459,13 @@ interface ModelFilter {
2433
2459
  release?: ReleaseTag[];
2434
2460
  }
2435
2461
 
2436
- type AppProvider = 'picsart' | 'google' | 'kling' | 'grok' | 'openai' | 'flux' | 'ideogram' | 'elevenlabs' | 'minimax' | 'wan' | 'seedance' | 'ltx' | 'seedream' | 'seedaudio' | 'hunyuan' | 'pika' | 'runway' | 'luma' | 'ovi' | 'creatify' | 'veed' | 'bytedance' | 'qwen' | 'reve' | 'recraft' | 'videography' | 'topaz' | 'heygen' | 'happyhorse' | 'pixverse' | 'anthropic' | 'async' | 'captionsai' | 'meta';
2462
+ type AppProvider = 'picsart' | 'google' | 'kling' | 'grok' | 'openai' | 'flux' | 'ideogram' | 'elevenlabs' | 'minimax' | 'wan' | 'seedance' | 'ltx' | 'seedream' | 'seedaudio' | 'hunyuan' | 'pika' | 'runway' | 'luma' | 'ovi' | 'creatify' | 'veed' | 'bytedance' | 'qwen' | 'reve' | 'recraft' | 'videography' | 'topaz' | 'heygen' | 'happyhorse' | 'pixverse' | 'anthropic' | 'async' | 'captionsai' | 'meta' | 'typesafe';
2437
2463
  /** Provider used by model definitions. */
2438
2464
  type Provider = AppProvider;
2439
- /** App generation modes. */
2440
- type GenerationMode = 'video' | 'image' | 'audio' | 'text';
2465
+ /** App generation modes. `json` marks structured-output models (judges,
2466
+ * evaluators, classifiers) — no media URL, no extractable text; their parsed
2467
+ * result is returned as-is by `ai.run()`. */
2468
+ type GenerationMode = 'video' | 'image' | 'audio' | 'text' | 'json';
2441
2469
  /** App input types. */
2442
2470
  type InputType = 't2v' | 'i2v' | 'v2v' | 'a2v' | 't2i' | 'i2i' | 't2a' | 'v2a' | 'tts' | 'sts' | 'sfx' | 'music' | 't2t' | 'i2t' | 'v2t' | 'a2t';
2443
2471
  interface ModelFeature {
@@ -3121,6 +3149,20 @@ interface GenerateResult {
3121
3149
  /** Present when Drive is enabled and the file was saved. */
3122
3150
  drive?: DriveSaveResult;
3123
3151
  }
3152
+ /**
3153
+ * Response of {@link AiClient.run} — the same shape `ai.apis.run()` answers
3154
+ * ({ result, status, usage, id }), in the SDK's own vocabulary.
3155
+ */
3156
+ interface RunResponse<R = unknown> {
3157
+ /** The task result as-is, validated by the model's `outputSchema` when declared. */
3158
+ result: R;
3159
+ /** Always `COMPLETED` — failures throw {@link ApiError} instead. */
3160
+ status: 'COMPLETED';
3161
+ /** Credit usage reported by the platform — same structure as the pluggable APIs' GenAITaskResponse. */
3162
+ usage?: CreditUsage;
3163
+ /** The generation/job id — absent for syncExecute models (nothing to poll). */
3164
+ id?: string;
3165
+ }
3124
3166
  /** Result of a text-generation (LLM) model. */
3125
3167
  interface GenerateTextResult {
3126
3168
  /** Generated text. */
@@ -3189,13 +3231,13 @@ interface GenerateOptions {
3189
3231
  signal?: AbortSignal;
3190
3232
  /**
3191
3233
  * Poll interval for the async status loop, in ms. Overrides the model's
3192
- * `pollOptions` and the mode default (video 2s; image/audio/text 1s).
3234
+ * `pollOptions` and the mode default (video 2s; image/audio/text/json 1s).
3193
3235
  */
3194
3236
  intervalMs?: number;
3195
3237
  /**
3196
3238
  * Max poll attempts before the call throws a timeout. Overrides the model's
3197
3239
  * `pollOptions` and the mode default (video 1800 ≈ 1 hour;
3198
- * image/audio/text 1200 ≈ 20 min).
3240
+ * image/audio/text/json 1200 ≈ 20 min).
3199
3241
  */
3200
3242
  maxAttempts?: number;
3201
3243
  /** Save to a specific subfolder instead of the root (legacy — used by SDK DriveConfig). */
@@ -3213,9 +3255,19 @@ interface GenerateOptions {
3213
3255
  app?: AppIdentity;
3214
3256
  }
3215
3257
  /** Non-text (image/video/audio) model IDs — the media generation surface. */
3216
- type MediaModelId = Exclude<TypedModelId, TextModelId>;
3258
+ type MediaModelId = Exclude<TypedModelId, TextModelId | JsonModelId>;
3217
3259
  /** AI SDK client with type-safe, model-aware method signatures. */
3218
3260
  interface AiClient {
3261
+ /**
3262
+ * Run any model by id and get the task result back, generically — the
3263
+ * model-id counterpart of {@link ApisClient.run}. Works on every model:
3264
+ * builds and validates the payload from paramConfig, executes the workflow,
3265
+ * applies the model's `outputSchema` when declared, and answers the task
3266
+ * result as-is (no media-URL/text extraction, no Drive save). The only
3267
+ * generation surface for json-mode (structured-output) models. Type the
3268
+ * result via `R` (mirrors `ai.apis.run()`): `ai.run<MyResult>(id, params)`.
3269
+ */
3270
+ run<R = unknown, M extends TypedModelId = TypedModelId>(model: M, params: ModelInputById[M], options?: GenerateOptions): Promise<RunResponse<R>>;
3219
3271
  /** Generate content using a media model. Text/LLM models use generateText(). */
3220
3272
  generate<M extends MediaModelId>(model: M, params: ModelInputById[M], options?: GenerateOptions): Promise<GenerateResult>;
3221
3273
  /** Generate text using an LLM model. Returns the generated text plus the raw response. */
@@ -3518,6 +3570,7 @@ declare const Models: {
3518
3570
  readonly SpicyMayo: "spicy-mayo";
3519
3571
  readonly TopazUpscaleImage: "topaz-upscale-image";
3520
3572
  readonly TopazUpscaleVideo: "topaz-upscale-video";
3573
+ readonly TypesafeEvaluate: "typesafe-evaluate";
3521
3574
  readonly VeedFabricV1: "veed-fabric-v1";
3522
3575
  readonly VeedFabricV1Fast: "veed-fabric-v1-fast";
3523
3576
  readonly Veo31: "veo-3.1";
@@ -3674,4 +3727,4 @@ declare const getModel: (id: string) => ModelDefinition | undefined;
3674
3727
  */
3675
3728
  declare const findModel: (ref: string) => ModelDefinition | undefined;
3676
3729
 
3677
- export { ALL_MODELS, type AiClient, ApiError, type ApiErrorCode, type ApiErrorInit, type ApiResponse, type ApiRunOptions, type ApiSchemas, type ApisClient, type AppIdentity, type AppType, type AuthenticatedFetch, type AvatarOption, type BooleanDescriptor, type BooleanEntry, type CatalogDescriptor, type CatalogEntry, type CatalogItem, type CatalogPage, type CatalogPageOptions, type CatalogPreview, type CatalogQuery, type CatalogResult, type CatalogSource, type CatalogsClient, type CatalogsOptions, type ClientConfig, type CreditRange, type CreditRangeContext, type CreditTier, type CreditUsage, DEFAULT_VISIBLE_RELEASES, type DeepLinkResult, type DriveAttributes, type DriveClient, type DriveConfig, type DriveDraftInfo, type DriveFile, type DriveFileDetails, type DriveFolder, type DriveMediaItem, type DriveSaveResult, type EntryMeta, type EnumDescriptor, type EnumEntry, type EnumOption, type FileDescriptor, type FileEntry, type FlatParamEntry, type GenerateOptions, type GenerateResult, type GenerateResultItem, type GenerateResultItemMetadata, type GenerateTextResult, type GenerationContext, type GenerationEvent, GenerationEventType, type GenerationFile, type GenerationMode, type GenerationOptions, type GenerationProgress, type GenerationProvenance, type ListOptions, type MediaModelId, type MediaTypeFilter, Model, type ModelDefinition, type ModelDescriptor, type ModelFilter, type ModelInput, type ModelInputById, type ModelMeta, type ModelParams, type ModelParamsAccessor, Models, type ObjectDescriptor, type ObjectEntry, type OptionsResult, type ParamDescriptor, type ParamEntry, type ParamOption, type PayloadDriveFolderOptions, type PayloadDriveOptions, type PayloadInputsTransformationOptions, type PricingOptions, type ProviderInfo, type RangeDescriptor, type RangeEntry, type ReleaseTag, type SaveParams, type SdkPayload, type SdkTransport, type SeedanceDraftTask, type TextDescriptor, type TextEntry, type TextModelId, type TextModelInputById, type ToolUsage, type TransportPollOptions, type TransportResult, type TypedModelId, type UserReaction, type ValidationResult, type VoiceOption, type WorkflowJobHandle, type WorkflowSubmitRequest, buildFilename, buildGenerationAttributes, catalog, createClient, decodeDeepLinkPayload, encodeDeepLinkPayload, expectedOutputFormat, findModel, getModel, getModelsByMode, getVoiceById, inferResourceType, isVisibleForReleases, parseGeneration, releaseOf, resolveExtension, toAvatarOption, toVoiceOption };
3730
+ export { ALL_MODELS, type AiClient, ApiError, type ApiErrorCode, type ApiErrorInit, type ApiResponse, type ApiRunOptions, type ApiSchemas, type ApisClient, type AppIdentity, type AppType, type AuthenticatedFetch, type AvatarOption, type BooleanDescriptor, type BooleanEntry, type CatalogDescriptor, type CatalogEntry, type CatalogItem, type CatalogPage, type CatalogPageOptions, type CatalogPreview, type CatalogQuery, type CatalogResult, type CatalogSource, type CatalogsClient, type CatalogsOptions, type ClientConfig, type CreditRange, type CreditRangeContext, type CreditTier, type CreditUsage, DEFAULT_VISIBLE_RELEASES, type DeepLinkResult, type DriveAttributes, type DriveClient, type DriveConfig, type DriveDraftInfo, type DriveFile, type DriveFileDetails, type DriveFolder, type DriveMediaItem, type DriveSaveResult, type EntryMeta, type EnumDescriptor, type EnumEntry, type EnumOption, type FileDescriptor, type FileEntry, type FlatParamEntry, type GenerateOptions, type GenerateResult, type GenerateResultItem, type GenerateResultItemMetadata, type GenerateTextResult, type GenerationContext, type GenerationEvent, GenerationEventType, type GenerationFile, type GenerationMode, type GenerationOptions, type GenerationProgress, type GenerationProvenance, type JsonModelId, type ListOptions, type MediaModelId, type MediaTypeFilter, Model, type ModelDefinition, type ModelDescriptor, type ModelFilter, type ModelInput, type ModelInputById, type ModelMeta, type ModelParams, type ModelParamsAccessor, Models, type ObjectDescriptor, type ObjectEntry, type OptionsResult, type ParamDescriptor, type ParamEntry, type ParamOption, type PayloadDriveFolderOptions, type PayloadDriveOptions, type PayloadInputsTransformationOptions, type PricingOptions, type ProviderInfo, type RangeDescriptor, type RangeEntry, type ReleaseTag, type RunResponse, type SaveParams, type SdkPayload, type SdkTransport, type SeedanceDraftTask, type TextDescriptor, type TextEntry, type TextModelId, type TextModelInputById, type ToolUsage, type TransportPollOptions, type TransportResult, type TypedModelId, type UnknownDescriptor, type UnknownEntry, type UserReaction, type ValidationResult, type VoiceOption, type WorkflowJobHandle, type WorkflowSubmitRequest, buildFilename, buildGenerationAttributes, catalog, createClient, decodeDeepLinkPayload, encodeDeepLinkPayload, expectedOutputFormat, findModel, getModel, getModelsByMode, getVoiceById, inferResourceType, isVisibleForReleases, parseGeneration, releaseOf, resolveExtension, toAvatarOption, toVoiceOption };
package/index.js CHANGED
@@ -566,12 +566,22 @@ function validateDescriptor(key, d, val, required) {
566
566
  `"${key}" allows at most ${d.array.max} items`
567
567
  );
568
568
  }
569
+ const declared = d.fields ?? {};
569
570
  for (const item of items) {
570
571
  if (item == null || typeof item !== "object" || Array.isArray(item)) {
571
- throw new Error(`"${key}" items must be objects`);
572
+ throw new Error(d.array ? `"${key}" items must be objects` : `"${key}" must be an object`);
572
573
  }
573
- for (const [fk, fd] of Object.entries(d.fields)) {
574
- validateDescriptor(`${key}.${fk}`, fd, item[fk]);
574
+ if (required && !d.array && d.additionalProperties && Object.keys(declared).length === 0 && Object.keys(item).length === 0) {
575
+ throw new Error(`"${key}" is required`);
576
+ }
577
+ for (const [fk, fd] of Object.entries(declared)) {
578
+ validateDescriptor(`${key}.${fk}`, fd, item[fk], fd.required);
579
+ }
580
+ if (d.additionalProperties) {
581
+ for (const [ek, ev] of Object.entries(item)) {
582
+ if (ek in declared) continue;
583
+ validateDescriptor(`${key}.${ek}`, d.additionalProperties, ev, true);
584
+ }
575
585
  }
576
586
  }
577
587
  break;
@@ -784,7 +794,8 @@ var providers = {
784
794
  anthropic: { color: "#D97757", label: "CL", name: "Anthropic" },
785
795
  async: { color: "#5E5CE6", label: "AA", name: "Async AI" },
786
796
  captionsai: { color: "#1D1F20", label: "MR", name: "Mirage" },
787
- meta: { color: "#0081FB", label: "MT", name: "Meta" }
797
+ meta: { color: "#0081FB", label: "MT", name: "Meta" },
798
+ typesafe: { color: "#3E6B8F", label: "TS", name: "TypeSafe" }
788
799
  };
789
800
 
790
801
  // src/core/descriptors/presets.ts
@@ -1162,7 +1173,7 @@ var passthroughPayload = (paramConfig) => (ctx) => {
1162
1173
  return payload;
1163
1174
  };
1164
1175
  function defineModels(provider, configs) {
1165
- const MODELS38 = [];
1176
+ const MODELS39 = [];
1166
1177
  for (const c of configs) {
1167
1178
  const prov = c.provider ?? provider;
1168
1179
  const resolvedPayload = c.buildPayload ?? passthroughPayload(c.paramConfig);
@@ -1198,19 +1209,19 @@ function defineModels(provider, configs) {
1198
1209
  if (c.constraints !== void 0) model.constraints = c.constraints;
1199
1210
  const contract = createModelContract(model);
1200
1211
  model.outputSchema = c.outputSchema ?? contract.output;
1201
- MODELS38.push(model);
1212
+ MODELS39.push(model);
1202
1213
  }
1203
- return { MODELS: MODELS38 };
1214
+ return { MODELS: MODELS39 };
1204
1215
  }
1205
- function registerPayloads(MODELS38, payloads) {
1216
+ function registerPayloads(MODELS39, payloads) {
1206
1217
  for (const [id, builder] of Object.entries(payloads)) {
1207
- const model = MODELS38.find((m) => m.id === id);
1218
+ const model = MODELS39.find((m) => m.id === id);
1208
1219
  if (model) model.buildPayload = builder;
1209
1220
  }
1210
1221
  }
1211
- function registerEditPayloads(MODELS38, payloads) {
1222
+ function registerEditPayloads(MODELS39, payloads) {
1212
1223
  for (const [id, builder] of Object.entries(payloads)) {
1213
- const model = MODELS38.find((m) => m.id === id);
1224
+ const model = MODELS39.find((m) => m.id === id);
1214
1225
  if (model) model.buildEditPayload = builder;
1215
1226
  }
1216
1227
  }
@@ -4176,6 +4187,10 @@ var SEEDANCE_25_VIDEO_BOUNDS = {
4176
4187
  maxDurationSec: SEEDANCE_25_MAX_MEDIA_SEC,
4177
4188
  maxFrameRate: SEEDANCE_MAX_FRAME_RATE
4178
4189
  };
4190
+ var SEEDANCE_25_EDIT_SOURCE_BOUNDS = {
4191
+ ...SEEDANCE_25_VIDEO_BOUNDS,
4192
+ minDurationSec: 4
4193
+ };
4179
4194
  var SEEDANCE_20_VIDEO_BOUNDS = {
4180
4195
  minAspectRatio: SEEDANCE_MIN_ASPECT_RATIO,
4181
4196
  maxAspectRatio: SEEDANCE_MAX_ASPECT_RATIO,
@@ -4658,7 +4673,7 @@ var { MODELS: MODELS13 } = defineModels("bytedance", [
4658
4673
  ...seedance25DraftParam,
4659
4674
  // Every limit rides in `bounds`; the positional maxDuration / maxShortSide
4660
4675
  // / maxBytes args predate it and are skipped rather than duplicated.
4661
- ...params.videoInput("Source Video", "reference", true, void 0, void 0, void 0, SEEDANCE_25_VIDEO_BOUNDS),
4676
+ ...params.videoInput("Source Video", "reference", true, void 0, void 0, void 0, SEEDANCE_25_EDIT_SOURCE_BOUNDS),
4662
4677
  ...params.imageInput(30, "Reference Images", false, "reference", SEEDANCE_IMAGE_BOUNDS)
4663
4678
  }
4664
4679
  },
@@ -4690,7 +4705,7 @@ var { MODELS: MODELS13 } = defineModels("bytedance", [
4690
4705
  ...seedance25DraftParam,
4691
4706
  // Every limit rides in `bounds`; the positional maxDuration / maxShortSide
4692
4707
  // / maxBytes args predate it and are skipped rather than duplicated.
4693
- ...params.videoInput("Source Video", "reference", true, void 0, void 0, void 0, SEEDANCE_25_VIDEO_BOUNDS),
4708
+ ...params.videoInput("Source Video", "reference", true, void 0, void 0, void 0, SEEDANCE_25_EDIT_SOURCE_BOUNDS),
4694
4709
  ...params.imageInput(30, "Reference Images", false, "reference", SEEDANCE_IMAGE_BOUNDS)
4695
4710
  }
4696
4711
  },
@@ -7674,7 +7689,7 @@ var buildElevenLabsDialoguePayload = (catalogId, modelId) => (input) => {
7674
7689
  };
7675
7690
  function dialogueCharacterCap(catalogId) {
7676
7691
  const descriptor = MODELS24.find((m) => m.id === catalogId)?.paramConfig.dialogue?.descriptor;
7677
- const text = descriptor?.kind === "object" ? descriptor.fields.text : void 0;
7692
+ const text = descriptor?.kind === "object" ? descriptor.fields?.text : void 0;
7678
7693
  const cap = text && "maxLength" in text ? text.maxLength : void 0;
7679
7694
  if (typeof cap !== "number") {
7680
7695
  throw new Error(`${catalogId}: dialogue entry declares no per-line maxLength to derive the cap from`);
@@ -10652,6 +10667,77 @@ registerEditPayloads(MODELS37, {
10652
10667
  "muse-image-1.0": buildMuseImageEditPayload
10653
10668
  });
10654
10669
 
10670
+ // src/vendors/catalog/typesafe.ts
10671
+ var evaluateOutputSchema = {
10672
+ parse(output) {
10673
+ const obj = output;
10674
+ if (!obj || typeof obj.answers !== "object" || obj.answers == null) {
10675
+ throw new Error("No answers in TypeSafe evaluate response");
10676
+ }
10677
+ return output;
10678
+ }
10679
+ };
10680
+ var { MODELS: MODELS38 } = defineModels("typesafe", [
10681
+ {
10682
+ id: "typesafe-evaluate",
10683
+ name: "Jev",
10684
+ workflow: "typesafe/v1/systemone/evaluate",
10685
+ addedAt: "2026-10-05",
10686
+ modelId: "jev-latest",
10687
+ estimatedTime: 6,
10688
+ badge: ["new"],
10689
+ mode: "json",
10690
+ inputType: "t2t",
10691
+ outputSchema: evaluateOutputSchema,
10692
+ description: "Evaluate content against named questions (yes/no, choice, score) and get structured answers back.",
10693
+ features: [feat("Structured Output", "characteristic")],
10694
+ paramConfig: {
10695
+ ...p.text("state", { label: "Content", required: true }),
10696
+ questions: {
10697
+ label: "Questions",
10698
+ required: true,
10699
+ // Dictionary of caller-chosen question ids → question objects.
10700
+ descriptor: {
10701
+ kind: "object",
10702
+ additionalProperties: {
10703
+ kind: "object",
10704
+ fields: {
10705
+ type: {
10706
+ kind: "enum",
10707
+ valueType: "string",
10708
+ default: "noul",
10709
+ required: true,
10710
+ options: [
10711
+ { id: "noul", label: "Yes/No" },
10712
+ { id: "choice", label: "Choice" },
10713
+ { id: "score", label: "Score" }
10714
+ ]
10715
+ },
10716
+ // Plain string or a structured instruction object — the shape is
10717
+ // vendor-defined (see https://docs.typesafe.ai/api), so only
10718
+ // presence is enforced here.
10719
+ instructions: { kind: "unknown", required: true }
10720
+ },
10721
+ // Choice options, score bounds, etc. are question-type-specific —
10722
+ // see https://docs.typesafe.ai/api; pass them through unvalidated.
10723
+ additionalProperties: { kind: "unknown" }
10724
+ }
10725
+ }
10726
+ }
10727
+ }
10728
+ }
10729
+ ]);
10730
+
10731
+ // src/vendors/catalog/typesafe.payloads.ts
10732
+ var buildEvaluatePayload = (input) => ({
10733
+ state: input.state,
10734
+ model: "jev-latest",
10735
+ questions: input.questions
10736
+ });
10737
+ registerPayloads(MODELS38, {
10738
+ "typesafe-evaluate": buildEvaluatePayload
10739
+ });
10740
+
10655
10741
  // src/vendors/catalog/creatify.payloads.ts
10656
10742
  var buildCreatifyBorealPayload = (input) => ({
10657
10743
  prompt: input.prompt,
@@ -10806,7 +10892,8 @@ var ALL_MODELS = [
10806
10892
  ...MODELS34,
10807
10893
  ...MODELS35,
10808
10894
  ...MODELS36,
10809
- ...MODELS37
10895
+ ...MODELS37,
10896
+ ...MODELS38
10810
10897
  ];
10811
10898
  var getModelsByMode = (mode, includeHidden = false) => ALL_MODELS.filter((m) => m.mode === mode && (includeHidden || isVisibleForReleases(m)));
10812
10899
 
@@ -12352,6 +12439,24 @@ function parseTextResult(completed, model) {
12352
12439
  }
12353
12440
  return { text, model: model.id, raw: completed.raw ?? completed.result, usage: completed.usage };
12354
12441
  }
12442
+ function parseRunResult(completed, model, contract) {
12443
+ throwIfErrorResult(completed.result, model.name);
12444
+ throwIfErrorResult(completed.raw, model.name);
12445
+ const result = contract?.output ? contract.output.parse(completed.result) : completed.result;
12446
+ if (result == null) {
12447
+ throw new ApiError(`${model.name}: unexpected response \u2014 empty result`, {
12448
+ status: 502,
12449
+ code: "invalid_response"
12450
+ });
12451
+ }
12452
+ return {
12453
+ result,
12454
+ status: "COMPLETED",
12455
+ usage: completed.usage,
12456
+ // Sync executions have no job id (nothing to poll) — omit rather than ''.
12457
+ ...completed.handle.id ? { id: completed.handle.id } : {}
12458
+ };
12459
+ }
12355
12460
 
12356
12461
  // src/core/limits.ts
12357
12462
  var MAX_DRIVE_PROMPT_LENGTH = 18e3;
@@ -13128,6 +13233,7 @@ var GenerationEventType = {
13128
13233
  };
13129
13234
 
13130
13235
  // src/client/index.ts
13236
+ var MEDIA_MODES = /* @__PURE__ */ new Set(["video", "image", "audio"]);
13131
13237
  var MODE_POLL_DEFAULTS = {
13132
13238
  video: { intervalMs: 2e3, maxAttempts: 1800 },
13133
13239
  // 2s × 1800 = 1 hour
@@ -13135,7 +13241,9 @@ var MODE_POLL_DEFAULTS = {
13135
13241
  // 1s × 1200 = 20 min
13136
13242
  audio: { intervalMs: 1e3, maxAttempts: 1200 },
13137
13243
  // 1s × 1200 = 20 min
13138
- text: { intervalMs: 1e3, maxAttempts: 1200 }
13244
+ text: { intervalMs: 1e3, maxAttempts: 1200 },
13245
+ // 1s × 1200 = 20 min
13246
+ json: { intervalMs: 1e3, maxAttempts: 1200 }
13139
13247
  // 1s × 1200 = 20 min
13140
13248
  };
13141
13249
  function resolvePollOptions(model, overrides) {
@@ -13193,13 +13301,16 @@ function createClient(config) {
13193
13301
  if (!transport.submit) throw unsupportedTransport("submit");
13194
13302
  if (!transport.poll) throw unsupportedTransport("polling");
13195
13303
  }
13304
+ function isMediaModel(model) {
13305
+ return MEDIA_MODES.has(model.mode);
13306
+ }
13196
13307
  function assertMediaModel(model) {
13197
- if (model.mode === "text") {
13198
- throw new ApiError(`${model.name} is a text model \u2014 use generateText() instead.`, {
13199
- status: 400,
13200
- code: "wrong_model_mode"
13201
- });
13202
- }
13308
+ if (isMediaModel(model)) return;
13309
+ const alternative = model.mode === "text" ? "generateText()" : "run()";
13310
+ throw new ApiError(`${model.name} is a ${model.mode} model \u2014 use ${alternative} instead.`, {
13311
+ status: 400,
13312
+ code: "wrong_model_mode"
13313
+ });
13203
13314
  }
13204
13315
  async function submitJob(workflow, payload, signal) {
13205
13316
  if (signal?.aborted) {
@@ -13282,6 +13393,21 @@ function createClient(config) {
13282
13393
  }
13283
13394
  return {
13284
13395
  // ── Simple path ──────────────────────────────────────────────────
13396
+ /**
13397
+ * Run any model by id and get the task result back, generically — the
13398
+ * model-id counterpart of `ai.apis.run()`. Works on every model: builds
13399
+ * and validates the payload from paramConfig, executes the workflow
13400
+ * (sync or async), applies the model's `outputSchema` when declared, and
13401
+ * returns the task result as-is — no media-URL or text extraction, no
13402
+ * Drive save, no options injection. The only generation surface for
13403
+ * json-mode (structured-output) models.
13404
+ */
13405
+ async run(model, params2, options) {
13406
+ const resolved = resolveModel(model);
13407
+ const { workflow, payload, contract } = prepareRequest(resolved, params2);
13408
+ const completed = await executeModel(resolved, workflow, payload, options);
13409
+ return parseRunResult(completed, resolved, contract);
13410
+ },
13285
13411
  /**
13286
13412
  * Generate content using a model.
13287
13413
  *
@@ -13705,6 +13831,7 @@ var Seedream50Pro = "seedream-5.0-pro";
13705
13831
  var SpicyMayo = "spicy-mayo";
13706
13832
  var TopazUpscaleImage = "topaz-upscale-image";
13707
13833
  var TopazUpscaleVideo = "topaz-upscale-video";
13834
+ var TypesafeEvaluate = "typesafe-evaluate";
13708
13835
  var VeedFabricV1 = "veed-fabric-v1";
13709
13836
  var VeedFabricV1Fast = "veed-fabric-v1-fast";
13710
13837
  var Veo31 = "veo-3.1";
@@ -13961,6 +14088,7 @@ var Models = {
13961
14088
  SpicyMayo,
13962
14089
  TopazUpscaleImage,
13963
14090
  TopazUpscaleVideo,
14091
+ TypesafeEvaluate,
13964
14092
  VeedFabricV1,
13965
14093
  VeedFabricV1Fast,
13966
14094
  Veo31,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@picsart/ai-sdk",
3
- "version": "6.25.0",
3
+ "version": "6.28.0",
4
4
  "type": "module",
5
5
  "description": "Type-safe SDK for 100+ AI models — image, video, audio, and text generation with Picsart",
6
6
  "license": "MIT",