cascade-ai 0.48.0 → 0.49.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.
@@ -222594,8 +222594,1660 @@ Anthropic.Messages = Messages2;
222594
222594
  Anthropic.Models = Models2;
222595
222595
  Anthropic.Beta = Beta;
222596
222596
 
222597
+ // src/core/router/pricing-data.json
222598
+ var pricing_data_default = {
222599
+ entries: [
222600
+ {
222601
+ model: "claude-opus-5",
222602
+ provider: "anthropic",
222603
+ modality: "text",
222604
+ currency: "USD",
222605
+ asOf: "2026-07-27",
222606
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222607
+ provenance: "vendor-pricing-page",
222608
+ tiers: [
222609
+ {
222610
+ inputPer1m: 5,
222611
+ outputPer1m: 25,
222612
+ cachedInputPer1m: 0.5,
222613
+ cacheWritePer1m: 6.25,
222614
+ reasoningOutputPer1m: 25
222615
+ }
222616
+ ],
222617
+ batchMultiplier: 0.5,
222618
+ contextWindow: 1e6
222619
+ },
222620
+ {
222621
+ model: "claude-opus-4-8",
222622
+ provider: "anthropic",
222623
+ modality: "text",
222624
+ currency: "USD",
222625
+ asOf: "2026-07-27",
222626
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222627
+ provenance: "vendor-pricing-page",
222628
+ tiers: [
222629
+ {
222630
+ inputPer1m: 5,
222631
+ outputPer1m: 25,
222632
+ cachedInputPer1m: 0.5,
222633
+ cacheWritePer1m: 6.25,
222634
+ reasoningOutputPer1m: 25
222635
+ }
222636
+ ],
222637
+ batchMultiplier: 0.5,
222638
+ contextWindow: 1e6
222639
+ },
222640
+ {
222641
+ model: "claude-opus-4-7",
222642
+ provider: "anthropic",
222643
+ modality: "text",
222644
+ currency: "USD",
222645
+ asOf: "2026-07-27",
222646
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222647
+ provenance: "vendor-pricing-page",
222648
+ tiers: [
222649
+ {
222650
+ inputPer1m: 5,
222651
+ outputPer1m: 25,
222652
+ cachedInputPer1m: 0.5,
222653
+ cacheWritePer1m: 6.25,
222654
+ reasoningOutputPer1m: 25
222655
+ }
222656
+ ],
222657
+ batchMultiplier: 0.5,
222658
+ contextWindow: 1e6
222659
+ },
222660
+ {
222661
+ model: "claude-opus-4-6",
222662
+ provider: "anthropic",
222663
+ modality: "text",
222664
+ currency: "USD",
222665
+ asOf: "2026-07-27",
222666
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222667
+ provenance: "vendor-pricing-page",
222668
+ tiers: [
222669
+ {
222670
+ inputPer1m: 5,
222671
+ outputPer1m: 25,
222672
+ cachedInputPer1m: 0.5,
222673
+ cacheWritePer1m: 6.25,
222674
+ reasoningOutputPer1m: 25
222675
+ }
222676
+ ],
222677
+ batchMultiplier: 0.5,
222678
+ contextWindow: 1e6
222679
+ },
222680
+ {
222681
+ model: "claude-opus-4-5",
222682
+ provider: "anthropic",
222683
+ modality: "text",
222684
+ currency: "USD",
222685
+ asOf: "2026-07-27",
222686
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222687
+ provenance: "vendor-pricing-page",
222688
+ tiers: [
222689
+ {
222690
+ inputPer1m: 5,
222691
+ outputPer1m: 25,
222692
+ cachedInputPer1m: 0.5,
222693
+ cacheWritePer1m: 6.25,
222694
+ reasoningOutputPer1m: 25
222695
+ }
222696
+ ],
222697
+ batchMultiplier: 0.5,
222698
+ contextWindow: 2e5
222699
+ },
222700
+ {
222701
+ model: "claude-opus-4-1",
222702
+ provider: "anthropic",
222703
+ modality: "text",
222704
+ currency: "USD",
222705
+ asOf: "2026-07-27",
222706
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222707
+ provenance: "vendor-pricing-page",
222708
+ tiers: [
222709
+ {
222710
+ inputPer1m: 15,
222711
+ outputPer1m: 75,
222712
+ cachedInputPer1m: 1.5,
222713
+ cacheWritePer1m: 18.75,
222714
+ reasoningOutputPer1m: 75
222715
+ }
222716
+ ],
222717
+ batchMultiplier: 0.5,
222718
+ contextWindow: 2e5,
222719
+ notes: "Deprecated by Anthropic; priced for historical/cost-reporting accuracy."
222720
+ },
222721
+ {
222722
+ model: "claude-opus-4",
222723
+ provider: "anthropic",
222724
+ modality: "text",
222725
+ currency: "USD",
222726
+ asOf: "2026-07-27",
222727
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222728
+ provenance: "vendor-pricing-page",
222729
+ tiers: [
222730
+ {
222731
+ inputPer1m: 15,
222732
+ outputPer1m: 75,
222733
+ cachedInputPer1m: 1.5,
222734
+ cacheWritePer1m: 18.75,
222735
+ reasoningOutputPer1m: 75
222736
+ }
222737
+ ],
222738
+ batchMultiplier: 0.5,
222739
+ contextWindow: 2e5,
222740
+ notes: "Retired except on Google Cloud; priced for historical/cost-reporting accuracy."
222741
+ },
222742
+ {
222743
+ model: "claude-sonnet-5",
222744
+ provider: "anthropic",
222745
+ modality: "text",
222746
+ currency: "USD",
222747
+ asOf: "2026-07-27",
222748
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222749
+ provenance: "vendor-pricing-page",
222750
+ tiers: [
222751
+ {
222752
+ inputPer1m: 2,
222753
+ outputPer1m: 10,
222754
+ cachedInputPer1m: 0.2,
222755
+ cacheWritePer1m: 2.5,
222756
+ reasoningOutputPer1m: 10
222757
+ }
222758
+ ],
222759
+ batchMultiplier: 0.5,
222760
+ contextWindow: 1e6,
222761
+ notes: "Introductory pricing through 2026-08-31. Standard pricing of $3/$15 per 1M takes effect 2026-09-01 \u2014 re-check this entry then."
222762
+ },
222763
+ {
222764
+ model: "claude-sonnet-4-6",
222765
+ provider: "anthropic",
222766
+ modality: "text",
222767
+ currency: "USD",
222768
+ asOf: "2026-07-27",
222769
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222770
+ provenance: "vendor-pricing-page",
222771
+ tiers: [
222772
+ {
222773
+ inputPer1m: 3,
222774
+ outputPer1m: 15,
222775
+ cachedInputPer1m: 0.3,
222776
+ cacheWritePer1m: 3.75,
222777
+ reasoningOutputPer1m: 15
222778
+ }
222779
+ ],
222780
+ batchMultiplier: 0.5,
222781
+ contextWindow: 1e6
222782
+ },
222783
+ {
222784
+ model: "claude-sonnet-4-5",
222785
+ provider: "anthropic",
222786
+ modality: "text",
222787
+ currency: "USD",
222788
+ asOf: "2026-07-27",
222789
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222790
+ provenance: "vendor-pricing-page",
222791
+ tiers: [
222792
+ {
222793
+ maxInputTokens: 2e5,
222794
+ inputPer1m: 3,
222795
+ outputPer1m: 15,
222796
+ cachedInputPer1m: 0.3,
222797
+ cacheWritePer1m: 3.75,
222798
+ reasoningOutputPer1m: 15
222799
+ },
222800
+ {
222801
+ inputPer1m: 6,
222802
+ outputPer1m: 22.5,
222803
+ cachedInputPer1m: 0.6,
222804
+ cacheWritePer1m: 7.5,
222805
+ reasoningOutputPer1m: 22.5
222806
+ }
222807
+ ],
222808
+ batchMultiplier: 0.5,
222809
+ contextWindow: 2e5,
222810
+ notes: "Long-context (>200K) premium applies to the 1M-context beta. Base rates from the Anthropic pricing page; the >200K tier from the litellm catalog (Anthropic does not tabulate it on the pricing page)."
222811
+ },
222812
+ {
222813
+ model: "claude-sonnet-4",
222814
+ provider: "anthropic",
222815
+ modality: "text",
222816
+ currency: "USD",
222817
+ asOf: "2026-07-27",
222818
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222819
+ provenance: "vendor-pricing-page",
222820
+ tiers: [
222821
+ {
222822
+ inputPer1m: 3,
222823
+ outputPer1m: 15,
222824
+ cachedInputPer1m: 0.3,
222825
+ cacheWritePer1m: 3.75,
222826
+ reasoningOutputPer1m: 15
222827
+ }
222828
+ ],
222829
+ batchMultiplier: 0.5,
222830
+ contextWindow: 2e5
222831
+ },
222832
+ {
222833
+ model: "claude-haiku-4-5",
222834
+ provider: "anthropic",
222835
+ modality: "text",
222836
+ currency: "USD",
222837
+ asOf: "2026-07-27",
222838
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222839
+ provenance: "vendor-pricing-page",
222840
+ tiers: [
222841
+ {
222842
+ inputPer1m: 1,
222843
+ outputPer1m: 5,
222844
+ cachedInputPer1m: 0.1,
222845
+ cacheWritePer1m: 1.25,
222846
+ reasoningOutputPer1m: 5
222847
+ }
222848
+ ],
222849
+ batchMultiplier: 0.5,
222850
+ contextWindow: 2e5
222851
+ },
222852
+ {
222853
+ model: "claude-haiku-3-5",
222854
+ provider: "anthropic",
222855
+ modality: "text",
222856
+ currency: "USD",
222857
+ asOf: "2026-07-27",
222858
+ source: "https://platform.claude.com/docs/en/about-claude/pricing",
222859
+ provenance: "vendor-pricing-page",
222860
+ tiers: [
222861
+ {
222862
+ inputPer1m: 0.8,
222863
+ outputPer1m: 4,
222864
+ cachedInputPer1m: 0.08,
222865
+ cacheWritePer1m: 1,
222866
+ reasoningOutputPer1m: 4
222867
+ }
222868
+ ],
222869
+ batchMultiplier: 0.5,
222870
+ contextWindow: 2e5
222871
+ },
222872
+ {
222873
+ model: "gpt-5.6-sol",
222874
+ provider: "openai",
222875
+ aliases: [
222876
+ "gpt-5.6"
222877
+ ],
222878
+ modality: "text",
222879
+ currency: "USD",
222880
+ asOf: "2026-07-27",
222881
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
222882
+ provenance: "litellm-catalog",
222883
+ tiers: [
222884
+ {
222885
+ maxInputTokens: 272e3,
222886
+ inputPer1m: 5,
222887
+ outputPer1m: 30,
222888
+ cachedInputPer1m: 0.5,
222889
+ cacheWritePer1m: 6.25
222890
+ },
222891
+ {
222892
+ inputPer1m: 10,
222893
+ outputPer1m: 45,
222894
+ cachedInputPer1m: 1,
222895
+ cacheWritePer1m: 12.5
222896
+ }
222897
+ ],
222898
+ batchMultiplier: 0.5,
222899
+ contextWindow: 105e4
222900
+ },
222901
+ {
222902
+ model: "gpt-5.6-terra",
222903
+ provider: "openai",
222904
+ modality: "text",
222905
+ currency: "USD",
222906
+ asOf: "2026-07-27",
222907
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
222908
+ provenance: "litellm-catalog",
222909
+ tiers: [
222910
+ {
222911
+ maxInputTokens: 272e3,
222912
+ inputPer1m: 2.5,
222913
+ outputPer1m: 15,
222914
+ cachedInputPer1m: 0.25,
222915
+ cacheWritePer1m: 3.125
222916
+ },
222917
+ {
222918
+ inputPer1m: 5,
222919
+ outputPer1m: 22.5,
222920
+ cachedInputPer1m: 0.5,
222921
+ cacheWritePer1m: 6.25
222922
+ }
222923
+ ],
222924
+ batchMultiplier: 0.5,
222925
+ contextWindow: 105e4
222926
+ },
222927
+ {
222928
+ model: "gpt-5.6-luna",
222929
+ provider: "openai",
222930
+ modality: "text",
222931
+ currency: "USD",
222932
+ asOf: "2026-07-27",
222933
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
222934
+ provenance: "litellm-catalog",
222935
+ tiers: [
222936
+ {
222937
+ maxInputTokens: 272e3,
222938
+ inputPer1m: 1,
222939
+ outputPer1m: 6,
222940
+ cachedInputPer1m: 0.1,
222941
+ cacheWritePer1m: 1.25
222942
+ },
222943
+ {
222944
+ inputPer1m: 2,
222945
+ outputPer1m: 9,
222946
+ cachedInputPer1m: 0.2,
222947
+ cacheWritePer1m: 2.5
222948
+ }
222949
+ ],
222950
+ batchMultiplier: 0.5,
222951
+ contextWindow: 105e4
222952
+ },
222953
+ {
222954
+ model: "gpt-5.5",
222955
+ provider: "openai",
222956
+ modality: "text",
222957
+ currency: "USD",
222958
+ asOf: "2026-07-27",
222959
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
222960
+ provenance: "litellm-catalog",
222961
+ tiers: [
222962
+ {
222963
+ maxInputTokens: 272e3,
222964
+ inputPer1m: 5,
222965
+ outputPer1m: 30,
222966
+ cachedInputPer1m: 0.5
222967
+ },
222968
+ {
222969
+ inputPer1m: 10,
222970
+ outputPer1m: 45,
222971
+ cachedInputPer1m: 1
222972
+ }
222973
+ ],
222974
+ batchMultiplier: 0.5,
222975
+ contextWindow: 105e4
222976
+ },
222977
+ {
222978
+ model: "gpt-5.4",
222979
+ provider: "openai",
222980
+ modality: "text",
222981
+ currency: "USD",
222982
+ asOf: "2026-07-27",
222983
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
222984
+ provenance: "litellm-catalog",
222985
+ tiers: [
222986
+ {
222987
+ maxInputTokens: 272e3,
222988
+ inputPer1m: 2.5,
222989
+ outputPer1m: 15,
222990
+ cachedInputPer1m: 0.25
222991
+ },
222992
+ {
222993
+ inputPer1m: 5,
222994
+ outputPer1m: 22.5,
222995
+ cachedInputPer1m: 0.5
222996
+ }
222997
+ ],
222998
+ batchMultiplier: 0.5,
222999
+ contextWindow: 105e4
223000
+ },
223001
+ {
223002
+ model: "gpt-5.4-mini",
223003
+ provider: "openai",
223004
+ modality: "text",
223005
+ currency: "USD",
223006
+ asOf: "2026-07-27",
223007
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223008
+ provenance: "litellm-catalog",
223009
+ tiers: [
223010
+ {
223011
+ inputPer1m: 0.75,
223012
+ outputPer1m: 4.5,
223013
+ cachedInputPer1m: 0.075
223014
+ }
223015
+ ],
223016
+ batchMultiplier: 0.5,
223017
+ contextWindow: 105e4
223018
+ },
223019
+ {
223020
+ model: "gpt-5",
223021
+ provider: "openai",
223022
+ modality: "text",
223023
+ currency: "USD",
223024
+ asOf: "2026-07-27",
223025
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223026
+ provenance: "litellm-catalog",
223027
+ tiers: [
223028
+ {
223029
+ inputPer1m: 1.25,
223030
+ outputPer1m: 10,
223031
+ cachedInputPer1m: 0.125
223032
+ }
223033
+ ],
223034
+ contextWindow: 272e3
223035
+ },
223036
+ {
223037
+ model: "gpt-5-mini",
223038
+ provider: "openai",
223039
+ modality: "text",
223040
+ currency: "USD",
223041
+ asOf: "2026-07-27",
223042
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223043
+ provenance: "litellm-catalog",
223044
+ tiers: [
223045
+ {
223046
+ inputPer1m: 0.25,
223047
+ outputPer1m: 2,
223048
+ cachedInputPer1m: 0.025
223049
+ }
223050
+ ],
223051
+ contextWindow: 272e3
223052
+ },
223053
+ {
223054
+ model: "gpt-5-nano",
223055
+ provider: "openai",
223056
+ modality: "text",
223057
+ currency: "USD",
223058
+ asOf: "2026-07-27",
223059
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223060
+ provenance: "litellm-catalog",
223061
+ tiers: [
223062
+ {
223063
+ inputPer1m: 0.05,
223064
+ outputPer1m: 0.4,
223065
+ cachedInputPer1m: 5e-3
223066
+ }
223067
+ ],
223068
+ contextWindow: 272e3
223069
+ },
223070
+ {
223071
+ model: "gpt-4.1",
223072
+ provider: "openai",
223073
+ modality: "text",
223074
+ currency: "USD",
223075
+ asOf: "2026-07-27",
223076
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223077
+ provenance: "litellm-catalog",
223078
+ tiers: [
223079
+ {
223080
+ inputPer1m: 2,
223081
+ outputPer1m: 8,
223082
+ cachedInputPer1m: 0.5
223083
+ }
223084
+ ],
223085
+ batchMultiplier: 0.5,
223086
+ contextWindow: 1047576
223087
+ },
223088
+ {
223089
+ model: "gpt-4.1-mini",
223090
+ provider: "openai",
223091
+ modality: "text",
223092
+ currency: "USD",
223093
+ asOf: "2026-07-27",
223094
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223095
+ provenance: "litellm-catalog",
223096
+ tiers: [
223097
+ {
223098
+ inputPer1m: 0.4,
223099
+ outputPer1m: 1.6,
223100
+ cachedInputPer1m: 0.1
223101
+ }
223102
+ ],
223103
+ batchMultiplier: 0.5,
223104
+ contextWindow: 1047576
223105
+ },
223106
+ {
223107
+ model: "gpt-4.1-nano",
223108
+ provider: "openai",
223109
+ modality: "text",
223110
+ currency: "USD",
223111
+ asOf: "2026-07-27",
223112
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223113
+ provenance: "litellm-catalog",
223114
+ tiers: [
223115
+ {
223116
+ inputPer1m: 0.1,
223117
+ outputPer1m: 0.4,
223118
+ cachedInputPer1m: 0.025
223119
+ }
223120
+ ],
223121
+ batchMultiplier: 0.5,
223122
+ contextWindow: 1047576
223123
+ },
223124
+ {
223125
+ model: "gpt-4o",
223126
+ provider: "openai",
223127
+ modality: "text",
223128
+ currency: "USD",
223129
+ asOf: "2026-07-27",
223130
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223131
+ provenance: "litellm-catalog",
223132
+ tiers: [
223133
+ {
223134
+ inputPer1m: 2.5,
223135
+ outputPer1m: 10,
223136
+ cachedInputPer1m: 1.25
223137
+ }
223138
+ ],
223139
+ batchMultiplier: 0.5,
223140
+ contextWindow: 128e3
223141
+ },
223142
+ {
223143
+ model: "gpt-4o-mini",
223144
+ provider: "openai",
223145
+ modality: "text",
223146
+ currency: "USD",
223147
+ asOf: "2026-07-27",
223148
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223149
+ provenance: "litellm-catalog",
223150
+ tiers: [
223151
+ {
223152
+ inputPer1m: 0.15,
223153
+ outputPer1m: 0.6,
223154
+ cachedInputPer1m: 0.075
223155
+ }
223156
+ ],
223157
+ batchMultiplier: 0.5,
223158
+ contextWindow: 128e3
223159
+ },
223160
+ {
223161
+ model: "gpt-5.5",
223162
+ provider: "azure",
223163
+ region: "global",
223164
+ modality: "text",
223165
+ currency: "USD",
223166
+ asOf: "2026-07-27",
223167
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223168
+ provenance: "litellm-catalog",
223169
+ tiers: [
223170
+ {
223171
+ maxInputTokens: 272e3,
223172
+ inputPer1m: 5,
223173
+ outputPer1m: 30,
223174
+ cachedInputPer1m: 0.5
223175
+ },
223176
+ {
223177
+ inputPer1m: 10,
223178
+ outputPer1m: 45,
223179
+ cachedInputPer1m: 1
223180
+ }
223181
+ ],
223182
+ contextWindow: 105e4
223183
+ },
223184
+ {
223185
+ model: "gpt-5.5",
223186
+ provider: "azure",
223187
+ region: "us",
223188
+ modality: "text",
223189
+ currency: "USD",
223190
+ asOf: "2026-07-27",
223191
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223192
+ provenance: "litellm-catalog",
223193
+ tiers: [
223194
+ {
223195
+ maxInputTokens: 272e3,
223196
+ inputPer1m: 5.5,
223197
+ outputPer1m: 33,
223198
+ cachedInputPer1m: 0.55
223199
+ },
223200
+ {
223201
+ inputPer1m: 11,
223202
+ outputPer1m: 49.5,
223203
+ cachedInputPer1m: 1.1
223204
+ }
223205
+ ],
223206
+ contextWindow: 105e4
223207
+ },
223208
+ {
223209
+ model: "gpt-5.5",
223210
+ provider: "azure",
223211
+ region: "eu",
223212
+ modality: "text",
223213
+ currency: "USD",
223214
+ asOf: "2026-07-27",
223215
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223216
+ provenance: "litellm-catalog",
223217
+ tiers: [
223218
+ {
223219
+ maxInputTokens: 272e3,
223220
+ inputPer1m: 5.5,
223221
+ outputPer1m: 33,
223222
+ cachedInputPer1m: 0.55
223223
+ },
223224
+ {
223225
+ inputPer1m: 11,
223226
+ outputPer1m: 49.5,
223227
+ cachedInputPer1m: 1.1
223228
+ }
223229
+ ],
223230
+ contextWindow: 105e4
223231
+ },
223232
+ {
223233
+ model: "gpt-5.4",
223234
+ provider: "azure",
223235
+ region: "global",
223236
+ modality: "text",
223237
+ currency: "USD",
223238
+ asOf: "2026-07-27",
223239
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223240
+ provenance: "litellm-catalog",
223241
+ tiers: [
223242
+ {
223243
+ maxInputTokens: 272e3,
223244
+ inputPer1m: 2.5,
223245
+ outputPer1m: 15,
223246
+ cachedInputPer1m: 0.25
223247
+ },
223248
+ {
223249
+ inputPer1m: 5,
223250
+ outputPer1m: 22.5,
223251
+ cachedInputPer1m: 0.5
223252
+ }
223253
+ ],
223254
+ contextWindow: 105e4
223255
+ },
223256
+ {
223257
+ model: "gpt-5.4",
223258
+ provider: "azure",
223259
+ region: "us",
223260
+ modality: "text",
223261
+ currency: "USD",
223262
+ asOf: "2026-07-27",
223263
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223264
+ provenance: "litellm-catalog",
223265
+ tiers: [
223266
+ {
223267
+ inputPer1m: 2.75,
223268
+ outputPer1m: 16.5,
223269
+ cachedInputPer1m: 0.28
223270
+ }
223271
+ ],
223272
+ contextWindow: 105e4
223273
+ },
223274
+ {
223275
+ model: "gpt-5.4",
223276
+ provider: "azure",
223277
+ region: "eu",
223278
+ modality: "text",
223279
+ currency: "USD",
223280
+ asOf: "2026-07-27",
223281
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223282
+ provenance: "litellm-catalog",
223283
+ tiers: [
223284
+ {
223285
+ inputPer1m: 2.75,
223286
+ outputPer1m: 16.5,
223287
+ cachedInputPer1m: 0.28
223288
+ }
223289
+ ],
223290
+ contextWindow: 105e4
223291
+ },
223292
+ {
223293
+ model: "gpt-5.6-terra",
223294
+ provider: "azure",
223295
+ region: "global",
223296
+ modality: "text",
223297
+ currency: "USD",
223298
+ asOf: "2026-07-27",
223299
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223300
+ provenance: "litellm-catalog",
223301
+ tiers: [
223302
+ {
223303
+ maxInputTokens: 272e3,
223304
+ inputPer1m: 2.5,
223305
+ outputPer1m: 15,
223306
+ cachedInputPer1m: 0.25
223307
+ },
223308
+ {
223309
+ inputPer1m: 5,
223310
+ outputPer1m: 22.5,
223311
+ cachedInputPer1m: 0.5
223312
+ }
223313
+ ],
223314
+ contextWindow: 105e4
223315
+ },
223316
+ {
223317
+ model: "gpt-5.6-terra",
223318
+ provider: "azure",
223319
+ region: "eu",
223320
+ modality: "text",
223321
+ currency: "USD",
223322
+ asOf: "2026-07-27",
223323
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223324
+ provenance: "litellm-catalog",
223325
+ tiers: [
223326
+ {
223327
+ maxInputTokens: 272e3,
223328
+ inputPer1m: 2.75,
223329
+ outputPer1m: 16.5,
223330
+ cachedInputPer1m: 0.275
223331
+ },
223332
+ {
223333
+ inputPer1m: 5.5,
223334
+ outputPer1m: 24.75,
223335
+ cachedInputPer1m: 0.55
223336
+ }
223337
+ ],
223338
+ contextWindow: 105e4
223339
+ },
223340
+ {
223341
+ model: "gpt-5",
223342
+ provider: "azure",
223343
+ region: "global",
223344
+ modality: "text",
223345
+ currency: "USD",
223346
+ asOf: "2026-07-27",
223347
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223348
+ provenance: "litellm-catalog",
223349
+ tiers: [
223350
+ {
223351
+ inputPer1m: 1.25,
223352
+ outputPer1m: 10,
223353
+ cachedInputPer1m: 0.125
223354
+ }
223355
+ ],
223356
+ contextWindow: 272e3
223357
+ },
223358
+ {
223359
+ model: "gpt-5-mini",
223360
+ provider: "azure",
223361
+ region: "global",
223362
+ modality: "text",
223363
+ currency: "USD",
223364
+ asOf: "2026-07-27",
223365
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223366
+ provenance: "litellm-catalog",
223367
+ tiers: [
223368
+ {
223369
+ inputPer1m: 0.25,
223370
+ outputPer1m: 2,
223371
+ cachedInputPer1m: 0.025
223372
+ }
223373
+ ],
223374
+ contextWindow: 272e3
223375
+ },
223376
+ {
223377
+ model: "gpt-5-nano",
223378
+ provider: "azure",
223379
+ region: "global",
223380
+ modality: "text",
223381
+ currency: "USD",
223382
+ asOf: "2026-07-27",
223383
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223384
+ provenance: "litellm-catalog",
223385
+ tiers: [
223386
+ {
223387
+ inputPer1m: 0.05,
223388
+ outputPer1m: 0.4,
223389
+ cachedInputPer1m: 5e-3
223390
+ }
223391
+ ],
223392
+ contextWindow: 272e3
223393
+ },
223394
+ {
223395
+ model: "gpt-4.1",
223396
+ provider: "azure",
223397
+ region: "global",
223398
+ modality: "text",
223399
+ currency: "USD",
223400
+ asOf: "2026-07-27",
223401
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223402
+ provenance: "litellm-catalog",
223403
+ tiers: [
223404
+ {
223405
+ inputPer1m: 2,
223406
+ outputPer1m: 8,
223407
+ cachedInputPer1m: 0.5
223408
+ }
223409
+ ],
223410
+ batchMultiplier: 0.5,
223411
+ contextWindow: 1047576
223412
+ },
223413
+ {
223414
+ model: "gpt-4o",
223415
+ provider: "azure",
223416
+ region: "global",
223417
+ modality: "text",
223418
+ currency: "USD",
223419
+ asOf: "2026-07-27",
223420
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223421
+ provenance: "litellm-catalog",
223422
+ tiers: [
223423
+ {
223424
+ inputPer1m: 2.5,
223425
+ outputPer1m: 10,
223426
+ cachedInputPer1m: 1.25
223427
+ }
223428
+ ],
223429
+ contextWindow: 128e3
223430
+ },
223431
+ {
223432
+ model: "gpt-4o-mini",
223433
+ provider: "azure",
223434
+ region: "global",
223435
+ modality: "text",
223436
+ currency: "USD",
223437
+ asOf: "2026-07-27",
223438
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223439
+ provenance: "litellm-catalog",
223440
+ tiers: [
223441
+ {
223442
+ inputPer1m: 0.165,
223443
+ outputPer1m: 0.66,
223444
+ cachedInputPer1m: 0.075
223445
+ }
223446
+ ],
223447
+ contextWindow: 128e3,
223448
+ notes: "Azure charges $0.165/$0.66 per 1M for gpt-4o-mini vs $0.15/$0.60 on OpenAI \u2014 same model, different price."
223449
+ },
223450
+ {
223451
+ model: "gemini-3.1-pro",
223452
+ provider: "gemini",
223453
+ aliases: [
223454
+ "gemini-3.1-pro-preview"
223455
+ ],
223456
+ modality: "text",
223457
+ currency: "USD",
223458
+ asOf: "2026-07-27",
223459
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
223460
+ provenance: "vendor-pricing-page",
223461
+ tiers: [
223462
+ {
223463
+ maxInputTokens: 2e5,
223464
+ inputPer1m: 2,
223465
+ outputPer1m: 12,
223466
+ cachedInputPer1m: 0.2,
223467
+ reasoningOutputPer1m: 12
223468
+ },
223469
+ {
223470
+ inputPer1m: 4,
223471
+ outputPer1m: 18,
223472
+ cachedInputPer1m: 0.4,
223473
+ reasoningOutputPer1m: 18
223474
+ }
223475
+ ],
223476
+ batchMultiplier: 0.5,
223477
+ contextWindow: 1048576,
223478
+ notes: "Long-context tier: $2/$12 per 1M up to 200K prompt tokens, $4/$18 above it."
223479
+ },
223480
+ {
223481
+ model: "gemini-3-pro",
223482
+ provider: "gemini",
223483
+ aliases: [
223484
+ "gemini-3-pro-preview"
223485
+ ],
223486
+ modality: "text",
223487
+ currency: "USD",
223488
+ asOf: "2026-07-27",
223489
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
223490
+ provenance: "vendor-pricing-page",
223491
+ tiers: [
223492
+ {
223493
+ maxInputTokens: 2e5,
223494
+ inputPer1m: 2,
223495
+ outputPer1m: 12,
223496
+ cachedInputPer1m: 0.2,
223497
+ reasoningOutputPer1m: 12
223498
+ },
223499
+ {
223500
+ inputPer1m: 4,
223501
+ outputPer1m: 18,
223502
+ cachedInputPer1m: 0.4,
223503
+ reasoningOutputPer1m: 18
223504
+ }
223505
+ ],
223506
+ batchMultiplier: 0.5,
223507
+ contextWindow: 1048576
223508
+ },
223509
+ {
223510
+ model: "gemini-3.6-flash",
223511
+ provider: "gemini",
223512
+ modality: "text",
223513
+ currency: "USD",
223514
+ asOf: "2026-07-27",
223515
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
223516
+ provenance: "vendor-pricing-page",
223517
+ tiers: [
223518
+ {
223519
+ inputPer1m: 1.5,
223520
+ outputPer1m: 7.5,
223521
+ cachedInputPer1m: 0.15,
223522
+ reasoningOutputPer1m: 7.5
223523
+ }
223524
+ ],
223525
+ batchMultiplier: 0.5,
223526
+ contextWindow: 1048576,
223527
+ notes: "Released 2026-07-21. Output pricing dropped ~17% from Gemini 3.5 Flash ($9.00 -> $7.50 per 1M); input unchanged."
223528
+ },
223529
+ {
223530
+ model: "gemini-3.5-flash",
223531
+ provider: "gemini",
223532
+ modality: "text",
223533
+ currency: "USD",
223534
+ asOf: "2026-07-27",
223535
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
223536
+ provenance: "vendor-pricing-page",
223537
+ tiers: [
223538
+ {
223539
+ inputPer1m: 1.5,
223540
+ outputPer1m: 9,
223541
+ cachedInputPer1m: 0.15,
223542
+ reasoningOutputPer1m: 9
223543
+ }
223544
+ ],
223545
+ batchMultiplier: 0.5,
223546
+ contextWindow: 1048576
223547
+ },
223548
+ {
223549
+ model: "gemini-3.5-flash-lite",
223550
+ provider: "gemini",
223551
+ modality: "text",
223552
+ currency: "USD",
223553
+ asOf: "2026-07-27",
223554
+ source: "https://ai.google.dev/gemini-api/docs/pricing",
223555
+ provenance: "litellm-catalog",
223556
+ tiers: [
223557
+ {
223558
+ inputPer1m: 0.3,
223559
+ outputPer1m: 2.5,
223560
+ cachedInputPer1m: 0.03,
223561
+ reasoningOutputPer1m: 2.5
223562
+ }
223563
+ ],
223564
+ batchMultiplier: 0.5,
223565
+ contextWindow: 1048576
223566
+ },
223567
+ {
223568
+ model: "gemini-3.1-flash-lite",
223569
+ provider: "gemini",
223570
+ modality: "text",
223571
+ currency: "USD",
223572
+ asOf: "2026-07-27",
223573
+ source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-3.1-flash-lite",
223574
+ provenance: "litellm-catalog",
223575
+ tiers: [
223576
+ {
223577
+ inputPer1m: 0.25,
223578
+ outputPer1m: 1.5,
223579
+ cachedInputPer1m: 0.025,
223580
+ reasoningOutputPer1m: 1.5
223581
+ }
223582
+ ],
223583
+ batchMultiplier: 0.5,
223584
+ contextWindow: 1048576
223585
+ },
223586
+ {
223587
+ model: "gemini-3-flash",
223588
+ provider: "gemini",
223589
+ aliases: [
223590
+ "gemini-3-flash-preview"
223591
+ ],
223592
+ modality: "text",
223593
+ currency: "USD",
223594
+ asOf: "2026-07-27",
223595
+ source: "https://ai.google.dev/pricing/gemini-3",
223596
+ provenance: "litellm-catalog",
223597
+ tiers: [
223598
+ {
223599
+ inputPer1m: 0.5,
223600
+ outputPer1m: 3,
223601
+ cachedInputPer1m: 0.05,
223602
+ reasoningOutputPer1m: 3
223603
+ }
223604
+ ],
223605
+ contextWindow: 1048576
223606
+ },
223607
+ {
223608
+ model: "gemini-2.5-pro",
223609
+ provider: "gemini",
223610
+ modality: "text",
223611
+ currency: "USD",
223612
+ asOf: "2026-07-27",
223613
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
223614
+ provenance: "litellm-catalog",
223615
+ tiers: [
223616
+ {
223617
+ maxInputTokens: 2e5,
223618
+ inputPer1m: 1.25,
223619
+ outputPer1m: 10,
223620
+ cachedInputPer1m: 0.125
223621
+ },
223622
+ {
223623
+ inputPer1m: 2.5,
223624
+ outputPer1m: 15,
223625
+ cachedInputPer1m: 0.25
223626
+ }
223627
+ ],
223628
+ contextWindow: 1048576
223629
+ },
223630
+ {
223631
+ model: "gemini-2.5-flash",
223632
+ provider: "gemini",
223633
+ modality: "text",
223634
+ currency: "USD",
223635
+ asOf: "2026-07-27",
223636
+ source: "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash-preview",
223637
+ provenance: "litellm-catalog",
223638
+ tiers: [
223639
+ {
223640
+ inputPer1m: 0.3,
223641
+ outputPer1m: 2.5,
223642
+ cachedInputPer1m: 0.03,
223643
+ reasoningOutputPer1m: 2.5
223644
+ }
223645
+ ],
223646
+ contextWindow: 1048576
223647
+ },
223648
+ {
223649
+ model: "gemini-2.5-flash-lite",
223650
+ provider: "gemini",
223651
+ modality: "text",
223652
+ currency: "USD",
223653
+ asOf: "2026-07-27",
223654
+ source: "https://ai.google.dev/gemini-api/docs/models#gemini-2.5-flash-lite",
223655
+ provenance: "litellm-catalog",
223656
+ tiers: [
223657
+ {
223658
+ inputPer1m: 0.1,
223659
+ outputPer1m: 0.4,
223660
+ cachedInputPer1m: 0.01,
223661
+ reasoningOutputPer1m: 0.4
223662
+ }
223663
+ ],
223664
+ contextWindow: 1048576
223665
+ },
223666
+ {
223667
+ model: "gemini-2.0-flash",
223668
+ provider: "gemini",
223669
+ modality: "text",
223670
+ currency: "USD",
223671
+ asOf: "2026-07-27",
223672
+ source: "https://ai.google.dev/pricing#2_0flash",
223673
+ provenance: "litellm-catalog",
223674
+ tiers: [
223675
+ {
223676
+ inputPer1m: 0.1,
223677
+ outputPer1m: 0.4,
223678
+ cachedInputPer1m: 0.025
223679
+ }
223680
+ ],
223681
+ contextWindow: 1048576,
223682
+ notes: "Gemini Developer API price. Vertex AI lists $0.15/$0.60 per 1M for the same model \u2014 see the vertex entry."
223683
+ },
223684
+ {
223685
+ model: "gemini-2.0-flash-lite",
223686
+ provider: "gemini",
223687
+ modality: "text",
223688
+ currency: "USD",
223689
+ asOf: "2026-07-27",
223690
+ source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-2.0-flash-lite",
223691
+ provenance: "litellm-catalog",
223692
+ tiers: [
223693
+ {
223694
+ inputPer1m: 0.075,
223695
+ outputPer1m: 0.3,
223696
+ cachedInputPer1m: 0.01875
223697
+ }
223698
+ ],
223699
+ contextWindow: 1048576
223700
+ },
223701
+ {
223702
+ model: "gemini-2.0-flash",
223703
+ provider: "vertex",
223704
+ modality: "text",
223705
+ currency: "USD",
223706
+ asOf: "2026-07-27",
223707
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
223708
+ provenance: "vendor-pricing-page",
223709
+ tiers: [
223710
+ {
223711
+ inputPer1m: 0.15,
223712
+ outputPer1m: 0.6
223713
+ }
223714
+ ],
223715
+ batchMultiplier: 0.5,
223716
+ notes: "Vertex AI lists $0.15/$0.60 per 1M; the Gemini Developer API lists $0.10/$0.40 for the same model."
223717
+ },
223718
+ {
223719
+ model: "gemini-3.1-pro",
223720
+ provider: "vertex",
223721
+ aliases: [
223722
+ "gemini-3.1-pro-preview"
223723
+ ],
223724
+ modality: "text",
223725
+ currency: "USD",
223726
+ asOf: "2026-07-27",
223727
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
223728
+ provenance: "vendor-pricing-page",
223729
+ tiers: [
223730
+ {
223731
+ maxInputTokens: 2e5,
223732
+ inputPer1m: 2,
223733
+ outputPer1m: 12,
223734
+ cachedInputPer1m: 0.2,
223735
+ reasoningOutputPer1m: 12
223736
+ },
223737
+ {
223738
+ inputPer1m: 4,
223739
+ outputPer1m: 18,
223740
+ cachedInputPer1m: 0.4,
223741
+ reasoningOutputPer1m: 18
223742
+ }
223743
+ ],
223744
+ batchMultiplier: 0.5,
223745
+ contextWindow: 1048576
223746
+ },
223747
+ {
223748
+ model: "gemini-3.6-flash",
223749
+ provider: "vertex",
223750
+ modality: "text",
223751
+ currency: "USD",
223752
+ asOf: "2026-07-27",
223753
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
223754
+ provenance: "vendor-pricing-page",
223755
+ tiers: [
223756
+ {
223757
+ inputPer1m: 1.5,
223758
+ outputPer1m: 7.5,
223759
+ cachedInputPer1m: 0.15,
223760
+ reasoningOutputPer1m: 7.5
223761
+ }
223762
+ ],
223763
+ batchMultiplier: 0.5,
223764
+ contextWindow: 1048576
223765
+ },
223766
+ {
223767
+ model: "gemini-2.5-pro",
223768
+ provider: "vertex",
223769
+ modality: "text",
223770
+ currency: "USD",
223771
+ asOf: "2026-07-27",
223772
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
223773
+ provenance: "vendor-pricing-page",
223774
+ tiers: [
223775
+ {
223776
+ maxInputTokens: 2e5,
223777
+ inputPer1m: 1.25,
223778
+ outputPer1m: 10,
223779
+ cachedInputPer1m: 0.13
223780
+ },
223781
+ {
223782
+ inputPer1m: 2.5,
223783
+ outputPer1m: 15,
223784
+ cachedInputPer1m: 0.25
223785
+ }
223786
+ ],
223787
+ batchMultiplier: 0.5,
223788
+ contextWindow: 1048576
223789
+ },
223790
+ {
223791
+ model: "gemini-2.5-flash",
223792
+ provider: "vertex",
223793
+ modality: "text",
223794
+ currency: "USD",
223795
+ asOf: "2026-07-27",
223796
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
223797
+ provenance: "vendor-pricing-page",
223798
+ tiers: [
223799
+ {
223800
+ inputPer1m: 0.3,
223801
+ outputPer1m: 2.5,
223802
+ cachedInputPer1m: 0.03,
223803
+ reasoningOutputPer1m: 2.5
223804
+ }
223805
+ ],
223806
+ batchMultiplier: 0.5,
223807
+ contextWindow: 1048576
223808
+ },
223809
+ {
223810
+ model: "claude-sonnet-4-6",
223811
+ provider: "openrouter",
223812
+ modality: "text",
223813
+ currency: "USD",
223814
+ asOf: "2026-07-27",
223815
+ source: "https://openrouter.ai/anthropic/claude-sonnet-4.6",
223816
+ provenance: "litellm-catalog",
223817
+ tiers: [
223818
+ {
223819
+ maxInputTokens: 2e5,
223820
+ inputPer1m: 3,
223821
+ outputPer1m: 15,
223822
+ cachedInputPer1m: 0.3,
223823
+ cacheWritePer1m: 3.75
223824
+ },
223825
+ {
223826
+ inputPer1m: 6,
223827
+ outputPer1m: 22.5,
223828
+ cachedInputPer1m: 0.6,
223829
+ cacheWritePer1m: 7.5
223830
+ }
223831
+ ],
223832
+ contextWindow: 1e6
223833
+ },
223834
+ {
223835
+ model: "claude-haiku-4-5",
223836
+ provider: "openrouter",
223837
+ modality: "text",
223838
+ currency: "USD",
223839
+ asOf: "2026-07-27",
223840
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223841
+ provenance: "litellm-catalog",
223842
+ tiers: [
223843
+ {
223844
+ inputPer1m: 1,
223845
+ outputPer1m: 5,
223846
+ cachedInputPer1m: 0.1,
223847
+ cacheWritePer1m: 1.25
223848
+ }
223849
+ ],
223850
+ contextWindow: 2e5
223851
+ },
223852
+ {
223853
+ model: "gpt-5",
223854
+ provider: "openrouter",
223855
+ modality: "text",
223856
+ currency: "USD",
223857
+ asOf: "2026-07-27",
223858
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223859
+ provenance: "litellm-catalog",
223860
+ tiers: [
223861
+ {
223862
+ inputPer1m: 1.25,
223863
+ outputPer1m: 10,
223864
+ cachedInputPer1m: 0.125
223865
+ }
223866
+ ],
223867
+ contextWindow: 272e3
223868
+ },
223869
+ {
223870
+ model: "gpt-5-mini",
223871
+ provider: "openrouter",
223872
+ modality: "text",
223873
+ currency: "USD",
223874
+ asOf: "2026-07-27",
223875
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223876
+ provenance: "litellm-catalog",
223877
+ tiers: [
223878
+ {
223879
+ inputPer1m: 0.25,
223880
+ outputPer1m: 2,
223881
+ cachedInputPer1m: 0.025
223882
+ }
223883
+ ],
223884
+ contextWindow: 272e3
223885
+ },
223886
+ {
223887
+ model: "gemini-3.1-pro",
223888
+ provider: "openrouter",
223889
+ aliases: [
223890
+ "gemini-3.1-pro-preview"
223891
+ ],
223892
+ modality: "text",
223893
+ currency: "USD",
223894
+ asOf: "2026-07-27",
223895
+ source: "https://openrouter.ai/google/gemini-3.1-pro-preview",
223896
+ provenance: "litellm-catalog",
223897
+ tiers: [
223898
+ {
223899
+ maxInputTokens: 2e5,
223900
+ inputPer1m: 2,
223901
+ outputPer1m: 12,
223902
+ cachedInputPer1m: 0.2
223903
+ },
223904
+ {
223905
+ inputPer1m: 4,
223906
+ outputPer1m: 18,
223907
+ cachedInputPer1m: 0.4,
223908
+ cacheWritePer1m: 0.25
223909
+ }
223910
+ ],
223911
+ contextWindow: 1048576
223912
+ },
223913
+ {
223914
+ model: "text-embedding-3-small",
223915
+ provider: "openai",
223916
+ modality: "embedding",
223917
+ currency: "USD",
223918
+ asOf: "2026-07-27",
223919
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223920
+ provenance: "litellm-catalog",
223921
+ tiers: [
223922
+ {
223923
+ inputPer1m: 0.02,
223924
+ outputPer1m: 0
223925
+ }
223926
+ ],
223927
+ batchMultiplier: 0.5,
223928
+ contextWindow: 8191
223929
+ },
223930
+ {
223931
+ model: "text-embedding-3-large",
223932
+ provider: "openai",
223933
+ modality: "embedding",
223934
+ currency: "USD",
223935
+ asOf: "2026-07-27",
223936
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223937
+ provenance: "litellm-catalog",
223938
+ tiers: [
223939
+ {
223940
+ inputPer1m: 0.13,
223941
+ outputPer1m: 0
223942
+ }
223943
+ ],
223944
+ batchMultiplier: 0.5,
223945
+ contextWindow: 8191
223946
+ },
223947
+ {
223948
+ model: "gemini-embedding-001",
223949
+ provider: "gemini",
223950
+ modality: "embedding",
223951
+ currency: "USD",
223952
+ asOf: "2026-07-27",
223953
+ source: "https://ai.google.dev/gemini-api/docs/embeddings#model-versions",
223954
+ provenance: "litellm-catalog",
223955
+ tiers: [
223956
+ {
223957
+ inputPer1m: 0.15,
223958
+ outputPer1m: 0
223959
+ }
223960
+ ],
223961
+ contextWindow: 2048
223962
+ },
223963
+ {
223964
+ model: "dall-e-3",
223965
+ provider: "openai",
223966
+ modality: "image",
223967
+ currency: "USD",
223968
+ asOf: "2026-07-27",
223969
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
223970
+ provenance: "litellm-catalog",
223971
+ rates: [
223972
+ {
223973
+ unit: "per_image",
223974
+ amount: 0.04,
223975
+ variant: "1024x1024 standard"
223976
+ }
223977
+ ]
223978
+ },
223979
+ {
223980
+ model: "gemini-3-pro-image",
223981
+ provider: "gemini",
223982
+ modality: "image",
223983
+ currency: "USD",
223984
+ asOf: "2026-07-27",
223985
+ source: "https://ai.google.dev/gemini-api/docs/pricing",
223986
+ provenance: "litellm-catalog",
223987
+ rates: [
223988
+ {
223989
+ unit: "per_image",
223990
+ amount: 0.134,
223991
+ variant: "default output resolution"
223992
+ }
223993
+ ],
223994
+ notes: "Google bills image output per output-token ($120 per 1M image output tokens); $0.134/image is that rate applied to one default-resolution image. Cost per image therefore varies with resolution."
223995
+ },
223996
+ {
223997
+ model: "imagen-4.0-generate-001",
223998
+ provider: "vertex",
223999
+ modality: "image",
224000
+ currency: "USD",
224001
+ asOf: "2026-07-27",
224002
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing",
224003
+ provenance: "litellm-catalog",
224004
+ rates: [
224005
+ {
224006
+ unit: "per_image",
224007
+ amount: 0.04
224008
+ }
224009
+ ]
224010
+ },
224011
+ {
224012
+ model: "veo-3.1-generate-001",
224013
+ provider: "gemini",
224014
+ modality: "video",
224015
+ currency: "USD",
224016
+ asOf: "2026-07-27",
224017
+ source: "https://ai.google.dev/gemini-api/docs/video",
224018
+ provenance: "litellm-catalog",
224019
+ rates: [
224020
+ {
224021
+ unit: "per_second",
224022
+ amount: 0.4
224023
+ }
224024
+ ]
224025
+ },
224026
+ {
224027
+ model: "veo-3.1-generate-001",
224028
+ provider: "vertex",
224029
+ modality: "video",
224030
+ currency: "USD",
224031
+ asOf: "2026-07-27",
224032
+ source: "https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/veo",
224033
+ provenance: "litellm-catalog",
224034
+ rates: [
224035
+ {
224036
+ unit: "per_second",
224037
+ amount: 0.4
224038
+ }
224039
+ ]
224040
+ },
224041
+ {
224042
+ model: "tts-1",
224043
+ provider: "openai",
224044
+ modality: "speech",
224045
+ currency: "USD",
224046
+ asOf: "2026-07-27",
224047
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
224048
+ provenance: "litellm-catalog",
224049
+ rates: [
224050
+ {
224051
+ unit: "per_character",
224052
+ amount: 15e-6
224053
+ }
224054
+ ],
224055
+ notes: "$15 per 1M characters."
224056
+ },
224057
+ {
224058
+ model: "tts-1-hd",
224059
+ provider: "openai",
224060
+ modality: "speech",
224061
+ currency: "USD",
224062
+ asOf: "2026-07-27",
224063
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
224064
+ provenance: "litellm-catalog",
224065
+ rates: [
224066
+ {
224067
+ unit: "per_character",
224068
+ amount: 3e-5
224069
+ }
224070
+ ],
224071
+ notes: "$30 per 1M characters."
224072
+ },
224073
+ {
224074
+ model: "whisper-1",
224075
+ provider: "openai",
224076
+ modality: "transcription",
224077
+ currency: "USD",
224078
+ asOf: "2026-07-27",
224079
+ source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
224080
+ provenance: "litellm-catalog",
224081
+ rates: [
224082
+ {
224083
+ unit: "per_audio_minute",
224084
+ amount: 6e-3
224085
+ }
224086
+ ],
224087
+ notes: "litellm records $0.0001 per audio second; $0.006/minute is that rate x 60."
224088
+ }
224089
+ ]
224090
+ };
224091
+
224092
+ // src/core/router/pricing.ts
224093
+ var DATASET = pricing_data_default;
224094
+ function normalizeForPricing(id) {
224095
+ let s3 = id.trim().toLowerCase();
224096
+ s3 = s3.replace(/^models\//, "");
224097
+ const slash = s3.lastIndexOf("/");
224098
+ if (slash !== -1) s3 = s3.slice(slash + 1);
224099
+ const tag = s3.search(/[:@]/);
224100
+ if (tag !== -1) s3 = s3.slice(0, tag);
224101
+ s3 = s3.replace(/-latest$/, "");
224102
+ s3 = s3.replace(/-preview(?:-\d{2}-\d{2})?$/, "");
224103
+ s3 = s3.replace(/-\d{4}-\d{2}-\d{2}$/, "");
224104
+ s3 = s3.replace(/-\d{8}$/, "");
224105
+ s3 = s3.replace(/-preview$/, "");
224106
+ return s3;
224107
+ }
224108
+ function indexKey(model, provider, region) {
224109
+ return `${provider}|${normalizeForPricing(model)}|${region ?? ""}`;
224110
+ }
224111
+ var INDEX = /* @__PURE__ */ new Map();
224112
+ for (const entry of DATASET.entries) {
224113
+ for (const name of [entry.model, ...entry.aliases ?? []]) {
224114
+ const withRegion = indexKey(name, entry.provider, entry.region);
224115
+ if (!INDEX.has(withRegion)) INDEX.set(withRegion, entry);
224116
+ const bare = indexKey(name, entry.provider);
224117
+ const existing = INDEX.get(bare);
224118
+ if (!existing || existing.region && existing.region !== "global" && entry.region === "global") {
224119
+ INDEX.set(bare, entry);
224120
+ }
224121
+ }
224122
+ }
224123
+ function findPricing(modelId, provider, opts = {}) {
224124
+ const ids = [modelId, opts.baseModelId].filter((x5) => !!x5);
224125
+ const providers = [provider, ...opts.fallbackProviders ?? []];
224126
+ for (const p3 of providers) {
224127
+ for (const id of ids) {
224128
+ const hit = (opts.region ? INDEX.get(indexKey(id, p3, opts.region)) : void 0) ?? INDEX.get(indexKey(id, p3));
224129
+ if (hit) return { entry: hit, matchedProvider: p3, viaFallback: p3 !== provider };
224130
+ }
224131
+ }
224132
+ return null;
224133
+ }
224134
+ function tierFor(entry, inputTokens = 0) {
224135
+ const tiers = entry.tiers;
224136
+ if (!tiers?.length) return null;
224137
+ for (const t4 of tiers) {
224138
+ if (t4.maxInputTokens === void 0 || inputTokens <= t4.maxInputTokens) return t4;
224139
+ }
224140
+ return tiers[tiers.length - 1] ?? null;
224141
+ }
224142
+ var PER_1M_TO_PER_1K = 1 / 1e3;
224143
+ function tokenRatesPer1k(entry, opts = {}) {
224144
+ const tier = tierFor(entry, opts.inputTokens ?? 0);
224145
+ if (!tier) return null;
224146
+ const mult = (opts.batch ? entry.batchMultiplier ?? 1 : 1) * PER_1M_TO_PER_1K;
224147
+ const out = {
224148
+ input: tier.inputPer1m * mult,
224149
+ output: tier.outputPer1m * mult
224150
+ };
224151
+ if (tier.cachedInputPer1m !== void 0) out.cachedInput = tier.cachedInputPer1m * mult;
224152
+ if (tier.cacheWritePer1m !== void 0) out.cacheWrite = tier.cacheWritePer1m * mult;
224153
+ if (tier.reasoningOutputPer1m !== void 0) out.reasoningOutput = tier.reasoningOutputPer1m * mult;
224154
+ return out;
224155
+ }
224156
+ var LOOPBACK_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "0.0.0.0", "::1", "[::1]"]);
224157
+ function isLoopbackOrPrivateHost(url2) {
224158
+ if (!url2) return false;
224159
+ try {
224160
+ const host = new URL(url2).hostname.toLowerCase().replace(/^\[|\]$/g, "");
224161
+ if (LOOPBACK_HOSTS.has(host) || LOOPBACK_HOSTS.has(`[${host}]`)) return true;
224162
+ if (host.endsWith(".local")) return true;
224163
+ if (/^127\./.test(host)) return true;
224164
+ if (/^10\./.test(host)) return true;
224165
+ if (/^192\.168\./.test(host)) return true;
224166
+ if (/^172\.(1[6-9]|2\d|3[01])\./.test(host)) return true;
224167
+ return false;
224168
+ } catch {
224169
+ return false;
224170
+ }
224171
+ }
224172
+ function isLocalEndpoint(cfg) {
224173
+ if (typeof cfg.local === "boolean") return cfg.local;
224174
+ if (cfg.type === "ollama") return true;
224175
+ if (cfg.type === "openai-compatible") return isLoopbackOrPrivateHost(cfg.baseUrl);
224176
+ return false;
224177
+ }
224178
+ var UNKNOWN = { input: 0, output: 0, unknown: true, free: false };
224179
+ var FREE = { input: 0, output: 0, unknown: false, free: true };
224180
+ function resolvePricing(model, opts = {}) {
224181
+ if (model.isLocal) return FREE;
224182
+ const fallbackProviders = model.provider === "azure" ? ["openai"] : model.provider === "gemini" ? ["vertex"] : [];
224183
+ const match = findPricing(model.id, model.provider, {
224184
+ region: opts.region,
224185
+ baseModelId: model.baseModelId,
224186
+ fallbackProviders
224187
+ });
224188
+ if (!match) return UNKNOWN;
224189
+ const rates = tokenRatesPer1k(match.entry, { inputTokens: opts.inputTokens, batch: opts.batch });
224190
+ if (!rates) return UNKNOWN;
224191
+ return {
224192
+ input: rates.input,
224193
+ output: rates.output,
224194
+ unknown: false,
224195
+ free: false,
224196
+ entry: match.entry,
224197
+ ...match.viaFallback ? { estimatedFromProvider: match.matchedProvider } : {}
224198
+ };
224199
+ }
224200
+ function withResolvedPricing(model, opts = {}) {
224201
+ const p3 = resolvePricing(model, opts);
224202
+ return {
224203
+ ...model,
224204
+ inputCostPer1kTokens: p3.input,
224205
+ outputCostPer1kTokens: p3.output,
224206
+ ...p3.unknown ? { pricingUnknown: true } : { pricingUnknown: false }
224207
+ };
224208
+ }
224209
+ function isPricingUnknown(model) {
224210
+ return model.pricingUnknown === true && !model.isLocal;
224211
+ }
224212
+ var BLENDED_COST_CEILING = 0.05;
224213
+ function blendedCostPer1k(model) {
224214
+ if (isPricingUnknown(model)) return BLENDED_COST_CEILING;
224215
+ return model.inputCostPer1kTokens + model.outputCostPer1kTokens * 2;
224216
+ }
224217
+ var DISAGREEMENT_THRESHOLD = 0.02;
224218
+ function reconcilePrice(model, live) {
224219
+ const baseline = resolvePricing(model);
224220
+ const liveIsZero = !(live.input > 0) && !(live.output > 0);
224221
+ if (liveIsZero && !model.isLocal) {
224222
+ return { input: baseline.input, output: baseline.output, accepted: false };
224223
+ }
224224
+ if (baseline.unknown || !baseline.entry) {
224225
+ return { input: live.input, output: live.output, accepted: true };
224226
+ }
224227
+ const dsBlend = baseline.input + baseline.output * 2;
224228
+ const liveBlend = live.input + live.output * 2;
224229
+ const ratio = dsBlend > 0 ? liveBlend / dsBlend : Number.POSITIVE_INFINITY;
224230
+ const material = dsBlend > 0 && Math.abs(ratio - 1) > DISAGREEMENT_THRESHOLD;
224231
+ return {
224232
+ input: live.input,
224233
+ output: live.output,
224234
+ accepted: true,
224235
+ ...material ? {
224236
+ disagreement: {
224237
+ modelId: model.id,
224238
+ provider: model.provider,
224239
+ dataset: { input: baseline.input, output: baseline.output },
224240
+ live: { input: live.input, output: live.output },
224241
+ ratio: Math.round(ratio * 1e3) / 1e3,
224242
+ datasetAsOf: baseline.entry.asOf,
224243
+ datasetSource: baseline.entry.source
224244
+ }
224245
+ } : {}
224246
+ };
224247
+ }
224248
+
222597
224249
  // src/constants.ts
