agent-zero/extensions/python/message_loop_result/_05_truncated_response.py
Alessandro 039efe4198 Keep model prose as thoughts and retry silently
Preserve free text and reasoning-only output in the current generation
and retry without intermediate warning rows. Require an explicit response
tool call to finish in both API modes, including after provider built-in
actions.

Keep history metadata, Responses state, tool validation and the
consecutive-failure stop intact. Allow core retries when Context Doctor
and its prompts are unavailable.

Validation: 411 backend tests and 2 Chromium live/replay grouping tests
passed; live runtime health check passed.
2026-11-01 06:50:49 +01:00

59 lines
2.2 KiB
Python

"""Retry model turns cut off by the output token limit with a specific warning."""
from __future__ import annotations
import json
from typing import Any
from helpers import extract_tools
from helpers.extension import Extension
from helpers.print_style import PrintStyle
class TruncatedResponse(Extension):
def execute(self, result_data: dict[str, Any] | None = None, **kwargs: Any) -> None:
if not self.agent or not isinstance(result_data, dict):
return
if result_data.get("skip_default_processing"):
return
llm_result = result_data.get("llm_result")
if not getattr(llm_result, "truncated", False):
return
function_calls = getattr(llm_result, "function_calls", None)
response = getattr(llm_result, "response", "")
if function_calls:
for call in function_calls:
arguments = call.raw.get("arguments")
if isinstance(arguments, str):
try:
arguments = json.loads(arguments)
except ValueError:
break
if not isinstance(arguments, dict):
break
else:
return
elif isinstance(response, str) and extract_tools.extract_tool_request(response):
return
elif (
isinstance(response, str) and not response.strip()
and getattr(llm_result, "reasoning", "").strip()
and not getattr(llm_result, "builtin_items", None)
):
return # Reasoning-only recovery preserves the emitted thoughts.
# Name truncation as the cause instead of the generic misformat warning.
warning = self.agent.read_prompt("fw.msg_output_limit.md")
warning_message = self.agent.hist_add_warning(message=warning)
notice = self.agent.read_prompt(
"fw.msg_output_limit_response.md",
finish_reason=getattr(llm_result, "finish_reason", ""),
)
PrintStyle(font_color="orange", padding=True).print(notice)
self.agent.context.log.log(
type="warning",
content=notice,
id=warning_message.id,
)
result_data["skip_default_processing"] = True