claude-agent-sdk 0.0.23__py3-none-any.whl → 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of claude-agent-sdk might be problematic. Click here for more details.
- claude_agent_sdk/_internal/query.py +10 -5
- claude_agent_sdk/_internal/transport/subprocess_cli.py +56 -14
- claude_agent_sdk/_version.py +1 -1
- claude_agent_sdk/client.py +18 -8
- claude_agent_sdk/types.py +37 -0
- {claude_agent_sdk-0.0.23.dist-info → claude_agent_sdk-0.1.1.dist-info}/METADATA +13 -4
- claude_agent_sdk-0.1.1.dist-info/RECORD +17 -0
- claude_agent_sdk-0.0.23.dist-info/RECORD +0 -17
- {claude_agent_sdk-0.0.23.dist-info → claude_agent_sdk-0.1.1.dist-info}/WHEEL +0 -0
- {claude_agent_sdk-0.0.23.dist-info → claude_agent_sdk-0.1.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -213,13 +213,18 @@ class Query:
|
|
|
213
213
|
|
|
214
214
|
# Convert PermissionResult to expected dict format
|
|
215
215
|
if isinstance(response, PermissionResultAllow):
|
|
216
|
-
response_data = {"
|
|
216
|
+
response_data = {"behavior": "allow"}
|
|
217
217
|
if response.updated_input is not None:
|
|
218
|
-
response_data["
|
|
219
|
-
|
|
218
|
+
response_data["updatedInput"] = response.updated_input
|
|
219
|
+
if response.updated_permissions is not None:
|
|
220
|
+
response_data["updatedPermissions"] = [
|
|
221
|
+
permission.to_dict()
|
|
222
|
+
for permission in response.updated_permissions
|
|
223
|
+
]
|
|
220
224
|
elif isinstance(response, PermissionResultDeny):
|
|
221
|
-
response_data = {"
|
|
222
|
-
|
|
225
|
+
response_data = {"behavior": "deny", "message": response.message}
|
|
226
|
+
if response.interrupt:
|
|
227
|
+
response_data["interrupt"] = response.interrupt
|
|
223
228
|
else:
|
|
224
229
|
raise TypeError(
|
|
225
230
|
f"Tool permission callback must return PermissionResult (PermissionResultAllow or PermissionResultDeny), got {type(response)}"
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
|
+
import re
|
|
6
7
|
import shutil
|
|
8
|
+
import sys
|
|
7
9
|
from collections.abc import AsyncIterable, AsyncIterator
|
|
8
10
|
from contextlib import suppress
|
|
9
11
|
from dataclasses import asdict
|
|
@@ -24,7 +26,8 @@ from . import Transport
|
|
|
24
26
|
|
|
25
27
|
logger = logging.getLogger(__name__)
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
_DEFAULT_MAX_BUFFER_SIZE = 1024 * 1024 # 1MB buffer limit
|
|
30
|
+
MINIMUM_CLAUDE_CODE_VERSION = "2.0.0"
|
|
28
31
|
|
|
29
32
|
|
|
30
33
|
class SubprocessCLITransport(Transport):
|
|
@@ -48,6 +51,11 @@ class SubprocessCLITransport(Transport):
|
|
|
48
51
|
self._stderr_task_group: anyio.abc.TaskGroup | None = None
|
|
49
52
|
self._ready = False
|
|
50
53
|
self._exit_error: Exception | None = None # Track process exit errors
|
|
54
|
+
self._max_buffer_size = (
|
|
55
|
+
options.max_buffer_size
|
|
56
|
+
if options.max_buffer_size is not None
|
|
57
|
+
else _DEFAULT_MAX_BUFFER_SIZE
|
|
58
|
+
)
|
|
51
59
|
|
|
52
60
|
def _find_cli(self) -> str:
|
|
53
61
|
"""Find Claude Code CLI binary."""
|
|
@@ -66,15 +74,6 @@ class SubprocessCLITransport(Transport):
|
|
|
66
74
|
if path.exists() and path.is_file():
|
|
67
75
|
return str(path)
|
|
68
76
|
|
|
69
|
-
node_installed = shutil.which("node") is not None
|
|
70
|
-
|
|
71
|
-
if not node_installed:
|
|
72
|
-
error_msg = "Claude Code requires Node.js, which is not installed.\n\n"
|
|
73
|
-
error_msg += "Install Node.js from: https://nodejs.org/\n"
|
|
74
|
-
error_msg += "\nAfter installing Node.js, install Claude Code:\n"
|
|
75
|
-
error_msg += " npm install -g @anthropic-ai/claude-code"
|
|
76
|
-
raise CLINotFoundError(error_msg)
|
|
77
|
-
|
|
78
77
|
raise CLINotFoundError(
|
|
79
78
|
"Claude Code not found. Install with:\n"
|
|
80
79
|
" npm install -g @anthropic-ai/claude-code\n"
|
|
@@ -206,6 +205,8 @@ class SubprocessCLITransport(Transport):
|
|
|
206
205
|
if self._process:
|
|
207
206
|
return
|
|
208
207
|
|
|
208
|
+
await self._check_claude_version()
|
|
209
|
+
|
|
209
210
|
cmd = self._build_command()
|
|
210
211
|
try:
|
|
211
212
|
# Merge environment variables: system -> user -> SDK required
|
|
@@ -411,12 +412,13 @@ class SubprocessCLITransport(Transport):
|
|
|
411
412
|
# Keep accumulating partial JSON until we can parse it
|
|
412
413
|
json_buffer += json_line
|
|
413
414
|
|
|
414
|
-
if len(json_buffer) >
|
|
415
|
+
if len(json_buffer) > self._max_buffer_size:
|
|
416
|
+
buffer_length = len(json_buffer)
|
|
415
417
|
json_buffer = ""
|
|
416
418
|
raise SDKJSONDecodeError(
|
|
417
|
-
f"JSON message exceeded maximum buffer size of {
|
|
419
|
+
f"JSON message exceeded maximum buffer size of {self._max_buffer_size} bytes",
|
|
418
420
|
ValueError(
|
|
419
|
-
f"Buffer size {
|
|
421
|
+
f"Buffer size {buffer_length} exceeds limit {self._max_buffer_size}"
|
|
420
422
|
),
|
|
421
423
|
)
|
|
422
424
|
|
|
@@ -427,7 +429,7 @@ class SubprocessCLITransport(Transport):
|
|
|
427
429
|
except json.JSONDecodeError:
|
|
428
430
|
# We are speculatively decoding the buffer until we get
|
|
429
431
|
# a full JSON object. If there is an actual issue, we
|
|
430
|
-
# raise an error after
|
|
432
|
+
# raise an error after exceeding the configured limit.
|
|
431
433
|
continue
|
|
432
434
|
|
|
433
435
|
except anyio.ClosedResourceError:
|
|
@@ -451,6 +453,46 @@ class SubprocessCLITransport(Transport):
|
|
|
451
453
|
)
|
|
452
454
|
raise self._exit_error
|
|
453
455
|
|
|
456
|
+
async def _check_claude_version(self) -> None:
|
|
457
|
+
"""Check Claude Code version and warn if below minimum."""
|
|
458
|
+
version_process = None
|
|
459
|
+
try:
|
|
460
|
+
with anyio.fail_after(2): # 2 second timeout
|
|
461
|
+
version_process = await anyio.open_process(
|
|
462
|
+
[self._cli_path, "-v"],
|
|
463
|
+
stdout=PIPE,
|
|
464
|
+
stderr=PIPE,
|
|
465
|
+
)
|
|
466
|
+
|
|
467
|
+
if version_process.stdout:
|
|
468
|
+
stdout_bytes = await version_process.stdout.receive()
|
|
469
|
+
version_output = stdout_bytes.decode().strip()
|
|
470
|
+
|
|
471
|
+
match = re.match(r"([0-9]+\.[0-9]+\.[0-9]+)", version_output)
|
|
472
|
+
if match:
|
|
473
|
+
version = match.group(1)
|
|
474
|
+
version_parts = [int(x) for x in version.split(".")]
|
|
475
|
+
min_parts = [
|
|
476
|
+
int(x) for x in MINIMUM_CLAUDE_CODE_VERSION.split(".")
|
|
477
|
+
]
|
|
478
|
+
|
|
479
|
+
if version_parts < min_parts:
|
|
480
|
+
warning = (
|
|
481
|
+
f"Warning: Claude Code version {version} is unsupported in the Agent SDK. "
|
|
482
|
+
f"Minimum required version is {MINIMUM_CLAUDE_CODE_VERSION}. "
|
|
483
|
+
"Some features may not work correctly."
|
|
484
|
+
)
|
|
485
|
+
logger.warning(warning)
|
|
486
|
+
print(warning, file=sys.stderr)
|
|
487
|
+
except Exception:
|
|
488
|
+
pass
|
|
489
|
+
finally:
|
|
490
|
+
if version_process:
|
|
491
|
+
with suppress(Exception):
|
|
492
|
+
version_process.terminate()
|
|
493
|
+
with suppress(Exception):
|
|
494
|
+
await version_process.wait()
|
|
495
|
+
|
|
454
496
|
def is_ready(self) -> bool:
|
|
455
497
|
"""Check if transport is ready for communication."""
|
|
456
498
|
return self._ready
|
claude_agent_sdk/_version.py
CHANGED
claude_agent_sdk/client.py
CHANGED
|
@@ -6,6 +6,7 @@ from collections.abc import AsyncIterable, AsyncIterator
|
|
|
6
6
|
from dataclasses import replace
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
|
+
from . import Transport
|
|
9
10
|
from ._errors import CLIConnectionError
|
|
10
11
|
from .types import ClaudeAgentOptions, HookEvent, HookMatcher, Message, ResultMessage
|
|
11
12
|
|
|
@@ -51,12 +52,17 @@ class ClaudeSDKClient:
|
|
|
51
52
|
exist.
|
|
52
53
|
"""
|
|
53
54
|
|
|
54
|
-
def __init__(
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
options: ClaudeAgentOptions | None = None,
|
|
58
|
+
transport: Transport | None = None,
|
|
59
|
+
):
|
|
55
60
|
"""Initialize Claude SDK client."""
|
|
56
61
|
if options is None:
|
|
57
62
|
options = ClaudeAgentOptions()
|
|
58
63
|
self.options = options
|
|
59
|
-
self.
|
|
64
|
+
self._custom_transport = transport
|
|
65
|
+
self._transport: Transport | None = None
|
|
60
66
|
self._query: Any | None = None
|
|
61
67
|
os.environ["CLAUDE_CODE_ENTRYPOINT"] = "sdk-py-client"
|
|
62
68
|
|
|
@@ -115,10 +121,14 @@ class ClaudeSDKClient:
|
|
|
115
121
|
else:
|
|
116
122
|
options = self.options
|
|
117
123
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
# Use provided custom transport or create subprocess transport
|
|
125
|
+
if self._custom_transport:
|
|
126
|
+
self._transport = self._custom_transport
|
|
127
|
+
else:
|
|
128
|
+
self._transport = SubprocessCLITransport(
|
|
129
|
+
prompt=actual_prompt,
|
|
130
|
+
options=options,
|
|
131
|
+
)
|
|
122
132
|
await self._transport.connect()
|
|
123
133
|
|
|
124
134
|
# Extract SDK MCP servers from options
|
|
@@ -222,7 +232,7 @@ class ClaudeSDKClient:
|
|
|
222
232
|
|
|
223
233
|
Args:
|
|
224
234
|
model: The model to use, or None to use default. Examples:
|
|
225
|
-
- 'claude-sonnet-4-
|
|
235
|
+
- 'claude-sonnet-4-5'
|
|
226
236
|
- 'claude-opus-4-1-20250805'
|
|
227
237
|
- 'claude-opus-4-20250514'
|
|
228
238
|
|
|
@@ -233,7 +243,7 @@ class ClaudeSDKClient:
|
|
|
233
243
|
await client.query("Help me understand this problem")
|
|
234
244
|
|
|
235
245
|
# Switch to a different model for implementation
|
|
236
|
-
await client.set_model('claude-
|
|
246
|
+
await client.set_model('claude-sonnet-4-5')
|
|
237
247
|
await client.query("Now implement the solution")
|
|
238
248
|
```
|
|
239
249
|
"""
|
claude_agent_sdk/types.py
CHANGED
|
@@ -70,6 +70,42 @@ class PermissionUpdate:
|
|
|
70
70
|
directories: list[str] | None = None
|
|
71
71
|
destination: PermissionUpdateDestination | None = None
|
|
72
72
|
|
|
73
|
+
def to_dict(self) -> dict[str, Any]:
|
|
74
|
+
"""Convert PermissionUpdate to dictionary format matching TypeScript control protocol."""
|
|
75
|
+
result: dict[str, Any] = {
|
|
76
|
+
"type": self.type,
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
# Add destination for all variants
|
|
80
|
+
if self.destination is not None:
|
|
81
|
+
result["destination"] = self.destination
|
|
82
|
+
|
|
83
|
+
# Handle different type variants
|
|
84
|
+
if self.type in ["addRules", "replaceRules", "removeRules"]:
|
|
85
|
+
# Rules-based variants require rules and behavior
|
|
86
|
+
if self.rules is not None:
|
|
87
|
+
result["rules"] = [
|
|
88
|
+
{
|
|
89
|
+
"toolName": rule.tool_name,
|
|
90
|
+
"ruleContent": rule.rule_content,
|
|
91
|
+
}
|
|
92
|
+
for rule in self.rules
|
|
93
|
+
]
|
|
94
|
+
if self.behavior is not None:
|
|
95
|
+
result["behavior"] = self.behavior
|
|
96
|
+
|
|
97
|
+
elif self.type == "setMode":
|
|
98
|
+
# Mode variant requires mode
|
|
99
|
+
if self.mode is not None:
|
|
100
|
+
result["mode"] = self.mode
|
|
101
|
+
|
|
102
|
+
elif self.type in ["addDirectories", "removeDirectories"]:
|
|
103
|
+
# Directory variants require directories
|
|
104
|
+
if self.directories is not None:
|
|
105
|
+
result["directories"] = self.directories
|
|
106
|
+
|
|
107
|
+
return result
|
|
108
|
+
|
|
73
109
|
|
|
74
110
|
# Tool callback types
|
|
75
111
|
@dataclass
|
|
@@ -320,6 +356,7 @@ class ClaudeAgentOptions:
|
|
|
320
356
|
extra_args: dict[str, str | None] = field(
|
|
321
357
|
default_factory=dict
|
|
322
358
|
) # Pass arbitrary CLI flags
|
|
359
|
+
max_buffer_size: int | None = None # Max bytes when buffering CLI stdout
|
|
323
360
|
debug_stderr: Any = (
|
|
324
361
|
sys.stderr
|
|
325
362
|
) # Deprecated: File-like object for debug output. Use stderr callback instead.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-agent-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: Python SDK for Claude Code
|
|
5
5
|
Project-URL: Homepage, https://github.com/anthropics/claude-agent-sdk-python
|
|
6
6
|
Project-URL: Documentation, https://docs.anthropic.com/en/docs/claude-code/sdk
|
|
@@ -43,8 +43,8 @@ pip install claude-agent-sdk
|
|
|
43
43
|
|
|
44
44
|
**Prerequisites:**
|
|
45
45
|
- Python 3.10+
|
|
46
|
-
- Node.js
|
|
47
|
-
- Claude Code
|
|
46
|
+
- Node.js
|
|
47
|
+
- Claude Code 2.0.0+: `npm install -g @anthropic-ai/claude-code`
|
|
48
48
|
|
|
49
49
|
## Quick Start
|
|
50
50
|
|
|
@@ -92,7 +92,7 @@ options = ClaudeAgentOptions(
|
|
|
92
92
|
)
|
|
93
93
|
|
|
94
94
|
async for message in query(
|
|
95
|
-
prompt="Create a hello.py file",
|
|
95
|
+
prompt="Create a hello.py file",
|
|
96
96
|
options=options
|
|
97
97
|
):
|
|
98
98
|
# Process tool use and results
|
|
@@ -304,6 +304,15 @@ See [examples/quick_start.py](examples/quick_start.py) for a complete working ex
|
|
|
304
304
|
|
|
305
305
|
See [examples/streaming_mode.py](examples/streaming_mode.py) for comprehensive examples involving `ClaudeSDKClient`. You can even run interactive examples in IPython from [examples/streaming_mode_ipython.py](examples/streaming_mode_ipython.py).
|
|
306
306
|
|
|
307
|
+
## Migrating from Claude Code SDK
|
|
308
|
+
|
|
309
|
+
If you're upgrading from the Claude Code SDK (versions < 0.1.0), please see the [CHANGELOG.md](CHANGELOG.md#010) for details on breaking changes and new features, including:
|
|
310
|
+
|
|
311
|
+
- `ClaudeCodeOptions` → `ClaudeAgentOptions` rename
|
|
312
|
+
- Merged system prompt configuration
|
|
313
|
+
- Settings isolation and explicit control
|
|
314
|
+
- New programmatic subagents and session forking features
|
|
315
|
+
|
|
307
316
|
## License
|
|
308
317
|
|
|
309
318
|
MIT
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
claude_agent_sdk/__init__.py,sha256=ZwJ2YpPdvDRdg1j73TGmK5FEfriv00MbgB5GbEkgqEs,11584
|
|
2
|
+
claude_agent_sdk/_errors.py,sha256=nSdJNNeszvXG1PfnXd2sQpVNORqMct-MfPaiM3XeJL4,1579
|
|
3
|
+
claude_agent_sdk/_version.py,sha256=yIo_daGf7IiorFxtDROWUbETCsox9r8uyNEv2NuZUfQ,71
|
|
4
|
+
claude_agent_sdk/client.py,sha256=Bye3QKb-iTg6Yq34ZPGHzaMg1isT9RvyHs5TkC2jWDI,13926
|
|
5
|
+
claude_agent_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
claude_agent_sdk/query.py,sha256=WebhztsMZPdaxyy1LBEZv4_j23vjp_ceX9DtrBsZqCA,4530
|
|
7
|
+
claude_agent_sdk/types.py,sha256=0GcWj57sqRqh7Rv3UXm8uTQkH9ENMr4AdDsm8_cUY7g,11841
|
|
8
|
+
claude_agent_sdk/_internal/__init__.py,sha256=zDdgjqp8SI9mTnwZbP2Be-w4LWlv4a3kA-TS2i75jsM,39
|
|
9
|
+
claude_agent_sdk/_internal/client.py,sha256=Z06Fj4t5mHkKHKBUwxmHMTEo7lzs3X4_D_c-xq6Wg4I,4603
|
|
10
|
+
claude_agent_sdk/_internal/message_parser.py,sha256=xxpOU3E8X21FCoy2OtLWKfEQr3AFYM454qJt6Xa0tmc,6475
|
|
11
|
+
claude_agent_sdk/_internal/query.py,sha256=b1JhWIKEIanVEA6g8SRqaYVVBsXjHWp-6rQXhIw8z70,20961
|
|
12
|
+
claude_agent_sdk/_internal/transport/__init__.py,sha256=sv8Iy1b9YmPlXu4XsdN98gJIlyrLtwq8PKQyF4qnQLk,1978
|
|
13
|
+
claude_agent_sdk/_internal/transport/subprocess_cli.py,sha256=ViZxmHoAx3NdFNgLUFgNYuCjJZdVqKk2sxHlB57Z2ng,19097
|
|
14
|
+
claude_agent_sdk-0.1.1.dist-info/METADATA,sha256=rNgqZ08Pq6tKo9n13C3d_R8EwdHZcqnP7vAiGHDJm5w,9648
|
|
15
|
+
claude_agent_sdk-0.1.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
claude_agent_sdk-0.1.1.dist-info/licenses/LICENSE,sha256=zr3eio-57lnl6q7RlXi_gIWqcEdWIlnDHzjyJcJvaBI,1070
|
|
17
|
+
claude_agent_sdk-0.1.1.dist-info/RECORD,,
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
claude_agent_sdk/__init__.py,sha256=ZwJ2YpPdvDRdg1j73TGmK5FEfriv00MbgB5GbEkgqEs,11584
|
|
2
|
-
claude_agent_sdk/_errors.py,sha256=nSdJNNeszvXG1PfnXd2sQpVNORqMct-MfPaiM3XeJL4,1579
|
|
3
|
-
claude_agent_sdk/_version.py,sha256=sLNUvI_d4RrYrZJlKrqcizYyZ0sKyQE6-uuWZ8slc1Y,72
|
|
4
|
-
claude_agent_sdk/client.py,sha256=je82F2J_BtB9Gh4PRUcjeTI1wrYVENMsAasOaUkO-3Y,13613
|
|
5
|
-
claude_agent_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
claude_agent_sdk/query.py,sha256=WebhztsMZPdaxyy1LBEZv4_j23vjp_ceX9DtrBsZqCA,4530
|
|
7
|
-
claude_agent_sdk/types.py,sha256=yGDK3TfoICruVIGY1t8lnLSZGd4McRY7gEZm3n_ZoTc,10447
|
|
8
|
-
claude_agent_sdk/_internal/__init__.py,sha256=zDdgjqp8SI9mTnwZbP2Be-w4LWlv4a3kA-TS2i75jsM,39
|
|
9
|
-
claude_agent_sdk/_internal/client.py,sha256=Z06Fj4t5mHkKHKBUwxmHMTEo7lzs3X4_D_c-xq6Wg4I,4603
|
|
10
|
-
claude_agent_sdk/_internal/message_parser.py,sha256=xxpOU3E8X21FCoy2OtLWKfEQr3AFYM454qJt6Xa0tmc,6475
|
|
11
|
-
claude_agent_sdk/_internal/query.py,sha256=G2CxNrMhrmae2V9oh8ctJsWIFOCU2VEkBQvH1-nXC6w,20721
|
|
12
|
-
claude_agent_sdk/_internal/transport/__init__.py,sha256=sv8Iy1b9YmPlXu4XsdN98gJIlyrLtwq8PKQyF4qnQLk,1978
|
|
13
|
-
claude_agent_sdk/_internal/transport/subprocess_cli.py,sha256=UFD5D5NKJitd-apg9_A5mQnmBALaer_ROUaPeDpQexc,17405
|
|
14
|
-
claude_agent_sdk-0.0.23.dist-info/METADATA,sha256=1xMFPeoP6u76JDH5IkBAe1-Pqcj-XKrPjcmLtogUPSY,9242
|
|
15
|
-
claude_agent_sdk-0.0.23.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
-
claude_agent_sdk-0.0.23.dist-info/licenses/LICENSE,sha256=zr3eio-57lnl6q7RlXi_gIWqcEdWIlnDHzjyJcJvaBI,1070
|
|
17
|
-
claude_agent_sdk-0.0.23.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|