claude-agent-sdk 0.1.3__py3-none-any.whl → 0.1.5__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/__init__.py +13 -2
- claude_agent_sdk/_internal/client.py +2 -1
- claude_agent_sdk/_internal/transport/subprocess_cli.py +62 -6
- claude_agent_sdk/_version.py +1 -1
- claude_agent_sdk/types.py +13 -0
- {claude_agent_sdk-0.1.3.dist-info → claude_agent_sdk-0.1.5.dist-info}/METADATA +11 -1
- {claude_agent_sdk-0.1.3.dist-info → claude_agent_sdk-0.1.5.dist-info}/RECORD +9 -9
- {claude_agent_sdk-0.1.3.dist-info → claude_agent_sdk-0.1.5.dist-info}/WHEEL +0 -0
- {claude_agent_sdk-0.1.3.dist-info → claude_agent_sdk-0.1.5.dist-info}/licenses/LICENSE +0 -0
claude_agent_sdk/__init__.py
CHANGED
|
@@ -39,6 +39,7 @@ from .types import (
|
|
|
39
39
|
PreCompactHookInput,
|
|
40
40
|
PreToolUseHookInput,
|
|
41
41
|
ResultMessage,
|
|
42
|
+
SdkPluginConfig,
|
|
42
43
|
SettingSource,
|
|
43
44
|
StopHookInput,
|
|
44
45
|
SubagentStopHookInput,
|
|
@@ -203,7 +204,7 @@ def create_sdk_mcp_server(
|
|
|
203
204
|
- ClaudeAgentOptions: Configuration for using servers with query()
|
|
204
205
|
"""
|
|
205
206
|
from mcp.server import Server
|
|
206
|
-
from mcp.types import TextContent, Tool
|
|
207
|
+
from mcp.types import ImageContent, TextContent, Tool
|
|
207
208
|
|
|
208
209
|
# Create MCP server instance
|
|
209
210
|
server = Server(name, version=version)
|
|
@@ -273,11 +274,19 @@ def create_sdk_mcp_server(
|
|
|
273
274
|
# Convert result to MCP format
|
|
274
275
|
# The decorator expects us to return the content, not a CallToolResult
|
|
275
276
|
# It will wrap our return value in CallToolResult
|
|
276
|
-
content = []
|
|
277
|
+
content: list[TextContent | ImageContent] = []
|
|
277
278
|
if "content" in result:
|
|
278
279
|
for item in result["content"]:
|
|
279
280
|
if item.get("type") == "text":
|
|
280
281
|
content.append(TextContent(type="text", text=item["text"]))
|
|
282
|
+
if item.get("type") == "image":
|
|
283
|
+
content.append(
|
|
284
|
+
ImageContent(
|
|
285
|
+
type="image",
|
|
286
|
+
data=item["data"],
|
|
287
|
+
mimeType=item["mimeType"],
|
|
288
|
+
)
|
|
289
|
+
)
|
|
281
290
|
|
|
282
291
|
# Return just the content list - the decorator wraps it
|
|
283
292
|
return content
|
|
@@ -331,6 +340,8 @@ __all__ = [
|
|
|
331
340
|
# Agent support
|
|
332
341
|
"AgentDefinition",
|
|
333
342
|
"SettingSource",
|
|
343
|
+
# Plugin support
|
|
344
|
+
"SdkPluginConfig",
|
|
334
345
|
# MCP Server Support
|
|
335
346
|
"create_sdk_mcp_server",
|
|
336
347
|
"tool",
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
import json
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
|
+
import platform
|
|
6
7
|
import re
|
|
7
8
|
import shutil
|
|
8
9
|
import sys
|
|
10
|
+
import tempfile
|
|
9
11
|
from collections.abc import AsyncIterable, AsyncIterator
|
|
10
12
|
from contextlib import suppress
|
|
11
13
|
from dataclasses import asdict
|
|
@@ -29,6 +31,11 @@ logger = logging.getLogger(__name__)
|
|
|
29
31
|
_DEFAULT_MAX_BUFFER_SIZE = 1024 * 1024 # 1MB buffer limit
|
|
30
32
|
MINIMUM_CLAUDE_CODE_VERSION = "2.0.0"
|
|
31
33
|
|
|
34
|
+
# Platform-specific command line length limits
|
|
35
|
+
# Windows cmd.exe has a limit of 8191 characters, use 8000 for safety
|
|
36
|
+
# Other platforms have much higher limits
|
|
37
|
+
_CMD_LENGTH_LIMIT = 8000 if platform.system() == "Windows" else 100000
|
|
38
|
+
|
|
32
39
|
|
|
33
40
|
class SubprocessCLITransport(Transport):
|
|
34
41
|
"""Subprocess transport using Claude Code CLI."""
|
|
@@ -37,12 +44,13 @@ class SubprocessCLITransport(Transport):
|
|
|
37
44
|
self,
|
|
38
45
|
prompt: str | AsyncIterable[dict[str, Any]],
|
|
39
46
|
options: ClaudeAgentOptions,
|
|
40
|
-
cli_path: str | Path | None = None,
|
|
41
47
|
):
|
|
42
48
|
self._prompt = prompt
|
|
43
49
|
self._is_streaming = not isinstance(prompt, str)
|
|
44
50
|
self._options = options
|
|
45
|
-
self._cli_path =
|
|
51
|
+
self._cli_path = (
|
|
52
|
+
str(options.cli_path) if options.cli_path is not None else self._find_cli()
|
|
53
|
+
)
|
|
46
54
|
self._cwd = str(options.cwd) if options.cwd else None
|
|
47
55
|
self._process: Process | None = None
|
|
48
56
|
self._stdout_stream: TextReceiveStream | None = None
|
|
@@ -56,6 +64,7 @@ class SubprocessCLITransport(Transport):
|
|
|
56
64
|
if options.max_buffer_size is not None
|
|
57
65
|
else _DEFAULT_MAX_BUFFER_SIZE
|
|
58
66
|
)
|
|
67
|
+
self._temp_files: list[str] = [] # Track temporary files for cleanup
|
|
59
68
|
|
|
60
69
|
def _find_cli(self) -> str:
|
|
61
70
|
"""Find Claude Code CLI binary."""
|
|
@@ -79,8 +88,8 @@ class SubprocessCLITransport(Transport):
|
|
|
79
88
|
" npm install -g @anthropic-ai/claude-code\n"
|
|
80
89
|
"\nIf already installed locally, try:\n"
|
|
81
90
|
' export PATH="$HOME/node_modules/.bin:$PATH"\n'
|
|
82
|
-
"\nOr
|
|
83
|
-
"
|
|
91
|
+
"\nOr provide the path via ClaudeAgentOptions:\n"
|
|
92
|
+
" ClaudeAgentOptions(cli_path='/path/to/claude')"
|
|
84
93
|
)
|
|
85
94
|
|
|
86
95
|
def _build_command(self) -> list[str]:
|
|
@@ -172,7 +181,8 @@ class SubprocessCLITransport(Transport):
|
|
|
172
181
|
name: {k: v for k, v in asdict(agent_def).items() if v is not None}
|
|
173
182
|
for name, agent_def in self._options.agents.items()
|
|
174
183
|
}
|
|
175
|
-
|
|
184
|
+
agents_json = json.dumps(agents_dict)
|
|
185
|
+
cmd.extend(["--agents", agents_json])
|
|
176
186
|
|
|
177
187
|
sources_value = (
|
|
178
188
|
",".join(self._options.setting_sources)
|
|
@@ -181,6 +191,14 @@ class SubprocessCLITransport(Transport):
|
|
|
181
191
|
)
|
|
182
192
|
cmd.extend(["--setting-sources", sources_value])
|
|
183
193
|
|
|
194
|
+
# Add plugin directories
|
|
195
|
+
if self._options.plugins:
|
|
196
|
+
for plugin in self._options.plugins:
|
|
197
|
+
if plugin["type"] == "local":
|
|
198
|
+
cmd.extend(["--plugin-dir", plugin["path"]])
|
|
199
|
+
else:
|
|
200
|
+
raise ValueError(f"Unsupported plugin type: {plugin['type']}")
|
|
201
|
+
|
|
184
202
|
# Add extra args for future CLI flags
|
|
185
203
|
for flag, value in self._options.extra_args.items():
|
|
186
204
|
if value is None:
|
|
@@ -198,6 +216,37 @@ class SubprocessCLITransport(Transport):
|
|
|
198
216
|
# String mode: use --print with the prompt
|
|
199
217
|
cmd.extend(["--print", "--", str(self._prompt)])
|
|
200
218
|
|
|
219
|
+
# Check if command line is too long (Windows limitation)
|
|
220
|
+
cmd_str = " ".join(cmd)
|
|
221
|
+
if len(cmd_str) > _CMD_LENGTH_LIMIT and self._options.agents:
|
|
222
|
+
# Command is too long - use temp file for agents
|
|
223
|
+
# Find the --agents argument and replace its value with @filepath
|
|
224
|
+
try:
|
|
225
|
+
agents_idx = cmd.index("--agents")
|
|
226
|
+
agents_json_value = cmd[agents_idx + 1]
|
|
227
|
+
|
|
228
|
+
# Create a temporary file
|
|
229
|
+
# ruff: noqa: SIM115
|
|
230
|
+
temp_file = tempfile.NamedTemporaryFile(
|
|
231
|
+
mode="w", suffix=".json", delete=False, encoding="utf-8"
|
|
232
|
+
)
|
|
233
|
+
temp_file.write(agents_json_value)
|
|
234
|
+
temp_file.close()
|
|
235
|
+
|
|
236
|
+
# Track for cleanup
|
|
237
|
+
self._temp_files.append(temp_file.name)
|
|
238
|
+
|
|
239
|
+
# Replace agents JSON with @filepath reference
|
|
240
|
+
cmd[agents_idx + 1] = f"@{temp_file.name}"
|
|
241
|
+
|
|
242
|
+
logger.info(
|
|
243
|
+
f"Command line length ({len(cmd_str)}) exceeds limit ({_CMD_LENGTH_LIMIT}). "
|
|
244
|
+
f"Using temp file for --agents: {temp_file.name}"
|
|
245
|
+
)
|
|
246
|
+
except (ValueError, IndexError) as e:
|
|
247
|
+
# This shouldn't happen, but log it just in case
|
|
248
|
+
logger.warning(f"Failed to optimize command line length: {e}")
|
|
249
|
+
|
|
201
250
|
return cmd
|
|
202
251
|
|
|
203
252
|
async def connect(self) -> None:
|
|
@@ -205,7 +254,8 @@ class SubprocessCLITransport(Transport):
|
|
|
205
254
|
if self._process:
|
|
206
255
|
return
|
|
207
256
|
|
|
208
|
-
|
|
257
|
+
if not os.environ.get("CLAUDE_AGENT_SDK_SKIP_VERSION_CHECK"):
|
|
258
|
+
await self._check_claude_version()
|
|
209
259
|
|
|
210
260
|
cmd = self._build_command()
|
|
211
261
|
try:
|
|
@@ -307,6 +357,12 @@ class SubprocessCLITransport(Transport):
|
|
|
307
357
|
"""Close the transport and clean up resources."""
|
|
308
358
|
self._ready = False
|
|
309
359
|
|
|
360
|
+
# Clean up temporary files first (before early return)
|
|
361
|
+
for temp_file in self._temp_files:
|
|
362
|
+
with suppress(Exception):
|
|
363
|
+
Path(temp_file).unlink(missing_ok=True)
|
|
364
|
+
self._temp_files.clear()
|
|
365
|
+
|
|
310
366
|
if not self._process:
|
|
311
367
|
return
|
|
312
368
|
|
claude_agent_sdk/_version.py
CHANGED
claude_agent_sdk/types.py
CHANGED
|
@@ -406,6 +406,16 @@ McpServerConfig = (
|
|
|
406
406
|
)
|
|
407
407
|
|
|
408
408
|
|
|
409
|
+
class SdkPluginConfig(TypedDict):
|
|
410
|
+
"""SDK plugin configuration.
|
|
411
|
+
|
|
412
|
+
Currently only local plugins are supported via the 'local' type.
|
|
413
|
+
"""
|
|
414
|
+
|
|
415
|
+
type: Literal["local"]
|
|
416
|
+
path: str
|
|
417
|
+
|
|
418
|
+
|
|
409
419
|
# Content block types
|
|
410
420
|
@dataclass
|
|
411
421
|
class TextBlock:
|
|
@@ -512,6 +522,7 @@ class ClaudeAgentOptions:
|
|
|
512
522
|
model: str | None = None
|
|
513
523
|
permission_prompt_tool_name: str | None = None
|
|
514
524
|
cwd: str | Path | None = None
|
|
525
|
+
cli_path: str | Path | None = None
|
|
515
526
|
settings: str | None = None
|
|
516
527
|
add_dirs: list[str | Path] = field(default_factory=list)
|
|
517
528
|
env: dict[str, str] = field(default_factory=dict)
|
|
@@ -541,6 +552,8 @@ class ClaudeAgentOptions:
|
|
|
541
552
|
agents: dict[str, AgentDefinition] | None = None
|
|
542
553
|
# Setting sources to load (user, project, local)
|
|
543
554
|
setting_sources: list[SettingSource] | None = None
|
|
555
|
+
# Plugin configurations for custom plugins
|
|
556
|
+
plugins: list[SdkPluginConfig] = field(default_factory=list)
|
|
544
557
|
|
|
545
558
|
|
|
546
559
|
# SDK Control Protocol
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: claude-agent-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
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
|
|
@@ -313,6 +313,16 @@ If you're upgrading from the Claude Code SDK (versions < 0.1.0), please see the
|
|
|
313
313
|
- Settings isolation and explicit control
|
|
314
314
|
- New programmatic subagents and session forking features
|
|
315
315
|
|
|
316
|
+
## Development
|
|
317
|
+
|
|
318
|
+
If you're contributing to this project, run the initial setup script to install git hooks:
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
./scripts/initial-setup.sh
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
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`.
|
|
325
|
+
|
|
316
326
|
## License
|
|
317
327
|
|
|
318
328
|
MIT
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
claude_agent_sdk/__init__.py,sha256=
|
|
1
|
+
claude_agent_sdk/__init__.py,sha256=x6BQQxJFOmSDd1nKJBNFd6qwMW5_8bGuiIU4z90dW7g,12494
|
|
2
2
|
claude_agent_sdk/_errors.py,sha256=nSdJNNeszvXG1PfnXd2sQpVNORqMct-MfPaiM3XeJL4,1579
|
|
3
|
-
claude_agent_sdk/_version.py,sha256=
|
|
3
|
+
claude_agent_sdk/_version.py,sha256=nZ6OuNGKukLpd_B658yKfzTuL47Goj7731otzHqLE6Q,71
|
|
4
4
|
claude_agent_sdk/client.py,sha256=Bye3QKb-iTg6Yq34ZPGHzaMg1isT9RvyHs5TkC2jWDI,13926
|
|
5
5
|
claude_agent_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
claude_agent_sdk/query.py,sha256=WebhztsMZPdaxyy1LBEZv4_j23vjp_ceX9DtrBsZqCA,4530
|
|
7
|
-
claude_agent_sdk/types.py,sha256=
|
|
7
|
+
claude_agent_sdk/types.py,sha256=Nrg_HtYoG-ZpDd7XSEPqrU1vJOOmkaVnhl_wQK5QH2E,16986
|
|
8
8
|
claude_agent_sdk/_internal/__init__.py,sha256=zDdgjqp8SI9mTnwZbP2Be-w4LWlv4a3kA-TS2i75jsM,39
|
|
9
|
-
claude_agent_sdk/_internal/client.py,sha256=
|
|
9
|
+
claude_agent_sdk/_internal/client.py,sha256=ySaWYtZUrYMwN93r7qANaD-RGiFlkB49j0njQNVPHRM,4620
|
|
10
10
|
claude_agent_sdk/_internal/message_parser.py,sha256=xxpOU3E8X21FCoy2OtLWKfEQr3AFYM454qJt6Xa0tmc,6475
|
|
11
11
|
claude_agent_sdk/_internal/query.py,sha256=mfSiIfs58U1LYMnbj5GeLATvdI_cRVIxStV1He-cMTE,22015
|
|
12
12
|
claude_agent_sdk/_internal/transport/__init__.py,sha256=sv8Iy1b9YmPlXu4XsdN98gJIlyrLtwq8PKQyF4qnQLk,1978
|
|
13
|
-
claude_agent_sdk/_internal/transport/subprocess_cli.py,sha256=
|
|
14
|
-
claude_agent_sdk-0.1.
|
|
15
|
-
claude_agent_sdk-0.1.
|
|
16
|
-
claude_agent_sdk-0.1.
|
|
17
|
-
claude_agent_sdk-0.1.
|
|
13
|
+
claude_agent_sdk/_internal/transport/subprocess_cli.py,sha256=VyVULCXhNx5SHWYszm2A-oQo3lT1YI4RBuOu_ek8l0M,21489
|
|
14
|
+
claude_agent_sdk-0.1.5.dist-info/METADATA,sha256=XdFqUjbWhLSU1ZB1XjSDc23QDX_oZ1S9QYAQIwhXIh8,9949
|
|
15
|
+
claude_agent_sdk-0.1.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
claude_agent_sdk-0.1.5.dist-info/licenses/LICENSE,sha256=zr3eio-57lnl6q7RlXi_gIWqcEdWIlnDHzjyJcJvaBI,1070
|
|
17
|
+
claude_agent_sdk-0.1.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|