floe-guard 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.
package/dist/index.js ADDED
@@ -0,0 +1,954 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/errors.ts
8
+ var FloeGuardError = class extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = "FloeGuardError";
12
+ Object.setPrototypeOf(this, new.target.prototype);
13
+ }
14
+ };
15
+ var BudgetExceeded = class extends FloeGuardError {
16
+ spentUsd;
17
+ limitUsd;
18
+ constructor(spentUsd, limitUsd) {
19
+ super(
20
+ `BUDGET EXCEEDED \u2014 call blocked (spent $${spentUsd.toFixed(6)} of $${limitUsd.toFixed(6)} ceiling)`
21
+ );
22
+ this.name = "BudgetExceeded";
23
+ this.spentUsd = spentUsd;
24
+ this.limitUsd = limitUsd;
25
+ }
26
+ };
27
+ var UnpriceableModelError = class extends FloeGuardError {
28
+ model;
29
+ constructor(model) {
30
+ super(
31
+ `Cannot price model '${model}': not in the bundled cost map and no manual price was given. The guard cannot enforce a budget on spend it cannot measure. Pass a price override to enable enforcement.`
32
+ );
33
+ this.name = "UnpriceableModelError";
34
+ this.model = model;
35
+ }
36
+ };
37
+
38
+ // src/pricing.ts
39
+ var pricing_exports = {};
40
+ __export(pricing_exports, {
41
+ priceTokens: () => priceTokens,
42
+ resolvePrice: () => resolvePrice
43
+ });
44
+
45
+ // src/cost_map.json
46
+ var cost_map_default = {
47
+ "chatgpt-4o-latest": {
48
+ input_cost_per_token: 5e-6,
49
+ output_cost_per_token: 15e-6,
50
+ litellm_provider: "openai",
51
+ mode: "chat"
52
+ },
53
+ "claude-3-7-sonnet-20250219": {
54
+ input_cost_per_token: 3e-6,
55
+ output_cost_per_token: 15e-6,
56
+ litellm_provider: "anthropic",
57
+ mode: "chat"
58
+ },
59
+ "claude-3-haiku-20240307": {
60
+ input_cost_per_token: 25e-8,
61
+ output_cost_per_token: 125e-8,
62
+ litellm_provider: "anthropic",
63
+ mode: "chat"
64
+ },
65
+ "claude-3-opus-20240229": {
66
+ input_cost_per_token: 15e-6,
67
+ output_cost_per_token: 75e-6,
68
+ litellm_provider: "anthropic",
69
+ mode: "chat"
70
+ },
71
+ "claude-4-opus-20250514": {
72
+ input_cost_per_token: 15e-6,
73
+ output_cost_per_token: 75e-6,
74
+ litellm_provider: "anthropic",
75
+ mode: "chat"
76
+ },
77
+ "claude-4-sonnet-20250514": {
78
+ input_cost_per_token: 3e-6,
79
+ output_cost_per_token: 15e-6,
80
+ litellm_provider: "anthropic",
81
+ mode: "chat"
82
+ },
83
+ "claude-haiku-4-5": {
84
+ input_cost_per_token: 1e-6,
85
+ output_cost_per_token: 5e-6,
86
+ litellm_provider: "anthropic",
87
+ mode: "chat"
88
+ },
89
+ "claude-haiku-4-5-20251001": {
90
+ input_cost_per_token: 1e-6,
91
+ output_cost_per_token: 5e-6,
92
+ litellm_provider: "anthropic",
93
+ mode: "chat"
94
+ },
95
+ "claude-opus-4-1": {
96
+ input_cost_per_token: 15e-6,
97
+ output_cost_per_token: 75e-6,
98
+ litellm_provider: "anthropic",
99
+ mode: "chat"
100
+ },
101
+ "claude-opus-4-1-20250805": {
102
+ input_cost_per_token: 15e-6,
103
+ output_cost_per_token: 75e-6,
104
+ litellm_provider: "anthropic",
105
+ mode: "chat"
106
+ },
107
+ "claude-opus-4-20250514": {
108
+ input_cost_per_token: 15e-6,
109
+ output_cost_per_token: 75e-6,
110
+ litellm_provider: "anthropic",
111
+ mode: "chat"
112
+ },
113
+ "claude-opus-4-5": {
114
+ input_cost_per_token: 5e-6,
115
+ output_cost_per_token: 25e-6,
116
+ litellm_provider: "anthropic",
117
+ mode: "chat"
118
+ },
119
+ "claude-opus-4-5-20251101": {
120
+ input_cost_per_token: 5e-6,
121
+ output_cost_per_token: 25e-6,
122
+ litellm_provider: "anthropic",
123
+ mode: "chat"
124
+ },
125
+ "claude-opus-4-6": {
126
+ input_cost_per_token: 5e-6,
127
+ output_cost_per_token: 25e-6,
128
+ litellm_provider: "anthropic",
129
+ mode: "chat"
130
+ },
131
+ "claude-opus-4-6-20260205": {
132
+ input_cost_per_token: 5e-6,
133
+ output_cost_per_token: 25e-6,
134
+ litellm_provider: "anthropic",
135
+ mode: "chat"
136
+ },
137
+ "claude-opus-4-7": {
138
+ input_cost_per_token: 5e-6,
139
+ output_cost_per_token: 25e-6,
140
+ litellm_provider: "anthropic",
141
+ mode: "chat"
142
+ },
143
+ "claude-opus-4-7-20260416": {
144
+ input_cost_per_token: 5e-6,
145
+ output_cost_per_token: 25e-6,
146
+ litellm_provider: "anthropic",
147
+ mode: "chat"
148
+ },
149
+ "claude-opus-4-8": {
150
+ input_cost_per_token: 5e-6,
151
+ output_cost_per_token: 25e-6,
152
+ litellm_provider: "anthropic",
153
+ mode: "chat"
154
+ },
155
+ "claude-sonnet-4-20250514": {
156
+ input_cost_per_token: 3e-6,
157
+ output_cost_per_token: 15e-6,
158
+ litellm_provider: "anthropic",
159
+ mode: "chat"
160
+ },
161
+ "claude-sonnet-4-5": {
162
+ input_cost_per_token: 3e-6,
163
+ output_cost_per_token: 15e-6,
164
+ litellm_provider: "anthropic",
165
+ mode: "chat"
166
+ },
167
+ "claude-sonnet-4-5-20250929": {
168
+ input_cost_per_token: 3e-6,
169
+ output_cost_per_token: 15e-6,
170
+ litellm_provider: "anthropic",
171
+ mode: "chat"
172
+ },
173
+ "claude-sonnet-4-6": {
174
+ input_cost_per_token: 3e-6,
175
+ output_cost_per_token: 15e-6,
176
+ litellm_provider: "anthropic",
177
+ mode: "chat"
178
+ },
179
+ "ft:gpt-3.5-turbo": {
180
+ input_cost_per_token: 3e-6,
181
+ output_cost_per_token: 6e-6,
182
+ litellm_provider: "openai",
183
+ mode: "chat"
184
+ },
185
+ "ft:gpt-3.5-turbo-0125": {
186
+ input_cost_per_token: 3e-6,
187
+ output_cost_per_token: 6e-6,
188
+ litellm_provider: "openai",
189
+ mode: "chat"
190
+ },
191
+ "ft:gpt-3.5-turbo-0613": {
192
+ input_cost_per_token: 3e-6,
193
+ output_cost_per_token: 6e-6,
194
+ litellm_provider: "openai",
195
+ mode: "chat"
196
+ },
197
+ "ft:gpt-3.5-turbo-1106": {
198
+ input_cost_per_token: 3e-6,
199
+ output_cost_per_token: 6e-6,
200
+ litellm_provider: "openai",
201
+ mode: "chat"
202
+ },
203
+ "ft:gpt-4-0613": {
204
+ input_cost_per_token: 3e-5,
205
+ output_cost_per_token: 6e-5,
206
+ litellm_provider: "openai",
207
+ mode: "chat"
208
+ },
209
+ "ft:gpt-4.1-2025-04-14": {
210
+ input_cost_per_token: 3e-6,
211
+ output_cost_per_token: 12e-6,
212
+ litellm_provider: "openai",
213
+ mode: "chat"
214
+ },
215
+ "ft:gpt-4.1-mini-2025-04-14": {
216
+ input_cost_per_token: 8e-7,
217
+ output_cost_per_token: 32e-7,
218
+ litellm_provider: "openai",
219
+ mode: "chat"
220
+ },
221
+ "ft:gpt-4.1-nano-2025-04-14": {
222
+ input_cost_per_token: 2e-7,
223
+ output_cost_per_token: 8e-7,
224
+ litellm_provider: "openai",
225
+ mode: "chat"
226
+ },
227
+ "ft:gpt-4o-2024-08-06": {
228
+ input_cost_per_token: 375e-8,
229
+ output_cost_per_token: 15e-6,
230
+ litellm_provider: "openai",
231
+ mode: "chat"
232
+ },
233
+ "ft:gpt-4o-2024-11-20": {
234
+ input_cost_per_token: 375e-8,
235
+ output_cost_per_token: 15e-6,
236
+ litellm_provider: "openai",
237
+ mode: "chat"
238
+ },
239
+ "ft:gpt-4o-mini-2024-07-18": {
240
+ input_cost_per_token: 3e-7,
241
+ output_cost_per_token: 12e-7,
242
+ litellm_provider: "openai",
243
+ mode: "chat"
244
+ },
245
+ "ft:o4-mini-2025-04-16": {
246
+ input_cost_per_token: 4e-6,
247
+ output_cost_per_token: 16e-6,
248
+ litellm_provider: "openai",
249
+ mode: "chat"
250
+ },
251
+ "gpt-3.5-turbo": {
252
+ input_cost_per_token: 5e-7,
253
+ output_cost_per_token: 15e-7,
254
+ litellm_provider: "openai",
255
+ mode: "chat"
256
+ },
257
+ "gpt-3.5-turbo-0125": {
258
+ input_cost_per_token: 5e-7,
259
+ output_cost_per_token: 15e-7,
260
+ litellm_provider: "openai",
261
+ mode: "chat"
262
+ },
263
+ "gpt-3.5-turbo-1106": {
264
+ input_cost_per_token: 1e-6,
265
+ output_cost_per_token: 2e-6,
266
+ litellm_provider: "openai",
267
+ mode: "chat"
268
+ },
269
+ "gpt-3.5-turbo-16k": {
270
+ input_cost_per_token: 3e-6,
271
+ output_cost_per_token: 4e-6,
272
+ litellm_provider: "openai",
273
+ mode: "chat"
274
+ },
275
+ "gpt-4": {
276
+ input_cost_per_token: 3e-5,
277
+ output_cost_per_token: 6e-5,
278
+ litellm_provider: "openai",
279
+ mode: "chat"
280
+ },
281
+ "gpt-4-0125-preview": {
282
+ input_cost_per_token: 1e-5,
283
+ output_cost_per_token: 3e-5,
284
+ litellm_provider: "openai",
285
+ mode: "chat"
286
+ },
287
+ "gpt-4-0314": {
288
+ input_cost_per_token: 3e-5,
289
+ output_cost_per_token: 6e-5,
290
+ litellm_provider: "openai",
291
+ mode: "chat"
292
+ },
293
+ "gpt-4-0613": {
294
+ input_cost_per_token: 3e-5,
295
+ output_cost_per_token: 6e-5,
296
+ litellm_provider: "openai",
297
+ mode: "chat"
298
+ },
299
+ "gpt-4-1106-preview": {
300
+ input_cost_per_token: 1e-5,
301
+ output_cost_per_token: 3e-5,
302
+ litellm_provider: "openai",
303
+ mode: "chat"
304
+ },
305
+ "gpt-4-turbo": {
306
+ input_cost_per_token: 1e-5,
307
+ output_cost_per_token: 3e-5,
308
+ litellm_provider: "openai",
309
+ mode: "chat"
310
+ },
311
+ "gpt-4-turbo-2024-04-09": {
312
+ input_cost_per_token: 1e-5,
313
+ output_cost_per_token: 3e-5,
314
+ litellm_provider: "openai",
315
+ mode: "chat"
316
+ },
317
+ "gpt-4-turbo-preview": {
318
+ input_cost_per_token: 1e-5,
319
+ output_cost_per_token: 3e-5,
320
+ litellm_provider: "openai",
321
+ mode: "chat"
322
+ },
323
+ "gpt-4.1": {
324
+ input_cost_per_token: 2e-6,
325
+ output_cost_per_token: 8e-6,
326
+ litellm_provider: "openai",
327
+ mode: "chat"
328
+ },
329
+ "gpt-4.1-2025-04-14": {
330
+ input_cost_per_token: 2e-6,
331
+ output_cost_per_token: 8e-6,
332
+ litellm_provider: "openai",
333
+ mode: "chat"
334
+ },
335
+ "gpt-4.1-mini": {
336
+ input_cost_per_token: 4e-7,
337
+ output_cost_per_token: 16e-7,
338
+ litellm_provider: "openai",
339
+ mode: "chat"
340
+ },
341
+ "gpt-4.1-mini-2025-04-14": {
342
+ input_cost_per_token: 4e-7,
343
+ output_cost_per_token: 16e-7,
344
+ litellm_provider: "openai",
345
+ mode: "chat"
346
+ },
347
+ "gpt-4.1-nano": {
348
+ input_cost_per_token: 1e-7,
349
+ output_cost_per_token: 4e-7,
350
+ litellm_provider: "openai",
351
+ mode: "chat"
352
+ },
353
+ "gpt-4.1-nano-2025-04-14": {
354
+ input_cost_per_token: 1e-7,
355
+ output_cost_per_token: 4e-7,
356
+ litellm_provider: "openai",
357
+ mode: "chat"
358
+ },
359
+ "gpt-4o": {
360
+ input_cost_per_token: 25e-7,
361
+ output_cost_per_token: 1e-5,
362
+ litellm_provider: "openai",
363
+ mode: "chat"
364
+ },
365
+ "gpt-4o-2024-05-13": {
366
+ input_cost_per_token: 5e-6,
367
+ output_cost_per_token: 15e-6,
368
+ litellm_provider: "openai",
369
+ mode: "chat"
370
+ },
371
+ "gpt-4o-2024-08-06": {
372
+ input_cost_per_token: 25e-7,
373
+ output_cost_per_token: 1e-5,
374
+ litellm_provider: "openai",
375
+ mode: "chat"
376
+ },
377
+ "gpt-4o-2024-11-20": {
378
+ input_cost_per_token: 25e-7,
379
+ output_cost_per_token: 1e-5,
380
+ litellm_provider: "openai",
381
+ mode: "chat"
382
+ },
383
+ "gpt-4o-audio-preview": {
384
+ input_cost_per_token: 25e-7,
385
+ output_cost_per_token: 1e-5,
386
+ litellm_provider: "openai",
387
+ mode: "chat"
388
+ },
389
+ "gpt-4o-audio-preview-2024-12-17": {
390
+ input_cost_per_token: 25e-7,
391
+ output_cost_per_token: 1e-5,
392
+ litellm_provider: "openai",
393
+ mode: "chat"
394
+ },
395
+ "gpt-4o-audio-preview-2025-06-03": {
396
+ input_cost_per_token: 25e-7,
397
+ output_cost_per_token: 1e-5,
398
+ litellm_provider: "openai",
399
+ mode: "chat"
400
+ },
401
+ "gpt-4o-mini": {
402
+ input_cost_per_token: 15e-8,
403
+ output_cost_per_token: 6e-7,
404
+ litellm_provider: "openai",
405
+ mode: "chat"
406
+ },
407
+ "gpt-4o-mini-2024-07-18": {
408
+ input_cost_per_token: 15e-8,
409
+ output_cost_per_token: 6e-7,
410
+ litellm_provider: "openai",
411
+ mode: "chat"
412
+ },
413
+ "gpt-4o-mini-audio-preview": {
414
+ input_cost_per_token: 15e-8,
415
+ output_cost_per_token: 6e-7,
416
+ litellm_provider: "openai",
417
+ mode: "chat"
418
+ },
419
+ "gpt-4o-mini-audio-preview-2024-12-17": {
420
+ input_cost_per_token: 15e-8,
421
+ output_cost_per_token: 6e-7,
422
+ litellm_provider: "openai",
423
+ mode: "chat"
424
+ },
425
+ "gpt-4o-mini-realtime-preview": {
426
+ input_cost_per_token: 6e-7,
427
+ output_cost_per_token: 24e-7,
428
+ litellm_provider: "openai",
429
+ mode: "chat"
430
+ },
431
+ "gpt-4o-mini-realtime-preview-2024-12-17": {
432
+ input_cost_per_token: 6e-7,
433
+ output_cost_per_token: 24e-7,
434
+ litellm_provider: "openai",
435
+ mode: "chat"
436
+ },
437
+ "gpt-4o-mini-search-preview": {
438
+ input_cost_per_token: 15e-8,
439
+ output_cost_per_token: 6e-7,
440
+ litellm_provider: "openai",
441
+ mode: "chat"
442
+ },
443
+ "gpt-4o-mini-search-preview-2025-03-11": {
444
+ input_cost_per_token: 15e-8,
445
+ output_cost_per_token: 6e-7,
446
+ litellm_provider: "openai",
447
+ mode: "chat"
448
+ },
449
+ "gpt-4o-realtime-preview": {
450
+ input_cost_per_token: 5e-6,
451
+ output_cost_per_token: 2e-5,
452
+ litellm_provider: "openai",
453
+ mode: "chat"
454
+ },
455
+ "gpt-4o-realtime-preview-2024-12-17": {
456
+ input_cost_per_token: 5e-6,
457
+ output_cost_per_token: 2e-5,
458
+ litellm_provider: "openai",
459
+ mode: "chat"
460
+ },
461
+ "gpt-4o-realtime-preview-2025-06-03": {
462
+ input_cost_per_token: 5e-6,
463
+ output_cost_per_token: 2e-5,
464
+ litellm_provider: "openai",
465
+ mode: "chat"
466
+ },
467
+ "gpt-4o-search-preview": {
468
+ input_cost_per_token: 25e-7,
469
+ output_cost_per_token: 1e-5,
470
+ litellm_provider: "openai",
471
+ mode: "chat"
472
+ },
473
+ "gpt-4o-search-preview-2025-03-11": {
474
+ input_cost_per_token: 25e-7,
475
+ output_cost_per_token: 1e-5,
476
+ litellm_provider: "openai",
477
+ mode: "chat"
478
+ },
479
+ "gpt-5": {
480
+ input_cost_per_token: 125e-8,
481
+ output_cost_per_token: 1e-5,
482
+ litellm_provider: "openai",
483
+ mode: "chat"
484
+ },
485
+ "gpt-5-2025-08-07": {
486
+ input_cost_per_token: 125e-8,
487
+ output_cost_per_token: 1e-5,
488
+ litellm_provider: "openai",
489
+ mode: "chat"
490
+ },
491
+ "gpt-5-chat": {
492
+ input_cost_per_token: 125e-8,
493
+ output_cost_per_token: 1e-5,
494
+ litellm_provider: "openai",
495
+ mode: "chat"
496
+ },
497
+ "gpt-5-chat-latest": {
498
+ input_cost_per_token: 125e-8,
499
+ output_cost_per_token: 1e-5,
500
+ litellm_provider: "openai",
501
+ mode: "chat"
502
+ },
503
+ "gpt-5-mini": {
504
+ input_cost_per_token: 25e-8,
505
+ output_cost_per_token: 2e-6,
506
+ litellm_provider: "openai",
507
+ mode: "chat"
508
+ },
509
+ "gpt-5-mini-2025-08-07": {
510
+ input_cost_per_token: 25e-8,
511
+ output_cost_per_token: 2e-6,
512
+ litellm_provider: "openai",
513
+ mode: "chat"
514
+ },
515
+ "gpt-5-nano": {
516
+ input_cost_per_token: 5e-8,
517
+ output_cost_per_token: 4e-7,
518
+ litellm_provider: "openai",
519
+ mode: "chat"
520
+ },
521
+ "gpt-5-nano-2025-08-07": {
522
+ input_cost_per_token: 5e-8,
523
+ output_cost_per_token: 4e-7,
524
+ litellm_provider: "openai",
525
+ mode: "chat"
526
+ },
527
+ "gpt-5-search-api": {
528
+ input_cost_per_token: 125e-8,
529
+ output_cost_per_token: 1e-5,
530
+ litellm_provider: "openai",
531
+ mode: "chat"
532
+ },
533
+ "gpt-5-search-api-2025-10-14": {
534
+ input_cost_per_token: 125e-8,
535
+ output_cost_per_token: 1e-5,
536
+ litellm_provider: "openai",
537
+ mode: "chat"
538
+ },
539
+ "gpt-5.1": {
540
+ input_cost_per_token: 125e-8,
541
+ output_cost_per_token: 1e-5,
542
+ litellm_provider: "openai",
543
+ mode: "chat"
544
+ },
545
+ "gpt-5.1-2025-11-13": {
546
+ input_cost_per_token: 125e-8,
547
+ output_cost_per_token: 1e-5,
548
+ litellm_provider: "openai",
549
+ mode: "chat"
550
+ },
551
+ "gpt-5.1-chat-latest": {
552
+ input_cost_per_token: 125e-8,
553
+ output_cost_per_token: 1e-5,
554
+ litellm_provider: "openai",
555
+ mode: "chat"
556
+ },
557
+ "gpt-5.2": {
558
+ input_cost_per_token: 175e-8,
559
+ output_cost_per_token: 14e-6,
560
+ litellm_provider: "openai",
561
+ mode: "chat"
562
+ },
563
+ "gpt-5.2-2025-12-11": {
564
+ input_cost_per_token: 175e-8,
565
+ output_cost_per_token: 14e-6,
566
+ litellm_provider: "openai",
567
+ mode: "chat"
568
+ },
569
+ "gpt-5.2-chat-latest": {
570
+ input_cost_per_token: 175e-8,
571
+ output_cost_per_token: 14e-6,
572
+ litellm_provider: "openai",
573
+ mode: "chat"
574
+ },
575
+ "gpt-5.3-chat-latest": {
576
+ input_cost_per_token: 175e-8,
577
+ output_cost_per_token: 14e-6,
578
+ litellm_provider: "openai",
579
+ mode: "chat"
580
+ },
581
+ "gpt-5.4": {
582
+ input_cost_per_token: 25e-7,
583
+ output_cost_per_token: 15e-6,
584
+ litellm_provider: "openai",
585
+ mode: "chat"
586
+ },
587
+ "gpt-5.4-2026-03-05": {
588
+ input_cost_per_token: 25e-7,
589
+ output_cost_per_token: 15e-6,
590
+ litellm_provider: "openai",
591
+ mode: "chat"
592
+ },
593
+ "gpt-5.4-mini": {
594
+ input_cost_per_token: 75e-8,
595
+ output_cost_per_token: 45e-7,
596
+ litellm_provider: "openai",
597
+ mode: "chat"
598
+ },
599
+ "gpt-5.4-mini-2026-03-17": {
600
+ input_cost_per_token: 75e-8,
601
+ output_cost_per_token: 45e-7,
602
+ litellm_provider: "openai",
603
+ mode: "chat"
604
+ },
605
+ "gpt-5.4-nano": {
606
+ input_cost_per_token: 2e-7,
607
+ output_cost_per_token: 125e-8,
608
+ litellm_provider: "openai",
609
+ mode: "chat"
610
+ },
611
+ "gpt-5.4-nano-2026-03-17": {
612
+ input_cost_per_token: 2e-7,
613
+ output_cost_per_token: 125e-8,
614
+ litellm_provider: "openai",
615
+ mode: "chat"
616
+ },
617
+ "gpt-5.5": {
618
+ input_cost_per_token: 5e-6,
619
+ output_cost_per_token: 3e-5,
620
+ litellm_provider: "openai",
621
+ mode: "chat"
622
+ },
623
+ "gpt-5.5-2026-04-23": {
624
+ input_cost_per_token: 5e-6,
625
+ output_cost_per_token: 3e-5,
626
+ litellm_provider: "openai",
627
+ mode: "chat"
628
+ },
629
+ "gpt-audio": {
630
+ input_cost_per_token: 25e-7,
631
+ output_cost_per_token: 1e-5,
632
+ litellm_provider: "openai",
633
+ mode: "chat"
634
+ },
635
+ "gpt-audio-1.5": {
636
+ input_cost_per_token: 25e-7,
637
+ output_cost_per_token: 1e-5,
638
+ litellm_provider: "openai",
639
+ mode: "chat"
640
+ },
641
+ "gpt-audio-2025-08-28": {
642
+ input_cost_per_token: 25e-7,
643
+ output_cost_per_token: 1e-5,
644
+ litellm_provider: "openai",
645
+ mode: "chat"
646
+ },
647
+ "gpt-audio-mini": {
648
+ input_cost_per_token: 6e-7,
649
+ output_cost_per_token: 24e-7,
650
+ litellm_provider: "openai",
651
+ mode: "chat"
652
+ },
653
+ "gpt-audio-mini-2025-10-06": {
654
+ input_cost_per_token: 6e-7,
655
+ output_cost_per_token: 24e-7,
656
+ litellm_provider: "openai",
657
+ mode: "chat"
658
+ },
659
+ "gpt-audio-mini-2025-12-15": {
660
+ input_cost_per_token: 6e-7,
661
+ output_cost_per_token: 24e-7,
662
+ litellm_provider: "openai",
663
+ mode: "chat"
664
+ },
665
+ "gpt-realtime": {
666
+ input_cost_per_token: 4e-6,
667
+ output_cost_per_token: 16e-6,
668
+ litellm_provider: "openai",
669
+ mode: "chat"
670
+ },
671
+ "gpt-realtime-1.5": {
672
+ input_cost_per_token: 4e-6,
673
+ output_cost_per_token: 16e-6,
674
+ litellm_provider: "openai",
675
+ mode: "chat"
676
+ },
677
+ "gpt-realtime-2": {
678
+ input_cost_per_token: 4e-6,
679
+ output_cost_per_token: 16e-6,
680
+ litellm_provider: "openai",
681
+ mode: "chat"
682
+ },
683
+ "gpt-realtime-2025-08-28": {
684
+ input_cost_per_token: 4e-6,
685
+ output_cost_per_token: 16e-6,
686
+ litellm_provider: "openai",
687
+ mode: "chat"
688
+ },
689
+ "gpt-realtime-mini": {
690
+ input_cost_per_token: 6e-7,
691
+ output_cost_per_token: 24e-7,
692
+ litellm_provider: "openai",
693
+ mode: "chat"
694
+ },
695
+ "gpt-realtime-mini-2025-10-06": {
696
+ input_cost_per_token: 6e-7,
697
+ output_cost_per_token: 24e-7,
698
+ litellm_provider: "openai",
699
+ mode: "chat"
700
+ },
701
+ "gpt-realtime-mini-2025-12-15": {
702
+ input_cost_per_token: 6e-7,
703
+ output_cost_per_token: 24e-7,
704
+ litellm_provider: "openai",
705
+ mode: "chat"
706
+ },
707
+ o1: {
708
+ input_cost_per_token: 15e-6,
709
+ output_cost_per_token: 6e-5,
710
+ litellm_provider: "openai",
711
+ mode: "chat"
712
+ },
713
+ "o1-2024-12-17": {
714
+ input_cost_per_token: 15e-6,
715
+ output_cost_per_token: 6e-5,
716
+ litellm_provider: "openai",
717
+ mode: "chat"
718
+ },
719
+ o3: {
720
+ input_cost_per_token: 2e-6,
721
+ output_cost_per_token: 8e-6,
722
+ litellm_provider: "openai",
723
+ mode: "chat"
724
+ },
725
+ "o3-2025-04-16": {
726
+ input_cost_per_token: 2e-6,
727
+ output_cost_per_token: 8e-6,
728
+ litellm_provider: "openai",
729
+ mode: "chat"
730
+ },
731
+ "o3-mini": {
732
+ input_cost_per_token: 11e-7,
733
+ output_cost_per_token: 44e-7,
734
+ litellm_provider: "openai",
735
+ mode: "chat"
736
+ },
737
+ "o3-mini-2025-01-31": {
738
+ input_cost_per_token: 11e-7,
739
+ output_cost_per_token: 44e-7,
740
+ litellm_provider: "openai",
741
+ mode: "chat"
742
+ },
743
+ "o4-mini": {
744
+ input_cost_per_token: 11e-7,
745
+ output_cost_per_token: 44e-7,
746
+ litellm_provider: "openai",
747
+ mode: "chat"
748
+ },
749
+ "o4-mini-2025-04-16": {
750
+ input_cost_per_token: 11e-7,
751
+ output_cost_per_token: 44e-7,
752
+ litellm_provider: "openai",
753
+ mode: "chat"
754
+ },
755
+ "text-embedding-3-large": {
756
+ input_cost_per_token: 13e-8,
757
+ output_cost_per_token: 0,
758
+ litellm_provider: "openai",
759
+ mode: "embedding"
760
+ },
761
+ "text-embedding-3-small": {
762
+ input_cost_per_token: 2e-8,
763
+ output_cost_per_token: 0,
764
+ litellm_provider: "openai",
765
+ mode: "embedding"
766
+ },
767
+ "text-embedding-ada-002": {
768
+ input_cost_per_token: 1e-7,
769
+ output_cost_per_token: 0,
770
+ litellm_provider: "openai",
771
+ mode: "embedding"
772
+ },
773
+ "text-embedding-ada-002-v2": {
774
+ input_cost_per_token: 1e-7,
775
+ output_cost_per_token: 0,
776
+ litellm_provider: "openai",
777
+ mode: "embedding"
778
+ }
779
+ };
780
+
781
+ // src/pricing.ts
782
+ var COST_MAP = cost_map_default;
783
+ function bareModel(model) {
784
+ const m = model.trim();
785
+ const slash = m.lastIndexOf("/");
786
+ return slash === -1 ? m : m.slice(slash + 1);
787
+ }
788
+ function bothFinite(a, b) {
789
+ return typeof a === "number" && typeof b === "number" && Number.isFinite(a) && Number.isFinite(b);
790
+ }
791
+ function resolvePrice(model, overrides) {
792
+ const bare = bareModel(model);
793
+ if (overrides) {
794
+ const ov = overrides[bare] ?? overrides[model.trim()];
795
+ if (ov !== void 0) {
796
+ if (bothFinite(ov.inputCostPerToken, ov.outputCostPerToken)) {
797
+ return {
798
+ inputCostPerToken: ov.inputCostPerToken,
799
+ outputCostPerToken: ov.outputCostPerToken,
800
+ source: "override"
801
+ };
802
+ }
803
+ return null;
804
+ }
805
+ }
806
+ const entry = COST_MAP[bare] ?? COST_MAP[model.trim()];
807
+ if (!entry) return null;
808
+ const input = entry.input_cost_per_token;
809
+ const output = entry.output_cost_per_token;
810
+ if (!bothFinite(input, output)) return null;
811
+ return {
812
+ inputCostPerToken: input,
813
+ outputCostPerToken: output,
814
+ source: "cost_map"
815
+ };
816
+ }
817
+ function priceTokens(priced, promptTokens, completionTokens) {
818
+ const p = Math.max(0, promptTokens);
819
+ const c = Math.max(0, completionTokens);
820
+ const cost = p * priced.inputCostPerToken + c * priced.outputCostPerToken;
821
+ if (!Number.isFinite(cost)) {
822
+ throw new Error("Non-finite LLM cost \u2014 pricing entry is invalid");
823
+ }
824
+ return Math.max(0, cost);
825
+ }
826
+
827
+ // src/guard.ts
828
+ var EPS = 1e-12;
829
+ var BudgetGuard = class {
830
+ limitUsd;
831
+ spentUsd = 0;
832
+ priceOverrides;
833
+ failClosed;
834
+ onBlock;
835
+ /** Cost of the most recent priced call, used to predict the next one. */
836
+ lastCost = 0;
837
+ /**
838
+ * @param limitUsd the spend ceiling, in USD. `0` blocks the very first call.
839
+ */
840
+ constructor(limitUsd, options = {}) {
841
+ if (!Number.isFinite(limitUsd) || limitUsd < 0) {
842
+ throw new RangeError(
843
+ `limitUsd must be a finite, non-negative number, got ${limitUsd}`
844
+ );
845
+ }
846
+ this.limitUsd = limitUsd;
847
+ this.priceOverrides = options.priceOverrides;
848
+ this.failClosed = options.failClosed ?? true;
849
+ this.onBlock = options.onBlock ?? defaultOnBlock;
850
+ }
851
+ /**
852
+ * Throw {@link BudgetExceeded} if the next call would cross the ceiling.
853
+ *
854
+ * Call this immediately before each LLM request. The "next call" is estimated
855
+ * from the last recorded call's cost (override with `estimatedNextCost`); the
856
+ * first call is always allowed unless the ceiling is already met. A check on
857
+ * the running total catches an overshoot if the estimate was too low.
858
+ */
859
+ check(estimatedNextCost) {
860
+ const estimate = estimatedNextCost === void 0 ? this.lastCost : Math.max(0, estimatedNextCost);
861
+ const projected = this.spentUsd + estimate;
862
+ if (this.spentUsd > this.limitUsd - EPS || projected > this.limitUsd + EPS) {
863
+ this.onBlock(this.spentUsd, this.limitUsd);
864
+ throw new BudgetExceeded(this.spentUsd, this.limitUsd);
865
+ }
866
+ }
867
+ /**
868
+ * Price one response's tokens offline and add the cost to the total.
869
+ *
870
+ * Returns the USD cost of this call. If the model is unpriceable and no `price`
871
+ * is given, behaviour depends on `failClosed`: warn + throw (default), or
872
+ * warn + skip accrual.
873
+ */
874
+ record(model, promptTokens, completionTokens, options = {}) {
875
+ let overrides = this.priceOverrides;
876
+ if (options.price !== void 0) {
877
+ overrides = { ...overrides ?? {}, [model]: options.price };
878
+ }
879
+ const priced = resolvePrice(model, overrides);
880
+ if (priced === null) {
881
+ console.warn(
882
+ `Cannot price model '${model}': not in the bundled cost map and no manual price given. The budget guard cannot enforce a ceiling on spend it cannot measure \u2014 pass { price } or set it in priceOverrides.`
883
+ );
884
+ if (this.failClosed) {
885
+ throw new UnpriceableModelError(model);
886
+ }
887
+ return 0;
888
+ }
889
+ const cost = priceTokens(priced, promptTokens, completionTokens);
890
+ this.spentUsd += cost;
891
+ if (this.spentUsd - this.limitUsd > 0 && this.spentUsd - this.limitUsd < EPS) {
892
+ this.spentUsd = this.limitUsd;
893
+ }
894
+ this.lastCost = cost;
895
+ return cost;
896
+ }
897
+ /** USD left before the ceiling (never negative). */
898
+ get remainingUsd() {
899
+ return Math.max(0, this.limitUsd - this.spentUsd);
900
+ }
901
+ };
902
+ function defaultOnBlock(spentUsd, limitUsd) {
903
+ console.error(
904
+ `BUDGET EXCEEDED \u2014 call blocked
905
+ spent so far: $${spentUsd.toFixed(6)} | ceiling: $${limitUsd.toFixed(6)}
906
+ The next call would cross your budget; floe-guard stopped your agent before it ran.`
907
+ );
908
+ }
909
+
910
+ // src/middleware.ts
911
+ function budgetGuardMiddleware(guard) {
912
+ return {
913
+ async wrapGenerate({ doGenerate, model }) {
914
+ guard.check();
915
+ const result = await doGenerate();
916
+ guard.record(
917
+ model.modelId,
918
+ result.usage.promptTokens,
919
+ result.usage.completionTokens
920
+ );
921
+ return result;
922
+ },
923
+ async wrapStream({ doStream, model }) {
924
+ guard.check();
925
+ const { stream, ...rest } = await doStream();
926
+ const guarded = stream.pipeThrough(
927
+ new TransformStream({
928
+ transform(chunk, controller) {
929
+ if (chunk.type === "finish") {
930
+ guard.record(
931
+ model.modelId,
932
+ chunk.usage.promptTokens,
933
+ chunk.usage.completionTokens
934
+ );
935
+ }
936
+ controller.enqueue(chunk);
937
+ }
938
+ })
939
+ );
940
+ return { stream: guarded, ...rest };
941
+ }
942
+ };
943
+ }
944
+ export {
945
+ BudgetExceeded,
946
+ BudgetGuard,
947
+ FloeGuardError,
948
+ UnpriceableModelError,
949
+ budgetGuardMiddleware,
950
+ priceTokens,
951
+ pricing_exports as pricing,
952
+ resolvePrice
953
+ };
954
+ //# sourceMappingURL=index.js.map