The whole hunk
from line 17, old and new numbered
/
lines
from line 17
1717<img src="https://mintcdn.com/claude-code/_xqph1dUOslCOwsj/images/agent-loop-diagram-dark.svg?fit=max&auto=format&n=_xqph1dUOslCOwsj&q=85&s=afe723c52a324d3c61fa72fb02432ab6" className="hidden dark:block" alt="Diagram of the agent loop: your prompt enters the agentic loop, where Claude evaluates and either requests tool calls, whose results feed back into another evaluation, or returns the final answer" width="720" height="212" data-path="images/agent-loop-diagram-dark.svg" />
1818
19191. **Receive prompt.** Claude receives your prompt, along with the system prompt, tool definitions, and conversation history. The SDK yields a [`SystemMessage`](#message-types) with subtype `"init"` containing session metadata.
202. **Evaluate and respond.** Claude evaluates the current state and determines how to proceed. It may respond with text, request one or more tool calls, or both. The SDK yields an [`AssistantMessage`](#message-types) containing the text and any tool call requests.
202. **Evaluate and respond.** Claude evaluates the current state and determines how to proceed. It may respond with text, request one or more tool calls, or both. The SDK yields one or more [`AssistantMessage`](#message-types) objects, one for each content block, such as a text block or a tool call request.
21213. **Execute tools.** The SDK runs each requested tool and collects the results. Each set of tool results feeds back to Claude for the next decision. You can use [hooks](/docs/en/agent-sdk/hooks) to intercept, modify, or block tool calls before they run.
22224. **Repeat.** Steps 2 and 3 repeat as a cycle. Each full cycle is one turn. Claude continues calling tools and processing results until it produces a response with no tool calls.
23235. **Return result.** The SDK yields a final [`AssistantMessage`](#message-types) with the text response (no tool calls), followed by a [`ResultMessage`](#message-types) with the final text, token usage, cost, and session ID.
from line 33
3333First, the SDK sends your prompt to Claude and yields a [`SystemMessage`](#message-types) with the session metadata. Then the loop begins:
3434
35351. **Turn 1:** Claude calls `Bash` to run `npm test`. The SDK yields an [`AssistantMessage`](#message-types) with the tool call, executes the command, then yields a [`UserMessage`](#message-types) with the output (three failures).
362. **Turn 2:** Claude calls `Read` on `auth.ts` and `auth.test.ts`. The SDK returns the file contents and yields an `AssistantMessage`.
373. **Turn 3:** Claude calls `Edit` to fix `auth.ts`, then calls `Bash` to re-run `npm test`. All three tests pass. The SDK yields an `AssistantMessage`.
362. **Turn 2:** Claude calls `Read` on `auth.ts` and `auth.test.ts`. The SDK yields an `AssistantMessage` for each call and returns the file contents.
373. **Turn 3:** Claude calls `Edit` to fix `auth.ts`, then calls `Bash` to re-run `npm test`. All three tests pass. The SDK yields an `AssistantMessage` for each call.
38384. **Final turn:** Claude produces a text-only response with no tool calls: "Fixed the auth bug, all three tests pass now." The SDK yields a final `AssistantMessage` with this text, then a [`ResultMessage`](#message-types) with the same text plus cost and usage.
3939
4040That was four turns: three with tool calls, one final text-only response.
from line 55
5555 * `"worker_shutting_down"`: the loop will end after the current turn because the host is exiting or Remote Control disconnected
5656
5757 In TypeScript, each subtype other than `"init"` is its own type in the [`SDKMessage` union](/docs/en/agent-sdk/typescript#sdkmessage) rather than a subtype of `SDKSystemMessage`.
58* **`AssistantMessage`:** emitted after each Claude response, including the final text-only one. Contains text content blocks and tool call blocks from that turn.
58* **`AssistantMessage`:** emitted for each content block in Claude's responses, including the final text-only one. Each carries a single content block, such as text or a tool call, and the messages from one response share a message ID.
5959* **`UserMessage`:** emitted after each tool execution with the tool result content sent back to Claude. Also emitted for any user inputs you stream mid-loop.
6060* **`StreamEvent`:** only emitted when partial messages are enabled. Contains raw API streaming events (text deltas, tool input chunks). See [Stream responses](/docs/en/agent-sdk/streaming-output).
6161* **`ResultMessage`:** marks the end of the agent loop. Contains the final text result, token usage, cost, and session ID. Check the `subtype` field to determine whether the task succeeded or hit a limit. A small number of trailing system events, such as `prompt_suggestion`, can arrive after it, so iterate the stream to completion rather than breaking on the result. See [Handle the result](#handle-the-result).
from line 79
7979 <CodeGroup>
8080 ```python Python theme={null}
8181 import asyncio
82 from claude_agent_sdk import query, AssistantMessage, ResultMessage
82 from claude_agent_sdk import query, AssistantMessage, ResultMessage, TextBlock, ToolUseBlock
8383
8484
8585 async def main():
from line 86
8686 try:
8787 async for message in query(prompt="Summarize this project"):
8888 if isinstance(message, AssistantMessage):
89 print(f"Turn completed: {len(message.content)} content blocks")
89 # Each AssistantMessage carries one content block
90 for block in message.content:
91 if isinstance(block, TextBlock):
92 print(f"Claude: {block.text}")
93 elif isinstance(block, ToolUseBlock):
94 print(f"Tool call: {block.name}")
9095 if isinstance(message, ResultMessage):
9196 if message.subtype == "success":
9297 print(message.result)
from line 113
108113 try {
109114 for await (const message of query({ prompt: "Summarize this project" })) {
110115 if (message.type === "assistant") {
111 console.log(`Turn completed: ${message.message.content.length} content blocks`);
116 // Each assistant message carries one content block
117 for (const block of message.message.content) {
118 if (block.type === "text") {
119 console.log(`Claude: ${block.text}`);
120 } else if (block.type === "tool_use") {
121 console.log(`Tool call: ${block.name}`);
122 }
123 }
112124 }
113125 if (message.type === "result") {
114126 if (message.subtype === "success") {