From 34af0de90625a6263fbb4ef19c91a6f1ae409486 Mon Sep 17 00:00:00 2001 From: ridalemkaalel0 Date: Tue, 14 Apr 2026 21:35:43 +0200 Subject: [PATCH 1/2] feat(snowflake): add REST API pricing for 18 Snowflake Cortex models Adds pricing entries for 18 Snowflake models from Table 6(b) of the Snowflake Service Consumption Table (REST API with Prompt Caching), using Regional pricing throughout. - 9 Claude models (AWS Regional): claude-3-7-sonnet, claude-4-opus, claude-4-sonnet, claude-haiku-4-5, claude-opus-4-5, claude-opus-4-6, claude-sonnet-4-5, claude-sonnet-4-5-long-context, claude-sonnet-4-6 - 9 OpenAI models (Azure Regional): openai-gpt-4.1, openai-gpt-5, openai-gpt-5-mini, openai-gpt-5-nano, openai-gpt-5.1, openai-gpt-5.2, openai-gpt-5.4, openai-gpt-5.4-long-context, openai-o4-mini --- ...odel_prices_and_context_window_backup.json | 286 ++++++++++++++++-- model_prices_and_context_window.json | 257 ++++++++++++++++ .../llms/snowflake/test_snowflake_pricing.py | 128 ++++++++ 3 files changed, 649 insertions(+), 22 deletions(-) create mode 100644 tests/test_litellm/llms/snowflake/test_snowflake_pricing.py 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) From 064152c354f7b68837c816ac468ab9b1f68f1fa0 Mon Sep 17 00:00:00 2001 From: ridalemkaalel0 Date: Tue, 14 Apr 2026 22:05:57 +0200 Subject: [PATCH 2/2] docs(snowflake): add Cortex Search, Agents, and v1 API base URLs --- docs/my-website/docs/providers/snowflake.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/my-website/docs/providers/snowflake.md b/docs/my-website/docs/providers/snowflake.md index 483bf939fe6..14463624762 100644 --- a/docs/my-website/docs/providers/snowflake.md +++ b/docs/my-website/docs/providers/snowflake.md @@ -8,10 +8,20 @@ import TabItem from '@theme/TabItem'; | Description | The Snowflake Cortex LLM REST API lets you access the COMPLETE and EMBED functions via HTTP POST requests | | Provider Route on LiteLLM | `snowflake/` | | Link to Provider Doc | [Snowflake ↗](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-llm-rest-api) | -| Base URLs | `https://{account-id}.snowflakecomputing.com/api/v2/cortex/inference:complete`,`https://{account-id}.snowflakecomputing.com/api/v2/cortex/inference:embed`| +| Base URLs | **Cortex LLM (v1):** `https://{account-id}.snowflakecomputing.com/api/v2/cortex/v1`
**Cortex Search:** `https://{account-id}.snowflakecomputing.com/api/v2/databases/{db}/schemas/{schema}/cortex-search-services/{service}:query`
**Cortex Agents:** `https://{account-id}.snowflakecomputing.com/api/v2/databases/{db}/schemas/{schema}/agents`
**Cortex inference (COMPLETE/EMBED):** `https://{account-id}.snowflakecomputing.com/api/v2/cortex/inference:complete`, `https://{account-id}.snowflakecomputing.com/api/v2/cortex/inference:embed` | | Supported OpenAI Endpoints | `/chat/completions`, `/completions`, `/embeddings` | +## Available APIs + +Snowflake Cortex exposes three REST API surfaces: + +| API | Endpoint Pattern | Description | Reference | +|-----|-----------------|-------------|-----------| +| **Cortex LLM (v1)** | `POST /api/v2/cortex/v1/chat/completions`
`POST /api/v2/cortex/v1/messages` | OpenAI-compatible chat completions and Anthropic-compatible messages. Supports all Cortex models. | [Cortex REST API ↗](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-rest-api) | +| **Cortex Search** | `POST /api/v2/databases/{db}/schemas/{schema}/cortex-search-services/{service}:query` | Query a Cortex Search Service for low-latency semantic/hybrid search. | [Query Cortex Search ↗](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-search/query-cortex-search-service) | +| **Cortex Agents** | `POST /api/v2/databases/{db}/schemas/{schema}/agents`
`GET /api/v2/databases/{db}/schemas/{schema}/agents/{name}`
`PUT /api/v2/databases/{db}/schemas/{schema}/agents/{name}`
`DELETE /api/v2/databases/{db}/schemas/{schema}/agents/{name}` | Create, manage, and interact with Cortex Agent objects. | [Cortex Agents REST API ↗](https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-agents-rest-api) | + ## Supported OpenAI Parameters ``` "temperature",