avantgate 1.1.0 → 1.1.2
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.
- package/README.md +45 -232
- package/dist/agent/index.d.mts +743 -0
- package/dist/agent/index.d.ts +743 -0
- package/dist/agent/index.js +1803 -0
- package/dist/agent/index.mjs +1700 -0
- package/dist/chunk-DVCF4CSV.mjs +56 -0
- package/dist/index.d.mts +89 -7
- package/dist/index.d.ts +89 -7
- package/dist/index.js +432 -51
- package/dist/index.mjs +424 -104
- package/package.json +19 -4
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// src/sanitizer.ts
|
|
2
|
+
var EMAIL_REGEX = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b/g;
|
|
3
|
+
var PHONE_FR_REGEX = /\b(?:(?:\+|00)33|0)\s*[1-9](?:[\s.-]*\d{2}){4}\b/g;
|
|
4
|
+
var NIR_SSN_REGEX = /\b[12]\s*\d{2}\s*(?:0[1-9]|1[0-2]|[2-9]\d)\s*(?:0[1-9]|[1-8]\d|9[0-8]|2[ABab])\s*(?!000)\d{3}\s*(?!000)\d{3}(?:\s*\d{2})?\b/g;
|
|
5
|
+
var SPI_LABELLED_REGEX = /(?:(?:num[ée]ro\s+fiscal|spi|n[°o]\s*fiscal|d[ée]clarant(?: fiscal)?)\s*[:=]?\s*)\b(\d{2}(?:[\s.-]?\d{2}){5}[\s.-]?\d|\d{13})\b/gi;
|
|
6
|
+
var SPI_FORMATTED_REGEX = /\b[0-3]\d(?:\s+\d{2}){5}\s+\d\b/g;
|
|
7
|
+
var IBAN_REGEX = /\b[A-Z]{2}\s*[0-9]{2}(?:[\s\r\n.-]*[A-Z0-9]){11,30}\b/g;
|
|
8
|
+
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;
|
|
9
|
+
function sanitizePII(input) {
|
|
10
|
+
let count = 0;
|
|
11
|
+
let result = input;
|
|
12
|
+
result = result.replace(EMAIL_REGEX, () => {
|
|
13
|
+
count++;
|
|
14
|
+
return "[REDACTED_EMAIL]";
|
|
15
|
+
});
|
|
16
|
+
result = result.replace(PHONE_FR_REGEX, () => {
|
|
17
|
+
count++;
|
|
18
|
+
return "[REDACTED_PHONE]";
|
|
19
|
+
});
|
|
20
|
+
result = result.replace(IBAN_REGEX, (match) => {
|
|
21
|
+
const cleanChars = match.replace(/[\s\r\n.-]/g, "");
|
|
22
|
+
if (cleanChars.length >= 15 && cleanChars.length <= 34) {
|
|
23
|
+
count++;
|
|
24
|
+
return "[REDACTED_IBAN]";
|
|
25
|
+
}
|
|
26
|
+
return match;
|
|
27
|
+
});
|
|
28
|
+
result = result.replace(BIC_LABELLED_REGEX, (_, bicCode) => {
|
|
29
|
+
count++;
|
|
30
|
+
return `[REDACTED_BIC: ${bicCode.slice(0, 4)}****]`;
|
|
31
|
+
});
|
|
32
|
+
result = result.replace(SPI_LABELLED_REGEX, (fullMatch, digits) => {
|
|
33
|
+
count++;
|
|
34
|
+
return fullMatch.replace(digits, "[REDACTED_SPI]");
|
|
35
|
+
});
|
|
36
|
+
result = result.replace(NIR_SSN_REGEX, (match) => {
|
|
37
|
+
const rawDigits = match.replace(/\s+/g, "");
|
|
38
|
+
if (rawDigits.length === 13 || rawDigits.length === 15) {
|
|
39
|
+
count++;
|
|
40
|
+
return "[REDACTED_NIR]";
|
|
41
|
+
}
|
|
42
|
+
return match;
|
|
43
|
+
});
|
|
44
|
+
result = result.replace(SPI_FORMATTED_REGEX, (match) => {
|
|
45
|
+
if (!match.includes("[REDACTED")) {
|
|
46
|
+
count++;
|
|
47
|
+
return "[REDACTED_SPI]";
|
|
48
|
+
}
|
|
49
|
+
return match;
|
|
50
|
+
});
|
|
51
|
+
return { text: result, maskedCount: count };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export {
|
|
55
|
+
sanitizePII
|
|
56
|
+
};
|
package/dist/index.d.mts
CHANGED
|
@@ -34,12 +34,28 @@ interface LLMProviderPort {
|
|
|
34
34
|
stream?(options: LLMCompletionOptions): AsyncGenerator<string, LLMUsage | undefined>;
|
|
35
35
|
generateStructuredOutput?<T>(options: LLMStructuredOutputOptions<T>): Promise<T>;
|
|
36
36
|
}
|
|
37
|
+
interface ModelPrice {
|
|
38
|
+
promptUSDPerMillion: number;
|
|
39
|
+
completionUSDPerMillion: number;
|
|
40
|
+
cacheHitUSDPerMillion?: number;
|
|
41
|
+
}
|
|
42
|
+
interface PricingAdapter {
|
|
43
|
+
fetchPrice(model: string, provider?: string): Promise<ModelPrice | undefined> | ModelPrice | undefined;
|
|
44
|
+
}
|
|
45
|
+
declare class ConfigurationError extends Error {
|
|
46
|
+
constructor(message: string);
|
|
47
|
+
}
|
|
48
|
+
declare class BudgetExceededError extends Error {
|
|
49
|
+
constructor(message: string);
|
|
50
|
+
}
|
|
51
|
+
|
|
37
52
|
interface ProviderConfig {
|
|
38
53
|
provider: "deepseek" | "mistral" | "openai" | "ollama" | "openrouter" | "custom";
|
|
39
54
|
model: string;
|
|
40
55
|
apiKey?: string;
|
|
41
56
|
baseUrl?: string;
|
|
42
57
|
client?: LLMProviderPort;
|
|
58
|
+
pricing?: ModelPrice;
|
|
43
59
|
}
|
|
44
60
|
interface SecurityConfig {
|
|
45
61
|
detectPromptInjection?: boolean;
|
|
@@ -89,6 +105,10 @@ interface ControlLayerConfig {
|
|
|
89
105
|
hourlyTokenLimit?: number;
|
|
90
106
|
dailyTokenLimit?: number;
|
|
91
107
|
features?: FeaturesConfig;
|
|
108
|
+
pricingAdapter?: PricingAdapter;
|
|
109
|
+
pricingCacheTtlMs?: number;
|
|
110
|
+
customPricing?: Record<string, ModelPrice>;
|
|
111
|
+
mockSimulation?: boolean;
|
|
92
112
|
}
|
|
93
113
|
interface ExecutionResult {
|
|
94
114
|
text: string;
|
|
@@ -125,13 +145,52 @@ interface GenerateStructuredOutputOptions<T> {
|
|
|
125
145
|
financialNormalizer?: boolean;
|
|
126
146
|
}
|
|
127
147
|
|
|
128
|
-
interface
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
148
|
+
interface CalculateCostOptions {
|
|
149
|
+
provider?: string;
|
|
150
|
+
providerPricing?: ModelPrice;
|
|
151
|
+
customPricing?: Record<string, ModelPrice>;
|
|
152
|
+
adapter?: PricingAdapter;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Catalogue indicatif non injecté par défaut dans le moteur.
|
|
156
|
+
* Les utilisateurs peuvent s'en servir comme jeu de données initial (ex: seed Prisma)
|
|
157
|
+
* ou pour peupler le PricingRegistry s'ils souhaitent des valeurs de départ.
|
|
158
|
+
*/
|
|
159
|
+
declare const SEED_MODEL_PRICES: Record<string, ModelPrice>;
|
|
160
|
+
declare class CachedPricingAdapter implements PricingAdapter {
|
|
161
|
+
private cache;
|
|
162
|
+
private ttlMs;
|
|
163
|
+
private delegate;
|
|
164
|
+
constructor(delegate: PricingAdapter, ttlMs?: number);
|
|
165
|
+
fetchPrice(model: string, provider?: string): Promise<ModelPrice | undefined>;
|
|
166
|
+
peek(model: string, provider?: string): ModelPrice | undefined;
|
|
167
|
+
clearCache(): void;
|
|
168
|
+
invalidate(model?: string, provider?: string): void;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Registre de tarification dynamique.
|
|
172
|
+
* Démarre 100% vide : aucune valeur codée en dur n'est imposée par défaut (Option A : Strict & Truthful).
|
|
173
|
+
*/
|
|
174
|
+
declare class PricingRegistry {
|
|
175
|
+
private static prices;
|
|
176
|
+
private static adapter?;
|
|
177
|
+
static registerPrice(identifier: string, price: ModelPrice): void;
|
|
178
|
+
static registerDistributorPrices(distributor: string, priceMap: Record<string, ModelPrice>): void;
|
|
179
|
+
static registerPrices(prices: Record<string, ModelPrice>): void;
|
|
180
|
+
static getPrice(model: string, provider?: string): ModelPrice | undefined;
|
|
181
|
+
static setAdapter(adapter: PricingAdapter): void;
|
|
182
|
+
static getAdapter(): PricingAdapter | undefined;
|
|
183
|
+
static clear(): void;
|
|
184
|
+
/**
|
|
185
|
+
* Réinitialise le registre en chargeant le catalogue d'exemple SEED_MODEL_PRICES.
|
|
186
|
+
*/
|
|
187
|
+
static loadSeedPrices(): void;
|
|
188
|
+
static getAllPrices(): Record<string, ModelPrice>;
|
|
132
189
|
}
|
|
133
190
|
declare const DEFAULT_MODEL_PRICES: Record<string, ModelPrice>;
|
|
134
|
-
declare function
|
|
191
|
+
declare function resolveModelPrice(model: string, options?: CalculateCostOptions | string): ModelPrice | undefined;
|
|
192
|
+
declare function resolveModelPriceAsync(model: string, options?: CalculateCostOptions | string): Promise<ModelPrice | undefined>;
|
|
193
|
+
declare function calculateCostUSD(model: string, promptTokens: number, completionTokens: number, cacheHitTokens?: number, options?: CalculateCostOptions | string): number;
|
|
135
194
|
|
|
136
195
|
/**
|
|
137
196
|
* In-Flight PII Sanitizer for AvantGate.
|
|
@@ -175,8 +234,14 @@ declare function validateWithZod<T>(rawText: string, schema: z.ZodType<T>, optio
|
|
|
175
234
|
|
|
176
235
|
declare class AvantGateControlLayer {
|
|
177
236
|
private config;
|
|
237
|
+
private cachedPricingAdapter?;
|
|
178
238
|
constructor(config: ControlLayerConfig);
|
|
239
|
+
private resolveProviderConfig;
|
|
240
|
+
private findProviderConfig;
|
|
241
|
+
private calculateCost;
|
|
179
242
|
private applySecurityGuards;
|
|
243
|
+
private checkPreflightBudget;
|
|
244
|
+
private checkPostExecutionBudget;
|
|
180
245
|
private buildMessages;
|
|
181
246
|
private resolveTokens;
|
|
182
247
|
private getProviderChain;
|
|
@@ -186,7 +251,7 @@ declare class AvantGateControlLayer {
|
|
|
186
251
|
private assembleResult;
|
|
187
252
|
private notifyAuditSink;
|
|
188
253
|
/**
|
|
189
|
-
* Exécute une requête avec garde d'entrée, masquage PII, et calcul des coûts.
|
|
254
|
+
* Exécute une requête avec garde d'entrée, masquage PII, garde pré-vol et calcul des coûts.
|
|
190
255
|
*/
|
|
191
256
|
execute(options: {
|
|
192
257
|
userQuery: string;
|
|
@@ -305,4 +370,21 @@ declare class PromptRegistry {
|
|
|
305
370
|
static clear(): void;
|
|
306
371
|
}
|
|
307
372
|
|
|
308
|
-
|
|
373
|
+
declare class HttpProviderClient implements LLMProviderPort {
|
|
374
|
+
readonly name: string;
|
|
375
|
+
private readonly baseUrl;
|
|
376
|
+
private readonly apiKey?;
|
|
377
|
+
private readonly providerType;
|
|
378
|
+
constructor(config: ProviderConfig);
|
|
379
|
+
private resolveEndpoint;
|
|
380
|
+
private buildHeaders;
|
|
381
|
+
private buildPayload;
|
|
382
|
+
private extractUsage;
|
|
383
|
+
complete(options: LLMCompletionOptions): Promise<{
|
|
384
|
+
text: string;
|
|
385
|
+
usage?: LLMUsage;
|
|
386
|
+
}>;
|
|
387
|
+
}
|
|
388
|
+
declare function createHttpProviderClient(config: ProviderConfig): HttpProviderClient;
|
|
389
|
+
|
|
390
|
+
export { type AuditRecord, type AuditSinkPort, BudgetExceededError as AvantGateBudgetExceededError, ConfigurationError as AvantGateConfigurationError, AvantGateControlLayer, BudgetExceededError, type BuildResult, CachedPricingAdapter, type CalculateCostOptions, type ChatMessage, ConfigurationError, type ControlLayerConfig, DEFAULT_MODEL_PRICES, type ExecutionResult, type FeaturesConfig, type FinanceFeaturesConfig, type GenerateStructuredOutputOptions, HttpProviderClient, type ITokenBudget, type InputGuardResult, type LLMCompletionOptions, type LLMProviderPort, type LLMStructuredOutputOptions, type LLMUsage, type ModelPrice, type PricingAdapter, PricingRegistry, PromptBuilder, type PromptLabel, type PromptMessage, PromptRegistry, PromptTemplate, type PromptTemplateOptions, type PromptValidationResult, type ProviderConfig, type RetryConfig, SEED_MODEL_PRICES, type SanitizeResult, type SecurityConfig, type StructuredExecutionResult, type ValidateOptions, AvantGateControlLayer as ZenLLMControlLayer, calculateCostUSD, createAvantGate, createHttpProviderClient, createLLMControlLayer, extractAndCleanJSON, resolveModelPrice, resolveModelPriceAsync, sanitizePII, validateUserInput, validateWithZod };
|
package/dist/index.d.ts
CHANGED
|
@@ -34,12 +34,28 @@ interface LLMProviderPort {
|
|
|
34
34
|
stream?(options: LLMCompletionOptions): AsyncGenerator<string, LLMUsage | undefined>;
|
|
35
35
|
generateStructuredOutput?<T>(options: LLMStructuredOutputOptions<T>): Promise<T>;
|
|
36
36
|
}
|
|
37
|
+
interface ModelPrice {
|
|
38
|
+
promptUSDPerMillion: number;
|
|
39
|
+
completionUSDPerMillion: number;
|
|
40
|
+
cacheHitUSDPerMillion?: number;
|
|
41
|
+
}
|
|
42
|
+
interface PricingAdapter {
|
|
43
|
+
fetchPrice(model: string, provider?: string): Promise<ModelPrice | undefined> | ModelPrice | undefined;
|
|
44
|
+
}
|
|
45
|
+
declare class ConfigurationError extends Error {
|
|
46
|
+
constructor(message: string);
|
|
47
|
+
}
|
|
48
|
+
declare class BudgetExceededError extends Error {
|
|
49
|
+
constructor(message: string);
|
|
50
|
+
}
|
|
51
|
+
|
|
37
52
|
interface ProviderConfig {
|
|
38
53
|
provider: "deepseek" | "mistral" | "openai" | "ollama" | "openrouter" | "custom";
|
|
39
54
|
model: string;
|
|
40
55
|
apiKey?: string;
|
|
41
56
|
baseUrl?: string;
|
|
42
57
|
client?: LLMProviderPort;
|
|
58
|
+
pricing?: ModelPrice;
|
|
43
59
|
}
|
|
44
60
|
interface SecurityConfig {
|
|
45
61
|
detectPromptInjection?: boolean;
|
|
@@ -89,6 +105,10 @@ interface ControlLayerConfig {
|
|
|
89
105
|
hourlyTokenLimit?: number;
|
|
90
106
|
dailyTokenLimit?: number;
|
|
91
107
|
features?: FeaturesConfig;
|
|
108
|
+
pricingAdapter?: PricingAdapter;
|
|
109
|
+
pricingCacheTtlMs?: number;
|
|
110
|
+
customPricing?: Record<string, ModelPrice>;
|
|
111
|
+
mockSimulation?: boolean;
|
|
92
112
|
}
|
|
93
113
|
interface ExecutionResult {
|
|
94
114
|
text: string;
|
|
@@ -125,13 +145,52 @@ interface GenerateStructuredOutputOptions<T> {
|
|
|
125
145
|
financialNormalizer?: boolean;
|
|
126
146
|
}
|
|
127
147
|
|
|
128
|
-
interface
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
148
|
+
interface CalculateCostOptions {
|
|
149
|
+
provider?: string;
|
|
150
|
+
providerPricing?: ModelPrice;
|
|
151
|
+
customPricing?: Record<string, ModelPrice>;
|
|
152
|
+
adapter?: PricingAdapter;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Catalogue indicatif non injecté par défaut dans le moteur.
|
|
156
|
+
* Les utilisateurs peuvent s'en servir comme jeu de données initial (ex: seed Prisma)
|
|
157
|
+
* ou pour peupler le PricingRegistry s'ils souhaitent des valeurs de départ.
|
|
158
|
+
*/
|
|
159
|
+
declare const SEED_MODEL_PRICES: Record<string, ModelPrice>;
|
|
160
|
+
declare class CachedPricingAdapter implements PricingAdapter {
|
|
161
|
+
private cache;
|
|
162
|
+
private ttlMs;
|
|
163
|
+
private delegate;
|
|
164
|
+
constructor(delegate: PricingAdapter, ttlMs?: number);
|
|
165
|
+
fetchPrice(model: string, provider?: string): Promise<ModelPrice | undefined>;
|
|
166
|
+
peek(model: string, provider?: string): ModelPrice | undefined;
|
|
167
|
+
clearCache(): void;
|
|
168
|
+
invalidate(model?: string, provider?: string): void;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Registre de tarification dynamique.
|
|
172
|
+
* Démarre 100% vide : aucune valeur codée en dur n'est imposée par défaut (Option A : Strict & Truthful).
|
|
173
|
+
*/
|
|
174
|
+
declare class PricingRegistry {
|
|
175
|
+
private static prices;
|
|
176
|
+
private static adapter?;
|
|
177
|
+
static registerPrice(identifier: string, price: ModelPrice): void;
|
|
178
|
+
static registerDistributorPrices(distributor: string, priceMap: Record<string, ModelPrice>): void;
|
|
179
|
+
static registerPrices(prices: Record<string, ModelPrice>): void;
|
|
180
|
+
static getPrice(model: string, provider?: string): ModelPrice | undefined;
|
|
181
|
+
static setAdapter(adapter: PricingAdapter): void;
|
|
182
|
+
static getAdapter(): PricingAdapter | undefined;
|
|
183
|
+
static clear(): void;
|
|
184
|
+
/**
|
|
185
|
+
* Réinitialise le registre en chargeant le catalogue d'exemple SEED_MODEL_PRICES.
|
|
186
|
+
*/
|
|
187
|
+
static loadSeedPrices(): void;
|
|
188
|
+
static getAllPrices(): Record<string, ModelPrice>;
|
|
132
189
|
}
|
|
133
190
|
declare const DEFAULT_MODEL_PRICES: Record<string, ModelPrice>;
|
|
134
|
-
declare function
|
|
191
|
+
declare function resolveModelPrice(model: string, options?: CalculateCostOptions | string): ModelPrice | undefined;
|
|
192
|
+
declare function resolveModelPriceAsync(model: string, options?: CalculateCostOptions | string): Promise<ModelPrice | undefined>;
|
|
193
|
+
declare function calculateCostUSD(model: string, promptTokens: number, completionTokens: number, cacheHitTokens?: number, options?: CalculateCostOptions | string): number;
|
|
135
194
|
|
|
136
195
|
/**
|
|
137
196
|
* In-Flight PII Sanitizer for AvantGate.
|
|
@@ -175,8 +234,14 @@ declare function validateWithZod<T>(rawText: string, schema: z.ZodType<T>, optio
|
|
|
175
234
|
|
|
176
235
|
declare class AvantGateControlLayer {
|
|
177
236
|
private config;
|
|
237
|
+
private cachedPricingAdapter?;
|
|
178
238
|
constructor(config: ControlLayerConfig);
|
|
239
|
+
private resolveProviderConfig;
|
|
240
|
+
private findProviderConfig;
|
|
241
|
+
private calculateCost;
|
|
179
242
|
private applySecurityGuards;
|
|
243
|
+
private checkPreflightBudget;
|
|
244
|
+
private checkPostExecutionBudget;
|
|
180
245
|
private buildMessages;
|
|
181
246
|
private resolveTokens;
|
|
182
247
|
private getProviderChain;
|
|
@@ -186,7 +251,7 @@ declare class AvantGateControlLayer {
|
|
|
186
251
|
private assembleResult;
|
|
187
252
|
private notifyAuditSink;
|
|
188
253
|
/**
|
|
189
|
-
* Exécute une requête avec garde d'entrée, masquage PII, et calcul des coûts.
|
|
254
|
+
* Exécute une requête avec garde d'entrée, masquage PII, garde pré-vol et calcul des coûts.
|
|
190
255
|
*/
|
|
191
256
|
execute(options: {
|
|
192
257
|
userQuery: string;
|
|
@@ -305,4 +370,21 @@ declare class PromptRegistry {
|
|
|
305
370
|
static clear(): void;
|
|
306
371
|
}
|
|
307
372
|
|
|
308
|
-
|
|
373
|
+
declare class HttpProviderClient implements LLMProviderPort {
|
|
374
|
+
readonly name: string;
|
|
375
|
+
private readonly baseUrl;
|
|
376
|
+
private readonly apiKey?;
|
|
377
|
+
private readonly providerType;
|
|
378
|
+
constructor(config: ProviderConfig);
|
|
379
|
+
private resolveEndpoint;
|
|
380
|
+
private buildHeaders;
|
|
381
|
+
private buildPayload;
|
|
382
|
+
private extractUsage;
|
|
383
|
+
complete(options: LLMCompletionOptions): Promise<{
|
|
384
|
+
text: string;
|
|
385
|
+
usage?: LLMUsage;
|
|
386
|
+
}>;
|
|
387
|
+
}
|
|
388
|
+
declare function createHttpProviderClient(config: ProviderConfig): HttpProviderClient;
|
|
389
|
+
|
|
390
|
+
export { type AuditRecord, type AuditSinkPort, BudgetExceededError as AvantGateBudgetExceededError, ConfigurationError as AvantGateConfigurationError, AvantGateControlLayer, BudgetExceededError, type BuildResult, CachedPricingAdapter, type CalculateCostOptions, type ChatMessage, ConfigurationError, type ControlLayerConfig, DEFAULT_MODEL_PRICES, type ExecutionResult, type FeaturesConfig, type FinanceFeaturesConfig, type GenerateStructuredOutputOptions, HttpProviderClient, type ITokenBudget, type InputGuardResult, type LLMCompletionOptions, type LLMProviderPort, type LLMStructuredOutputOptions, type LLMUsage, type ModelPrice, type PricingAdapter, PricingRegistry, PromptBuilder, type PromptLabel, type PromptMessage, PromptRegistry, PromptTemplate, type PromptTemplateOptions, type PromptValidationResult, type ProviderConfig, type RetryConfig, SEED_MODEL_PRICES, type SanitizeResult, type SecurityConfig, type StructuredExecutionResult, type ValidateOptions, AvantGateControlLayer as ZenLLMControlLayer, calculateCostUSD, createAvantGate, createHttpProviderClient, createLLMControlLayer, extractAndCleanJSON, resolveModelPrice, resolveModelPriceAsync, sanitizePII, validateUserInput, validateWithZod };
|