fix(langgraph): pass the recursion limit of the flow run on to AgentNode agents - #261
Open
fede-kamel wants to merge 1 commit into
Open
fix(langgraph): pass the recursion limit of the flow run on to AgentNode agents#261fede-kamel wants to merge 1 commit into
fede-kamel wants to merge 1 commit into
Conversation
…ode agents create_agent binds recursion_limit=9999 to the agents it compiles. The AgentNodeExecutor invoked that agent with the loader config only, so the limit configured for the enclosing flow run never applied to the nested agent: an agent that did not terminate made thousands of model calls before failing (5000 calls with a fake model in the new test on the previous code), whatever recursion_limit the caller had set. The executor now reads the config of the current run and passes on a recursion limit that was explicitly configured (any value other than LangChain's default of 25). A recursion limit set in the loader config still takes precedence, and runs using the default limit keep the agent's own limit so tool-heavy agents are not cut at 25 steps. Investigation notes for oracle#227: the non-termination itself comes from create_agent's structured-output loop (ToolStrategy with no tools routes back to the model until a structured response exists), which the adapter enables for any agent with outputs; the CTS deterministic LLM server answers in prose, so such agents loop until the recursion limit. Open PR oracle#210 addresses that part. Signed-off-by: Federico Kamelhar <federico.kamelhar@oracle.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Relates to #227.
Root cause
Two things combine in the CTS failures reported in #227:
response_format=ToolStrategy(...)for any agent with declared outputs. With no tools, LangChain'screate_agentroutes from the model back to the model until astructured_responseexists, so a model that answers in prose (the CTS deterministic LLM server, or any provider ignoring the structured-output tool) loops untilGraphRecursionError. Reproduced deterministically with a fake chat model (agent with outputs and no tools: recursion error after 12 model calls; same agent without outputs: terminates in 2 calls). Open PR feat(adapters/langgraph): make agent structured output not hang or silently vanish #210 addresses this part and, applied locally, makes the CTS case terminate in 2 calls.create_agentbindsrecursion_limit=9999to the agents it compiles, andAgentNodeExecutorinvoked the nested agent with the loader config only. The limit configured for the enclosing flow run therefore never applied inside anAgentNode: withrecursion_limit=12on the flow run, a non-terminating nested agent made 9999 model calls before failing.Changes
langgraph/_node_execution.py:AgentNodeExecutorreads the config of the current run and passes an explicitly configured recursion limit (any value other than LangChain's default of 25) on to the nested agent. A limit set in the loader config still takes precedence, and runs using the default limit keep the agent's own limit so tool-heavy agents are not cut at 25 steps.tests/adapters/langgraph/flows/test_agentnode_recursion_limit.py: sync and async runs withrecursion_limit=6stop the nested agent after 3 model calls (5000 calls onmainbefore the test was capped), the loader config wins over the run config, and a run with the default limit keeps the agent's limit. Fake chat model, no LLM calls.Verification
SKIP_LLM_TESTS=1 pytest tests/adapters/langgraph: 113 passed, 89 skipped.tests/run_tests.sh) reproduced locally on Python 3.10 through 3.14.Notes for reviewers
KeyError: 'name'of LangGraph client-tool confirmation interrupt raises KeyError: 'name' #223; a proposed patch is posted on that issue.