|
17 | 17 | "model": "gpt-5.4", |
18 | 18 | "language": "en", |
19 | 19 | "pageindex_threshold": 20, |
20 | | - # Whether query/chat agents may call tools in parallel. None (default) omits |
21 | | - # the setting so the provider decides — required for Amazon Bedrock's Claude |
22 | | - # models, where sending parallel_tool_calls makes LiteLLM emit a malformed |
23 | | - # tool_choice (missing `type`) and every query/chat fails (issue #175). Set |
24 | | - # false to force sequential tool calls (fine on OpenAI/Anthropic-direct). |
25 | | - "parallel_tool_calls": None, |
| 20 | + # Whether query/chat agents may call tools in parallel. Default false = |
| 21 | + # force sequential tool calls (historical behavior). true = allow parallel. |
| 22 | + # null = don't send the setting at all (use the provider default) — the |
| 23 | + # escape hatch for Amazon Bedrock Claude, where sending parallel_tool_calls |
| 24 | + # (any value) makes LiteLLM emit a malformed tool_choice missing `type`, so |
| 25 | + # every query/chat fails (issue #175). |
| 26 | + "parallel_tool_calls": False, |
26 | 27 | } |
27 | 28 |
|
28 | 29 | # Default entity-type vocabulary. Overridable per-KB via the optional |
@@ -153,20 +154,32 @@ def resolve_extra_headers(config: dict) -> dict[str, str]: |
153 | 154 | def resolve_parallel_tool_calls(config: dict) -> bool | None: |
154 | 155 | """Resolve the optional ``parallel_tool_calls:`` key. |
155 | 156 |
|
156 | | - Returns ``None`` (omit the setting — provider default) when absent or |
157 | | - explicitly null; ``True``/``False`` when set to a bool. A non-bool value is |
158 | | - invalid and treated as unset, with a warning. ``None`` is the normal |
159 | | - "unset" case and warns silently, matching ``resolve_timeout``. |
| 157 | + Tri-state: |
| 158 | + * key absent → the default (``False`` — force sequential tool calls). |
| 159 | + * ``true`` / ``false`` → that bool. |
| 160 | + * explicit ``null`` → ``None``, meaning "don't send the setting" so the |
| 161 | + provider's own default applies. This is the escape hatch for Amazon |
| 162 | + Bedrock Claude, which rejects the request when the param is sent at all. |
| 163 | +
|
| 164 | + A non-bool, non-null value is invalid → falls back to the default with a |
| 165 | + warning. An explicit ``null`` is a valid choice and warns silently. |
| 166 | +
|
| 167 | + Note this relies on the config being merged with ``DEFAULT_CONFIG`` (as |
| 168 | + ``load_config`` does), so an omitted key reads back as ``False`` while an |
| 169 | + explicit ``null`` reads back as ``None`` — the two are distinguishable. |
160 | 170 | """ |
161 | | - value = config.get("parallel_tool_calls") |
| 171 | + default = DEFAULT_CONFIG["parallel_tool_calls"] |
| 172 | + value = config.get("parallel_tool_calls", default) |
162 | 173 | if value is None: |
163 | 174 | return None |
164 | 175 | if not isinstance(value, bool): |
165 | 176 | logger.warning( |
166 | | - "config: 'parallel_tool_calls' must be true or false, got %r — ignoring it.", |
| 177 | + "config: 'parallel_tool_calls' must be true, false, or null, got %r " |
| 178 | + "— using default (%r).", |
167 | 179 | value, |
| 180 | + default, |
168 | 181 | ) |
169 | | - return None |
| 182 | + return default |
170 | 183 | return value |
171 | 184 |
|
172 | 185 |
|
|
0 commit comments