chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,355 @@
|
||||
# Agent SDK — Python
|
||||
|
||||
The Claude Agent SDK provides a higher-level interface for building AI agents with built-in tools, safety features, and agentic capabilities.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install claude-agent-sdk
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
|
||||
|
||||
async def main():
|
||||
async for message in query(
|
||||
prompt="Explain this codebase",
|
||||
options=ClaudeAgentOptions(allowed_tools=["Read", "Glob", "Grep"])
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Built-in Tools
|
||||
|
||||
| Tool | Description |
|
||||
| --------- | ------------------------------------ |
|
||||
| Read | Read files in the workspace |
|
||||
| Write | Create new files |
|
||||
| Edit | Make precise edits to existing files |
|
||||
| Bash | Execute shell commands |
|
||||
| Glob | Find files by pattern |
|
||||
| Grep | Search files by content |
|
||||
| WebSearch | Search the web for information |
|
||||
| WebFetch | Fetch and analyze web pages |
|
||||
| AskUserQuestion | Ask user clarifying questions |
|
||||
| Agent | Spawn subagents |
|
||||
|
||||
---
|
||||
|
||||
## Primary Interfaces
|
||||
|
||||
### `query()` — Simple One-Shot Usage
|
||||
|
||||
The `query()` function is the simplest way to run an agent. It returns an async iterator of messages.
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
|
||||
|
||||
async for message in query(
|
||||
prompt="Explain this codebase",
|
||||
options=ClaudeAgentOptions(allowed_tools=["Read", "Glob", "Grep"])
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
```
|
||||
|
||||
### `ClaudeSDKClient` — Full Control
|
||||
|
||||
`ClaudeSDKClient` provides full control over the agent lifecycle. Use it when you need custom tools, hooks, streaming, or the ability to interrupt execution.
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions, AssistantMessage, TextBlock
|
||||
|
||||
async def main():
|
||||
options = ClaudeAgentOptions(allowed_tools=["Read", "Glob", "Grep"])
|
||||
async with ClaudeSDKClient(options=options) as client:
|
||||
await client.query("Explain this codebase")
|
||||
async for message in client.receive_response():
|
||||
if isinstance(message, AssistantMessage):
|
||||
for block in message.content:
|
||||
if isinstance(block, TextBlock):
|
||||
print(block.text)
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
|
||||
`ClaudeSDKClient` supports:
|
||||
|
||||
- **Context manager** (`async with`) for automatic resource cleanup
|
||||
- **`client.query(prompt)`** to send a prompt to the agent
|
||||
- **`receive_response()`** for streaming messages until completion
|
||||
- **`interrupt()`** to stop agent execution mid-task
|
||||
- **Required for custom tools** (via SDK MCP servers)
|
||||
|
||||
---
|
||||
|
||||
## Permission System
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
|
||||
|
||||
async for message in query(
|
||||
prompt="Refactor the authentication module",
|
||||
options=ClaudeAgentOptions(
|
||||
allowed_tools=["Read", "Edit", "Write"],
|
||||
permission_mode="acceptEdits" # Auto-accept file edits
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
```
|
||||
|
||||
Permission modes:
|
||||
|
||||
- `"default"`: Prompt for dangerous operations
|
||||
- `"plan"`: Planning only, no execution
|
||||
- `"acceptEdits"`: Auto-accept file edits
|
||||
- `"bypassPermissions"`: Skip all prompts (use with caution)
|
||||
|
||||
---
|
||||
|
||||
## MCP (Model Context Protocol) Support
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
|
||||
|
||||
async for message in query(
|
||||
prompt="Open example.com and describe what you see",
|
||||
options=ClaudeAgentOptions(
|
||||
mcp_servers={
|
||||
"playwright": {"command": "npx", "args": ["@playwright/mcp@latest"]}
|
||||
}
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Hooks
|
||||
|
||||
Customize agent behavior with hooks using callback functions:
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher, ResultMessage
|
||||
|
||||
async def log_file_change(input_data, tool_use_id, context):
|
||||
file_path = input_data.get('tool_input', {}).get('file_path', 'unknown')
|
||||
print(f"Modified: {file_path}")
|
||||
return {}
|
||||
|
||||
async for message in query(
|
||||
prompt="Refactor utils.py",
|
||||
options=ClaudeAgentOptions(
|
||||
permission_mode="acceptEdits",
|
||||
hooks={
|
||||
"PostToolUse": [HookMatcher(matcher="Edit|Write", hooks=[log_file_change])]
|
||||
}
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
```
|
||||
|
||||
Hook callback inputs for tool-lifecycle events (`PreToolUse`, `PostToolUse`, `PostToolUseFailure`) include `agent_id` and `agent_type` fields, allowing hooks to identify which agent (main or subagent) triggered the tool call.
|
||||
|
||||
Available hook events: `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `UserPromptSubmit`, `Stop`, `SubagentStop`, `PreCompact`, `Notification`, `SubagentStart`, `PermissionRequest`
|
||||
|
||||
---
|
||||
|
||||
## Common Options
|
||||
|
||||
`query()` takes a top-level `prompt` (string) and an `options` object (`ClaudeAgentOptions`):
|
||||
|
||||
```python
|
||||
async for message in query(prompt="...", options=ClaudeAgentOptions(...)):
|
||||
```
|
||||
|
||||
| Option | Type | Description |
|
||||
| ----------------------------------- | ------ | -------------------------------------------------------------------------- |
|
||||
| `cwd` | string | Working directory for file operations |
|
||||
| `allowed_tools` | list | Tools the agent can use (e.g., `["Read", "Edit", "Bash"]`) |
|
||||
| `tools` | list | Built-in tools to make available (restricts the default set) |
|
||||
| `disallowed_tools` | list | Tools to explicitly disallow |
|
||||
| `permission_mode` | string | How to handle permission prompts |
|
||||
| `mcp_servers` | dict | MCP servers to connect to |
|
||||
| `hooks` | dict | Hooks for customizing behavior |
|
||||
| `system_prompt` | string | Custom system prompt |
|
||||
| `max_turns` | int | Maximum agent turns before stopping |
|
||||
| `max_budget_usd` | float | Maximum budget in USD for the query |
|
||||
| `model` | string | Model ID (default: determined by CLI) |
|
||||
| `agents` | dict | Subagent definitions (`dict[str, AgentDefinition]`) |
|
||||
| `output_format` | dict | Structured output schema |
|
||||
| `thinking` | dict | Thinking/reasoning control |
|
||||
| `betas` | list | Beta features to enable (e.g., `["context-1m-2025-08-07"]`) |
|
||||
| `setting_sources` | list | Settings to load (e.g., `["project"]`). Default: none (no CLAUDE.md files) |
|
||||
| `env` | dict | Environment variables to set for the session |
|
||||
|
||||
---
|
||||
|
||||
## Message Types
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage, SystemMessage
|
||||
|
||||
async for message in query(
|
||||
prompt="Find TODO comments",
|
||||
options=ClaudeAgentOptions(allowed_tools=["Read", "Glob", "Grep"])
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
print(f"Stop reason: {message.stop_reason}") # e.g., "end_turn", "max_turns"
|
||||
elif isinstance(message, SystemMessage) and message.subtype == "init":
|
||||
session_id = message.data.get("session_id") # Capture for resuming later
|
||||
```
|
||||
|
||||
`AssistantMessage` includes per-turn `usage` data (a dict matching the Anthropic API usage shape) for tracking costs:
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage
|
||||
|
||||
async for message in query(prompt="...", options=ClaudeAgentOptions()):
|
||||
if isinstance(message, AssistantMessage) and message.usage:
|
||||
print(f"Input: {message.usage['input_tokens']}, Output: {message.usage['output_tokens']}")
|
||||
```
|
||||
|
||||
Typed task message subclasses are available for better type safety when handling subagent task events:
|
||||
- `TaskStartedMessage` — emitted when a subagent task is registered
|
||||
- `TaskProgressMessage` — real-time progress updates with cumulative usage metrics
|
||||
- `TaskNotificationMessage` — task completion notifications
|
||||
|
||||
`RateLimitEvent` is emitted when the rate limit status transitions (e.g., from `allowed` to `allowed_warning` or `rejected`). Use it to warn users or back off gracefully:
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, RateLimitEvent
|
||||
|
||||
async for message in query(prompt="...", options=ClaudeAgentOptions()):
|
||||
if isinstance(message, RateLimitEvent):
|
||||
print(f"Rate limit status: {message.rate_limit_info.status}")
|
||||
if message.rate_limit_info.resets_at:
|
||||
print(f"Resets at: {message.rate_limit_info.resets_at}")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Subagents
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition, ResultMessage
|
||||
|
||||
async for message in query(
|
||||
prompt="Use the code-reviewer agent to review this codebase",
|
||||
options=ClaudeAgentOptions(
|
||||
allowed_tools=["Read", "Glob", "Grep", "Agent"],
|
||||
agents={
|
||||
"code-reviewer": AgentDefinition(
|
||||
description="Expert code reviewer for quality and security reviews.",
|
||||
prompt="Analyze code quality and suggest improvements.",
|
||||
tools=["Read", "Glob", "Grep"]
|
||||
)
|
||||
}
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, CLINotFoundError, CLIConnectionError, ResultMessage
|
||||
|
||||
try:
|
||||
async for message in query(
|
||||
prompt="...",
|
||||
options=ClaudeAgentOptions(allowed_tools=["Read"])
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
except CLINotFoundError:
|
||||
print("Claude Code CLI not found. Install with: pip install claude-agent-sdk")
|
||||
except CLIConnectionError as e:
|
||||
print(f"Connection error: {e}")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Session History
|
||||
|
||||
Retrieve past session data with top-level functions:
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import list_sessions, get_session_messages
|
||||
|
||||
# List all past sessions (sync function — no await)
|
||||
sessions = list_sessions()
|
||||
for session in sessions:
|
||||
print(f"{session.session_id}: {session.cwd}")
|
||||
|
||||
# Get messages from a specific session (sync function — no await)
|
||||
messages = get_session_messages(session_id="...")
|
||||
for msg in messages:
|
||||
print(msg)
|
||||
```
|
||||
|
||||
### Session Mutations
|
||||
|
||||
Rename or tag sessions (sync functions — no await):
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import rename_session, tag_session
|
||||
|
||||
# Rename a session
|
||||
rename_session(session_id="...", title="My refactoring session")
|
||||
|
||||
# Tag a session (tags are Unicode-sanitized automatically)
|
||||
tag_session(session_id="...", tag="experiment")
|
||||
|
||||
# Clear a tag
|
||||
tag_session(session_id="...", tag=None)
|
||||
|
||||
# Optionally scope to a specific project directory
|
||||
rename_session(session_id="...", title="New title", directory="/path/to/project")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MCP Server Management
|
||||
|
||||
Manage MCP servers at runtime using `ClaudeSDKClient`:
|
||||
|
||||
```python
|
||||
async with ClaudeSDKClient(options=options) as client:
|
||||
# Reconnect a disconnected MCP server
|
||||
await client.reconnect_mcp_server("my-server")
|
||||
|
||||
# Toggle an MCP server on/off
|
||||
await client.toggle_mcp_server("my-server", enabled=False)
|
||||
|
||||
# Get status of all MCP servers
|
||||
status = await client.get_mcp_status() # returns McpStatusResponse
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always specify allowed_tools** — Explicitly list which tools the agent can use
|
||||
2. **Set working directory** — Always specify `cwd` for file operations
|
||||
3. **Use appropriate permission modes** — Start with `"default"` and only escalate when needed
|
||||
4. **Handle all message types** — Check for `ResultMessage` to get agent output
|
||||
5. **Limit max_turns** — Prevent runaway agents with reasonable limits
|
||||
@@ -0,0 +1,359 @@
|
||||
# Agent SDK Patterns — Python
|
||||
|
||||
## Basic Agent
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
|
||||
|
||||
async def main():
|
||||
async for message in query(
|
||||
prompt="Explain what this repository does",
|
||||
options=ClaudeAgentOptions(
|
||||
cwd="/path/to/project",
|
||||
allowed_tools=["Read", "Glob", "Grep"]
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Custom Tools
|
||||
|
||||
Custom tools require an MCP server. Use `ClaudeSDKClient` for full control (custom SDK MCP tools require `ClaudeSDKClient` — `query()` only supports external stdio/http MCP servers).
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from claude_agent_sdk import (
|
||||
tool,
|
||||
create_sdk_mcp_server,
|
||||
ClaudeSDKClient,
|
||||
ClaudeAgentOptions,
|
||||
AssistantMessage,
|
||||
TextBlock,
|
||||
)
|
||||
|
||||
@tool("get_weather", "Get the current weather for a location", {"location": str})
|
||||
async def get_weather(args):
|
||||
location = args["location"]
|
||||
return {"content": [{"type": "text", "text": f"The weather in {location} is sunny and 72°F."}]}
|
||||
|
||||
server = create_sdk_mcp_server("weather-tools", tools=[get_weather])
|
||||
|
||||
async def main():
|
||||
options = ClaudeAgentOptions(mcp_servers={"weather": server})
|
||||
async with ClaudeSDKClient(options=options) as client:
|
||||
await client.query("What's the weather in Paris?")
|
||||
async for message in client.receive_response():
|
||||
if isinstance(message, AssistantMessage):
|
||||
for block in message.content:
|
||||
if isinstance(block, TextBlock):
|
||||
print(block.text)
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Hooks
|
||||
|
||||
### After Tool Use Hook
|
||||
|
||||
Log file changes after any edit:
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from datetime import datetime
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher, ResultMessage
|
||||
|
||||
async def log_file_change(input_data, tool_use_id, context):
|
||||
file_path = input_data.get('tool_input', {}).get('file_path', 'unknown')
|
||||
with open('./audit.log', 'a') as f:
|
||||
f.write(f"{datetime.now()}: modified {file_path}\n")
|
||||
return {}
|
||||
|
||||
async def main():
|
||||
async for message in query(
|
||||
prompt="Refactor utils.py to improve readability",
|
||||
options=ClaudeAgentOptions(
|
||||
allowed_tools=["Read", "Edit", "Write"],
|
||||
permission_mode="acceptEdits",
|
||||
hooks={
|
||||
"PostToolUse": [HookMatcher(matcher="Edit|Write", hooks=[log_file_change])]
|
||||
}
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Subagents
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition, ResultMessage
|
||||
|
||||
async def main():
|
||||
async for message in query(
|
||||
prompt="Use the code-reviewer agent to review this codebase",
|
||||
options=ClaudeAgentOptions(
|
||||
allowed_tools=["Read", "Glob", "Grep", "Agent"],
|
||||
agents={
|
||||
"code-reviewer": AgentDefinition(
|
||||
description="Expert code reviewer for quality and security reviews.",
|
||||
prompt="Analyze code quality and suggest improvements.",
|
||||
tools=["Read", "Glob", "Grep"]
|
||||
)
|
||||
}
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MCP Server Integration
|
||||
|
||||
### Browser Automation (Playwright)
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
|
||||
|
||||
async def main():
|
||||
async for message in query(
|
||||
prompt="Open example.com and describe what you see",
|
||||
options=ClaudeAgentOptions(
|
||||
mcp_servers={
|
||||
"playwright": {"command": "npx", "args": ["@playwright/mcp@latest"]}
|
||||
}
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
|
||||
### Database Access (PostgreSQL)
|
||||
|
||||
```python
|
||||
import os
|
||||
import anyio
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
|
||||
|
||||
async def main():
|
||||
async for message in query(
|
||||
prompt="Show me the top 10 users by order count",
|
||||
options=ClaudeAgentOptions(
|
||||
mcp_servers={
|
||||
"postgres": {
|
||||
"command": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-postgres"],
|
||||
"env": {"DATABASE_URL": os.environ["DATABASE_URL"]}
|
||||
}
|
||||
}
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Permission Modes
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions
|
||||
|
||||
async def main():
|
||||
# Default: prompt for dangerous operations
|
||||
async for message in query(
|
||||
prompt="Delete all test files",
|
||||
options=ClaudeAgentOptions(
|
||||
allowed_tools=["Bash"],
|
||||
permission_mode="default" # Will prompt before deleting
|
||||
)
|
||||
):
|
||||
pass
|
||||
|
||||
# Plan: agent creates a plan before making changes
|
||||
async for message in query(
|
||||
prompt="Refactor the auth system",
|
||||
options=ClaudeAgentOptions(
|
||||
allowed_tools=["Read", "Edit"],
|
||||
permission_mode="plan"
|
||||
)
|
||||
):
|
||||
pass
|
||||
|
||||
# Accept edits: auto-accept file edits
|
||||
async for message in query(
|
||||
prompt="Refactor this module",
|
||||
options=ClaudeAgentOptions(
|
||||
allowed_tools=["Read", "Edit"],
|
||||
permission_mode="acceptEdits"
|
||||
)
|
||||
):
|
||||
pass
|
||||
|
||||
# Bypass: skip all prompts (use with caution)
|
||||
async for message in query(
|
||||
prompt="Set up the development environment",
|
||||
options=ClaudeAgentOptions(
|
||||
allowed_tools=["Bash", "Write"],
|
||||
permission_mode="bypassPermissions"
|
||||
)
|
||||
):
|
||||
pass
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Recovery
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from claude_agent_sdk import (
|
||||
query,
|
||||
ClaudeAgentOptions,
|
||||
CLINotFoundError,
|
||||
CLIConnectionError,
|
||||
ProcessError,
|
||||
ResultMessage,
|
||||
)
|
||||
|
||||
async def run_with_recovery():
|
||||
try:
|
||||
async for message in query(
|
||||
prompt="Fix the failing tests",
|
||||
options=ClaudeAgentOptions(
|
||||
allowed_tools=["Read", "Edit", "Bash"],
|
||||
max_turns=10
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
except CLINotFoundError:
|
||||
print("Claude Code CLI not found. Install with: pip install claude-agent-sdk")
|
||||
except CLIConnectionError as e:
|
||||
print(f"Connection error: {e}")
|
||||
except ProcessError as e:
|
||||
print(f"Process error: {e}")
|
||||
|
||||
anyio.run(run_with_recovery)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Session Resumption
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage, SystemMessage
|
||||
|
||||
async def main():
|
||||
session_id = None
|
||||
|
||||
# First query: capture the session ID
|
||||
async for message in query(
|
||||
prompt="Read the authentication module",
|
||||
options=ClaudeAgentOptions(allowed_tools=["Read", "Glob"])
|
||||
):
|
||||
if isinstance(message, SystemMessage) and message.subtype == "init":
|
||||
session_id = message.data.get("session_id")
|
||||
|
||||
# Resume with full context from the first query
|
||||
async for message in query(
|
||||
prompt="Now find all places that call it", # "it" = auth module
|
||||
options=ClaudeAgentOptions(resume=session_id)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Session History
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import list_sessions, get_session_messages
|
||||
|
||||
# List past sessions (sync function — no await)
|
||||
sessions = list_sessions()
|
||||
for session in sessions:
|
||||
print(f"Session {session.session_id} in {session.cwd}")
|
||||
|
||||
# Retrieve messages from the most recent session (sync function — no await)
|
||||
if sessions:
|
||||
messages = get_session_messages(session_id=sessions[0].session_id)
|
||||
for msg in messages:
|
||||
print(msg)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Session Mutations
|
||||
|
||||
```python
|
||||
from claude_agent_sdk import rename_session, tag_session
|
||||
|
||||
session_id = "your-session-id"
|
||||
|
||||
# Rename a session
|
||||
rename_session(session_id=session_id, title="Refactoring auth module")
|
||||
|
||||
# Tag a session for filtering
|
||||
tag_session(session_id=session_id, tag="experiment-v2")
|
||||
|
||||
# Clear a tag
|
||||
tag_session(session_id=session_id, tag=None)
|
||||
|
||||
# Scope to a specific project directory
|
||||
rename_session(session_id=session_id, title="New title", directory="/path/to/project")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Custom System Prompt
|
||||
|
||||
```python
|
||||
import anyio
|
||||
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
|
||||
|
||||
async def main():
|
||||
async for message in query(
|
||||
prompt="Review this code",
|
||||
options=ClaudeAgentOptions(
|
||||
allowed_tools=["Read", "Glob", "Grep"],
|
||||
system_prompt="""You are a senior code reviewer focused on:
|
||||
1. Security vulnerabilities
|
||||
2. Performance issues
|
||||
3. Code maintainability
|
||||
|
||||
Always provide specific line numbers and suggestions for improvement."""
|
||||
)
|
||||
):
|
||||
if isinstance(message, ResultMessage):
|
||||
print(message.result)
|
||||
|
||||
anyio.run(main)
|
||||
```
|
||||
Reference in New Issue
Block a user