avantgate 1.6.0 → 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 +61 -5
  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 +20 -3
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  extractAndCleanJSON,
3
3
  validateWithZod
4
- } from "./chunk-CO26LNFD.mjs";
4
+ } from "./chunk-36ULFTM2.mjs";
5
5
  import {
6
6
  WorkflowAbortSignal,
7
7
  WorkflowSagaRollbackError,
@@ -9,10 +9,13 @@ import {
9
9
  defineWorkflow,
10
10
  executeWorkflow,
11
11
  isWorkflowAbortSignal
12
- } from "./chunk-4XWO3NZW.mjs";
12
+ } from "./chunk-AH5XXSS4.mjs";
13
13
  import {
14
14
  sanitizePII
15
- } from "./chunk-5VA3EKPJ.mjs";
15
+ } from "./chunk-W27A25DK.mjs";
16
+ import {
17
+ __require
18
+ } from "./chunk-Y6FXYEAI.mjs";
16
19
 
17
20
  // src/types.ts
18
21
  var ConfigurationError = class extends Error {
@@ -28,6 +31,213 @@ var BudgetExceededError = class extends Error {
28
31
  }
29
32
  };
30
33
 
34
+ // src/sqlite-pricing-adapter.ts
35
+ import fs from "fs";
36
+ import path from "path";
37
+ var normalizeIdentifier = (val) => {
38
+ return val.trim().toLowerCase().replace(":", "/");
39
+ };
40
+ var SqlitePricingAdapter = class {
41
+ db;
42
+ tableName;
43
+ constructor(options = {}) {
44
+ this.tableName = options.tableName ?? "model_pricing";
45
+ this.db = options.db ?? this.initDatabase(options.dbPath ?? ":memory:");
46
+ this.initSchema();
47
+ if (options.autoSeed) {
48
+ this.seedDefaultPrices(false);
49
+ }
50
+ }
51
+ initDatabase = (dbPath) => {
52
+ if (dbPath !== ":memory:") {
53
+ const dir = path.dirname(path.resolve(dbPath));
54
+ if (!fs.existsSync(dir)) {
55
+ fs.mkdirSync(dir, { recursive: true });
56
+ }
57
+ }
58
+ try {
59
+ const { DatabaseSync } = __require("sqlite");
60
+ return new DatabaseSync(dbPath);
61
+ } catch (err) {
62
+ throw new ConfigurationError(
63
+ `[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)}`
64
+ );
65
+ }
66
+ };
67
+ initSchema = () => {
68
+ this.db.exec(`
69
+ CREATE TABLE IF NOT EXISTS ${this.tableName} (
70
+ provider TEXT NOT NULL,
71
+ model TEXT NOT NULL,
72
+ prompt_usd_per_million REAL NOT NULL,
73
+ completion_usd_per_million REAL NOT NULL,
74
+ cache_hit_usd_per_million REAL,
75
+ is_active INTEGER DEFAULT 1,
76
+ updated_at TEXT NOT NULL,
77
+ PRIMARY KEY (provider, model)
78
+ );
79
+ CREATE INDEX IF NOT EXISTS idx_${this.tableName}_lookup
80
+ ON ${this.tableName}(provider, model, is_active);
81
+ `);
82
+ };
83
+ /**
84
+ * Implémentation du port avantGate PricingAdapter.
85
+ * Résolution hiérarchique : (provider, model) -> (provider/model) -> (model).
86
+ */
87
+ fetchPrice = (model, provider) => {
88
+ const normModel = normalizeIdentifier(model);
89
+ const normProvider = provider ? normalizeIdentifier(provider) : void 0;
90
+ if (normProvider) {
91
+ const row = this.queryActiveRow(normProvider, normModel);
92
+ if (row) return this.mapRowToPrice(row);
93
+ }
94
+ if (normModel.includes("/")) {
95
+ const firstSlashIdx = normModel.indexOf("/");
96
+ const extractedProvider = normModel.slice(0, firstSlashIdx);
97
+ const extractedModel = normModel.slice(firstSlashIdx + 1);
98
+ const splitRow = this.queryActiveRow(extractedProvider, extractedModel);
99
+ if (splitRow) return this.mapRowToPrice(splitRow);
100
+ }
101
+ const directRow = this.queryByModelOnly(normModel);
102
+ if (directRow) return this.mapRowToPrice(directRow);
103
+ return void 0;
104
+ };
105
+ queryActiveRow = (provider, model) => {
106
+ const stmt = this.db.prepare(`
107
+ SELECT provider, model, prompt_usd_per_million, completion_usd_per_million, cache_hit_usd_per_million, is_active, updated_at
108
+ FROM ${this.tableName}
109
+ WHERE provider = ? AND model = ? AND is_active = 1
110
+ LIMIT 1
111
+ `);
112
+ return stmt.get(provider, model);
113
+ };
114
+ queryByModelOnly = (model) => {
115
+ const stmt = this.db.prepare(`
116
+ SELECT provider, model, prompt_usd_per_million, completion_usd_per_million, cache_hit_usd_per_million, is_active, updated_at
117
+ FROM ${this.tableName}
118
+ WHERE model = ? AND is_active = 1
119
+ LIMIT 1
120
+ `);
121
+ return stmt.get(model);
122
+ };
123
+ mapRowToPrice = (row) => {
124
+ return {
125
+ promptUSDPerMillion: Number(row.prompt_usd_per_million),
126
+ completionUSDPerMillion: Number(row.completion_usd_per_million),
127
+ cacheHitUSDPerMillion: row.cache_hit_usd_per_million != null ? Number(row.cache_hit_usd_per_million) : void 0
128
+ };
129
+ };
130
+ /**
131
+ * Enregistre ou met à jour la tarification d'un modèle.
132
+ */
133
+ upsertPrice = (provider, model, price, isActive = true) => {
134
+ const normProvider = normalizeIdentifier(provider);
135
+ const normModel = normalizeIdentifier(model);
136
+ const now = (/* @__PURE__ */ new Date()).toISOString();
137
+ const stmt = this.db.prepare(`
138
+ INSERT OR REPLACE INTO ${this.tableName}
139
+ (provider, model, prompt_usd_per_million, completion_usd_per_million, cache_hit_usd_per_million, is_active, updated_at)
140
+ VALUES (?, ?, ?, ?, ?, ?, ?)
141
+ `);
142
+ stmt.run(
143
+ normProvider,
144
+ normModel,
145
+ price.promptUSDPerMillion,
146
+ price.completionUSDPerMillion,
147
+ price.cacheHitUSDPerMillion ?? null,
148
+ isActive ? 1 : 0,
149
+ now
150
+ );
151
+ };
152
+ /**
153
+ * Supprime une règle tarifaire de la base de données.
154
+ */
155
+ deletePrice = (provider, model) => {
156
+ const normProvider = normalizeIdentifier(provider);
157
+ const normModel = normalizeIdentifier(model);
158
+ const stmt = this.db.prepare(`
159
+ DELETE FROM ${this.tableName}
160
+ WHERE provider = ? AND model = ?
161
+ `);
162
+ const result = stmt.run(normProvider, normModel);
163
+ return Boolean(result && typeof result.changes === "number" && result.changes > 0);
164
+ };
165
+ /**
166
+ * Retourne l'ensemble des règles tarifaires enregistrées.
167
+ */
168
+ getAllPrices = () => {
169
+ const stmt = this.db.prepare(`
170
+ SELECT provider, model, prompt_usd_per_million, completion_usd_per_million, cache_hit_usd_per_million, is_active, updated_at
171
+ FROM ${this.tableName}
172
+ ORDER BY provider ASC, model ASC
173
+ `);
174
+ const rows = stmt.all();
175
+ return rows.map((row) => ({
176
+ provider: row.provider,
177
+ model: row.model,
178
+ price: this.mapRowToPrice(row),
179
+ isActive: Boolean(row.is_active),
180
+ updatedAt: row.updated_at
181
+ }));
182
+ };
183
+ /**
184
+ * Remplit la base avec le catalogue de départ SEED_MODEL_PRICES.
185
+ * @param force Si true, écrase les tarifs existants. Si false, insère uniquement les modèles manquants.
186
+ * @returns Le nombre d'enregistrements insérés.
187
+ */
188
+ seedDefaultPrices = (force = false) => {
189
+ const conflictClause = force ? "INSERT OR REPLACE" : "INSERT OR IGNORE";
190
+ const stmt = this.db.prepare(`
191
+ ${conflictClause} INTO ${this.tableName}
192
+ (provider, model, prompt_usd_per_million, completion_usd_per_million, cache_hit_usd_per_million, is_active, updated_at)
193
+ VALUES (?, ?, ?, ?, ?, ?, ?)
194
+ `);
195
+ let inserted = 0;
196
+ const now = (/* @__PURE__ */ new Date()).toISOString();
197
+ for (const [key, price] of Object.entries(SEED_MODEL_PRICES)) {
198
+ const normKey = normalizeIdentifier(key);
199
+ let provider = "direct";
200
+ let model = normKey;
201
+ if (normKey.includes("/")) {
202
+ const slashIdx = normKey.indexOf("/");
203
+ provider = normKey.slice(0, slashIdx);
204
+ model = normKey.slice(slashIdx + 1);
205
+ }
206
+ const res1 = stmt.run(
207
+ provider,
208
+ model,
209
+ price.promptUSDPerMillion,
210
+ price.completionUSDPerMillion,
211
+ price.cacheHitUSDPerMillion ?? null,
212
+ 1,
213
+ now
214
+ );
215
+ if (res1?.changes && res1.changes > 0) inserted++;
216
+ if (provider !== "direct") {
217
+ const res2 = stmt.run(
218
+ "direct",
219
+ normKey,
220
+ price.promptUSDPerMillion,
221
+ price.completionUSDPerMillion,
222
+ price.cacheHitUSDPerMillion ?? null,
223
+ 1,
224
+ now
225
+ );
226
+ if (res2?.changes && res2.changes > 0) inserted++;
227
+ }
228
+ }
229
+ return inserted;
230
+ };
231
+ /**
232
+ * Ferme la connexion SQLite sous-jacente si supporté.
233
+ */
234
+ close = () => {
235
+ if (typeof this.db.close === "function") {
236
+ this.db.close();
237
+ }
238
+ };
239
+ };
240
+
31
241
  // src/pricing.ts
