docs: expand tool runner documentation with internal mechanics #881
+73
−0
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.
How the Tool Runner Works
Iteration Lifecycle
On each iteration, the tool runner performs three key operations:
State update (only if unchanged): The tool runner appends the last message from the API response (the one yielded to the client) to its internal state only if the state wasn't modified during that iteration via
pushMessages()orsetMessagesParams(). If the state was mutated, it ignores that message and continues using the user-mutated state.Tool handling (always): The tool runner inspects the last message. If it contains any
tool_useblocks, it handles them and appends an appropriate message containing the correspondingtool_resultblocks — regardless of whether the state was mutated.Next request + repeat: It sends a new request to the API using the current internal state, yields the new message to the user, and repeats the loop.
generateToolResponse()
The
generateToolResponse()method is a helper that reads thetool_useblocks, calls the tools, and generates a message containing the correspondingtool_resultblocks. Note that:If you push both the last message and the result of
generateToolResponse()into the state, the tool runner will effectively do nothing except send the next request:Execution Flow Diagram
sequenceDiagram autonumber participant U as User participant TR as ToolRunner participant API as Model API participant Tools as Tools loop Repeat until done TR->>API: Send request (using current state) API-->>TR: Message TR-->>U: Yield message note over U: User can read message<br/>and optionally change state via<br/>pushMessages or setMessagesParams U->>TR: Resume iteration alt User did not change state TR->>TR: Append message to history else User changed state TR->>TR: Keep user state (no auto-append) end alt Message contains tool request TR->>Tools: Run tools (with generateToolResponse) Tools-->>TR: Tool results TR->>TR: Append tool results else No tool request TR->>TR: Finish end end