Skip to content

Commit 8abed69

Browse files
gn00295120claude
andcommitted
fix: address all Copilot/Codex feedback for PR #1929
Critical fixes based on review feedback: - Fix dict format mismatch: Read "name" directly instead of "function.name" (Responses Converter returns {"type": "function", "name": "..."}, not nested format) - Add explicit handling for ToolChoiceFunction instances (avoid silent fallback to "auto") - Add defensive checks for tool_name (exists, is string, non-empty) - Replace type: ignore with explicit cast for better type safety - Remove unused ChatCompletionNamedToolChoiceParam import This addresses the critical P1 issue identified by chatgpt-codex-connector and all Copilot nitpicks. Generated with Lucas Wang<[email protected]> Co-Authored-By: Claude <[email protected]>
1 parent 2f85765 commit 8abed69

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

src/agents/extensions/models/litellm_model.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
ChatCompletionMessageCustomToolCall,
2525
ChatCompletionMessageFunctionToolCall,
2626
ChatCompletionMessageParam,
27-
ChatCompletionNamedToolChoiceParam,
2827
)
2928
from openai.types.chat.chat_completion_message import (
3029
Annotation,
@@ -370,27 +369,31 @@ async def _fetch_response(
370369
return ret
371370

372371
# Convert tool_choice to the correct type for Response
373-
# tool_choice can be a Literal, a ChatCompletionNamedToolChoiceParam, or omit
372+
# tool_choice can be a Literal, ToolChoiceFunction, dict from Responses Converter, or omit
374373
response_tool_choice: Literal["auto", "required", "none"] | ToolChoiceFunction
375374
if tool_choice is omit:
376375
response_tool_choice = "auto"
376+
elif isinstance(tool_choice, ToolChoiceFunction):
377+
# Already a ToolChoiceFunction, use directly
378+
response_tool_choice = tool_choice
377379
elif isinstance(tool_choice, dict):
378-
# Convert from ChatCompletionNamedToolChoiceParam to ToolChoiceFunction
379-
# The dict has structure: {"type": "function", "function": {"name": "tool_name"}}
380-
func_data = tool_choice.get("function")
380+
# Convert from Responses format dict to ToolChoiceFunction
381+
# The Responses Converter returns: {"type": "function", "name": "tool_name"}
382+
tool_name = tool_choice.get("name")
381383
if (
382384
tool_choice.get("type") == "function"
383-
and func_data is not None
384-
and isinstance(func_data, dict)
385+
and tool_name is not None
386+
and isinstance(tool_name, str)
387+
and tool_name # Ensure non-empty string
385388
):
386-
response_tool_choice = ToolChoiceFunction(
387-
type="function", name=func_data["name"]
388-
)
389+
response_tool_choice = ToolChoiceFunction(type="function", name=tool_name)
389390
else:
390391
# Fallback to auto if unexpected format
391392
response_tool_choice = "auto"
392393
elif tool_choice in ("auto", "required", "none"):
393-
response_tool_choice = tool_choice # type: ignore
394+
from typing import cast
395+
396+
response_tool_choice = cast(Literal["auto", "required", "none"], tool_choice)
394397
else:
395398
# Fallback to auto for any other case
396399
response_tool_choice = "auto"

0 commit comments

Comments
 (0)