Skip to main content

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:
Execution stops when any condition is met.

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 with toolChoice: '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.
The final turn only happens when a stop condition halted the loop while the last response contained executable tool calls. It never fires on natural completion, HITL/approval pauses, or interruption.

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 using maxToolRounds, migrate to stopWhen:

Default Behavior

If stopWhen 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