floe-guard 0.5.0 → 0.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.
package/dist/index.d.ts CHANGED
@@ -514,4 +514,33 @@ interface BudgetGuardMiddleware {
514
514
  */
515
515
  declare function budgetGuardMiddleware(guard: BudgetGuard): BudgetGuardMiddleware;
516
516
 
517
- export { type BudgetAdvisory, BudgetExceeded, BudgetGuard, type BudgetGuardMiddleware, type BudgetGuardOptions, DeadlineExceeded, FloeGuardError, type LatencyAdvisory, LatencyBudget, type LatencyBudgetOptions, type ManualPrice, type PricedModel, type SpendEvent, UnpriceableModelError, budgetGuardMiddleware, priceTokens, pricing, resolvePrice };
517
+ interface RetryPlan<T> {
518
+ /** Operation to run for this retry attempt. */
519
+ call: () => T | Promise<T>;
520
+ /**
521
+ * Estimated retry cost passed to `guard.check()` before the retry runs.
522
+ * Leave undefined to use the guard's default last-call estimate.
523
+ */
524
+ estimatedCost?: number;
525
+ }
526
+ interface BudgetRetryOptions<T> {
527
+ /** Estimated cost for retrying the original call. */
528
+ estimatedCost?: number;
529
+ /** Total attempts, including the first call. Default: 2. */
530
+ maxAttempts?: number;
531
+ /** Choose a cheaper retry plan when `guard.advisory().nearLimit` is true. */
532
+ onDegrade?: (error: unknown, advisory: BudgetAdvisory) => RetryPlan<T> | Promise<RetryPlan<T> | undefined> | undefined;
533
+ /** Decide whether an error is retryable. Defaults to all non-budget errors. */
534
+ retryIf?: (error: unknown) => boolean;
535
+ }
536
+ /**
537
+ * Run `call` with budget-aware retries.
538
+ *
539
+ * The first attempt runs unchanged. If it fails with a retryable error, the
540
+ * helper retries as-is with ample budget, asks `onDegrade` for a cheaper plan
541
+ * when near the limit, and always calls `guard.check(estimatedCost)` before a
542
+ * retry so an over-budget retry is blocked before it runs.
543
+ */
544
+ declare function withBudgetRetry<T>(guard: BudgetGuard, call: () => T | Promise<T>, options?: BudgetRetryOptions<T>): Promise<T>;
545
+
546
+ export { type BudgetAdvisory, BudgetExceeded, BudgetGuard, type BudgetGuardMiddleware, type BudgetGuardOptions, type BudgetRetryOptions, DeadlineExceeded, FloeGuardError, type LatencyAdvisory, LatencyBudget, type LatencyBudgetOptions, type ManualPrice, type PricedModel, type RetryPlan, type SpendEvent, UnpriceableModelError, budgetGuardMiddleware, priceTokens, pricing, resolvePrice, withBudgetRetry };
package/dist/index.js CHANGED
@@ -275,6 +275,222 @@ var cost_map_default = {
275
275
  litellm_provider: "openai",
276
276
  mode: "chat"
277
277
  },
278
+ "gemini-2.0-flash": {
279
+ input_cost_per_token: 1e-7,
280
+ output_cost_per_token: 4e-7,
281
+ litellm_provider: "gemini",
282
+ mode: "chat"
283
+ },
284
+ "gemini-2.0-flash-001": {
285
+ input_cost_per_token: 1e-7,
286
+ output_cost_per_token: 4e-7,
287
+ litellm_provider: "gemini",
288
+ mode: "chat"
289
+ },
290
+ "gemini-2.0-flash-lite": {
291
+ input_cost_per_token: 75e-9,
292
+ output_cost_per_token: 3e-7,
293
+ litellm_provider: "gemini",
294
+ mode: "chat"
295
+ },
296
+ "gemini-2.0-flash-lite-001": {
297
+ input_cost_per_token: 75e-9,
298
+ output_cost_per_token: 3e-7,
299
+ litellm_provider: "gemini",
300
+ mode: "chat"
301
+ },
302
+ "gemini-2.5-computer-use-preview-10-2025": {
303
+ input_cost_per_token: 125e-8,
304
+ output_cost_per_token: 1e-5,
305
+ litellm_provider: "gemini",
306
+ mode: "chat"
307
+ },
308
+ "gemini-2.5-flash": {
309
+ input_cost_per_token: 3e-7,
310
+ output_cost_per_token: 25e-7,
311
+ litellm_provider: "gemini",
312
+ mode: "chat"
313
+ },
314
+ "gemini-2.5-flash-lite": {
315
+ input_cost_per_token: 1e-7,
316
+ output_cost_per_token: 4e-7,
317
+ litellm_provider: "gemini",
318
+ mode: "chat"
319
+ },
320
+ "gemini-2.5-flash-lite-preview-06-17": {
321
+ input_cost_per_token: 1e-7,
322
+ output_cost_per_token: 4e-7,
323
+ litellm_provider: "gemini",
324
+ mode: "chat"
325
+ },
326
+ "gemini-2.5-flash-lite-preview-09-2025": {
327
+ input_cost_per_token: 1e-7,
328
+ output_cost_per_token: 4e-7,
329
+ litellm_provider: "gemini",
330
+ mode: "chat"
331
+ },
332
+ "gemini-2.5-flash-native-audio-latest": {
333
+ input_cost_per_token: 3e-7,
334
+ output_cost_per_token: 25e-7,
335
+ litellm_provider: "gemini",
336
+ mode: "chat"
337
+ },
338
+ "gemini-2.5-flash-native-audio-preview-09-2025": {
339
+ input_cost_per_token: 3e-7,
340
+ output_cost_per_token: 25e-7,
341
+ litellm_provider: "gemini",
342
+ mode: "chat"
343
+ },
344
+ "gemini-2.5-flash-native-audio-preview-12-2025": {
345
+ input_cost_per_token: 3e-7,
346
+ output_cost_per_token: 25e-7,
347
+ litellm_provider: "gemini",
348
+ mode: "chat"
349
+ },
350
+ "gemini-2.5-flash-preview-09-2025": {
351
+ input_cost_per_token: 3e-7,
352
+ output_cost_per_token: 25e-7,
353
+ litellm_provider: "gemini",
354
+ mode: "chat"
355
+ },
356
+ "gemini-2.5-pro": {
357
+ input_cost_per_token: 125e-8,
358
+ output_cost_per_token: 1e-5,
359
+ litellm_provider: "gemini",
360
+ mode: "chat"
361
+ },
362
+ "gemini-2.5-pro-preview-tts": {
363
+ input_cost_per_token: 125e-8,
364
+ output_cost_per_token: 1e-5,
365
+ litellm_provider: "gemini",
366
+ mode: "chat"
367
+ },
368
+ "gemini-3-flash-preview": {
369
+ input_cost_per_token: 5e-7,
370
+ output_cost_per_token: 3e-6,
371
+ litellm_provider: "gemini",
372
+ mode: "chat"
373
+ },
374
+ "gemini-3-pro-preview": {
375
+ input_cost_per_token: 2e-6,
376
+ output_cost_per_token: 12e-6,
377
+ litellm_provider: "gemini",
378
+ mode: "chat"
379
+ },
380
+ "gemini-3.1-flash-lite": {
381
+ input_cost_per_token: 25e-8,
382
+ output_cost_per_token: 15e-7,
383
+ litellm_provider: "gemini",
384
+ mode: "chat"
385
+ },
386
+ "gemini-3.1-flash-lite-preview": {
387
+ input_cost_per_token: 25e-8,
388
+ output_cost_per_token: 15e-7,
389
+ litellm_provider: "gemini",
390
+ mode: "chat"
391
+ },
392
+ "gemini-3.1-flash-live-preview": {
393
+ input_cost_per_token: 75e-8,
394
+ output_cost_per_token: 45e-7,
395
+ litellm_provider: "gemini",
396
+ mode: "chat"
397
+ },
398
+ "gemini-3.1-pro-preview": {
399
+ input_cost_per_token: 2e-6,
400
+ output_cost_per_token: 12e-6,
401
+ litellm_provider: "gemini",
402
+ mode: "chat"
403
+ },
404
+ "gemini-3.1-pro-preview-customtools": {
405
+ input_cost_per_token: 2e-6,
406
+ output_cost_per_token: 12e-6,
407
+ litellm_provider: "gemini",
408
+ mode: "chat"
409
+ },
410
+ "gemini-3.5-flash": {
411
+ input_cost_per_token: 15e-7,
412
+ output_cost_per_token: 9e-6,
413
+ litellm_provider: "gemini",
414
+ mode: "chat"
415
+ },
416
+ "gemini-3.5-flash-lite": {
417
+ input_cost_per_token: 3e-7,
418
+ output_cost_per_token: 25e-7,
419
+ litellm_provider: "gemini",
420
+ mode: "chat"
421
+ },
422
+ "gemini-3.6-flash": {
423
+ input_cost_per_token: 15e-7,
424
+ output_cost_per_token: 75e-7,
425
+ litellm_provider: "gemini",
426
+ mode: "chat"
427
+ },
428
+ "gemini-embedding-001": {
429
+ input_cost_per_token: 15e-8,
430
+ output_cost_per_token: 0,
431
+ litellm_provider: "gemini",
432
+ mode: "embedding"
433
+ },
434
+ "gemini-embedding-2": {
435
+ input_cost_per_token: 2e-7,
436
+ output_cost_per_token: 0,
437
+ litellm_provider: "gemini",
438
+ mode: "embedding"
439
+ },
440
+ "gemini-embedding-2-preview": {
441
+ input_cost_per_token: 2e-7,
442
+ output_cost_per_token: 0,
443
+ litellm_provider: "gemini",
444
+ mode: "embedding"
445
+ },
446
+ "gemini-exp-1206": {
447
+ input_cost_per_token: 3e-7,
448
+ output_cost_per_token: 25e-7,
449
+ litellm_provider: "gemini",
450
+ mode: "chat"
451
+ },
452
+ "gemini-flash-latest": {
453
+ input_cost_per_token: 3e-7,
454
+ output_cost_per_token: 25e-7,
455
+ litellm_provider: "gemini",
456
+ mode: "chat"
457
+ },
458
+ "gemini-flash-lite-latest": {
459
+ input_cost_per_token: 1e-7,
460
+ output_cost_per_token: 4e-7,
461
+ litellm_provider: "gemini",
462
+ mode: "chat"
463
+ },
464
+ "gemini-gemma-2-27b-it": {
465
+ input_cost_per_token: 35e-8,
466
+ output_cost_per_token: 105e-8,
467
+ litellm_provider: "gemini",
468
+ mode: "chat"
469
+ },
470
+ "gemini-gemma-2-9b-it": {
471
+ input_cost_per_token: 35e-8,
472
+ output_cost_per_token: 105e-8,
473
+ litellm_provider: "gemini",
474
+ mode: "chat"
475
+ },
476
+ "gemini-omni-flash-preview": {
477
+ input_cost_per_token: 15e-7,
478
+ output_cost_per_token: 9e-6,
479
+ litellm_provider: "gemini",
480
+ mode: "chat"
481
+ },
482
+ "gemini-pro-latest": {
483
+ input_cost_per_token: 125e-8,
484
+ output_cost_per_token: 1e-5,
485
+ litellm_provider: "gemini",
486
+ mode: "chat"
487
+ },
488
+ "gemini-robotics-er-1.5-preview": {
489
+ input_cost_per_token: 3e-7,
490
+ output_cost_per_token: 25e-7,
491
+ litellm_provider: "gemini",
492
+ mode: "chat"
493
+ },
278
494
  "gpt-3.5-turbo": {
279
495
  input_cost_per_token: 5e-7,
280
496
  output_cost_per_token: 15e-7,
@@ -449,18 +665,6 @@ var cost_map_default = {
449
665
  litellm_provider: "openai",
450
666
  mode: "chat"
451
667
  },
452
- "gpt-4o-mini-realtime-preview": {
453
- input_cost_per_token: 6e-7,
454
- output_cost_per_token: 24e-7,
455
- litellm_provider: "openai",
456
- mode: "chat"
457
- },
458
- "gpt-4o-mini-realtime-preview-2024-12-17": {
459
- input_cost_per_token: 6e-7,
460
- output_cost_per_token: 24e-7,
461
- litellm_provider: "openai",
462
- mode: "chat"
463
- },
464
668
  "gpt-4o-mini-search-preview": {
465
669
  input_cost_per_token: 15e-8,
466
670
  output_cost_per_token: 6e-7,
@@ -473,24 +677,6 @@ var cost_map_default = {
473
677
  litellm_provider: "openai",
474
678
  mode: "chat"
475
679
  },
476
- "gpt-4o-realtime-preview": {
477
- input_cost_per_token: 5e-6,
478
- output_cost_per_token: 2e-5,
479
- litellm_provider: "openai",
480
- mode: "chat"
481
- },
482
- "gpt-4o-realtime-preview-2024-12-17": {
483
- input_cost_per_token: 5e-6,
484
- output_cost_per_token: 2e-5,
485
- litellm_provider: "openai",
486
- mode: "chat"
487
- },
488
- "gpt-4o-realtime-preview-2025-06-03": {
489
- input_cost_per_token: 5e-6,
490
- output_cost_per_token: 2e-5,
491
- litellm_provider: "openai",
492
- mode: "chat"
493
- },
494
680
  "gpt-4o-search-preview": {
495
681
  input_cost_per_token: 25e-7,
496
682
  output_cost_per_token: 1e-5,
@@ -713,60 +899,6 @@ var cost_map_default = {
713
899
  litellm_provider: "openai",
714
900
  mode: "chat"
715
901
  },
716
- "gpt-realtime": {
717
- input_cost_per_token: 4e-6,
718
- output_cost_per_token: 16e-6,
719
- litellm_provider: "openai",
720
- mode: "chat"
721
- },
722
- "gpt-realtime-1.5": {
723
- input_cost_per_token: 4e-6,
724
- output_cost_per_token: 16e-6,
725
- litellm_provider: "openai",
726
- mode: "chat"
727
- },
728
- "gpt-realtime-2": {
729
- input_cost_per_token: 4e-6,
730
- output_cost_per_token: 16e-6,
731
- litellm_provider: "openai",
732
- mode: "chat"
733
- },
734
- "gpt-realtime-2.1": {
735
- input_cost_per_token: 4e-6,
736
- output_cost_per_token: 24e-6,
737
- litellm_provider: "openai",
738
- mode: "chat"
739
- },
740
- "gpt-realtime-2.1-mini": {
741
- input_cost_per_token: 6e-7,
742
- output_cost_per_token: 24e-7,
743
- litellm_provider: "openai",
744
- mode: "chat"
745
- },
746
- "gpt-realtime-2025-08-28": {
747
- input_cost_per_token: 4e-6,
748
- output_cost_per_token: 16e-6,
749
- litellm_provider: "openai",
750
- mode: "chat"
751
- },
752
- "gpt-realtime-mini": {
753
- input_cost_per_token: 6e-7,
754
- output_cost_per_token: 24e-7,
755
- litellm_provider: "openai",
756
- mode: "chat"
757
- },
758
- "gpt-realtime-mini-2025-10-06": {
759
- input_cost_per_token: 6e-7,
760
- output_cost_per_token: 24e-7,
761
- litellm_provider: "openai",
762
- mode: "chat"
763
- },
764
- "gpt-realtime-mini-2025-12-15": {
765
- input_cost_per_token: 6e-7,
766
- output_cost_per_token: 24e-7,
767
- litellm_provider: "openai",
768
- mode: "chat"
769
- },
770
902
  "llama-3.1-8b-instant": {
771
903
  input_cost_per_token: 5e-8,
772
904
  output_cost_per_token: 8e-8,
@@ -1492,6 +1624,42 @@ function budgetGuardMiddleware(guard) {
1492
1624
  }
1493
1625
  };
1494
1626
  }
1627
+
1628
+ // src/retry.ts
1629
+ function defaultRetryIf(error) {
1630
+ return !(error instanceof BudgetExceeded);
1631
+ }
1632
+ async function withBudgetRetry(guard, call, options = {}) {
1633
+ const maxAttempts = options.maxAttempts ?? 2;
1634
+ if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {
1635
+ throw new RangeError(`maxAttempts must be an integer >= 1, got ${maxAttempts}`);
1636
+ }
1637
+ const retryIf = options.retryIf ?? defaultRetryIf;
1638
+ let plan = { call, estimatedCost: options.estimatedCost };
1639
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
1640
+ try {
1641
+ return await plan.call();
1642
+ } catch (error) {
1643
+ if (attempt >= maxAttempts || !retryIf(error)) {
1644
+ throw error;
1645
+ }
1646
+ plan = await nextPlan(guard, error, plan, options.onDegrade);
1647
+ }
1648
+ }
1649
+ throw new Error("unreachable");
1650
+ }
1651
+ async function nextPlan(guard, error, current, onDegrade) {
1652
+ const advisory = guard.advisory();
1653
+ if (advisory.nearLimit && onDegrade !== void 0) {
1654
+ const degraded = await onDegrade(error, advisory);
1655
+ if (degraded !== void 0) {
1656
+ guard.check(degraded.estimatedCost);
1657
+ return degraded;
1658
+ }
1659
+ }
1660
+ guard.check(current.estimatedCost);
1661
+ return current;
1662
+ }
1495
1663
  export {
1496
1664
  BudgetExceeded,
1497
1665
  BudgetGuard,
@@ -1502,6 +1670,7 @@ export {
1502
1670
  budgetGuardMiddleware,
1503
1671
  priceTokens,
1504
1672
  pricing_exports as pricing,
1505
- resolvePrice
1673
+ resolvePrice,
1674
+ withBudgetRetry
1506
1675
  };
1507
1676
  //# sourceMappingURL=index.js.map