From e9929835cbb35095022327be94ecb2c5d821478d Mon Sep 17 00:00:00 2001 From: botbikamordehai2-sketch Date: Fri, 10 Jul 2026 12:02:58 +0000 Subject: [PATCH] fix: Add streaming tool_calls support for Snowflake Cortex (closes #30762) --- litellm/llms/snowflake/utils.py | 36 ++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/litellm/llms/snowflake/utils.py b/litellm/llms/snowflake/utils.py index d84efdd9fcd..2d1c829eddc 100644 --- a/litellm/llms/snowflake/utils.py +++ b/litellm/llms/snowflake/utils.py @@ -116,6 +116,40 @@ class SnowflakeBaseConfig: def _get_openai_compatible_provider_info( self, api_base: Optional[str], api_key: Optional[str] - ) -> Tuple[Optional[str], Optional[str]]: + ) -> Tuple[Optional[str], Opt + + def chunk_parser(self, chunk: dict) -> ModelResponse: + from litellm.utils import ModelResponse, Choices, Message, Delta + + # Check if chunk contains tool_use (streaming tool call) + if "choices" in chunk and len(chunk["choices"]) > 0: + delta = chunk["choices"][0].get("delta", {}) + if "tool_calls" in delta: + # Already OpenAI format, return as is + return chunk + + # Snowflake native streaming format: content_list may contain tool_use + content_list = chunk.get("content_list", []) + tool_calls = [] + for item in content_list: + if item.get("type") == "tool_use": + tool_calls.append({ + "id": item.get("id", ""), + "type": "function", + "function": { + "name": item.get("name", ""), + "arguments": item.get("input", "") + } + }) + if tool_calls: + return { + "choices": [{ + "delta": { + "tool_calls": tool_calls + }, + "index": 0 + }] + } + return chunkional[str]]: dynamic_api_key = api_key or get_secret_str("SNOWFLAKE_JWT") return api_base, dynamic_api_key