avantgate 1.6.1 → 1.7.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 (37) hide show
  1. package/README.md +15 -1
  2. package/dist/agent/index.js +97 -24
  3. package/dist/agent/index.mjs +5 -2
  4. package/dist/agent/isolated-tool.d.ts +8 -3
  5. package/dist/agent/isolated-tool.d.ts.map +1 -1
  6. package/dist/agent/types.d.ts +16 -0
  7. package/dist/agent/types.d.ts.map +1 -1
  8. package/dist/{chunk-CO26LNFD.mjs → chunk-36ULFTM2.mjs} +8 -8
  9. package/dist/{chunk-4XWO3NZW.mjs → chunk-AH5XXSS4.mjs} +1 -1
  10. package/dist/{chunk-5VA3EKPJ.mjs → chunk-W27A25DK.mjs} +97 -25
  11. package/dist/chunk-Y6FXYEAI.mjs +10 -0
  12. package/dist/client/index.mjs +2 -0
  13. package/dist/control-layer.d.ts +7 -7
  14. package/dist/control-layer.d.ts.map +1 -1
  15. package/dist/finance/index.js +6 -6
  16. package/dist/finance/index.mjs +2 -1
  17. package/dist/finance/normalizer.d.ts +2 -2
  18. package/dist/finance/normalizer.d.ts.map +1 -1
  19. package/dist/index.d.ts +1 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +421 -130
  22. package/dist/index.mjs +318 -103
  23. package/dist/input-guard.d.ts +2 -2
  24. package/dist/input-guard.d.ts.map +1 -1
  25. package/dist/pricing.d.ts +17 -16
  26. package/dist/pricing.d.ts.map +1 -1
  27. package/dist/providers/http-client.d.ts +2 -2
  28. package/dist/providers/http-client.d.ts.map +1 -1
  29. package/dist/response-validator.d.ts +2 -2
  30. package/dist/response-validator.d.ts.map +1 -1
  31. package/dist/sanitizer.d.ts +1 -1
  32. package/dist/sanitizer.d.ts.map +1 -1
  33. package/dist/sqlite-pricing-adapter.d.ts +87 -0
  34. package/dist/sqlite-pricing-adapter.d.ts.map +1 -0
  35. package/dist/workflow/index.js +92 -24
  36. package/dist/workflow/index.mjs +3 -2
  37. package/package.json +4 -2
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
@@ -33,6 +43,7 @@ __export(index_exports, {
33
43
  PromptRegistry: () => PromptRegistry,
34
44
  PromptTemplate: () => PromptTemplate,
35
45
  SEED_MODEL_PRICES: () => SEED_MODEL_PRICES,
46
+ SqlitePricingAdapter: () => SqlitePricingAdapter,
36
47
  WorkflowAbortSignal: () => WorkflowAbortSignal,
37
48
  WorkflowSagaRollbackError: () => WorkflowSagaRollbackError,
38
49
  WorkflowValidationError: () => WorkflowValidationError,
@@ -67,6 +78,213 @@ var BudgetExceededError = class extends Error {
67
78
  }
68
79
  };
69
80
 
81
+ // src/sqlite-pricing-adapter.ts
82
+ var import_fs = __toESM(require("fs"));
83
+ var import_path = __toESM(require("path"));
84
+ var normalizeIdentifier = (val) => {
85
+ return val.trim().toLowerCase().replace(":", "/");
86
+ };
87
+ var SqlitePricingAdapter = class {
88
+ db;
89
+ tableName;
90
+ constructor(options = {}) {
91
+ this.tableName = options.tableName ?? "model_pricing";
92
+ this.db = options.db ?? this.initDatabase(options.dbPath ?? ":memory:");
93
+ this.initSchema();
94
+ if (options.autoSeed) {
95
+ this.seedDefaultPrices(false);
96
+ }
97
+ }
98
+ initDatabase = (dbPath) => {
99
+ if (dbPath !== ":memory:") {
100
+ const dir = import_path.default.dirname(import_path.default.resolve(dbPath));
101
+ if (!import_fs.default.existsSync(dir)) {
102
+ import_fs.default.mkdirSync(dir, { recursive: true });
103
+ }
104
+ }
105
+ try {
106
+ const { DatabaseSync } = require("sqlite");
107
+ return new DatabaseSync(dbPath);
108
+ } catch (err) {
109
+ throw new ConfigurationError(
110
+ `[avantGate] Failed to initialize native SQLite at '${dbPath}'. Ensure you are running on Node.js 22+ or provide a custom 'db' instance in options. Error: ${String(err)}`
111
+ );
112
+ }
113
+ };
114
+ initSchema = () => {
115
+ this.db.exec(`
116
+ CREATE TABLE IF NOT EXISTS ${this.tableName} (
117
+ provider TEXT NOT NULL,
118
+ model TEXT NOT NULL,
119
+ prompt_usd_per_million REAL NOT NULL,
120
+ completion_usd_per_million REAL NOT NULL,
121
+ cache_hit_usd_per_million REAL,
122
+ is_active INTEGER DEFAULT 1,
123
+ updated_at TEXT NOT NULL,
124
+ PRIMARY KEY (provider, model)
125
+ );
126
+ CREATE INDEX IF NOT EXISTS idx_${this.tableName}_lookup
127
+ ON ${this.tableName}(provider, model, is_active);
128
+ `);
129
+ };
130
+ /**
131
+ * Implémentation du port avantGate PricingAdapter.
132
+ * Résolution hiérarchique : (provider, model) -> (provider/model) -> (model).
133
+ */
134
+ fetchPrice = (model, provider) => {
135
+ const normModel = normalizeIdentifier(model);
136
+ const normProvider = provider ? normalizeIdentifier(provider) : void 0;
137
+ if (normProvider) {
138
+ const row = this.queryActiveRow(normProvider, normModel);
139
+ if (row) return this.mapRowToPrice(row);
140
+ }
141
+ if (normModel.includes("/")) {
142
+ const firstSlashIdx = normModel.indexOf("/");
143
+ const extractedProvider = normModel.slice(0, firstSlashIdx);
144
+ const extractedModel = normModel.slice(firstSlashIdx + 1);
145
+ const splitRow = this.queryActiveRow(extractedProvider, extractedModel);
146
+ if (splitRow) return this.mapRowToPrice(splitRow);
147
+ }
148
+ const directRow = this.queryByModelOnly(normModel);
149
+ if (directRow) return this.mapRowToPrice(directRow);
150
+ return void 0;
151
+ };
152
+ queryActiveRow = (provider, model) => {
153
+ const stmt = this.db.prepare(`
154
+ SELECT provider, model, prompt_usd_per_million, completion_usd_per_million, cache_hit_usd_per_million, is_active, updated_at
155
+ FROM ${this.tableName}
156
+ WHERE provider = ? AND model = ? AND is_active = 1
157
+ LIMIT 1
158
+ `);
159
+ return stmt.get(provider, model);
160
+ };
161
+ queryByModelOnly = (model) => {
162
+ const stmt = this.db.prepare(`
163
+ SELECT provider, model, prompt_usd_per_million, completion_usd_per_million, cache_hit_usd_per_million, is_active, updated_at
164
+ FROM ${this.tableName}
165
+ WHERE model = ? AND is_active = 1
166
+ LIMIT 1
167
+ `);
168
+ return stmt.get(model);
169
+ };
170
+ mapRowToPrice = (row) => {
171
+ return {
172
+ promptUSDPerMillion: Number(row.prompt_usd_per_million),
173
+ completionUSDPerMillion: Number(row.completion_usd_per_million),
174
+ cacheHitUSDPerMillion: row.cache_hit_usd_per_million != null ? Number(row.cache_hit_usd_per_million) : void 0
175
+ };
176
+ };
177
+ /**
178
+ * Enregistre ou met à jour la tarification d'un modèle.
179
+ */
180
+ upsertPrice = (provider, model, price, isActive = true) => {
181
+ const normProvider = normalizeIdentifier(provider);
182
+ const normModel = normalizeIdentifier(model);
183
+ const now = (/* @__PURE__ */ new Date()).toISOString();
184
+ const stmt = this.db.prepare(`
185
+ INSERT OR REPLACE INTO ${this.tableName}
186
+ (provider, model, prompt_usd_per_million, completion_usd_per_million, cache_hit_usd_per_million, is_active, updated_at)
187
+ VALUES (?, ?, ?, ?, ?, ?, ?)
188
+ `);
189
+ stmt.run(
190
+ normProvider,
191
+ normModel,
192
+ price.promptUSDPerMillion,
193
+ price.completionUSDPerMillion,
194
+ price.cacheHitUSDPerMillion ?? null,
195
+ isActive ? 1 : 0,
196
+ now
197
+ );
198
+ };
199
+ /**
200
+ * Supprime une règle tarifaire de la base de données.
201
+ */
202
+ deletePrice = (provider, model) => {
203
+ const normProvider = normalizeIdentifier(provider);
204
+ const normModel = normalizeIdentifier(model);
205
+ const stmt = this.db.prepare(`
206
+ DELETE FROM ${this.tableName}
207
+ WHERE provider = ? AND model = ?
208
+ `);
209
+ const result = stmt.run(normProvider, normModel);
210
+ return Boolean(result && typeof result.changes === "number" && result.changes > 0);
211
+ };
212
+ /**
213
+ * Retourne l'ensemble des règles tarifaires enregistrées.
214
+ */
215
+ getAllPrices = () => {
216
+ const stmt = this.db.prepare(`
217
+ SELECT provider, model, prompt_usd_per_million, completion_usd_per_million, cache_hit_usd_per_million, is_active, updated_at
218
+ FROM ${this.tableName}
219
+ ORDER BY provider ASC, model ASC
220
+ `);
221
+ const rows = stmt.all();
222
+ return rows.map((row) => ({
223
+ provider: row.provider,
224
+ model: row.model,
225
+ price: this.mapRowToPrice(row),
226
+ isActive: Boolean(row.is_active),
227
+ updatedAt: row.updated_at
228
+ }));
229
+ };
230
+ /**
231
+ * Remplit la base avec le catalogue de départ SEED_MODEL_PRICES.
232
+ * @param force Si true, écrase les tarifs existants. Si false, insère uniquement les modèles manquants.
233
+ * @returns Le nombre d'enregistrements insérés.
234
+ */
235
+ seedDefaultPrices = (force = false) => {
236
+ const conflictClause = force ? "INSERT OR REPLACE" : "INSERT OR IGNORE";
237
+ const stmt = this.db.prepare(`
238
+ ${conflictClause} INTO ${this.tableName}
239
+ (provider, model, prompt_usd_per_million, completion_usd_per_million, cache_hit_usd_per_million, is_active, updated_at)
240
+ VALUES (?, ?, ?, ?, ?, ?, ?)
241
+ `);
242
+ let inserted = 0;
243
+ const now = (/* @__PURE__ */ new Date()).toISOString();
244
+ for (const [key, price] of Object.entries(SEED_MODEL_PRICES)) {
245
+ const normKey = normalizeIdentifier(key);
246
+ let provider = "direct";
247
+ let model = normKey;
248
+ if (normKey.includes("/")) {
249
+ const slashIdx = normKey.indexOf("/");
250
+ provider = normKey.slice(0, slashIdx);
251
+ model = normKey.slice(slashIdx + 1);
252
+ }
253
+ const res1 = stmt.run(
254
+ provider,
255
+ model,
256
+ price.promptUSDPerMillion,
257
+ price.completionUSDPerMillion,
258
+ price.cacheHitUSDPerMillion ?? null,
259
+ 1,
260
+ now
261
+ );
262
+ if (res1?.changes && res1.changes > 0) inserted++;
263
+ if (provider !== "direct") {
264
+ const res2 = stmt.run(
265
+ "direct",
266
+ normKey,
267
+ price.promptUSDPerMillion,
268
+ price.completionUSDPerMillion,
269
+ price.cacheHitUSDPerMillion ?? null,
270
+ 1,
271
+ now
272
+ );
273
+ if (res2?.changes && res2.changes > 0) inserted++;
274
+ }
275
+ }
276
+ return inserted;
277
+ };
278
+ /**
279
+ * Ferme la connexion SQLite sous-jacente si supporté.
280
+ */
281
+ close = () => {
282
+ if (typeof this.db.close === "function") {
283
+ this.db.close();
284
+ }
285
+ };
286
+ };
287
+
70
288
  // src/pricing.ts
71
289
  var SEED_MODEL_PRICES = {
72
290
  // DeepSeek Direct
@@ -91,9 +309,9 @@ var SEED_MODEL_PRICES = {
91
309
  // Local Ollama (Toujours $0)
92
310
  "ollama": { promptUSDPerMillion: 0, completionUSDPerMillion: 0 }
93
311
  };
94
- function normalizeKey(identifier) {
312
+ var normalizeKey = (identifier) => {
95
313
  return identifier.trim().toLowerCase().replace(":", "/");
96
- }
314
+ };
97
315
  var CachedPricingAdapter = class {
98
316
  cache = /* @__PURE__ */ new Map();
99
317
  ttlMs;
@@ -102,7 +320,7 @@ var CachedPricingAdapter = class {
102
320
  this.delegate = delegate;
103
321
  this.ttlMs = ttlMs;
104
322
  }
105
- async fetchPrice(model, provider) {
323
+ fetchPrice = async (model, provider) => {
106
324
  const key = provider ? normalizeKey(`${provider}/${model}`) : normalizeKey(model);
107
325
  const cached = this.cache.get(key);
108
326
  if (cached && Date.now() < cached.expiresAt) {
@@ -120,72 +338,76 @@ var CachedPricingAdapter = class {
120
338
  }
121
339
  }
122
340
  return void 0;
123
- }
124
- peek(model, provider) {
341
+ };
342
+ peek = (model, provider) => {
125
343
  const key = provider ? normalizeKey(`${provider}/${model}`) : normalizeKey(model);
126
- return this.cache.get(key)?.price;
127
- }
128
- clearCache() {
344
+ const cached = this.cache.get(key);
345
+ if (cached && Date.now() < cached.expiresAt) {
346
+ return cached.price;
347
+ }
348
+ return void 0;
349
+ };
350
+ clearCache = () => {
129
351
  this.cache.clear();
130
- }
131
- invalidate(model, provider) {
352
+ };
353
+ invalidate = (model, provider) => {
132
354
  if (!model) {
133
355
  this.clearCache();
134
356
  return;
135
357
  }
136
358
  const key = provider ? normalizeKey(`${provider}/${model}`) : normalizeKey(model);
137
359
  this.cache.delete(key);
138
- }
360
+ };
139
361
  };
140
- var PricingRegistry = class {
362
+ var PricingRegistry = class _PricingRegistry {
141
363
  static prices = /* @__PURE__ */ new Map();
142
364
  static adapter;
143
- static registerPrice(identifier, price) {
144
- this.prices.set(normalizeKey(identifier), price);
145
- }
146
- static registerDistributorPrices(distributor, priceMap) {
365
+ static registerPrice = (identifier, price) => {
366
+ _PricingRegistry.prices.set(normalizeKey(identifier), price);
367
+ };
368
+ static registerDistributorPrices = (distributor, priceMap) => {
147
369
  for (const [model, price] of Object.entries(priceMap)) {
148
- this.prices.set(normalizeKey(`${distributor}/${model}`), price);
370
+ _PricingRegistry.prices.set(normalizeKey(`${distributor}/${model}`), price);
149
371
  }
150
- }
151
- static registerPrices(prices) {
372
+ };
373
+ static registerPrices = (prices) => {
152
374
  for (const [key, price] of Object.entries(prices)) {
153
- this.prices.set(normalizeKey(key), price);
375
+ _PricingRegistry.prices.set(normalizeKey(key), price);
154
376
  }
155
- }
156
- static getPrice(model, provider) {
377
+ };
378
+ static getPrice = (model, provider) => {
157
379
  if (provider) {
158
380
  const distributorKey = normalizeKey(`${provider}/${model}`);
159
- const directDistributorPrice = this.prices.get(distributorKey);
381
+ const directDistributorPrice = _PricingRegistry.prices.get(distributorKey);
160
382
  if (directDistributorPrice) {
161
383
  return directDistributorPrice;
162
384
  }
163
385
  }
164
- return this.prices.get(normalizeKey(model));
165
- }
166
- static setAdapter(adapter) {
167
- this.adapter = adapter;
168
- }
169
- static getAdapter() {
170
- return this.adapter;
171
- }
172
- static clear() {
173
- this.prices.clear();
174
- this.adapter = void 0;
175
- }
386
+ return _PricingRegistry.prices.get(normalizeKey(model));
387
+ };
388
+ static setAdapter = (adapter) => {
389
+ _PricingRegistry.adapter = adapter;
390
+ };
391
+ static getAdapter = () => {
392
+ return _PricingRegistry.adapter;
393
+ };
394
+ static clear = () => {
395
+ _PricingRegistry.prices.clear();
396
+ _PricingRegistry.adapter = void 0;
397
+ };
176
398
  /**
177
399
  * Réinitialise le registre en chargeant le catalogue d'exemple SEED_MODEL_PRICES.
178
400
  */
179
- static loadSeedPrices() {
180
- this.registerPrices(SEED_MODEL_PRICES);
181
- }
182
- static getAllPrices() {
401
+ static loadSeedPrices = () => {
402
+ _PricingRegistry.registerPrices(SEED_MODEL_PRICES);
403
+ };
404
+ static getAllPrices = () => {
183
405
  const out = {};
184
- for (const [k, v] of this.prices.entries()) {
406
+ for (const [k, v] of _PricingRegistry.prices.entries()) {
185
407
  out[k] = v;
186
408
  }
187
409
  return out;
188
- }
410
+ };
189
411
  };
190
412
  var DEFAULT_MODEL_PRICES = new Proxy({}, {
191
413
  get(_target, prop) {
@@ -205,7 +427,7 @@ var DEFAULT_MODEL_PRICES = new Proxy({}, {
205
427
  return void 0;
206
428
  }
207
429
  });
208
- function resolveModelPrice(model, options) {
430
+ var resolveModelPrice = (model, options) => {
209
431
  const opts = typeof options === "string" ? { provider: options } : options ?? {};
210
432
  if (opts.providerPricing) {
211
433
  return opts.providerPricing;
@@ -236,8 +458,8 @@ function resolveModelPrice(model, options) {
236
458
  return { promptUSDPerMillion: 0, completionUSDPerMillion: 0 };
237
459
  }
238
460
  return void 0;
239
- }
240
- async function resolveModelPriceAsync(model, options) {
461
+ };
462
+ var resolveModelPriceAsync = async (model, options) => {
241
463
  const opts = typeof options === "string" ? { provider: options } : options ?? {};
242
464
  const activeAdapter = opts.adapter ?? PricingRegistry.getAdapter();
243
465
  if (activeAdapter) {
@@ -250,8 +472,8 @@ async function resolveModelPriceAsync(model, options) {
250
472
  }
251
473
  }
252
474
  return resolveModelPrice(model, options);
253
- }
254
- function calculateCostUSD(model, promptTokens, completionTokens, cacheHitTokens = 0, options) {
475
+ };
476
+ var calculateCostUSD = (model, promptTokens, completionTokens, cacheHitTokens = 0, options) => {
255
477
  const pricing = resolveModelPrice(model, options);
256
478
  if (!pricing) {
257
479
  return 0;
@@ -260,7 +482,7 @@ function calculateCostUSD(model, promptTokens, completionTokens, cacheHitTokens
260
482
  const completionCost = completionTokens / 1e6 * pricing.completionUSDPerMillion;
261
483
  const cacheDiscount = cacheHitTokens && pricing.cacheHitUSDPerMillion ? cacheHitTokens / 1e6 * (pricing.promptUSDPerMillion - pricing.cacheHitUSDPerMillion) : 0;
262
484
  return Math.max(0, promptCost + completionCost - cacheDiscount);
263
- }
485
+ };
264
486
 
265
487
  // src/sanitizer.ts
266
488
  var EMAIL_REGEX = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b/g;
@@ -270,7 +492,7 @@ var SPI_LABELLED_REGEX = /(?:(?:num[ée]ro\s+fiscal|spi|n[°o]\s*fiscal|d[ée]cl
270
492
  var SPI_FORMATTED_REGEX = /\b[0-3]\d(?:\s+\d{2}){5}\s+\d\b/g;
271
493
  var IBAN_REGEX = /\b[A-Z]{2}\s*[0-9]{2}(?:[\s\r\n.-]*[A-Z0-9]){11,30}\b/g;
272
494
  var BIC_LABELLED_REGEX = /(?:(?:bic|swift)\s*[:=]?\s*)\b([A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?)\b/gi;
273
- function sanitizePII(input) {
495
+ var sanitizePII = (input) => {
274
496
  let count = 0;
275
497
  let result = input;
276
498
  result = result.replace(EMAIL_REGEX, () => {
@@ -313,7 +535,7 @@ function sanitizePII(input) {
313
535
  return match;
314
536
  });
315
537
  return { text: result, maskedCount: count };
316
- }
538
+ };
317
539
 
318
540
  // src/input-guard.ts
319
541
  var INJECTION_PATTERNS = [
@@ -324,7 +546,7 @@ var INJECTION_PATTERNS = [
324
546
  /output\s+(?:your\s+)?(?:system\s+prompt|initial\s+instructions)/i,
325
547
  /repeat\s+(?:the\s+words\s+above|everything\s+above)/i
326
548
  ];
327
- function validateUserInput(input, options) {
549
+ var validateUserInput = (input, options) => {
328
550
  const maxLength = options?.maxLength ?? 5e4;
329
551
  if (input.length > maxLength) {
330
552
  return {
@@ -343,7 +565,7 @@ function validateUserInput(input, options) {
343
565
  }
344
566
  }
345
567
  return { valid: true };
346
- }
568
+ };
347
569
 
348
570
  // src/finance/strategies/french-pcg.strategy.ts
349
571
  var FrenchPCGStrategy = class {
@@ -799,17 +1021,17 @@ var AccountingFactory = class {
799
1021
  };
800
1022
 
801
1023
  // src/finance/normalizer.ts
802
- function cleanFinancialJSON(rawText, options) {
1024
+ var cleanFinancialJSON = (rawText, options) => {
803
1025
  if (!rawText) {
804
1026
  return "";
805
1027
  }
806
1028
  const jsonBlock = extractAndCleanJSON(rawText);
807
1029
  const strategy = options?.jurisdiction ? AccountingFactory.getStrategy(options.jurisdiction) : options?.autoDetect !== false ? AccountingFactory.detectStrategy(rawText) : AccountingFactory.getStrategy("FR");
808
1030
  return strategy.cleanJSON(jsonBlock);
809
- }
1031
+ };
810
1032
 
811
1033
  // src/response-validator.ts
812
- function extractAndCleanJSON(rawText) {
1034
+ var extractAndCleanJSON = (rawText) => {
813
1035
  let cleaned = rawText.trim();
814
1036
  cleaned = cleaned.replace(/<think>[\s\S]*?<\/think>/gi, "").trim();
815
1037
  const codeBlockMatch = cleaned.match(/```(?:json)?\s*([\s\S]*?)\s*```/i);
@@ -833,8 +1055,8 @@ function extractAndCleanJSON(rawText) {
833
1055
  cleaned = cleaned.slice(startIndex, endIndex + 1);
834
1056
  }
835
1057
  return cleaned;
836
- }
837
- function validateWithZod(rawText, schema, options) {
1058
+ };
1059
+ var validateWithZod = (rawText, schema, options) => {
838
1060
  let jsonString = extractAndCleanJSON(rawText);
839
1061
  if (options?.normalizer) {
840
1062
  jsonString = options.normalizer(jsonString);
@@ -849,7 +1071,7 @@ function validateWithZod(rawText, schema, options) {
849
1071
  parsed = JSON.parse(sanitized);
850
1072
  }
851
1073
  return schema.parse(parsed);
852
- }
1074
+ };
853
1075
 
854
1076
  // src/providers/http-client.ts
855
1077
  var DEFAULT_BASE_URLS = {
@@ -870,14 +1092,14 @@ var HttpProviderClient = class {
870
1092
  this.apiKey = config.apiKey;
871
1093
  this.baseUrl = config.baseUrl || DEFAULT_BASE_URLS[config.provider] || "https://api.openai.com/v1";
872
1094
  }
873
- resolveEndpoint() {
1095
+ resolveEndpoint = () => {
874
1096
  const trimmed = this.baseUrl.replace(/\/+$/, "");
875
1097
  if (trimmed.endsWith("/chat/completions")) {
876
1098
  return trimmed;
877
1099
  }
878
1100
  return `${trimmed}/chat/completions`;
879
- }
880
- buildHeaders() {
1101
+ };
1102
+ buildHeaders = () => {
881
1103
  const headers = {
882
1104
  "Content-Type": "application/json"
883
1105
  };
@@ -889,8 +1111,8 @@ var HttpProviderClient = class {
889
1111
  headers["X-Title"] = "AvantGate";
890
1112
  }
891
1113
  return headers;
892
- }
893
- buildPayload(options, model) {
1114
+ };
1115
+ buildPayload = (options, model) => {
894
1116
  return {
895
1117
  model,
896
1118
  messages: options.messages.map((m) => ({
@@ -900,8 +1122,8 @@ var HttpProviderClient = class {
900
1122
  temperature: options.temperature ?? 0.2,
901
1123
  ...options.responseFormat ? { response_format: options.responseFormat } : {}
902
1124
  };
903
- }
904
- extractUsage(usageData) {
1125
+ };
1126
+ extractUsage = (usageData) => {
905
1127
  if (!usageData) {
906
1128
  return void 0;
907
1129
  }
@@ -911,8 +1133,8 @@ var HttpProviderClient = class {
911
1133
  totalTokens: usageData.total_tokens,
912
1134
  promptCacheHitTokens: usageData.prompt_tokens_details?.cached_tokens
913
1135
  };
914
- }
915
- async complete(options) {
1136
+ };
1137
+ complete = async (options) => {
916
1138
  const endpoint = this.resolveEndpoint();
917
1139
  const model = options.model ?? "default";
918
1140
  const headers = this.buildHeaders();
@@ -932,11 +1154,11 @@ var HttpProviderClient = class {
932
1154
  const text = data.choices?.[0]?.message?.content ?? "";
933
1155
  const usage = this.extractUsage(data.usage);
934
1156
  return { text, usage };
935
- }
1157
+ };
936
1158
  };
937
- function createHttpProviderClient(config) {
1159
+ var createHttpProviderClient = (config) => {
938
1160
  return new HttpProviderClient(config);
939
- }
1161
+ };
940
1162
 
941
1163
  // src/control-layer.ts
942
1164
  var AvantGateControlLayer = class {
@@ -956,7 +1178,7 @@ var AvantGateControlLayer = class {
956
1178
  );
957
1179
  }
958
1180
  }
959
- resolveProviderConfig(provider) {
1181
+ resolveProviderConfig = (provider) => {
960
1182
  if (!provider) return void 0;
961
1183
  if (provider.client) return provider;
962
1184
  if (provider.apiKey || provider.baseUrl || provider.provider === "ollama") {
@@ -966,8 +1188,8 @@ var AvantGateControlLayer = class {
966
1188
  };
967
1189
  }
968
1190
  return provider;
969
- }
970
- findProviderConfig(provider, model) {
1191
+ };
1192
+ findProviderConfig = (provider, model) => {
971
1193
  const list = [this.config.primary, this.config.fallback, this.config.emergencyFallback].filter(
972
1194
  (p) => Boolean(p)
973
1195
  );
@@ -980,8 +1202,8 @@ var AvantGateControlLayer = class {
980
1202
  if (matchModel) return matchModel;
981
1203
  }
982
1204
  return this.config.primary;
983
- }
984
- calculateCost(model, promptTokens, completionTokens, cacheHitTokens = 0, provider) {
1205
+ };
1206
+ calculateCost = (model, promptTokens, completionTokens, cacheHitTokens = 0, provider) => {
985
1207
  const providerCfg = this.findProviderConfig(provider, model);
986
1208
  return calculateCostUSD(model, promptTokens, completionTokens, cacheHitTokens, {
987
1209
  provider: provider ?? providerCfg?.provider,
@@ -989,8 +1211,8 @@ var AvantGateControlLayer = class {
989
1211
  customPricing: this.config.customPricing,
990
1212
  adapter: this.cachedPricingAdapter
991
1213
  });
992
- }
993
- applySecurityGuards(userQuery) {
1214
+ };
1215
+ applySecurityGuards = (userQuery) => {
994
1216
  const guard = validateUserInput(userQuery, {
995
1217
  detectInjection: this.config.security?.detectPromptInjection,
996
1218
  maxLength: this.config.security?.maxInputLength
@@ -1002,8 +1224,8 @@ var AvantGateControlLayer = class {
1002
1224
  return sanitizePII(userQuery).text;
1003
1225
  }
1004
1226
  return userQuery;
1005
- }
1006
- checkPreflightBudget(estimatedPromptTokens, targetModel, provider) {
1227
+ };
1228
+ checkPreflightBudget = async (estimatedPromptTokens, targetModel, provider) => {
1007
1229
  if (this.config.maxTokenBudget !== void 0 && estimatedPromptTokens > this.config.maxTokenBudget) {
1008
1230
  throw new BudgetExceededError(
1009
1231
  `[AvantGate Budget Guard] Pre-flight token budget exceeded: estimated prompt (${estimatedPromptTokens} tokens) exceeds maxTokenBudget (${this.config.maxTokenBudget}).`
@@ -1012,7 +1234,7 @@ var AvantGateControlLayer = class {
1012
1234
  if (this.config.maxCostUSD !== void 0) {
1013
1235
  const isLocalFree = provider === "ollama" || targetModel.toLowerCase().includes("ollama");
1014
1236
  const providerCfg = this.findProviderConfig(provider, targetModel);
1015
- const price = resolveModelPrice(targetModel, {
1237
+ const price = await resolveModelPriceAsync(targetModel, {
1016
1238
  provider: provider ?? providerCfg?.provider,
1017
1239
  providerPricing: providerCfg?.pricing,
1018
1240
  customPricing: this.config.customPricing,
@@ -1030,8 +1252,8 @@ var AvantGateControlLayer = class {
1030
1252
  );
1031
1253
  }
1032
1254
  }
1033
- }
1034
- checkPostExecutionBudget(tokensTotal, costUSD) {
1255
+ };
1256
+ checkPostExecutionBudget = (tokensTotal, costUSD) => {
1035
1257
  if (this.config.maxTokenBudget !== void 0 && tokensTotal > this.config.maxTokenBudget) {
1036
1258
  throw new BudgetExceededError(
1037
1259
  `[AvantGate Budget Guard] Execution total tokens (${tokensTotal}) exceeded maxTokenBudget (${this.config.maxTokenBudget}).`
@@ -1042,16 +1264,16 @@ var AvantGateControlLayer = class {
1042
1264
  `[AvantGate Budget Guard] Execution cost ($${costUSD.toFixed(6)}) exceeded maxCostUSD ($${this.config.maxCostUSD}).`
1043
1265
  );
1044
1266
  }
1045
- }
1046
- buildMessages(systemPrompt, query) {
1267
+ };
1268
+ buildMessages = (systemPrompt, query) => {
1047
1269
  const messages = [];
1048
1270
  if (systemPrompt) {
1049
1271
  messages.push({ role: "system", content: systemPrompt });
1050
1272
  }
1051
1273
  messages.push({ role: "user", content: query });
1052
1274
  return messages;
1053
- }
1054
- resolveTokens(rawUsage, query, text) {
1275
+ };
1276
+ resolveTokens = (rawUsage, query, text) => {
1055
1277
  const promptTokens = rawUsage?.promptTokens ?? Math.ceil(query.length / 4);
1056
1278
  const completionTokens = rawUsage?.completionTokens ?? Math.ceil(text.length / 4);
1057
1279
  const totalTokens = rawUsage?.totalTokens ?? promptTokens + completionTokens;
@@ -1061,15 +1283,15 @@ var AvantGateControlLayer = class {
1061
1283
  totalTokens,
1062
1284
  promptCacheHitTokens: rawUsage?.promptCacheHitTokens
1063
1285
  };
1064
- }
1065
- getProviderChain() {
1286
+ };
1287
+ getProviderChain = () => {
1066
1288
  return [
1067
1289
  this.config.primary,
1068
1290
  this.config.fallback,
1069
1291
  this.config.emergencyFallback
1070
1292
  ].filter((provider) => Boolean(provider?.client));
1071
- }
1072
- executeSimulation(query, systemPrompt) {
1293
+ };
1294
+ executeSimulation = (query, systemPrompt) => {
1073
1295
  const promptTokens = Math.ceil(((systemPrompt?.length ?? 0) + query.length) / 4);
1074
1296
  const completionTokens = 50;
1075
1297
  const cost = this.calculateCost(this.config.primary.model, promptTokens, completionTokens);
@@ -1085,8 +1307,8 @@ var AvantGateControlLayer = class {
1085
1307
  failoverOccurred: false,
1086
1308
  attempts: 1
1087
1309
  };
1088
- }
1089
- async executeOverrideProvider(provider, messages, query, temperature) {
1310
+ };
1311
+ executeOverrideProvider = async (provider, messages, query, temperature) => {
1090
1312
  const response = await provider.complete({
1091
1313
  model: this.config.primary.model,
1092
1314
  messages,
@@ -1100,8 +1322,8 @@ var AvantGateControlLayer = class {
1100
1322
  failoverOccurred: false,
1101
1323
  attempts: 1
1102
1324
  };
1103
- }
1104
- async executeProviderPipeline(messages, query, temperature, modelOverride) {
1325
+ };
1326
+ executeProviderPipeline = async (messages, query, temperature, modelOverride) => {
1105
1327
  const chain = this.getProviderChain();
1106
1328
  let lastError;
1107
1329
  for (let index = 0; index < chain.length; index++) {
@@ -1126,8 +1348,8 @@ var AvantGateControlLayer = class {
1126
1348
  }
1127
1349
  }
1128
1350
  throw lastError;
1129
- }
1130
- assembleResult(output) {
1351
+ };
1352
+ assembleResult = (output) => {
1131
1353
  const costUSD = this.calculateCost(
1132
1354
  output.modelUsed,
1133
1355
  output.usage.promptTokens,
@@ -1146,8 +1368,8 @@ var AvantGateControlLayer = class {
1146
1368
  failoverOccurred: output.failoverOccurred,
1147
1369
  attempts: output.attempts
1148
1370
  };
1149
- }
1150
- async notifyAuditSink(result) {
1371
+ };
1372
+ notifyAuditSink = async (result) => {
1151
1373
  if (!this.config.auditSink) {
1152
1374
  return;
1153
1375
  }
@@ -1159,16 +1381,16 @@ var AvantGateControlLayer = class {
1159
1381
  failoverOccurred: result.failoverOccurred,
1160
1382
  attempts: result.attempts
1161
1383
  });
1162
- }
1384
+ };
1163
1385
  /**
1164
1386
  * Exécute une requête avec garde d'entrée, masquage PII, garde pré-vol et calcul des coûts.
1165
1387
  */
1166
- async execute(options) {
1388
+ execute = async (options) => {
1167
1389
  const sanitizedQuery = this.applySecurityGuards(options.userQuery);
1168
1390
  const messages = this.buildMessages(options.systemPrompt, sanitizedQuery);
1169
1391
  const promptLength = (options.systemPrompt?.length ?? 0) + sanitizedQuery.length;
1170
1392
  const estimatedPromptTokens = Math.ceil(promptLength / 4);
1171
- this.checkPreflightBudget(estimatedPromptTokens, this.config.primary.model, this.config.primary.provider);
1393
+ await this.checkPreflightBudget(estimatedPromptTokens, this.config.primary.model, this.config.primary.provider);
1172
1394
  if (!options.providerOverride && this.getProviderChain().length === 0) {
1173
1395
  if (this.config.mockSimulation) {
1174
1396
  const simResult = this.executeSimulation(sanitizedQuery, options.systemPrompt);
@@ -1184,11 +1406,11 @@ var AvantGateControlLayer = class {
1184
1406
  this.checkPostExecutionBudget(result.tokens.total, result.costUSD);
1185
1407
  await this.notifyAuditSink(result);
1186
1408
  return result;
1187
- }
1409
+ };
1188
1410
  /**
1189
1411
  * Exécute une requête et valide/répare le résultat selon un schéma Zod.
1190
1412
  */
1191
- async executeStructured(options) {
1413
+ executeStructured = async (options) => {
1192
1414
  const rawResult = await this.execute({
1193
1415
  userQuery: options.userQuery,
1194
1416
  systemPrompt: options.systemPrompt,
@@ -1210,12 +1432,12 @@ var AvantGateControlLayer = class {
1210
1432
  modelUsed: rawResult.modelUsed,
1211
1433
  failoverOccurred: rawResult.failoverOccurred
1212
1434
  };
1213
- }
1435
+ };
1214
1436
  /**
1215
1437
  * Méthode unifiée de premier niveau pour l'extraction structurée sans code boilerplate.
1216
1438
  * Gère le failover multi-fournisseurs, les retries, la validation Zod et la normalisation financière.
1217
1439
  */
1218
- async generateStructuredOutput(options) {
1440
+ generateStructuredOutput = async (options) => {
1219
1441
  const maxRetries = options.maxRetries ?? this.config.retryOptions?.maxRetries ?? 2;
1220
1442
  const modelToUse = options.model ?? this.config.primary.model;
1221
1443
  const processedMessages = options.messages.map((msg) => {
@@ -1226,7 +1448,7 @@ var AvantGateControlLayer = class {
1226
1448
  });
1227
1449
  const promptLength = processedMessages.reduce((sum, msg) => sum + msg.content.length, 0);
1228
1450
  const estimatedPromptTokens = Math.ceil(promptLength / 4);
1229
- this.checkPreflightBudget(estimatedPromptTokens, modelToUse);
1451
+ await this.checkPreflightBudget(estimatedPromptTokens, modelToUse);
1230
1452
  let lastError;
1231
1453
  let accumulatedPromptTokens = 0;
1232
1454
  let accumulatedCompletionTokens = 0;
@@ -1314,11 +1536,11 @@ var AvantGateControlLayer = class {
1314
1536
  }
1315
1537
  }
1316
1538
  throw lastError;
1317
- }
1539
+ };
1318
1540
  };
1319
- function createLLMControlLayer(config) {
1541
+ var createLLMControlLayer = (config) => {
1320
1542
  return new AvantGateControlLayer(config);
1321
- }
1543
+ };
1322
1544
  var createAvantGate = createLLMControlLayer;
1323
1545
 
1324
1546
  // src/prompts/prompt-template.ts
@@ -1741,7 +1963,23 @@ function auditToolResult(data, options) {
1741
1963
  }
1742
1964
 
1743
1965
  // src/agent/isolated-tool.ts
1744
- async function verifyDataAccessGuard(guard, args, context, toolIdentifier) {
1966
+ var verifyRoles = (configuredRoles, context, toolIdentifier) => {
1967
+ if (!configuredRoles || configuredRoles.length === 0) {
1968
+ return;
1969
+ }
1970
+ const userRoles = [
1971
+ ...context.roles ?? [],
1972
+ ...context.role ? [context.role] : []
1973
+ ];
1974
+ const hasAllowedRole = configuredRoles.some((role) => userRoles.includes(role));
1975
+ if (!hasAllowedRole) {
1976
+ throw new ToolAccessDeniedError(
1977
+ toolIdentifier,
1978
+ "Access denied: insufficient role permissions"
1979
+ );
1980
+ }
1981
+ };
1982
+ var verifyDataAccessGuard = async (guard, args, context, toolIdentifier) => {
1745
1983
  if (!guard) {
1746
1984
  return;
1747
1985
  }
@@ -1749,8 +1987,55 @@ async function verifyDataAccessGuard(guard, args, context, toolIdentifier) {
1749
1987
  if (!isAllowed) {
1750
1988
  throw new ToolAccessDeniedError(toolIdentifier, "Access denied by data access guard");
1751
1989
  }
1752
- }
1753
- async function resolveInvalidationTags(config, args, rawResult, context) {
1990
+ };
1991
+ var verifyTenantIsolation = (assertTenant, rawResult, context, toolIdentifier) => {
1992
+ if (!assertTenant) {
1993
+ return;
1994
+ }
1995
+ if (!context.tenantId) {
1996
+ throw new ToolAccessDeniedError(
1997
+ toolIdentifier,
1998
+ "Access denied: missing session tenantId in execution context for multi-tenant tool"
1999
+ );
2000
+ }
2001
+ const recordTenantId = assertTenant(rawResult);
2002
+ if (recordTenantId && recordTenantId !== context.tenantId) {
2003
+ throw new ToolAccessDeniedError(
2004
+ toolIdentifier,
2005
+ `Cross-tenant IDOR access violation: record tenant '${recordTenantId}' does not match session tenant '${context.tenantId}'`
2006
+ );
2007
+ }
2008
+ };
2009
+ var verifyResourceOwnership = async (assertOwnership, rawResult, context, toolIdentifier) => {
2010
+ if (!assertOwnership) {
2011
+ return;
2012
+ }
2013
+ const isOwner = await assertOwnership(rawResult, context);
2014
+ if (!isOwner) {
2015
+ throw new ToolAccessDeniedError(
2016
+ toolIdentifier,
2017
+ "Ownership IDOR access violation: user does not own or have access to this resource"
2018
+ );
2019
+ }
2020
+ };
2021
+ var checkSuspiciousParameters = (parameters, toolName) => {
2022
+ if (!parameters || typeof parameters !== "object") {
2023
+ return;
2024
+ }
2025
+ const zodShape = parameters.shape;
2026
+ if (!zodShape || typeof zodShape !== "object") {
2027
+ return;
2028
+ }
2029
+ const suspiciousKeys = ["tenantId", "tenant_id", "ownerTenantId"];
2030
+ for (const key of suspiciousKeys) {
2031
+ if (key in zodShape) {
2032
+ console.warn(
2033
+ `[avantGate Security Warning] Tool '${toolName}' defines '${key}' as a model parameter. Tenancy should be inferred from the trusted server context (context.tenantId) rather than supplied by the untrusted model to prevent IDOR attacks.`
2034
+ );
2035
+ }
2036
+ }
2037
+ };
2038
+ var resolveInvalidationTags = async (config, args, rawResult, context) => {
1754
2039
  if (!config.invalidationTags) {
1755
2040
  return void 0;
1756
2041
  }
@@ -1759,33 +2044,29 @@ async function resolveInvalidationTags(config, args, rawResult, context) {
1759
2044
  await context.onInvalidationTags(tags);
1760
2045
  }
1761
2046
  return tags;
1762
- }
1763
- async function dispatchClientData(rawResult, callback) {
2047
+ };
2048
+ var dispatchClientData = async (rawResult, callback) => {
1764
2049
  if (!callback) {
1765
2050
  return;
1766
2051
  }
1767
2052
  await callback(rawResult);
1768
- }
1769
- async function produceLlmPayload(rawResult, args, context, transformer) {
2053
+ };
2054
+ var produceLlmPayload = async (rawResult, args, context, transformer) => {
1770
2055
  if (transformer) {
1771
2056
  return await transformer(rawResult, args, context);
1772
2057
  }
1773
2058
  return rawResult;
1774
- }
1775
- function validateLlmDto(payload, schema, toolIdentifier) {
2059
+ };
2060
+ var validateLlmDto = (payload, schema, toolIdentifier) => {
1776
2061
  const parseResult = schema.safeParse(payload);
1777
2062
  if (!parseResult.success) {
1778
2063
  const issues = parseResult.error.issues ?? [];
1779
2064
  const errorMessages = issues.map((issue) => `${issue.path.join(".") || "root"}: ${issue.message}`).join(", ");
1780
- throw new DtoValidationError(
1781
- toolIdentifier,
1782
- errorMessages,
1783
- issues
1784
- );
2065
+ throw new DtoValidationError(toolIdentifier, errorMessages, issues);
1785
2066
  }
1786
2067
  return parseResult.data;
1787
- }
1788
- function protectLlmPayload(payload, toolIdentifier, sanitizePii = true, throwOnPii = false) {
2068
+ };
2069
+ var protectLlmPayload = (payload, toolIdentifier, sanitizePii = true, throwOnPii = false) => {
1789
2070
  if (!sanitizePii) {
1790
2071
  return { sanitized: payload, count: 0 };
1791
2072
  }
@@ -1794,8 +2075,8 @@ function protectLlmPayload(payload, toolIdentifier, sanitizePii = true, throwOnP
1794
2075
  throwOnPii
1795
2076
  });
1796
2077
  return { sanitized: sanitizedData, count: maskedCount };
1797
- }
1798
- async function processLlmPayload(rawResult, args, context, config, toolIdentifier) {
2078
+ };
2079
+ var processLlmPayload = async (rawResult, args, context, config, toolIdentifier) => {
1799
2080
  let payload = await produceLlmPayload(rawResult, args, context, config.llmDto);
1800
2081
  if (config.llmDtoSchema) {
1801
2082
  payload = validateLlmDto(payload, config.llmDtoSchema, toolIdentifier);
@@ -1806,14 +2087,15 @@ async function processLlmPayload(rawResult, args, context, config, toolIdentifie
1806
2087
  config.sanitizePii !== false,
1807
2088
  config.throwOnPii === true
1808
2089
  );
1809
- }
1810
- function createIsolatedTool(config) {
2090
+ };
2091
+ var createIsolatedTool = (config) => {
1811
2092
  const toolId = config.id || config.name;
1812
2093
  const toolAlias = config.alias;
1813
2094
  const clientCallback = config.clientDto;
1814
2095
  const toolIdentifier = toolAlias || config.name;
1815
2096
  const toolImpact = config.impact ?? "READ_ONLY";
1816
2097
  const requireApproval = config.requireApproval ?? toolImpact === "DESTRUCTIVE";
2098
+ checkSuspiciousParameters(config.parameters, config.name);
1817
2099
  const tool = {
1818
2100
  description: config.description,
1819
2101
  parameters: config.parameters,
@@ -1829,11 +2111,12 @@ function createIsolatedTool(config) {
1829
2111
  _requireApproval: requireApproval,
1830
2112
  _lastPiiFilteredCount: 0,
1831
2113
  _lastInvalidationTags: void 0,
1832
- async execute(args, context) {
2114
+ execute: async (args, context) => {
1833
2115
  const updatedContext = {
1834
2116
  ...context,
1835
2117
  callChain: context?.callChain ?? Object.freeze([toolId])
1836
2118
  };
2119
+ verifyRoles(config.roles, updatedContext, toolIdentifier);
1837
2120
  await verifyDataAccessGuard(
1838
2121
  config.dataAccessGuard,
1839
2122
  args,
@@ -1841,6 +2124,13 @@ function createIsolatedTool(config) {
1841
2124
  toolIdentifier
1842
2125
  );
1843
2126
  const rawResult = await config.execute(args, updatedContext);
2127
+ verifyTenantIsolation(config.assertTenant, rawResult, updatedContext, toolIdentifier);
2128
+ await verifyResourceOwnership(
2129
+ config.assertOwnership,
2130
+ rawResult,
2131
+ updatedContext,
2132
+ toolIdentifier
2133
+ );
1844
2134
  const tags = await resolveInvalidationTags(
1845
2135
  config,
1846
2136
  args,
@@ -1863,7 +2153,7 @@ function createIsolatedTool(config) {
1863
2153
  }
1864
2154
  };
1865
2155
  return tool;
1866
- }
2156
+ };
1867
2157
 
1868
2158
  // src/workflow/errors.ts
1869
2159
  var WorkflowSagaRollbackError = class extends Error {
@@ -2169,6 +2459,7 @@ var defineWorkflow = (config) => {
2169
2459
  PromptRegistry,
2170
2460
  PromptTemplate,
2171
2461
  SEED_MODEL_PRICES,
2462
+ SqlitePricingAdapter,
2172
2463
  WorkflowAbortSignal,
2173
2464
  WorkflowSagaRollbackError,
2174
2465
  WorkflowValidationError,