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:
@@ -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,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user