fix: Responses streaming tools don't concatenate None and str (#2326)

# What does this PR do?

This adds a check to ensure we don't attempt to concatenate `None + str`
or `str + None` when building up our arguments for streaming tool calls
in the Responses API.

## Test Plan

All existing tests pass with this change.

Unit tests:

```
python -m pytest -s -v \
  tests/unit/providers/agents/meta_reference/test_openai_responses.py
```

Integration tests:

```
llama stack run llama_stack/templates/together/run.yaml

LLAMA_STACK_CONFIG=http://localhost:8321 \
python -m pytest -s -v \
  tests/integration/agents/test_openai_responses.py \
  --text-model meta-llama/Llama-4-Scout-17B-16E-Instruct
```

Verification tests:

```
llama stack run llama_stack/templates/together/run.yaml

pytest -s -v 'tests/verifications/openai_api/test_responses.py' \
  --base-url=http://localhost:8321/v1/openai/v1 \
  --model meta-llama/Llama-4-Scout-17B-16E-Instruct
```

Additionally, the manual example using Codex CLI from #2325 now succeeds
instead of throwing a 500 error.

Closes #2325

Signed-off-by: Ben Browning <bbrownin@redhat.com>
This commit is contained in:
Ben Browning 2025-05-31 21:24:04 -04:00 committed by GitHub
parent f328436831
commit 277f8690ef
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -492,7 +492,12 @@ class OpenAIResponsesImpl:
for tool_call in chunk_choice.delta.tool_calls: for tool_call in chunk_choice.delta.tool_calls:
response_tool_call = chat_response_tool_calls.get(tool_call.index, None) response_tool_call = chat_response_tool_calls.get(tool_call.index, None)
if response_tool_call: if response_tool_call:
response_tool_call.function.arguments += tool_call.function.arguments # Don't attempt to concatenate arguments if we don't have any new arguments
if tool_call.function.arguments:
# Guard against an initial None argument before we concatenate
response_tool_call.function.arguments = (
response_tool_call.function.arguments or ""
) + tool_call.function.arguments
else: else:
tool_call_dict: dict[str, Any] = tool_call.model_dump() tool_call_dict: dict[str, Any] = tool_call.model_dump()
tool_call_dict.pop("type", None) tool_call_dict.pop("type", None)