From c61a1465a8e1aca47fe18a94d58859ebc78fa2ff Mon Sep 17 00:00:00 2001 From: Jordan Diaz Date: Tue, 14 Apr 2026 21:31:14 +0000 Subject: [PATCH] Ajustes de max tokens --- src/orchestrator/agents/base.py | 39 +++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/orchestrator/agents/base.py b/src/orchestrator/agents/base.py index 235c22f..c8f051d 100644 --- a/src/orchestrator/agents/base.py +++ b/src/orchestrator/agents/base.py @@ -150,9 +150,23 @@ class BaseAgent: final_args = tool["arguments"] or chunk.tool_arguments or "" try: args = json.loads(final_args) if final_args else {} - except json.JSONDecodeError: - logger.warning("Failed to parse tool args: %s", final_args[:200]) + tool["parse_error"] = None + except json.JSONDecodeError as e: + # Args truncados o malformados — causa tipica: el modelo + # excedio max_tokens a mitad de la serializacion JSON + # del tool_use (ej. escribiendo un fichero grande). + logger.warning( + "Failed to parse tool args for %s (%d chars): %s... | err: %s", + tool.get("name", "?"), len(final_args), final_args[:200], str(e)[:100], + ) args = {} + # Guardamos el raw para poder generar un fingerprint distinto + # al de otros fallos y un mensaje util para el modelo. + tool["parse_error"] = { + "raw": final_args, + "raw_hash": hashlib.md5(final_args.encode()).hexdigest()[:8], + "message": str(e)[:200], + } tool["parsed_arguments"] = args tool_calls.append(tool) @@ -194,6 +208,27 @@ class BaseAgent: # Execute tool calls and add COMPLETE results to conversation duplicates_this_step = 0 for tc in tool_calls: + # Si los args no se pudieron parsear (p.ej. truncados por max_tokens), + # NO ejecutamos la tool. En su lugar devolvemos un mensaje al modelo + # explicando el problema para que pueda ajustar el siguiente intento + # (dividir el contenido, acortar, etc.). Fingerprint incluye el hash + # del raw para distinguir fallos distintos. + if tc.get("parse_error"): + pe = tc["parse_error"] + conversation.append({ + "role": "tool", + "tool_call_id": tc["id"], + "content": ( + f"[ERROR] No se pudieron parsear los argumentos del tool " + f"'{tc['name']}'. Los argumentos llegaron truncados o mal " + f"formados (probablemente excediste el limite de max_tokens " + f"al serializar el tool_use). Recibido {len(pe['raw'])} chars. " + f"Error: {pe['message']}. " + f"Reintenta dividiendo el contenido en varios tool calls mas " + f"pequenos o reduciendo el tamano del argumento 'content'." + ), + }) + continue fp_raw = f"{tc['name']}:{json.dumps(tc.get('parsed_arguments', {}), sort_keys=True)}" fp = hashlib.md5(fp_raw.encode()).hexdigest()