diff --git a/litellm/model_prices_and_context_window_backup.json b/litellm/model_prices_and_context_window_backup.json index f7189a60a31..001e7c2eb29 100644 --- a/litellm/model_prices_and_context_window_backup.json +++ b/litellm/model_prices_and_context_window_backup.json @@ -18991,13 +18991,11 @@ "cache_read_input_token_cost_above_272k_tokens": 5e-07, "cache_read_input_token_cost_flex": 1.3e-07, "cache_read_input_token_cost_priority": 5e-07, - "cache_read_input_token_cost_above_272k_tokens_priority": 1e-06, "input_cost_per_token": 2.5e-06, "input_cost_per_token_above_272k_tokens": 5e-06, "input_cost_per_token_flex": 1.25e-06, "input_cost_per_token_batches": 1.25e-06, "input_cost_per_token_priority": 5e-06, - "input_cost_per_token_above_272k_tokens_priority": 1e-05, "litellm_provider": "openai", "max_input_tokens": 1050000, "max_output_tokens": 128000, @@ -19007,8 +19005,7 @@ "output_cost_per_token_above_272k_tokens": 2.25e-05, "output_cost_per_token_flex": 7.5e-06, "output_cost_per_token_batches": 7.5e-06, - "output_cost_per_token_priority": 2.25e-05, - "output_cost_per_token_above_272k_tokens_priority": 3.375e-05, + "output_cost_per_token_priority": 3e-05, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -19041,13 +19038,11 @@ "cache_read_input_token_cost_above_272k_tokens": 5e-07, "cache_read_input_token_cost_flex": 1.3e-07, "cache_read_input_token_cost_priority": 5e-07, - "cache_read_input_token_cost_above_272k_tokens_priority": 1e-06, "input_cost_per_token": 2.5e-06, "input_cost_per_token_above_272k_tokens": 5e-06, "input_cost_per_token_flex": 1.25e-06, "input_cost_per_token_batches": 1.25e-06, "input_cost_per_token_priority": 5e-06, - "input_cost_per_token_above_272k_tokens_priority": 1e-05, "litellm_provider": "openai", "max_input_tokens": 1050000, "max_output_tokens": 128000, @@ -19057,8 +19052,7 @@ "output_cost_per_token_above_272k_tokens": 2.25e-05, "output_cost_per_token_flex": 7.5e-06, "output_cost_per_token_batches": 7.5e-06, - "output_cost_per_token_priority": 2.25e-05, - "output_cost_per_token_above_272k_tokens_priority": 3.375e-05, + "output_cost_per_token_priority": 3e-05, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -19086,14 +19080,10 @@ "gpt-5.4-pro": { "cache_read_input_token_cost": 3e-06, "cache_read_input_token_cost_above_272k_tokens": 6e-06, - "cache_read_input_token_cost_priority": 6e-06, - "cache_read_input_token_cost_above_272k_tokens_priority": 1.2e-05, "input_cost_per_token": 3e-05, "input_cost_per_token_above_272k_tokens": 6e-05, "input_cost_per_token_flex": 1.5e-05, "input_cost_per_token_batches": 1.5e-05, - "input_cost_per_token_priority": 6e-05, - "input_cost_per_token_above_272k_tokens_priority": 0.00012, "litellm_provider": "openai", "max_input_tokens": 1050000, "max_output_tokens": 128000, @@ -19103,8 +19093,6 @@ "output_cost_per_token_above_272k_tokens": 0.00027, "output_cost_per_token_flex": 9e-05, "output_cost_per_token_batches": 9e-05, - "output_cost_per_token_priority": 0.00027, - "output_cost_per_token_above_272k_tokens_priority": 0.000405, "supported_endpoints": [ "/v1/responses", "/v1/batch" @@ -19135,14 +19123,10 @@ "gpt-5.4-pro-2026-03-05": { "cache_read_input_token_cost": 3e-06, "cache_read_input_token_cost_above_272k_tokens": 6e-06, - "cache_read_input_token_cost_priority": 6e-06, - "cache_read_input_token_cost_above_272k_tokens_priority": 1.2e-05, "input_cost_per_token": 3e-05, "input_cost_per_token_above_272k_tokens": 6e-05, "input_cost_per_token_flex": 1.5e-05, "input_cost_per_token_batches": 1.5e-05, - "input_cost_per_token_priority": 6e-05, - "input_cost_per_token_above_272k_tokens_priority": 0.00012, "litellm_provider": "openai", "max_input_tokens": 1050000, "max_output_tokens": 128000, @@ -19152,8 +19136,6 @@ "output_cost_per_token_above_272k_tokens": 0.00027, "output_cost_per_token_flex": 9e-05, "output_cost_per_token_batches": 9e-05, - "output_cost_per_token_priority": 0.00027, - "output_cost_per_token_above_272k_tokens_priority": 0.000405, "supported_endpoints": [ "/v1/responses", "/v1/batch" @@ -19183,11 +19165,13 @@ }, "gpt-5.4-mini": { "cache_read_input_token_cost": 7.5e-08, - "cache_read_input_token_cost_flex": 1e-08, - "cache_read_input_token_cost_batches": 3.8e-08, + "cache_read_input_token_cost_flex": 3.75e-08, + "cache_read_input_token_cost_batches": 3.75e-08, + "cache_read_input_token_cost_priority": 1.5e-07, "input_cost_per_token": 7.5e-07, "input_cost_per_token_flex": 3.75e-07, "input_cost_per_token_batches": 3.75e-07, + "input_cost_per_token_priority": 1.5e-06, "litellm_provider": "openai", "max_input_tokens": 272000, "max_output_tokens": 128000, @@ -19196,6 +19180,7 @@ "output_cost_per_token": 4.5e-06, "output_cost_per_token_flex": 2.25e-06, "output_cost_per_token_batches": 2.25e-06, + "output_cost_per_token_priority": 9e-06, "supported_endpoints": [ "/v1/chat/completions", "/v1/batch", @@ -27684,6 +27669,149 @@ "mode": "chat", "supports_computer_use": true }, + "snowflake/claude-3-7-sonnet": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "cache_creation_input_token_cost": 3.75e-06, + "cache_read_input_token_cost": 3e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/claude-4-opus": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 32000, + "max_tokens": 32000, + "mode": "chat", + "input_cost_per_token": 1.5e-05, + "output_cost_per_token": 7.5e-05, + "cache_creation_input_token_cost": 1.875e-05, + "cache_read_input_token_cost": 1.5e-06, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-4-sonnet": { + "litellm_provider": "snowflake", + "max_input_tokens": 1000000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "cache_creation_input_token_cost": 3.75e-06, + "cache_read_input_token_cost": 3e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-haiku-4-5": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 1.1e-06, + "output_cost_per_token": 5.5e-06, + "cache_creation_input_token_cost": 1.38e-06, + "cache_read_input_token_cost": 1.1e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-opus-4-5": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 5.5e-06, + "output_cost_per_token": 2.75e-05, + "cache_creation_input_token_cost": 6.88e-06, + "cache_read_input_token_cost": 5.5e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-opus-4-6": { + "litellm_provider": "snowflake", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 5.5e-06, + "output_cost_per_token": 2.75e-05, + "cache_creation_input_token_cost": 6.88e-06, + "cache_read_input_token_cost": 5.5e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-sonnet-4-5": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 3.3e-06, + "output_cost_per_token": 1.65e-05, + "cache_creation_input_token_cost": 4.13e-06, + "cache_read_input_token_cost": 3.3e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-sonnet-4-5-long-context": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 6.6e-06, + "output_cost_per_token": 2.475e-05, + "cache_creation_input_token_cost": 8.25e-06, + "cache_read_input_token_cost": 6.6e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-sonnet-4-6": { + "litellm_provider": "snowflake", + "max_input_tokens": 1000000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 3.3e-06, + "output_cost_per_token": 1.65e-05, + "cache_creation_input_token_cost": 4.13e-06, + "cache_read_input_token_cost": 3.3e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, "snowflake/deepseek-r1": { "litellm_provider": "snowflake", "max_input_tokens": 32768, @@ -27811,6 +27939,120 @@ "max_tokens": 8192, "mode": "chat" }, + "snowflake/openai-gpt-4.1": { + "litellm_provider": "snowflake", + "max_input_tokens": 1047576, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "input_cost_per_token": 2.2e-06, + "output_cost_per_token": 8.8e-06, + "cache_read_input_token_cost": 5.5e-07, + "supports_function_calling": true, + "supports_vision": true + }, + "snowflake/openai-gpt-5": { + "litellm_provider": "snowflake", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 1.38e-06, + "output_cost_per_token": 1.1e-05, + "cache_read_input_token_cost": 1.4e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/openai-gpt-5-mini": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 100000, + "max_tokens": 100000, + "mode": "chat", + "input_cost_per_token": 2.8e-07, + "output_cost_per_token": 2.2e-06, + "cache_read_input_token_cost": 3e-08, + "supports_function_calling": true, + "supports_vision": true + }, + "snowflake/openai-gpt-5-nano": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 100000, + "max_tokens": 100000, + "mode": "chat", + "input_cost_per_token": 6e-08, + "output_cost_per_token": 4.4e-07, + "cache_read_input_token_cost": 1e-08, + "supports_function_calling": true, + "supports_vision": true + }, + "snowflake/openai-gpt-5.1": { + "litellm_provider": "snowflake", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 1.38e-06, + "output_cost_per_token": 1.1e-05, + "cache_read_input_token_cost": 1.4e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/openai-gpt-5.2": { + "litellm_provider": "snowflake", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 1.93e-06, + "output_cost_per_token": 1.54e-05, + "cache_read_input_token_cost": 1.9e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/openai-gpt-5.4": { + "litellm_provider": "snowflake", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 2.75e-06, + "output_cost_per_token": 1.65e-05, + "cache_read_input_token_cost": 2.8e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/openai-gpt-5.4-long-context": { + "litellm_provider": "snowflake", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 5.5e-06, + "output_cost_per_token": 2.475e-05, + "cache_read_input_token_cost": 5.5e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/openai-o4-mini": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 100000, + "max_tokens": 100000, + "mode": "chat", + "input_cost_per_token": 1.1e-06, + "output_cost_per_token": 4.4e-06, + "cache_read_input_token_cost": 2.8e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, "snowflake/reka-core": { "litellm_provider": "snowflake", "max_input_tokens": 32000, diff --git a/model_prices_and_context_window.json b/model_prices_and_context_window.json index 3ffc0ec7c58..001e7c2eb29 100644 --- a/model_prices_and_context_window.json +++ b/model_prices_and_context_window.json @@ -27669,6 +27669,149 @@ "mode": "chat", "supports_computer_use": true }, + "snowflake/claude-3-7-sonnet": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "cache_creation_input_token_cost": 3.75e-06, + "cache_read_input_token_cost": 3e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/claude-4-opus": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 32000, + "max_tokens": 32000, + "mode": "chat", + "input_cost_per_token": 1.5e-05, + "output_cost_per_token": 7.5e-05, + "cache_creation_input_token_cost": 1.875e-05, + "cache_read_input_token_cost": 1.5e-06, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-4-sonnet": { + "litellm_provider": "snowflake", + "max_input_tokens": 1000000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 3e-06, + "output_cost_per_token": 1.5e-05, + "cache_creation_input_token_cost": 3.75e-06, + "cache_read_input_token_cost": 3e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-haiku-4-5": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 1.1e-06, + "output_cost_per_token": 5.5e-06, + "cache_creation_input_token_cost": 1.38e-06, + "cache_read_input_token_cost": 1.1e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-opus-4-5": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 5.5e-06, + "output_cost_per_token": 2.75e-05, + "cache_creation_input_token_cost": 6.88e-06, + "cache_read_input_token_cost": 5.5e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-opus-4-6": { + "litellm_provider": "snowflake", + "max_input_tokens": 1000000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 5.5e-06, + "output_cost_per_token": 2.75e-05, + "cache_creation_input_token_cost": 6.88e-06, + "cache_read_input_token_cost": 5.5e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-sonnet-4-5": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 3.3e-06, + "output_cost_per_token": 1.65e-05, + "cache_creation_input_token_cost": 4.13e-06, + "cache_read_input_token_cost": 3.3e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-sonnet-4-5-long-context": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 6.6e-06, + "output_cost_per_token": 2.475e-05, + "cache_creation_input_token_cost": 8.25e-06, + "cache_read_input_token_cost": 6.6e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, + "snowflake/claude-sonnet-4-6": { + "litellm_provider": "snowflake", + "max_input_tokens": 1000000, + "max_output_tokens": 64000, + "max_tokens": 64000, + "mode": "chat", + "input_cost_per_token": 3.3e-06, + "output_cost_per_token": 1.65e-05, + "cache_creation_input_token_cost": 4.13e-06, + "cache_read_input_token_cost": 3.3e-07, + "supports_prompt_caching": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true, + "supports_computer_use": true + }, "snowflake/deepseek-r1": { "litellm_provider": "snowflake", "max_input_tokens": 32768, @@ -27796,6 +27939,120 @@ "max_tokens": 8192, "mode": "chat" }, + "snowflake/openai-gpt-4.1": { + "litellm_provider": "snowflake", + "max_input_tokens": 1047576, + "max_output_tokens": 32768, + "max_tokens": 32768, + "mode": "chat", + "input_cost_per_token": 2.2e-06, + "output_cost_per_token": 8.8e-06, + "cache_read_input_token_cost": 5.5e-07, + "supports_function_calling": true, + "supports_vision": true + }, + "snowflake/openai-gpt-5": { + "litellm_provider": "snowflake", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 1.38e-06, + "output_cost_per_token": 1.1e-05, + "cache_read_input_token_cost": 1.4e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/openai-gpt-5-mini": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 100000, + "max_tokens": 100000, + "mode": "chat", + "input_cost_per_token": 2.8e-07, + "output_cost_per_token": 2.2e-06, + "cache_read_input_token_cost": 3e-08, + "supports_function_calling": true, + "supports_vision": true + }, + "snowflake/openai-gpt-5-nano": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 100000, + "max_tokens": 100000, + "mode": "chat", + "input_cost_per_token": 6e-08, + "output_cost_per_token": 4.4e-07, + "cache_read_input_token_cost": 1e-08, + "supports_function_calling": true, + "supports_vision": true + }, + "snowflake/openai-gpt-5.1": { + "litellm_provider": "snowflake", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 1.38e-06, + "output_cost_per_token": 1.1e-05, + "cache_read_input_token_cost": 1.4e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/openai-gpt-5.2": { + "litellm_provider": "snowflake", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 1.93e-06, + "output_cost_per_token": 1.54e-05, + "cache_read_input_token_cost": 1.9e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/openai-gpt-5.4": { + "litellm_provider": "snowflake", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 2.75e-06, + "output_cost_per_token": 1.65e-05, + "cache_read_input_token_cost": 2.8e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/openai-gpt-5.4-long-context": { + "litellm_provider": "snowflake", + "max_input_tokens": 272000, + "max_output_tokens": 128000, + "max_tokens": 128000, + "mode": "chat", + "input_cost_per_token": 5.5e-06, + "output_cost_per_token": 2.475e-05, + "cache_read_input_token_cost": 5.5e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, + "snowflake/openai-o4-mini": { + "litellm_provider": "snowflake", + "max_input_tokens": 200000, + "max_output_tokens": 100000, + "max_tokens": 100000, + "mode": "chat", + "input_cost_per_token": 1.1e-06, + "output_cost_per_token": 4.4e-06, + "cache_read_input_token_cost": 2.8e-07, + "supports_function_calling": true, + "supports_vision": true, + "supports_reasoning": true + }, "snowflake/reka-core": { "litellm_provider": "snowflake", "max_input_tokens": 32000, diff --git a/tests/test_litellm/llms/snowflake/test_snowflake_pricing.py b/tests/test_litellm/llms/snowflake/test_snowflake_pricing.py new file mode 100644 index 00000000000..e76457cee78 --- /dev/null +++ b/tests/test_litellm/llms/snowflake/test_snowflake_pricing.py @@ -0,0 +1,128 @@ +import json +import os + + +# All 18 Snowflake models added from Table 6(b) of the Snowflake Service +# Consumption Table (REST API with Prompt Caching, Regional pricing). +SNOWFLAKE_CLAUDE_MODELS = [ + "snowflake/claude-3-7-sonnet", + "snowflake/claude-4-opus", + "snowflake/claude-4-sonnet", + "snowflake/claude-haiku-4-5", + "snowflake/claude-opus-4-5", + "snowflake/claude-opus-4-6", + "snowflake/claude-sonnet-4-5", + "snowflake/claude-sonnet-4-5-long-context", + "snowflake/claude-sonnet-4-6", +] + +SNOWFLAKE_OPENAI_MODELS = [ + "snowflake/openai-gpt-4.1", + "snowflake/openai-gpt-5", + "snowflake/openai-gpt-5-mini", + "snowflake/openai-gpt-5-nano", + "snowflake/openai-gpt-5.1", + "snowflake/openai-gpt-5.2", + "snowflake/openai-gpt-5.4", + "snowflake/openai-gpt-5.4-long-context", + "snowflake/openai-o4-mini", +] + +ALL_SNOWFLAKE_MODELS = SNOWFLAKE_CLAUDE_MODELS + SNOWFLAKE_OPENAI_MODELS + + +def _load_pricing_data(): + json_path = os.path.join( + os.path.dirname(__file__), "../../../../model_prices_and_context_window.json" + ) + assert os.path.exists(json_path), f"Could not find pricing JSON at {json_path}" + with open(json_path, "r") as f: + return json.load(f) + + +def test_snowflake_models_exist(): + """All 18 new Snowflake REST API models must be present in the pricing JSON.""" + data = _load_pricing_data() + missing = [m for m in ALL_SNOWFLAKE_MODELS if m not in data] + assert not missing, f"Missing Snowflake models: {missing}" + + +def test_snowflake_models_have_correct_provider(): + """Every new Snowflake model must declare litellm_provider = 'snowflake'.""" + data = _load_pricing_data() + errors = [] + for model in ALL_SNOWFLAKE_MODELS: + if model in data: + provider = data[model].get("litellm_provider") + if provider != "snowflake": + errors.append( + f"{model}: litellm_provider={provider!r}, expected 'snowflake'" + ) + assert not errors, "\n".join(errors) + + +def test_snowflake_models_have_positive_pricing(): + """All new Snowflake models must have positive input and output costs.""" + data = _load_pricing_data() + errors = [] + for model in ALL_SNOWFLAKE_MODELS: + info = data.get(model, {}) + for field in ("input_cost_per_token", "output_cost_per_token"): + val = info.get(field) + if val is None: + errors.append(f"{model}: missing {field}") + elif val <= 0: + errors.append(f"{model}: {field}={val} is not positive") + assert not errors, "\n".join(errors) + + +def test_snowflake_claude_models_have_prompt_caching_fields(): + """Claude models on Snowflake support prompt caching and must include both + cache_creation_input_token_cost and cache_read_input_token_cost.""" + data = _load_pricing_data() + errors = [] + for model in SNOWFLAKE_CLAUDE_MODELS: + info = data.get(model, {}) + for field in ("cache_creation_input_token_cost", "cache_read_input_token_cost"): + val = info.get(field) + if val is None: + errors.append(f"{model}: missing {field}") + elif val <= 0: + errors.append(f"{model}: {field}={val} is not positive") + if not info.get("supports_prompt_caching"): + errors.append(f"{model}: supports_prompt_caching should be True") + assert not errors, "\n".join(errors) + + +def test_snowflake_openai_models_have_cache_read_but_no_cache_write(): + """OpenAI models on Snowflake (Azure) have cache read pricing but no cache + write cost (Table 6b shows '-' for cache write on OpenAI models).""" + data = _load_pricing_data() + errors = [] + for model in SNOWFLAKE_OPENAI_MODELS: + info = data.get(model, {}) + # Must have cache read cost + val = info.get("cache_read_input_token_cost") + if val is None: + errors.append(f"{model}: missing cache_read_input_token_cost") + elif val <= 0: + errors.append(f"{model}: cache_read_input_token_cost={val} is not positive") + # Must NOT have cache creation cost + if "cache_creation_input_token_cost" in info: + errors.append( + f"{model}: unexpected cache_creation_input_token_cost " + f"(OpenAI models have no cache write pricing)" + ) + assert not errors, "\n".join(errors) + + +def test_snowflake_models_have_context_window(): + """All new Snowflake models must define max_input_tokens and max_output_tokens.""" + data = _load_pricing_data() + errors = [] + for model in ALL_SNOWFLAKE_MODELS: + info = data.get(model, {}) + for field in ("max_input_tokens", "max_output_tokens", "max_tokens"): + if info.get(field) is None: + errors.append(f"{model}: missing {field}") + assert not errors, "\n".join(errors)