You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Manage the agentic inference loop lifecycle for the Responses API. Observes whether tool calls are present in the response, checks exit conditions, manages iteration state, and signals via filter_results whether to loop back for another inference round or exit to the client.
Does not classify tool calls by type or execute them — classification is handled by tool_parse; execution by sub-filters routed via branch chains.
Behavior
Read state.tool_calls from ResponsesState
If no tool calls → set action = "done", exit loop
Check exit conditions:
Response finish_reason == "length" / status == "incomplete" → exit as incomplete
Request-level max_tool_calls reached → exit as incomplete
Iteration limit reached (max_infer_iters) → exit as incomplete
If tool calls present and no exit condition:
Increment state.iteration
Reset tool_choice to "auto" after first iteration
Set action = "loop" to signal branch chain re-entry
Loop control via filter_results + branch chain re-entrance:
agentic_loop.action = "loop" — branch re-enters at responses_proxy
agentic_loop.action = "done" — exit loop
Branch Chain Re-entrance
The loop is driven by praxis-core's ReEnter rejoin mode (proposal #36, released). A branch chain on agentic_loop matches action = loop and rejoins at the named responses_proxy filter:
Two iteration limits serve complementary purposes:
max_infer_iters (filter config) — application-level cap that marks the response as incomplete when reached
max_iterations (branch chain) — infrastructure-level safety cap that prevents infinite loops; should be ≥ max_infer_iters
Architectural Decision
Renamed from tool_dispatch to agentic_loop to reflect its role as a pure loop controller. Classification (client vs server tool calls) and execution are intentionally excluded — those responsibilities belong to tool_parse and sub-filters routed via branch chains. This avoids duplication between the loop controller and the classify→route→execute pipeline.
Config
filter: agentic_loopmax_infer_iters: 10
Praxis trait methods
on_request — check tool calls, exit conditions, manage iteration state, set loop signal
Branch chains only evaluate on_result conditions during the request phase (after on_request), so all loop control must happen here. On the first pass, tool_calls is empty and the filter signals done. After stream_events/tool_parse populate tool_calls during response-body processing, the branch chain re-enters the pipeline and on_request runs again with populated tool calls.
Dependencies
ResponsesState in request extensions (created by openai_responses_validate for all Responses API create requests)
Purpose
Manage the agentic inference loop lifecycle for the Responses API. Observes whether tool calls are present in the response, checks exit conditions, manages iteration state, and signals via
filter_resultswhether to loop back for another inference round or exit to the client.Does not classify tool calls by type or execute them — classification is handled by
tool_parse; execution by sub-filters routed via branch chains.Behavior
state.tool_callsfromResponsesStateaction = "done", exit loopfinish_reason == "length"/status == "incomplete"→ exit as incompletemax_tool_callsreached → exit as incompletemax_infer_iters) → exit as incompletestate.iterationtool_choiceto"auto"after first iterationaction = "loop"to signal branch chain re-entryfilter_results+ branch chain re-entrance:agentic_loop.action = "loop"— branch re-enters atresponses_proxyagentic_loop.action = "done"— exit loopBranch Chain Re-entrance
The loop is driven by praxis-core's
ReEnterrejoin mode (proposal #36, released). A branch chain onagentic_loopmatchesaction = loopand rejoins at the namedresponses_proxyfilter:Two iteration limits serve complementary purposes:
max_infer_iters(filter config) — application-level cap that marks the response asincompletewhen reachedmax_iterations(branch chain) — infrastructure-level safety cap that prevents infinite loops; should be ≥max_infer_itersArchitectural Decision
Renamed from
tool_dispatchtoagentic_loopto reflect its role as a pure loop controller. Classification (client vs server tool calls) and execution are intentionally excluded — those responsibilities belong totool_parseand sub-filters routed via branch chains. This avoids duplication between the loop controller and the classify→route→execute pipeline.Config
Praxis trait methods
on_request— check tool calls, exit conditions, manage iteration state, set loop signalBranch chains only evaluate
on_resultconditions during the request phase (afteron_request), so all loop control must happen here. On the first pass,tool_callsis empty and the filter signals done. Afterstream_events/tool_parsepopulatetool_callsduring response-body processing, the branch chain re-enters the pipeline andon_requestruns again with populated tool calls.Dependencies
ResponsesStatein request extensions (created byopenai_responses_validatefor all Responses API create requests)tool_parsefor tool call classification (future)Reference