clawd-code-sdk 1.0.6__tar.gz → 1.0.7__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.
Files changed (78) hide show
  1. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/PKG-INFO +1 -1
  2. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/pyproject.toml +1 -1
  3. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/__init__.py +10 -0
  4. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/_internal/query.py +39 -0
  5. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/anthropic_types.py +24 -26
  6. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/client.py +63 -0
  7. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/__init__.py +10 -2
  8. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/base.py +2 -0
  9. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/content_blocks.py +1 -3
  10. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/control.py +70 -3
  11. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/hooks.py +2 -1
  12. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/permissions.py +1 -1
  13. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/server_info.py +1 -6
  14. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_tool_callbacks.py +1 -1
  15. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/.gitignore +0 -0
  16. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/LICENSE +0 -0
  17. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/README.md +0 -0
  18. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/_bundled/.gitignore +0 -0
  19. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/_errors.py +0 -0
  20. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/_internal/__init__.py +0 -0
  21. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/_internal/message_parser.py +0 -0
  22. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/_internal/transport/__init__.py +0 -0
  23. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/_internal/transport/subprocess_cli.py +0 -0
  24. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/_version.py +0 -0
  25. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/list_sessions.py +0 -0
  26. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/mcp_utils.py +0 -0
  27. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/agents.py +0 -0
  28. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/input_types.py +0 -0
  29. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/mcp.py +0 -0
  30. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/messages.py +0 -0
  31. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/options.py +0 -0
  32. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/output_types.py +0 -0
  33. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/prompt_requests.py +0 -0
  34. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/prompts.py +0 -0
  35. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/session.py +0 -0
  36. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/settings.py +0 -0
  37. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/system_messages.py +0 -0
  38. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/models/thinking.py +0 -0
  39. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/py.typed +0 -0
  40. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/query.py +0 -0
  41. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/session.py +0 -0
  42. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/storage/ARCHITECTURE.md +0 -0
  43. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/storage/__init__.py +0 -0
  44. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/storage/helpers.py +0 -0
  45. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/storage/models.py +0 -0
  46. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/storage/replay.py +0 -0
  47. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/src/clawd_code_sdk/usage.py +0 -0
  48. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/__init__.py +0 -0
  49. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/conftest.py +0 -0
  50. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/__init__.py +0 -0
  51. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_agents_and_settings.py +0 -0
  52. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_dynamic_control.py +0 -0
  53. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_hook_events.py +0 -0
  54. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_hooks.py +0 -0
  55. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_include_partial_messages.py +0 -0
  56. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_mcp_resources.py +0 -0
  57. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_mcp_tools.py +0 -0
  58. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_sdk_mcp_resources.py +0 -0
  59. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_sdk_mcp_tools.py +0 -0
  60. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_slash_commands.py +0 -0
  61. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_stderr_callback.py +0 -0
  62. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_storage_parsing.py +0 -0
  63. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_structured_output.py +0 -0
  64. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_subagent_invocation.py +0 -0
  65. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/e2e/test_tool_permissions.py +0 -0
  66. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/mcp_server.py +0 -0
  67. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/mock_claude_server.py +0 -0
  68. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_changelog.py +0 -0
  69. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_client.py +0 -0
  70. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_errors.py +0 -0
  71. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_image.png +0 -0
  72. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_integration.py +0 -0
  73. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_message_parser.py +0 -0
  74. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_sdk_mcp_integration.py +0 -0
  75. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_session.py +0 -0
  76. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_streaming_client.py +0 -0
  77. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_subprocess_buffering.py +0 -0
  78. {clawd_code_sdk-1.0.6 → clawd_code_sdk-1.0.7}/tests/test_transport.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clawd-code-sdk
3
- Version: 1.0.6
3
+ Version: 1.0.7
4
4
  Summary: Python SDK for Claude Code
5
5
  Project-URL: Documentation, https://github.com/phil65/claude-agent-sdk-python