222598
- var CASCADE_VERSION = "0.48.0";
224250
+ var CASCADE_VERSION = "0.49.0";
222599
224251
  var CASCADE_CONFIG_DIR = ".cascade";
222600
224252
  var CASCADE_MD_FILE = "CASCADE.md";
222601
224253
  var CASCADE_IGNORE_FILE = ".cascadeignore";
@@ -222944,6 +224596,13 @@ var MODELS = {
222944
224596
  for (const _m of Object.values(MODELS)) {
222945
224597
  if (_m.supportsToolUse === void 0) _m.supportsToolUse = !_m.isLocal;
222946
224598
  }
224599
+ for (const _m of Object.values(MODELS)) {
224600
+ const priced = resolvePricing(_m);
224601
+ if (priced.unknown || priced.free || priced.estimatedFromProvider) continue;
224602
+ _m.inputCostPer1kTokens = priced.input;
224603
+ _m.outputCostPer1kTokens = priced.output;
224604
+ _m.pricingUnknown = false;
224605
+ }
222947
224606
  var T1_MODEL_PRIORITY = [
222948
224607
  "gpt-5.5",
222949
224608
  "gpt-5.4",
@@ -223034,21 +224693,49 @@ var PROVIDER_DISPLAY_NAMES = {
223034
224693
 
223035
224694
  // src/utils/cost.ts
223036
224695
  function resolveModelPricing(model) {
223037
- let input = model.inputCostPer1kTokens;
223038
- let output = model.outputCostPer1kTokens;
223039
- if (input === 0 && output === 0 && model.id && !model.isLocal) {
224696
+ if (model.isLocal) return { input: 0, output: 0, unknown: false };
224697
+ if (model.inputCostPer1kTokens > 0 || model.outputCostPer1kTokens > 0) {
224698
+ return {
224699
+ input: model.inputCostPer1kTokens,
224700
+ output: model.outputCostPer1kTokens,
224701
+ unknown: false
224702
+ };
224703
+ }
224704
+ const fromDataset = resolvePricing(model);
224705
+ if (!fromDataset.unknown) {
224706
+ return {
224707
+ input: fromDataset.input,
224708
+ output: fromDataset.output,
224709
+ unknown: false,
224710
+ ...fromDataset.estimatedFromProvider ? { estimatedFromProvider: fromDataset.estimatedFromProvider } : {}
224711
+ };
224712
+ }
224713
+ if (model.id) {
223040
224714
  const known = Object.values(MODELS).find((m3) => m3.id === model.id && !m3.isLocal);
223041
- if (known) {
223042
- input = known.inputCostPer1kTokens;
223043
- output = known.outputCostPer1kTokens;
224715
+ if (known && (known.inputCostPer1kTokens > 0 || known.outputCostPer1kTokens > 0)) {
224716
+ return {
224717
+ input: known.inputCostPer1kTokens,
224718
+ output: known.outputCostPer1kTokens,
224719
+ unknown: false
224720
+ };
223044
224721
  }
223045
224722
  }
223046
- return { input, output };
224723
+ return { input: 0, output: 0, unknown: true };
223047
224724
  }
223048
224725
  function calculateCost(inputTokens, outputTokens, model) {
223049
224726
  const { input, output } = resolveModelPricing(model);
223050
224727
  return inputTokens / 1e3 * input + outputTokens / 1e3 * output;
223051
224728
  }
224729
+ function buildTokenUsage(inputTokens, outputTokens, model) {
224730
+ const { input, output, unknown: unknown2 } = resolveModelPricing(model);
224731
+ return {
224732
+ inputTokens,
224733
+ outputTokens,
224734
+ totalTokens: inputTokens + outputTokens,
224735
+ estimatedCostUsd: inputTokens / 1e3 * input + outputTokens / 1e3 * output,
224736
+ ...unknown2 ? { costUnknown: true } : {}
224737
+ };
224738
+ }
223052
224739
 
223053
224740
  // src/providers/base.ts
223054
224741
  var BaseProvider = class {
@@ -223068,12 +224755,7 @@ var BaseProvider = class {
223068
224755
  return calculateCost(inputTokens, outputTokens, this.model);
223069
224756
  }
223070
224757
  makeUsage(inputTokens, outputTokens) {
223071
- return {
223072
- inputTokens,
223073
- outputTokens,
223074
- totalTokens: inputTokens + outputTokens,
223075
- estimatedCostUsd: this.estimateCost(inputTokens, outputTokens)
223076
- };
224758
+ return buildTokenUsage(inputTokens, outputTokens, this.model);
223077
224759
  }
223078
224760
  };
223079
224761
 
@@ -223242,7 +224924,7 @@ var AnthropicProvider = class extends BaseProvider {
223242
224924
  return data.data.filter((m3) => isChatModel(m3.id)).map((m3) => {
223243
224925
  const known = Object.values(MODELS).find((km) => km.id === m3.id && km.provider === "anthropic");
223244
224926
  if (known) return known;
223245
- return {
224927
+ return withResolvedPricing({
223246
224928
  id: m3.id,
223247
224929
  name: m3.display_name || m3.id,
223248
224930
  provider: "anthropic",
@@ -223253,7 +224935,7 @@ var AnthropicProvider = class extends BaseProvider {
223253
224935
  maxOutputTokens: 8e3,
223254
224936
  supportsStreaming: true,
223255
224937
  isLocal: false
223256
- };
224938
+ });
223257
224939
  });
223258
224940
  } catch {
223259
224941
  return Object.values(MODELS).filter((m3) => m3.provider === "anthropic");
@@ -231330,7 +233012,7 @@ var OpenAIProvider = class extends BaseProvider {
231330
233012
  return response.data.filter((m3) => isChatModel(m3.id)).map((m3) => {
231331
233013
  const known = Object.values(MODELS).find((km) => km.id === m3.id && km.provider === "openai");
231332
233014
  if (known) return known;
231333
- return {
233015
+ return withResolvedPricing({
231334
233016
  id: m3.id,
231335
233017
  name: m3.id,
231336
233018
  provider: "openai",
@@ -231341,7 +233023,7 @@ var OpenAIProvider = class extends BaseProvider {
231341
233023
  maxOutputTokens: 4e3,
231342
233024
  supportsStreaming: true,
231343
233025
  isLocal: false
231344
- };
233026
+ });
231345
233027
  });
231346
233028
  } catch {
231347
233029
  return Object.values(MODELS).filter((m3) => m3.provider === "openai");
@@ -231437,6 +233119,10 @@ function azureModelForDeployment(cfg) {
231437
233119
  const baseModelId = cfg.model?.trim() || inferAzureBaseModel(id) || void 0;
231438
233120
  const base = baseModelId ? MODELS[baseModelId] : void 0;
231439
233121
  if (base) {
233122
+ const azurePrice = resolvePricing(
233123
+ { id, provider: "azure", isLocal: false, baseModelId },
233124
+ { region: cfg.region }
233125
+ );
231440
233126
  return {
231441
233127
  ...base,
231442
233128
  id,
@@ -231445,7 +233131,12 @@ function azureModelForDeployment(cfg) {
231445
233131
  provider: "azure",
231446
233132
  baseModelId,
231447
233133
  // real identity for benchmark + live pricing
231448
- supportsToolUse: base.supportsToolUse ?? true
233134
+ supportsToolUse: base.supportsToolUse ?? true,
233135
+ ...azurePrice.unknown ? {} : {
233136
+ inputCostPer1kTokens: azurePrice.input,
233137
+ outputCostPer1kTokens: azurePrice.output,
233138
+ pricingUnknown: false
233139
+ }
231449
233140
  };
231450
233141
  }
231451
233142
  return {
@@ -249638,7 +251329,7 @@ var GeminiProvider = class extends BaseProvider {
249638
251329
  (km) => km.id === id && km.provider === "gemini"
249639
251330
  );
249640
251331
  if (known) return known;
249641
- return {
251332
+ return withResolvedPricing({
249642
251333
  id,
249643
251334
  name: m3.displayName || id,
249644
251335
  provider: "gemini",
@@ -249649,7 +251340,7 @@ var GeminiProvider = class extends BaseProvider {
249649
251340
  maxOutputTokens: m3.outputTokenLimit || 8e3,
249650
251341
  supportsStreaming: true,
249651
251342
  isLocal: false
249652
- };
251343
+ });
249653
251344
  });
249654
251345
  } catch {
249655
251346
  return Object.values(MODELS).filter((m3) => m3.provider === "gemini");
@@ -249996,9 +251687,10 @@ var OllamaProvider = class extends BaseProvider {
249996
251687
  return supportedKeywords.some((k4) => name.includes(k4)) && isChatModel(name);
249997
251688
  });
249998
251689
  const shows = await Promise.all(entries.map((m3) => this.showModel(m3.name)));
251690
+ const local = isLocalEndpoint({ ...this.config, type: "ollama" });
249999
251691
  return entries.map((m3, i4) => {
250000
251692
  const show = shows[i4];
250001
- return {
251693
+ return withResolvedPricing({
250002
251694
  id: m3.name,
250003
251695
  name: m3.name,
250004
251696
  provider: "ollama",
@@ -250008,10 +251700,10 @@ var OllamaProvider = class extends BaseProvider {
250008
251700
  outputCostPer1kTokens: 0,
250009
251701
  maxOutputTokens: 4e3,
250010
251702
  supportsStreaming: true,
250011
- isLocal: true,
251703
+ isLocal: local,
250012
251704
  supportsToolUse: show?.tools ?? isToolCapable(m3.name),
250013
251705
  minSizeB: this.parseSizeB(m3.details?.parameter_size)
250014
- };
251706
+ });
250015
251707
  });
250016
251708
  } catch {
250017
251709
  return [];
@@ -250116,7 +251808,8 @@ var OpenAICompatibleProvider = class extends OpenAIProvider {
250116
251808
  }).filter((x5) => typeof x5 === "string" && x5.length > 0);
250117
251809
  if (ids.length === 0) return [this.model];
250118
251810
  const chatIds = ids.filter((id) => isChatModel(id));
250119
- return (chatIds.length ? chatIds : ids).map((id) => ({
251811
+ const local = isLocalEndpoint(this.config);
251812
+ return (chatIds.length ? chatIds : ids).map((id) => withResolvedPricing({
250120
251813
  id,
250121
251814
  name: id,
250122
251815
  provider: "openai-compatible",
@@ -250126,7 +251819,7 @@ var OpenAICompatibleProvider = class extends OpenAIProvider {
250126
251819
  outputCostPer1kTokens: 0,
250127
251820
  maxOutputTokens: 4e3,
250128
251821
  supportsStreaming: true,
250129
- isLocal: false
251822
+ isLocal: local
250130
251823
  }));
250131
251824
  }
250132
251825
  async isAvailable() {
@@ -250341,7 +252034,7 @@ var ModelSelector = class {
250341
252034
  else if (this.availableProviders.size === 1) providerStr = Array.from(this.availableProviders)[0];
250342
252035
  }
250343
252036
  if (providerStr && this.availableProviders.has(providerStr)) {
250344
- const dynamicModel = {
252037
+ const dynamicModel = withResolvedPricing({
250345
252038
  id: actualId,
250346
252039
  name: actualId,
250347
252040
  provider: providerStr,
@@ -250352,7 +252045,7 @@ var ModelSelector = class {
250352
252045
  maxOutputTokens: 8e3,
250353
252046
  supportsStreaming: true,
250354
252047
  isLocal: providerStr === "ollama"
250355
- };
252048
+ });
250356
252049
  this.addDynamicModel(dynamicModel);
250357
252050
  return dynamicModel;
250358
252051
  }
@@ -250744,6 +252437,8 @@ var LiveDataProvider = class {
250744
252437
  snapshot = null;
250745
252438
  prices = /* @__PURE__ */ new Map();
250746
252439
  capabilities = /* @__PURE__ */ new Map();
252440
+ /** Dataset-vs-live price mismatches, deduped by `provider:modelId`. */
252441
+ disagreements = /* @__PURE__ */ new Map();
250747
252442
  source = "bundled";
250748
252443
  fetchedAt = 0;
250749
252444
  loaded = false;
@@ -250897,14 +252592,45 @@ var LiveDataProvider = class {
250897
252592
  /**
250898
252593
  * Returns a price-corrected copy of each model when live pricing is known,
250899
252594
  * leaving the original untouched (so the shared catalog is never mutated).
252595
+ *
252596
+ * Reconciliation policy (see reconcilePrice in pricing.ts): the bundled
252597
+ * dataset is the authoritative baseline, and a live quote overrides it
252598
+ * because it is fresher by construction — but the disagreement is RECORDED,
252599
+ * not swallowed. A dataset/live mismatch is the best signal available that
252600
+ * the committed prices have gone stale, so it must be visible rather than
252601
+ * silently resolved in either direction. A live quote of $0 for a non-local
252602
+ * model is rejected outright: that is the very failure mode this change
252603
+ * exists to prevent, and a marketplace's free-tier alias must never zero out
252604
+ * the price of the paid model Cascade is actually calling.
250900
252605
  */
250901
252606
  applyLivePricing(models) {
250902
252607
  return models.map((m3) => {
250903
252608
  const p3 = this.getLivePrice(m3.baseModelId ?? m3.id);
250904
252609
  if (!p3) return m3;
250905
- return { ...m3, inputCostPer1kTokens: p3.input, outputCostPer1kTokens: p3.output };
252610
+ const reconciled = reconcilePrice(m3, p3);
252611
+ if (reconciled.disagreement) this.recordDisagreement(reconciled.disagreement);
252612
+ if (!reconciled.accepted) return m3;
252613
+ return {
252614
+ ...m3,
252615
+ inputCostPer1kTokens: reconciled.input,
252616
+ outputCostPer1kTokens: reconciled.output,
252617
+ pricingUnknown: false
252618
+ };
250906
252619
  });
250907
252620
  }
252621
+ recordDisagreement(d2) {
252622
+ const key = `${d2.provider}:${d2.modelId}`;
252623
+ if (this.disagreements.has(key)) return;
252624
+ this.disagreements.set(key, d2);
252625
+ }
252626
+ /**
252627
+ * Dataset-vs-live price mismatches seen this session, newest-model-first
252628
+ * insertion order. Surfaced by `cascade models --verbose`; a non-empty list
252629
+ * means src/core/router/pricing-data.json is probably due a refresh.
252630
+ */
252631
+ getPriceDisagreements() {
252632
+ return [...this.disagreements.values()];
252633
+ }
250908
252634
  /** Current capability facts for a model id, or null when unknown. */
250909
252635
  getCapability(modelId) {
250910
252636
  return this.capabilities.get(normalizeModelId2(modelId)) ?? null;
@@ -251101,7 +252827,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
251101
252827
  tokensByTier: {},
251102
252828
  inputTokensByTier: {},
251103
252829
  outputTokensByTier: {},
251104
- costByFeature: {}
252830
+ costByFeature: {},
252831
+ untrackedCostCalls: 0,
252832
+ untrackedCostModels: []
251105
252833
  };
251106
252834
  tierModels = /* @__PURE__ */ new Map();
251107
252835
  /**
@@ -251451,7 +253179,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
251451
253179
  `Model ${model.id} inference timed out after ${cloudTimeoutMs}ms`
251452
253180
  );
251453
253181
  }
251454
- const correctedCost = calculateCost(
253182
+ const corrected = buildTokenUsage(
251455
253183
  result.usage.inputTokens,
251456
253184
  result.usage.outputTokens,
251457
253185
  model
@@ -251460,7 +253188,8 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
251460
253188
  ...result,
251461
253189
  usage: {
251462
253190
  ...result.usage,
251463
- estimatedCostUsd: correctedCost
253191
+ estimatedCostUsd: corrected.estimatedCostUsd,
253192
+ ...corrected.costUnknown ? { costUnknown: true } : { costUnknown: void 0 }
251464
253193
  }
251465
253194
  };
251466
253195
  if (!result || typeof result.content !== "string" || !result.usage) {
@@ -251647,7 +253376,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
251647
253376
  tokensByTier: { ...this.stats.tokensByTier },
251648
253377
  inputTokensByTier: { ...this.stats.inputTokensByTier },
251649
253378
  outputTokensByTier: { ...this.stats.outputTokensByTier },
251650
- costByFeature: { ...this.stats.costByFeature }
253379
+ costByFeature: { ...this.stats.costByFeature },
253380
+ untrackedCostCalls: this.stats.untrackedCostCalls,
253381
+ untrackedCostModels: [...this.stats.untrackedCostModels]
251651
253382
  };
251652
253383
  }
251653
253384
  /**
@@ -251698,7 +253429,9 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
251698
253429
  tokensByTier: {},
251699
253430
  inputTokensByTier: {},
251700
253431
  outputTokensByTier: {},
251701
- costByFeature: {}
253432
+ costByFeature: {},
253433
+ untrackedCostCalls: 0,
253434
+ untrackedCostModels: []
251702
253435
  };
251703
253436
  this.sessionCostUsd = 0;
251704
253437
  this.budgetState = "ok";
@@ -251883,6 +253616,18 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
251883
253616
  if (featureTag) {
251884
253617
  this.stats.costByFeature[featureTag] = (this.stats.costByFeature[featureTag] ?? 0) + usage.estimatedCostUsd;
251885
253618
  }
253619
+ if (usage.costUnknown) {
253620
+ this.stats.untrackedCostCalls += 1;
253621
+ if (!this.stats.untrackedCostModels.includes(model.id)) {
253622
+ this.stats.untrackedCostModels.push(model.id);
253623
+ const capped = this.config?.budget?.maxCostPerRunUsd != null || this.config?.budget?.sessionBudgetUsd != null;
253624
+ this.emit("cost:untracked", {
253625
+ modelId: model.id,
253626
+ provider: model.provider,
253627
+ reason: capped ? `No published price for ${model.provider}:${model.id}. Its spend is not counted toward your cost budget \u2014 the token cap still applies. Add it to the pricing dataset, or set the provider's \`local: true\` if this endpoint really is free.` : `No published price for ${model.provider}:${model.id}. Cost for this model is reported as "not tracked" rather than $0.00.`
253628
+ });
253629
+ }
253630
+ }
251886
253631
  this.runTokens += usage.totalTokens;
251887
253632
  this.runCostUsd += usage.estimatedCostUsd;
251888
253633
  this.updateBudgetState();
@@ -297684,7 +299429,18 @@ var ProviderConfigSchema = external_exports.object({
297684
299429
  apiVersion: external_exports.string().optional(),
297685
299430
  model: external_exports.string().optional(),
297686
299431
  authToken: external_exports.string().optional(),
297687
- credentialSource: external_exports.string().optional()
299432
+ credentialSource: external_exports.string().optional(),
299433
+ /**
299434
+ * "This endpoint is self-hosted, so inference genuinely costs $0."
299435
+ * Only meaningful for `ollama` and `openai-compatible`. Unset ⇒ inferred:
299436
+ * ollama is local, openai-compatible is local when its baseUrl is
299437
+ * loopback/LAN. Set it explicitly to override — e.g. `false` for an Ollama
299438
+ * instance you rent, `true` for a llama.cpp box on your own LAN reached by
299439
+ * hostname.
299440
+ */
299441
+ local: external_exports.boolean().optional(),
299442
+ /** Region for providers whose price varies by region (Azure: global | us | eu | …). */
299443
+ region: external_exports.string().optional()
297688
299444
  });
297689
299445
  var ModelOverridesSchema = external_exports.object({
297690
299446
  t1: external_exports.string().optional(),
@@ -298270,8 +300026,8 @@ var TaskAnalyzer = class {
298270
300026
  }
298271
300027
  costEfficiency(model, complexity) {
298272
300028
  if (this.tracker) return this.tracker.costEfficiencyScore(model, complexity);
298273
- const blended = model.inputCostPer1kTokens + model.outputCostPer1kTokens * 2;
298274
- const normalised = Math.min(1, blended / 0.05);
300029
+ const blended = blendedCostPer1k(model);
300030
+ const normalised = Math.min(1, blended / BLENDED_COST_CEILING);
298275
300031
  const complexityWeight = (6 - complexity) / 5;
298276
300032
  return Math.max(0.1, 1 - normalised * complexityWeight);
298277
300033
  }
@@ -298406,8 +300162,8 @@ var ModelPerformanceTracker = class {
298406
300162
  * normalised over $0.05 blended as the "expensive" ceiling.
298407
300163
  */
298408
300164
  costEfficiencyScore(model, complexity) {
298409
- const blended = model.inputCostPer1kTokens + model.outputCostPer1kTokens * 2;
298410
- const normalised = Math.min(1, blended / 0.05);
300165
+ const blended = blendedCostPer1k(model);
300166
+ const normalised = Math.min(1, blended / BLENDED_COST_CEILING);
298411
300167
  const complexityWeight = (6 - complexity) / 5;
298412
300168
  return Math.max(0.1, 1 - normalised * complexityWeight);
298413
300169
  }
@@ -301260,7 +303016,11 @@ _(incomplete: ${reasons.join("; ")})_` : partial2;
301260
303016
  inputTokens: 0,
301261
303017
  outputTokens: 0,
301262
303018
  totalTokens: stats.totalTokens,
301263
- estimatedCostUsd: stats.totalCostUsd
303019
+ estimatedCostUsd: stats.totalCostUsd,
303020
+ // At least one call ran on a model with no known price, so its spend is
303021
+ // missing from the total above. Say so rather than letting the caller
303022
+ // present an undercount as the final figure.
303023
+ ...stats.untrackedCostCalls > 0 ? { costUnknown: true } : {}
301264
303024
  },
301265
303025
  t2Results,
301266
303026
  durationMs,
@@ -301330,7 +303090,8 @@ _(incomplete: ${reasons.join("; ")})_` : partial2;
301330
303090
  inputTokens: 0,
301331
303091
  outputTokens: 0,
301332
303092
  totalTokens: stats2.totalTokens,
301333
- estimatedCostUsd: stats2.totalCostUsd
303093
+ estimatedCostUsd: stats2.totalCostUsd,
303094
+ ...stats2.untrackedCostCalls > 0 ? { costUnknown: true } : {}
301334
303095
  },
301335
303096
  t2Results: [],
301336
303097
  durationMs: Date.now() - startMs,
@@ -301354,7 +303115,8 @@ _(incomplete: ${reasons.join("; ")})_` : partial2;
301354
303115
  inputTokens: result.usage?.inputTokens ?? 0,
301355
303116
  outputTokens: result.usage?.outputTokens ?? 0,
301356
303117
  totalTokens: stats.totalTokens,
301357
- estimatedCostUsd: stats.totalCostUsd
303118
+ estimatedCostUsd: stats.totalCostUsd,
303119
+ ...stats.untrackedCostCalls > 0 ? { costUnknown: true } : {}
301358
303120
  },
301359
303121
  t2Results: [],
301360
303122
  durationMs: Date.now() - startMs,
@@ -303922,7 +305684,10 @@ var DashboardServer = class {
303922
305684
  this.socket.broadcast("cost:update", {
303923
305685
  sessionId,
303924
305686
  totalTokens: result.usage.totalTokens,
303925
- totalCostUsd: result.usage.estimatedCostUsd
305687
+ totalCostUsd: result.usage.estimatedCostUsd,
305688
+ // True when a model with no known price was used: the total above is
305689
+ // an undercount, and the UI must not present it as the full spend.
305690
+ costUnknown: result.usage.costUnknown === true
303926
305691
  });
303927
305692
  this.throttledBroadcast("workspace");
303928
305693
  } catch (err) {
@@ -304235,7 +306000,8 @@ var DashboardServer = class {
304235
306000
  this.socket.broadcast("cost:update", {
304236
306001
  sessionId,
304237
306002
  totalTokens: result.usage.totalTokens,
304238
- totalCostUsd: result.usage.estimatedCostUsd
306003
+ totalCostUsd: result.usage.estimatedCostUsd,
306004
+ costUnknown: result.usage.costUnknown === true
304239
306005
  });
304240
306006
  this.throttledBroadcast("workspace");
304241
306007
  } catch (err) {
@@ -304777,7 +306543,8 @@ ${prompt}`;
304777
306543
  this.socket.broadcast("cost:update", {
304778
306544
  sessionId,
304779
306545
  totalTokens: result.usage.totalTokens,
304780
- totalCostUsd: result.usage.estimatedCostUsd
306546
+ totalCostUsd: result.usage.estimatedCostUsd,
306547
+ costUnknown: result.usage.costUnknown === true
304781
306548
  });
304782
306549
  this.socket.broadcastToRoom(`session:${sessionId}`, "session:complete", { sessionId, result });
304783
306550
  this.throttledBroadcast("workspace");
@@ -305333,12 +307100,19 @@ var CloudClient = class _CloudClient {
305333
307100
  );
305334
307101
  await openUrl(authorizeUrl);
305335
307102
  const code = await listener.waitForCode;
305336
- const res = await fetch(this.url("/api/native/token"), {
305337
- method: "POST",
305338
- headers: { "Content-Type": "application/json" },
305339
- body: JSON.stringify({ code, code_verifier: verifier })
305340
- });
305341
- if (!res.ok) throw new Error("Sign-in could not be completed. Please try again.");
307103
+ let res;
307104
+ try {
307105
+ res = await fetch(this.url("/api/native/token"), {
307106
+ method: "POST",
307107
+ headers: { "Content-Type": "application/json" },
307108
+ body: JSON.stringify({ code, code_verifier: verifier })
307109
+ });
307110
+ } catch (err) {
307111
+ throw new Error(
307112
+ `Signed in, but could not reach Cascade at ${this.serverUrl} to finish. Check your connection and that the server URL is correct. (${err instanceof Error ? err.message : String(err)})`
307113
+ );
307114
+ }
307115
+ if (!res.ok) throw new Error(await loginFailureMessage(res, this.serverUrl));
305342
307116
  const tokens = await res.json();
305343
307117
  return await this.finishLogin(tokens);
305344
307118
  } finally {
@@ -305512,6 +307286,22 @@ function sleep4(ms2, signal) {
305512
307286
  }, { once: true });
305513
307287
  });
305514
307288
  }
307289
+ async function loginFailureMessage(res, serverUrl) {
307290
+ const body = await res.text().catch(() => "");
307291
+ let apiError = "";
307292
+ try {
307293
+ apiError = String(JSON.parse(body).error ?? "");
307294
+ } catch {
307295
+ }
307296
+ if (apiError === "invalid_grant") {
307297
+ return "Sign-in expired before it completed \u2014 the code is single-use and short-lived, and restarting the server during sign-in also invalidates it. Please try again.";
307298
+ }
307299
+ if (apiError) return `Sign-in failed: ${apiError} (HTTP ${res.status}).`;
307300
+ if (res.status === 404 || /<html/i.test(body)) {
307301
+ return `Signed in, but ${serverUrl} did not answer the Cascade API (HTTP ${res.status}). If this host was recently pointed at a new server, DNS may still be propagating.`;
307302
+ }
307303
+ return `Sign-in could not be completed (HTTP ${res.status}). Please try again.`;
307304
+ }
305515
307305
  function base64url2(buf) {
305516
307306
  return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
305517
307307
  }