Skip to content

Commit 6279123

Browse files
fix(oci): drop dead Cohere toolChoice field and emit GENERIC tool-call dicts inline
- Remove the unreachable toolChoice field from CohereChatRequest. The Cohere param map explicitly marks tool_choice as unsupported, so the field can never be populated through the normal optional_params flow and only confused the public model surface. - Build GENERIC stream tool-call dicts inline (id/type/function shape) instead of round-tripping through ChatCompletionMessageToolCall and model_dump(). Matches handle_cohere_stream_chunk so downstream stream-mergers see the same minimal payload regardless of which vendor produced the chunk. Co-authored-by: Yassin Kortam <[email protected]>
1 parent b1febaa commit 6279123

2 files changed

Lines changed: 25 additions & 9 deletions

File tree

litellm/llms/oci/chat/generic.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import datetime
1010
import hashlib
11-
from typing import Dict, List, Optional, Union
11+
from typing import Any, Dict, List, Optional, Union
1212

1313
import httpx
1414
from pydantic import ValidationError
@@ -435,9 +435,26 @@ def handle_generic_stream_chunk(dict_chunk: dict) -> ModelResponseStream:
435435
message=f"Unsupported content type in OCI streaming response: {item.type}",
436436
)
437437

438-
tool_calls = None
438+
# Build plain tool-call dicts inline (matching the shape produced by
439+
# ``handle_cohere_stream_chunk``) rather than calling
440+
# ``adapt_tools_to_openai_standard`` and ``model_dump``-ing the typed
441+
# objects. Both code paths feed ``Delta.tool_calls``, so emitting the
442+
# same minimal ``{"id", "type", "function": {"name", "arguments"}}``
443+
# shape keeps downstream stream-mergers behaving identically across
444+
# GENERIC and Cohere chunks.
445+
tool_calls: Optional[List[Dict[str, Any]]] = None
439446
if typed_chunk.message and typed_chunk.message.toolCalls:
440-
tool_calls = adapt_tools_to_openai_standard(typed_chunk.message.toolCalls)
447+
tool_calls = [
448+
{
449+
"id": tc.id or _synthesize_oci_tool_call_id(i, tc.name, tc.arguments),
450+
"type": "function",
451+
"function": {
452+
"name": tc.name,
453+
"arguments": tc.arguments,
454+
},
455+
}
456+
for i, tc in enumerate(typed_chunk.message.toolCalls)
457+
]
441458

442459
finish_reason: Optional[str] = _normalize_oci_finish_reason(
443460
typed_chunk.finishReason
@@ -449,11 +466,7 @@ def handle_generic_stream_chunk(dict_chunk: dict) -> ModelResponseStream:
449466
index=typed_chunk.index,
450467
delta=Delta(
451468
content=text,
452-
tool_calls=(
453-
[tool.model_dump() for tool in tool_calls]
454-
if tool_calls
455-
else None
456-
),
469+
tool_calls=tool_calls,
457470
provider_specific_fields=None,
458471
thinking_blocks=None,
459472
reasoning_content=None,

litellm/types/llms/oci.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,10 @@ class CohereChatRequest(BaseModel):
332332
stopSequences: Optional[List[str]] = None
333333
seed: Optional[int] = None
334334
tools: Optional[List[CohereTool]] = None
335-
toolChoice: Optional[Union[str, Dict[str, Any]]] = None
335+
# NOTE: OCI's Cohere chat endpoint does not accept ``toolChoice`` — see
336+
# ``OCIChatConfig.openai_to_oci_cohere_param_map`` which marks
337+
# ``tool_choice`` as unsupported. The field is intentionally absent here
338+
# so it isn't silently dropped or surfaced as a supported feature.
336339
responseFormat: Optional[
337340
Union[
338341
CohereResponseTextFormat,

0 commit comments

Comments
 (0)