clawd-code-sdk 1.0.7__tar.gz → 1.0.8__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.
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/PKG-INFO +1 -1
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/pyproject.toml +1 -1
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/client.py +2 -16
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/agents.py +6 -2
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/base.py +8 -2
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/control.py +3 -1
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/hooks.py +2 -2
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/input_types.py +2 -2
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/messages.py +7 -10
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/options.py +12 -2
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/output_types.py +9 -9
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/permissions.py +19 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/server_info.py +9 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/settings.py +1 -1
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/system_messages.py +15 -1
- clawd_code_sdk-1.0.8/src/clawd_code_sdk/models/thinking.py +56 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_subprocess_buffering.py +14 -14
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_tool_callbacks.py +27 -20
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_transport.py +7 -5
- clawd_code_sdk-1.0.7/src/clawd_code_sdk/models/thinking.py +0 -30
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/.gitignore +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/LICENSE +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/README.md +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/__init__.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/_bundled/.gitignore +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/_errors.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/_internal/__init__.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/_internal/message_parser.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/_internal/query.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/_internal/transport/__init__.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/_internal/transport/subprocess_cli.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/_version.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/anthropic_types.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/list_sessions.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/mcp_utils.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/__init__.py +1 -1
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/content_blocks.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/mcp.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/prompt_requests.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/prompts.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/models/session.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/py.typed +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/query.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/session.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/storage/ARCHITECTURE.md +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/storage/__init__.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/storage/helpers.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/storage/models.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/storage/replay.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/usage.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/__init__.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/conftest.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/__init__.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_agents_and_settings.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_dynamic_control.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_hook_events.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_hooks.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_include_partial_messages.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_mcp_resources.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_mcp_tools.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_sdk_mcp_resources.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_sdk_mcp_tools.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_slash_commands.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_stderr_callback.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_storage_parsing.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_structured_output.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_subagent_invocation.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/e2e/test_tool_permissions.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/mcp_server.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/mock_claude_server.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_changelog.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_client.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_errors.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_image.png +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_integration.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_message_parser.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_sdk_mcp_integration.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_session.py +0 -0
- {clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/tests/test_streaming_client.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clawd-code-sdk
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.8
|
|
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
|
|
@@ -7,7 +7,6 @@ import os
|
|
|
7
7
|
from typing import TYPE_CHECKING, Any, Literal, Self, cast
|
|
8
8
|
|
|
9
9
|
import anyenv
|
|
10
|
-
from pydantic import TypeAdapter
|
|
11
10
|
|
|
12
11
|
from clawd_code_sdk._errors import CLIConnectionError
|
|
13
12
|
from clawd_code_sdk.models import (
|
|
@@ -95,9 +94,6 @@ class ClaudeSDKClient:
|
|
|
95
94
|
from clawd_code_sdk._internal.query import Query
|
|
96
95
|
from clawd_code_sdk._internal.transport.subprocess_cli import SubprocessCLITransport
|
|
97
96
|
|
|
98
|
-
# Validate and configure permission settings (matching TypeScript SDK logic)
|
|
99
|
-
self.options.validate()
|
|
100
|
-
|
|
101
97
|
# If on_permission is a callback, extract it for Query and replace with
|
|
102
98
|
# "stdio" so the CLI routes permission requests through the control protocol.
|
|
103
99
|
if callable(self.options.on_permission):
|
|
@@ -134,20 +130,10 @@ class ClaudeSDKClient:
|
|
|
134
130
|
else:
|
|
135
131
|
system_prompt = self.options.system_prompt
|
|
136
132
|
|
|
137
|
-
# JSON schema for structured output
|
|
138
|
-
json_schema: dict[str, Any] | None
|
|
139
|
-
match self.options.output_schema:
|
|
140
|
-
case type() as typ:
|
|
141
|
-
json_schema = TypeAdapter(typ).json_schema()
|
|
142
|
-
case dict() as schema:
|
|
143
|
-
json_schema = schema
|
|
144
|
-
case None:
|
|
145
|
-
json_schema = None
|
|
146
|
-
|
|
147
133
|
# Create Query to handle control protocol
|
|
148
134
|
self._query = Query(
|
|
149
135
|
transport=self._transport,
|
|
150
|
-
can_use_tool=can_use_tool,
|
|
136
|
+
can_use_tool=can_use_tool, # ty:ignore[invalid-argument-type]
|
|
151
137
|
on_user_question=self.options.on_user_question,
|
|
152
138
|
on_elicitation=self.options.on_elicitation,
|
|
153
139
|
hooks=self.options.hooks,
|
|
@@ -156,7 +142,7 @@ class ClaudeSDKClient:
|
|
|
156
142
|
agents=self.options.agents,
|
|
157
143
|
system_prompt=system_prompt,
|
|
158
144
|
append_system_prompt=append_system_prompt,
|
|
159
|
-
json_schema=
|
|
145
|
+
json_schema=self.options.get_json_schema(),
|
|
160
146
|
prompt_suggestions=self.options.prompt_suggestions,
|
|
161
147
|
agent_progress_summaries=self.options.agent_progress_summaries,
|
|
162
148
|
)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from dataclasses import dataclass, fields
|
|
6
|
-
from typing import Any, Literal, TypedDict
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Literal, TypedDict
|
|
7
7
|
|
|
8
8
|
from anthropic.types import Model # noqa: TC002
|
|
9
9
|
|
|
@@ -12,6 +12,10 @@ from clawd_code_sdk.models.hooks import AgentHooksConfig # noqa: TC001
|
|
|
12
12
|
from clawd_code_sdk.models.mcp import ExternalMcpServerConfig # noqa: TC001
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from collections.abc import Mapping
|
|
17
|
+
|
|
18
|
+
|
|
15
19
|
# Agent MCP server spec: either a string name or a {name: config} dict.
|
|
16
20
|
# Matches the TypeScript type: AgentMcpServerSpec =
|
|
17
21
|
# string | Record<string, McpServerConfigForProcessTransport>
|
|
@@ -57,7 +61,7 @@ class AgentDefinition:
|
|
|
57
61
|
tools: list[str] | None = None
|
|
58
62
|
model: ModelName | Literal["inherit"] | str | None = None # noqa: PYI051
|
|
59
63
|
memory: SettingSource | None = None
|
|
60
|
-
mcp_servers: list[AgentMcpServerSpec] |
|
|
64
|
+
mcp_servers: list[AgentMcpServerSpec] | Mapping[str, ExternalMcpServerConfig] | None = None
|
|
61
65
|
disallowed_tools: list[str] | None = None
|
|
62
66
|
critical_system_reminder_experimental: str | None = None
|
|
63
67
|
skills: list[str] | None = None
|
|
@@ -27,8 +27,14 @@ ElicitationMode = Literal["form", "url"]
|
|
|
27
27
|
ElicitationAction = Literal["accept", "decline", "cancel"]
|
|
28
28
|
FastModeState = Literal["off", "cooldown", "on"]
|
|
29
29
|
EffortLevel = Literal["low", "medium", "high", "max"]
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
AssistantMessageError = Literal[
|
|
31
|
+
"authentication_failed",
|
|
32
|
+
"billing_error",
|
|
33
|
+
"rate_limit",
|
|
34
|
+
"invalid_request",
|
|
35
|
+
"server_error",
|
|
36
|
+
"unknown",
|
|
37
|
+
]
|
|
32
38
|
StopReason = Literal[
|
|
33
39
|
"end_turn",
|
|
34
40
|
"max_tokens",
|
|
@@ -35,10 +35,12 @@ class SDKControlPermissionRequest:
|
|
|
35
35
|
subtype: Literal["can_use_tool"] = "can_use_tool"
|
|
36
36
|
tool_name: str
|
|
37
37
|
input: dict[str, Any]
|
|
38
|
-
tool_use_id: str
|
|
39
38
|
permission_suggestions: list[PermissionUpdate] | None = None
|
|
40
39
|
blocked_path: str | None = None
|
|
41
40
|
decision_reason: str | None = None
|
|
41
|
+
title: str | None = None
|
|
42
|
+
display_name: str | None = None
|
|
43
|
+
tool_use_id: str
|
|
42
44
|
agent_id: str | None = None
|
|
43
45
|
description: str | None = None
|
|
44
46
|
|
|
@@ -42,7 +42,7 @@ HookEvent = Literal[
|
|
|
42
42
|
"WorktreeRemove",
|
|
43
43
|
"InstructionsLoaded",
|
|
44
44
|
]
|
|
45
|
-
|
|
45
|
+
LoadReason = Literal["session_start", "nested_traversal", "path_glob_match", "include", "compact"]
|
|
46
46
|
|
|
47
47
|
# ---------------------------------------------------------------------------
|
|
48
48
|
# Declarative hook handler configs (for agent/skill frontmatter & settings)
|
|
@@ -338,7 +338,7 @@ class InstructionsLoadedHookInput(BaseHookInput):
|
|
|
338
338
|
hook_event_name: Literal["InstructionsLoaded"]
|
|
339
339
|
file_path: str
|
|
340
340
|
memory_type: Literal["User", "Project", "Local", "Managed"]
|
|
341
|
-
load_reason:
|
|
341
|
+
load_reason: LoadReason
|
|
342
342
|
globs: NotRequired[list[str]]
|
|
343
343
|
trigger_file_path: NotRequired[str]
|
|
344
344
|
parent_file_path: NotRequired[str]
|
|
@@ -33,8 +33,8 @@ class AgentInput(TypedDict):
|
|
|
33
33
|
|
|
34
34
|
Takes precedence over the agent definition's model frontmatter.
|
|
35
35
|
If omitted, uses the agent definition's model, or inherits from the parent."""
|
|
36
|
-
resume: NotRequired[str]
|
|
37
|
-
"""Optional agent ID to resume from in order to continue from the previous exec transcript."""
|
|
36
|
+
# resume: NotRequired[str]
|
|
37
|
+
# """Optional agent ID to resume from in order to continue from the previous exec transcript."""
|
|
38
38
|
run_in_background: NotRequired[bool]
|
|
39
39
|
"""Whether to run the agent in the background."""
|
|
40
40
|
name: NotRequired[str]
|
|
@@ -31,7 +31,12 @@ from clawd_code_sdk._errors import (
|
|
|
31
31
|
RateLimitError,
|
|
32
32
|
ServerError,
|
|
33
33
|
)
|
|
34
|
-
from clawd_code_sdk.models.base import
|
|
34
|
+
from clawd_code_sdk.models.base import ( # noqa: TC001
|
|
35
|
+
AssistantMessageError,
|
|
36
|
+
FastModeState,
|
|
37
|
+
StopReason,
|
|
38
|
+
ToolName,
|
|
39
|
+
)
|
|
35
40
|
from clawd_code_sdk.models.content_blocks import (
|
|
36
41
|
AssistantMessageContent,
|
|
37
42
|
MessageParam,
|
|
@@ -46,15 +51,6 @@ if TYPE_CHECKING:
|
|
|
46
51
|
|
|
47
52
|
|
|
48
53
|
# Message types
|
|
49
|
-
AssistantMessageError = Literal[
|
|
50
|
-
"authentication_failed",
|
|
51
|
-
"billing_error",
|
|
52
|
-
"rate_limit",
|
|
53
|
-
"invalid_request",
|
|
54
|
-
"server_error",
|
|
55
|
-
"unknown",
|
|
56
|
-
]
|
|
57
|
-
|
|
58
54
|
ErrorSubType = Literal[
|
|
59
55
|
"error_during_execution",
|
|
60
56
|
"error_max_turns",
|
|
@@ -173,6 +169,7 @@ class UserMessage(BaseMessage):
|
|
|
173
169
|
is_synthetic: bool | None = Field(default=None, validation_alias="isSynthetic")
|
|
174
170
|
priority: Literal["now", "next", "later"] | None = None
|
|
175
171
|
message: MessageParam
|
|
172
|
+
timestamp: str | None = None
|
|
176
173
|
|
|
177
174
|
@property
|
|
178
175
|
def content(self) -> str | Sequence[ContentBlock]:
|
|
@@ -334,5 +334,15 @@ class ClaudeAgentOptions:
|
|
|
334
334
|
|
|
335
335
|
return anyenv.dump_json(settings_obj) if settings_obj else None
|
|
336
336
|
|
|
337
|
-
def
|
|
338
|
-
|
|
337
|
+
def get_json_schema(self) -> dict[str, Any] | None:
|
|
338
|
+
from pydantic import TypeAdapter
|
|
339
|
+
|
|
340
|
+
match self.output_schema:
|
|
341
|
+
case type() as typ:
|
|
342
|
+
return TypeAdapter(typ).json_schema()
|
|
343
|
+
case dict() as schema:
|
|
344
|
+
return schema
|
|
345
|
+
case None:
|
|
346
|
+
return None
|
|
347
|
+
case _ as unreachable:
|
|
348
|
+
assert_never(unreachable)
|
|
@@ -112,18 +112,18 @@ class AgentAsyncLaunchedOutput(TypedDict):
|
|
|
112
112
|
"""Whether the calling agent has Read/Bash tools to check progress."""
|
|
113
113
|
|
|
114
114
|
|
|
115
|
-
class AgentQueuedToRunningOutput(TypedDict):
|
|
116
|
-
|
|
115
|
+
# class AgentQueuedToRunningOutput(TypedDict):
|
|
116
|
+
# """Output from the Task tool when an agent is queued to run."""
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
118
|
+
# status: Literal["queued_to_running"]
|
|
119
|
+
# """Indicates the agent is queued to run."""
|
|
120
|
+
# agentId: str
|
|
121
|
+
# """The ID of the async agent."""
|
|
122
|
+
# prompt: str
|
|
123
|
+
# """The prompt for the agent."""
|
|
124
124
|
|
|
125
125
|
|
|
126
|
-
AgentOutput = AgentCompletedOutput | AgentAsyncLaunchedOutput | AgentQueuedToRunningOutput
|
|
126
|
+
AgentOutput = AgentCompletedOutput | AgentAsyncLaunchedOutput # | AgentQueuedToRunningOutput
|
|
127
127
|
|
|
128
128
|
|
|
129
129
|
# ---------------------------------------------------------------------------
|
|
@@ -90,6 +90,25 @@ class ToolPermissionContext:
|
|
|
90
90
|
For example, when a Bash command tries to access a path outside allowed directories.
|
|
91
91
|
"""
|
|
92
92
|
|
|
93
|
+
title: str | None = None
|
|
94
|
+
"""Full permission prompt sentence rendered by the bridge.
|
|
95
|
+
|
|
96
|
+
E.g. "Claude wants to read foo.txt". Use this as the primary prompt
|
|
97
|
+
text when present instead of reconstructing from toolName+input.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
display_name: str | None = None
|
|
101
|
+
"""Short noun phrase for the tool action (e.g. "Read file").
|
|
102
|
+
|
|
103
|
+
Suitable for button labels or compact UI.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
description: str | None = None
|
|
107
|
+
"""Human-readable subtitle from the bridge.
|
|
108
|
+
|
|
109
|
+
E.g. "Claude will have read and write access to files in ~/Downloads".
|
|
110
|
+
"""
|
|
111
|
+
|
|
93
112
|
|
|
94
113
|
# Match TypeScript's PermissionResult structure
|
|
95
114
|
class PermissionResultAllow(ClaudeCodeBaseModel):
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
5
7
|
from anthropic.types import Model
|
|
6
8
|
from pydantic import Field
|
|
7
9
|
|
|
@@ -67,6 +69,13 @@ class ClaudeCodeAccountInfo(ClaudeCodeBaseModel):
|
|
|
67
69
|
organization: str | None = None
|
|
68
70
|
"""Organization name."""
|
|
69
71
|
|
|
72
|
+
api_provider: Literal["firstParty", "bedrock", "vertex", "foundry"] | None = None
|
|
73
|
+
"""Active API backend.
|
|
74
|
+
|
|
75
|
+
Anthropic OAuth login only applies when "firstParty"; for 3P providers
|
|
76
|
+
the other fields are absent and auth is external (AWS creds, gcloud ADC, etc.).
|
|
77
|
+
"""
|
|
78
|
+
|
|
70
79
|
|
|
71
80
|
class ClaudeCodeAgentInfo(ClaudeCodeBaseModel):
|
|
72
81
|
"""Information about an available subagent from Claude Code server."""
|
|
@@ -10,6 +10,7 @@ from pydantic import BaseModel, ConfigDict, Discriminator, TypeAdapter
|
|
|
10
10
|
from clawd_code_sdk.models import McpConnectionStatus
|
|
11
11
|
from clawd_code_sdk.models.base import ( # noqa: TC001
|
|
12
12
|
ApiKeySource,
|
|
13
|
+
AssistantMessageError,
|
|
13
14
|
CompactionTrigger,
|
|
14
15
|
FastModeState,
|
|
15
16
|
PermissionMode,
|
|
@@ -216,6 +217,17 @@ class TaskProgressSystemMessage(BaseSystemMessage):
|
|
|
216
217
|
"""AI-generated progress summary when agentProgressSummaries is enabled."""
|
|
217
218
|
|
|
218
219
|
|
|
220
|
+
class APIRetrySystemMessage(BaseSystemMessage):
|
|
221
|
+
"""System message emitted when an API call fails and is retried."""
|
|
222
|
+
|
|
223
|
+
subtype: Literal["api_retry"] = "api_retry"
|
|
224
|
+
attempt: int
|
|
225
|
+
max_retries: int
|
|
226
|
+
retry_delay_ms: int
|
|
227
|
+
error_status: int | None
|
|
228
|
+
error: AssistantMessageError
|
|
229
|
+
|
|
230
|
+
|
|
219
231
|
SystemMessageUnion = (
|
|
220
232
|
InitSystemMessage
|
|
221
233
|
| HookStartedSystemMessage
|
|
@@ -229,6 +241,7 @@ SystemMessageUnion = (
|
|
|
229
241
|
| FilesPersistedSystemMessage
|
|
230
242
|
| ElicitationCompleteMessage
|
|
231
243
|
| LocalCommandOutputMessage
|
|
244
|
+
| APIRetrySystemMessage
|
|
232
245
|
)
|
|
233
246
|
|
|
234
247
|
SystemMessages = Annotated[
|
|
@@ -243,7 +256,8 @@ SystemMessages = Annotated[
|
|
|
243
256
|
| TaskProgressSystemMessage
|
|
244
257
|
| FilesPersistedSystemMessage
|
|
245
258
|
| ElicitationCompleteMessage
|
|
246
|
-
| LocalCommandOutputMessage
|
|
259
|
+
| LocalCommandOutputMessage
|
|
260
|
+
| APIRetrySystemMessage,
|
|
247
261
|
Discriminator("subtype"),
|
|
248
262
|
]
|
|
249
263
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Thinking configuration models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
from clawd_code_sdk.models.base import ClaudeCodeBaseModel
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
ThinkingDisplay = Literal["summarized", "omitted"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Thinking configuration types
|
|
14
|
+
class ThinkingConfigAdaptive(ClaudeCodeBaseModel):
|
|
15
|
+
"""Adaptive thinking configuration - model decides thinking budget."""
|
|
16
|
+
|
|
17
|
+
type: Literal["adaptive"] = "adaptive"
|
|
18
|
+
|
|
19
|
+
display: ThinkingDisplay | None = None
|
|
20
|
+
"""Controls how thinking content appears in the response.
|
|
21
|
+
When set to `summarized`, thinking is returned normally. When set to `omitted`,
|
|
22
|
+
thinking content is redacted but a signature is returned for multi-turn
|
|
23
|
+
continuity. Defaults to `summarized`.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ThinkingConfigEnabled(ClaudeCodeBaseModel):
|
|
28
|
+
"""Enabled thinking configuration with explicit token budget."""
|
|
29
|
+
|
|
30
|
+
type: Literal["enabled"] = "enabled"
|
|
31
|
+
|
|
32
|
+
budget_tokens: int
|
|
33
|
+
"""Determines how many tokens Claude can use for its internal reasoning process.
|
|
34
|
+
Larger budgets can enable more thorough analysis for complex problems, improving
|
|
35
|
+
response quality.
|
|
36
|
+
Must be ≥1024 and less than `max_tokens`.
|
|
37
|
+
See
|
|
38
|
+
[extended thinking](https://docs.claude.com/en/docs/build-with-claude/extended-thinking)
|
|
39
|
+
for details.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
display: ThinkingDisplay | None = None
|
|
43
|
+
"""Controls how thinking content appears in the response.
|
|
44
|
+
When set to `summarized`, thinking is returned normally. When set to `omitted`,
|
|
45
|
+
thinking content is redacted but a signature is returned for multi-turn
|
|
46
|
+
continuity. Defaults to `summarized`.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class ThinkingConfigDisabled(ClaudeCodeBaseModel):
|
|
51
|
+
"""Disabled thinking configuration."""
|
|
52
|
+
|
|
53
|
+
type: Literal["disabled"] = "disabled"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
ThinkingConfig = ThinkingConfigAdaptive | ThinkingConfigEnabled | ThinkingConfigDisabled
|
|
@@ -92,8 +92,8 @@ class TestSubprocessBuffering:
|
|
|
92
92
|
mock_process.returncode = None
|
|
93
93
|
mock_process.wait = AsyncMock(return_value=None)
|
|
94
94
|
transport._process = mock_process
|
|
95
|
-
transport._stdout_stream = MockTextReceiveStream([buffered_line]) # pyright: ignore[reportAttributeAccessIssue]
|
|
96
|
-
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue]
|
|
95
|
+
transport._stdout_stream = MockTextReceiveStream([buffered_line]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
96
|
+
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
97
97
|
messages = [msg async for msg in transport.read_messages()]
|
|
98
98
|
assert len(messages) == 2
|
|
99
99
|
assert messages[0]["content"] == "Line 1\nLine 2\nLine 3"
|
|
@@ -113,8 +113,8 @@ class TestSubprocessBuffering:
|
|
|
113
113
|
mock_process.returncode = None
|
|
114
114
|
mock_process.wait = AsyncMock(return_value=None)
|
|
115
115
|
transport._process = mock_process
|
|
116
|
-
transport._stdout_stream = MockTextReceiveStream([buffered_line]) # pyright: ignore[reportAttributeAccessIssue]
|
|
117
|
-
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue]
|
|
116
|
+
transport._stdout_stream = MockTextReceiveStream([buffered_line]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
117
|
+
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
118
118
|
messages = [msg async for msg in transport.read_messages()]
|
|
119
119
|
assert len(messages) == 2
|
|
120
120
|
assert messages[0]["id"] == "msg1"
|
|
@@ -150,8 +150,8 @@ class TestSubprocessBuffering:
|
|
|
150
150
|
mock_process.returncode = None
|
|
151
151
|
mock_process.wait = AsyncMock(return_value=None)
|
|
152
152
|
transport._process = mock_process
|
|
153
|
-
transport._stdout_stream = MockTextReceiveStream([part1, part2, part3]) # pyright: ignore[reportAttributeAccessIssue]
|
|
154
|
-
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue]
|
|
153
|
+
transport._stdout_stream = MockTextReceiveStream([part1, part2, part3]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
154
|
+
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
155
155
|
messages = [msg async for msg in transport.read_messages()]
|
|
156
156
|
assert len(messages) == 1
|
|
157
157
|
assert messages[0]["type"] == "assistant"
|
|
@@ -187,8 +187,8 @@ class TestSubprocessBuffering:
|
|
|
187
187
|
mock_process.returncode = None
|
|
188
188
|
mock_process.wait = AsyncMock(return_value=None)
|
|
189
189
|
transport._process = mock_process
|
|
190
|
-
transport._stdout_stream = MockTextReceiveStream(chunks) # pyright: ignore[reportAttributeAccessIssue]
|
|
191
|
-
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue]
|
|
190
|
+
transport._stdout_stream = MockTextReceiveStream(chunks) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
191
|
+
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
192
192
|
messages = [msg async for msg in transport.read_messages()]
|
|
193
193
|
assert len(messages) == 1
|
|
194
194
|
assert messages[0]["type"] == "user"
|
|
@@ -209,8 +209,8 @@ class TestSubprocessBuffering:
|
|
|
209
209
|
mock_process.returncode = None
|
|
210
210
|
mock_process.wait = AsyncMock(return_value=None)
|
|
211
211
|
transport._process = mock_process
|
|
212
|
-
transport._stdout_stream = MockTextReceiveStream([huge_incomplete]) # pyright: ignore[reportAttributeAccessIssue]
|
|
213
|
-
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue]
|
|
212
|
+
transport._stdout_stream = MockTextReceiveStream([huge_incomplete]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
213
|
+
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
214
214
|
with pytest.raises(Exception) as exc_info: # noqa: PT011
|
|
215
215
|
_messages = [msg async for msg in transport.read_messages()]
|
|
216
216
|
|
|
@@ -231,8 +231,8 @@ class TestSubprocessBuffering:
|
|
|
231
231
|
mock_process.returncode = None
|
|
232
232
|
mock_process.wait = AsyncMock(return_value=None)
|
|
233
233
|
transport._process = mock_process
|
|
234
|
-
transport._stdout_stream = MockTextReceiveStream([huge_incomplete]) # pyright: ignore[reportAttributeAccessIssue]
|
|
235
|
-
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue]
|
|
234
|
+
transport._stdout_stream = MockTextReceiveStream([huge_incomplete]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
235
|
+
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
236
236
|
|
|
237
237
|
with pytest.raises(CLIJSONDecodeError) as exc_info:
|
|
238
238
|
async for _ in transport.read_messages():
|
|
@@ -264,8 +264,8 @@ class TestSubprocessBuffering:
|
|
|
264
264
|
mock_process.returncode = None
|
|
265
265
|
mock_process.wait = AsyncMock(return_value=None)
|
|
266
266
|
transport._process = mock_process
|
|
267
|
-
transport._stdout_stream = MockTextReceiveStream(lines) # pyright: ignore[reportAttributeAccessIssue]
|
|
268
|
-
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue]
|
|
267
|
+
transport._stdout_stream = MockTextReceiveStream(lines) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
268
|
+
transport._stderr_stream = MockTextReceiveStream([]) # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
269
269
|
messages = [msg async for msg in transport.read_messages()]
|
|
270
270
|
assert len(messages) == 3
|
|
271
271
|
assert messages[0]["type"] == "system"
|
|
@@ -26,7 +26,14 @@ async def _dispatch(query: Query, request: dict[str, Any]) -> None:
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
if TYPE_CHECKING:
|
|
29
|
-
from clawd_code_sdk import
|
|
29
|
+
from clawd_code_sdk import (
|
|
30
|
+
HookContext,
|
|
31
|
+
HookInput,
|
|
32
|
+
HookJSONOutput,
|
|
33
|
+
PermissionResult,
|
|
34
|
+
ToolPermissionContext,
|
|
35
|
+
)
|
|
36
|
+
from clawd_code_sdk.models import HookEvent, ToolInput
|
|
30
37
|
|
|
31
38
|
|
|
32
39
|
class MockTransport(Transport):
|
|
@@ -65,7 +72,7 @@ class TestToolPermissionCallbacks:
|
|
|
65
72
|
callback_invoked = False
|
|
66
73
|
|
|
67
74
|
async def allow_callback(
|
|
68
|
-
tool_name: str, input_data: dict, context: ToolPermissionContext
|
|
75
|
+
tool_name: str, input_data: ToolInput | dict[str, Any], context: ToolPermissionContext
|
|
69
76
|
) -> PermissionResultAllow:
|
|
70
77
|
nonlocal callback_invoked
|
|
71
78
|
callback_invoked = True
|
|
@@ -97,7 +104,7 @@ class TestToolPermissionCallbacks:
|
|
|
97
104
|
"""Test callback that denies tool execution."""
|
|
98
105
|
|
|
99
106
|
async def deny_callback(
|
|
100
|
-
tool_name: str, input_data: dict, context: ToolPermissionContext
|
|
107
|
+
tool_name: str, input_data: ToolInput | dict[str, Any], context: ToolPermissionContext
|
|
101
108
|
) -> PermissionResultDeny:
|
|
102
109
|
return PermissionResultDeny(message="Security policy violation")
|
|
103
110
|
|
|
@@ -130,7 +137,7 @@ class TestToolPermissionCallbacks:
|
|
|
130
137
|
"""Test callback that modifies tool input."""
|
|
131
138
|
|
|
132
139
|
async def modify_callback(
|
|
133
|
-
tool_name: str, input_data: dict, context: ToolPermissionContext
|
|
140
|
+
tool_name: str, input_data: ToolInput | dict[str, Any], context: ToolPermissionContext
|
|
134
141
|
) -> PermissionResultAllow:
|
|
135
142
|
# Modify the input to add safety flag
|
|
136
143
|
modified_input = input_data.copy()
|
|
@@ -138,11 +145,7 @@ class TestToolPermissionCallbacks:
|
|
|
138
145
|
return PermissionResultAllow(updated_input=modified_input)
|
|
139
146
|
|
|
140
147
|
transport = MockTransport()
|
|
141
|
-
query = Query(
|
|
142
|
-
transport=transport,
|
|
143
|
-
can_use_tool=modify_callback,
|
|
144
|
-
hooks=None,
|
|
145
|
-
)
|
|
148
|
+
query = Query(transport=transport, can_use_tool=modify_callback)
|
|
146
149
|
request_data = SDKControlPermissionRequest(
|
|
147
150
|
tool_name="WriteTool",
|
|
148
151
|
input={"file_path": "/etc/passwd"},
|
|
@@ -161,16 +164,12 @@ class TestToolPermissionCallbacks:
|
|
|
161
164
|
"""Test that callback exceptions are properly handled."""
|
|
162
165
|
|
|
163
166
|
async def error_callback(
|
|
164
|
-
tool_name: str, input_data: dict, context: ToolPermissionContext
|
|
165
|
-
) ->
|
|
167
|
+
tool_name: str, input_data: ToolInput | dict[str, Any], context: ToolPermissionContext
|
|
168
|
+
) -> PermissionResult:
|
|
166
169
|
raise ValueError("Callback error")
|
|
167
170
|
|
|
168
171
|
transport = MockTransport()
|
|
169
|
-
query = Query(
|
|
170
|
-
transport=transport,
|
|
171
|
-
can_use_tool=error_callback,
|
|
172
|
-
hooks=None,
|
|
173
|
-
)
|
|
172
|
+
query = Query(transport=transport, can_use_tool=error_callback)
|
|
174
173
|
request_data = SDKControlPermissionRequest(
|
|
175
174
|
tool_name="TestTool",
|
|
176
175
|
input={},
|
|
@@ -201,7 +200,9 @@ class TestHookCallbacks:
|
|
|
201
200
|
|
|
202
201
|
transport = MockTransport()
|
|
203
202
|
# Create hooks configuration
|
|
204
|
-
hooks
|
|
203
|
+
hooks: dict[HookEvent, list[HookMatcher]] = {
|
|
204
|
+
"tool_use_start": [HookMatcher(matcher="TestTool", hooks=[test_hook])]
|
|
205
|
+
}
|
|
205
206
|
query = Query(transport=transport, can_use_tool=None, hooks=hooks)
|
|
206
207
|
# Manually register the hook callback to avoid needing the full initialize flow
|
|
207
208
|
callback_id = "test_hook_0"
|
|
@@ -261,7 +262,9 @@ class TestHookCallbacks:
|
|
|
261
262
|
}
|
|
262
263
|
|
|
263
264
|
transport = MockTransport()
|
|
264
|
-
hooks
|
|
265
|
+
hooks: dict[HookEvent, list[HookMatcher]] = {
|
|
266
|
+
"PreToolUse": [HookMatcher(matcher="TestTool", hooks=[comprehensive_hook])]
|
|
267
|
+
}
|
|
265
268
|
|
|
266
269
|
query = Query(transport=transport, can_use_tool=None, hooks=hooks)
|
|
267
270
|
|
|
@@ -319,7 +322,9 @@ class TestHookCallbacks:
|
|
|
319
322
|
return {"async_": True, "asyncTimeout": 5000}
|
|
320
323
|
|
|
321
324
|
transport = MockTransport()
|
|
322
|
-
hooks
|
|
325
|
+
hooks: dict[HookEvent, list[HookMatcher]] = {
|
|
326
|
+
"PreToolUse": [HookMatcher(hooks=[async_hook])]
|
|
327
|
+
}
|
|
323
328
|
query = Query(transport=transport, can_use_tool=None, hooks=hooks)
|
|
324
329
|
callback_id = "test_async_hook"
|
|
325
330
|
query.hook_callbacks[callback_id] = async_hook
|
|
@@ -369,7 +374,9 @@ class TestHookCallbacks:
|
|
|
369
374
|
}
|
|
370
375
|
|
|
371
376
|
transport = MockTransport()
|
|
372
|
-
hooks
|
|
377
|
+
hooks: dict[HookEvent, list[HookMatcher]] = {
|
|
378
|
+
"PreToolUse": [HookMatcher(hooks=[conversion_test_hook])]
|
|
379
|
+
}
|
|
373
380
|
query = Query(transport=transport, can_use_tool=None, hooks=hooks)
|
|
374
381
|
callback_id = "test_conversion"
|
|
375
382
|
query.hook_callbacks[callback_id] = conversion_test_hook
|
|
@@ -21,6 +21,7 @@ from clawd_code_sdk.models import (
|
|
|
21
21
|
AgentDefinition,
|
|
22
22
|
ClaudeAgentOptions,
|
|
23
23
|
ClaudeCodeSettings,
|
|
24
|
+
McpStdioServerConfig,
|
|
24
25
|
Network,
|
|
25
26
|
Permissions,
|
|
26
27
|
Sandbox,
|
|
@@ -28,6 +29,7 @@ from clawd_code_sdk.models import (
|
|
|
28
29
|
ThinkingConfigDisabled,
|
|
29
30
|
ThinkingConfigEnabled,
|
|
30
31
|
)
|
|
32
|
+
from clawd_code_sdk.models.mcp import McpSSEServerConfig
|
|
31
33
|
|
|
32
34
|
|
|
33
35
|
DEFAULT_CLI_PATH = "/usr/bin/claude"
|
|
@@ -797,7 +799,7 @@ class TestSubprocessCLITransport:
|
|
|
797
799
|
async def __aexit__(self, *args):
|
|
798
800
|
pass
|
|
799
801
|
|
|
800
|
-
transport._write_lock = NoOpLock() # pyright: ignore[reportAttributeAccessIssue]
|
|
802
|
+
transport._write_lock = NoOpLock() # pyright: ignore[reportAttributeAccessIssue] # ty:ignore[invalid-assignment]
|
|
801
803
|
|
|
802
804
|
# Without the lock, writes may interleave. We verify the lock
|
|
803
805
|
# exists and is used by checking the serialized test passes
|
|
@@ -983,7 +985,7 @@ class TestSubprocessCLITransport:
|
|
|
983
985
|
description="Agent with MCP servers",
|
|
984
986
|
prompt="You have MCP tools",
|
|
985
987
|
mcp_servers={
|
|
986
|
-
"git":
|
|
988
|
+
"git": McpStdioServerConfig(command="uvx", args=["mcp-server-git"]),
|
|
987
989
|
},
|
|
988
990
|
)
|
|
989
991
|
serialized = agent_with_mcp.to_dict()
|
|
@@ -1042,7 +1044,7 @@ class TestSubprocessCLITransport:
|
|
|
1042
1044
|
model="sonnet",
|
|
1043
1045
|
memory="project",
|
|
1044
1046
|
mcp_servers={
|
|
1045
|
-
"git":
|
|
1047
|
+
"git": McpStdioServerConfig(command="uvx", args=["mcp-server-git"]),
|
|
1046
1048
|
},
|
|
1047
1049
|
)
|
|
1048
1050
|
serialized = agent.to_dict()
|
|
@@ -1063,8 +1065,8 @@ class TestSubprocessCLITransport:
|
|
|
1063
1065
|
description="Multi-MCP agent",
|
|
1064
1066
|
prompt="You have many tools",
|
|
1065
1067
|
mcp_servers={
|
|
1066
|
-
"git":
|
|
1067
|
-
"remote":
|
|
1068
|
+
"git": McpStdioServerConfig(command="uvx", args=["mcp-server-git"]),
|
|
1069
|
+
"remote": McpSSEServerConfig(type="sse", url="http://localhost:8080/sse"),
|
|
1068
1070
|
},
|
|
1069
1071
|
)
|
|
1070
1072
|
serialized = agent.to_dict()
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"""Thinking configuration models."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from typing import Literal
|
|
6
|
-
|
|
7
|
-
from clawd_code_sdk.models.base import ClaudeCodeBaseModel
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# Thinking configuration types
|
|
11
|
-
class ThinkingConfigAdaptive(ClaudeCodeBaseModel):
|
|
12
|
-
"""Adaptive thinking configuration - model decides thinking budget."""
|
|
13
|
-
|
|
14
|
-
type: Literal["adaptive"] = "adaptive"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class ThinkingConfigEnabled(ClaudeCodeBaseModel):
|
|
18
|
-
"""Enabled thinking configuration with explicit token budget."""
|
|
19
|
-
|
|
20
|
-
type: Literal["enabled"] = "enabled"
|
|
21
|
-
budget_tokens: int
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class ThinkingConfigDisabled(ClaudeCodeBaseModel):
|
|
25
|
-
"""Disabled thinking configuration."""
|
|
26
|
-
|
|
27
|
-
type: Literal["disabled"] = "disabled"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
ThinkingConfig = ThinkingConfigAdaptive | ThinkingConfigEnabled | ThinkingConfigDisabled
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/_internal/message_parser.py
RENAMED
|
File without changes
|
|
File without changes
|
{clawd_code_sdk-1.0.7 → clawd_code_sdk-1.0.8}/src/clawd_code_sdk/_internal/transport/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
from .agents import AgentDefinition, AgentInfo, ToolsPreset
|
|
6
6
|
from .base import (
|
|
7
7
|
ApiKeySource,
|
|
8
|
+
AssistantMessageError,
|
|
8
9
|
ElicitationAction,
|
|
9
10
|
ElicitationMode,
|
|
10
11
|
PermissionMode,
|
|
@@ -223,7 +224,6 @@ from .content_blocks import (
|
|
|
223
224
|
from .session import SDKSessionInfo, ListSessionsOptions
|
|
224
225
|
from .messages import (
|
|
225
226
|
AssistantMessage,
|
|
226
|
-
AssistantMessageError,
|
|
227
227
|
ModelUsage,
|
|
228
228
|
BaseResultMessage,
|
|
229
229
|
PromptSuggestionMessage,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|