Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions astrbot/core/provider/sources/openai_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,14 @@ async def _query_stream(
state = ChatCompletionStreamState()

async for chunk in stream:
# Fix for #6661: Add missing 'index' field to tool_call deltas
# Gemini and some OpenAI-compatible proxies omit this field
if chunk.choices:
choice = chunk.choices[0]
if choice.delta and choice.delta.tool_calls:
for tc in choice.delta.tool_calls:
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Outdated
if not hasattr(tc, "index") or tc.index is None:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This condition can be written more concisely and safely using getattr.

Suggested change
if not hasattr(tc, "index") or tc.index is None:
if getattr(tc, "index", None) is None:

tc.index = 0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Hardcoding tc.index = 0 can lead to incorrect behavior if the streaming provider sends multiple tool calls concurrently without an index. All tool calls would be assigned to the same index, causing them to be merged incorrectly by ChatCompletionStreamState. This could result in lost tool calls or malformed arguments.

A more robust solution would be to assign a unique index to each tool call. This can be achieved by maintaining a state within _query_stream that maps tool call IDs to indices. When a new tool call ID is seen, assign it the next available index.

If you can confirm that the targeted OpenAI-compatible proxies will only ever stream one tool call at a time, then this fix is sufficient. Otherwise, I strongly recommend implementing the stateful indexing logic to prevent bugs with multiple tool calls.

try:
state.handle_chunk(chunk)
except Exception as e:
Expand Down