fix(adapter): no perder tool_calls cuando DeepSeek cierra con finish_reason=stop

Sintoma (solo con el conector OpenAI): el agente anuncia la accion en texto
("Voy a crear los modulos…") y se PARA sin ejecutarla — 0 tools.

Causa: el stream del OpenAIAdapter solo emitia los tool_calls acumulados cuando
choice.finish_reason == "tool_calls". Pero DeepSeek (endpoint OpenAI) a veces
cierra el stream con finish_reason="stop" AUNQUE haya emitido tool_calls; en ese
caso caiamos en el branch else (end_turn) y los tool_calls acumulados se
descartaban. base.py solo ejecuta al recibir finish_reason="tool_use", asi que
nunca se ejecutaban. Con el adapter Claude (Anthropic) el finish_reason venia
distinto, por eso solo aparecia tras el cambio de conector.

Fix: disparar los tool_use SIEMPRE que haya tool_calls acumulados al cerrar el
stream, sea cual sea el finish_reason.

Validado: "crea un modulo…" ahora ejecuta acai_write + check_module y completa,
en vez de pararse tras anunciar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jordan Diaz
2026-06-05 17:55:40 +00:00
parent 96b4542918
commit d6b04e4122

View File

@@ -109,7 +109,13 @@ class OpenAIAdapter(ModelAdapter):
# Finish # Finish
if choice.finish_reason: if choice.finish_reason:
if choice.finish_reason == "tool_calls": # IMPORTANTE: DeepSeek (endpoint OpenAI) a veces cierra el stream
# con finish_reason="stop" AUNQUE haya emitido tool_calls. Si nos
# fiamos solo de =="tool_calls" perdemos esos tool calls: el agente
# anuncia la accion en texto y "se para" sin ejecutarla. Por eso
# disparamos los tool_use SIEMPRE que haya tool calls acumulados,
# sea cual sea el finish_reason.
if tool_calls_acc:
for acc in tool_calls_acc.values(): for acc in tool_calls_acc.values():
yield StreamChunk( yield StreamChunk(
tool_call_id=acc["id"], tool_call_id=acc["id"],
@@ -123,7 +129,7 @@ class OpenAIAdapter(ModelAdapter):
else: else:
yield StreamChunk( yield StreamChunk(
finish_reason="end_turn" finish_reason="end_turn"
if choice.finish_reason == "stop" if choice.finish_reason in ("stop", "tool_calls")
else choice.finish_reason, else choice.finish_reason,
usage=final_usage, usage=final_usage,
) )