A tool is offered but never runs
The model calls a tool and the loop stops instead of executing it.
Symptom
The result comes back with a toolCall in toolCalls but no matching entry in
toolResults, and the loop ended.
Why it happens
The tool has no executor. A Tool built without an execute closure is a
client-side tool by design: the SDK surfaces the call and expects your app to
run it and post the result back. hasExecutor is false for these.
Provider-defined tools behave the same way from the loop's side, since they run on the provider rather than locally.
Fix
If the tool was meant to run locally, give it an execute closure. If it is
genuinely client-side, handle the call in your UI and send a result back before
resuming, then check with
lastAssistantMessageIsCompleteWithToolCalls.