symfonic.core.nodes.tool_selection¶
tool_selection ¶
Legacy-side wiring for the tool-selection capability (T3.1.2).
The react node used to compose the selection levers inline: ninety lines
that resolved a forced tool_choice, released it against history,
called the role palette resolver, and re-added the forced tool the
palette had just excluded. The levers are now stages in
:mod:symfonic.capabilities.tools; this module is the adapter that reads
them out of :class:BaseAgentDeps and states the order.
The order is the contract, so it lives here in one readable list:
forced_choiceโ decide what is forced, from the state stamp or the per-iteration resolver, releasing once history answers it.role_paletteโ narrow to the active role's palette. It runs after the force is known, which is what lets the pipeline's protection rule put a forced tool back rather than each consumer special-casing it.
Intent routing has already run upstream (the engine writes
state["resolved_tools"]), which is why it is not a stage here: the
react node receives its output, not its inputs. The stage exists and
narrow_tools_for_intent delegates to it.
select_tools_for_role
async
¶
Run the react node's selection pipeline for one iteration.
Returns the tools to bind and the tool_choice to bind them with.
Never raises: every stage failure degrades to "no policy" inside the
pipeline, because a selection preference must not be able to stall
the loop.