feat: Generate a fallback report upon recursion limit hit (#838)

* finish handle_recursion_limit_fallback

* fix

* renmae test file

* fix

* doc

---------

Co-authored-by: lxl0413 <lixinling2021@gmail.com>
This commit is contained in:
Xun
2026-01-26 21:10:18 +08:00
committed by GitHub
parent 9a34e32252
commit ee02b9f637
7 changed files with 895 additions and 12 deletions
+16
View File
@@ -0,0 +1,16 @@
---
CURRENT_TIME: {{ CURRENT_TIME }}
locale: {{ locale }}
---
You have reached the maximum number of reasoning steps.
Using ONLY the tool observations already produced,
write the final research report in EXACTLY the same format
as you would normally output at the end of this task.
Do not call any tools.
Do not add new information.
If something is missing, state it explicitly.
Always output in the locale of **{{ locale }}**.
+26 -5
View File
@@ -4,7 +4,6 @@
import dataclasses
import os
from datetime import datetime
from jinja2 import Environment, FileSystemLoader, TemplateNotFound, select_autoescape
from langchain.agents import AgentState
@@ -61,6 +60,28 @@ def apply_prompt_template(
Returns:
List of messages with the system prompt as the first message
"""
try:
system_prompt = get_system_prompt_template(prompt_name, state, configurable, locale)
return [{"role": "system", "content": system_prompt}] + state["messages"]
except Exception as e:
raise ValueError(f"Error applying template {prompt_name} for locale {locale}: {e}")
def get_system_prompt_template(
prompt_name: str, state: AgentState, configurable: Configuration = None, locale: str = "en-US"
) -> str:
"""
Render and return the system prompt template with state and configuration variables.
This function loads a Jinja2-based prompt template (with optional locale-specific
variants), applies variables from the agent state and Configuration object, and
returns the fully rendered system prompt string.
Args:
prompt_name: Name of the prompt template to load (without .md extension).
state: Current agent state containing variables available to the template.
configurable: Optional Configuration object providing additional template variables.
locale: Language locale for template selection (e.g., en-US, zh-CN).
Returns:
The rendered system prompt string after applying all template variables.
"""
# Convert state to dict for template rendering
state_vars = {
"CURRENT_TIME": datetime.now().strftime("%a %b %d %Y %H:%M:%S %z"),
@@ -74,15 +95,15 @@ def apply_prompt_template(
try:
# Normalize locale format
normalized_locale = locale.replace("-", "_") if locale and locale.strip() else "en_US"
# Try locale-specific template first
try:
template = env.get_template(f"{prompt_name}.{normalized_locale}.md")
except TemplateNotFound:
# Fallback to English template
template = env.get_template(f"{prompt_name}.md")
system_prompt = template.render(**state_vars)
return [{"role": "system", "content": system_prompt}] + state["messages"]
return system_prompt
except Exception as e:
raise ValueError(f"Error applying template {prompt_name} for locale {locale}: {e}")
raise ValueError(f"Error loading template {prompt_name} for locale {locale}: {e}")