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.

@@ -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",
@@ -71,7 +71,8 @@ class InternalClient:
71
71
  chosen_transport = transport
72
72
  else:
73
73
  chosen_transport = SubprocessCLITransport(
74
- prompt=prompt, options=configured_options
74
+ prompt=prompt,
75
+ options=configured_options,
75
76
  )
76
77
 
77
78
  # Connect transport
@@ -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 = str(cli_path) if cli_path else self._find_cli()
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 specify the path when creating transport:\n"
83
- " SubprocessCLITransport(..., cli_path='/path/to/claude')"
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
- cmd.extend(["--agents", json.dumps(agents_dict)])
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
- await self._check_claude_version()
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
 
@@ -1,3 +1,3 @@
1
1
  """Version information for claude-agent-sdk."""
2
2
 
3
- __version__ = "0.1.3"
3
+ __version__ = "0.1.5"
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
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=6bpu7xdAzyHRRgxdXGBFbZgS-sVq2bvC7s2Z_whog7c,12035
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=E5buSXiVJIZpoi3ylyUDKfQutllqoNUPcsm7cW4lC70,71
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=0CJP14sf1PJm1NdpLYvFQ_8bUrtuQMWaOPHsmvxB040,16646
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=Z06Fj4t5mHkKHKBUwxmHMTEo7lzs3X4_D_c-xq6Wg4I,4603
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=ViZxmHoAx3NdFNgLUFgNYuCjJZdVqKk2sxHlB57Z2ng,19097
14
- claude_agent_sdk-0.1.3.dist-info/METADATA,sha256=UieBXMnHeT5-bVpX8aJWQtph4MtLpf4hL8O-vL1up-8,9648
15
- claude_agent_sdk-0.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- claude_agent_sdk-0.1.3.dist-info/licenses/LICENSE,sha256=zr3eio-57lnl6q7RlXi_gIWqcEdWIlnDHzjyJcJvaBI,1070
17
- claude_agent_sdk-0.1.3.dist-info/RECORD,,
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,,