6
6
  Project-URL: Homepage, https://github.com/phil65/claude-agent-sdk-python
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "clawd-code-sdk"
3
- version = "1.0.6"
3
+ version = "1.0.7"
4
4
  description = "Python SDK for Claude Code"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.13"
@@ -51,8 +51,13 @@ from .models import (
51
51
  McpSdkServerConfig,
52
52
  McpSdkServerConfigWithInstance,
53
53
  McpServerConfig,
54
+ AppliedSettings,
55
+ GetSettingsResponse,
56
+ McpAuthenticateResponse,
54
57
  McpSetServersResult,
58
+ SettingsSource,
55
59
  Message,
60
+ RemoteControlResponse,
56
61
  NotificationHookInput,
57
62
  NotificationHookSpecificOutput,
58
63
  PermissionMode,
@@ -138,6 +143,7 @@ __all__ = [
138
143
  # Hook support
139
144
  "AgentHookHandler",
140
145
  "AgentHooksConfig",
146
+ "AppliedSettings",
141
147
  "AssistantMessage",
142
148
  "AuthenticationError",
143
149
  "BaseHookInput",
@@ -163,6 +169,7 @@ __all__ = [
163
169
  "DocumentMediaType",
164
170
  "Filesystem",
165
171
  "FromPR",
172
+ "GetSettingsResponse",
166
173
  "HookCallback",
167
174
  "HookContext",
168
175
  "HookHandler",
@@ -177,6 +184,7 @@ __all__ = [
177
184
  "InitSystemMessage",
178
185
  "InvalidRequestError",
179
186
  "ListSessionsOptions",
187
+ "McpAuthenticateResponse",
180
188
  "McpSdkServerConfig",
181
189
  "McpSdkServerConfigWithInstance",
182
190
  "McpServerConfig",
@@ -206,6 +214,7 @@ __all__ = [
206
214
  "ProcessError",
207
215
  "PromptHookHandler",
208
216
  "RateLimitError",
217
+ "RemoteControlResponse",
209
218
  "ResultErrorMessage",
210
219
  "ResultMessage",
211
220
  "ResultSuccessMessage",
@@ -225,6 +234,7 @@ __all__ = [
225
234
  "SessionSnapshot",
226
235
  "SessionState",
227
236
  "SettingSource",
237
+ "SettingsSource",
228
238
  "StopHookInput",
229
239
  "SubagentStartHookInput",
230
240
  "SubagentStartHookSpecificOutput",
@@ -522,6 +522,45 @@ class Query:
522
522
  """End the current session."""
523
523
  return await self._send_control_request({"subtype": "end_session"})
524
524
 
525
+ async def remote_control(self, *, enabled: bool) -> dict[str, Any]:
526
+ """Toggle the remote control REPL bridge for external session access.
527
+
528
+ When enabled, starts a bridge that allows remote clients to send prompts,
529
+ permission responses, interrupts, and model changes into the session.
530
+ The response includes ``session_url``, ``connect_url``, and
531
+ ``environment_id`` when enabling.
532
+ """
533
+ req = {"subtype": "remote_control", "enabled": enabled}
534
+ return await self._send_control_request(req)
535
+
536
+ async def apply_flag_settings(self, settings: dict[str, Any]) -> dict[str, Any]:
537
+ """Apply runtime flag settings."""
538
+ req = {"subtype": "apply_flag_settings", "settings": settings}
539
+ return await self._send_control_request(req)
540
+
541
+ async def get_settings(self) -> dict[str, Any]:
542
+ """Get the effective merged settings and raw per-source settings."""
543
+ return await self._send_control_request({"subtype": "get_settings"})
544
+
545
+ async def mcp_authenticate(self, server_name: str) -> dict[str, Any]:
546
+ """Trigger OAuth authentication for an MCP server."""
547
+ req = {"subtype": "mcp_authenticate", "serverName": server_name}
548
+ return await self._send_control_request(req)
549
+
550
+ async def mcp_clear_auth(self, server_name: str) -> dict[str, Any]:
551
+ """Clear OAuth credentials for an MCP server."""
552
+ req = {"subtype": "mcp_clear_auth", "serverName": server_name}
553
+ return await self._send_control_request(req)
554
+
555
+ async def mcp_oauth_callback_url(self, server_name: str, callback_url: str) -> dict[str, Any]:
556
+ """Provide an OAuth redirect callback URL to complete an MCP server OAuth flow."""
557
+ req = {
558
+ "subtype": "mcp_oauth_callback_url",
559
+ "serverName": server_name,
560
+ "callbackUrl": callback_url,
561
+ }
562
+ return await self._send_control_request(req)
563
+
525
564
  async def rewind_files(self, user_message_id: str) -> dict[str, Any]:
526
565
  """Rewind tracked files to their state at a specific user message.
527
566
 
@@ -7,6 +7,7 @@ used to provide proper typing for ToolResultBlock.content.
7
7
 
8
8
  from __future__ import annotations
9
9
 
10
+ import functools
10
11
  from typing import Annotated
11
12
 
12
13
  from anthropic.types.beta import (
@@ -73,35 +74,32 @@ ToolResultContentBlock = Annotated[
73
74
  | BetaTextEditorCodeExecutionToolResultError,
74
75
  Field(discriminator="type"),
75
76
  ]
76
- _tool_result_content_adapter: TypeAdapter[list[ToolResultContentBlock]] | None = None
77
77
 
78
78
 
79
+ @functools.cache
79
80
  def _get_adapter() -> TypeAdapter[list[ToolResultContentBlock]]:
80
- global _tool_result_content_adapter # noqa: PLW0603
81
- if _tool_result_content_adapter is None:
82
- # Force schema build for Anthropic models (deferred by default)
83
- for model in [
84
- BetaTextBlock,
85
- BetaWebSearchResultBlock,
86
- BetaWebSearchToolResultError,
87
- BetaBashCodeExecutionResultBlock,
88
- BetaBashCodeExecutionToolResultError,
89
- BetaCodeExecutionResultBlock,
90
- BetaCodeExecutionToolResultError,
91
- BetaTextEditorCodeExecutionCreateResultBlock,
92
- BetaTextEditorCodeExecutionStrReplaceResultBlock,
93
- BetaTextEditorCodeExecutionToolResultError,
94
- BetaTextEditorCodeExecutionViewResultBlock,
95
- BetaToolReferenceBlock,
96
- BetaToolSearchToolResultError,
97
- BetaToolSearchToolSearchResultBlock,
98
- BetaWebFetchBlock,
99
- BetaWebFetchToolResultErrorBlock,
100
- ]:
101
- if isinstance(model, type) and issubclass(model, BaseModel):
102
- model.model_rebuild()
103
- _tool_result_content_adapter = TypeAdapter(list[ToolResultContentBlock])
104
- return _tool_result_content_adapter
81
+ # Force schema build for Anthropic models (deferred by default)
82
+ for model in [
83
+ BetaTextBlock,
84
+ BetaWebSearchResultBlock,
85
+ BetaWebSearchToolResultError,
86
+ BetaBashCodeExecutionResultBlock,
87
+ BetaBashCodeExecutionToolResultError,
88
+ BetaCodeExecutionResultBlock,
89
+ BetaCodeExecutionToolResultError,
90
+ BetaTextEditorCodeExecutionCreateResultBlock,
91
+ BetaTextEditorCodeExecutionStrReplaceResultBlock,
92
+ BetaTextEditorCodeExecutionToolResultError,
93
+ BetaTextEditorCodeExecutionViewResultBlock,
94
+ BetaToolReferenceBlock,
95
+ BetaToolSearchToolResultError,
96
+ BetaToolSearchToolSearchResultBlock,
97
+ BetaWebFetchBlock,
98
+ BetaWebFetchToolResultErrorBlock,
99
+ ]:
100
+ if isinstance(model, type) and issubclass(model, BaseModel):
101
+ model.model_rebuild()
102
+ return TypeAdapter(list[ToolResultContentBlock])
105
103
 
106
104
 
107
105
  def validate_tool_result_content(content: list[dict[str, object]]) -> list[ToolResultContentBlock]:
@@ -14,9 +14,12 @@ from clawd_code_sdk.models import (
14
14
  AssistantMessage,
15
15
  ClaudeAgentOptions,
16
16
  ClaudeCodeAgentInfo, # noqa: TC001
17
+ GetSettingsResponse,
18
+ McpAuthenticateResponse,
17
19
  McpSdkServerConfigWithInstance,
18
20
  McpSetServersResult,
19
21
  McpStatusResponse,
22
+ RemoteControlResponse,
20
23
  ResultErrorMessage,
21
24
  ResultMessage,
22
25
  ResultSuccessMessage,
@@ -33,6 +36,7 @@ if TYPE_CHECKING:
33
36
  from clawd_code_sdk._internal.query import Query
34
37
  from clawd_code_sdk.models import (
35
38
  ClaudeCodeServerInfo,
39
+ ClaudeCodeSettings,
36
40
  McpServerConfig,
37
41
  Message,
38
42
  PermissionMode,
@@ -338,6 +342,65 @@ class ClaudeSDKClient:
338
342
  query = self._ensure_connected()
339
343
  await query.end_session()
340
344
 
345
+ async def remote_control(self, *, enabled: bool) -> RemoteControlResponse | None:
346
+ """Toggle the remote control REPL bridge for external session access.
347
+
348
+ When enabled, starts a bridge that allows remote clients to send prompts,
349
+ permission responses, interrupts, and model changes into the session.
350
+
351
+ Returns:
352
+ A ``RemoteControlResponse`` with session URLs and environment ID
353
+ when enabling, or ``None`` when disabling.
354
+ """
355
+ query = self._ensure_connected()
356
+ result = await query.remote_control(enabled=enabled)
357
+ if not result:
358
+ return None
359
+ return RemoteControlResponse.model_validate(result)
360
+
361
+ async def apply_flag_settings(self, settings: ClaudeCodeSettings) -> None:
362
+ """Apply runtime settings overrides without restarting the session.
363
+
364
+ Flag settings are an in-memory settings source that gets merged with
365
+ other sources (user, project, etc.) to produce the effective settings.
366
+
367
+ Args:
368
+ settings: Settings to apply. Only non-None fields will be sent.
369
+ """
370
+ query = self._ensure_connected()
371
+ serialized = settings.model_dump(by_alias=True, exclude_none=True)
372
+ await query.apply_flag_settings(serialized)
373
+
374
+ async def get_settings(self) -> GetSettingsResponse:
375
+ """Get the effective merged settings and raw per-source settings."""
376
+ query = self._ensure_connected()
377
+ result = await query.get_settings()
378
+ return GetSettingsResponse.model_validate(result)
379
+
380
+ async def mcp_authenticate(self, server_name: str) -> McpAuthenticateResponse:
381
+ """Trigger OAuth authentication for an MCP server.
382
+
383
+ Returns:
384
+ Response indicating whether user action is required and the auth URL if so.
385
+ """
386
+ query = self._ensure_connected()
387
+ result = await query.mcp_authenticate(server_name)
388
+ return McpAuthenticateResponse.model_validate(result)
389
+
390
+ async def mcp_clear_auth(self, server_name: str) -> None:
391
+ """Clear OAuth credentials for an MCP server."""
392
+ query = self._ensure_connected()
393
+ await query.mcp_clear_auth(server_name)
394
+
395
+ async def mcp_oauth_callback_url(self, server_name: str, callback_url: str) -> None:
396
+ """Provide an OAuth redirect callback URL to complete an MCP server OAuth flow.
397
+
398
+ After the user completes browser-based OAuth, call this with the full
399
+ redirect URL (containing the authorization code) to finish the flow.
400
+ """
401
+ query = self._ensure_connected()
402
+ await query.mcp_oauth_callback_url(server_name, callback_url)
403
+
341
404
  async def set_max_thinking_tokens(self, max_thinking_tokens: int) -> None:
342
405
  """Set the maximum number of thinking tokens for extended thinking."""
343
406
  query = self._ensure_connected()
@@ -34,7 +34,12 @@ from .control import (
34
34
  SDKControlMcpMessageRequest,
35
35
  SDKControlMcpOAuthCallbackUrlRequest,
36
36
  SDKControlPermissionRequest,
37
+ AppliedSettings,
38
+ GetSettingsResponse,
39
+ McpAuthenticateResponse,
40
+ RemoteControlResponse,
37
41
  SDKControlRemoteControlRequest,
42
+ SettingsSource,
38
43
  SDKControlRequest,
39
44
  SDKControlResponse,
40
45
  SDKControlRewindFilesRequest,
@@ -214,7 +219,6 @@ from .content_blocks import (
214
219
  ThinkingBlock,
215
220
  ToolResultBlock,
216
221
  ToolUseBlock,
217
- content_block_adapter,
218
222
  )
219
223
  from .session import SDKSessionInfo, ListSessionsOptions
220
224
  from .messages import (
@@ -367,6 +371,7 @@ __all__ = [
367
371
  "AgentOutputUsage",
368
372
  "AgentServerToolUse",
369
373
  "ApiKeySource",
374
+ "AppliedSettings",
370
375
  "AskUserQuestion",
371
376
  "AskUserQuestionInput",
372
377
  "AskUserQuestionItem",
@@ -424,6 +429,7 @@ __all__ = [
424
429
  "FilesPersistedSystemMessage",
425
430
  "Filesystem",
426
431
  "FromPR",
432
+ "GetSettingsResponse",
427
433
  "GitDiff",
428
434
  "GlobInput",
429
435
  "GlobOutput",
@@ -460,6 +466,7 @@ __all__ = [
460
466
  "ListMcpResourcesOutput",
461
467
  "ListSessionsOptions",
462
468
  "LocalCommandOutputMessage",
469
+ "McpAuthenticateResponse",
463
470
  "McpClaudeAIProxyServerConfig",
464
471
  "McpConnectionStatus",
465
472
  "McpHttpServerConfig",
@@ -532,6 +539,7 @@ __all__ = [
532
539
  "ReadPdfOutput",
533
540
  "ReadTextOutput",
534
541
  "ReasoningEffort",
542
+ "RemoteControlResponse",
535
543
  "RequestId",
536
544
  "ResultErrorMessage",
537
545
  "ResultMessage",
@@ -564,6 +572,7 @@ __all__ = [
564
572
  "SessionStartHookInput",
565
573
  "SessionStartHookSpecificOutput",
566
574
  "SettingSource",
575
+ "SettingsSource",
567
576
  "SetupHookInput",
568
577
  "SkillInput",
569
578
  "SkillOutput",
@@ -631,7 +640,6 @@ __all__ = [
631
640
  "WorktreeCreateHookInput",
632
641
  "WorktreeRemoveHookInput",
633
642
  "WriteOutput",
634
- "content_block_adapter",
635
643
  "control_request_adapter",
636
644
  "message_adapter",
637
645
  "system_message_adapter",
@@ -26,6 +26,8 @@ CompactionTrigger = Literal["auto", "manual"]
26
26
  ElicitationMode = Literal["form", "url"]
27
27
  ElicitationAction = Literal["accept", "decline", "cancel"]
28
28
  FastModeState = Literal["off", "cooldown", "on"]
29
+ EffortLevel = Literal["low", "medium", "high", "max"]
30
+
29
31
 
30
32
  StopReason = Literal[
31
33
  "end_turn",
@@ -11,7 +11,7 @@ from collections.abc import Sequence
11
11
  from typing import TYPE_CHECKING, Annotated, Any, Literal
12
12
 
13
13
  from anthropic.types.beta.beta_tool_use_block import Caller
14
- from pydantic import BaseModel, ConfigDict, Discriminator, TypeAdapter
14
+ from pydantic import BaseModel, ConfigDict, Discriminator
15
15
 
16
16
  from clawd_code_sdk.models import ToolInput
17
17
  from clawd_code_sdk.models.base import ClaudeCodeBaseModel, StopReason, ToolName
@@ -110,8 +110,6 @@ ContentBlock = Annotated[
110
110
  Discriminator("type"),
111
111
  ]
112
112
 
113
- content_block_adapter = TypeAdapter[ContentBlock](ContentBlock)
114
-
115
113
 
116
114
  # =============================================================================
117
115
  # Message-level models
@@ -5,12 +5,19 @@ from __future__ import annotations
5
5
  from dataclasses import dataclass
6
6
  from typing import Annotated, Any, Literal, TypedDict
7
7
 
8
- from pydantic import Discriminator, TypeAdapter
8
+ from pydantic import BaseModel, Discriminator, TypeAdapter
9
9
 
10
10
  from clawd_code_sdk.models.agents import AgentDefinition # noqa: TC001
11
- from clawd_code_sdk.models.base import ElicitationMode, PermissionMode # noqa: TC001
11
+ from clawd_code_sdk.models.base import ( # noqa: TC001
12
+ ClaudeCodeBaseModel,
13
+ EffortLevel,
14
+ ElicitationMode,
15
+ ModelName,
16
+ PermissionMode,
17
+ )
12
18
  from clawd_code_sdk.models.hooks import HookEvent, HookInput # noqa: TC001
13
19
  from clawd_code_sdk.models.mcp import ExternalMcpServerConfig, JSONRPCMessage # noqa: TC001
20
+ from clawd_code_sdk.models.permissions import PermissionUpdate # noqa: TC001
14
21
 
15
22
 
16
23
  # SDK Control Protocol
@@ -29,7 +36,7 @@ class SDKControlPermissionRequest:
29
36
  tool_name: str
30
37
  input: dict[str, Any]
31
38
  tool_use_id: str
32
- permission_suggestions: list[Any] | None = None
39
+ permission_suggestions: list[PermissionUpdate] | None = None
33
40
  blocked_path: str | None = None
34
41
  decision_reason: str | None = None
35
42
  agent_id: str | None = None
@@ -209,6 +216,66 @@ class SDKControlRemoteControlRequest:
209
216
  enabled: bool = False
210
217
 
211
218
 
219
+ class RemoteControlResponse(BaseModel):
220
+ """Response from enabling remote control.
221
+
222
+ Contains the URLs and identifiers needed for remote clients to connect
223
+ to the session.
224
+ """
225
+
226
+ session_url: str
227
+ """URL for the remote control session."""
228
+
229
+ connect_url: str
230
+ """URL for remote clients to connect to the session."""
231
+
232
+ environment_id: str
233
+ """Identifier for the environment hosting the session."""
234
+
235
+
236
+ class McpAuthenticateResponse(ClaudeCodeBaseModel):
237
+ """Response from authenticating with an MCP server."""
238
+
239
+ auth_url: str | None = None
240
+ """OAuth authorization URL for the user to visit, if user action is required."""
241
+
242
+ requires_user_action: bool
243
+ """Whether the user needs to complete an OAuth flow in the browser."""
244
+
245
+
246
+ class AppliedSettings(BaseModel):
247
+ """The currently applied model and effort settings."""
248
+
249
+ model: ModelName | str
250
+ """The active model identifier."""
251
+
252
+ effort: EffortLevel | None = None
253
+ """The active effort level, or None if not set."""
254
+
255
+
256
+ class SettingsSource(BaseModel):
257
+ """A single settings source with its raw settings."""
258
+
259
+ source: str
260
+ """The source name (e.g. 'user', 'project', 'flagSettings')."""
261
+
262
+ settings: dict[str, Any]
263
+ """The raw settings from this source."""
264
+
265
+
266
+ class GetSettingsResponse(BaseModel):
267
+ """Response from get_settings() containing effective and per-source settings."""
268
+
269
+ effective: dict[str, Any]
270
+ """The merged effective settings (ClaudeCodeSettings shape, camelCase keys)."""
271
+
272
+ sources: list[SettingsSource]
273
+ """Raw settings from each source."""
274
+
275
+ applied: AppliedSettings
276
+ """The currently applied model and effort."""
277
+
278
+
212
279
  @dataclass(frozen=True, slots=True, kw_only=True)
213
280
  class SDKControlElicitationRequest:
214
281
  """Requests the SDK consumer to handle an MCP elicitation (user input request)."""
@@ -11,6 +11,7 @@ from clawd_code_sdk.models.base import ( # noqa: TC001
11
11
  ElicitationAction,
12
12
  ElicitationMode,
13
13
  )
14
+ from clawd_code_sdk.models.permissions import PermissionUpdate # noqa: TC001
14
15
 
15
16
 
16
17
  if TYPE_CHECKING:
@@ -237,7 +238,7 @@ class PermissionRequestHookInput(BaseHookInput):
237
238
  hook_event_name: Literal["PermissionRequest"]
238
239
  tool_name: str
239
240
  tool_input: dict[str, Any]
240
- permission_suggestions: NotRequired[list[Any]]
241
+ permission_suggestions: NotRequired[list[PermissionUpdate]]
241
242
  agent_id: NotRequired[str]
242
243
  agent_type: NotRequired[str]
243
244
 
@@ -6,7 +6,6 @@ from collections.abc import Awaitable, Callable
6
6
  from dataclasses import dataclass, field
7
7
  from typing import Any, Literal
8
8
 
9
- from clawd_code_sdk.models import AskUserQuestionInput, ToolInput
10
9
  from clawd_code_sdk.models.base import (
11
10
  ClaudeCodeBaseModel,
12
11
  ElicitationAction, # noqa: TC001
@@ -14,6 +13,7 @@ from clawd_code_sdk.models.base import (
14
13
  PermissionBehavior,
15
14
  PermissionMode,
16
15
  )
16
+ from clawd_code_sdk.models.input_types import AskUserQuestionInput, ToolInput
17
17
 
18
18
 
19
19
  # Permission Update types (matching TypeScript SDK)
@@ -2,15 +2,10 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from typing import Literal
6
-
7
5
  from anthropic.types import Model
8
6
  from pydantic import Field
9
7
 
10
- from clawd_code_sdk.models.base import ClaudeCodeBaseModel, FastModeState
11
-
12
-
13
- EffortLevel = Literal["low", "medium", "high", "max"]
8
+ from clawd_code_sdk.models.base import ClaudeCodeBaseModel, EffortLevel, FastModeState
14
9
 
15
10
 
16
11
  class ClaudeCodeModelInfo(ClaudeCodeBaseModel):
@@ -114,7 +114,7 @@ class TestToolPermissionCallbacks:
114
114
  "tool_name": "DangerousTool",
115
115
  "input": {"command": "rm -rf /"},
116
116
  "tool_use_id": "tu-2",
117
- "permission_suggestions": ["deny"],
117
+ "permission_suggestions": [],
118
118
  "blocked_path": None,
119
119
  }
120
120
  )
File without changes
File without changes