@picsart/ai-sdk 1.138.1 → 1.140.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/_cli.js +40 -69
  2. package/index.d.ts +11 -16
  3. package/index.js +40 -63
  4. package/package.json +1 -1
package/_cli.js CHANGED
@@ -583,8 +583,14 @@ function validateDescriptor(key, d, val, required) {
583
583
  }
584
584
  break;
585
585
  case "file":
586
- if (d.accept === "image" && key !== "startFrame" && key !== "endFrame") {
586
+ if (d.array) {
587
587
  if (!Array.isArray(val)) throw new Error(`"${key}" must be an array of URLs`);
588
+ if (d.array.min != null && val.length < d.array.min) {
589
+ throw new Error(`"${key}" needs at least ${d.array.min} items`);
590
+ }
591
+ if (d.array.max != null && val.length > d.array.max) {
592
+ throw new Error(`"${key}" allows at most ${d.array.max} items`);
593
+ }
588
594
  } else {
589
595
  if (typeof val !== "string") throw new Error(`"${key}" must be a string URL`);
590
596
  }
@@ -907,7 +913,7 @@ var init_presets = __esm({
907
913
  descriptor: {
908
914
  kind: "file",
909
915
  accept,
910
- max: opts?.max ?? 1
916
+ ...opts?.array ? { array: opts.array } : {}
911
917
  }
912
918
  }
913
919
  };
@@ -1103,7 +1109,7 @@ var init_define = __esm({
1103
1109
  videoId: p.videoId,
1104
1110
  language: p.language,
1105
1111
  // File presets — key matches the runtime GenerationContext field name:
1106
- imageInput: (max = 1, label = "Start Image", required = false) => p.file("imageUrls", "image", { max, label, required }),
1112
+ imageInput: (max = 1, label = "Start Image", required = false) => p.file("imageUrls", "image", { array: { max }, label, required }),
1107
1113
  videoInput: (label = "Source Video") => p.file("videoUrl", "video", { label, required: true }),
1108
1114
  audioInput: (label = "Audio Track", required = false) => p.file("audioUrl", "audio", { label, required }),
1109
1115
  startFrame: (label = "Start Frame", required = false) => p.file("startFrame", "image", { label, required }),
@@ -2552,7 +2558,6 @@ var init_wan = __esm({
2552
2558
  estimatedTime: 26,
2553
2559
  mode: "video",
2554
2560
  inputType: "v2v",
2555
- disabled: true,
2556
2561
  badge: ["popular", "new"],
2557
2562
  description: "Wan 2.7 Video Edit \u2014 restyle or modify existing video with reference images.",
2558
2563
  features: [feat("Video Input", "input"), feat("Image Input", "input"), feat("1080P", "resolution")],
@@ -4276,7 +4281,7 @@ var init_elevenlabs = __esm({
4276
4281
  buildPayload: buildElevenLabsSTSPayload,
4277
4282
  toolId: "audio-gen.eleven-sts-v2",
4278
4283
  creditPrice: { "audio-gen.eleven-sts-v2": 1 },
4279
- pricingUnit: "per_second",
4284
+ pricingUnit: "per_minute",
4280
4285
  estimatedTime: 15,
4281
4286
  mode: "audio",
4282
4287
  inputType: "sts",
@@ -5353,6 +5358,7 @@ var init_picsart = __esm({
5353
5358
  buildPayload: buildRemoveBgPayload,
5354
5359
  toolId: "image-to-image.picsart-sod",
5355
5360
  creditPrice: { "image-to-image.picsart-sod": 1 },
5361
+ pricingUnit: "per_image",
5356
5362
  outputSchema: sodOutputSchema,
5357
5363
  mode: "image",
5358
5364
  inputType: "i2i",
@@ -5367,6 +5373,7 @@ var init_picsart = __esm({
5367
5373
  buildPayload: buildEnhancePayload,
5368
5374
  toolId: "image-to-image.picsart-enhance",
5369
5375
  creditPrice: { "image-to-image.picsart-enhance": 1 },
5376
+ pricingUnit: "per_image",
5370
5377
  mode: "image",
5371
5378
  inputType: "i2i",
5372
5379
  estimatedTime: 30,
@@ -6263,11 +6270,19 @@ function createClient(config) {
6263
6270
  const completed = await executeModel(resolved, workflow, finalPayload, options?.signal);
6264
6271
  return parseResult(completed, resolved, contract);
6265
6272
  },
6273
+ /** @deprecated Use `getCredits()` instead. */
6274
+ async estimate(model, params2) {
6275
+ if (!transport.options) return null;
6276
+ const resolved = resolveModel(model);
6277
+ const { workflow, payload } = prepareRequest(resolved, params2);
6278
+ return await transport.options(workflow, payload) ?? null;
6279
+ },
6266
6280
  /**
6267
- * Estimate credit cost for a generation.
6281
+ * Get exact credit cost for a model with specific parameters.
6282
+ * Calls the backend /options endpoint for real-time pricing.
6268
6283
  * Returns null if pricing is unavailable.
6269
6284
  */
6270
- async estimate(model, params2) {
6285
+ async getCredits(model, params2) {
6271
6286
  if (!transport.options) return null;
6272
6287
  const resolved = resolveModel(model);
6273
6288
  const { workflow, payload } = prepareRequest(resolved, params2);
@@ -6361,52 +6376,6 @@ var init_client = __esm({
6361
6376
  }
6362
6377
  });
6363
6378
 
6364
- // src/core/descriptors/param-access.ts
6365
- function getEnumOptions(model, key) {
6366
- const entry = model.paramConfig[key];
6367
- if (!entry) return null;
6368
- const d = entry.descriptor;
6369
- if (d.kind === "enum") {
6370
- return d.options.map((o) => o.id);
6371
- }
6372
- return null;
6373
- }
6374
- function getDefault(model, key) {
6375
- const entry = model.paramConfig[key];
6376
- if (!entry) return void 0;
6377
- const d = entry.descriptor;
6378
- return "default" in d ? d.default : void 0;
6379
- }
6380
- function getRange(model, key) {
6381
- const entry = model.paramConfig[key];
6382
- if (!entry) return null;
6383
- const d = entry.descriptor;
6384
- if (d.kind === "range") {
6385
- const r = d;
6386
- return { min: r.min, max: r.max, step: r.step, default: r.default };
6387
- }
6388
- return null;
6389
- }
6390
- function getFileParam(model, key) {
6391
- const entry = model.paramConfig[key];
6392
- if (!entry) return null;
6393
- const d = entry.descriptor;
6394
- if (d.kind === "file") {
6395
- const f = d;
6396
- return {
6397
- required: entry.required ?? false,
6398
- max: f.max,
6399
- label: entry.label,
6400
- accept: f.accept
6401
- };
6402
- }
6403
- return null;
6404
- }
6405
- var init_param_access = __esm({
6406
- "src/core/descriptors/param-access.ts"() {
6407
- }
6408
- });
6409
-
6410
6379
  // src/core/descriptors/model-accessor.ts
6411
6380
  function _model(id) {
6412
6381
  return new ModelDescriptorImpl(resolveModel(id));
@@ -6431,7 +6400,6 @@ function _search(query) {
6431
6400
  var ModelParamsAccessorImpl, ModelMetaImpl, ModelDescriptorImpl, Model;
6432
6401
  var init_model_accessor = __esm({
6433
6402
  "src/core/descriptors/model-accessor.ts"() {
6434
- init_param_access();
6435
6403
  init_utils();
6436
6404
  init_resolve();
6437
6405
  init_catalog();
@@ -6441,7 +6409,10 @@ var init_model_accessor = __esm({
6441
6409
  this.def = def;
6442
6410
  }
6443
6411
  param(key) {
6444
- return this.def.paramConfig[key];
6412
+ const entry = this.def.paramConfig[key];
6413
+ if (!entry) return void 0;
6414
+ const { descriptor, ...meta } = entry;
6415
+ return { ...meta, ...descriptor };
6445
6416
  }
6446
6417
  hasParam(key) {
6447
6418
  return key in this.def.paramConfig;
@@ -6494,19 +6465,19 @@ var init_model_accessor = __esm({
6494
6465
  return Object.values(this.def.paramConfig).some((e) => e.descriptor.kind === "file");
6495
6466
  }
6496
6467
  getDefault(key) {
6497
- return getDefault(this.def, key);
6468
+ const entry = this.def.paramConfig[key];
6469
+ if (!entry) return void 0;
6470
+ const d = entry.descriptor;
6471
+ return "default" in d ? d.default : void 0;
6498
6472
  }
6499
6473
  getDefaults() {
6500
6474
  return extractDefaults(this.def.paramConfig);
6501
6475
  }
6476
+ /** @deprecated Use `enum(key)` instead. */
6502
6477
  getEnumOptions(key) {
6503
- return getEnumOptions(this.def, key);
6504
- }
6505
- getRange(key) {
6506
- return getRange(this.def, key);
6507
- }
6508
- getFileParam(key) {
6509
- return getFileParam(this.def, key);
6478
+ const entry = this.def.paramConfig[key];
6479
+ if (!entry || entry.descriptor.kind !== "enum") return null;
6480
+ return entry.descriptor.options.map((o) => o.id);
6510
6481
  }
6511
6482
  toSchema() {
6512
6483
  return descriptorsToSchema(this.def.paramConfig);
@@ -6516,9 +6487,8 @@ var init_model_accessor = __esm({
6516
6487
  }
6517
6488
  narrow(key, kind) {
6518
6489
  const entry = this.param(key);
6519
- if (!entry || entry.descriptor.kind !== kind) return void 0;
6520
- const { descriptor, ...meta } = entry;
6521
- return { ...meta, ...descriptor };
6490
+ if (!entry || entry.kind !== kind) return void 0;
6491
+ return entry;
6522
6492
  }
6523
6493
  };
6524
6494
  ModelMetaImpl = class {
@@ -6880,9 +6850,11 @@ var init_model_constants = __esm({
6880
6850
  toSchema(id) {
6881
6851
  return Model(id).params().toSchema();
6882
6852
  },
6883
- /** @deprecated Use `Model(id).params().getFileParam(key)` instead. */
6853
+ /** @deprecated Use `Model(id).params().file(key)` instead. */
6884
6854
  getFileParam(id, key) {
6885
- return Model(id).params().getFileParam(key);
6855
+ const f = Model(id).params().file(key);
6856
+ if (!f) return null;
6857
+ return { required: f.required ?? false, max: f.array?.max ?? 1, label: f.label, accept: f.accept };
6886
6858
  },
6887
6859
  /** @deprecated Use `Model(id).params().hasParam(key)` instead. */
6888
6860
  hasParam(id, key) {
@@ -6897,7 +6869,6 @@ var init_descriptors = __esm({
6897
6869
  "src/core/descriptors/index.ts"() {
6898
6870
  init_utils();
6899
6871
  init_presets();
6900
- init_param_access();
6901
6872
  init_model_accessor();
6902
6873
  }
6903
6874
  });
package/index.d.ts CHANGED
@@ -940,8 +940,10 @@ interface GenerateOptions {
940
940
  interface AiClient {
941
941
  /** Generate content using a model. Params are type-checked against the model's schema. */
942
942
  generate<M extends TypedModelId>(model: M, params: ModelInputById[M], options?: GenerateOptions): Promise<GenerateResult>;
943
- /** Estimate credit cost for a generation. */
943
+ /** @deprecated Use `getCredits()` instead. */
944
944
  estimate<M extends TypedModelId>(model: M, params: ModelInputById[M]): Promise<number | null>;
945
+ /** Get exact credit cost for a model with specific parameters. */
946
+ getCredits<M extends TypedModelId>(model: M, params: ModelInputById[M]): Promise<number | null>;
945
947
  /** Submit a generation job and get a handle back. */
946
948
  submit<M extends TypedModelId>(model: M, params: ModelInputById[M], options?: GenerateOptions): Promise<WorkflowJobHandle>;
947
949
  /** Check the current status of a submitted job. */
@@ -1122,7 +1124,11 @@ interface TextDescriptor {
1122
1124
  interface FileDescriptor {
1123
1125
  kind: 'file';
1124
1126
  accept: 'image' | 'video' | 'audio' | 'media';
1125
- max: number;
1127
+ /** Present = array; absent = single. `min`/`max` bound the array length. */
1128
+ array?: {
1129
+ min?: number;
1130
+ max?: number;
1131
+ };
1126
1132
  }
1127
1133
  interface ObjectDescriptor {
1128
1134
  kind: 'object';
@@ -1175,7 +1181,7 @@ interface ModelMeta {
1175
1181
  }
1176
1182
  /** Parameter operations — fluent access to model params, schemas, defaults. */
1177
1183
  interface ModelParamsAccessor {
1178
- param(key: string): ParamEntry | undefined;
1184
+ param(key: string): (EntryMeta & ParamDescriptor) | undefined;
1179
1185
  hasParam(key: string): boolean;
1180
1186
  all(): FlatParamEntry[];
1181
1187
  enum(key: string): EnumEntry | undefined;
@@ -1193,19 +1199,8 @@ interface ModelParamsAccessor {
1193
1199
  hasFileInput(): boolean;
1194
1200
  getDefault(key: string): unknown;
1195
1201
  getDefaults(): Record<string, unknown>;
1202
+ /** @deprecated Use `enum(key)` instead — returns full `EnumEntry` with `.options`, `.default`, etc. */
1196
1203
  getEnumOptions(key: string): (string | number)[] | null;
1197
- getRange(key: string): {
1198
- min: number;
1199
- max: number;
1200
- step?: number;
1201
- default: number;
1202
- } | null;
1203
- getFileParam(key: string): {
1204
- required: boolean;
1205
- max: number;
1206
- label?: string;
1207
- accept?: string;
1208
- } | null;
1209
1204
  toSchema(): ModelParamSchema;
1210
1205
  transferValues(prev: Record<string, unknown>): Record<string, unknown>;
1211
1206
  }
@@ -1579,7 +1574,7 @@ declare const Models: {
1579
1574
  readonly validate: (model: string, input: unknown) => ValidationResult;
1580
1575
  /** @deprecated Use `Model(id).params().toSchema()` instead. */
1581
1576
  readonly toSchema: (id: string) => ModelParamSchema;
1582
- /** @deprecated Use `Model(id).params().getFileParam(key)` instead. */
1577
+ /** @deprecated Use `Model(id).params().file(key)` instead. */
1583
1578
  readonly getFileParam: (id: string, key: string) => {
1584
1579
  required: boolean;
1585
1580
  max: number;
package/index.js CHANGED
@@ -176,8 +176,14 @@ function validateDescriptor(key, d, val, required) {
176
176
  }
177
177
  break;
178
178
  case "file":
179
- if (d.accept === "image" && key !== "startFrame" && key !== "endFrame") {
179
+ if (d.array) {
180
180
  if (!Array.isArray(val)) throw new Error(`"${key}" must be an array of URLs`);
181
+ if (d.array.min != null && val.length < d.array.min) {
182
+ throw new Error(`"${key}" needs at least ${d.array.min} items`);
183
+ }
184
+ if (d.array.max != null && val.length > d.array.max) {
185
+ throw new Error(`"${key}" allows at most ${d.array.max} items`);
186
+ }
181
187
  } else {
182
188
  if (typeof val !== "string") throw new Error(`"${key}" must be a string URL`);
183
189
  }
@@ -488,7 +494,7 @@ var p = {
488
494
  descriptor: {
489
495
  kind: "file",
490
496
  accept,
491
- max: opts?.max ?? 1
497
+ ...opts?.array ? { array: opts.array } : {}
492
498
  }
493
499
  }
494
500
  };
@@ -668,7 +674,7 @@ var params = {
668
674
  videoId: p.videoId,
669
675
  language: p.language,
670
676
  // File presets — key matches the runtime GenerationContext field name:
671
- imageInput: (max = 1, label = "Start Image", required = false) => p.file("imageUrls", "image", { max, label, required }),
677
+ imageInput: (max = 1, label = "Start Image", required = false) => p.file("imageUrls", "image", { array: { max }, label, required }),
672
678
  videoInput: (label = "Source Video") => p.file("videoUrl", "video", { label, required: true }),
673
679
  audioInput: (label = "Audio Track", required = false) => p.file("audioUrl", "audio", { label, required }),
674
680
  startFrame: (label = "Start Frame", required = false) => p.file("startFrame", "image", { label, required }),
@@ -2056,7 +2062,6 @@ var { MODELS: MODELS10} = defineModels("wan", [
2056
2062
  estimatedTime: 26,
2057
2063
  mode: "video",
2058
2064
  inputType: "v2v",
2059
- disabled: true,
2060
2065
  badge: ["popular", "new"],
2061
2066
  description: "Wan 2.7 Video Edit \u2014 restyle or modify existing video with reference images.",
2062
2067
  features: [feat("Video Input", "input"), feat("Image Input", "input"), feat("1080P", "resolution")],
@@ -3689,7 +3694,7 @@ var { MODELS: MODELS23} = defineModels("elevenlabs", [
3689
3694
  buildPayload: buildElevenLabsSTSPayload,
3690
3695
  toolId: "audio-gen.eleven-sts-v2",
3691
3696
  creditPrice: { "audio-gen.eleven-sts-v2": 1 },
3692
- pricingUnit: "per_second",
3697
+ pricingUnit: "per_minute",
3693
3698
  estimatedTime: 15,
3694
3699
  mode: "audio",
3695
3700
  inputType: "sts",
@@ -4710,6 +4715,7 @@ var { MODELS: MODELS31} = defineModels("picsart", [
4710
4715
  buildPayload: buildRemoveBgPayload,
4711
4716
  toolId: "image-to-image.picsart-sod",
4712
4717
  creditPrice: { "image-to-image.picsart-sod": 1 },
4718
+ pricingUnit: "per_image",
4713
4719
  outputSchema: sodOutputSchema,
4714
4720
  mode: "image",
4715
4721
  inputType: "i2i",
@@ -4724,6 +4730,7 @@ var { MODELS: MODELS31} = defineModels("picsart", [
4724
4730
  buildPayload: buildEnhancePayload,
4725
4731
  toolId: "image-to-image.picsart-enhance",
4726
4732
  creditPrice: { "image-to-image.picsart-enhance": 1 },
4733
+ pricingUnit: "per_image",
4727
4734
  mode: "image",
4728
4735
  inputType: "i2i",
4729
4736
  estimatedTime: 30,
@@ -5538,11 +5545,19 @@ function createClient(config) {
5538
5545
  const completed = await executeModel(resolved, workflow, finalPayload, options?.signal);
5539
5546
  return parseResult(completed, resolved, contract);
5540
5547
  },
5548
+ /** @deprecated Use `getCredits()` instead. */
5549
+ async estimate(model, params2) {
5550
+ if (!transport.options) return null;
5551
+ const resolved = resolveModel(model);
5552
+ const { workflow, payload } = prepareRequest(resolved, params2);
5553
+ return await transport.options(workflow, payload) ?? null;
5554
+ },
5541
5555
  /**
5542
- * Estimate credit cost for a generation.
5556
+ * Get exact credit cost for a model with specific parameters.
5557
+ * Calls the backend /options endpoint for real-time pricing.
5543
5558
  * Returns null if pricing is unavailable.
5544
5559
  */
5545
- async estimate(model, params2) {
5560
+ async getCredits(model, params2) {
5546
5561
  if (!transport.options) return null;
5547
5562
  const resolved = resolveModel(model);
5548
5563
  const { workflow, payload } = prepareRequest(resolved, params2);
@@ -5624,48 +5639,6 @@ function createClient(config) {
5624
5639
  };
5625
5640
  }
5626
5641
 
5627
- // src/core/descriptors/param-access.ts
5628
- function getEnumOptions(model, key) {
5629
- const entry = model.paramConfig[key];
5630
- if (!entry) return null;
5631
- const d = entry.descriptor;
5632
- if (d.kind === "enum") {
5633
- return d.options.map((o) => o.id);
5634
- }
5635
- return null;
5636
- }
5637
- function getDefault(model, key) {
5638
- const entry = model.paramConfig[key];
5639
- if (!entry) return void 0;
5640
- const d = entry.descriptor;
5641
- return "default" in d ? d.default : void 0;
5642
- }
5643
- function getRange(model, key) {
5644
- const entry = model.paramConfig[key];
5645
- if (!entry) return null;
5646
- const d = entry.descriptor;
5647
- if (d.kind === "range") {
5648
- const r = d;
5649
- return { min: r.min, max: r.max, step: r.step, default: r.default };
5650
- }
5651
- return null;
5652
- }
5653
- function getFileParam(model, key) {
5654
- const entry = model.paramConfig[key];
5655
- if (!entry) return null;
5656
- const d = entry.descriptor;
5657
- if (d.kind === "file") {
5658
- const f = d;
5659
- return {
5660
- required: entry.required ?? false,
5661
- max: f.max,
5662
- label: entry.label,
5663
- accept: f.accept
5664
- };
5665
- }
5666
- return null;
5667
- }
5668
-
5669
5642
  // src/core/descriptors/model-accessor.ts
5670
5643
  var ModelParamsAccessorImpl = class {
5671
5644
  def;
@@ -5673,7 +5646,10 @@ var ModelParamsAccessorImpl = class {
5673
5646
  this.def = def;
5674
5647
  }
5675
5648
  param(key) {
5676
- return this.def.paramConfig[key];
5649
+ const entry = this.def.paramConfig[key];
5650
+ if (!entry) return void 0;
5651
+ const { descriptor, ...meta } = entry;
5652
+ return { ...meta, ...descriptor };
5677
5653
  }
5678
5654
  hasParam(key) {
5679
5655
  return key in this.def.paramConfig;
@@ -5726,19 +5702,19 @@ var ModelParamsAccessorImpl = class {
5726
5702
  return Object.values(this.def.paramConfig).some((e) => e.descriptor.kind === "file");
5727
5703
  }
5728
5704
  getDefault(key) {
5729
- return getDefault(this.def, key);
5705
+ const entry = this.def.paramConfig[key];
5706
+ if (!entry) return void 0;
5707
+ const d = entry.descriptor;
5708
+ return "default" in d ? d.default : void 0;
5730
5709
  }
5731
5710
  getDefaults() {
5732
5711
  return extractDefaults(this.def.paramConfig);
5733
5712
  }
5713
+ /** @deprecated Use `enum(key)` instead. */
5734
5714
  getEnumOptions(key) {
5735
- return getEnumOptions(this.def, key);
5736
- }
5737
- getRange(key) {
5738
- return getRange(this.def, key);
5739
- }
5740
- getFileParam(key) {
5741
- return getFileParam(this.def, key);
5715
+ const entry = this.def.paramConfig[key];
5716
+ if (!entry || entry.descriptor.kind !== "enum") return null;
5717
+ return entry.descriptor.options.map((o) => o.id);
5742
5718
  }
5743
5719
  toSchema() {
5744
5720
  return descriptorsToSchema(this.def.paramConfig);
@@ -5748,9 +5724,8 @@ var ModelParamsAccessorImpl = class {
5748
5724
  }
5749
5725
  narrow(key, kind) {
5750
5726
  const entry = this.param(key);
5751
- if (!entry || entry.descriptor.kind !== kind) return void 0;
5752
- const { descriptor, ...meta } = entry;
5753
- return { ...meta, ...descriptor };
5727
+ if (!entry || entry.kind !== kind) return void 0;
5728
+ return entry;
5754
5729
  }
5755
5730
  };
5756
5731
  var ModelMetaImpl = class {
@@ -6123,9 +6098,11 @@ var Models = {
6123
6098
  toSchema(id) {
6124
6099
  return Model(id).params().toSchema();
6125
6100
  },
6126
- /** @deprecated Use `Model(id).params().getFileParam(key)` instead. */
6101
+ /** @deprecated Use `Model(id).params().file(key)` instead. */
6127
6102
  getFileParam(id, key) {
6128
- return Model(id).params().getFileParam(key);
6103
+ const f = Model(id).params().file(key);
6104
+ if (!f) return null;
6105
+ return { required: f.required ?? false, max: f.array?.max ?? 1, label: f.label, accept: f.accept };
6129
6106
  },
6130
6107
  /** @deprecated Use `Model(id).params().hasParam(key)` instead. */
6131
6108
  hasParam(id, key) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@picsart/ai-sdk",
3
- "version": "1.138.1",
3
+ "version": "1.140.0",
4
4
  "type": "module",
5
5
  "description": "Type-safe SDK for 100+ AI models — image, video, and audio generation with Picsart",
6
6
  "license": "MIT",