fix(delegate): inherit parent fallback_chain in _build_child_agent

_build_child_agent constructed child AIAgents without passing
fallback_model, leaving _fallback_chain=[] for every subagent.
When a subagent hit a rate-limit or credential exhaustion the
runtime fallback check (run_agent.py:7486 / 12267) found an empty
chain and failed immediately — even though the parent agent was
configured with fallback_providers and would have recovered.

The cron scheduler already propagates fallback_model correctly
(scheduler.py:1038). Fix closes the parity gap by reading the
parent's _fallback_chain (the normalised list form accepted by
AIAgent's fallback_model parameter) and threading it through.

Empty chains coerce to None so AIAgent initialises _fallback_chain=[]
as usual rather than iterating an empty list.
This commit is contained in:
nftpoetrist 2026-05-03 11:35:12 +03:00 committed by Teknium
parent cb33c73418
commit 9faaa292b4
2 changed files with 54 additions and 0 deletions

View file

@ -1026,6 +1026,12 @@ def _build_child_agent(
except Exception as exc:
logger.debug("Could not load delegation reasoning_effort: %s", exc)
# Inherit the parent's fallback provider chain so subagents can recover
# from rate-limits and credential exhaustion exactly like the top-level
# agent does. _fallback_chain is a list accepted by AIAgent's
# fallback_model parameter (which handles both list and dict forms).
parent_fallback = getattr(parent_agent, "_fallback_chain", None) or None
child = AIAgent(
base_url=effective_base_url,
api_key=effective_api_key,
@ -1038,6 +1044,7 @@ def _build_child_agent(
max_tokens=getattr(parent_agent, "max_tokens", None),
reasoning_config=child_reasoning,
prefill_messages=getattr(parent_agent, "prefill_messages", None),
fallback_model=parent_fallback,
enabled_toolsets=child_toolsets,
quiet_mode=True,
ephemeral_system_prompt=child_prompt,