Skip to content

Commit 8b9c63d

Browse files
committed
Fix token_budget casing and add toolCalls conversion
- Fix thinking token_budget → tokenBudget (camelCase for OCI API) - Add V2 response toolCalls → tool_calls conversion for SDK compatibility - Update test for tokenBudget casing - Add test for tool_calls conversion
1 parent 213d744 commit 8b9c63d

2 files changed

Lines changed: 40 additions & 3 deletions

File tree

src/cohere/oci_client.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ def transform_request_to_oci(
671671
if "type" in thinking:
672672
oci_thinking["type"] = thinking["type"].upper()
673673
if "token_budget" in thinking and thinking["token_budget"] is not None:
674-
oci_thinking["token_budget"] = thinking["token_budget"]
674+
oci_thinking["tokenBudget"] = thinking["token_budget"]
675675
if oci_thinking:
676676
chat_request["thinking"] = oci_thinking
677677
else:
@@ -840,6 +840,12 @@ def transform_oci_response_to_cohere(
840840
transformed_content.append(item)
841841
message = {**message, "content": transformed_content}
842842

843+
# Convert toolCalls to tool_calls (OCI uses camelCase, Cohere SDK expects snake_case)
844+
if "toolCalls" in message:
845+
tool_calls = message["toolCalls"]
846+
message = {k: v for k, v in message.items() if k != "toolCalls"}
847+
message["tool_calls"] = tool_calls
848+
843849
return {
844850
"id": chat_response.get("id", str(uuid.uuid4())),
845851
"message": message,

tests/test_oci_client.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,11 +513,11 @@ def test_thinking_parameter_transformation(self):
513513

514514
result = transform_request_to_oci("chat", cohere_body, "compartment-123")
515515

516-
# Verify thinking parameter is transformed
516+
# Verify thinking parameter is transformed with camelCase for OCI API
517517
chat_request = result["chatRequest"]
518518
self.assertIn("thinking", chat_request)
519519
self.assertEqual(chat_request["thinking"]["type"], "ENABLED")
520-
self.assertEqual(chat_request["thinking"]["token_budget"], 10000)
520+
self.assertEqual(chat_request["thinking"]["tokenBudget"], 10000) # camelCase for OCI
521521

522522
def test_thinking_parameter_disabled(self):
523523
"""Test that disabled thinking is correctly transformed."""
@@ -656,6 +656,37 @@ def test_v2_response_finish_reason_uppercase(self):
656656
# V2 finish_reason should stay uppercase
657657
self.assertEqual(result["finish_reason"], "MAX_TOKENS")
658658

659+
def test_v2_response_tool_calls_conversion(self):
660+
"""Test that V2 response converts toolCalls to tool_calls."""
661+
from cohere.oci_client import transform_oci_response_to_cohere
662+
663+
oci_response = {
664+
"chatResponse": {
665+
"id": "test-id",
666+
"message": {
667+
"role": "ASSISTANT",
668+
"content": [{"type": "TEXT", "text": "I'll help with that."}],
669+
"toolCalls": [
670+
{
671+
"id": "call_123",
672+
"type": "function",
673+
"function": {"name": "get_weather", "arguments": '{"city": "London"}'},
674+
}
675+
],
676+
},
677+
"finishReason": "TOOL_CALL",
678+
"usage": {"inputTokens": 10, "completionTokens": 20},
679+
}
680+
}
681+
682+
result = transform_oci_response_to_cohere("chat", oci_response, is_v2=True)
683+
684+
# toolCalls should be converted to tool_calls
685+
self.assertIn("tool_calls", result["message"])
686+
self.assertNotIn("toolCalls", result["message"])
687+
self.assertEqual(len(result["message"]["tool_calls"]), 1)
688+
self.assertEqual(result["message"]["tool_calls"][0]["id"], "call_123")
689+
659690

660691
if __name__ == "__main__":
661692
unittest.main()

0 commit comments

Comments
 (0)