Basic Usage
Built-in Stop Conditions
stepCountIs(n)
Stop after a specific number of steps:hasToolCall(name)
Stop when a specific tool is called:maxTokensUsed(n)
Stop after using a certain number of tokens:maxCost(amount)
Stop after reaching a cost threshold:finishReasonIs(reason)
Stop on a specific finish reason:Combining Conditions
Pass an array to stop on any condition:Final Response After Stop
A stop condition can fire while the model is still emitting tool calls. By default, the SDK then executes those pending tool calls (so they have matching outputs) and makes one more model turn withtoolChoice: 'none',
appending a built-in final-answer directive (exported as
DEFAULT_FINAL_RESPONSE_DIRECTIVE) as a user message — so the run ends with
a real natural-language answer instead of a half-finished tool call. Tools
stay in the request; only calling is forbidden, which preserves the
prompt-cache prefix.
Tune it with allowFinalResponse:
Without the directive, models that emit tool-call syntax as text can leak
an unparsed tool call (e.g.
<tool_call>…) into the final content when
the loop stops mid-tool-call. The default directive exists to prevent
exactly that.Empty final output after tool rounds
Some mini-class models intermittently treat a successful tool call as the terminal answer, returning an emptyoutput array on the final turn. By
default, the SDK retries that follow-up once, and if it’s still empty,
resolves the run with empty text instead of throwing Invalid final response: empty or invalid output.
This tolerance only applies after at least one completed tool execution
round. Runs that produce no tool work still throw on an empty final
response.
Opt back into the strict contract with strictFinalResponse: true:
strictFinalResponse: true if your code depends on non-empty final
text and you’d rather see an error than an empty completion. Leave it off
(the default) to keep tool-terminal runs from being reported as failures.
Custom Stop Conditions
Create custom conditions with a function:StopConditionContext
Custom functions receive:StepResult
Each step contains:Advanced Patterns
Time-Based Stopping
Stop after a time limit:Content-Based Stopping
Stop based on response content:Quality-Based Stopping
Stop when results meet quality threshold:Combination with Early Exit
Combine conditions for complex logic:Migration from maxToolRounds
If you were usingmaxToolRounds, migrate to stopWhen:
Default Behavior
IfstopWhen is not specified, the loop runs until the model produces a
turn with no tool calls. Always pass an explicit stopWhen (e.g.
stepCountIs(n), maxCost(...)) to bound iterations, cost, or tokens.
Best Practices
Always Set Limits
Always include a hard limit to prevent runaway execution:Log Stop Reasons
Track why execution stopped:Test Conditions
Verify conditions work as expected:See Also
- Tools - Multi-turn orchestration
- Dynamic Parameters - Adaptive behavior
- nextTurnParams - Tool-driven modifications