15. Stop Reasons & When to Loop
stop, toolUse, error, aborted — what each means.
The Anthropic API returns a stop_reason that tells you why the model stopped generating.
File: packages/ai/src/providers/anthropic.ts L934-954
function mapStopReason(reason: string): StopReason {
switch (reason) {
case "end_turn":
return "stop"; // Model finished naturally
case "max_tokens":
return "length"; // Hit token limit
case "tool_use":
return "toolUse"; // Wants to call tools
default:
throw new Error(`Unhandled: ${reason}`);
}
}
File: packages/ai/src/types.ts L192
export type StopReason = "stop" | "length" | "toolUse" | "error" | "aborted";
The loop decision:
| StopReason | Action |
|---|---|
"toolUse" | Execute tools, loop again |
"stop" | Model is done, break the loop |
"length" | Hit token limit, might need to continue |
"error" | Something went wrong, stop |
"aborted" | User cancelled, stop |
File: packages/agent/src/agent-loop.ts L194-198
if (message.stopReason === "error" || message.stopReason === "aborted") {
await emit({ type: "turn_end", message, toolResults: [] });
await emit({ type: "agent_end", messages: newMessages });
return; // Stop the loop
}
const toolCalls = message.content.filter((c) => c.type === "toolCall");
hasMoreToolCalls = toolCalls.length > 0; // Continue if tools requested