Configure your agent changedagent-sdk/configuration
Nearest release: v2.1.280, published 12 hours after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 22 Sep 2026 03:07 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 20 Oct 2026 18:37 UTC.
Upstream edited
Recorded here
Lines+144added
Lines−154removed
From line
15
where the diff opens
First seen
15 Sep 2026
this site's first read of the page
Recorded edits5to this page, all time
The whole hunk
from line 15, old and new numbered
/
from line 15
1515* **`maxTurns` / `max_turns`**: caps the turn count
1616* **`cwd`**: sets the working directory
1717
18<CodeGroup>
19 ```typescript TypeScript theme={null}
20 import { query } from "@anthropic-ai/claude-agent-sdk";
18```typescript TypeScript theme={null}
19import { query } from "@anthropic-ai/claude-agent-sdk";
2120
22 for await (const message of query({
23 prompt: "Summarize the open TODOs in this repo",
24 options: {
25 model: "claude-sonnet-5",
26 allowedTools: ["Read", "Glob", "Grep"],
27 maxTurns: 8,
28 cwd: "/path/to/repo",
29 },
30 })) {
31 if (message.type === "result" && message.subtype === "success" && !message.is_error) {
32 console.log(message.result);
33 }
21for await (const message of query({
22 prompt: "Summarize the open TODOs in this repo",
23 options: {
24 model: "claude-sonnet-5",
25 allowedTools: ["Read", "Glob", "Grep"],
26 maxTurns: 8,
27 cwd: "/path/to/repo",
28 },
29})) {
30 if (message.type === "result" && message.subtype === "success" && !message.is_error) {
31 console.log(message.result);
3432 }
35 ```
33}
34```
3635
37 ```python Python theme={null}
38 import asyncio
36```python Python theme={null}
37import asyncio
3938
40 from claude_agent_sdk import ClaudeAgentOptions, ResultMessage, query
39from claude_agent_sdk import ClaudeAgentOptions, ResultMessage, query
4140
42 async def main():
43 options = ClaudeAgentOptions(
44 model="claude-sonnet-5",
45 allowed_tools=["Read", "Glob", "Grep"],
46 max_turns=8,
47 cwd="/path/to/repo",
48 )
41async def main():
42 options = ClaudeAgentOptions(
43 model="claude-sonnet-5",
44 allowed_tools=["Read", "Glob", "Grep"],
45 max_turns=8,
46 cwd="/path/to/repo",
47 )
4948
50 async for message in query(
51 prompt="Summarize the open TODOs in this repo",
52 options=options,
53 ):
54 if isinstance(message, ResultMessage) and not message.is_error:
55 print(message.result)
49 async for message in query(
50 prompt="Summarize the open TODOs in this repo",
51 options=options,
52 ):
53 if isinstance(message, ResultMessage) and not message.is_error:
54 print(message.result)
5655
57 asyncio.run(main())
58 ```
59</CodeGroup>
56asyncio.run(main())
57```
6058
6159Point `cwd` at one of your own projects and run the example. The summary of that project's open TODOs prints when the result message arrives.
6260
from line 79
8179
8280The examples below show a fallback list in TypeScript and a single fallback in Python:
8381
84<CodeGroup>
85 ```typescript TypeScript theme={null}
86 const options = {
87 model: "claude-fable-5",
88 fallbackModel: "claude-opus-5,claude-sonnet-5",
89 };
90 ```
82```typescript TypeScript theme={null}
83const options = {
84 model: "claude-fable-5",
85 fallbackModel: "claude-opus-5,claude-sonnet-5",
86};
87```
9188
92 ```python Python theme={null}
93 options = ClaudeAgentOptions(
94 model="claude-fable-5",
95 fallback_model="claude-opus-5",
96 )
97 ```
98</CodeGroup>
89```python Python theme={null}
90options = ClaudeAgentOptions(
91 model="claude-fable-5",
92 fallback_model="claude-opus-5",
93)
94```
9995
100<span id="sampling-parameters" />
96> [!NOTE]
97>
98> The [Messages API](https://platform.claude.com/docs/en/api/messages) request parameters `temperature`, `top_p`, and `max_tokens` have no fields on the options object in either language. Set the [effort level](/docs/en/agent-sdk/agent-loop#effort-level) or a [spend cap](#limit-turns-and-spend) instead, or call the Messages API when you need those parameters directly.
10199
102<Note>
103 The [Messages API](https://platform.claude.com/docs/en/api/messages) request parameters `temperature`, `top_p`, and `max_tokens` have no fields on the options object in either language. Set the [effort level](/docs/en/agent-sdk/agent-loop#effort-level) or a [spend cap](#limit-turns-and-spend) instead, or call the Messages API when you need those parameters directly.
104</Note>
105
106100## Set environment variables
107101
108102The `env` option sets environment variables for the Claude Code process that runs your session. Whether your values replace the inherited environment or merge over it differs by language:
from line 108
114108
115109The example routes API traffic through a gateway by setting `ANTHROPIC_BASE_URL`.
116110
117<CodeGroup>
118 ```typescript TypeScript theme={null}
119 const options = {
120 env: { ...process.env, ANTHROPIC_BASE_URL: "https://gateway.example.com" },
121 };
122 ```
111```typescript TypeScript theme={null}
112const options = {
113 env: { ...process.env, ANTHROPIC_BASE_URL: "https://gateway.example.com" },
114};
115```
123116
124 ```python Python theme={null}
125 options = ClaudeAgentOptions(
126 env={"ANTHROPIC_BASE_URL": "https://gateway.example.com"},
127 )
128 ```
129</CodeGroup>
117```python Python theme={null}
118options = ClaudeAgentOptions(
119 env={"ANTHROPIC_BASE_URL": "https://gateway.example.com"},
120)
121```
130122
131123The variables you pass can also configure Claude Code itself. For the variables the Claude Code process reads, see [Environment variables](/docs/en/env-vars). To tune API timeouts and stall detection this way, follow the Handle slow or stalled API responses section in the [TypeScript reference](/docs/en/agent-sdk/typescript#handle-slow-or-stalled-api-responses) or the [Python reference](/docs/en/agent-sdk/python#handle-slow-or-stalled-api-responses).
132124
from line 169
177169
178170The example below runs a two-turn session, changes the configuration between the turns, and prints the model that answered each turn. In TypeScript, the prompt stream holds the second message until the setters have run, and the second turn runs on the new model.
179171
180<CodeGroup>
181 ```typescript TypeScript theme={null}
182 import { query, type SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
172```typescript TypeScript theme={null}
173import { query, type SDKUserMessage } from "@anthropic-ai/claude-agent-sdk";
183174
184 function userMessage(text: string): SDKUserMessage {
185 return { type: "user", message: { role: "user", content: text }, parent_tool_use_id: null };
186 }
175function userMessage(text: string): SDKUserMessage {
176 return { type: "user", message: { role: "user", content: text }, parent_tool_use_id: null };
177}
187178
188 // Hold the second prompt until the setters have run.
189 let startSecondTurn!: () => void;
190 const secondTurnReady = new Promise<void>((resolve) => {
191 startSecondTurn = resolve;
192 });
179// Hold the second prompt until the setters have run.
180let startSecondTurn!: () => void;
181const secondTurnReady = new Promise<void>((resolve) => {
182 startSecondTurn = resolve;
183});
193184
194 async function* turnPrompts(): AsyncGenerator<SDKUserMessage, void> {
195 yield userMessage("Reply with exactly: ready");
196 await secondTurnReady;
197 yield userMessage("Reply with exactly: done");
198 }
185async function* turnPrompts(): AsyncGenerator<SDKUserMessage, void> {
186 yield userMessage("Reply with exactly: ready");
187 await secondTurnReady;
188 yield userMessage("Reply with exactly: done");
189}
199190
200 const session = query({
201 prompt: turnPrompts(),
202 options: {
203 model: "claude-sonnet-5",
204 },
205 });
191const session = query({
192 prompt: turnPrompts(),
193 options: {
194 model: "claude-sonnet-5",
195 },
196});
206197
207 let turnModel = "";
208 let completedTurns = 0;
198let turnModel = "";
199let completedTurns = 0;
209200
210 for await (const message of session) {
211 if (message.type === "assistant") {
212 turnModel = message.message.model;
213 } else if (message.type === "result") {
214 completedTurns += 1;
215 if (completedTurns === 1) {
216 console.log(`First turn model: ${turnModel}`);
217 await session.setModel("claude-opus-5");
218 await session.setPermissionMode("acceptEdits");
219 startSecondTurn();
220 } else {
221 console.log(`Second turn model: ${turnModel}`);
222 break;
223 }
201for await (const message of session) {
202 if (message.type === "assistant") {
203 turnModel = message.message.model;
204 } else if (message.type === "result") {
205 completedTurns += 1;
206 if (completedTurns === 1) {
207 console.log(`First turn model: ${turnModel}`);
208 await session.setModel("claude-opus-5");
209 await session.setPermissionMode("acceptEdits");
210 startSecondTurn();
211 } else {
212 console.log(`Second turn model: ${turnModel}`);
213 break;
224214 }
225215 }
226 ```
216}
217```
227218
228 ```python Python theme={null}
229 import asyncio
219```python Python theme={null}
220import asyncio
230221
231 from claude_agent_sdk import AssistantMessage, ClaudeAgentOptions, ClaudeSDKClient
222from claude_agent_sdk import AssistantMessage, ClaudeAgentOptions, ClaudeSDKClient
232223
233 async def main():
234 options = ClaudeAgentOptions(model="claude-sonnet-5")
224async def main():
225 options = ClaudeAgentOptions(model="claude-sonnet-5")
235226
236 async with ClaudeSDKClient(options=options) as client:
237 await client.query("Reply with exactly: ready")
238 first_model = ""
239 async for message in client.receive_response():
240 if isinstance(message, AssistantMessage):
241 first_model = message.model
227 async with ClaudeSDKClient(options=options) as client:
228 await client.query("Reply with exactly: ready")
229 first_model = ""
230 async for message in client.receive_response():
231 if isinstance(message, AssistantMessage):
232 first_model = message.model
242233
243 await client.set_model("claude-opus-5")
244 await client.set_permission_mode("acceptEdits")
234 await client.set_model("claude-opus-5")
235 await client.set_permission_mode("acceptEdits")
245236
246 await client.query("Reply with exactly: done")
247 second_model = ""
248 async for message in client.receive_response():
249 if isinstance(message, AssistantMessage):
250 second_model = message.model
237 await client.query("Reply with exactly: done")
238 second_model = ""
239 async for message in client.receive_response():
240 if isinstance(message, AssistantMessage):
241 second_model = message.model
251242
252 print(f"First turn model: {first_model}")
253 print(f"Second turn model: {second_model}")
243 print(f"First turn model: {first_model}")
244 print(f"Second turn model: {second_model}")
254245
255 asyncio.run(main())
256 ```
257</CodeGroup>
246asyncio.run(main())
247```
258248
259249On the Claude API, the program prints `First turn model: claude-sonnet-5`, then `Second turn model: claude-opus-5` after the switch.
260250
261<Note>
262 Each model has its own prompt cache, so after a mid-session switch the next request recomputes the full conversation uncached at the new model's rates. For more information, see [Switching models](/docs/en/prompt-caching#switching-models).
263</Note>
251> [!NOTE]
252>
253> Each model has its own prompt cache, so after a mid-session switch the next request recomputes the full conversation uncached at the new model's rates. For more information, see [Switching models](/docs/en/prompt-caching#switching-models).
264254
265255## Configure specific features
266256
No line in this hunk matches that.