@picsart/ai-sdk 3.31.0 → 3.32.1

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.
@@ -2,5 +2,5 @@ import { ModelPricingClient } from './lib/ModelPricingClient';
2
2
  import { ModelPricingClientError } from './lib/errors/ModelPricingClientError';
3
3
  import { ModelPricingServerError } from './lib/errors/ModelPricingServerError';
4
4
  import { ModelPricingUnknownError } from './lib/errors/ModelPricingUnknownError';
5
- import { UseCase, PricingUnit, ModelPricingFilters, ModelPricingMetadata, SkuEntry, VendorCostEntry, ModelPricing, ModelPricingListResponse, ModelPricingClientOptions } from './lib/types';
6
- export { ModelPricingClient, ModelPricingClientError, ModelPricingServerError, ModelPricingUnknownError, UseCase, PricingUnit, ModelPricingFilters, ModelPricingMetadata, SkuEntry, VendorCostEntry, ModelPricing, ModelPricingListResponse, ModelPricingClientOptions, };
5
+ import { UseCase, PricingUnit, ModelPricingFilters, ModelPricingMetadata, SkuEntry, VendorCostEntry, CreditOverride, MinTier, ModelPricing, ModelPricingListResponse, ModelPricingClientOptions, UserDiscount, UserDiscountListResponse } from './lib/types';
6
+ export { ModelPricingClient, ModelPricingClientError, ModelPricingServerError, ModelPricingUnknownError, UseCase, PricingUnit, ModelPricingFilters, ModelPricingMetadata, SkuEntry, VendorCostEntry, CreditOverride, MinTier, ModelPricing, ModelPricingListResponse, ModelPricingClientOptions, UserDiscount, UserDiscountListResponse, };
@@ -3,7 +3,9 @@ export declare class ModelPricingClient {
3
3
  private readonly options;
4
4
  private readonly modelPricingApiBaseUrl;
5
5
  private pricing;
6
+ private userDiscounts;
6
7
  private refreshTimer;
8
+ private userDiscountsRefreshTimer;
7
9
  private readonly defaultHeaders;
8
10
  constructor(options: ModelPricingClientOptions);
9
11
  /**
@@ -21,7 +23,12 @@ export declare class ModelPricingClient {
21
23
  */
22
24
  getModelPricing(filters?: ModelPricingFilters): ModelPricing[];
23
25
  private loadAll;
26
+ private loadPricing;
27
+ private loadUserDiscounts;
28
+ private indexUserDiscounts;
29
+ private applyUserDiscounts;
24
30
  private applyFilters;
31
+ private applyCreditOverrides;
25
32
  private toSuccessResponse;
26
33
  private throwIfError;
27
34
  private wrapError;
@@ -4,6 +4,7 @@ export declare enum UseCase {
4
4
  TextToVideo = "text-to-video",
5
5
  ImageToVideo = "image-to-video",
6
6
  VideoToVideo = "video-to-video",
7
+ VideoToImage = "video-to-image",
7
8
  TextToSpeech = "text-to-speech",
8
9
  TextToAudio = "text-to-audio",
9
10
  SpeechToText = "speech-to-text",
@@ -24,16 +25,29 @@ export declare enum PricingUnit {
24
25
  InputTokens = "input_tokens",
25
26
  InputTextTokens = "input_text_tokens",
26
27
  InputCachedTokens = "input_cached_tokens",
28
+ CacheWrite5mTokens = "cache_write_5m_tokens",
29
+ CacheWrite1hTokens = "cache_write_1h_tokens",
30
+ InputImageTokens = "input_image_tokens",
27
31
  OutputImageTokens = "output_image_tokens",
28
32
  OutputAudioTokens = "output_audio_tokens",
29
- OutputTextTokens = "output_text_tokens"
33
+ OutputTextTokens = "output_text_tokens",
34
+ InputMegapixel = "input_megapixel",
35
+ OutputMegapixel = "output_megapixel",
36
+ OutputMegapixelAdditional = "output_megapixel_additional",
37
+ ThousandOutputVideoTokens = "1k_output_video_tokens"
30
38
  }
31
39
  export interface ModelPricingFilters {
32
40
  vendor?: string;
33
41
  modelId?: string;
42
+ operationId?: string;
34
43
  useCase?: UseCase;
35
44
  quality?: string;
36
45
  audio?: boolean;
46
+ countryCode?: string;
47
+ touchpoint?: string;
48
+ platform?: string;
49
+ packageId?: string;
50
+ userId?: string;
37
51
  }
38
52
  export interface ModelPricingMetadata {
39
53
  vendor: string;
@@ -51,15 +65,41 @@ export interface VendorCostEntry {
51
65
  unit: PricingUnit;
52
66
  skus: SkuEntry[];
53
67
  }
68
+ export interface CreditOverride {
69
+ countries: string[];
70
+ touchpoints: string[];
71
+ /** Optional: older overrides created before platform targeting have no platforms. */
72
+ platforms?: string[];
73
+ /** Optional: older overrides created before package targeting have no packageIds. */
74
+ packageIds?: string[];
75
+ credits: number;
76
+ startDate: string;
77
+ endDate: string;
78
+ }
79
+ export interface MinTier {
80
+ name: string;
81
+ accessLevel: number;
82
+ }
54
83
  export interface ModelPricing {
55
84
  id: string;
56
85
  operationId: string;
57
86
  metadata: ModelPricingMetadata;
58
87
  vendorCosts: VendorCostEntry[];
59
88
  unit: PricingUnit;
89
+ /** Credits the user pays — already discounted when a user discount applies. */
60
90
  credits: number;
91
+ /**
92
+ * The original (pre-discount) credits, present only when a discount was
93
+ * applied. On the frontend the service fills both fields (userId travels via
94
+ * the access token in headers); on the backend the SDK fills them when
95
+ * getModelPricing is called with a userId.
96
+ */
97
+ originalCredits?: number;
61
98
  costPerUnit: number;
62
99
  legacy: boolean;
100
+ /** Minimum subscription tier required to use this model, when one is set. */
101
+ minTier?: MinTier;
102
+ creditOverrides: CreditOverride[];
63
103
  created: string;
64
104
  updated: string;
65
105
  }
@@ -67,6 +107,19 @@ export interface ModelPricingListResponse {
67
107
  status: string;
68
108
  response: ModelPricing[];
69
109
  }
110
+ export interface UserDiscount {
111
+ id: string;
112
+ userId: string;
113
+ modelId: string;
114
+ expirationDate: string;
115
+ discountPercent: number;
116
+ created: string;
117
+ updated: string;
118
+ }
119
+ export interface UserDiscountListResponse {
120
+ status: string;
121
+ response: UserDiscount[];
122
+ }
70
123
  export interface ModelPricingClientOptions {
71
124
  /** Base URL of the model pricing service. */
72
125
  baseUrl: string;
package/index.js CHANGED
@@ -110,12 +110,15 @@ var require_ModelPricingClient = __commonJS({
110
110
  var ModelPricingServerError_1 = require_ModelPricingServerError();
111
111
  var ModelPricingUnknownError_1 = require_ModelPricingUnknownError();
112
112
  var DEFAULT_REFRESH_INTERVAL_MS = 6e5;
113
+ var USER_DISCOUNTS_REFRESH_INTERVAL_MS = 3e4;
113
114
  var DEFAULT_TIMEOUT_MS = 5e3;
114
115
  var ModelPricingClient2 = class {
115
116
  constructor(options) {
116
117
  var _a;
117
118
  this.pricing = null;
119
+ this.userDiscounts = null;
118
120
  this.refreshTimer = null;
121
+ this.userDiscountsRefreshTimer = null;
119
122
  this.defaultHeaders = {
120
123
  Accept: "application/json"
121
124
  };
@@ -134,13 +137,22 @@ var require_ModelPricingClient = __commonJS({
134
137
  const refreshIntervalMs = (_a = this.options.refreshIntervalMs) !== null && _a !== void 0 ? _a : DEFAULT_REFRESH_INTERVAL_MS;
135
138
  if (refreshIntervalMs > 0 && this.refreshTimer == null) {
136
139
  this.refreshTimer = setInterval(() => {
137
- this.loadAll().catch(() => {
140
+ this.loadPricing().catch(() => {
138
141
  });
139
142
  }, refreshIntervalMs);
140
143
  if (typeof this.refreshTimer.unref === "function") {
141
144
  this.refreshTimer.unref();
142
145
  }
143
146
  }
147
+ if (this.userDiscountsRefreshTimer == null) {
148
+ this.userDiscountsRefreshTimer = setInterval(() => {
149
+ this.loadUserDiscounts().catch(() => {
150
+ });
151
+ }, USER_DISCOUNTS_REFRESH_INTERVAL_MS);
152
+ if (typeof this.userDiscountsRefreshTimer.unref === "function") {
153
+ this.userDiscountsRefreshTimer.unref();
154
+ }
155
+ }
144
156
  });
145
157
  }
146
158
  /**
@@ -151,18 +163,34 @@ var require_ModelPricingClient = __commonJS({
151
163
  clearInterval(this.refreshTimer);
152
164
  this.refreshTimer = null;
153
165
  }
166
+ if (this.userDiscountsRefreshTimer != null) {
167
+ clearInterval(this.userDiscountsRefreshTimer);
168
+ this.userDiscountsRefreshTimer = null;
169
+ }
154
170
  }
155
171
  /**
156
172
  * Returns model pricings matching the given filters from the in-memory cache.
157
173
  * Throws if pricing has not been loaded yet — call and await init() first.
158
174
  */
159
175
  getModelPricing(filters = {}) {
176
+ var _a, _b, _c, _d, _e;
160
177
  if (this.pricing == null) {
161
178
  throw new Error("ModelPricingClient: pricing not loaded. Call and await init() before getModelPricing().");
162
179
  }
163
- return this.applyFilters(this.pricing, filters);
180
+ const filtered = this.applyFilters(this.pricing, filters);
181
+ const countryCode = ((_a = filters.countryCode) === null || _a === void 0 ? void 0 : _a.trim()) || void 0;
182
+ const touchpoint = ((_b = filters.touchpoint) === null || _b === void 0 ? void 0 : _b.trim()) || void 0;
183
+ const platform = ((_c = filters.platform) === null || _c === void 0 ? void 0 : _c.trim()) || void 0;
184
+ const packageId = ((_d = filters.packageId) === null || _d === void 0 ? void 0 : _d.trim()) || void 0;
185
+ const withOverrides = this.applyCreditOverrides(filtered, countryCode, touchpoint, platform, packageId);
186
+ return this.applyUserDiscounts(withOverrides, ((_e = filters.userId) === null || _e === void 0 ? void 0 : _e.trim()) || void 0);
164
187
  }
165
188
  loadAll() {
189
+ return __awaiter(this, void 0, void 0, function* () {
190
+ yield Promise.all([this.loadPricing(), this.loadUserDiscounts()]);
191
+ });
192
+ }
193
+ loadPricing() {
166
194
  return __awaiter(this, void 0, void 0, function* () {
167
195
  try {
168
196
  const url = `${this.modelPricingApiBaseUrl}/pricing-management/model-pricing`;
@@ -177,12 +205,75 @@ var require_ModelPricingClient = __commonJS({
177
205
  }
178
206
  });
179
207
  }
208
+ loadUserDiscounts() {
209
+ return __awaiter(this, void 0, void 0, function* () {
210
+ try {
211
+ const url = `${this.modelPricingApiBaseUrl}/pricing-management/user-discounts/public`;
212
+ const response = yield this._fetch(url, {
213
+ method: "GET",
214
+ signal: AbortSignal.timeout(this.options.timeoutMs)
215
+ });
216
+ const data = yield this.toSuccessResponse(response, "getUserDiscounts");
217
+ this.userDiscounts = this.indexUserDiscounts(data.response);
218
+ } catch (error) {
219
+ console.error(`ModelPricingClient: failed to load user discounts - ${error.message}`);
220
+ if (this.userDiscounts == null) {
221
+ this.userDiscounts = /* @__PURE__ */ new Map();
222
+ }
223
+ }
224
+ });
225
+ }
226
+ indexUserDiscounts(discounts) {
227
+ const index = /* @__PURE__ */ new Map();
228
+ for (const discount of discounts) {
229
+ let byModel = index.get(discount.userId);
230
+ if (byModel == null) {
231
+ byModel = /* @__PURE__ */ new Map();
232
+ index.set(discount.userId, byModel);
233
+ }
234
+ const list = byModel.get(discount.modelId);
235
+ if (list == null)
236
+ byModel.set(discount.modelId, [discount]);
237
+ else
238
+ list.push(discount);
239
+ }
240
+ return index;
241
+ }
242
+ applyUserDiscounts(items, userId) {
243
+ var _a;
244
+ if (userId == null)
245
+ return items;
246
+ const byModel = (_a = this.userDiscounts) === null || _a === void 0 ? void 0 : _a.get(userId);
247
+ if (byModel == null || byModel.size === 0)
248
+ return items;
249
+ const now = Date.now();
250
+ return items.map((item) => {
251
+ const discounts = byModel.get(item.metadata.modelId);
252
+ if (discounts == null || discounts.length === 0)
253
+ return item;
254
+ let bestPercent = 0;
255
+ for (const discount of discounts) {
256
+ const expiresAt = Date.parse(discount.expirationDate);
257
+ const active = Number.isNaN(expiresAt) || expiresAt >= now;
258
+ if (active && discount.discountPercent > bestPercent) {
259
+ bestPercent = discount.discountPercent;
260
+ }
261
+ }
262
+ if (bestPercent <= 0)
263
+ return item;
264
+ const pct = Math.min(bestPercent, 100);
265
+ const discounted = Math.round(item.credits * (1 - pct / 100));
266
+ return Object.assign(Object.assign({}, item), { credits: discounted, originalCredits: item.credits });
267
+ });
268
+ }
180
269
  applyFilters(items, filters) {
181
270
  return items.filter((item) => {
182
271
  if (filters.vendor != null && item.metadata.vendor !== filters.vendor)
183
272
  return false;
184
273
  if (filters.modelId != null && item.metadata.modelId !== filters.modelId)
185
274
  return false;
275
+ if (filters.operationId != null && item.operationId !== filters.operationId)
276
+ return false;
186
277
  if (filters.useCase != null && item.metadata.useCase !== filters.useCase)
187
278
  return false;
188
279
  if (filters.quality != null && item.metadata.quality !== filters.quality)
@@ -192,6 +283,31 @@ var require_ModelPricingClient = __commonJS({
192
283
  return true;
193
284
  });
194
285
  }
286
+ applyCreditOverrides(items, countryCode, touchpoint, platform, packageId) {
287
+ if (countryCode == null && touchpoint == null && platform == null && packageId == null)
288
+ return items;
289
+ console.log(`Applying credit overrides for countryCode: ${countryCode}, touchpoint: ${touchpoint}, platform: ${platform} and packageId: ${packageId}`);
290
+ return items.map((item) => {
291
+ var _a, _b, _c;
292
+ if (!((_a = item.creditOverrides) === null || _a === void 0 ? void 0 : _a.length))
293
+ return item;
294
+ let matchedCredits;
295
+ for (const co of item.creditOverrides) {
296
+ const countryMatch = co.countries.length === 0 || countryCode != null && co.countries.some((c) => c.toLowerCase() === countryCode.toLowerCase());
297
+ const touchpointMatch = co.touchpoints.length === 0 || touchpoint != null && co.touchpoints.some((t) => t.toLowerCase() === touchpoint.toLowerCase());
298
+ const platforms = (_b = co.platforms) !== null && _b !== void 0 ? _b : [];
299
+ const platformMatch = platforms.length === 0 || platform != null && platforms.some((p2) => p2.toLowerCase() === platform.toLowerCase());
300
+ const packageIds = (_c = co.packageIds) !== null && _c !== void 0 ? _c : [];
301
+ const packageMatch = packageIds.length === 0 || packageId != null && packageIds.some((p2) => p2.toLowerCase() === packageId.toLowerCase());
302
+ if (countryMatch && touchpointMatch && platformMatch && packageMatch) {
303
+ matchedCredits = co.credits;
304
+ }
305
+ }
306
+ if (matchedCredits == null)
307
+ return item;
308
+ return Object.assign(Object.assign({}, item), { credits: matchedCredits });
309
+ });
310
+ }
195
311
  toSuccessResponse(response, actionName) {
196
312
  return __awaiter(this, void 0, void 0, function* () {
197
313
  yield this.throwIfError(response, actionName);
@@ -258,6 +374,7 @@ var require_types = __commonJS({
258
374
  UseCase2["TextToVideo"] = "text-to-video";
259
375
  UseCase2["ImageToVideo"] = "image-to-video";
260
376
  UseCase2["VideoToVideo"] = "video-to-video";
377
+ UseCase2["VideoToImage"] = "video-to-image";
261
378
  UseCase2["TextToSpeech"] = "text-to-speech";
262
379
  UseCase2["TextToAudio"] = "text-to-audio";
263
380
  UseCase2["SpeechToText"] = "speech-to-text";
@@ -279,9 +396,16 @@ var require_types = __commonJS({
279
396
  PricingUnit2["InputTokens"] = "input_tokens";
280
397
  PricingUnit2["InputTextTokens"] = "input_text_tokens";
281
398
  PricingUnit2["InputCachedTokens"] = "input_cached_tokens";
399
+ PricingUnit2["CacheWrite5mTokens"] = "cache_write_5m_tokens";
400
+ PricingUnit2["CacheWrite1hTokens"] = "cache_write_1h_tokens";
401
+ PricingUnit2["InputImageTokens"] = "input_image_tokens";
282
402
  PricingUnit2["OutputImageTokens"] = "output_image_tokens";
283
403
  PricingUnit2["OutputAudioTokens"] = "output_audio_tokens";
284
404
  PricingUnit2["OutputTextTokens"] = "output_text_tokens";
405
+ PricingUnit2["InputMegapixel"] = "input_megapixel";
406
+ PricingUnit2["OutputMegapixel"] = "output_megapixel";
407
+ PricingUnit2["OutputMegapixelAdditional"] = "output_megapixel_additional";
408
+ PricingUnit2["ThousandOutputVideoTokens"] = "1k_output_video_tokens";
285
409
  })(PricingUnit || (exports.PricingUnit = PricingUnit = {}));
286
410
  }
287
411
  });
@@ -3297,6 +3421,7 @@ var { MODELS: MODELS10 } = defineModels("wan", [
3297
3421
  // start/end frames. buildPayload registered in wan.payloads.ts.
3298
3422
  workflow: "wan/v3/video",
3299
3423
  estimatedTime: 120,
3424
+ release: "preview",
3300
3425
  mode: "video",
3301
3426
  inputType: "t2v",
3302
3427
  description: "Wan 3.0 all-in-one \u2014 text, image/video/audio references, and start/end frames with adaptive ratio, intelligent duration, and audio.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@picsart/ai-sdk",
3
- "version": "3.31.0",
3
+ "version": "3.32.1",
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",