32
242
  var SEED_MODEL_PRICES = {
33
243
  // DeepSeek Direct
@@ -52,9 +262,9 @@ var SEED_MODEL_PRICES = {
52
262
  // Local Ollama (Toujours $0)
53
263
  "ollama": { promptUSDPerMillion: 0, completionUSDPerMillion: 0 }
54
264
  };
55
- function normalizeKey(identifier) {
265
+ var normalizeKey = (identifier) => {
56
266
  return identifier.trim().toLowerCase().replace(":", "/");
57
- }
267
+ };
58
268
  var CachedPricingAdapter = class {
59
269
  cache = /* @__PURE__ */ new Map();
60
270
  ttlMs;
@@ -63,7 +273,7 @@ var CachedPricingAdapter = class {
63
273
  this.delegate = delegate;
64
274
  this.ttlMs = ttlMs;
65
275
  }
66
- async fetchPrice(model, provider) {
276
+ fetchPrice = async (model, provider) => {
67
277
  const key = provider ? normalizeKey(`${provider}/${model}`) : normalizeKey(model);
68
278
  const cached = this.cache.get(key);
69
279
  if (cached && Date.now() < cached.expiresAt) {
@@ -81,72 +291,76 @@ var CachedPricingAdapter = class {
81
291
  }
82
292
  }
83
293
  return void 0;
84
- }
85
- peek(model, provider) {
294
+ };
295
+ peek = (model, provider) => {
86
296
  const key = provider ? normalizeKey(`${provider}/${model}`) : normalizeKey(model);
87
- return this.cache.get(key)?.price;
88
- }
89
- clearCache() {
297
+ const cached = this.cache.get(key);
298
+ if (cached && Date.now() < cached.expiresAt) {
299
+ return cached.price;
300
+ }
301
+ return void 0;
302
+ };
303
+ clearCache = () => {
90
304
  this.cache.clear();
91
- }
92
- invalidate(model, provider) {
305
+ };
306
+ invalidate = (model, provider) => {
93
307
  if (!model) {
94
308
  this.clearCache();
95
309
  return;
96
310
  }
97
311
  const key = provider ? normalizeKey(`${provider}/${model}`) : normalizeKey(model);
98
312
  this.cache.delete(key);
99
- }
313
+ };
100
314
  };
101
- var PricingRegistry = class {
315
+ var PricingRegistry = class _PricingRegistry {
102
316
  static prices = /* @__PURE__ */ new Map();
103
317
  static adapter;
104
- static registerPrice(identifier, price) {
105
- this.prices.set(normalizeKey(identifier), price);
106
- }
107
- static registerDistributorPrices(distributor, priceMap) {
318
+ static registerPrice = (identifier, price) => {
319
+ _PricingRegistry.prices.set(normalizeKey(identifier), price);
320
+ };
321
+ static registerDistributorPrices = (distributor, priceMap) => {
108
322
  for (const [model, price] of Object.entries(priceMap)) {
109
- this.prices.set(normalizeKey(`${distributor}/${model}`), price);
323
+ _PricingRegistry.prices.set(normalizeKey(`${distributor}/${model}`), price);
110
324
  }
111
- }
112
- static registerPrices(prices) {
325
+ };
326
+ static registerPrices = (prices) => {
113
327
  for (const [key, price] of Object.entries(prices)) {
114
- this.prices.set(normalizeKey(key), price);
328
+ _PricingRegistry.prices.set(normalizeKey(key), price);
115
329
  }
116
- }
117
- static getPrice(model, provider) {
330
+ };
331
+ static getPrice = (model, provider) => {
118
332
  if (provider) {
119
333
  const distributorKey = normalizeKey(`${provider}/${model}`);
120
- const directDistributorPrice = this.prices.get(distributorKey);
334
+ const directDistributorPrice = _PricingRegistry.prices.get(distributorKey);
121
335
  if (directDistributorPrice) {
122
336
  return directDistributorPrice;
123
337
  }
124
338
  }
125
- return this.prices.get(normalizeKey(model));
126
- }
127
- static setAdapter(adapter) {
128
- this.adapter = adapter;
129
- }
130
- static getAdapter() {
131
- return this.adapter;
132
- }
133
- static clear() {
134
- this.prices.clear();
135
- this.adapter = void 0;
136
- }
339
+ return _PricingRegistry.prices.get(normalizeKey(model));
340
+ };
341
+ static setAdapter = (adapter) => {
342
+ _PricingRegistry.adapter = adapter;
343
+ };
344
+ static getAdapter = () => {
345
+ return _PricingRegistry.adapter;
346
+ };
347
+ static clear = () => {
348
+ _PricingRegistry.prices.clear();
349
+ _PricingRegistry.adapter = void 0;
350
+ };
137
351
  /**
138
352
  * Réinitialise le registre en chargeant le catalogue d'exemple SEED_MODEL_PRICES.
139
353
  */
140
- static loadSeedPrices() {
141
- this.registerPrices(SEED_MODEL_PRICES);
142
- }
143
- static getAllPrices() {
354
+ static loadSeedPrices = () => {
355
+ _PricingRegistry.registerPrices(SEED_MODEL_PRICES);
356
+ };
357
+ static getAllPrices = () => {
144
358
  const out = {};
145
- for (const [k, v] of this.prices.entries()) {
359
+ for (const [k, v] of _PricingRegistry.prices.entries()) {
146
360
  out[k] = v;
147
361
  }
148
362
  return out;
149
- }
363
+ };
150
364
  };
151
365
  var DEFAULT_MODEL_PRICES = new Proxy({}, {
152
366
  get(_target, prop) {
@@ -166,7 +380,7 @@ var DEFAULT_MODEL_PRICES = new Proxy({}, {
166
380
  return void 0;
167
381
  }
168
382
  });
169
- function resolveModelPrice(model, options) {
383
+ var resolveModelPrice = (model, options) => {
170
384
  const opts = typeof options === "string" ? { provider: options } : options ?? {};
171
385
  if (opts.providerPricing) {
172
386
  return opts.providerPricing;
@@ -197,8 +411,8 @@ function resolveModelPrice(model, options) {
197
411
  return { promptUSDPerMillion: 0, completionUSDPerMillion: 0 };
198
412
  }
199
413
  return void 0;
200
- }
201
- async function resolveModelPriceAsync(model, options) {
414
+ };
415
+ var resolveModelPriceAsync = async (model, options) => {
202
416
  const opts = typeof options === "string" ? { provider: options } : options ?? {};
203
417
  const activeAdapter = opts.adapter ?? PricingRegistry.getAdapter();
204
418
  if (activeAdapter) {
@@ -211,8 +425,8 @@ async function resolveModelPriceAsync(model, options) {
211
425
  }
212
426
  }
213
427
  return resolveModelPrice(model, options);
214
- }
215
- function calculateCostUSD(model, promptTokens, completionTokens, cacheHitTokens = 0, options) {
428
+ };
429
+ var calculateCostUSD = (model, promptTokens, completionTokens, cacheHitTokens = 0, options) => {
216
430
  const pricing = resolveModelPrice(model, options);
217
431
  if (!pricing) {
218
432
  return 0;
@@ -221,7 +435,7 @@ function calculateCostUSD(model, promptTokens, completionTokens, cacheHitTokens
221
435
  const completionCost = completionTokens / 1e6 * pricing.completionUSDPerMillion;
222
436
  const cacheDiscount = cacheHitTokens && pricing.cacheHitUSDPerMillion ? cacheHitTokens / 1e6 * (pricing.promptUSDPerMillion - pricing.cacheHitUSDPerMillion) : 0;
223
437
  return Math.max(0, promptCost + completionCost - cacheDiscount);
224
- }
438
+ };
225
439
 
226
440
  // src/input-guard.ts
227
441
  var INJECTION_PATTERNS = [
@@ -232,7 +446,7 @@ var INJECTION_PATTERNS = [
232
446
  /output\s+(?:your\s+)?(?:system\s+prompt|initial\s+instructions)/i,
233
447
  /repeat\s+(?:the\s+words\s+above|everything\s+above)/i
234
448
  ];
235
- function validateUserInput(input, options) {
449
+ var validateUserInput = (input, options) => {
236
450
  const maxLength = options?.maxLength ?? 5e4;
237
451
  if (input.length > maxLength) {
238
452
  return {
@@ -251,7 +465,7 @@ function validateUserInput(input, options) {
251
465
  }
252
466
  }
253
467
  return { valid: true };
254
- }
468
+ };
255
469
 
256
470
  // src/providers/http-client.ts
257
471
  var DEFAULT_BASE_URLS = {
@@ -272,14 +486,14 @@ var HttpProviderClient = class {
272
486
  this.apiKey = config.apiKey;
273
487
  this.baseUrl = config.baseUrl || DEFAULT_BASE_URLS[config.provider] || "https://api.openai.com/v1";
274
488
  }
275
- resolveEndpoint() {
489
+ resolveEndpoint = () => {
276
490
  const trimmed = this.baseUrl.replace(/\/+$/, "");
277
491
  if (trimmed.endsWith("/chat/completions")) {
278
492
  return trimmed;
279
493
  }
280
494
  return `${trimmed}/chat/completions`;
281
- }
282
- buildHeaders() {
495
+ };
496
+ buildHeaders = () => {
283
497
  const headers = {
284
498
  "Content-Type": "application/json"
285
499
  };
@@ -291,8 +505,8 @@ var HttpProviderClient = class {
291
505
  headers["X-Title"] = "AvantGate";
292
506
  }
293
507
  return headers;
294
- }
295
- buildPayload(options, model) {
508
+ };
509
+ buildPayload = (options, model) => {
296
510
  return {
297
511
  model,
298
512
  messages: options.messages.map((m) => ({
@@ -302,8 +516,8 @@ var HttpProviderClient = class {
302
516
  temperature: options.temperature ?? 0.2,
303
517
  ...options.responseFormat ? { response_format: options.responseFormat } : {}
304
518
  };
305
- }
306
- extractUsage(usageData) {
519
+ };
520
+ extractUsage = (usageData) => {
307
521
  if (!usageData) {
308
522
  return void 0;
309
523
  }
@@ -313,8 +527,8 @@ var HttpProviderClient = class {
313
527
  totalTokens: usageData.total_tokens,
314
528
  promptCacheHitTokens: usageData.prompt_tokens_details?.cached_tokens
315
529
  };
316
- }
317
- async complete(options) {
530
+ };
531
+ complete = async (options) => {
318
532
  const endpoint = this.resolveEndpoint();
319
533
  const model = options.model ?? "default";
320
534
  const headers = this.buildHeaders();
@@ -334,11 +548,11 @@ var HttpProviderClient = class {
334
548
  const text = data.choices?.[0]?.message?.content ?? "";
335
549
  const usage = this.extractUsage(data.usage);
336
550
  return { text, usage };
337
- }
551
+ };
338
552
  };
339
- function createHttpProviderClient(config) {
553
+ var createHttpProviderClient = (config) => {
340
554
  return new HttpProviderClient(config);
341
- }
555
+ };
342
556
 
343
557
  // src/control-layer.ts
344
558
  var AvantGateControlLayer = class {
@@ -358,7 +572,7 @@ var AvantGateControlLayer = class {
358
572
  );
359
573
  }
360
574
  }
361
- resolveProviderConfig(provider) {
575
+ resolveProviderConfig = (provider) => {
362
576
  if (!provider) return void 0;
363
577
  if (provider.client) return provider;
364
578
  if (provider.apiKey || provider.baseUrl || provider.provider === "ollama") {
@@ -368,8 +582,8 @@ var AvantGateControlLayer = class {
368
582
  };
369
583
  }
370
584
  return provider;
371
- }
372
- findProviderConfig(provider, model) {
585
+ };
586
+ findProviderConfig = (provider, model) => {
373
587
  const list = [this.config.primary, this.config.fallback, this.config.emergencyFallback].filter(
374
588
  (p) => Boolean(p)
375
589
  );
@@ -382,8 +596,8 @@ var AvantGateControlLayer = class {
382
596
  if (matchModel) return matchModel;
383
597
  }
384
598
  return this.config.primary;
385
- }
386
- calculateCost(model, promptTokens, completionTokens, cacheHitTokens = 0, provider) {
599
+ };
600
+ calculateCost = (model, promptTokens, completionTokens, cacheHitTokens = 0, provider) => {
387
601
  const providerCfg = this.findProviderConfig(provider, model);
388
602
  return calculateCostUSD(model, promptTokens, completionTokens, cacheHitTokens, {
389
603
  provider: provider ?? providerCfg?.provider,
@@ -391,8 +605,8 @@ var AvantGateControlLayer = class {
391
605
  customPricing: this.config.customPricing,
392
606
  adapter: this.cachedPricingAdapter
393
607
  });
394
- }
395
- applySecurityGuards(userQuery) {
608
+ };
609
+ applySecurityGuards = (userQuery) => {
396
610
  const guard = validateUserInput(userQuery, {
397
611
  detectInjection: this.config.security?.detectPromptInjection,
398
612
  maxLength: this.config.security?.maxInputLength
@@ -404,8 +618,8 @@ var AvantGateControlLayer = class {
404
618
  return sanitizePII(userQuery).text;
405
619
  }
406
620
  return userQuery;
407
- }
408
- checkPreflightBudget(estimatedPromptTokens, targetModel, provider) {
621
+ };
622
+ checkPreflightBudget = async (estimatedPromptTokens, targetModel, provider) => {
409
623
  if (this.config.maxTokenBudget !== void 0 && estimatedPromptTokens > this.config.maxTokenBudget) {
410
624
  throw new BudgetExceededError(
411
625
  `[AvantGate Budget Guard] Pre-flight token budget exceeded: estimated prompt (${estimatedPromptTokens} tokens) exceeds maxTokenBudget (${this.config.maxTokenBudget}).`
@@ -414,7 +628,7 @@ var AvantGateControlLayer = class {
414
628
  if (this.config.maxCostUSD !== void 0) {
415
629
  const isLocalFree = provider === "ollama" || targetModel.toLowerCase().includes("ollama");
416
630
  const providerCfg = this.findProviderConfig(provider, targetModel);
417
- const price = resolveModelPrice(targetModel, {
631
+ const price = await resolveModelPriceAsync(targetModel, {
418
632
  provider: provider ?? providerCfg?.provider,
419
633
  providerPricing: providerCfg?.pricing,
420
634
  customPricing: this.config.customPricing,
@@ -432,8 +646,8 @@ var AvantGateControlLayer = class {
432
646
  );
433
647
  }
434
648
  }
435
- }
436
- checkPostExecutionBudget(tokensTotal, costUSD) {
649
+ };
650
+ checkPostExecutionBudget = (tokensTotal, costUSD) => {
437
651
  if (this.config.maxTokenBudget !== void 0 && tokensTotal > this.config.maxTokenBudget) {
438
652
  throw new BudgetExceededError(
439
653
  `[AvantGate Budget Guard] Execution total tokens (${tokensTotal}) exceeded maxTokenBudget (${this.config.maxTokenBudget}).`
@@ -444,16 +658,16 @@ var AvantGateControlLayer = class {
444
658
  `[AvantGate Budget Guard] Execution cost ($${costUSD.toFixed(6)}) exceeded maxCostUSD ($${this.config.maxCostUSD}).`
445
659
  );
446
660
  }
447
- }
448
- buildMessages(systemPrompt, query) {
661
+ };
662
+ buildMessages = (systemPrompt, query) => {
449
663
  const messages = [];
450
664
  if (systemPrompt) {
451
665
  messages.push({ role: "system", content: systemPrompt });
452
666
  }
453
667
  messages.push({ role: "user", content: query });
454
668
  return messages;
455
- }
456
- resolveTokens(rawUsage, query, text) {
669
+ };
670
+ resolveTokens = (rawUsage, query, text) => {
457
671
  const promptTokens = rawUsage?.promptTokens ?? Math.ceil(query.length / 4);
458
672
  const completionTokens = rawUsage?.completionTokens ?? Math.ceil(text.length / 4);
459
673
  const totalTokens = rawUsage?.totalTokens ?? promptTokens + completionTokens;
@@ -463,15 +677,15 @@ var AvantGateControlLayer = class {
463
677
  totalTokens,
464
678
  promptCacheHitTokens: rawUsage?.promptCacheHitTokens
465
679
  };
466
- }
467
- getProviderChain() {
680
+ };
681
+ getProviderChain = () => {
468
682
  return [
469
683
  this.config.primary,
470
684
  this.config.fallback,
471
685
  this.config.emergencyFallback
472
686
  ].filter((provider) => Boolean(provider?.client));
473
- }
474
- executeSimulation(query, systemPrompt) {
687
+ };
688
+ executeSimulation = (query, systemPrompt) => {
475
689
  const promptTokens = Math.ceil(((systemPrompt?.length ?? 0) + query.length) / 4);
476
690
  const completionTokens = 50;
477
691
  const cost = this.calculateCost(this.config.primary.model, promptTokens, completionTokens);
@@ -487,8 +701,8 @@ var AvantGateControlLayer = class {
487
701
  failoverOccurred: false,
488
702
  attempts: 1
489
703
  };
490
- }
491
- async executeOverrideProvider(provider, messages, query, temperature) {
704
+ };
705
+ executeOverrideProvider = async (provider, messages, query, temperature) => {
492
706
  const response = await provider.complete({
493
707
  model: this.config.primary.model,
494
708
  messages,
@@ -502,8 +716,8 @@ var AvantGateControlLayer = class {
502
716
  failoverOccurred: false,
503
717
  attempts: 1
504
718
  };
505
- }
506
- async executeProviderPipeline(messages, query, temperature, modelOverride) {
719
+ };
720
+ executeProviderPipeline = async (messages, query, temperature, modelOverride) => {
507
721
  const chain = this.getProviderChain();
508
722
  let lastError;
509
723
  for (let index = 0; index < chain.length; index++) {
@@ -528,8 +742,8 @@ var AvantGateControlLayer = class {
528
742
  }
529
743
  }
530
744
  throw lastError;
531
- }
532
- assembleResult(output) {
745
+ };
746
+ assembleResult = (output) => {
533
747
  const costUSD = this.calculateCost(
534
748
  output.modelUsed,
535
749
  output.usage.promptTokens,
@@ -548,8 +762,8 @@ var AvantGateControlLayer = class {
548
762
  failoverOccurred: output.failoverOccurred,
549
763
  attempts: output.attempts
550
764
  };
551
- }
552
- async notifyAuditSink(result) {
765
+ };
766
+ notifyAuditSink = async (result) => {
553
767
  if (!this.config.auditSink) {
554
768
  return;
555
769
  }
@@ -561,16 +775,16 @@ var AvantGateControlLayer = class {
561
775
  failoverOccurred: result.failoverOccurred,
562
776
  attempts: result.attempts
563
777
  });
564
- }
778
+ };
565
779
  /**
566
780
  * Exécute une requête avec garde d'entrée, masquage PII, garde pré-vol et calcul des coûts.
567
781
  */
568
- async execute(options) {
782
+ execute = async (options) => {
569
783
  const sanitizedQuery = this.applySecurityGuards(options.userQuery);
570
784
  const messages = this.buildMessages(options.systemPrompt, sanitizedQuery);
571
785
  const promptLength = (options.systemPrompt?.length ?? 0) + sanitizedQuery.length;
572
786
  const estimatedPromptTokens = Math.ceil(promptLength / 4);
573
- this.checkPreflightBudget(estimatedPromptTokens, this.config.primary.model, this.config.primary.provider);
787
+ await this.checkPreflightBudget(estimatedPromptTokens, this.config.primary.model, this.config.primary.provider);
574
788
  if (!options.providerOverride && this.getProviderChain().length === 0) {
575
789
  if (this.config.mockSimulation) {
576
790
  const simResult = this.executeSimulation(sanitizedQuery, options.systemPrompt);
@@ -586,11 +800,11 @@ var AvantGateControlLayer = class {
586
800
  this.checkPostExecutionBudget(result.tokens.total, result.costUSD);
587
801
  await this.notifyAuditSink(result);
588
802
  return result;
589
- }
803
+ };
590
804
  /**
591
805
  * Exécute une requête et valide/répare le résultat selon un schéma Zod.
592
806
  */
593
- async executeStructured(options) {
807
+ executeStructured = async (options) => {
594
808
  const rawResult = await this.execute({
595
809
  userQuery: options.userQuery,
596
810
  systemPrompt: options.systemPrompt,
@@ -612,12 +826,12 @@ var AvantGateControlLayer = class {
612
826
  modelUsed: rawResult.modelUsed,
613
827
  failoverOccurred: rawResult.failoverOccurred
614
828
  };
615
- }
829
+ };
616
830
  /**
617
831
  * Méthode unifiée de premier niveau pour l'extraction structurée sans code boilerplate.
618
832
  * Gère le failover multi-fournisseurs, les retries, la validation Zod et la normalisation financière.
619
833
  */
620
- async generateStructuredOutput(options) {
834
+ generateStructuredOutput = async (options) => {
621
835
  const maxRetries = options.maxRetries ?? this.config.retryOptions?.maxRetries ?? 2;
622
836
  const modelToUse = options.model ?? this.config.primary.model;
623
837
  const processedMessages = options.messages.map((msg) => {
@@ -628,7 +842,7 @@ var AvantGateControlLayer = class {
628
842
  });
629
843
  const promptLength = processedMessages.reduce((sum, msg) => sum + msg.content.length, 0);
630
844
  const estimatedPromptTokens = Math.ceil(promptLength / 4);
631
- this.checkPreflightBudget(estimatedPromptTokens, modelToUse);
845
+ await this.checkPreflightBudget(estimatedPromptTokens, modelToUse);
632
846
  let lastError;
633
847
  let accumulatedPromptTokens = 0;
634
848
  let accumulatedCompletionTokens = 0;
@@ -716,11 +930,11 @@ var AvantGateControlLayer = class {
716
930
  }
717
931
  }
718
932
  throw lastError;
719
- }
933
+ };
720
934
  };
721
- function createLLMControlLayer(config) {
935
+ var createLLMControlLayer = (config) => {
722
936
  return new AvantGateControlLayer(config);
723
- }
937
+ };
724
938
  var createAvantGate = createLLMControlLayer;
725
939
 
726
940
  // src/prompts/prompt-template.ts
@@ -1051,6 +1265,7 @@ export {
1051
1265
  PromptRegistry,
1052
1266
  PromptTemplate,
1053
1267
  SEED_MODEL_PRICES,
1268
+ SqlitePricingAdapter,
1054
1269
  WorkflowAbortSignal,
1055
1270
  WorkflowSagaRollbackError,
1056
1271
  WorkflowValidationError,