Replace heredoc with echo statements to fix YAML parsing issue. The
unindented heredoc content was breaking out of the literal block scalar,
causing `---` to be interpreted as a YAML document separator.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.18 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.18
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.18
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.18/
- Bundled CLI version: 2.0.72
- Install with: `pip install claude-agent-sdk==0.1.18`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Add `Dockerfile.test`: Python 3.12 image with Claude Code CLI
installed
- Add `scripts/test-docker.sh`: Local script to run tests in Docker
- Add `test-e2e-docker` job to CI workflow that runs the full e2e suite
in a container
- Add `.dockerignore` to speed up Docker builds
## Context
This helps catch Docker-specific issues like #406 where filesystem-based
agents loaded via `setting_sources=["project"]` may silently fail in
Docker environments.
## Local Usage
```bash
# Run unit tests in Docker (no API key needed)
./scripts/test-docker.sh unit
# Run e2e tests in Docker
ANTHROPIC_API_KEY=sk-... ./scripts/test-docker.sh e2e
# Run all tests
ANTHROPIC_API_KEY=sk-... ./scripts/test-docker.sh all
```
## Test plan
- [x] Unit tests pass in Docker locally (129 passed)
- [ ] CI job runs successfully
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Replace auto-generated release notes with content extracted from
CHANGELOG.md for the specific version being released. This provides more
structured and consistent release notes with proper sections like Bug
Fixes, New Features, etc.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.17 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.17
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.17
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.17/
- Bundled CLI version: 2.0.70
- Install with: `pip install claude-agent-sdk==0.1.17`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.16 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.16
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.16
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.16/
- Bundled CLI version: 2.0.68
- Install with: `pip install claude-agent-sdk==0.1.16`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Fixes#401
Enables applications to detect API errors (especially `rate_limit`
errors) by properly parsing the `error` field in `AssistantMessage`.
## Problem
The SDK defines `AssistantMessage.error` (including `"rate_limit"`), but
the message parser never extracted this field from the CLI response.
This made it impossible for applications to:
- Detect when rate limits are hit
- Implement retry logic
- Handle other API errors gracefully
## Solution
Added error field extraction in the message parser:
```python
return AssistantMessage(
content=content_blocks,
model=data["message"]["model"],
parent_tool_use_id=data.get("parent_tool_use_id"),
error=data["message"].get("error"), # ← Now extracts error field
)
```
## Changes
**Modified: `src/claude_agent_sdk/_internal/message_parser.py`**
The parser now extracts the `error` field from API responses and
populates it in the `AssistantMessage` object.
## Usage Example
Applications can now detect and handle rate limits:
```python
async for message in client.receive_response():
if isinstance(message, AssistantMessage):
if message.error == "rate_limit":
print("Rate limit hit! Implementing backoff...")
await asyncio.sleep(60)
# Retry logic here
elif message.error:
print(f"API error: {message.error}")
```
## Testing
- ✅ Passed ruff linting and formatting
- ✅ Passed mypy type checking
- ✅ All existing tests pass
## Type of Change
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
## Impact
This fix enables production applications to:
- Implement proper error handling for API errors
- Build robust retry logic for rate limits
- Provide better user feedback when errors occur
- Avoid silent failures when the API returns errors
---
🤖 Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
This PR updates the version to 0.1.15 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.15
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.15
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.15/
- Bundled CLI version: 2.0.62
- Install with: `pip install claude-agent-sdk==0.1.15`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Add `enable_file_checkpointing` option to `ClaudeAgentOptions`
- Add `rewind_files(user_message_id)` method to `ClaudeSDKClient` and
`Query`
- Add `SDKControlRewindFilesRequest` type for the control protocol
- Set `CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING` env var when enabled
This adds Python SDK support for the file rewind feature from
claude-cli-internal PR #11265.
## Test plan
- [x] Verified imports work correctly
- [x] Verified linting passes (`ruff check`)
- [x] Verified existing tests still pass (106 passed, pre-existing
failures unrelated to this change)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
This PR updates the version to 0.1.14 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.14
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.14
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.14/
- Bundled CLI version: 2.0.62
- Install with: `pip install claude-agent-sdk==0.1.14`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
The fetch-depth: 0 was on build-wheels but changelog generation happens
in the publish job. Moved it to the correct location and upgraded the
model for better changelog generation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.13 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.13
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.13
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.13/
- Bundled CLI version: 2.0.59
- Install with: `pip install claude-agent-sdk==0.1.13`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
When the CLI exits with an error (e.g., invalid session ID passed to
`--resume`), signal all pending control requests immediately instead of
waiting for the 60-second timeout.
**The fix adds 4 lines** to the exception handler in `_read_messages`:
```python
# Signal all pending control requests so they fail fast instead of timing out
for request_id, event in list(self.pending_control_responses.items()):
if request_id not in self.pending_control_results:
self.pending_control_results[request_id] = e
event.set()
```
## Problem
When the CLI exits with an error, the SDK's message reader catches it
but doesn't notify pending control requests. This causes `initialize()`
to wait for the full 60-second timeout even though the error is known
within seconds.
Example scenario:
1. User passes invalid session ID via
`ClaudeAgentOptions(resume="invalid-id")`
2. CLI prints `No conversation found with session ID: xxx` and exits
with code 1
3. SDK message reader catches the error after ~3 seconds
4. But `initialize()` keeps waiting for 60 seconds before timing out
## Solution
The existing code at `_send_control_request` lines 361-362 already
handles exceptions in results:
```python
if isinstance(result, Exception):
raise result
```
The fix simply signals all pending control events when an error occurs,
allowing them to fail fast with the actual error instead of timing out.
## Test Plan
- [ ] Test with invalid session ID - should fail fast (~3s) instead of
timing out (60s)
- [ ] Test normal flow still works
- [ ] Test multiple pending requests all get signaled
Fixes#387
## Summary
- Add runtime placeholder for `McpServer` type to fix Pydantic 2.12+
compatibility
- `McpServer` was only imported under `TYPE_CHECKING`, causing
`PydanticUserError` at runtime
Fixes#384
Co-authored-by: lyrica <lyrica@example.com>
## TL;DR
Adds a write lock to `SubprocessCLITransport` to prevent concurrent
writes from parallel subagents.
---
## Overview
When multiple subagents run in parallel and invoke MCP tools, the CLI
sends concurrent `control_request` messages. Each handler tries to write
a response back to the subprocess stdin at the same time. Trio's
`TextSendStream` isn't thread-safe for concurrent access, so this causes
`BusyResourceError`.
This PR adds an `anyio.Lock` around all write operations (`write()`,
`end_input()`, and the stdin-closing part of `close()`). The lock
serializes concurrent writes so they happen one at a time. The `_ready`
flag is now set inside the lock during `close()` to prevent a TOCTOU
race where `write()` checks `_ready`, then `close()` sets it and closes
the stream before `write()` actually sends data.
---
## Call Flow
```mermaid
flowchart TD
A["write()<br/>subprocess_cli.py:505"] --> B["acquire _write_lock<br/>subprocess_cli.py:507"]
B --> C["check _ready & stream<br/>subprocess_cli.py:509"]
C --> D["_stdin_stream.send()<br/>subprocess_cli.py:523"]
E["close()<br/>subprocess_cli.py:458"] --> F["acquire _write_lock<br/>subprocess_cli.py:478"]
F --> G["set _ready = False<br/>subprocess_cli.py:479"]
G --> H["close _stdin_stream<br/>subprocess_cli.py:481"]
I["end_input()<br/>subprocess_cli.py:531"] --> J["acquire _write_lock<br/>subprocess_cli.py:533"]
J --> K["close _stdin_stream<br/>subprocess_cli.py:535"]
```
This PR updates the version to 0.1.12 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.12
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.12
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.12/
- Bundled CLI version: 2.0.58
- Install with: `pip install claude-agent-sdk==0.1.12`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
Add support for the `tools` option matching the TypeScript SDK, which
controls the base set of available tools separately from
allowed/disallowed tool filtering.
Supports three modes:
- Array of tool names: `["Read", "Edit", "Bash"]`
- Empty array: `[]` (disables all built-in tools)
- Preset object: `{"type": "preset", "preset": "claude_code"}`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Port the SdkBeta type and betas option from the TypeScript SDK to enable
SDK users to pass beta feature flags (e.g., 1M context window) to the
CLI.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.11 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.11
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.11
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.11/
- Bundled CLI version: 2.0.57
- Install with: `pip install claude-agent-sdk==0.1.11`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Currently wheels with packaged claude-code CLI are only published for
windows amd64, linux x86_64 and macos arm64. For version 0.1.10, we can
see the following download files are available on pypi contain the
following artifacts:
https://pypi.org/project/claude-agent-sdk/0.1.10/#files
- claude_agent_sdk-0.1.10.tar.gz
- claude_agent_sdk-0.1.10-py3-none-win_amd64.whl
- claude_agent_sdk-0.1.10-py3-none-manylinux_2_17_x86_64.whl
- claude_agent_sdk-0.1.10-py3-none-macosx_11_0_arm64.whl
The existing publishing code should support adding a new linux arm64
wheel builder, using the Github ARM runners:
https://github.blog/changelog/2025-08-07-arm64-hosted-runners-for-public-repositories-are-now-generally-available/
Unfortunately, there's no `ubuntu-latest-arm` label similar to the one
we use for the other builds, so I'm using the `ubuntu-24.04-arm` label.
Port SDK MCP fix from TypeScript to Python.
Now, when SDK MCP servers or hooks are present, stream_input() waits for
the first result message before closing stdin, allowing bidirectional
control protocol communication to complete.
Fixes repro in
https://github.com/anthropics/claude-agent-sdk-python/issues/266.
The `query()` design requires input streams to be held open by the user
for SDK MCP bidirectional communication to work. This has confused a lot
of folks, so we're moving towards a more explicit lifecycle design. In
the meantime, this is the way we've addressed it with V1 APIs in
https://github.com/anthropics/claude-agent-sdk-typescript.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Update type: ignore comments to use `untyped-decorator` instead of
`misc` to match the actual mypy error codes reported in CI.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Adds programmatic sandbox configuration to the Python SDK, matching the
TypeScript SDK's approach.
Changes:
- Add SandboxSettings, SandboxNetworkConfig, SandboxIgnoreViolations
types
- Add sandbox field to ClaudeAgentOptions
- Merge sandbox into --settings CLI flag in SubprocessCLITransport
- Export sandbox types from package __init__.py
- Add comprehensive tests for sandbox settings
**Important:** Filesystem and network restrictions are configured via
permission rules (Read/Edit/WebFetch), not via these sandbox settings.
The sandbox settings control sandbox behavior (enabled, auto-allow,
excluded commands, etc.).
Example usage:
```python
from claude_agent_sdk import query, SandboxSettings
result = query(
prompt='Build and test the project',
options=ClaudeAgentOptions(
sandbox={
'enabled': True,
'autoAllowBashIfSandboxed': True,
'excludedCommands': ['docker'],
'network': {
'allowLocalBinding': True,
'allowUnixSockets': ['/var/run/docker.sock']
}
}
)
)
```
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.10 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.10
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.10
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.10/
- Bundled CLI version: 2.0.53
- Install with: `pip install claude-agent-sdk==0.1.10`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Posts new issues to claude-agent-sdk-feedback. Can't use the default
github slack bot as it's too noisy (all comments and issue updates such
as comments, closing, etc...)
---------
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
This PR updates the version to 0.1.9 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.9
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.9
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.9/
- Bundled CLI version: 2.0.49
- Install with: `pip install claude-agent-sdk==0.1.9`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
## Summary
- Adds optional `timeout` field to `HookMatcher` dataclass in `types.py`
that allows users to specify a custom timeout (in seconds) for hooks
- Propagates the timeout value through:
- `client.py` and `_internal/client.py`: `_convert_hooks_to_internal()`
method
- `_internal/query.py`: hook config sent to CLI
## Test plan
- [x] Verify hooks work without timeout specified (default behavior)
- [x] Verify custom timeout is passed to CLI when specified in
HookMatcher
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Remove the claude_code_version workflow input and instead read the CLI
version directly from src/claude_agent_sdk/_cli_version.py. This allows
the version to be managed separately and updated by automation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.8 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml` to 0.1.8
- Updated version in `src/claude_agent_sdk/_version.py` to 0.1.8
- Updated bundled CLI version in `src/claude_agent_sdk/_cli_version.py`
to 2.0.45
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.8/
- Bundled CLI version: 2.0.45
- Install with: `pip install claude-agent-sdk==0.1.8`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
The build_wheel.py script uses `python -m wheel tags` to retag wheels
with platform-specific tags, but `wheel` wasn't explicitly installed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Wheels are already ZIP files - double compression via GitHub Actions
artifacts can cause "Mis-matched data size" errors on PyPI upload.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
The bash install script (install.sh) explicitly rejects Windows. Use the
PowerShell installer (install.ps1) instead when running on Windows,
matching the approach used in test.yml.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Windows console encoding (cp1252) doesn't support Unicode emoji
characters, causing UnicodeEncodeError in CI. Replaced all emoji
characters with plain text equivalents.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Bundle platform-specific Claude Code CLI binaries directly in the Python
package, eliminating the need for separate CLI installation.
## Changes
### Build System
- Created `scripts/download_cli.py` to fetch CLI during build
- Created `scripts/build_wheel.py` for building platform-specific wheels
- Created `scripts/update_cli_version.py` to track bundled CLI version
- Updated `pyproject.toml` to properly bundle CLI without duplicate file
warnings
- Made twine check non-blocking (License-File warnings are false
positives)
### Runtime
- Modified `subprocess_cli.py` to check for bundled CLI first
- Added `_cli_version.py` to track which CLI version is bundled
- SDK automatically uses bundled CLI, falling back to system
installation if not found
- Users can still override with `cli_path` option
### Release Workflow
- Updated GitHub workflow to build separate wheels per platform (macOS,
Linux, Windows)
- Workflow now accepts two inputs:
- `version`: Package version to publish (e.g., `0.1.5`)
- `claude_code_version`: CLI version to bundle (e.g., `2.0.0` or
`latest`)
- Workflow builds platform-specific wheels with bundled CLI
- Creates release PR that updates:
- `pyproject.toml` version
- `src/claude_agent_sdk/_version.py`
- `src/claude_agent_sdk/_cli_version.py` with bundled CLI version
- `CHANGELOG.md` with auto-generated release notes
### Documentation
- Updated README to reflect bundled CLI (removed Node.js requirement)
- Added release workflow documentation
- Added local wheel building instructions
## Benefits
- **Zero external dependencies**: No need for Node.js or npm
- **Easier installation**: Single `pip install` gets everything
- **Version control**: Track exactly which CLI version is bundled
- **Flexible releases**: Can release new package versions with updated
CLI without code changes
- **Better user experience**: Works out of the box with no setup
Platform-specific wheels are automatically selected by pip during
installation based on the user's OS and architecture.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.7 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_agent_sdk/_version.py`
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.7/
- Install with: `pip install claude-agent-sdk==0.1.7`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: inigo <bogini@users.noreply.github.com>
Add support for automatic model fallback when primary model is
overloaded. The Python SDK passes the fallback_model parameter to the
Claude CLI, which handles the validation and fallback logic.
Changes:
- Add fallback_model parameter to ClaudeAgentOptions
- Pass --fallback-model to CLI subprocess
- Add test for fallback model command building
The validation that fallback_model != model happens at the CLI layer,
keeping the SDK implementation simple and focused on parameter passing.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Add ~/.claude/local/claude to the list of locations checked when finding
the Claude CLI binary.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.6 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_agent_sdk/_version.py`
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.6/
- Install with: `pip install claude-agent-sdk==0.1.6`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
Reduce CI job count by only running examples on Python 3.13 instead of
all Python versions (3.10-3.13). This reduces the combinatorial
explosion while still ensuring examples work on the latest Python
version.
Co-authored-by: Claude <noreply@anthropic.com>
Add support for limiting API costs using the max_budget_usd option,
mirroring the TypeScript SDK functionality. When the budget is exceeded,
query execution stops and returns a result with subtype
'error_max_budget_usd'.
- Add max_budget_usd field to ClaudeAgentOptions
- Pass --max-budget-usd flag to Claude Code CLI
- Add test coverage for budget limit behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Add support for controlling the maximum number of tokens allocated to
extended thinking blocks via the max_thinking_tokens parameter.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Move changelog generation prompt from publish.yml into a reusable slash
command at .claude/commands/generate-changelog.md. Update workflow to
call the command with version parameters.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.5 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_agent_sdk/_version.py`
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.5/
- Install with: `pip install claude-agent-sdk==0.1.5`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Add SdkPluginConfig type and plugins field to ClaudeAgentOptions.
Plugins can be loaded using the local type with a path to the plugin
directory.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.4 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_agent_sdk/_version.py`
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.4/
- Install with: `pip install claude-agent-sdk==0.1.4`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
The changelog generation step was failing to get the previous release
tag because the checkout action was doing a shallow clone. Adding
fetch-depth: 0 ensures all tags are available for git describe.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Fixes#238 - Resolves "command line too long" error on Windows when
using multiple subagents with long prompts.
## Problem
On Windows, the command line length is limited to 8191 characters
(cmd.exe). When using multiple subagents with long prompts, the
`--agents` JSON argument can easily exceed this limit, causing the
error:
```
命令行太长。 (command line too long)
Fatal error in message reader: Command failed with exit code 1
```
## Solution
This PR implements automatic detection and handling of command line
length limits:
1. **Platform-specific limits**:
- Windows: 8000 characters (safe margin below 8191)
- Other platforms: 100,000 characters
2. **Automatic fallback**: When the command line would exceed the limit:
- Write agents JSON to a temporary file
- Use Claude CLI's `@filepath` syntax to reference the file
- Clean up temp files when transport is closed
3. **Zero breaking changes**: The fix is transparent to users - it
automatically activates only when needed
## Changes
- Add `platform` and `tempfile` imports
- Add `_CMD_LENGTH_LIMIT` constant with platform-specific values
- Track temporary files in `self._temp_files` list
- Modify `_build_command()` to detect long command lines and use temp
files
- Clean up temp files in `close()` method
## Testing
- ✅ All existing tests pass (122 tests)
- ✅ Linting and type checking pass
- ✅ Minimal changes - only 47 lines added/modified
- ✅ Solution transparently handles the Windows command line limit
## Test plan
- [x] Test on Windows with multiple subagents and long prompts
- [x] Verify temp files are created and cleaned up properly
- [x] Verify normal operation (short command lines) is unaffected
- [x] Test cross-platform compatibility (limit only applies on Windows)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Adds environment variable to allow skipping the Claude Code version
check. Users can set CLAUDE_AGENT_SDK_SKIP_VERSION_CHECK to disable the
check.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
With this change claude_code_sdk tools can now also return base64
images, in addition to text, following the MCP standard.
For example:
```
import base64
@tool("make_response", "prompt", {"foo": str})
def make_response(args):
fake_bytes = b"someimagebytes"
encoded_image = base64.b64encode(fake_bytes).decode("utf-8")
return {
"content": [
{"type": "text", "text": "Hello world!"},
{
"type": "image",
"mimeType": "image/jpeg",
"data": encoded_image,
},
]
}
```
The image will now be sent to Claude Code when calling the function,
allowing it to react to it.
---------
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
Adds a committable pre-push hook that runs ruff checks before pushing,
matching the CI lint workflow. Developers run ./scripts/initial-setup.sh
to install the hook locally.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Adds support for passing custom Claude Code CLI paths through
`ClaudeAgentOptions`, allowing organizations with non-standard
installation locations to specify the CLI path explicitly.
## Motivation
As noted in #214, organizations may install Claude Code CLI (or wrapped
versions) at custom locations and prefer to provide those paths instead
of relying on the SDK's default search logic. The transport layer
already supported `cli_path`, but it was never exposed through the
public API.
## Changes
1. **types.py**: Added `cli_path: str | Path | None = None` parameter to
`ClaudeAgentOptions` dataclass
2. **_internal/client.py**: Pass `cli_path` from
`configured_options.cli_path` to `SubprocessCLITransport`
3. **client.py**: Pass `cli_path` from `options.cli_path` to
`SubprocessCLITransport`
## Implementation Details
The `SubprocessCLITransport` constructor already accepted a `cli_path`
parameter (line 40 of subprocess_cli.py), but it was never passed from
the client layers. This PR completes the wiring by:
- Adding the option to the public `ClaudeAgentOptions` interface
- Extracting and passing it through both client implementations
(`InternalClient.process_query` and `ClaudeSDKClient.connect`)
## Usage Example
```python
from claude_agent_sdk import query, ClaudeAgentOptions
# Specify custom CLI path
options = ClaudeAgentOptions(
cli_path="/custom/path/to/claude"
)
result = await query("Hello!", options=options)
```
## Testing
- No new tests added as this is a straightforward parameter pass-through
- Existing tests should continue to work (default behavior unchanged)
- CI will validate the changes don't break existing functionality
Fixes#214
---------
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
This PR updates the version to 0.1.3 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_agent_sdk/_version.py`
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.3/
- Install with: `pip install claude-agent-sdk==0.1.3`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Ashwin Bhat <ashwin@anthropic.com>
Add typed hook input structures (PreToolUseHookInput,
PostToolUseHookInput, etc.) to provide better IDE autocomplete and type
safety for hook callbacks. Also convert HookContext from dataclass to
TypedDict to match runtime behavior.
Changes:
- Add BaseHookInput, PreToolUseHookInput, PostToolUseHookInput,
UserPromptSubmitHookInput, StopHookInput, SubagentStopHookInput, and
PreCompactHookInput TypedDict classes
- Update HookCallback signature to use HookInput union type
- Convert HookContext from dataclass to TypedDict (fixes type mismatch)
- Export all new hook input types from __init__.py
- Update all examples and tests to use typed hook inputs
Benefits:
- Zero breaking changes (TypedDict is dict-compatible at runtime)
- Full type safety and IDE autocomplete for hook callbacks
- Matches TypeScript SDK structure exactly
- Self-documenting hook input fields
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Fixes critical bug where hook outputs using `async_` and `continue_`
(Python-safe names avoiding keyword conflicts) were not being converted
to `async` and `continue` as expected by the CLI. This caused hook
control fields like `{"decision": "block"}` or `{"continue_": False}` to
be silently ignored.
Changes:
- Add _convert_hook_output_for_cli() to handle field name conversion
- Apply conversion in hook callback handling
- Update type documentation to clarify field name usage
- Add comprehensive test coverage for field name conversion
- Update existing tests to verify conversion occurs correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
This PR updates the version to 0.1.2 after publishing to PyPI.
## Changes
- Updated version in `pyproject.toml`
- Updated version in `src/claude_agent_sdk/_version.py`
- Updated `CHANGELOG.md` with release notes
## Release Information
- Published to PyPI: https://pypi.org/project/claude-agent-sdk/0.1.2/
- Install with: `pip install claude-agent-sdk==0.1.2`
🤖 Generated by GitHub Actions
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Closes the gap between Python and TypeScript SDK hook output types by
adding:
- `reason` field for explaining decisions
- `continue_` field for controlling execution flow
- `suppressOutput` field for hiding stdout
- `stopReason` field for stop explanations
- `decision` now supports both "approve" and "block" (not just "block")
- `AsyncHookJSONOutput` type for deferred hook execution
- Proper typing for `hookSpecificOutput` with discriminated unions
Also adds comprehensive examples and tests:
- New examples in hooks.py demonstrating all new fields
- Unit tests in test_tool_callbacks.py for new output types
- E2E tests in e2e-tests/test_hooks.py with real API calls
- CI integration in .github/workflows/test.yml
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Temporarily removes windows-latest from the test-e2e job matrix to
disable Windows end-to-end testing. Unit tests continue to run on
Windows.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
https://github.com/anthropics/claude-agent-sdk-python/issues/227
Fixes zod issues returned by cli subprocess transport - example now runs
correctly to completion:
```
============================================================
Tool Permission Callback Example
============================================================
This example demonstrates how to:
1. Allow/deny tools based on type
2. Modify tool inputs for safety
3. Log tool usage
4. Prompt for unknown tools
============================================================
📝 Sending query to Claude...
📨 Receiving response...
💬 Claude: I'll help you with these tasks. Let me execute them in sequence.
💬 Claude: Now I'll create a simple Python hello world script:
🔧 Tool Permission Request: Write
Input: {
"file_path": "/Users/vimota/code/claude-agent-sdk-python/hello.py",
"content": "#!/usr/bin/env python3\n\nprint(\"Hello, World!\")\n"
}
⚠️ Redirecting write from /Users/vimota/code/claude-agent-sdk-python/hello.py to ./safe_output/hello.py
💬 Claude: Now let's run the script:
🔧 Tool Permission Request: Bash
Input: {
"command": "python hello.py",
"description": "Run hello.py script"
}
✅ Allowing bash command: python hello.py
💬 Claude: Let me check where the file was created:
💬 Claude: I see the file was created in the `safe_output` directory. Let me run it from there:
🔧 Tool Permission Request: Bash
Input: {
"command": "python ./safe_output/hello.py",
"description": "Run hello.py from safe_output"
}
✅ Allowing bash command: python ./safe_output/hello.py
💬 Claude: Perfect! All tasks completed successfully:
1. **Listed files** - The directory contains a Python SDK project with source code in `src/`, tests, examples, and configuration files.
2. **Created hello.py** - A simple Python script was created at `./safe_output/hello.py` with a basic "Hello, World!" print statement.
3. **Ran the script** - The script executed successfully and printed "Hello, World!" to the console.
Note: The file was created in the `safe_output/` subdirectory rather than the root directory.
✅ Task completed!
Duration: 31158ms
Cost: $0.0736
Messages processed: 18
============================================================
Tool Usage Summary
============================================================
1. Tool: Write
Input: {
"file_path": "/Users/vimota/code/claude-agent-sdk-python/hello.py",
"content": "#!/usr/bin/env python3\n\nprint(\"Hello, World!\")\n"
}
Suggestions: [{'type': 'setMode', 'mode': 'acceptEdits', 'destination': 'session'}]
2. Tool: Bash
Input: {
"command": "python hello.py",
"description": "Run hello.py script"
}
Suggestions: [{'type': 'addRules', 'rules': [{'toolName': 'Bash', 'ruleContent': 'python:*'}], 'behavior': 'allow', 'destination': 'localSettings'}]
3. Tool: Bash
Input: {
"command": "python ./safe_output/hello.py",
"description": "Run hello.py from safe_output"
}
Suggestions: [{'type': 'addRules', 'rules': [{'toolName': 'Bash', 'ruleContent': 'python:*'}], 'behavior': 'allow', 'destination': 'localSettings'}]
```
Replace GitHub API-based commits with local git workflow and integrate
claude-code-action to automatically generate changelog entries. The
workflow now:
- Creates release branch locally with version commits
- Uses Claude to review changes and update CHANGELOG.md
- Pushes complete branch with all commits together
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Document the features and improvements released in version 0.1.1,
including minimum Claude Code version check, updated PermissionResult
types, and simplified model references.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
Add cross-platform testing for Windows alongside Linux across all test
jobs (unit tests, e2e tests, and examples). Uses native Windows
installation via PowerShell script and platform-specific timeout
handling for example scripts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
- Make test_cli_path_accepts_pathlib_path platform-aware by comparing
with str(path)
- Fix test_build_command_with_add_dirs to check directories individually
- Fix test_build_command_with_mcp_servers_as_file_path to handle Path
conversion
- Fix test_query_with_async_iterable to properly execute Python scripts
on Windows
All tests now pass on both Windows and Unix-like systems (110/110 tests
passing).
Fixes the issue #217 where pathlib.Path automatically converts path
separators based on the operating system, causing test assertions to
fail on Windows.
2025-10-07 16:18:30 -07:00
46 changed files with 3908 additions and 318 deletions
description: Generate changelog for a new release version
---
You are updating the changelog for the new release.
Update CHANGELOG.md to add a new section for the new version at the top of the file, right after the '# Changelog' heading.
Review the recent commits and merged pull requests since the last release to generate meaningful changelog content for the new version. Follow the existing format in CHANGELOG.md with sections like:
- Breaking Changes (if any)
- New Features
- Bug Fixes
- Documentation
- Internal/Other changes
Include only the sections that are relevant based on the actual changes. Write clear, user-focused descriptions.
After updating CHANGELOG.md, commit the changes with the message "docs: update changelog for v{new_version}".
- **Docker-based test infrastructure**: Added Docker support for running e2e tests in containerized environments, helping catch Docker-specific issues (#424)
- Updated bundled Claude CLI to version 2.0.72
## 0.1.17
### New Features
- **UserMessage UUID field**: Added `uuid` field to `UserMessage` response type, making it easier to use the `rewind_files()` method by providing direct access to message identifiers needed for file checkpointing (#418)
### Internal/Other Changes
- Updated bundled Claude CLI to version 2.0.70
## 0.1.16
### Bug Fixes
- **Rate limit detection**: Fixed parsing of the `error` field in `AssistantMessage`, enabling applications to detect and handle API errors like rate limits. Previously, the `error` field was defined but never populated from CLI responses (#405)
### Internal/Other Changes
- Updated bundled Claude CLI to version 2.0.68
## 0.1.15
### New Features
- **File checkpointing and rewind**: Added `enable_file_checkpointing` option to `ClaudeAgentOptions` and `rewind_files(user_message_id)` method to `ClaudeSDKClient` and `Query`. This enables reverting file changes made during a session back to a specific checkpoint, useful for exploring different approaches or recovering from unwanted modifications (#395)
### Documentation
- Added license and terms section to README (#399)
## 0.1.14
### Internal/Other Changes
- Updated bundled Claude CLI to version 2.0.62
## 0.1.13
### Bug Fixes
- **Faster error handling**: CLI errors (e.g., invalid session ID) now propagate to pending requests immediately instead of waiting for the 60-second timeout (#388)
- **Pydantic 2.12+ compatibility**: Fixed `PydanticUserError` caused by `McpServer` type only being imported under `TYPE_CHECKING` (#385)
- **Concurrent subagent writes**: Added write lock to prevent `BusyResourceError` when multiple subagents invoke MCP tools in parallel (#391)
### Internal/Other Changes
- Updated bundled Claude CLI to version 2.0.59
## 0.1.12
### New Features
- **Tools option**: Added `tools` option to `ClaudeAgentOptions` for controlling the base set of available tools, matching the TypeScript SDK functionality. Supports three modes:
- Array of tool names to specify which tools should be available (e.g., `["Read", "Edit", "Bash"]`)
- Empty array `[]` to disable all built-in tools
- Preset object `{"type": "preset", "preset": "claude_code"}` to use the default Claude Code toolset
- **SDK beta support**: Added `betas` option to `ClaudeAgentOptions` for enabling Anthropic API beta features. Currently supports `"context-1m-2025-08-07"` for extended context window
## 0.1.11
### Internal/Other Changes
- Updated bundled Claude CLI to version 2.0.57
## 0.1.10
### Internal/Other Changes
- Updated bundled Claude CLI to version 2.0.53
## 0.1.9
### Internal/Other Changes
- Updated bundled Claude CLI to version 2.0.49
## 0.1.8
### Features
- Claude Code is now included by default in the package, removing the requirement to install it separately. If you do wish to use a separately installed build, use the `cli_path` field in `Options`.
## 0.1.7
### Features
- **Structured outputs support**: Agents can now return validated JSON matching your schema. See https://docs.claude.com/en/docs/agent-sdk/structured-outputs. (#340)
- **Fallback model handling**: Added automatic fallback model handling for improved reliability and parity with the TypeScript SDK. When the primary model is unavailable, the SDK will automatically use a fallback model (#317)
- **Local Claude CLI support**: Added support for using a locally installed Claude CLI from `~/.claude/local/claude`, enabling development and testing with custom Claude CLI builds (#302)
## 0.1.6
### Features
- **Max budget control**: Added `max_budget_usd` option to set a maximum spending limit in USD for SDK sessions. When the budget is exceeded, the session will automatically terminate, helping prevent unexpected costs (#293)
- **Extended thinking configuration**: Added `max_thinking_tokens` option to control the maximum number of tokens allocated for Claude's internal reasoning process. This allows fine-tuning of the balance between response quality and token usage (#298)
### Bug Fixes
- **System prompt defaults**: Fixed issue where a default system prompt was being used when none was specified. The SDK now correctly uses an empty system prompt by default, giving users full control over agent behavior (#290)
## 0.1.5
### Features
- **Plugin support**: Added the ability to load Claude Code plugins programmatically through the SDK. Plugins can be specified using the new `plugins` field in `ClaudeAgentOptions` with a `SdkPluginConfig` type that supports loading local plugins by path. This enables SDK applications to extend functionality with custom commands and capabilities defined in plugin directories
## 0.1.4
### Features
- **Skip version check**: Added `CLAUDE_AGENT_SDK_SKIP_VERSION_CHECK` environment variable to allow users to disable the Claude Code version check. Set this environment variable to skip the minimum version validation when the SDK connects to Claude Code. (Only recommended if you already have Claude Code 2.0.0 or higher installed, otherwise some functionality may break)
- SDK MCP server tool calls can now return image content blocks
## 0.1.3
### Features
- **Strongly-typed hook inputs**: Added typed hook input structures (`PreToolUseHookInput`, `PostToolUseHookInput`, `UserPromptSubmitHookInput`, etc.) using TypedDict for better IDE autocomplete and type safety. Hook callbacks now receive fully typed input parameters
### Bug Fixes
- **Hook output field conversion**: Fixed bug where Python-safe field names (`async_`, `continue_`) in hook outputs were not being converted to CLI format (`async`, `continue`). This caused hook control fields to be silently ignored, preventing proper hook behavior. The SDK now automatically converts field names when communicating with the CLI
### Internal/Other Changes
- **CI/CD**: Re-enabled Windows testing in the end-to-end test workflow. Windows CI had been temporarily disabled but is now fully operational across all test suites
## 0.1.2
### Bug Fixes
- **Hook output fields**: Added missing hook output fields to match the TypeScript SDK, including `reason`, `continue_`, `suppressOutput`, and `stopReason`. The `decision` field now properly supports both "approve" and "block" values. Added `AsyncHookJSONOutput` type for deferred hook execution and proper typing for `hookSpecificOutput` with discriminated unions
## 0.1.1
### Features
- **Minimum Claude Code version check**: Added version validation to ensure Claude Code 2.0.0+ is installed. The SDK will display a warning if an older version is detected, helping prevent compatibility issues
- **Updated PermissionResult types**: Aligned permission result types with the latest control protocol for better type safety and compatibility
### Improvements
- **Model references**: Updated all examples and tests to use the simplified `claude-sonnet-4-5` model identifier instead of dated version strings
## 0.1.0
Introducing the Claude Agent SDK! The Claude Code SDK has been renamed to better reflect its capabilities for building AI agents across all domains, not just coding.
@ -7,7 +159,9 @@ Introducing the Claude Agent SDK! The Claude Code SDK has been renamed to better
### Breaking Changes
#### Type Name Changes
- **ClaudeCodeOptions renamed to ClaudeAgentOptions**: The options type has been renamed to match the new SDK branding. Update all imports and type references:
```python
# Before
from claude_agent_sdk import query, ClaudeCodeOptions
@ -19,6 +173,7 @@ Introducing the Claude Agent SDK! The Claude Code SDK has been renamed to better
```
#### System Prompt Changes
- **Merged prompt options**: The `custom_system_prompt` and `append_system_prompt` fields have been merged into a single `system_prompt` field for simpler configuration
- **No default system prompt**: The Claude Code system prompt is no longer included by default, giving you full control over agent behavior. To use the Claude Code system prompt, explicitly set:
```python
@ -26,6 +181,7 @@ Introducing the Claude Agent SDK! The Claude Code SDK has been renamed to better
```
#### Settings Isolation
- **No filesystem settings by default**: Settings files (`settings.json`, `CLAUDE.md`), slash commands, and subagents are no longer loaded automatically. This ensures SDK applications have predictable behavior independent of local filesystem configurations
- **Explicit settings control**: Use the new `setting_sources` field to specify which settings locations to load: `["user", "project", "local"]`
@ -80,4 +236,3 @@ For full migration instructions, see our [migration guide](https://docs.claude.c
- Fix multi-line buffering issue
- Rename cost_usd to total_cost_usd in API responses
- Claude Code 2.0.0+: `npm install -g @anthropic-ai/claude-code`
**Note:** The Claude Code CLI is automatically bundled with the package - no separate installation required! The SDK will use the bundled CLI by default. If you prefer to use a system-wide installation or a specific version, you can:
- Install Claude Code separately: `curl -fsSL https://claude.ai/install.sh | bash`
- Specify a custom path: `ClaudeAgentOptions(cli_path="/path/to/claude")`
## Quick Start
@ -179,7 +183,7 @@ options = ClaudeAgentOptions(
### Hooks
A **hook** is a Python function that the Claude Code *application* (*not* Claude) invokes at specific points of the Claude agent loop. Hooks can provide deterministic processing and automated feedback for Claude. Read more in [Claude Code Hooks Reference](https://docs.anthropic.com/en/docs/claude-code/hooks).
A **hook** is a Python function that the Claude Code _application_ (_not_ Claude) invokes at specific points of the Claude agent loop. Hooks can provide deterministic processing and automated feedback for Claude. Read more in [Claude Code Hooks Reference](https://docs.anthropic.com/en/docs/claude-code/hooks).
For more examples, see examples/hooks.py.
@ -229,10 +233,10 @@ async with ClaudeSDKClient(options=options) as client:
print(msg)
```
## Types
See [src/claude_agent_sdk/types.py](src/claude_agent_sdk/types.py) for complete type definitions:
@ -259,7 +263,7 @@ except CLIJSONDecodeError as e:
print(f"Failed to parse response: {e}")
```
See [src/claude_agent_sdk/_errors.py](src/claude_agent_sdk/_errors.py) for all error types.
See [src/claude_agent_sdk/\_errors.py](src/claude_agent_sdk/_errors.py) for all error types.
## Available Tools
@ -280,6 +284,73 @@ If you're upgrading from the Claude Code SDK (versions < 0.1.0), please see the
- Settings isolation and explicit control
- New programmatic subagents and session forking features
## License
## Development
MIT
If you're contributing to this project, run the initial setup script to install git hooks:
```bash
./scripts/initial-setup.sh
```
This installs a pre-push hook that runs lint checks before pushing, matching the CI workflow. To skip the hook temporarily, use `git push --no-verify`.
### Building Wheels Locally
To build wheels with the bundled Claude Code CLI:
```bash
# Install build dependencies
pip install build twine
# Build wheel with bundled CLI
python scripts/build_wheel.py
# Build with specific version
python scripts/build_wheel.py --version 0.1.4
# Build with specific CLI version
python scripts/build_wheel.py --cli-version 2.0.0
# Clean bundled CLI after building
python scripts/build_wheel.py --clean
# Skip CLI download (use existing)
python scripts/build_wheel.py --skip-download
```
The build script:
1. Downloads Claude Code CLI for your platform
2. Bundles it in the wheel
3. Builds both wheel and source distribution
4. Checks the package with twine
See `python scripts/build_wheel.py --help` for all options.
### Release Workflow
The package is published to PyPI via the GitHub Actions workflow in `.github/workflows/publish.yml`. To create a new release:
1. **Trigger the workflow** manually from the Actions tab with two inputs:
- `version`: The package version to publish (e.g., `0.1.5`)
- `claude_code_version`: The Claude Code CLI version to bundle (e.g., `2.0.0` or `latest`)
2. **The workflow will**:
- Build platform-specific wheels for macOS, Linux, and Windows
- Bundle the specified Claude Code CLI version in each wheel
- Build a source distribution
- Publish all artifacts to PyPI
- Create a release branch with version updates
- Open a PR to main with:
- Updated `pyproject.toml` version
- Updated `src/claude_agent_sdk/_version.py`
- Updated `src/claude_agent_sdk/_cli_version.py` with bundled CLI version
- Auto-generated `CHANGELOG.md` entry
3. **Review and merge** the release PR to update main with the new version information
The workflow tracks both the package version and the bundled CLI version separately, allowing you to release a new package version with an updated CLI without code changes.
## License and terms
Use of this SDK is governed by Anthropic's [Commercial Terms of Service](https://www.anthropic.com/legal/commercial-terms), including when you use it to power products and services that you make available to your own customers and end users, except to the extent a specific component or dependency is covered by a different license as indicated in that component's LICENSE file.
prompt="Search for test files in the tests/ directory. Determine which test framework is being used (pytest/unittest/nose) and count how many test files exist. Use Grep to search for framework imports.",
This is a custom greeting command from the demo plugin.
When the user runs this command, greet them warmly and explain that this message came from a custom plugin loaded via the Python SDK. Tell them that plugins can be used to extend Claude Code with custom commands, agents, skills, and hooks.