From 43880362d8580c34b695ef3dc389517b85358a0b Mon Sep 17 00:00:00 2001 From: Mason Daugherty Date: Wed, 10 Jun 2026 22:29:02 -0400 Subject: [PATCH] feat(standard-tests): validate tool call chunks during streaming (#34707) As a LangChain user streaming a tool-calling model, I expect each streamed chunk to expose structured `tool_call_chunk` content blocks so I can render or process tool calls live, instead of waiting for the final aggregated message. This adds `tool_call_streaming` to `ModelProfile` and uses it in the standard chat-model tool-calling tests. When a model profile opts in, `test_tool_calling` and `test_tool_calling_async` now validate that at least one streamed chunk includes a `tool_call_chunk` block via `content_blocks`, while preserving the existing final-message validation. This keeps the contract profile-gated so providers can opt in once their streaming chunk shape is verified. This PR opts in the providers verified by smoke testing with straightforward profile coverage: OpenAI, Anthropic, Fireworks, HuggingFace, OpenRouter, DeepSeek, and xAI. The generated profile artifacts are refreshed so runtime profiles expose the new capability flag. Perplexity Responses also passed the smoke test, but its current profile data is for the `sonar` family while the Responses smoke path used a routed model string. That profile strategy is left as follow-up. MistralAI currently streams `.tool_call_chunks`, but its content-block translator exposes a complete `tool_call` block instead of `tool_call_chunk`, so it also stays out of this flag until that integration is fixed. --- .../language_models/model_profile.py | 6 + .../langchain_model_profiles/cli.py | 1 + .../langchain_anthropic/data/_profiles.py | 25 ++ .../data/profile_augmentations.toml | 1 + .../langchain_deepseek/data/_profiles.py | 4 + .../data/profile_augmentations.toml | 4 + .../langchain_fireworks/data/_profiles.py | 13 + .../data/profile_augmentations.toml | 4 + .../langchain_huggingface/data/_profiles.py | 24 ++ .../data/profile_augmentations.toml | 4 + .../openai/langchain_openai/data/_profiles.py | 50 +++ .../data/profile_augmentations.toml | 1 + .../langchain_openrouter/data/_profiles.py | 363 ++++++++++++++++-- .../data/profile_augmentations.toml | 4 + .../langchain_perplexity/data/_profiles.py | 4 +- .../data/profile_augmentations.toml | 12 - .../xai/langchain_xai/data/_profiles.py | 8 + .../data/profile_augmentations.toml | 4 + .../integration_tests/chat_models.py | 52 +++ 19 files changed, 547 insertions(+), 37 deletions(-) create mode 100644 libs/partners/deepseek/langchain_deepseek/data/profile_augmentations.toml create mode 100644 libs/partners/fireworks/langchain_fireworks/data/profile_augmentations.toml create mode 100644 libs/partners/huggingface/langchain_huggingface/data/profile_augmentations.toml create mode 100644 libs/partners/openrouter/langchain_openrouter/data/profile_augmentations.toml create mode 100644 libs/partners/xai/langchain_xai/data/profile_augmentations.toml diff --git a/libs/core/langchain_core/language_models/model_profile.py b/libs/core/langchain_core/language_models/model_profile.py index 75524ad6e50..441cd376752 100644 --- a/libs/core/langchain_core/language_models/model_profile.py +++ b/libs/core/langchain_core/language_models/model_profile.py @@ -113,6 +113,12 @@ class ModelProfile(TypedDict, total=False): tool_choice: bool """Whether the model supports [tool choice](https://docs.langchain.com/oss/python/langchain/models#forcing-tool-calls).""" + tool_call_streaming: bool + """Whether the model returns properly structured `tool_call_chunks` when streaming. + + Only meaningful when `tool_calling` is `True`. + """ + # --- Structured output --- structured_output: bool """Whether the model supports native [structured output](https://docs.langchain.com/oss/python/langchain/models#structured-outputs).""" diff --git a/libs/model-profiles/langchain_model_profiles/cli.py b/libs/model-profiles/langchain_model_profiles/cli.py index 06246fd2333..3507a916f1d 100644 --- a/libs/model-profiles/langchain_model_profiles/cli.py +++ b/libs/model-profiles/langchain_model_profiles/cli.py @@ -126,6 +126,7 @@ def _model_data_to_profile(model_data: dict[str, Any]) -> dict[str, Any]: "reasoning_output": model_data.get("reasoning"), "tool_calling": model_data.get("tool_call"), "tool_choice": model_data.get("tool_choice"), + "tool_call_streaming": model_data.get("tool_call_streaming"), "structured_output": model_data.get("structured_output"), "attachment": model_data.get("attachment"), "temperature": model_data.get("temperature"), diff --git a/libs/partners/anthropic/langchain_anthropic/data/_profiles.py b/libs/partners/anthropic/langchain_anthropic/data/_profiles.py index 2caba64c2d6..6afc7a87ed5 100644 --- a/libs/partners/anthropic/langchain_anthropic/data/_profiles.py +++ b/libs/partners/anthropic/langchain_anthropic/data/_profiles.py @@ -41,6 +41,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-3-5-haiku-latest": { "name": "Claude Haiku 3.5 (latest)", @@ -66,6 +67,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-3-5-sonnet-20240620": { "name": "Claude Sonnet 3.5", @@ -92,6 +94,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-3-5-sonnet-20241022": { "name": "Claude Sonnet 3.5 v2", @@ -118,6 +121,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-3-7-sonnet-20250219": { "name": "Claude Sonnet 3.7", @@ -144,6 +148,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-3-haiku-20240307": { "name": "Claude Haiku 3", @@ -170,6 +175,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-3-opus-20240229": { "name": "Claude Opus 3", @@ -196,6 +202,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-3-sonnet-20240229": { "name": "Claude Sonnet 3", @@ -222,6 +229,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-fable-5": { "name": "Claude Fable 5", @@ -247,6 +255,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-haiku-4-5": { "name": "Claude Haiku 4.5 (latest)", @@ -272,6 +281,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": True, + "tool_call_streaming": True, }, "claude-haiku-4-5-20251001": { "name": "Claude Haiku 4.5", @@ -297,6 +307,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-opus-4-0": { "name": "Claude Opus 4 (latest)", @@ -322,6 +333,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-opus-4-1": { "name": "Claude Opus 4.1 (latest)", @@ -347,6 +359,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": True, + "tool_call_streaming": True, }, "claude-opus-4-1-20250805": { "name": "Claude Opus 4.1", @@ -372,6 +385,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-opus-4-20250514": { "name": "Claude Opus 4", @@ -397,6 +411,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-opus-4-5": { "name": "Claude Opus 4.5 (latest)", @@ -422,6 +437,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": True, + "tool_call_streaming": True, }, "claude-opus-4-5-20251101": { "name": "Claude Opus 4.5", @@ -447,6 +463,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-opus-4-6": { "name": "Claude Opus 4.6", @@ -472,6 +489,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": True, + "tool_call_streaming": True, }, "claude-opus-4-7": { "name": "Claude Opus 4.7", @@ -497,6 +515,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": True, + "tool_call_streaming": True, }, "claude-opus-4-8": { "name": "Claude Opus 4.8", @@ -522,6 +541,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-sonnet-4-0": { "name": "Claude Sonnet 4 (latest)", @@ -547,6 +567,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-sonnet-4-20250514": { "name": "Claude Sonnet 4", @@ -572,6 +593,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-sonnet-4-5": { "name": "Claude Sonnet 4.5 (latest)", @@ -597,6 +619,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": True, + "tool_call_streaming": True, }, "claude-sonnet-4-5-20250929": { "name": "Claude Sonnet 4.5", @@ -622,6 +645,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": False, + "tool_call_streaming": True, }, "claude-sonnet-4-6": { "name": "Claude Sonnet 4.6", @@ -647,5 +671,6 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "structured_output": True, + "tool_call_streaming": True, }, } diff --git a/libs/partners/anthropic/langchain_anthropic/data/profile_augmentations.toml b/libs/partners/anthropic/langchain_anthropic/data/profile_augmentations.toml index 38480f92b69..6f8dd96e9a7 100644 --- a/libs/partners/anthropic/langchain_anthropic/data/profile_augmentations.toml +++ b/libs/partners/anthropic/langchain_anthropic/data/profile_augmentations.toml @@ -6,6 +6,7 @@ pdf_inputs = true pdf_tool_message = true image_tool_message = true structured_output = false +tool_call_streaming = true [overrides."claude-haiku-4-5"] structured_output = true diff --git a/libs/partners/deepseek/langchain_deepseek/data/_profiles.py b/libs/partners/deepseek/langchain_deepseek/data/_profiles.py index f3f4aefe36d..c27eee98051 100644 --- a/libs/partners/deepseek/langchain_deepseek/data/_profiles.py +++ b/libs/partners/deepseek/langchain_deepseek/data/_profiles.py @@ -35,6 +35,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "deepseek-reasoner": { "name": "DeepSeek Reasoner", @@ -55,6 +56,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "deepseek-v4-flash": { "name": "DeepSeek V4 Flash", @@ -76,6 +78,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek-v4-pro": { "name": "DeepSeek V4 Pro", @@ -97,5 +100,6 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, } diff --git a/libs/partners/deepseek/langchain_deepseek/data/profile_augmentations.toml b/libs/partners/deepseek/langchain_deepseek/data/profile_augmentations.toml new file mode 100644 index 00000000000..e7f06cb94f7 --- /dev/null +++ b/libs/partners/deepseek/langchain_deepseek/data/profile_augmentations.toml @@ -0,0 +1,4 @@ +provider = "deepseek" + +[overrides] +tool_call_streaming = true diff --git a/libs/partners/fireworks/langchain_fireworks/data/_profiles.py b/libs/partners/fireworks/langchain_fireworks/data/_profiles.py index 70914a4f30c..3093574c001 100644 --- a/libs/partners/fireworks/langchain_fireworks/data/_profiles.py +++ b/libs/partners/fireworks/langchain_fireworks/data/_profiles.py @@ -36,6 +36,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/models/deepseek-v4-pro": { "name": "DeepSeek V4 Pro", @@ -57,6 +58,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/models/glm-5p1": { "name": "GLM 5.1", @@ -77,6 +79,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/models/gpt-oss-120b": { "name": "GPT OSS 120B", @@ -97,6 +100,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/models/gpt-oss-20b": { "name": "GPT OSS 20B", @@ -117,6 +121,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/models/kimi-k2p5": { "name": "Kimi K2.5", @@ -137,6 +142,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/models/kimi-k2p6": { "name": "Kimi K2.6", @@ -157,6 +163,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/models/minimax-m2p5": { "name": "MiniMax-M2.5", @@ -177,6 +184,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/models/minimax-m2p7": { "name": "MiniMax-M2.7", @@ -197,6 +205,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/models/qwen3p6-plus": { "name": "Qwen 3.6 Plus", @@ -217,6 +226,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/routers/glm-5p1-fast": { "name": "GLM 5.1 Fast", @@ -237,6 +247,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/routers/kimi-k2p6-fast": { "name": "Kimi K2.6 Fast", @@ -257,6 +268,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "accounts/fireworks/routers/kimi-k2p6-turbo": { "name": "Kimi K2.6 Turbo", @@ -277,5 +289,6 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, } diff --git a/libs/partners/fireworks/langchain_fireworks/data/profile_augmentations.toml b/libs/partners/fireworks/langchain_fireworks/data/profile_augmentations.toml new file mode 100644 index 00000000000..2c19b9ed32c --- /dev/null +++ b/libs/partners/fireworks/langchain_fireworks/data/profile_augmentations.toml @@ -0,0 +1,4 @@ +provider = "fireworks-ai" + +[overrides] +tool_call_streaming = true diff --git a/libs/partners/huggingface/langchain_huggingface/data/_profiles.py b/libs/partners/huggingface/langchain_huggingface/data/_profiles.py index 5ce0c696952..cf656d3eb24 100644 --- a/libs/partners/huggingface/langchain_huggingface/data/_profiles.py +++ b/libs/partners/huggingface/langchain_huggingface/data/_profiles.py @@ -35,6 +35,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "MiniMaxAI/MiniMax-M2.5": { "name": "MiniMax-M2.5", @@ -55,6 +56,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "MiniMaxAI/MiniMax-M2.7": { "name": "MiniMax-M2.7", @@ -76,6 +78,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "Qwen/Qwen3-235B-A22B-Thinking-2507": { "name": "Qwen3-235B-A22B-Thinking-2507", @@ -96,6 +99,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "Qwen/Qwen3-Coder-480B-A35B-Instruct": { "name": "Qwen3-Coder-480B-A35B-Instruct", @@ -116,6 +120,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "Qwen/Qwen3-Coder-Next": { "name": "Qwen3-Coder-Next", @@ -136,6 +141,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "Qwen/Qwen3-Embedding-4B": { "name": "Qwen 3 Embedding 4B", @@ -156,6 +162,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": False, "attachment": False, "temperature": False, + "tool_call_streaming": True, }, "Qwen/Qwen3-Embedding-8B": { "name": "Qwen 3 Embedding 8B", @@ -176,6 +183,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": False, "attachment": False, "temperature": False, + "tool_call_streaming": True, }, "Qwen/Qwen3-Next-80B-A3B-Instruct": { "name": "Qwen3-Next-80B-A3B-Instruct", @@ -196,6 +204,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "Qwen/Qwen3-Next-80B-A3B-Thinking": { "name": "Qwen3-Next-80B-A3B-Thinking", @@ -216,6 +225,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "Qwen/Qwen3.5-397B-A17B": { "name": "Qwen3.5-397B-A17B", @@ -236,6 +246,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "XiaomiMiMo/MiMo-V2-Flash": { "name": "MiMo-V2-Flash", @@ -256,6 +267,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek-ai/DeepSeek-R1-0528": { "name": "DeepSeek-R1-0528", @@ -276,6 +288,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek-ai/DeepSeek-V3.2": { "name": "DeepSeek-V3.2", @@ -296,6 +309,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek-ai/DeepSeek-V4-Pro": { "name": "DeepSeek V4 Pro", @@ -317,6 +331,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "moonshotai/Kimi-K2-Instruct": { "name": "Kimi-K2-Instruct", @@ -337,6 +352,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "moonshotai/Kimi-K2-Instruct-0905": { "name": "Kimi-K2-Instruct-0905", @@ -357,6 +373,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "moonshotai/Kimi-K2-Thinking": { "name": "Kimi-K2-Thinking", @@ -377,6 +394,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "moonshotai/Kimi-K2.5": { "name": "Kimi-K2.5", @@ -397,6 +415,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "moonshotai/Kimi-K2.6": { "name": "Kimi-K2.6", @@ -417,6 +436,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "zai-org/GLM-4.7": { "name": "GLM-4.7", @@ -437,6 +457,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "zai-org/GLM-4.7-Flash": { "name": "GLM-4.7-Flash", @@ -457,6 +478,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "zai-org/GLM-5": { "name": "GLM-5", @@ -477,6 +499,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "zai-org/GLM-5.1": { "name": "GLM-5.1", @@ -497,5 +520,6 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, } diff --git a/libs/partners/huggingface/langchain_huggingface/data/profile_augmentations.toml b/libs/partners/huggingface/langchain_huggingface/data/profile_augmentations.toml new file mode 100644 index 00000000000..9a50845e425 --- /dev/null +++ b/libs/partners/huggingface/langchain_huggingface/data/profile_augmentations.toml @@ -0,0 +1,4 @@ +provider = "huggingface" + +[overrides] +tool_call_streaming = true diff --git a/libs/partners/openai/langchain_openai/data/_profiles.py b/libs/partners/openai/langchain_openai/data/_profiles.py index 22957ec5252..d4ea8b27508 100644 --- a/libs/partners/openai/langchain_openai/data/_profiles.py +++ b/libs/partners/openai/langchain_openai/data/_profiles.py @@ -40,6 +40,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-3.5-turbo": { "name": "GPT-3.5-turbo", @@ -66,6 +67,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": False, "image_tool_message": False, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-4": { "name": "GPT-4", @@ -92,6 +94,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-4-turbo": { "name": "GPT-4 Turbo", @@ -118,6 +121,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-4.1": { "name": "GPT-4.1", @@ -144,6 +148,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-4.1-mini": { "name": "GPT-4.1 mini", @@ -170,6 +175,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-4.1-nano": { "name": "GPT-4.1 nano", @@ -196,6 +202,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-4o": { "name": "GPT-4o", @@ -222,6 +229,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-4o-2024-05-13": { "name": "GPT-4o (2024-05-13)", @@ -248,6 +256,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-4o-2024-08-06": { "name": "GPT-4o (2024-08-06)", @@ -274,6 +283,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-4o-2024-11-20": { "name": "GPT-4o (2024-11-20)", @@ -300,6 +310,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-4o-mini": { "name": "GPT-4o mini", @@ -326,6 +337,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5": { "name": "GPT-5", @@ -352,6 +364,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5-chat-latest": { "name": "GPT-5 Chat (latest)", @@ -378,6 +391,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5-codex": { "name": "GPT-5-Codex", @@ -404,6 +418,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5-mini": { "name": "GPT-5 Mini", @@ -430,6 +445,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5-nano": { "name": "GPT-5 Nano", @@ -456,6 +472,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5-pro": { "name": "GPT-5 Pro", @@ -482,6 +499,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.1": { "name": "GPT-5.1", @@ -508,6 +526,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.1-chat-latest": { "name": "GPT-5.1 Chat", @@ -534,6 +553,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.1-codex": { "name": "GPT-5.1 Codex", @@ -560,6 +580,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.1-codex-max": { "name": "GPT-5.1 Codex Max", @@ -586,6 +607,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.1-codex-mini": { "name": "GPT-5.1 Codex mini", @@ -612,6 +634,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.2": { "name": "GPT-5.2", @@ -638,6 +661,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.2-chat-latest": { "name": "GPT-5.2 Chat", @@ -664,6 +688,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.2-codex": { "name": "GPT-5.2 Codex", @@ -690,6 +715,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.2-pro": { "name": "GPT-5.2 Pro", @@ -716,6 +742,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.3-chat-latest": { "name": "GPT-5.3 Chat (latest)", @@ -742,6 +769,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.3-codex": { "name": "GPT-5.3 Codex", @@ -768,6 +796,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.3-codex-spark": { "name": "GPT-5.3 Codex Spark", @@ -794,6 +823,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.4": { "name": "GPT-5.4", @@ -820,6 +850,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.4-mini": { "name": "GPT-5.4 mini", @@ -846,6 +877,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.4-nano": { "name": "GPT-5.4 nano", @@ -872,6 +904,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.4-pro": { "name": "GPT-5.4 Pro", @@ -898,6 +931,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.5": { "name": "GPT-5.5", @@ -924,6 +958,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-5.5-pro": { "name": "GPT-5.5 Pro", @@ -950,6 +985,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-image-1": { "name": "gpt-image-1", @@ -975,6 +1011,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-image-1-mini": { "name": "gpt-image-1-mini", @@ -1000,6 +1037,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "gpt-image-1.5": { "name": "gpt-image-1.5", @@ -1025,6 +1063,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "o1": { "name": "o1", @@ -1051,6 +1090,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "o1-pro": { "name": "o1-pro", @@ -1077,6 +1117,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "o3": { "name": "o3", @@ -1103,6 +1144,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "o3-deep-research": { "name": "o3-deep-research", @@ -1128,6 +1170,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "o3-mini": { "name": "o3-mini", @@ -1154,6 +1197,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "o3-pro": { "name": "o3-pro", @@ -1180,6 +1224,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "o4-mini": { "name": "o4-mini", @@ -1206,6 +1251,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "o4-mini-deep-research": { "name": "o4-mini-deep-research", @@ -1231,6 +1277,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "text-embedding-3-large": { "name": "text-embedding-3-large", @@ -1256,6 +1303,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "text-embedding-3-small": { "name": "text-embedding-3-small", @@ -1281,6 +1329,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, "text-embedding-ada-002": { "name": "text-embedding-ada-002", @@ -1306,5 +1355,6 @@ _PROFILES: dict[str, dict[str, Any]] = { "pdf_tool_message": True, "image_tool_message": True, "tool_choice": True, + "tool_call_streaming": True, }, } diff --git a/libs/partners/openai/langchain_openai/data/profile_augmentations.toml b/libs/partners/openai/langchain_openai/data/profile_augmentations.toml index 6fb3ee4975f..ad38e801033 100644 --- a/libs/partners/openai/langchain_openai/data/profile_augmentations.toml +++ b/libs/partners/openai/langchain_openai/data/profile_augmentations.toml @@ -6,6 +6,7 @@ pdf_inputs = true pdf_tool_message = true image_tool_message = true tool_choice = true +tool_call_streaming = true [overrides."gpt-3.5-turbo"] image_url_inputs = false diff --git a/libs/partners/openrouter/langchain_openrouter/data/_profiles.py b/libs/partners/openrouter/langchain_openrouter/data/_profiles.py index 40994f5321a..23631cdd0a0 100644 --- a/libs/partners/openrouter/langchain_openrouter/data/_profiles.py +++ b/libs/partners/openrouter/langchain_openrouter/data/_profiles.py @@ -36,6 +36,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "aion-labs/aion-1.0": { "name": "Aion-1.0", @@ -57,6 +58,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "aion-labs/aion-1.0-mini": { "name": "Aion-1.0-Mini", @@ -78,6 +80,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "aion-labs/aion-2.0": { "name": "Aion-2.0", @@ -99,6 +102,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "aion-labs/aion-rp-llama-3.1-8b": { "name": "Aion-RP 1.0 (8B)", @@ -120,6 +124,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "allenai/olmo-3-32b-think": { "name": "Olmo 3 32B Think", @@ -141,6 +146,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "amazon/nova-2-lite-v1": { "name": "Nova 2 Lite", @@ -163,6 +169,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "amazon/nova-lite-v1": { "name": "Nova Lite 1.0", @@ -184,6 +191,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "amazon/nova-micro-v1": { "name": "Nova Micro 1.0", @@ -205,6 +213,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "amazon/nova-premier-v1": { "name": "Nova Premier 1.0", @@ -226,6 +235,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "amazon/nova-pro-v1": { "name": "Nova Pro 1.0", @@ -247,6 +257,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthracite-org/magnum-v4-72b": { "name": "Magnum v4 72B", @@ -268,6 +279,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-3-haiku": { "name": "Claude 3 Haiku", @@ -289,6 +301,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-3.5-haiku": { "name": "Claude 3.5 Haiku", @@ -310,6 +323,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-fable-5": { "name": "Claude Fable 5", @@ -332,6 +346,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "anthropic/claude-haiku-4.5": { "name": "Claude Haiku 4.5 (latest)", @@ -354,6 +369,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-opus-4": { "name": "Claude Opus 4", @@ -376,6 +392,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-opus-4.1": { "name": "Claude Opus 4.1 (latest)", @@ -398,6 +415,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-opus-4.5": { "name": "Claude Opus 4.5 (latest)", @@ -420,6 +438,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-opus-4.6": { "name": "Claude Opus 4.6", @@ -442,6 +461,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-opus-4.6-fast": { "name": "Claude Opus 4.6 (Fast)", @@ -464,6 +484,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-opus-4.7": { "name": "Claude Opus 4.7", @@ -486,6 +507,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "anthropic/claude-opus-4.7-fast": { "name": "Claude Opus 4.7 (Fast)", @@ -508,6 +530,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "anthropic/claude-opus-4.8": { "name": "Claude Opus 4.8", @@ -530,6 +553,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "anthropic/claude-opus-4.8-fast": { "name": "Claude Opus 4.8 (Fast)", @@ -552,6 +576,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "anthropic/claude-sonnet-4": { "name": "Claude Sonnet 4", @@ -574,6 +599,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-sonnet-4.5": { "name": "Claude Sonnet 4.5 (latest)", @@ -596,6 +622,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "anthropic/claude-sonnet-4.6": { "name": "Claude Sonnet 4.6", @@ -618,6 +645,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "arcee-ai/coder-large": { "name": "Coder Large", @@ -639,6 +667,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "arcee-ai/trinity-large-thinking": { "name": "Trinity Large Thinking", @@ -660,6 +689,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "arcee-ai/trinity-mini": { "name": "Trinity Mini", @@ -681,6 +711,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "arcee-ai/virtuoso-large": { "name": "Virtuoso Large", @@ -702,6 +733,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "baidu/ernie-4.5-vl-424b-a47b": { "name": "ERNIE 4.5 VL 424B A47B ", @@ -723,6 +755,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "bytedance-seed/seed-1.6": { "name": "Seed 1.6", @@ -744,6 +777,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "bytedance-seed/seed-1.6-flash": { "name": "Seed 1.6 Flash", @@ -765,6 +799,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "bytedance-seed/seed-2.0-lite": { "name": "Seed-2.0-Lite", @@ -786,6 +821,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "bytedance-seed/seed-2.0-mini": { "name": "Seed-2.0-Mini", @@ -807,6 +843,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "bytedance/ui-tars-1.5-7b": { "name": "UI-TARS 7B ", @@ -828,6 +865,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "cognitivecomputations/dolphin-mistral-24b-venice-edition:free": { "name": "Uncensored (free)", @@ -849,6 +887,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "cohere/command-a": { "name": "Command A", @@ -870,6 +909,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "cohere/command-r-08-2024": { "name": "Command R", @@ -891,6 +931,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "cohere/command-r-plus-08-2024": { "name": "Command R+", @@ -912,6 +953,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "cohere/command-r7b-12-2024": { "name": "Command R7B", @@ -933,6 +975,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepcogito/cogito-v2.1-671b": { "name": "Cogito v2.1 671B", @@ -954,6 +997,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-chat": { "name": "DeepSeek Chat", @@ -975,13 +1019,14 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-chat-v3-0324": { "name": "DeepSeek V3 0324", "release_date": "2025-03-24", "last_updated": "2025-03-24", "open_weights": True, - "max_input_tokens": 163840, + "max_input_tokens": 32768, "max_output_tokens": 16384, "text_inputs": True, "image_inputs": False, @@ -996,6 +1041,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-chat-v3.1": { "name": "DeepSeek V3.1", @@ -1017,6 +1063,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-r1": { "name": "DeepSeek-R1", @@ -1038,6 +1085,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-r1-0528": { "name": "R1 0528", @@ -1059,6 +1107,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-r1-distill-llama-70b": { "name": "R1 Distill Llama 70B", @@ -1080,6 +1129,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-r1-distill-qwen-32b": { "name": "R1 Distill Qwen 32B", @@ -1101,6 +1151,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-v3.1-terminus": { "name": "DeepSeek V3.1 Terminus", @@ -1122,6 +1173,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-v3.2": { "name": "DeepSeek V3.2", @@ -1143,6 +1195,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-v3.2-exp": { "name": "DeepSeek V3.2 Exp", @@ -1164,6 +1217,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-v4-flash": { "name": "DeepSeek V4 Flash", @@ -1185,6 +1239,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "deepseek/deepseek-v4-pro": { "name": "DeepSeek V4 Pro", @@ -1206,6 +1261,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "essentialai/rnj-1-instruct": { "name": "Rnj 1 Instruct", @@ -1227,6 +1283,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-2.5-flash": { "name": "Gemini 2.5 Flash", @@ -1249,6 +1306,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-2.5-flash-image": { "name": "Nano Banana", @@ -1270,6 +1328,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-2.5-flash-lite": { "name": "Gemini 2.5 Flash-Lite", @@ -1292,6 +1351,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-2.5-flash-lite-preview-09-2025": { "name": "Gemini 2.5 Flash Lite Preview 09-2025", @@ -1314,6 +1374,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-2.5-pro": { "name": "Gemini 2.5 Pro", @@ -1336,6 +1397,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-2.5-pro-preview": { "name": "Gemini 2.5 Pro Preview 06-05", @@ -1358,6 +1420,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-2.5-pro-preview-05-06": { "name": "Gemini 2.5 Pro Preview 05-06", @@ -1380,6 +1443,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-3-flash-preview": { "name": "Gemini 3 Flash Preview", @@ -1402,6 +1466,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-3-pro-image-preview": { "name": "Nano Banana Pro", @@ -1423,6 +1488,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-3.1-flash-image-preview": { "name": "Nano Banana 2", @@ -1444,6 +1510,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-3.1-flash-lite": { "name": "Gemini 3.1 Flash Lite", @@ -1466,6 +1533,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-3.1-flash-lite-preview": { "name": "Gemini 3.1 Flash Lite Preview", @@ -1488,6 +1556,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-3.1-pro-preview": { "name": "Gemini 3.1 Pro Preview", @@ -1510,6 +1579,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-3.1-pro-preview-customtools": { "name": "Gemini 3.1 Pro Preview Custom Tools", @@ -1532,6 +1602,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemini-3.5-flash": { "name": "Gemini 3.5 Flash", @@ -1554,6 +1625,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemma-2-27b-it": { "name": "Gemma 2 27B", @@ -1575,6 +1647,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "google/gemma-3-12b-it": { "name": "Gemma 3 12B", @@ -1596,6 +1669,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemma-3-27b-it": { "name": "Gemma 3 27B", @@ -1617,6 +1691,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemma-3-4b-it": { "name": "Gemma 3 4B", @@ -1638,6 +1713,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemma-3n-e4b-it": { "name": "Gemma 3n 4B", @@ -1659,6 +1735,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "google/gemma-4-26b-a4b-it": { "name": "Gemma 4 26B A4B IT", @@ -1680,6 +1757,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemma-4-26b-a4b-it:free": { "name": "Gemma 4 26B A4B (free)", @@ -1701,6 +1779,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemma-4-31b-it": { "name": "Gemma 4 31B IT", @@ -1722,6 +1801,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/gemma-4-31b-it:free": { "name": "Gemma 4 31B (free)", @@ -1743,6 +1823,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/lyria-3-clip-preview": { "name": "Lyria 3 Clip Preview", @@ -1764,6 +1845,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "google/lyria-3-pro-preview": { "name": "Lyria 3 Pro Preview", @@ -1785,6 +1867,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "gryphe/mythomax-l2-13b": { "name": "MythoMax 13B", @@ -1806,6 +1889,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "ibm-granite/granite-4.0-h-micro": { "name": "Granite 4.0 Micro", @@ -1827,6 +1911,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "ibm-granite/granite-4.1-8b": { "name": "Granite 4.1 8B", @@ -1848,6 +1933,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "inception/mercury-2": { "name": "Mercury 2", @@ -1869,6 +1955,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "inclusionai/ling-2.6-1t": { "name": "Ling-2.6-1T", @@ -1890,6 +1977,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "inclusionai/ling-2.6-flash": { "name": "Ling-2.6-flash", @@ -1911,6 +1999,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "inclusionai/ring-2.6-1t": { "name": "Ring-2.6-1T", @@ -1932,6 +2021,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "inflection/inflection-3-pi": { "name": "Inflection 3 Pi", @@ -1953,6 +2043,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "inflection/inflection-3-productivity": { "name": "Inflection 3 Productivity", @@ -1974,6 +2065,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "kwaipilot/kat-coder-pro-v2": { "name": "KAT-Coder-Pro V2", @@ -1995,6 +2087,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "liquid/lfm-2-24b-a2b": { "name": "LFM2-24B-A2B", @@ -2016,6 +2109,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "liquid/lfm-2.5-1.2b-instruct:free": { "name": "LFM2.5-1.2B-Instruct (free)", @@ -2037,6 +2131,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "liquid/lfm-2.5-1.2b-thinking:free": { "name": "LFM2.5-1.2B-Thinking (free)", @@ -2058,6 +2153,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "mancer/weaver": { "name": "Weaver (alpha)", @@ -2079,6 +2175,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-3-70b-instruct": { "name": "Llama 3 70B Instruct", @@ -2100,6 +2197,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-3-8b-instruct": { "name": "Llama 3 8B Instruct", @@ -2121,6 +2219,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-3.1-70b-instruct": { "name": "Llama 3.1 70B Instruct", @@ -2142,6 +2241,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-3.1-8b-instruct": { "name": "Llama 3.1 8B Instruct", @@ -2163,6 +2263,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-3.2-11b-vision-instruct": { "name": "Llama 3.2 11B Vision Instruct", @@ -2184,6 +2285,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-3.2-1b-instruct": { "name": "Llama 3.2 1B Instruct", @@ -2205,6 +2307,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-3.2-3b-instruct": { "name": "Llama 3.2 3B Instruct", @@ -2226,6 +2329,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-3.2-3b-instruct:free": { "name": "Llama 3.2 3B Instruct (free)", @@ -2247,6 +2351,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-3.3-70b-instruct": { "name": "Llama-3.3-70B-Instruct", @@ -2268,6 +2373,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-3.3-70b-instruct:free": { "name": "Llama 3.3 70B Instruct (free)", @@ -2289,6 +2395,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-4-maverick": { "name": "Llama 4 Maverick", @@ -2310,6 +2417,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-4-scout": { "name": "Llama 4 Scout", @@ -2331,6 +2439,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-guard-3-8b": { "name": "Llama Guard 3 8B", @@ -2352,6 +2461,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "meta-llama/llama-guard-4-12b": { "name": "Llama Guard 4 12B", @@ -2373,6 +2483,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "microsoft/phi-4": { "name": "Phi 4", @@ -2394,6 +2505,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "microsoft/phi-4-mini-instruct": { "name": "Phi 4 Mini Instruct", @@ -2415,6 +2527,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "microsoft/wizardlm-2-8x22b": { "name": "WizardLM-2 8x22B", @@ -2436,6 +2549,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "minimax/minimax-01": { "name": "MiniMax-01", @@ -2457,6 +2571,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "minimax/minimax-m1": { "name": "MiniMax M1", @@ -2478,6 +2593,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "minimax/minimax-m2": { "name": "MiniMax-M2", @@ -2499,6 +2615,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "minimax/minimax-m2-her": { "name": "MiniMax M2-her", @@ -2520,6 +2637,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "minimax/minimax-m2.1": { "name": "MiniMax-M2.1", @@ -2541,6 +2659,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "minimax/minimax-m2.5": { "name": "MiniMax-M2.5", @@ -2562,6 +2681,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "minimax/minimax-m2.7": { "name": "MiniMax-M2.7", @@ -2583,6 +2703,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "minimax/minimax-m3": { "name": "MiniMax-M3", @@ -2604,6 +2725,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/codestral-2508": { "name": "Codestral 2508", @@ -2626,6 +2748,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/devstral-2512": { "name": "Devstral 2", @@ -2649,6 +2772,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/ministral-14b-2512": { "name": "Ministral 3 14B 2512", @@ -2670,6 +2794,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/ministral-3b-2512": { "name": "Ministral 3 3B 2512", @@ -2691,6 +2816,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/ministral-8b-2512": { "name": "Ministral 3 8B 2512", @@ -2712,6 +2838,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-large": { "name": "Mistral Large", @@ -2734,6 +2861,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-large-2407": { "name": "Mistral Large 2407", @@ -2756,6 +2884,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-large-2512": { "name": "Mistral Large 3", @@ -2778,6 +2907,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-medium-3": { "name": "Mistral Medium 3", @@ -2800,6 +2930,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-medium-3-5": { "name": "Mistral Medium 3.5", @@ -2822,6 +2953,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-medium-3.1": { "name": "Mistral Medium 3.1", @@ -2844,6 +2976,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-nemo": { "name": "Mistral Nemo", @@ -2865,6 +2998,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-saba": { "name": "Saba", @@ -2887,6 +3021,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-small-24b-instruct-2501": { "name": "Mistral Small 3", @@ -2908,6 +3043,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-small-2603": { "name": "Mistral Small 4", @@ -2929,6 +3065,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-small-3.1-24b-instruct": { "name": "Mistral Small 3.1 24B", @@ -2950,6 +3087,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mistral-small-3.2-24b-instruct": { "name": "Mistral Small 3.2 24B", @@ -2971,6 +3109,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/mixtral-8x22b-instruct": { "name": "Mixtral 8x22B Instruct", @@ -2993,6 +3132,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "mistralai/voxtral-small-24b-2507": { "name": "Voxtral Small 24B 2507", @@ -3015,6 +3155,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "moonshotai/kimi-k2": { "name": "Kimi K2 0711", @@ -3036,6 +3177,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "moonshotai/kimi-k2-0905": { "name": "Kimi K2 0905", @@ -3057,6 +3199,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "moonshotai/kimi-k2-thinking": { "name": "Kimi K2 Thinking", @@ -3078,6 +3221,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "moonshotai/kimi-k2.5": { "name": "Kimi K2.5", @@ -3099,6 +3243,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "moonshotai/kimi-k2.6": { "name": "Kimi K2.6", @@ -3120,27 +3265,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, - }, - "moonshotai/kimi-k2.6:free": { - "name": "Kimi K2.6 (free)", - "release_date": "2026-04-21", - "last_updated": "2026-04-21", - "open_weights": True, - "max_input_tokens": 262144, - "max_output_tokens": 262144, - "text_inputs": True, - "image_inputs": True, - "audio_inputs": False, - "video_inputs": False, - "text_outputs": True, - "image_outputs": False, - "audio_outputs": False, - "video_outputs": False, - "reasoning_output": True, - "tool_calling": True, - "structured_output": False, - "attachment": True, - "temperature": False, + "tool_call_streaming": True, }, "morph/morph-v3-fast": { "name": "Morph V3 Fast", @@ -3162,6 +3287,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "morph/morph-v3-large": { "name": "Morph V3 Large", @@ -3183,6 +3309,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nex-agi/nex-n2-pro:free": { "name": "Nex-N2-Pro (free)", @@ -3204,6 +3331,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "nousresearch/hermes-3-llama-3.1-405b": { "name": "Hermes 3 405B Instruct", @@ -3225,6 +3353,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nousresearch/hermes-3-llama-3.1-405b:free": { "name": "Hermes 3 405B Instruct (free)", @@ -3246,6 +3375,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nousresearch/hermes-3-llama-3.1-70b": { "name": "Hermes 3 70B Instruct", @@ -3267,6 +3397,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nousresearch/hermes-4-405b": { "name": "Hermes 4 405B", @@ -3288,6 +3419,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nousresearch/hermes-4-70b": { "name": "Hermes 4 70B", @@ -3309,6 +3441,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nvidia/llama-3.3-nemotron-super-49b-v1.5": { "name": "Llama 3.3 Nemotron Super 49B v1.5", @@ -3330,6 +3463,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-3-nano-30b-a3b": { "name": "Nemotron 3 Nano 30B A3B", @@ -3351,6 +3485,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-3-nano-30b-a3b:free": { "name": "Nemotron 3 Nano 30B A3B (free)", @@ -3372,6 +3507,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free": { "name": "Nemotron 3 Nano Omni (free)", @@ -3393,6 +3529,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-3-super-120b-a12b": { "name": "Nemotron 3 Super 120B A12B", @@ -3411,9 +3548,10 @@ _PROFILES: dict[str, dict[str, Any]] = { "video_outputs": False, "reasoning_output": True, "tool_calling": True, - "structured_output": False, + "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-3-super-120b-a12b:free": { "name": "Nemotron 3 Super (free)", @@ -3435,6 +3573,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-3-ultra-550b-a55b": { "name": "Nemotron 3 Ultra 550B A55B", @@ -3456,6 +3595,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-3-ultra-550b-a55b:free": { "name": "Nemotron 3 Ultra (free)", @@ -3477,6 +3617,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-3.5-content-safety:free": { "name": "Nemotron 3.5 Content Safety (free)", @@ -3498,6 +3639,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-nano-12b-v2-vl:free": { "name": "Nemotron Nano 12B 2 VL (free)", @@ -3519,6 +3661,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-nano-9b-v2": { "name": "Nemotron Nano 9B v2", @@ -3540,6 +3683,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "nvidia/nemotron-nano-9b-v2:free": { "name": "Nemotron Nano 9B V2 (free)", @@ -3561,6 +3705,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-3.5-turbo": { "name": "GPT-3.5-turbo", @@ -3582,6 +3727,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-3.5-turbo-0613": { "name": "GPT-3.5 Turbo (older v0613)", @@ -3603,6 +3749,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-3.5-turbo-16k": { "name": "GPT-3.5 Turbo 16k", @@ -3624,6 +3771,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-3.5-turbo-instruct": { "name": "GPT-3.5 Turbo Instruct", @@ -3645,6 +3793,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4": { "name": "GPT-4", @@ -3666,6 +3815,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4-turbo": { "name": "GPT-4 Turbo", @@ -3687,6 +3837,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4-turbo-preview": { "name": "GPT-4 Turbo Preview", @@ -3708,6 +3859,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4.1": { "name": "GPT-4.1", @@ -3730,6 +3882,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4.1-mini": { "name": "GPT-4.1 mini", @@ -3752,6 +3905,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4.1-nano": { "name": "GPT-4.1 nano", @@ -3774,6 +3928,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4o": { "name": "GPT-4o", @@ -3796,6 +3951,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4o-2024-05-13": { "name": "GPT-4o (2024-05-13)", @@ -3818,6 +3974,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4o-2024-08-06": { "name": "GPT-4o (2024-08-06)", @@ -3840,6 +3997,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4o-2024-11-20": { "name": "GPT-4o (2024-11-20)", @@ -3862,6 +4020,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4o-mini": { "name": "GPT-4o mini", @@ -3884,6 +4043,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4o-mini-2024-07-18": { "name": "GPT-4o-mini (2024-07-18)", @@ -3906,6 +4066,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-4o-mini-search-preview": { "name": "GPT-4o-mini Search Preview", @@ -3927,6 +4088,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-4o-search-preview": { "name": "GPT-4o Search Preview", @@ -3948,6 +4110,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5": { "name": "GPT-5", @@ -3970,6 +4133,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5-chat": { "name": "GPT-5 Chat", @@ -3992,6 +4156,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5-codex": { "name": "GPT-5-Codex", @@ -4013,6 +4178,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5-image": { "name": "GPT-5 Image", @@ -4035,6 +4201,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-5-image-mini": { "name": "GPT-5 Image Mini", @@ -4057,6 +4224,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-5-mini": { "name": "GPT-5 Mini", @@ -4079,6 +4247,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5-nano": { "name": "GPT-5 Nano", @@ -4101,6 +4270,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5-pro": { "name": "GPT-5 Pro", @@ -4123,6 +4293,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.1": { "name": "GPT-5.1", @@ -4145,6 +4316,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.1-chat": { "name": "GPT-5.1 Chat", @@ -4167,6 +4339,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.1-codex": { "name": "GPT-5.1 Codex", @@ -4188,6 +4361,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.1-codex-max": { "name": "GPT-5.1 Codex Max", @@ -4209,6 +4383,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.1-codex-mini": { "name": "GPT-5.1 Codex mini", @@ -4230,6 +4405,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.2": { "name": "GPT-5.2", @@ -4252,6 +4428,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.2-chat": { "name": "GPT-5.2 Chat", @@ -4274,6 +4451,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.2-codex": { "name": "GPT-5.2 Codex", @@ -4295,6 +4473,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.2-pro": { "name": "GPT-5.2 Pro", @@ -4317,6 +4496,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.3-chat": { "name": "GPT-5.3 Chat", @@ -4339,6 +4519,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.3-codex": { "name": "GPT-5.3 Codex", @@ -4361,6 +4542,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.4": { "name": "GPT-5.4", @@ -4383,6 +4565,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.4-image-2": { "name": "GPT-5.4 Image 2", @@ -4405,6 +4588,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.4-mini": { "name": "GPT-5.4 mini", @@ -4427,6 +4611,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.4-nano": { "name": "GPT-5.4 nano", @@ -4449,6 +4634,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.4-pro": { "name": "GPT-5.4 Pro", @@ -4471,6 +4657,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.5": { "name": "GPT-5.5", @@ -4493,6 +4680,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-5.5-pro": { "name": "GPT-5.5 Pro", @@ -4515,6 +4703,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-audio": { "name": "GPT Audio", @@ -4536,6 +4725,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-audio-mini": { "name": "GPT Audio Mini", @@ -4557,6 +4747,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-chat-latest": { "name": "GPT Chat Latest", @@ -4579,6 +4770,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/gpt-oss-120b": { "name": "gpt-oss-120b", @@ -4600,6 +4792,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-oss-120b:free": { "name": "gpt-oss-120b (free)", @@ -4621,6 +4814,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-oss-20b": { "name": "gpt-oss-20b", @@ -4642,6 +4836,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-oss-20b:free": { "name": "gpt-oss-20b (free)", @@ -4663,6 +4858,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/gpt-oss-safeguard-20b": { "name": "gpt-oss-safeguard-20b", @@ -4684,6 +4880,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openai/o1": { "name": "o1", @@ -4706,6 +4903,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/o1-pro": { "name": "o1-pro", @@ -4728,6 +4926,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/o3": { "name": "o3", @@ -4750,6 +4949,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/o3-deep-research": { "name": "o3-deep-research", @@ -4772,6 +4972,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/o3-mini": { "name": "o3-mini", @@ -4794,6 +4995,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/o3-mini-high": { "name": "o3 Mini High", @@ -4816,6 +5018,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/o3-pro": { "name": "o3-pro", @@ -4838,6 +5041,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/o4-mini": { "name": "o4-mini", @@ -4860,6 +5064,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openai/o4-mini-deep-research": { "name": "o4-mini-deep-research", @@ -4882,6 +5087,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openai/o4-mini-high": { "name": "o4 Mini High", @@ -4904,6 +5110,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "openrouter/auto": { "name": "Auto Router", @@ -4926,6 +5133,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openrouter/bodybuilder": { "name": "Body Builder (beta)", @@ -4947,6 +5155,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": False, + "tool_call_streaming": True, }, "openrouter/free": { "name": "Free Models Router", @@ -4968,6 +5177,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "openrouter/fusion": { "name": "Fusion", @@ -4989,6 +5199,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": False, + "tool_call_streaming": True, }, "openrouter/owl-alpha": { "name": "Owl Alpha", @@ -5011,6 +5222,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "openrouter/pareto-code": { "name": "Pareto Code Router", @@ -5032,6 +5244,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": False, + "tool_call_streaming": True, }, "perceptron/perceptron-mk1": { "name": "Perceptron Mk1", @@ -5053,6 +5266,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "perplexity/sonar": { "name": "Sonar", @@ -5074,6 +5288,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "perplexity/sonar-deep-research": { "name": "Sonar Deep Research", @@ -5095,6 +5310,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "perplexity/sonar-pro": { "name": "Sonar Pro", @@ -5116,6 +5332,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "perplexity/sonar-pro-search": { "name": "Sonar Pro Search", @@ -5137,6 +5354,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "perplexity/sonar-reasoning-pro": { "name": "Sonar Reasoning Pro", @@ -5158,6 +5376,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "poolside/laguna-m.1:free": { "name": "Laguna M.1 (free)", @@ -5179,6 +5398,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "poolside/laguna-xs.2:free": { "name": "Laguna XS.2 (free)", @@ -5200,6 +5420,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "prime-intellect/intellect-3": { "name": "INTELLECT-3", @@ -5221,6 +5442,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen-2.5-72b-instruct": { "name": "Qwen2.5 72B Instruct", @@ -5242,6 +5464,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen-2.5-7b-instruct": { "name": "Qwen2.5 7B Instruct", @@ -5263,6 +5486,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen-2.5-coder-32b-instruct": { "name": "Qwen2.5 Coder 32B Instruct", @@ -5284,6 +5508,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen-plus": { "name": "Qwen Plus", @@ -5305,6 +5530,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen-plus-2025-07-28": { "name": "Qwen Plus 0728", @@ -5326,6 +5552,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen-plus-2025-07-28:thinking": { "name": "Qwen Plus 0728 (thinking)", @@ -5347,6 +5574,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen2.5-vl-72b-instruct": { "name": "Qwen2.5 VL 72B Instruct", @@ -5368,6 +5596,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-14b": { "name": "Qwen3 14B", @@ -5389,6 +5618,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-235b-a22b": { "name": "Qwen3 235B-A22B", @@ -5410,6 +5640,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-235b-a22b-2507": { "name": "Qwen3 235B A22B Instruct 2507", @@ -5431,6 +5662,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-235b-a22b-thinking-2507": { "name": "Qwen3 235B A22B Thinking 2507", @@ -5452,6 +5684,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-30b-a3b": { "name": "Qwen3 30B A3B", @@ -5473,6 +5706,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-30b-a3b-instruct-2507": { "name": "Qwen3 30B A3B Instruct 2507", @@ -5494,6 +5728,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-30b-a3b-thinking-2507": { "name": "Qwen3 30B A3B Thinking 2507", @@ -5515,6 +5750,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-32b": { "name": "Qwen3 32B", @@ -5536,6 +5772,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-8b": { "name": "Qwen3 8B", @@ -5557,6 +5794,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-coder": { "name": "Qwen3 Coder 480B A35B", @@ -5578,6 +5816,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-coder-30b-a3b-instruct": { "name": "Qwen3-Coder 30B-A3B Instruct", @@ -5599,6 +5838,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-coder-flash": { "name": "Qwen3 Coder Flash", @@ -5620,6 +5860,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-coder-next": { "name": "Qwen3 Coder Next", @@ -5641,6 +5882,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-coder-plus": { "name": "Qwen3 Coder Plus", @@ -5662,6 +5904,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-coder:free": { "name": "Qwen3 Coder 480B A35B (free)", @@ -5683,6 +5926,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-max": { "name": "Qwen3 Max", @@ -5704,6 +5948,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-max-thinking": { "name": "Qwen3 Max Thinking", @@ -5725,6 +5970,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-next-80b-a3b-instruct": { "name": "Qwen3-Next 80B-A3B Instruct", @@ -5746,6 +5992,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-next-80b-a3b-instruct:free": { "name": "Qwen3 Next 80B A3B Instruct (free)", @@ -5767,6 +6014,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-next-80b-a3b-thinking": { "name": "Qwen3-Next 80B-A3B (Thinking)", @@ -5788,6 +6036,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-vl-235b-a22b-instruct": { "name": "Qwen3 VL 235B A22B Instruct", @@ -5809,6 +6058,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-vl-235b-a22b-thinking": { "name": "Qwen3 VL 235B A22B Thinking", @@ -5830,6 +6080,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-vl-30b-a3b-instruct": { "name": "Qwen3 VL 30B A3B Instruct", @@ -5851,6 +6102,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-vl-30b-a3b-thinking": { "name": "Qwen3 VL 30B A3B Thinking", @@ -5872,6 +6124,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-vl-32b-instruct": { "name": "Qwen3 VL 32B Instruct", @@ -5893,6 +6146,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-vl-8b-instruct": { "name": "Qwen3 VL 8B Instruct", @@ -5914,6 +6168,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3-vl-8b-thinking": { "name": "Qwen3 VL 8B Thinking", @@ -5935,6 +6190,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.5-122b-a10b": { "name": "Qwen3.5 122B-A10B", @@ -5956,6 +6212,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.5-27b": { "name": "Qwen3.5 27B", @@ -5977,6 +6234,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.5-35b-a3b": { "name": "Qwen3.5 35B-A3B", @@ -5998,6 +6256,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.5-397b-a17b": { "name": "Qwen3.5 397B-A17B", @@ -6019,6 +6278,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.5-9b": { "name": "Qwen3.5-9B", @@ -6040,6 +6300,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.5-flash-02-23": { "name": "Qwen3.5-Flash", @@ -6061,6 +6322,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.5-plus-02-15": { "name": "Qwen3.5 Plus 2026-02-15", @@ -6082,6 +6344,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.5-plus-20260420": { "name": "Qwen3.5 Plus 2026-04-20", @@ -6103,6 +6366,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.6-27b": { "name": "Qwen3.6 27B", @@ -6124,6 +6388,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.6-35b-a3b": { "name": "Qwen3.6 35B-A3B", @@ -6145,6 +6410,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.6-flash": { "name": "Qwen3.6 Flash", @@ -6166,6 +6432,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.6-max-preview": { "name": "Qwen3.6 Max Preview", @@ -6187,6 +6454,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.6-plus": { "name": "Qwen3.6 Plus", @@ -6208,6 +6476,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.7-max": { "name": "Qwen3.7 Max", @@ -6229,6 +6498,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "qwen/qwen3.7-plus": { "name": "Qwen3.7 Plus", @@ -6250,6 +6520,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "rekaai/reka-edge": { "name": "Reka Edge", @@ -6271,6 +6542,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "rekaai/reka-flash-3": { "name": "Reka Flash 3", @@ -6292,6 +6564,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "relace/relace-apply-3": { "name": "Relace Apply 3", @@ -6313,6 +6586,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": False, + "tool_call_streaming": True, }, "relace/relace-search": { "name": "Relace Search", @@ -6334,6 +6608,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "sao10k/l3-lunaris-8b": { "name": "Llama 3 8B Lunaris", @@ -6355,6 +6630,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "sao10k/l3.1-70b-hanami-x1": { "name": "Llama 3.1 70B Hanami x1", @@ -6376,6 +6652,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "sao10k/l3.1-euryale-70b": { "name": "Llama 3.1 Euryale 70B v2.2", @@ -6397,6 +6674,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "sao10k/l3.3-euryale-70b": { "name": "Llama 3.3 Euryale 70B", @@ -6418,6 +6696,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "stepfun/step-3.5-flash": { "name": "Step 3.5 Flash", @@ -6439,6 +6718,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "stepfun/step-3.7-flash": { "name": "Step 3.7 Flash", @@ -6460,6 +6740,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "switchpoint/router": { "name": "Switchpoint Router", @@ -6481,6 +6762,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "tencent/hunyuan-a13b-instruct": { "name": "Hunyuan A13B Instruct", @@ -6502,6 +6784,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "tencent/hy3-preview": { "name": "Hy3 preview", @@ -6523,6 +6806,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "thedrummer/cydonia-24b-v4.1": { "name": "Cydonia 24B V4.1", @@ -6544,6 +6828,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "thedrummer/rocinante-12b": { "name": "Rocinante 12B", @@ -6565,6 +6850,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "thedrummer/skyfall-36b-v2": { "name": "Skyfall 36B V2", @@ -6586,6 +6872,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "thedrummer/unslopnemo-12b": { "name": "UnslopNemo 12B", @@ -6607,6 +6894,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "undi95/remm-slerp-l2-13b": { "name": "ReMM SLERP 13B", @@ -6628,6 +6916,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "upstage/solar-pro-3": { "name": "Solar Pro 3", @@ -6649,6 +6938,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "writer/palmyra-x5": { "name": "Palmyra X5", @@ -6670,6 +6960,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "x-ai/grok-4.20": { "name": "Grok 4.20", @@ -6692,6 +6983,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "x-ai/grok-4.20-multi-agent": { "name": "Grok 4.20 Multi-Agent", @@ -6714,6 +7006,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "x-ai/grok-4.3": { "name": "Grok 4.3", @@ -6735,6 +7028,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "x-ai/grok-build-0.1": { "name": "Grok Build 0.1", @@ -6756,6 +7050,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "xiaomi/mimo-v2-flash": { "name": "MiMo-V2-Flash", @@ -6777,6 +7072,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "xiaomi/mimo-v2.5": { "name": "MiMo-V2.5", @@ -6798,6 +7094,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "xiaomi/mimo-v2.5-pro": { "name": "MiMo-V2.5-Pro", @@ -6819,6 +7116,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "z-ai/glm-4.5": { "name": "GLM-4.5", @@ -6840,6 +7138,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "z-ai/glm-4.5-air": { "name": "GLM-4.5-Air", @@ -6861,6 +7160,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "z-ai/glm-4.5v": { "name": "GLM-4.5V", @@ -6882,6 +7182,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "z-ai/glm-4.6": { "name": "GLM-4.6", @@ -6903,6 +7204,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "z-ai/glm-4.6v": { "name": "GLM-4.6V", @@ -6924,6 +7226,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "z-ai/glm-4.7": { "name": "GLM-4.7", @@ -6945,6 +7248,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "z-ai/glm-4.7-flash": { "name": "GLM-4.7-Flash", @@ -6966,6 +7270,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "z-ai/glm-5": { "name": "GLM-5", @@ -6987,6 +7292,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "z-ai/glm-5-turbo": { "name": "GLM-5-Turbo", @@ -7008,6 +7314,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": False, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "z-ai/glm-5.1": { "name": "GLM-5.1", @@ -7029,6 +7336,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": False, "temperature": True, + "tool_call_streaming": True, }, "~anthropic/claude-fable-latest": { "name": "Claude Fable Latest", @@ -7051,6 +7359,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "~anthropic/claude-haiku-latest": { "name": "Anthropic Claude Haiku Latest", @@ -7073,6 +7382,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "~anthropic/claude-opus-latest": { "name": "Claude Opus Latest", @@ -7095,6 +7405,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "~anthropic/claude-sonnet-latest": { "name": "Anthropic Claude Sonnet Latest", @@ -7117,6 +7428,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "~google/gemini-flash-latest": { "name": "Google Gemini Flash Latest", @@ -7139,6 +7451,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "~google/gemini-pro-latest": { "name": "Google Gemini Pro Latest", @@ -7161,6 +7474,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "~moonshotai/kimi-latest": { "name": "MoonshotAI Kimi Latest", @@ -7182,6 +7496,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "~openai/gpt-latest": { "name": "OpenAI GPT Latest", @@ -7204,6 +7519,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "~openai/gpt-mini-latest": { "name": "OpenAI GPT Mini Latest", @@ -7226,5 +7542,6 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, } diff --git a/libs/partners/openrouter/langchain_openrouter/data/profile_augmentations.toml b/libs/partners/openrouter/langchain_openrouter/data/profile_augmentations.toml new file mode 100644 index 00000000000..6ba88640dcd --- /dev/null +++ b/libs/partners/openrouter/langchain_openrouter/data/profile_augmentations.toml @@ -0,0 +1,4 @@ +provider = "openrouter" + +[overrides] +tool_call_streaming = true diff --git a/libs/partners/perplexity/langchain_perplexity/data/_profiles.py b/libs/partners/perplexity/langchain_perplexity/data/_profiles.py index 35c4ce82825..38a4c6db78f 100644 --- a/libs/partners/perplexity/langchain_perplexity/data/_profiles.py +++ b/libs/partners/perplexity/langchain_perplexity/data/_profiles.py @@ -42,9 +42,9 @@ _PROFILES: dict[str, dict[str, Any]] = { "last_updated": "2025-09-01", "open_weights": False, "max_input_tokens": 128000, - "max_output_tokens": 8192, + "max_output_tokens": 32768, "text_inputs": True, - "image_inputs": True, + "image_inputs": False, "audio_inputs": False, "video_inputs": False, "text_outputs": True, diff --git a/libs/partners/perplexity/langchain_perplexity/data/profile_augmentations.toml b/libs/partners/perplexity/langchain_perplexity/data/profile_augmentations.toml index 5af031fb137..05e7f4d0539 100644 --- a/libs/partners/perplexity/langchain_perplexity/data/profile_augmentations.toml +++ b/libs/partners/perplexity/langchain_perplexity/data/profile_augmentations.toml @@ -1,13 +1 @@ provider = "perplexity" - -[overrides."sonar-deep-research"] -max_input_tokens = 128000 -max_output_tokens = 8192 -image_inputs = true -audio_inputs = false -video_inputs = false -image_outputs = false -audio_outputs = false -video_outputs = false -reasoning_output = true -tool_calling = false diff --git a/libs/partners/xai/langchain_xai/data/_profiles.py b/libs/partners/xai/langchain_xai/data/_profiles.py index 0de339d44cd..16f54a83c02 100644 --- a/libs/partners/xai/langchain_xai/data/_profiles.py +++ b/libs/partners/xai/langchain_xai/data/_profiles.py @@ -37,6 +37,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "grok-4.20-0309-reasoning": { "name": "Grok 4.20 (Reasoning)", @@ -59,6 +60,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "grok-4.20-multi-agent-0309": { "name": "Grok 4.20 Multi-Agent", @@ -81,6 +83,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "grok-4.3": { "name": "Grok 4.3", @@ -103,6 +106,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "grok-build-0.1": { "name": "Grok Build 0.1", @@ -125,6 +129,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "structured_output": True, "attachment": True, "temperature": True, + "tool_call_streaming": True, }, "grok-imagine-image": { "name": "Grok Imagine Image", @@ -146,6 +151,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": False, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "grok-imagine-image-quality": { "name": "Grok Imagine Image Quality", @@ -167,6 +173,7 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": False, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, "grok-imagine-video": { "name": "Grok Imagine Video", @@ -188,5 +195,6 @@ _PROFILES: dict[str, dict[str, Any]] = { "tool_calling": False, "attachment": True, "temperature": False, + "tool_call_streaming": True, }, } diff --git a/libs/partners/xai/langchain_xai/data/profile_augmentations.toml b/libs/partners/xai/langchain_xai/data/profile_augmentations.toml new file mode 100644 index 00000000000..1403df685f5 --- /dev/null +++ b/libs/partners/xai/langchain_xai/data/profile_augmentations.toml @@ -0,0 +1,4 @@ +provider = "xai" + +[overrides] +tool_call_streaming = true diff --git a/libs/standard-tests/langchain_tests/integration_tests/chat_models.py b/libs/standard-tests/langchain_tests/integration_tests/chat_models.py index 0aeeea8d232..f17dfa5e47f 100644 --- a/libs/standard-tests/langchain_tests/integration_tests/chat_models.py +++ b/libs/standard-tests/langchain_tests/integration_tests/chat_models.py @@ -134,6 +134,22 @@ def _validate_tool_call_message(message: BaseMessage) -> None: assert content_tool_call["id"] is not None +def _validate_tool_call_chunk(chunk: AIMessageChunk) -> bool: + """Check whether a streaming chunk contains valid `tool_call_chunk` blocks. + + Returns: + `True` if at least one `tool_call_chunk` block was found. + """ + found = False + for block in chunk.content_blocks: + if block.get("type") == "tool_call_chunk": + found = True + assert "name" in block, "tool_call_chunk block missing 'name' field" + assert "args" in block, "tool_call_chunk block missing 'args' field" + assert "id" in block, "tool_call_chunk block missing 'id' field" + return found + + def _validate_tool_call_message_no_args(message: BaseMessage) -> None: assert isinstance(message, AIMessage) assert len(message.tool_calls) == 1 @@ -1666,6 +1682,10 @@ class ChatModelIntegrationTests(ChatModelTests): Otherwise, in the case that only one tool is bound, ensure that `tool_choice` supports the string `'any'` to force calling that tool. + If `tool_call_streaming = true` is set in the model's profile + augmentations, individual chunks are also validated to contain + `tool_call_chunk` blocks in `content_blocks`. + """ if not self.has_tool_calling: pytest.skip("Test requires tool calling.") @@ -1680,13 +1700,28 @@ class ChatModelIntegrationTests(ChatModelTests): result = model_with_tools.invoke(query) _validate_tool_call_message(result) + tool_call_streaming = ( + model.profile.get("tool_call_streaming", False) if model.profile else False + ) + # Test stream full: BaseMessage | None = None + found_tool_call_chunk = False for chunk in model_with_tools.stream(query): + if tool_call_streaming and isinstance(chunk, AIMessageChunk): + found_tool_call_chunk |= _validate_tool_call_chunk(chunk) full = chunk if full is None else full + chunk # type: ignore[assignment] assert isinstance(full, AIMessage) _validate_tool_call_message(full) + if tool_call_streaming: + assert found_tool_call_chunk, ( + "Expected to find 'tool_call_chunk' blocks in content_blocks of at " + "least one chunk during streaming, but none were found. If this " + "model does not support streaming tool calls, set " + "tool_call_streaming=false in the model's profile augmentations." + ) + async def test_tool_calling_async(self, model: BaseChatModel) -> None: """Test that the model generates tool calls. @@ -1728,6 +1763,8 @@ class ChatModelIntegrationTests(ChatModelTests): Otherwise, in the case that only one tool is bound, ensure that `tool_choice` supports the string `'any'` to force calling that tool. + See `test_tool_calling` for `tool_call_streaming` profile configuration. + """ if not self.has_tool_calling: pytest.skip("Test requires tool calling.") @@ -1742,13 +1779,28 @@ class ChatModelIntegrationTests(ChatModelTests): result = await model_with_tools.ainvoke(query) _validate_tool_call_message(result) + tool_call_streaming = ( + model.profile.get("tool_call_streaming", False) if model.profile else False + ) + # Test astream full: BaseMessage | None = None + found_tool_call_chunk = False async for chunk in model_with_tools.astream(query): + if tool_call_streaming and isinstance(chunk, AIMessageChunk): + found_tool_call_chunk |= _validate_tool_call_chunk(chunk) full = chunk if full is None else full + chunk # type: ignore[assignment] assert isinstance(full, AIMessage) _validate_tool_call_message(full) + if tool_call_streaming: + assert found_tool_call_chunk, ( + "Expected to find 'tool_call_chunk' blocks in content_blocks of at " + "least one chunk during streaming, but none were found. If this " + "model does not support streaming tool calls, set " + "tool_call_streaming=false in the model's profile augmentations." + ) + def test_bind_runnables_as_tools(self, model: BaseChatModel) -> None: """Test bind runnables as tools.