mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-30 06:43:27 +00:00
fix: drop empty additional_tools input items too
Follow-up Codex turns re-send the additional_tools item with an EMPTY tools list; the empty item is still a non-standard input variant strict providers reject, so it must be dropped even with nothing to merge — keying the rewrite off relocated tools alone made every turn after the first fail again. (Codex >= 26.707 'Responses Lite'; Codex issue #32086.) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
c755a81b5e
commit
586f08ff5b
2 changed files with 24 additions and 2 deletions
|
|
@ -7478,19 +7478,30 @@ def relocate_input_additional_tools(
|
|||
the request valid AND lets filter_tools_by_allowed_types apply the
|
||||
deployment's allowlist to the merged list.
|
||||
|
||||
Returns ``(input, tools)``; both unchanged when there is nothing to move.
|
||||
Follow-up Codex turns re-send the item with an EMPTY tools list (tools
|
||||
were established earlier in the thread); the empty item is still a
|
||||
non-standard variant strict providers reject, so it is dropped even when
|
||||
it carries nothing to merge (Codex >= 26.707 "Responses Lite"
|
||||
serialization; see Codex issue #32086).
|
||||
|
||||
Returns ``(input, tools)``; both unchanged when no additional_tools item
|
||||
is present.
|
||||
"""
|
||||
if not isinstance(input, list):
|
||||
return input, tools
|
||||
found = False
|
||||
relocated: List[dict] = []
|
||||
kept_items = []
|
||||
for item in input:
|
||||
if isinstance(item, dict) and item.get("type") == "additional_tools":
|
||||
found = True
|
||||
relocated.extend(item.get("tools") or [])
|
||||
else:
|
||||
kept_items.append(item)
|
||||
if not relocated:
|
||||
if not found:
|
||||
return input, tools
|
||||
if not relocated:
|
||||
return kept_items, tools
|
||||
merged = list(tools) if tools is not None else []
|
||||
merged.extend(relocated)
|
||||
return kept_items, merged
|
||||
|
|
|
|||
|
|
@ -4976,3 +4976,14 @@ def test_relocate_input_additional_tools() -> None:
|
|||
# string input passes through
|
||||
s_input, s_tools = relocate_input_additional_tools(input="hello", tools=None)
|
||||
assert s_input == "hello" and s_tools is None
|
||||
|
||||
# follow-up Codex turns re-send the item with an EMPTY tools list — the
|
||||
# non-standard item must STILL be dropped (strict providers reject it),
|
||||
# with the tools param left untouched
|
||||
turn2_input = [
|
||||
{"role": "developer", "type": "additional_tools", "tools": []},
|
||||
{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "next"}]},
|
||||
]
|
||||
t2_input, t2_tools = relocate_input_additional_tools(input=turn2_input, tools=None)
|
||||
assert [i.get("type") for i in t2_input] == ["message"]
|
||||
assert t2_tools is None
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue