@modelcost/sdk 0.1.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.
@@ -0,0 +1,1208 @@
1
+ import { z } from 'zod';
2
+
3
+ /** Actions that can be taken when a budget threshold is reached. */
4
+ declare const BudgetAction: z.ZodEnum<["alert", "throttle", "block"]>;
5
+ type BudgetAction = z.infer<typeof BudgetAction>;
6
+ /** Scope levels for budget policies. */
7
+ declare const BudgetScope: z.ZodEnum<["organization", "feature", "environment", "custom"]>;
8
+ type BudgetScope = z.infer<typeof BudgetScope>;
9
+ /** Time periods for budget policies. */
10
+ declare const BudgetPeriod: z.ZodEnum<["daily", "weekly", "monthly", "custom"]>;
11
+ type BudgetPeriod = z.infer<typeof BudgetPeriod>;
12
+ /** Supported AI providers. */
13
+ declare const Provider: z.ZodEnum<["openai", "anthropic", "google", "aws_bedrock", "cohere", "mistral"]>;
14
+ type Provider = z.infer<typeof Provider>;
15
+
16
+ /**
17
+ * Zod schema for ModelCost initialization options.
18
+ * Validates all configuration fields and applies defaults.
19
+ */
20
+ declare const ModelCostInitOptionsSchema: z.ZodObject<{
21
+ apiKey: z.ZodString;
22
+ orgId: z.ZodString;
23
+ environment: z.ZodDefault<z.ZodString>;
24
+ baseUrl: z.ZodDefault<z.ZodString>;
25
+ monthlyBudget: z.ZodOptional<z.ZodNumber>;
26
+ budgetAction: z.ZodDefault<z.ZodEnum<["alert", "throttle", "block"]>>;
27
+ failOpen: z.ZodDefault<z.ZodBoolean>;
28
+ flushIntervalMs: z.ZodDefault<z.ZodNumber>;
29
+ flushBatchSize: z.ZodDefault<z.ZodNumber>;
30
+ syncIntervalMs: z.ZodDefault<z.ZodNumber>;
31
+ contentPrivacy: z.ZodDefault<z.ZodBoolean>;
32
+ }, "strip", z.ZodTypeAny, {
33
+ environment: string;
34
+ apiKey: string;
35
+ orgId: string;
36
+ baseUrl: string;
37
+ budgetAction: "alert" | "throttle" | "block";
38
+ failOpen: boolean;
39
+ flushIntervalMs: number;
40
+ flushBatchSize: number;
41
+ syncIntervalMs: number;
42
+ contentPrivacy: boolean;
43
+ monthlyBudget?: number | undefined;
44
+ }, {
45
+ apiKey: string;
46
+ orgId: string;
47
+ environment?: string | undefined;
48
+ baseUrl?: string | undefined;
49
+ monthlyBudget?: number | undefined;
50
+ budgetAction?: "alert" | "throttle" | "block" | undefined;
51
+ failOpen?: boolean | undefined;
52
+ flushIntervalMs?: number | undefined;
53
+ flushBatchSize?: number | undefined;
54
+ syncIntervalMs?: number | undefined;
55
+ contentPrivacy?: boolean | undefined;
56
+ }>;
57
+ type ModelCostInitOptions = z.input<typeof ModelCostInitOptionsSchema>;
58
+ /**
59
+ * Resolved configuration after validation and env-var fallback.
60
+ */
61
+ type ModelCostResolvedConfig = z.output<typeof ModelCostInitOptionsSchema>;
62
+ /**
63
+ * Configuration manager that validates init options and reads
64
+ * environment variables as fallbacks.
65
+ */
66
+ declare class ModelCostConfig {
67
+ readonly apiKey: string;
68
+ readonly orgId: string;
69
+ readonly environment: string;
70
+ readonly baseUrl: string;
71
+ readonly monthlyBudget: number | undefined;
72
+ readonly budgetAction: z.infer<typeof BudgetAction>;
73
+ readonly failOpen: boolean;
74
+ readonly flushIntervalMs: number;
75
+ readonly flushBatchSize: number;
76
+ readonly syncIntervalMs: number;
77
+ readonly contentPrivacy: boolean;
78
+ constructor(options: ModelCostInitOptions);
79
+ }
80
+
81
+ /**
82
+ * Result of a PII scan on a text string.
83
+ */
84
+ interface PiiEntity {
85
+ type: string;
86
+ value: string;
87
+ start: number;
88
+ end: number;
89
+ }
90
+ interface PiiResult {
91
+ detected: boolean;
92
+ entities: PiiEntity[];
93
+ redactedText: string;
94
+ }
95
+ /**
96
+ * A governance violation detected by the full scanner.
97
+ */
98
+ interface GovernanceViolation {
99
+ category: string;
100
+ type: string;
101
+ severity: string;
102
+ start: number;
103
+ end: number;
104
+ }
105
+ /**
106
+ * Result of a full governance scan across all categories.
107
+ */
108
+ interface FullScanResult {
109
+ detected: boolean;
110
+ violations: GovernanceViolation[];
111
+ categories: string[];
112
+ }
113
+ /**
114
+ * Local PII scanner using regex pattern matching.
115
+ *
116
+ * Provides a fast, offline first-pass for PII detection before
117
+ * optionally deferring to the server-side governance scan.
118
+ *
119
+ * Also provides full governance scanning (PII, PHI, secrets, financial)
120
+ * for metadata-only mode where content never leaves the customer's environment.
121
+ */
122
+ declare class PiiScanner {
123
+ /**
124
+ * Scan text and return all detected PII entities, plus a redacted version.
125
+ */
126
+ scan(text: string): PiiResult;
127
+ /**
128
+ * Full governance scan across multiple categories.
129
+ * Used in metadata-only mode where content never leaves the customer's environment.
130
+ */
131
+ fullScan(text: string, categories?: string[]): FullScanResult;
132
+ /**
133
+ * Convenience method: return only the redacted text.
134
+ */
135
+ redact(text: string): string;
136
+ private _scanPiiViolations;
137
+ private _scanPhi;
138
+ private _scanSecrets;
139
+ private _scanFinancial;
140
+ /**
141
+ * Remove overlapping entities, preferring the one that starts first
142
+ * (and is longest in case of a tie).
143
+ */
144
+ private _removeOverlaps;
145
+ /**
146
+ * Replace detected entities with [REDACTED] markers.
147
+ */
148
+ private _redactText;
149
+ /**
150
+ * Luhn algorithm for credit card validation.
151
+ */
152
+ static _isValidLuhn(number: string): boolean;
153
+ }
154
+
155
+ /**
156
+ * A single recorded call within a session.
157
+ */
158
+ interface SessionCallRecord {
159
+ callSequence: number;
160
+ callType: string;
161
+ toolName?: string;
162
+ inputTokens: number;
163
+ outputTokens: number;
164
+ cumulativeInputTokens: number;
165
+ costUsd: number;
166
+ cumulativeCostUsd: number;
167
+ createdAt: Date;
168
+ }
169
+ /**
170
+ * Options for creating a new SessionContext.
171
+ */
172
+ interface SessionOptions {
173
+ sessionId: string;
174
+ serverSessionId?: string;
175
+ feature?: string;
176
+ userId?: string;
177
+ maxSpendUsd?: number;
178
+ maxIterations?: number;
179
+ }
180
+ /**
181
+ * Local session governance context.
182
+ *
183
+ * Tracks cumulative spend, iteration count, and call history for an
184
+ * agent session. Enforces budget and iteration limits before each call
185
+ * via `preCallCheck()`.
186
+ */
187
+ declare class SessionContext {
188
+ readonly sessionId: string;
189
+ serverSessionId?: string;
190
+ readonly feature?: string;
191
+ readonly userId?: string;
192
+ readonly maxSpendUsd?: number;
193
+ readonly maxIterations?: number;
194
+ private _currentSpendUsd;
195
+ private _iterationCount;
196
+ private _cumulativeInputTokens;
197
+ private _status;
198
+ private _terminationReason?;
199
+ private _calls;
200
+ constructor(options: SessionOptions);
201
+ get currentSpendUsd(): number;
202
+ get iterationCount(): number;
203
+ get status(): string;
204
+ get terminationReason(): string | undefined;
205
+ get calls(): readonly SessionCallRecord[];
206
+ get remainingBudget(): number | undefined;
207
+ get remainingIterations(): number | undefined;
208
+ /**
209
+ * Pre-flight check before making an AI call.
210
+ * Throws if budget or iteration limits would be exceeded.
211
+ */
212
+ preCallCheck(estimatedCost: number): void;
213
+ /**
214
+ * Record a completed call, updating cumulative counters.
215
+ */
216
+ recordCall(options: {
217
+ callType: string;
218
+ inputTokens: number;
219
+ outputTokens: number;
220
+ costUsd: number;
221
+ toolName?: string;
222
+ }): SessionCallRecord;
223
+ /**
224
+ * Close the session with a terminal status.
225
+ */
226
+ close(reason?: string): void;
227
+ }
228
+
229
+ /**
230
+ * Schema for budget check API response (snake_case from API -> camelCase).
231
+ */
232
+ declare const BudgetCheckResponseSchema: z.ZodEffects<z.ZodObject<{
233
+ allowed: z.ZodBoolean;
234
+ action: z.ZodNullable<z.ZodString>;
235
+ throttle_percentage: z.ZodNullable<z.ZodNumber>;
236
+ reason: z.ZodNullable<z.ZodString>;
237
+ }, "strip", z.ZodTypeAny, {
238
+ action: string | null;
239
+ throttle_percentage: number | null;
240
+ allowed: boolean;
241
+ reason: string | null;
242
+ }, {
243
+ action: string | null;
244
+ throttle_percentage: number | null;
245
+ allowed: boolean;
246
+ reason: string | null;
247
+ }>, {
248
+ allowed: boolean;
249
+ action: string | null;
250
+ throttlePercentage: number | null;
251
+ reason: string | null;
252
+ }, {
253
+ action: string | null;
254
+ throttle_percentage: number | null;
255
+ allowed: boolean;
256
+ reason: string | null;
257
+ }>;
258
+ type BudgetCheckResponse = z.output<typeof BudgetCheckResponseSchema>;
259
+ /**
260
+ * Schema for a single budget policy (snake_case from API -> camelCase).
261
+ */
262
+ declare const BudgetPolicySchema: z.ZodEffects<z.ZodObject<{
263
+ id: z.ZodString;
264
+ name: z.ZodString;
265
+ scope: z.ZodEnum<["organization", "feature", "environment", "custom"]>;
266
+ scope_identifier: z.ZodNullable<z.ZodString>;
267
+ budget_amount_usd: z.ZodNumber;
268
+ period: z.ZodEnum<["daily", "weekly", "monthly", "custom"]>;
269
+ custom_period_days: z.ZodNullable<z.ZodNumber>;
270
+ action: z.ZodEnum<["alert", "throttle", "block"]>;
271
+ throttle_percentage: z.ZodNullable<z.ZodNumber>;
272
+ alert_thresholds: z.ZodNullable<z.ZodArray<z.ZodNumber, "many">>;
273
+ current_spend_usd: z.ZodNumber;
274
+ spend_percentage: z.ZodNumber;
275
+ period_start: z.ZodString;
276
+ is_active: z.ZodBoolean;
277
+ created_at: z.ZodString;
278
+ updated_at: z.ZodString;
279
+ }, "strip", z.ZodTypeAny, {
280
+ id: string;
281
+ name: string;
282
+ scope: "custom" | "organization" | "feature" | "environment";
283
+ scope_identifier: string | null;
284
+ budget_amount_usd: number;
285
+ period: "custom" | "daily" | "weekly" | "monthly";
286
+ custom_period_days: number | null;
287
+ action: "alert" | "throttle" | "block";
288
+ throttle_percentage: number | null;
289
+ alert_thresholds: number[] | null;
290
+ current_spend_usd: number;
291
+ spend_percentage: number;
292
+ period_start: string;
293
+ is_active: boolean;
294
+ created_at: string;
295
+ updated_at: string;
296
+ }, {
297
+ id: string;
298
+ name: string;
299
+ scope: "custom" | "organization" | "feature" | "environment";
300
+ scope_identifier: string | null;
301
+ budget_amount_usd: number;
302
+ period: "custom" | "daily" | "weekly" | "monthly";
303
+ custom_period_days: number | null;
304
+ action: "alert" | "throttle" | "block";
305
+ throttle_percentage: number | null;
306
+ alert_thresholds: number[] | null;
307
+ current_spend_usd: number;
308
+ spend_percentage: number;
309
+ period_start: string;
310
+ is_active: boolean;
311
+ created_at: string;
312
+ updated_at: string;
313
+ }>, {
314
+ id: string;
315
+ name: string;
316
+ scope: "custom" | "organization" | "feature" | "environment";
317
+ scopeIdentifier: string | null;
318
+ budgetAmountUsd: number;
319
+ period: "custom" | "daily" | "weekly" | "monthly";
320
+ customPeriodDays: number | null;
321
+ action: "alert" | "throttle" | "block";
322
+ throttlePercentage: number | null;
323
+ alertThresholds: number[] | null;
324
+ currentSpendUsd: number;
325
+ spendPercentage: number;
326
+ periodStart: string;
327
+ isActive: boolean;
328
+ createdAt: string;
329
+ updatedAt: string;
330
+ }, {
331
+ id: string;
332
+ name: string;
333
+ scope: "custom" | "organization" | "feature" | "environment";
334
+ scope_identifier: string | null;
335
+ budget_amount_usd: number;
336
+ period: "custom" | "daily" | "weekly" | "monthly";
337
+ custom_period_days: number | null;
338
+ action: "alert" | "throttle" | "block";
339
+ throttle_percentage: number | null;
340
+ alert_thresholds: number[] | null;
341
+ current_spend_usd: number;
342
+ spend_percentage: number;
343
+ period_start: string;
344
+ is_active: boolean;
345
+ created_at: string;
346
+ updated_at: string;
347
+ }>;
348
+ type BudgetPolicy = z.output<typeof BudgetPolicySchema>;
349
+ /**
350
+ * Schema for the budget status API response (snake_case from API -> camelCase).
351
+ */
352
+ declare const BudgetStatusResponseSchema: z.ZodEffects<z.ZodObject<{
353
+ policies: z.ZodArray<z.ZodEffects<z.ZodObject<{
354
+ id: z.ZodString;
355
+ name: z.ZodString;
356
+ scope: z.ZodEnum<["organization", "feature", "environment", "custom"]>;
357
+ scope_identifier: z.ZodNullable<z.ZodString>;
358
+ budget_amount_usd: z.ZodNumber;
359
+ period: z.ZodEnum<["daily", "weekly", "monthly", "custom"]>;
360
+ custom_period_days: z.ZodNullable<z.ZodNumber>;
361
+ action: z.ZodEnum<["alert", "throttle", "block"]>;
362
+ throttle_percentage: z.ZodNullable<z.ZodNumber>;
363
+ alert_thresholds: z.ZodNullable<z.ZodArray<z.ZodNumber, "many">>;
364
+ current_spend_usd: z.ZodNumber;
365
+ spend_percentage: z.ZodNumber;
366
+ period_start: z.ZodString;
367
+ is_active: z.ZodBoolean;
368
+ created_at: z.ZodString;
369
+ updated_at: z.ZodString;
370
+ }, "strip", z.ZodTypeAny, {
371
+ id: string;
372
+ name: string;
373
+ scope: "custom" | "organization" | "feature" | "environment";
374
+ scope_identifier: string | null;
375
+ budget_amount_usd: number;
376
+ period: "custom" | "daily" | "weekly" | "monthly";
377
+ custom_period_days: number | null;
378
+ action: "alert" | "throttle" | "block";
379
+ throttle_percentage: number | null;
380
+ alert_thresholds: number[] | null;
381
+ current_spend_usd: number;
382
+ spend_percentage: number;
383
+ period_start: string;
384
+ is_active: boolean;
385
+ created_at: string;
386
+ updated_at: string;
387
+ }, {
388
+ id: string;
389
+ name: string;
390
+ scope: "custom" | "organization" | "feature" | "environment";
391
+ scope_identifier: string | null;
392
+ budget_amount_usd: number;
393
+ period: "custom" | "daily" | "weekly" | "monthly";
394
+ custom_period_days: number | null;
395
+ action: "alert" | "throttle" | "block";
396
+ throttle_percentage: number | null;
397
+ alert_thresholds: number[] | null;
398
+ current_spend_usd: number;
399
+ spend_percentage: number;
400
+ period_start: string;
401
+ is_active: boolean;
402
+ created_at: string;
403
+ updated_at: string;
404
+ }>, {
405
+ id: string;
406
+ name: string;
407
+ scope: "custom" | "organization" | "feature" | "environment";
408
+ scopeIdentifier: string | null;
409
+ budgetAmountUsd: number;
410
+ period: "custom" | "daily" | "weekly" | "monthly";
411
+ customPeriodDays: number | null;
412
+ action: "alert" | "throttle" | "block";
413
+ throttlePercentage: number | null;
414
+ alertThresholds: number[] | null;
415
+ currentSpendUsd: number;
416
+ spendPercentage: number;
417
+ periodStart: string;
418
+ isActive: boolean;
419
+ createdAt: string;
420
+ updatedAt: string;
421
+ }, {
422
+ id: string;
423
+ name: string;
424
+ scope: "custom" | "organization" | "feature" | "environment";
425
+ scope_identifier: string | null;
426
+ budget_amount_usd: number;
427
+ period: "custom" | "daily" | "weekly" | "monthly";
428
+ custom_period_days: number | null;
429
+ action: "alert" | "throttle" | "block";
430
+ throttle_percentage: number | null;
431
+ alert_thresholds: number[] | null;
432
+ current_spend_usd: number;
433
+ spend_percentage: number;
434
+ period_start: string;
435
+ is_active: boolean;
436
+ created_at: string;
437
+ updated_at: string;
438
+ }>, "many">;
439
+ total_budget_usd: z.ZodNumber;
440
+ total_spend_usd: z.ZodNumber;
441
+ policies_at_risk: z.ZodNumber;
442
+ }, "strip", z.ZodTypeAny, {
443
+ policies: {
444
+ id: string;
445
+ name: string;
446
+ scope: "custom" | "organization" | "feature" | "environment";
447
+ scopeIdentifier: string | null;
448
+ budgetAmountUsd: number;
449
+ period: "custom" | "daily" | "weekly" | "monthly";
450
+ customPeriodDays: number | null;
451
+ action: "alert" | "throttle" | "block";
452
+ throttlePercentage: number | null;
453
+ alertThresholds: number[] | null;
454
+ currentSpendUsd: number;
455
+ spendPercentage: number;
456
+ periodStart: string;
457
+ isActive: boolean;
458
+ createdAt: string;
459
+ updatedAt: string;
460
+ }[];
461
+ total_budget_usd: number;
462
+ total_spend_usd: number;
463
+ policies_at_risk: number;
464
+ }, {
465
+ policies: {
466
+ id: string;
467
+ name: string;
468
+ scope: "custom" | "organization" | "feature" | "environment";
469
+ scope_identifier: string | null;
470
+ budget_amount_usd: number;
471
+ period: "custom" | "daily" | "weekly" | "monthly";
472
+ custom_period_days: number | null;
473
+ action: "alert" | "throttle" | "block";
474
+ throttle_percentage: number | null;
475
+ alert_thresholds: number[] | null;
476
+ current_spend_usd: number;
477
+ spend_percentage: number;
478
+ period_start: string;
479
+ is_active: boolean;
480
+ created_at: string;
481
+ updated_at: string;
482
+ }[];
483
+ total_budget_usd: number;
484
+ total_spend_usd: number;
485
+ policies_at_risk: number;
486
+ }>, {
487
+ policies: {
488
+ id: string;
489
+ name: string;
490
+ scope: "custom" | "organization" | "feature" | "environment";
491
+ scopeIdentifier: string | null;
492
+ budgetAmountUsd: number;
493
+ period: "custom" | "daily" | "weekly" | "monthly";
494
+ customPeriodDays: number | null;
495
+ action: "alert" | "throttle" | "block";
496
+ throttlePercentage: number | null;
497
+ alertThresholds: number[] | null;
498
+ currentSpendUsd: number;
499
+ spendPercentage: number;
500
+ periodStart: string;
501
+ isActive: boolean;
502
+ createdAt: string;
503
+ updatedAt: string;
504
+ }[];
505
+ totalBudgetUsd: number;
506
+ totalSpendUsd: number;
507
+ policiesAtRisk: number;
508
+ }, {
509
+ policies: {
510
+ id: string;
511
+ name: string;
512
+ scope: "custom" | "organization" | "feature" | "environment";
513
+ scope_identifier: string | null;
514
+ budget_amount_usd: number;
515
+ period: "custom" | "daily" | "weekly" | "monthly";
516
+ custom_period_days: number | null;
517
+ action: "alert" | "throttle" | "block";
518
+ throttle_percentage: number | null;
519
+ alert_thresholds: number[] | null;
520
+ current_spend_usd: number;
521
+ spend_percentage: number;
522
+ period_start: string;
523
+ is_active: boolean;
524
+ created_at: string;
525
+ updated_at: string;
526
+ }[];
527
+ total_budget_usd: number;
528
+ total_spend_usd: number;
529
+ policies_at_risk: number;
530
+ }>;
531
+ type BudgetStatusResponse = z.output<typeof BudgetStatusResponseSchema>;
532
+
533
+ declare const VERSION = "0.1.0";
534
+
535
+ /**
536
+ * Schema for tracking an AI API call.
537
+ * API uses snake_case; we transform to camelCase for SDK consumers.
538
+ */
539
+ declare const TrackRequestSchema: z.ZodObject<{
540
+ apiKey: z.ZodString;
541
+ timestamp: z.ZodString;
542
+ provider: z.ZodEnum<["openai", "anthropic", "google", "aws_bedrock", "cohere", "mistral"]>;
543
+ model: z.ZodString;
544
+ feature: z.ZodOptional<z.ZodString>;
545
+ customerId: z.ZodOptional<z.ZodString>;
546
+ inputTokens: z.ZodNumber;
547
+ outputTokens: z.ZodNumber;
548
+ latencyMs: z.ZodOptional<z.ZodNumber>;
549
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
550
+ }, "strip", z.ZodTypeAny, {
551
+ apiKey: string;
552
+ timestamp: string;
553
+ provider: "openai" | "anthropic" | "google" | "aws_bedrock" | "cohere" | "mistral";
554
+ model: string;
555
+ inputTokens: number;
556
+ outputTokens: number;
557
+ feature?: string | undefined;
558
+ customerId?: string | undefined;
559
+ latencyMs?: number | undefined;
560
+ metadata?: Record<string, unknown> | undefined;
561
+ }, {
562
+ apiKey: string;
563
+ timestamp: string;
564
+ provider: "openai" | "anthropic" | "google" | "aws_bedrock" | "cohere" | "mistral";
565
+ model: string;
566
+ inputTokens: number;
567
+ outputTokens: number;
568
+ feature?: string | undefined;
569
+ customerId?: string | undefined;
570
+ latencyMs?: number | undefined;
571
+ metadata?: Record<string, unknown> | undefined;
572
+ }>;
573
+ type TrackRequest = z.infer<typeof TrackRequestSchema>;
574
+ /** Schema for the track API response. */
575
+ declare const TrackResponseSchema: z.ZodObject<{
576
+ status: z.ZodLiteral<"ok">;
577
+ }, "strip", z.ZodTypeAny, {
578
+ status: "ok";
579
+ }, {
580
+ status: "ok";
581
+ }>;
582
+ type TrackResponse = z.infer<typeof TrackResponseSchema>;
583
+
584
+ interface CreateSessionRequest {
585
+ apiKey: string;
586
+ sessionId: string;
587
+ feature?: string;
588
+ userId?: string;
589
+ maxSpendUsd?: number;
590
+ maxIterations?: number;
591
+ }
592
+ interface RecordSessionCallRequest {
593
+ apiKey: string;
594
+ callSequence: number;
595
+ callType: string;
596
+ toolName?: string;
597
+ inputTokens: number;
598
+ outputTokens: number;
599
+ cumulativeInputTokens: number;
600
+ costUsd: number;
601
+ cumulativeCostUsd: number;
602
+ piiDetected: boolean;
603
+ }
604
+ interface CloseSessionRequest {
605
+ apiKey: string;
606
+ status: string;
607
+ terminationReason?: string;
608
+ finalSpendUsd: number;
609
+ finalIterationCount: number;
610
+ }
611
+ interface CreateSessionResponse {
612
+ id: string;
613
+ sessionId: string;
614
+ status: string;
615
+ maxSpendUsd?: number;
616
+ maxIterations?: number;
617
+ }
618
+
619
+ /**
620
+ * Schema for a governance scan request (camelCase -> snake_case for API).
621
+ */
622
+ declare const GovernanceScanRequestSchema: z.ZodObject<{
623
+ orgId: z.ZodString;
624
+ text: z.ZodString;
625
+ feature: z.ZodOptional<z.ZodString>;
626
+ environment: z.ZodOptional<z.ZodString>;
627
+ }, "strip", z.ZodTypeAny, {
628
+ orgId: string;
629
+ text: string;
630
+ feature?: string | undefined;
631
+ environment?: string | undefined;
632
+ }, {
633
+ orgId: string;
634
+ text: string;
635
+ feature?: string | undefined;
636
+ environment?: string | undefined;
637
+ }>;
638
+ type GovernanceScanRequest = z.infer<typeof GovernanceScanRequestSchema>;
639
+ /**
640
+ * Schema for a detected violation (snake_case from API -> camelCase).
641
+ */
642
+ declare const DetectedViolationSchema: z.ZodObject<{
643
+ type: z.ZodString;
644
+ subtype: z.ZodString;
645
+ severity: z.ZodEnum<["low", "medium", "high"]>;
646
+ start: z.ZodNumber;
647
+ end: z.ZodNumber;
648
+ }, "strip", z.ZodTypeAny, {
649
+ type: string;
650
+ subtype: string;
651
+ severity: "low" | "medium" | "high";
652
+ start: number;
653
+ end: number;
654
+ }, {
655
+ type: string;
656
+ subtype: string;
657
+ severity: "low" | "medium" | "high";
658
+ start: number;
659
+ end: number;
660
+ }>;
661
+ type DetectedViolation = z.infer<typeof DetectedViolationSchema>;
662
+ /**
663
+ * Schema for the governance scan API response (snake_case from API -> camelCase).
664
+ */
665
+ declare const GovernanceScanResponseSchema: z.ZodEffects<z.ZodObject<{
666
+ is_allowed: z.ZodBoolean;
667
+ action: z.ZodNullable<z.ZodString>;
668
+ violations: z.ZodArray<z.ZodObject<{
669
+ type: z.ZodString;
670
+ subtype: z.ZodString;
671
+ severity: z.ZodEnum<["low", "medium", "high"]>;
672
+ start: z.ZodNumber;
673
+ end: z.ZodNumber;
674
+ }, "strip", z.ZodTypeAny, {
675
+ type: string;
676
+ subtype: string;
677
+ severity: "low" | "medium" | "high";
678
+ start: number;
679
+ end: number;
680
+ }, {
681
+ type: string;
682
+ subtype: string;
683
+ severity: "low" | "medium" | "high";
684
+ start: number;
685
+ end: number;
686
+ }>, "many">;
687
+ redacted_text: z.ZodNullable<z.ZodString>;
688
+ }, "strip", z.ZodTypeAny, {
689
+ action: string | null;
690
+ is_allowed: boolean;
691
+ violations: {
692
+ type: string;
693
+ subtype: string;
694
+ severity: "low" | "medium" | "high";
695
+ start: number;
696
+ end: number;
697
+ }[];
698
+ redacted_text: string | null;
699
+ }, {
700
+ action: string | null;
701
+ is_allowed: boolean;
702
+ violations: {
703
+ type: string;
704
+ subtype: string;
705
+ severity: "low" | "medium" | "high";
706
+ start: number;
707
+ end: number;
708
+ }[];
709
+ redacted_text: string | null;
710
+ }>, {
711
+ isAllowed: boolean;
712
+ action: string | null;
713
+ violations: {
714
+ type: string;
715
+ subtype: string;
716
+ severity: "low" | "medium" | "high";
717
+ start: number;
718
+ end: number;
719
+ }[];
720
+ redactedText: string | null;
721
+ }, {
722
+ action: string | null;
723
+ is_allowed: boolean;
724
+ violations: {
725
+ type: string;
726
+ subtype: string;
727
+ severity: "low" | "medium" | "high";
728
+ start: number;
729
+ end: number;
730
+ }[];
731
+ redacted_text: string | null;
732
+ }>;
733
+ type GovernanceScanResponse = z.output<typeof GovernanceScanResponseSchema>;
734
+ /**
735
+ * Request to report a governance signal in metadata-only mode.
736
+ * No raw content is included — only classification signals.
737
+ */
738
+ interface GovernanceSignalRequest {
739
+ organizationId: string;
740
+ violationType: string;
741
+ violationSubtype?: string;
742
+ severity: string;
743
+ userId?: string;
744
+ feature?: string;
745
+ environment?: string;
746
+ actionTaken: string;
747
+ wasAllowed: boolean;
748
+ detectedAt?: string;
749
+ source: string;
750
+ violationCount?: number;
751
+ }
752
+
753
+ /**
754
+ * Low-level HTTP client for the ModelCost API.
755
+ * Uses native fetch, implements circuit breaker, and supports fail-open semantics.
756
+ */
757
+ declare class ModelCostClient {
758
+ private readonly _baseUrl;
759
+ private readonly _apiKey;
760
+ private readonly _headers;
761
+ private readonly _failOpen;
762
+ /** Circuit breaker state */
763
+ private _consecutiveFailures;
764
+ private _circuitOpenUntil;
765
+ constructor(config: ModelCostConfig);
766
+ /**
767
+ * Record a tracked AI API call.
768
+ */
769
+ track(request: TrackRequest): Promise<TrackResponse>;
770
+ /**
771
+ * Pre-flight budget check before making an AI call.
772
+ */
773
+ checkBudget(orgId: string, feature: string, estimatedCost: number): Promise<BudgetCheckResponse>;
774
+ /**
775
+ * Scan text for PII and governance violations.
776
+ */
777
+ scanText(request: GovernanceScanRequest): Promise<GovernanceScanResponse>;
778
+ /**
779
+ * Report a governance signal (metadata-only mode).
780
+ * Sends classification signals without raw content.
781
+ */
782
+ reportSignal(request: GovernanceSignalRequest): Promise<void>;
783
+ /**
784
+ * Get current budget status for an organization.
785
+ */
786
+ getBudgetStatus(orgId: string): Promise<BudgetStatusResponse>;
787
+ /**
788
+ * Create a new agent session on the server.
789
+ */
790
+ createSession(request: CreateSessionRequest): Promise<CreateSessionResponse>;
791
+ /**
792
+ * Record a call within an existing session.
793
+ */
794
+ recordSessionCall(sessionId: string, request: RecordSessionCallRequest): Promise<void>;
795
+ /**
796
+ * Close an existing session on the server.
797
+ */
798
+ closeSession(sessionId: string, request: CloseSessionRequest): Promise<void>;
799
+ /**
800
+ * Close the client (cleanup resources).
801
+ */
802
+ close(): void;
803
+ private _isCircuitOpen;
804
+ private _recordSuccess;
805
+ private _recordFailure;
806
+ private _post;
807
+ private _get;
808
+ private _request;
809
+ /**
810
+ * Returns a safe default response when operating in fail-open mode.
811
+ */
812
+ private _failOpenDefault;
813
+ }
814
+
815
+ /**
816
+ * Manages budget state with local caching and periodic sync.
817
+ * Keeps an in-memory cache of budget status to avoid hitting the API
818
+ * on every call, while still staying in sync with the server.
819
+ */
820
+ declare class BudgetManager {
821
+ private _cache;
822
+ private _lastSync;
823
+ private readonly _syncIntervalMs;
824
+ constructor(syncIntervalMs: number);
825
+ /**
826
+ * Check whether a request with the given estimated cost is allowed.
827
+ * Uses the local cache if fresh, otherwise syncs from the API first.
828
+ */
829
+ check(client: ModelCostClient, orgId: string, feature: string, estimatedCost: number): Promise<BudgetCheckResponse>;
830
+ /**
831
+ * Sync the budget status from the server and populate the local cache.
832
+ */
833
+ sync(client: ModelCostClient, orgId: string): Promise<void>;
834
+ /**
835
+ * Optimistically update local spend after a tracked call,
836
+ * so subsequent budget checks reflect the estimated spend
837
+ * without waiting for the next server sync.
838
+ */
839
+ updateLocalSpend(orgId: string, _feature: string, cost: number): void;
840
+ /**
841
+ * Get the cached budget status for an org, if available.
842
+ */
843
+ getCached(orgId: string): BudgetStatusResponse | undefined;
844
+ /**
845
+ * Clear all cached state.
846
+ */
847
+ clear(): void;
848
+ private _isStale;
849
+ }
850
+
851
+ /**
852
+ * Schema describing the pricing for a single model.
853
+ */
854
+ declare const ModelPricingSchema: z.ZodObject<{
855
+ provider: z.ZodString;
856
+ model: z.ZodString;
857
+ inputCostPer1k: z.ZodNumber;
858
+ outputCostPer1k: z.ZodNumber;
859
+ }, "strip", z.ZodTypeAny, {
860
+ provider: string;
861
+ model: string;
862
+ inputCostPer1k: number;
863
+ outputCostPer1k: number;
864
+ }, {
865
+ provider: string;
866
+ model: string;
867
+ inputCostPer1k: number;
868
+ outputCostPer1k: number;
869
+ }>;
870
+ type ModelPricing = z.infer<typeof ModelPricingSchema>;
871
+
872
+ /**
873
+ * Known model pricing table (cost per 1,000 tokens in USD).
874
+ * Loaded from sdk/common/model_pricing.json at import time,
875
+ * refreshed at runtime via syncPricingFromApi().
876
+ */
877
+ declare const MODEL_PRICING: ReadonlyMap<string, ModelPricing>;
878
+ /**
879
+ * Calculate the cost of an AI call based on token counts and known pricing.
880
+ * Returns 0 if the model is not found in the pricing table.
881
+ */
882
+ declare function calculateCost(model: string, inputTokens: number, outputTokens: number): number;
883
+ /**
884
+ * Buffers track requests and periodically flushes them to the API.
885
+ */
886
+ declare class CostTracker {
887
+ private _buffer;
888
+ private _flushTimer;
889
+ private _pricingSyncTimer;
890
+ private readonly _batchSize;
891
+ constructor(batchSize: number);
892
+ /**
893
+ * Add a track request to the buffer.
894
+ * Automatically flushes when buffer reaches batch size.
895
+ */
896
+ record(request: TrackRequest, client?: ModelCostClient): void;
897
+ /**
898
+ * Flush all buffered track requests to the API.
899
+ */
900
+ flush(client: ModelCostClient): Promise<void>;
901
+ /**
902
+ * Start automatic periodic flushing.
903
+ */
904
+ startAutoFlush(client: ModelCostClient, intervalMs: number): void;
905
+ /**
906
+ * Stop automatic periodic flushing.
907
+ */
908
+ stopAutoFlush(): void;
909
+ private static readonly _PRICING_SYNC_INTERVAL_MS;
910
+ /**
911
+ * Start periodic pricing sync from the server.
912
+ */
913
+ startPricingSync(baseUrl: string, apiKey: string): void;
914
+ /**
915
+ * Stop periodic pricing sync.
916
+ */
917
+ stopPricingSync(): void;
918
+ /**
919
+ * Get the current number of buffered requests.
920
+ */
921
+ get bufferSize(): number;
922
+ }
923
+
924
+ /**
925
+ * Token-bucket rate limiter.
926
+ *
927
+ * Allows `burst` tokens to be consumed immediately, and refills at `rate`
928
+ * tokens per second. Useful for throttling outbound API calls.
929
+ */
930
+ declare class TokenBucketRateLimiter {
931
+ private _tokens;
932
+ private _lastRefill;
933
+ private readonly _rate;
934
+ private readonly _burst;
935
+ private readonly _strict;
936
+ /**
937
+ * @param rate - Tokens refilled per second
938
+ * @param burst - Maximum tokens (bucket capacity)
939
+ * @param strict - If true, `allow()` throws RateLimitedError instead of returning false
940
+ */
941
+ constructor(rate: number, burst: number, strict?: boolean);
942
+ /**
943
+ * Attempt to consume one token.
944
+ * Returns true if allowed, false if rate-limited.
945
+ * In strict mode, throws RateLimitedError instead of returning false.
946
+ */
947
+ allow(): boolean;
948
+ /**
949
+ * Wait until a token is available, then consume it.
950
+ * Resolves immediately if a token is available now.
951
+ */
952
+ wait(): Promise<void>;
953
+ /**
954
+ * Get the current number of available tokens (for inspection/testing).
955
+ */
956
+ get availableTokens(): number;
957
+ private _refill;
958
+ }
959
+
960
+ /**
961
+ * Base error class for all ModelCost SDK errors.
962
+ */
963
+ declare class ModelCostError extends Error {
964
+ constructor(message: string);
965
+ }
966
+ /**
967
+ * Thrown when the SDK is misconfigured (invalid API key, missing org ID, etc.).
968
+ */
969
+ declare class ConfigurationError extends ModelCostError {
970
+ constructor(message: string);
971
+ }
972
+ /**
973
+ * Thrown when a request is blocked because the budget has been exceeded.
974
+ */
975
+ declare class BudgetExceededError extends ModelCostError {
976
+ readonly remainingBudget: number;
977
+ readonly scope: string;
978
+ readonly overrideUrl?: string;
979
+ constructor(message: string, remainingBudget: number, scope: string, overrideUrl?: string);
980
+ }
981
+ /**
982
+ * Thrown when the client is rate-limited by the ModelCost API.
983
+ */
984
+ declare class RateLimitedError extends ModelCostError {
985
+ readonly retryAfterSeconds: number;
986
+ readonly limitDimension: string;
987
+ constructor(message: string, retryAfterSeconds: number, limitDimension: string);
988
+ }
989
+ /**
990
+ * Thrown when PII is detected in scanned text and the policy requires blocking.
991
+ */
992
+ declare class PiiDetectedError extends ModelCostError {
993
+ readonly detectedEntities: DetectedViolation[];
994
+ readonly redactedText: string;
995
+ constructor(message: string, detectedEntities: DetectedViolation[], redactedText: string);
996
+ }
997
+ /**
998
+ * Thrown when a session's spend budget has been exceeded.
999
+ */
1000
+ declare class SessionBudgetExceededError extends ModelCostError {
1001
+ readonly sessionId: string;
1002
+ readonly currentSpend: number;
1003
+ readonly maxSpend: number;
1004
+ constructor(message: string, sessionId: string, currentSpend: number, maxSpend: number);
1005
+ }
1006
+ /**
1007
+ * Thrown when a session's iteration limit has been exceeded.
1008
+ */
1009
+ declare class SessionIterationLimitExceededError extends ModelCostError {
1010
+ readonly sessionId: string;
1011
+ readonly currentIterations: number;
1012
+ readonly maxIterations: number;
1013
+ constructor(message: string, sessionId: string, currentIterations: number, maxIterations: number);
1014
+ }
1015
+ /**
1016
+ * Thrown when the ModelCost API returns an error response.
1017
+ */
1018
+ declare class ModelCostApiError extends ModelCostError {
1019
+ readonly statusCode: number;
1020
+ readonly errorCode: string;
1021
+ constructor(message: string, statusCode: number, errorCode: string);
1022
+ }
1023
+
1024
+ /**
1025
+ * Usage information extracted from a provider's API response.
1026
+ */
1027
+ interface ExtractedUsage {
1028
+ inputTokens: number;
1029
+ outputTokens: number;
1030
+ }
1031
+ /**
1032
+ * Base interface that all provider wrappers must implement.
1033
+ */
1034
+ interface BaseProvider {
1035
+ /**
1036
+ * Wrap an AI client with cost tracking, budget enforcement, and PII scanning.
1037
+ * Returns a proxied version of the client.
1038
+ */
1039
+ wrap(client: unknown): unknown;
1040
+ /**
1041
+ * Extract token usage from a provider-specific API response.
1042
+ */
1043
+ extractUsage(response: unknown): ExtractedUsage;
1044
+ /**
1045
+ * Get the canonical provider name.
1046
+ */
1047
+ getProviderName(): string;
1048
+ }
1049
+
1050
+ /**
1051
+ * Provider wrapper for OpenAI-compatible clients.
1052
+ *
1053
+ * Intercepts `client.chat.completions.create()` calls to:
1054
+ * 1. Run a budget pre-check
1055
+ * 2. Scan prompt messages for PII
1056
+ * 3. Enforce rate limits
1057
+ * 4. Extract usage from the response and record the cost
1058
+ */
1059
+ declare class OpenAIProvider implements BaseProvider {
1060
+ private readonly _client;
1061
+ private readonly _config;
1062
+ private readonly _budgetManager;
1063
+ private readonly _costTracker;
1064
+ private readonly _piiScanner;
1065
+ private readonly _rateLimiter;
1066
+ private readonly _session?;
1067
+ constructor(apiClient: ModelCostClient, config: ModelCostConfig, budgetManager: BudgetManager, costTracker: CostTracker, piiScanner: PiiScanner, rateLimiter: TokenBucketRateLimiter, session?: SessionContext);
1068
+ getProviderName(): string;
1069
+ extractUsage(response: unknown): ExtractedUsage;
1070
+ wrap(client: unknown): unknown;
1071
+ }
1072
+
1073
+ /**
1074
+ * Provider wrapper for Anthropic clients.
1075
+ *
1076
+ * Intercepts `client.messages.create()` calls to add budget enforcement,
1077
+ * PII scanning, rate limiting, and cost tracking.
1078
+ */
1079
+ declare class AnthropicProvider implements BaseProvider {
1080
+ private readonly _client;
1081
+ private readonly _config;
1082
+ private readonly _budgetManager;
1083
+ private readonly _costTracker;
1084
+ private readonly _piiScanner;
1085
+ private readonly _rateLimiter;
1086
+ private readonly _session?;
1087
+ constructor(apiClient: ModelCostClient, config: ModelCostConfig, budgetManager: BudgetManager, costTracker: CostTracker, piiScanner: PiiScanner, rateLimiter: TokenBucketRateLimiter, session?: SessionContext);
1088
+ getProviderName(): string;
1089
+ extractUsage(response: unknown): ExtractedUsage;
1090
+ wrap(client: unknown): unknown;
1091
+ }
1092
+
1093
+ /**
1094
+ * Provider wrapper for Google Generative AI clients.
1095
+ *
1096
+ * Intercepts `model.generateContent()` calls returned from
1097
+ * `client.getGenerativeModel()`.
1098
+ */
1099
+ declare class GoogleProvider implements BaseProvider {
1100
+ private readonly _client;
1101
+ private readonly _config;
1102
+ private readonly _budgetManager;
1103
+ private readonly _costTracker;
1104
+ private readonly _piiScanner;
1105
+ private readonly _rateLimiter;
1106
+ private readonly _session?;
1107
+ constructor(apiClient: ModelCostClient, config: ModelCostConfig, budgetManager: BudgetManager, costTracker: CostTracker, piiScanner: PiiScanner, rateLimiter: TokenBucketRateLimiter, session?: SessionContext);
1108
+ getProviderName(): string;
1109
+ extractUsage(response: unknown): ExtractedUsage;
1110
+ wrap(client: unknown): unknown;
1111
+ private _wrapModel;
1112
+ }
1113
+
1114
+ interface TrackCostOptions {
1115
+ model: string;
1116
+ feature?: string;
1117
+ provider?: string;
1118
+ session?: SessionContext;
1119
+ }
1120
+ interface UsageReport {
1121
+ totalSpendUsd: number;
1122
+ totalBudgetUsd: number;
1123
+ policiesAtRisk: number;
1124
+ policies: BudgetStatusResponse["policies"];
1125
+ }
1126
+ /**
1127
+ * Main entry point for the ModelCost Node.js SDK.
1128
+ *
1129
+ * Uses a static singleton pattern -- call `ModelCost.init()` once,
1130
+ * then use the static methods from anywhere in your application.
1131
+ *
1132
+ * @example
1133
+ * ```ts
1134
+ * import { ModelCost } from "@modelcost/sdk";
1135
+ * import OpenAI from "openai";
1136
+ *
1137
+ * ModelCost.init({ apiKey: "mc_...", orgId: "org-123" });
1138
+ * const openai = ModelCost.wrap(new OpenAI());
1139
+ * ```
1140
+ */
1141
+ declare class ModelCost {
1142
+ private static _instance;
1143
+ /** Prevent direct instantiation. */
1144
+ private constructor();
1145
+ /**
1146
+ * Initialize the ModelCost SDK. Must be called before any other method.
1147
+ * Subsequent calls will re-initialize (shutting down the previous instance).
1148
+ */
1149
+ static init(options: ModelCostInitOptions): void;
1150
+ /**
1151
+ * Wrap an AI provider client with cost tracking, budget enforcement,
1152
+ * and PII scanning. Returns a proxied version of the same client.
1153
+ *
1154
+ * Supports: OpenAI, Anthropic, Google Generative AI.
1155
+ */
1156
+ static wrap<T>(client: T, session?: SessionContext): T;
1157
+ /**
1158
+ * Decorator factory for tracking costs on individual functions.
1159
+ *
1160
+ * @example
1161
+ * ```ts
1162
+ * const trackedFn = ModelCost.trackCost({ model: "gpt-4o" })(myFunction);
1163
+ * ```
1164
+ */
1165
+ static trackCost(options: TrackCostOptions): <TFn extends (...args: unknown[]) => unknown>(fn: TFn) => TFn;
1166
+ /**
1167
+ * Check whether a request is allowed under current budget policies.
1168
+ */
1169
+ static checkBudget(scope: string, id: string): Promise<BudgetCheckResponse>;
1170
+ /**
1171
+ * Get usage/spend information for a scope and period.
1172
+ */
1173
+ static getUsage(scope: string, _period: string): Promise<UsageReport>;
1174
+ /**
1175
+ * Start a new agent session with optional budget and iteration limits.
1176
+ * Registers the session with the server (fail-open if unavailable)
1177
+ * and returns a local SessionContext for tracking.
1178
+ */
1179
+ static startSession(options?: {
1180
+ feature?: string;
1181
+ maxSpendUsd?: number;
1182
+ maxIterations?: number;
1183
+ userId?: string;
1184
+ sessionId?: string;
1185
+ }): Promise<SessionContext>;
1186
+ /**
1187
+ * Close an active session, recording final state on the server.
1188
+ */
1189
+ static closeSession(session: SessionContext, reason?: string): Promise<void>;
1190
+ /**
1191
+ * Scan text for PII using the local scanner.
1192
+ */
1193
+ static scanPii(text: string): Promise<PiiResult>;
1194
+ /**
1195
+ * Flush all buffered tracking events to the API.
1196
+ */
1197
+ static flush(): Promise<void>;
1198
+ /**
1199
+ * Gracefully shut down the SDK: flush remaining events, stop timers, close client.
1200
+ */
1201
+ static shutdown(): Promise<void>;
1202
+ /**
1203
+ * Assert the SDK has been initialized and return the instance.
1204
+ */
1205
+ private static _requireInstance;
1206
+ }
1207
+
1208
+ export { AnthropicProvider, type BaseProvider, BudgetAction, type BudgetCheckResponse, BudgetExceededError, BudgetManager, BudgetPeriod, type BudgetPolicy, BudgetScope, type BudgetStatusResponse, type CloseSessionRequest, ConfigurationError, CostTracker, type CreateSessionRequest, type CreateSessionResponse, type DetectedViolation, type ExtractedUsage, type FullScanResult, GoogleProvider, type GovernanceScanRequest, type GovernanceScanResponse, type GovernanceViolation, MODEL_PRICING, ModelCost, ModelCostApiError, ModelCostClient, ModelCostConfig, ModelCostError, type ModelCostInitOptions, type ModelCostResolvedConfig, type ModelPricing, OpenAIProvider, PiiDetectedError, type PiiEntity, type PiiResult, PiiScanner, Provider, RateLimitedError, type RecordSessionCallRequest, SessionBudgetExceededError, type SessionCallRecord, SessionContext, SessionIterationLimitExceededError, type SessionOptions, TokenBucketRateLimiter, type TrackCostOptions, type TrackRequest, type TrackResponse, type UsageReport, VERSION, calculateCost };