claude-agent-sdk 0.1.5__tar.gz → 0.1.6__tar.gz

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.

Files changed (30) hide show
  1. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/.gitignore +1 -0
  2. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/PKG-INFO +1 -1
  3. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/pyproject.toml +1 -1
  4. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/_internal/transport/subprocess_cli.py +9 -1
  5. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/_version.py +1 -1
  6. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/types.py +3 -0
  7. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_integration.py +70 -0
  8. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_transport.py +13 -0
  9. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/LICENSE +0 -0
  10. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/README.md +0 -0
  11. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/__init__.py +0 -0
  12. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/_errors.py +0 -0
  13. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/_internal/__init__.py +0 -0
  14. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/_internal/client.py +0 -0
  15. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/_internal/message_parser.py +0 -0
  16. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/_internal/query.py +0 -0
  17. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/_internal/transport/__init__.py +0 -0
  18. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/client.py +0 -0
  19. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/py.typed +0 -0
  20. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/src/claude_agent_sdk/query.py +0 -0
  21. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/conftest.py +0 -0
  22. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_changelog.py +0 -0
  23. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_client.py +0 -0
  24. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_errors.py +0 -0
  25. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_message_parser.py +0 -0
  26. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_sdk_mcp_integration.py +0 -0
  27. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_streaming_client.py +0 -0
  28. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_subprocess_buffering.py +0 -0
  29. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_tool_callbacks.py +0 -0
  30. {claude_agent_sdk-0.1.5 → claude_agent_sdk-0.1.6}/tests/test_types.py +0 -0
@@ -26,6 +26,7 @@ venv/
26
26
  ENV/
27
27
  env/
28
28
  .venv
29
+ uv.lock
29
30
 
30
31
  # IDEs
31
32
  .vscode/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-agent-sdk
3
- Version: 0.1.5
3
+ Version: 0.1.6
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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "claude-agent-sdk"
7
- version = "0.1.5"
7
+ version = "0.1.6"
8
8
  description = "Python SDK for Claude Code"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -97,7 +97,7 @@ class SubprocessCLITransport(Transport):
97
97
  cmd = [self._cli_path, "--output-format", "stream-json", "--verbose"]
98
98
 
99
99
  if self._options.system_prompt is None:
100
- pass
100
+ cmd.extend(["--system-prompt", ""])
101
101
  elif isinstance(self._options.system_prompt, str):
102
102
  cmd.extend(["--system-prompt", self._options.system_prompt])
103
103
  else:
@@ -115,6 +115,9 @@ class SubprocessCLITransport(Transport):
115
115
  if self._options.max_turns:
116
116
  cmd.extend(["--max-turns", str(self._options.max_turns)])
117
117
 
118
+ if self._options.max_budget_usd is not None:
119
+ cmd.extend(["--max-budget-usd", str(self._options.max_budget_usd)])
120
+
118
121
  if self._options.disallowed_tools:
119
122
  cmd.extend(["--disallowedTools", ",".join(self._options.disallowed_tools)])
120
123
 
@@ -216,6 +219,11 @@ class SubprocessCLITransport(Transport):
216
219
  # String mode: use --print with the prompt
217
220
  cmd.extend(["--print", "--", str(self._prompt)])
218
221
 
222
+ if self._options.max_thinking_tokens is not None:
223
+ cmd.extend(
224
+ ["--max-thinking-tokens", str(self._options.max_thinking_tokens)]
225
+ )
226
+
219
227
  # Check if command line is too long (Windows limitation)
220
228
  cmd_str = " ".join(cmd)
221
229
  if len(cmd_str) > _CMD_LENGTH_LIMIT and self._options.agents:
@@ -1,3 +1,3 @@
1
1
  """Version information for claude-agent-sdk."""
2
2
 
3
- __version__ = "0.1.5"
3
+ __version__ = "0.1.6"
@@ -518,6 +518,7 @@ class ClaudeAgentOptions:
518
518
  continue_conversation: bool = False
519
519
  resume: str | None = None
520
520
  max_turns: int | None = None
521
+ max_budget_usd: float | None = None
521
522
  disallowed_tools: list[str] = field(default_factory=list)
522
523
  model: str | None = None
523
524
  permission_prompt_tool_name: str | None = None
@@ -554,6 +555,8 @@ class ClaudeAgentOptions:
554
555
  setting_sources: list[SettingSource] | None = None
