Fix no stream tool calls

This commit is contained in:
luijait 2025-05-23 17:43:19 +02:00
parent 394b0f400c
commit 64e75ae279
2 changed files with 38 additions and 67 deletions

View File

@ -744,80 +744,28 @@ def run_cai_cli(starting_agent, context_variables=None, max_turns=float('inf'),
# Use non-streamed response
response = asyncio.run(Runner.run(agent, conversation_input))
# Process the response items
# En modo no-streaming, procesamos SOLO los tool outputs de response.new_items
# Los tool calls (assistant messages) ya se añaden correctamente en openai_chatcompletions.py
for item in response.new_items:
# Handle tool call output items (tool results)
# Handle ONLY tool call output items (tool results)
if isinstance(item, ToolCallOutputItem):
# First, ensure there's a corresponding assistant message with tool_calls
# before adding the tool response to prevent the OpenAI error
assistant_with_tool_call_exists = False
tool_call_id = item.raw_item["call_id"]
for msg in message_history:
if (msg.get("role") == "assistant" and
msg.get("tool_calls") and
any(tc.get("id") == tool_call_id for tc in msg.get("tool_calls", []))):
assistant_with_tool_call_exists = True
break
# Verificar si ya existe este tool output en message_history para evitar duplicación
tool_msg_exists = any(
msg.get("role") == "tool" and msg.get("tool_call_id") == tool_call_id
for msg in message_history
)
# If no matching assistant message exists, create one first
if not assistant_with_tool_call_exists:
tool_call_msg = {
"role": "assistant",
"content": None,
"tool_calls": [{
"id": tool_call_id,
"type": "function",
"function": {
"name": "unknown_function",
"arguments": "{}"
}
}]
if not tool_msg_exists:
# Añadir solo el tool output al message_history
tool_msg = {
"role": "tool",
"tool_call_id": tool_call_id,
"content": item.output,
}
add_to_message_history(tool_call_msg)
# Now add the tool response
tool_msg = {
"role": "tool",
"tool_call_id": tool_call_id,
"content": item.output,
}
add_to_message_history(tool_msg)
add_to_message_history(tool_msg)
# Make sure that assistant messages with tool calls are also added to message_history
# This is especially important for non-streaming mode
if hasattr(agent, 'model'):
# Access the _Converter directly from the OpenAIChatCompletionsModel implementation
from cai.sdk.agents.models.openai_chatcompletions import _Converter
# Check if recent_tool_calls exists and process them
if hasattr(_Converter, 'recent_tool_calls'):
for call_id, call_info in _Converter.recent_tool_calls.items():
# Only process new tool calls that haven't been added to message history yet
tool_call_found = False
for msg in message_history:
if (msg.get("role") == "assistant" and
msg.get("tool_calls") and
any(tc.get("id") == call_id for tc in msg.get("tool_calls", []))):
tool_call_found = True
break
if not tool_call_found:
# Add the assistant message with the tool call
tool_call_msg = {
"role": "assistant",
"content": None,
"tool_calls": [{
"id": call_id,
"type": "function",
"function": {
"name": call_info.get('name', ''),
"arguments": call_info.get('arguments', '{}')
}
}]
}
add_to_message_history(tool_call_msg)
# Final validation to ensure message history follows OpenAI's requirements
# Ensure every tool message has a preceding assistant message with matching tool_call_id
from cai.util import fix_message_list

View File

@ -656,6 +656,29 @@ class OpenAIChatCompletionsModel(Model):
# Log the assistant message
self.logger.log_assistant_message(assistant_msg.content)
# En no-streaming, también necesitamos añadir cualquier tool output al message_history
# Esto se hace procesando los items de output del ModelResponse
items = _Converter.message_to_output_items(response.choices[0].message)
# Además, necesitamos añadir los tool outputs que se hayan generado
# durante la ejecución de las herramientas
if hasattr(_Converter, 'tool_outputs'):
for call_id, output_content in _Converter.tool_outputs.items():
# Verificar si ya existe un mensaje tool con este call_id en message_history
tool_msg_exists = any(
msg.get("role") == "tool" and msg.get("tool_call_id") == call_id
for msg in message_history
)
if not tool_msg_exists:
# Añadir el mensaje tool al message_history
tool_msg = {
"role": "tool",
"tool_call_id": call_id,
"content": output_content
}
add_to_message_history(tool_msg)
# Log the complete response for the session
self.logger.rec_training_data(
{