555
556
  # Plugin configurations for custom plugins
556
557
  plugins: list[SdkPluginConfig] = field(default_factory=list)
558
+ # Max tokens for thinking blocks
559
+ max_thinking_tokens: int | None = None
557
560
 
558
561
 
559
562
  # SDK Control Protocol
@@ -212,3 +212,73 @@ class TestIntegration:
212
212
  assert call_kwargs["options"].continue_conversation is True
213
213
 
214
214
  anyio.run(_test)
215
+
216
+ def test_max_budget_usd_option(self):
217
+ """Test query with max_budget_usd option."""
218
+
219
+ async def _test():
220
+ with patch(
221
+ "claude_agent_sdk._internal.client.SubprocessCLITransport"
222
+ ) as mock_transport_class:
223
+ mock_transport = AsyncMock()
224
+ mock_transport_class.return_value = mock_transport
225
+
226
+ # Mock the message stream that exceeds budget
227
+ async def mock_receive():
228
+ yield {
229
+ "type": "assistant",
230
+ "message": {
231
+ "role": "assistant",
232
+ "content": [
233
+ {"type": "text", "text": "Starting to read..."}
234
+ ],
235
+ "model": "claude-opus-4-1-20250805",
236
+ },
237
+ }
238
+ yield {
239
+ "type": "result",
240
+ "subtype": "error_max_budget_usd",
241
+ "duration_ms": 500,
242
+ "duration_api_ms": 400,
243
+ "is_error": False,
244
+ "num_turns": 1,
245
+ "session_id": "test-session-budget",
246
+ "total_cost_usd": 0.0002,
247
+ "usage": {
248
+ "input_tokens": 100,
249
+ "output_tokens": 50,
250
+ },
251
+ }
252
+
253
+ mock_transport.read_messages = mock_receive
254
+ mock_transport.connect = AsyncMock()
255
+ mock_transport.close = AsyncMock()
256
+ mock_transport.end_input = AsyncMock()
257
+ mock_transport.write = AsyncMock()
258
+ mock_transport.is_ready = Mock(return_value=True)
259
+
260
+ # Run query with very small budget
261
+ messages = []
262
+ async for msg in query(
263
+ prompt="Read the readme",
264
+ options=ClaudeAgentOptions(max_budget_usd=0.0001),
265
+ ):
266
+ messages.append(msg)
267
+
268
+ # Verify results
269
+ assert len(messages) == 2
270
+
271
+ # Check result message
272
+ assert isinstance(messages[1], ResultMessage)
273
+ assert messages[1].subtype == "error_max_budget_usd"
274
+ assert messages[1].is_error is False
275
+ assert messages[1].total_cost_usd == 0.0002
276
+ assert messages[1].total_cost_usd is not None
277
+ assert messages[1].total_cost_usd > 0
278
+
279
+ # Verify transport was created with max_budget_usd option
280
+ mock_transport_class.assert_called_once()
281
+ call_kwargs = mock_transport_class.call_args.kwargs
282
+ assert call_kwargs["options"].max_budget_usd == 0.0001
283
+
284
+ anyio.run(_test)
@@ -46,6 +46,8 @@ class TestSubprocessCLITransport:
46
46
  assert "stream-json" in cmd
47
47
  assert "--print" in cmd
48
48
  assert "Hello" in cmd
49
+ assert "--system-prompt" in cmd
50
+ assert cmd[cmd.index("--system-prompt") + 1] == ""
49
51
 
50
52
  def test_cli_path_accepts_pathlib_path(self):
51
53
  """Test that cli_path accepts pathlib.Path objects."""
@@ -129,6 +131,17 @@ class TestSubprocessCLITransport:
129
131
  assert "--max-turns" in cmd
130
132
  assert "5" in cmd
131
133
 
134
+ def test_build_command_with_max_thinking_tokens(self):
135
+ """Test building CLI command with max_thinking_tokens option."""
136
+ transport = SubprocessCLITransport(
137
+ prompt="test",
138
+ options=make_options(max_thinking_tokens=5000),
139
+ )
140
+
141
+ cmd = transport._build_command()
142
+ assert "--max-thinking-tokens" in cmd
143
+ assert "5000" in cmd
144
+
132
145
  def test_build_command_with_add_dirs(self):
133
146
  """Test building CLI command with add_dirs option."""
134
147
  from pathlib import Path