clawd-code-sdk 0.2.1__tar.gz → 0.2.2__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-0.2.1 → clawd_code_sdk-0.2.2}/PKG-INFO +2 -2
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/README.md +1 -1
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/pyproject.toml +1 -1
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/__init__.py +4 -2
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/_internal/transport/subprocess_cli.py +6 -16
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/client.py +3 -3
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/__init__.py +6 -2
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/messages.py +24 -27
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/options.py +12 -10
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/storage/replay.py +1 -1
- clawd_code_sdk-0.2.2/tests/conftest.py +35 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_client.py +39 -50
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_integration.py +14 -23
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_message_parser.py +17 -21
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_session.py +8 -10
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_streaming_client.py +14 -35
- clawd_code_sdk-0.2.1/tests/conftest.py +0 -10
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/.gitignore +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/LICENSE +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/_bundled/.gitignore +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/_errors.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/_internal/__init__.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/_internal/message_parser.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/_internal/query.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/_internal/transport/__init__.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/_version.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/anthropic_types.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/mcp_utils.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/agents.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/base.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/content_blocks.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/control.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/hooks.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/input_types.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/mcp.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/output_types.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/permissions.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/sandbox.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/server_info.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/models/ts_output_types.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/py.typed +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/query.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/session.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/storage/ARCHITECTURE.md +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/storage/__init__.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/storage/helpers.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/storage/models.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/usage.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/mcp_server.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_changelog.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_errors.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_image.png +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_sdk_mcp_integration.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_subprocess_buffering.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_tool_callbacks.py +0 -0
- {clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/tests/test_transport.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: clawd-code-sdk
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
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
|
|
@@ -271,7 +271,7 @@ async with ClaudeSDKClient(options=options) as client:
|
|
|
271
271
|
See [src/clawd_code_sdk/types.py](src/clawd_code_sdk/types.py) for complete type definitions:
|
|
272
272
|
|
|
273
273
|
- `ClaudeAgentOptions` - Configuration options
|
|
274
|
-
- `AssistantMessage`, `UserMessage`, `
|
|
274
|
+
- `AssistantMessage`, `UserMessage`, `InitSystemMessage`, `ResultMessage` - Message types
|
|
275
275
|
- `TextBlock`, `ToolUseBlock`, `ToolResultBlock` - Content blocks
|
|
276
276
|
|
|
277
277
|
## Error Handling
|
|
@@ -238,7 +238,7 @@ async with ClaudeSDKClient(options=options) as client:
|
|
|
238
238
|
See [src/clawd_code_sdk/types.py](src/clawd_code_sdk/types.py) for complete type definitions:
|
|
239
239
|
|
|
240
240
|
- `ClaudeAgentOptions` - Configuration options
|
|
241
|
-
- `AssistantMessage`, `UserMessage`, `
|
|
241
|
+
- `AssistantMessage`, `UserMessage`, `InitSystemMessage`, `ResultMessage` - Message types
|
|
242
242
|
- `TextBlock`, `ToolUseBlock`, `ToolResultBlock` - Content blocks
|
|
243
243
|
|
|
244
244
|
## Error Handling
|
|
@@ -61,7 +61,8 @@ from .models import (
|
|
|
61
61
|
SubagentStartHookInput,
|
|
62
62
|
SubagentStartHookSpecificOutput,
|
|
63
63
|
SubagentStopHookInput,
|
|
64
|
-
|
|
64
|
+
BaseSystemMessage,
|
|
65
|
+
InitSystemMessage,
|
|
65
66
|
TextBlock,
|
|
66
67
|
ThinkingBlock,
|
|
67
68
|
ThinkingConfig,
|
|
@@ -115,7 +116,8 @@ __all__ = [
|
|
|
115
116
|
"UserPromptMessage",
|
|
116
117
|
"UserPromptMessageContent",
|
|
117
118
|
"AssistantMessage",
|
|
118
|
-
"
|
|
119
|
+
"BaseSystemMessage",
|
|
120
|
+
"InitSystemMessage",
|
|
119
121
|
"ResultMessage",
|
|
120
122
|
"Message",
|
|
121
123
|
"ClaudeAgentOptions",
|
|
@@ -125,30 +125,20 @@ class SubprocessCLITransport(Transport):
|
|
|
125
125
|
|
|
126
126
|
session = resolve_session_config(self._options.session)
|
|
127
127
|
match session:
|
|
128
|
-
case NewSession(session_id=sid
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if not persist:
|
|
132
|
-
cmd.append("--no-persist-session")
|
|
133
|
-
case ResumeSession(
|
|
134
|
-
session_id=sid,
|
|
135
|
-
fork=fork,
|
|
136
|
-
at_message=at_msg,
|
|
137
|
-
persist=persist,
|
|
138
|
-
):
|
|
128
|
+
case NewSession(session_id=sid) if sid is not None:
|
|
129
|
+
cmd.extend(["--session-id", sid])
|
|
130
|
+
case ResumeSession(session_id=sid, fork=fork, at_message=at_msg):
|
|
139
131
|
cmd.extend(["--resume", sid])
|
|
140
132
|
if fork:
|
|
141
133
|
cmd.append("--fork-session")
|
|
142
134
|
if at_msg is not None:
|
|
143
135
|
cmd.extend(["--resume-session-at", at_msg])
|
|
144
|
-
|
|
145
|
-
cmd.append("--no-persist-session")
|
|
146
|
-
case ContinueLatest(fork=fork, persist=persist):
|
|
136
|
+
case ContinueLatest(fork=fork):
|
|
147
137
|
cmd.append("--continue")
|
|
148
138
|
if fork:
|
|
149
139
|
cmd.append("--fork-session")
|
|
150
|
-
|
|
151
|
-
|
|
140
|
+
if not session.persist:
|
|
141
|
+
cmd.append("--no-persist-session")
|
|
152
142
|
|
|
153
143
|
# Handle settings and sandbox: merge sandbox into settings if both are provided
|
|
154
144
|
if settings_value := self._options.build_settings_value():
|
|
@@ -128,10 +128,10 @@ class ClaudeSDKClient:
|
|
|
128
128
|
# JSON schema for structured output
|
|
129
129
|
json_schema: dict[str, Any] | None
|
|
130
130
|
match self.options.output_schema:
|
|
131
|
-
case type() as
|
|
131
|
+
case type() as typ:
|
|
132
132
|
from pydantic import TypeAdapter
|
|
133
133
|
|
|
134
|
-
json_schema = TypeAdapter(
|
|
134
|
+
json_schema = TypeAdapter(typ).json_schema()
|
|
135
135
|
case dict() as schema:
|
|
136
136
|
json_schema = schema
|
|
137
137
|
case None:
|
|
@@ -342,7 +342,7 @@ class ClaudeSDKClient:
|
|
|
342
342
|
- If no ResultMessage is received, the iterator continues indefinitely
|
|
343
343
|
|
|
344
344
|
Yields:
|
|
345
|
-
Message: Each message received (UserMessage, AssistantMessage,
|
|
345
|
+
Message: Each message received (UserMessage, AssistantMessage, InitSystemMessage, ResultMessage)
|
|
346
346
|
|
|
347
347
|
Example:
|
|
348
348
|
```python
|
|
@@ -200,9 +200,11 @@ from .content_blocks import (
|
|
|
200
200
|
from .messages import (
|
|
201
201
|
AssistantMessage,
|
|
202
202
|
AssistantMessageError,
|
|
203
|
+
BaseSystemMessage,
|
|
203
204
|
CompactBoundarySystemMessage,
|
|
204
205
|
HookResponseSystemMessage,
|
|
205
206
|
HookStartedSystemMessage,
|
|
207
|
+
InitSystemMessage,
|
|
206
208
|
McpServerStatus,
|
|
207
209
|
Message,
|
|
208
210
|
ModelUsage,
|
|
@@ -210,7 +212,6 @@ from .messages import (
|
|
|
210
212
|
SDKPermissionDenial,
|
|
211
213
|
StatusSystemMessage,
|
|
212
214
|
StreamEvent,
|
|
213
|
-
SystemMessage,
|
|
214
215
|
AuthStatusMessage,
|
|
215
216
|
FilesPersistedSystemMessage,
|
|
216
217
|
HookProgressSystemMessage,
|
|
@@ -229,6 +230,7 @@ from .messages import (
|
|
|
229
230
|
)
|
|
230
231
|
from .options import ClaudeAgentOptions
|
|
231
232
|
from .options import (
|
|
233
|
+
BaseSessionConfig,
|
|
232
234
|
ContinueLatest,
|
|
233
235
|
NewSession,
|
|
234
236
|
ResumeSession,
|
|
@@ -337,10 +339,12 @@ __all__ = [
|
|
|
337
339
|
# messages
|
|
338
340
|
"AssistantMessage",
|
|
339
341
|
"AssistantMessageError",
|
|
342
|
+
"BaseSystemMessage",
|
|
340
343
|
"CompactBoundarySystemMessage",
|
|
341
344
|
"ContentBlock",
|
|
342
345
|
"HookResponseSystemMessage",
|
|
343
346
|
"HookStartedSystemMessage",
|
|
347
|
+
"InitSystemMessage",
|
|
344
348
|
"McpServerStatus",
|
|
345
349
|
"Message",
|
|
346
350
|
"ModelUsage",
|
|
@@ -348,7 +352,6 @@ __all__ = [
|
|
|
348
352
|
"SDKPermissionDenial",
|
|
349
353
|
"StatusSystemMessage",
|
|
350
354
|
"StreamEvent",
|
|
351
|
-
"SystemMessage",
|
|
352
355
|
"AuthStatusMessage",
|
|
353
356
|
"FilesPersistedSystemMessage",
|
|
354
357
|
"HookProgressSystemMessage",
|
|
@@ -371,6 +374,7 @@ __all__ = [
|
|
|
371
374
|
"system_message_adapter",
|
|
372
375
|
# options
|
|
373
376
|
"ClaudeAgentOptions",
|
|
377
|
+
"BaseSessionConfig",
|
|
374
378
|
"ContinueLatest",
|
|
375
379
|
"NewSession",
|
|
376
380
|
"ResumeSession",
|
|
@@ -79,6 +79,13 @@ class BaseMessage:
|
|
|
79
79
|
session_id: str
|
|
80
80
|
|
|
81
81
|
|
|
82
|
+
@dataclass(kw_only=True)
|
|
83
|
+
class BaseSystemMessage(BaseMessage):
|
|
84
|
+
"""Base class for all system messages."""
|
|
85
|
+
|
|
86
|
+
type: Literal["system"] = "system"
|
|
87
|
+
|
|
88
|
+
|
|
82
89
|
@dataclass(kw_only=True)
|
|
83
90
|
class UserMessage(BaseMessage):
|
|
84
91
|
"""User message."""
|
|
@@ -164,10 +171,9 @@ class Plugin:
|
|
|
164
171
|
|
|
165
172
|
|
|
166
173
|
@dataclass(kw_only=True)
|
|
167
|
-
class
|
|
168
|
-
"""System message with metadata."""
|
|
174
|
+
class InitSystemMessage(BaseSystemMessage):
|
|
175
|
+
"""System init message with session metadata."""
|
|
169
176
|
|
|
170
|
-
type: Literal["system"] = "system"
|
|
171
177
|
subtype: Literal["init"] = "init"
|
|
172
178
|
apiKeySource: ApiKeySource | None = None # noqa: N815
|
|
173
179
|
cwd: str
|
|
@@ -185,10 +191,9 @@ class SystemMessage(BaseMessage):
|
|
|
185
191
|
|
|
186
192
|
|
|
187
193
|
@dataclass(kw_only=True)
|
|
188
|
-
class HookStartedSystemMessage(
|
|
189
|
-
"""System message
|
|
194
|
+
class HookStartedSystemMessage(BaseSystemMessage):
|
|
195
|
+
"""System message emitted when a hook starts."""
|
|
190
196
|
|
|
191
|
-
type: Literal["system"] = "system"
|
|
192
197
|
subtype: Literal["hook_started"] = "hook_started"
|
|
193
198
|
hook_id: str | None = None
|
|
194
199
|
hook_name: str | None = None
|
|
@@ -196,12 +201,11 @@ class HookStartedSystemMessage(BaseMessage):
|
|
|
196
201
|
|
|
197
202
|
|
|
198
203
|
@dataclass(kw_only=True)
|
|
199
|
-
class StatusSystemMessage(
|
|
204
|
+
class StatusSystemMessage(BaseSystemMessage):
|
|
200
205
|
"""System status message."""
|
|
201
206
|
|
|
202
|
-
type: Literal["system"] = "system"
|
|
203
207
|
subtype: Literal["status"] = "status"
|
|
204
|
-
status: Literal["compacting"] |
|
|
208
|
+
status: Literal["compacting"] | None
|
|
205
209
|
|
|
206
210
|
|
|
207
211
|
class TriggerMetadata(TypedDict):
|
|
@@ -210,10 +214,9 @@ class TriggerMetadata(TypedDict):
|
|
|
210
214
|
|
|
211
215
|
|
|
212
216
|
@dataclass(kw_only=True)
|
|
213
|
-
class CompactBoundarySystemMessage(
|
|
214
|
-
"""System message
|
|
217
|
+
class CompactBoundarySystemMessage(BaseSystemMessage):
|
|
218
|
+
"""System message emitted at compaction boundaries."""
|
|
215
219
|
|
|
216
|
-
type: Literal["system"] = "system"
|
|
217
220
|
subtype: Literal["compact_boundary"] = "compact_boundary"
|
|
218
221
|
compact_metadata: TriggerMetadata
|
|
219
222
|
|
|
@@ -237,10 +240,9 @@ class RateLimitMessage(BaseMessage):
|
|
|
237
240
|
|
|
238
241
|
|
|
239
242
|
@dataclass(kw_only=True)
|
|
240
|
-
class TaskStartedSystemMessage(
|
|
243
|
+
class TaskStartedSystemMessage(BaseSystemMessage):
|
|
241
244
|
"""System message emitted when a subagent task starts."""
|
|
242
245
|
|
|
243
|
-
type: Literal["system"] = "system"
|
|
244
246
|
subtype: Literal["task_started"] = "task_started"
|
|
245
247
|
task_id: str = ""
|
|
246
248
|
tool_use_id: str | None = None
|
|
@@ -249,10 +251,9 @@ class TaskStartedSystemMessage(BaseMessage):
|
|
|
249
251
|
|
|
250
252
|
|
|
251
253
|
@dataclass(kw_only=True)
|
|
252
|
-
class TaskNotificationSystemMessage(
|
|
254
|
+
class TaskNotificationSystemMessage(BaseSystemMessage):
|
|
253
255
|
"""System message emitted when a subagent task completes, fails, or stops."""
|
|
254
256
|
|
|
255
|
-
type: Literal["system"] = "system"
|
|
256
257
|
subtype: Literal["task_notification"] = "task_notification"
|
|
257
258
|
task_id: str = ""
|
|
258
259
|
status: Literal["completed", "failed", "stopped"] = "completed"
|
|
@@ -270,10 +271,9 @@ class TaskProgressUsage(TypedDict):
|
|
|
270
271
|
|
|
271
272
|
|
|
272
273
|
@dataclass(kw_only=True)
|
|
273
|
-
class TaskProgressSystemMessage(
|
|
274
|
+
class TaskProgressSystemMessage(BaseSystemMessage):
|
|
274
275
|
"""System message emitted periodically with task progress updates."""
|
|
275
276
|
|
|
276
|
-
type: Literal["system"] = "system"
|
|
277
277
|
subtype: Literal["task_progress"] = "task_progress"
|
|
278
278
|
task_id: str = ""
|
|
279
279
|
tool_use_id: str | None = None
|
|
@@ -297,10 +297,9 @@ class FilePersistedFailure(TypedDict):
|
|
|
297
297
|
|
|
298
298
|
|
|
299
299
|
@dataclass(kw_only=True)
|
|
300
|
-
class FilesPersistedSystemMessage(
|
|
300
|
+
class FilesPersistedSystemMessage(BaseSystemMessage):
|
|
301
301
|
"""System message emitted when files have been persisted."""
|
|
302
302
|
|
|
303
|
-
type: Literal["system"] = "system"
|
|
304
303
|
subtype: Literal["files_persisted"] = "files_persisted"
|
|
305
304
|
files: list[FilePersistedEntry] | None = None
|
|
306
305
|
failed: list[FilePersistedFailure] | None = None
|
|
@@ -310,10 +309,9 @@ class FilesPersistedSystemMessage(BaseMessage):
|
|
|
310
309
|
|
|
311
310
|
|
|
312
311
|
@dataclass(kw_only=True)
|
|
313
|
-
class HookProgressSystemMessage(
|
|
312
|
+
class HookProgressSystemMessage(BaseSystemMessage):
|
|
314
313
|
"""Progress update from a running hook."""
|
|
315
314
|
|
|
316
|
-
type: Literal["system"] = "system"
|
|
317
315
|
subtype: Literal["hook_progress"] = "hook_progress"
|
|
318
316
|
hook_id: str = ""
|
|
319
317
|
hook_name: str = ""
|
|
@@ -324,10 +322,9 @@ class HookProgressSystemMessage(BaseMessage):
|
|
|
324
322
|
|
|
325
323
|
|
|
326
324
|
@dataclass(kw_only=True)
|
|
327
|
-
class HookResponseSystemMessage(
|
|
328
|
-
"""System message
|
|
325
|
+
class HookResponseSystemMessage(BaseSystemMessage):
|
|
326
|
+
"""System message emitted when a hook completes."""
|
|
329
327
|
|
|
330
|
-
type: Literal["system"] = "system"
|
|
331
328
|
subtype: Literal["hook_response"] = "hook_response"
|
|
332
329
|
hook_id: str
|
|
333
330
|
hook_name: str
|
|
@@ -441,7 +438,7 @@ class AuthStatusMessage(BaseMessage):
|
|
|
441
438
|
|
|
442
439
|
|
|
443
440
|
SystemMessageUnion = Annotated[
|
|
444
|
-
|
|
441
|
+
InitSystemMessage
|
|
445
442
|
| HookStartedSystemMessage
|
|
446
443
|
| StatusSystemMessage
|
|
447
444
|
| CompactBoundarySystemMessage
|
|
@@ -460,7 +457,7 @@ system_message_adapter: TypeAdapter[SystemMessageUnion] = TypeAdapter(SystemMess
|
|
|
460
457
|
Message = (
|
|
461
458
|
UserMessage
|
|
462
459
|
| AssistantMessage
|
|
463
|
-
|
|
|
460
|
+
| InitSystemMessage
|
|
464
461
|
| ResultMessage
|
|
465
462
|
| StreamEvent
|
|
466
463
|
| RateLimitMessage
|
|
@@ -30,49 +30,51 @@ logger = logging.getLogger(__name__)
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
@dataclass(kw_only=True)
|
|
33
|
-
class
|
|
33
|
+
class BaseSessionConfig:
|
|
34
|
+
"""Common fields for all session configurations."""
|
|
35
|
+
|
|
36
|
+
persist: bool = True
|
|
37
|
+
"""Whether to persist the session to disk."""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(kw_only=True)
|
|
41
|
+
class NewSession(BaseSessionConfig):
|
|
34
42
|
"""Start a fresh session.
|
|
35
43
|
|
|
36
44
|
Attributes:
|
|
37
45
|
session_id: Deterministic session ID, or None to auto-generate a UUID.
|
|
38
|
-
persist: Whether to persist the session to disk.
|
|
39
46
|
"""
|
|
40
47
|
|
|
41
48
|
mode: Literal["new"] = "new"
|
|
42
49
|
session_id: str | None = None
|
|
43
|
-
persist: bool = True
|
|
44
50
|
|
|
45
51
|
|
|
46
52
|
@dataclass(kw_only=True)
|
|
47
|
-
class ResumeSession:
|
|
53
|
+
class ResumeSession(BaseSessionConfig):
|
|
48
54
|
"""Resume an existing session by ID.
|
|
49
55
|
|
|
50
56
|
Attributes:
|
|
51
57
|
session_id: The session ID to resume.
|
|
52
58
|
fork: If True, fork to a new session ID instead of continuing in-place.
|
|
53
59
|
at_message: Resume from a specific message UUID within the session.
|
|
54
|
-
persist: Whether to persist the session to disk.
|
|
55
60
|
"""
|
|
56
61
|
|
|
57
62
|
mode: Literal["resume"] = "resume"
|
|
58
63
|
session_id: str
|
|
59
64
|
fork: bool = False
|
|
60
65
|
at_message: str | None = None
|
|
61
|
-
persist: bool = True
|
|
62
66
|
|
|
63
67
|
|
|
64
68
|
@dataclass(kw_only=True)
|
|
65
|
-
class ContinueLatest:
|
|
69
|
+
class ContinueLatest(BaseSessionConfig):
|
|
66
70
|
"""Continue the most recent conversation.
|
|
67
71
|
|
|
68
72
|
Attributes:
|
|
69
73
|
fork: If True, fork to a new session ID instead of continuing in-place.
|
|
70
|
-
persist: Whether to persist the session to disk.
|
|
71
74
|
"""
|
|
72
75
|
|
|
73
76
|
mode: Literal["continue"] = "continue"
|
|
74
77
|
fork: bool = False
|
|
75
|
-
persist: bool = True
|
|
76
78
|
|
|
77
79
|
|
|
78
80
|
SessionConfig = NewSession | ResumeSession | ContinueLatest
|
|
@@ -98,7 +100,7 @@ def resolve_session_config(value: str | SessionConfig | None) -> SessionConfig:
|
|
|
98
100
|
return NewSession()
|
|
99
101
|
case str() as session_id:
|
|
100
102
|
return ResumeSession(session_id=session_id)
|
|
101
|
-
case
|
|
103
|
+
case BaseSessionConfig() as config:
|
|
102
104
|
return config
|
|
103
105
|
|
|
104
106
|
|
|
@@ -17,7 +17,7 @@ full content (since token-level deltas are not preserved in storage).
|
|
|
17
17
|
|
|
18
18
|
Not reconstructible from storage:
|
|
19
19
|
- Token-level streaming granularity (deltas are synthetic, one per block).
|
|
20
|
-
-
|
|
20
|
+
- InitSystemMessage(init): Session initialization metadata (tools, model, etc.).
|
|
21
21
|
- RateLimitMessage: Rate limit events are transient.
|
|
22
22
|
|
|
23
23
|
Partially reconstructible (with ``include_result=True``):
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Pytest configuration for tests."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
_MSG_COUNTER = 0
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def make_beta_message(
|
|
13
|
+
content: list[dict[str, Any]],
|
|
14
|
+
model: str = "claude-opus-4-1-20250805",
|
|
15
|
+
**kwargs: Any,
|
|
16
|
+
) -> dict[str, Any]:
|
|
17
|
+
"""Create a wire-format message dict matching BetaMessage shape."""
|
|
18
|
+
global _MSG_COUNTER # noqa: PLW0603
|
|
19
|
+
_MSG_COUNTER += 1
|
|
20
|
+
return {
|
|
21
|
+
"id": f"msg_test_{_MSG_COUNTER:04d}",
|
|
22
|
+
"type": "message",
|
|
23
|
+
"role": "assistant",
|
|
24
|
+
"content": content,
|
|
25
|
+
"model": model,
|
|
26
|
+
"stop_reason": "end_turn",
|
|
27
|
+
"stop_sequence": None,
|
|
28
|
+
"usage": {"input_tokens": 10, "output_tokens": 5},
|
|
29
|
+
**kwargs,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@pytest.fixture(scope="session", autouse=True)
|
|
34
|
+
def unset_anthropic_api_key():
|
|
35
|
+
os.environ["ANTHROPIC_API_KEY"] = ""
|
|
@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Literal
|
|
|
9
9
|
from unittest.mock import AsyncMock
|
|
10
10
|
|
|
11
11
|
import anyio
|
|
12
|
+
from conftest import make_beta_message
|
|
12
13
|
import pytest
|
|
13
14
|
|
|
14
15
|
from clawd_code_sdk import (
|
|
@@ -130,11 +131,9 @@ class TestQueryFunction:
|
|
|
130
131
|
test_messages = [
|
|
131
132
|
{
|
|
132
133
|
"type": "assistant",
|
|
133
|
-
"message":
|
|
134
|
-
"
|
|
135
|
-
|
|
136
|
-
"model": "claude-opus-4-1-20250805",
|
|
137
|
-
},
|
|
134
|
+
"message": make_beta_message(
|
|
135
|
+
content=[{"type": "text", "text": "4"}],
|
|
136
|
+
),
|
|
138
137
|
},
|
|
139
138
|
_make_result(),
|
|
140
139
|
]
|
|
@@ -158,11 +157,9 @@ class TestQueryFunction:
|
|
|
158
157
|
test_messages = [
|
|
159
158
|
{
|
|
160
159
|
"type": "assistant",
|
|
161
|
-
"message":
|
|
162
|
-
"
|
|
163
|
-
|
|
164
|
-
"model": "claude-opus-4-1-20250805",
|
|
165
|
-
},
|
|
160
|
+
"message": make_beta_message(
|
|
161
|
+
content=[{"type": "text", "text": "Hello!"}],
|
|
162
|
+
),
|
|
166
163
|
},
|
|
167
164
|
_make_result(),
|
|
168
165
|
]
|
|
@@ -193,11 +190,9 @@ class TestQueryFunction:
|
|
|
193
190
|
test_messages = [
|
|
194
191
|
{
|
|
195
192
|
"type": "assistant",
|
|
196
|
-
"message":
|
|
197
|
-
"
|
|
198
|
-
|
|
199
|
-
"model": "claude-opus-4-1-20250805",
|
|
200
|
-
},
|
|
193
|
+
"message": make_beta_message(
|
|
194
|
+
content=[{"type": "text", "text": "Done"}],
|
|
195
|
+
),
|
|
201
196
|
},
|
|
202
197
|
_make_result(),
|
|
203
198
|
]
|
|
@@ -225,17 +220,16 @@ class TestAPIErrorRaising:
|
|
|
225
220
|
async def _test():
|
|
226
221
|
error_message = {
|
|
227
222
|
"type": "assistant",
|
|
228
|
-
"message":
|
|
229
|
-
|
|
230
|
-
"content": [
|
|
223
|
+
"message": make_beta_message(
|
|
224
|
+
content=[
|
|
231
225
|
{
|
|
232
226
|
"type": "text",
|
|
233
227
|
"text": "API Error: The provided model identifier is invalid.",
|
|
234
228
|
}
|
|
235
229
|
],
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
230
|
+
model="claude-invalid-model",
|
|
231
|
+
error="invalid_request",
|
|
232
|
+
),
|
|
239
233
|
}
|
|
240
234
|
mock_transport = create_mock_transport_with_messages([error_message])
|
|
241
235
|
|
|
@@ -255,17 +249,16 @@ class TestAPIErrorRaising:
|
|
|
255
249
|
async def _test():
|
|
256
250
|
error_message = {
|
|
257
251
|
"type": "assistant",
|
|
258
|
-
"message":
|
|
259
|
-
|
|
260
|
-
"content": [
|
|
252
|
+
"message": make_beta_message(
|
|
253
|
+
content=[
|
|
261
254
|
{
|
|
262
255
|
"type": "text",
|
|
263
256
|
"text": "API Error: Rate limit exceeded",
|
|
264
257
|
}
|
|
265
258
|
],
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
259
|
+
model="claude-sonnet-4-5-20250514",
|
|
260
|
+
error="rate_limit",
|
|
261
|
+
),
|
|
269
262
|
}
|
|
270
263
|
mock_transport = create_mock_transport_with_messages([error_message])
|
|
271
264
|
|
|
@@ -283,12 +276,11 @@ class TestAPIErrorRaising:
|
|
|
283
276
|
async def _test():
|
|
284
277
|
error_message = {
|
|
285
278
|
"type": "assistant",
|
|
286
|
-
"message":
|
|
287
|
-
"
|
|
288
|
-
"
|
|
289
|
-
"
|
|
290
|
-
|
|
291
|
-
},
|
|
279
|
+
"message": make_beta_message(
|
|
280
|
+
content=[{"type": "text", "text": "API Error: Invalid API key"}],
|
|
281
|
+
model="claude-sonnet-4-5-20250514",
|
|
282
|
+
error="authentication_failed",
|
|
283
|
+
),
|
|
292
284
|
}
|
|
293
285
|
mock_transport = create_mock_transport_with_messages([error_message])
|
|
294
286
|
|
|
@@ -306,17 +298,16 @@ class TestAPIErrorRaising:
|
|
|
306
298
|
async def _test():
|
|
307
299
|
error_message = {
|
|
308
300
|
"type": "assistant",
|
|
309
|
-
"message":
|
|
310
|
-
|
|
311
|
-
"content": [
|
|
301
|
+
"message": make_beta_message(
|
|
302
|
+
content=[
|
|
312
303
|
{
|
|
313
304
|
"type": "text",
|
|
314
305
|
"text": "API Error: Repeated 529 Overloaded errors",
|
|
315
306
|
}
|
|
316
307
|
],
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
308
|
+
model="claude-sonnet-4-5-20250514",
|
|
309
|
+
error="server_error",
|
|
310
|
+
),
|
|
320
311
|
}
|
|
321
312
|
mock_transport = create_mock_transport_with_messages([error_message])
|
|
322
313
|
|
|
@@ -334,12 +325,11 @@ class TestAPIErrorRaising:
|
|
|
334
325
|
async def _test():
|
|
335
326
|
error_message = {
|
|
336
327
|
"type": "assistant",
|
|
337
|
-
"message":
|
|
338
|
-
"
|
|
339
|
-
"
|
|
340
|
-
"
|
|
341
|
-
|
|
342
|
-
},
|
|
328
|
+
"message": make_beta_message(
|
|
329
|
+
content=[{"type": "text", "text": "Unknown error"}],
|
|
330
|
+
model="claude-sonnet-4-5-20250514",
|
|
331
|
+
error="unknown",
|
|
332
|
+
),
|
|
343
333
|
}
|
|
344
334
|
mock_transport = create_mock_transport_with_messages([error_message])
|
|
345
335
|
|
|
@@ -358,11 +348,10 @@ class TestAPIErrorRaising:
|
|
|
358
348
|
test_messages = [
|
|
359
349
|
{
|
|
360
350
|
"type": "assistant",
|
|
361
|
-
"message":
|
|
362
|
-
"
|
|
363
|
-
"
|
|
364
|
-
|
|
365
|
-
},
|
|
351
|
+
"message": make_beta_message(
|
|
352
|
+
content=[{"type": "text", "text": "Hello!"}],
|
|
353
|
+
model="claude-sonnet-4-5-20250514",
|
|
354
|
+
),
|
|
366
355
|
},
|
|
367
356
|
_make_result(uuid="msg-002"),
|
|
368
357
|
]
|
|
@@ -8,6 +8,7 @@ import json
|
|
|
8
8
|
from unittest.mock import AsyncMock, patch
|
|
9
9
|
|
|
10
10
|
import anyio
|
|
11
|
+
from conftest import make_beta_message
|
|
11
12
|
import pytest
|
|
12
13
|
|
|
13
14
|
from clawd_code_sdk import (
|
|
@@ -74,11 +75,9 @@ class TestIntegration:
|
|
|
74
75
|
test_messages = [
|
|
75
76
|
{
|
|
76
77
|
"type": "assistant",
|
|
77
|
-
"message":
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
"model": "claude-opus-4-1-20250805",
|
|
81
|
-
},
|
|
78
|
+
"message": make_beta_message(
|
|
79
|
+
content=[{"type": "text", "text": "2 + 2 equals 4"}]
|
|
80
|
+
),
|
|
82
81
|
},
|
|
83
82
|
{
|
|
84
83
|
"type": "result",
|
|
@@ -121,9 +120,8 @@ class TestIntegration:
|
|
|
121
120
|
test_messages = [
|
|
122
121
|
{
|
|
123
122
|
"type": "assistant",
|
|
124
|
-
"message":
|
|
125
|
-
|
|
126
|
-
"content": [
|
|
123
|
+
"message": make_beta_message(
|
|
124
|
+
content=[
|
|
127
125
|
{"type": "text", "text": "Let me read that file for you."},
|
|
128
126
|
{
|
|
129
127
|
"type": "tool_use",
|
|
@@ -131,9 +129,8 @@ class TestIntegration:
|
|
|
131
129
|
"name": "Read",
|
|
132
130
|
"input": {"file_path": "/test.txt"},
|
|
133
131
|
},
|
|
134
|
-
]
|
|
135
|
-
|
|
136
|
-
},
|
|
132
|
+
]
|
|
133
|
+
),
|
|
137
134
|
},
|
|
138
135
|
{
|
|
139
136
|
"type": "result",
|
|
@@ -196,13 +193,9 @@ class TestIntegration:
|
|
|
196
193
|
test_messages = [
|
|
197
194
|
{
|
|
198
195
|
"type": "assistant",
|
|
199
|
-
"message":
|
|
200
|
-
"
|
|
201
|
-
|
|
202
|
-
{"type": "text", "text": "Continuing from previous conversation"}
|
|
203
|
-
],
|
|
204
|
-
"model": "claude-opus-4-1-20250805",
|
|
205
|
-
},
|
|
196
|
+
"message": make_beta_message(
|
|
197
|
+
content=[{"type": "text", "text": "Continuing from previous conversation"}]
|
|
198
|
+
),
|
|
206
199
|
},
|
|
207
200
|
{
|
|
208
201
|
"type": "result",
|
|
@@ -245,11 +238,9 @@ class TestIntegration:
|
|
|
245
238
|
test_messages = [
|
|
246
239
|
{
|
|
247
240
|
"type": "assistant",
|
|
248
|
-
"message":
|
|
249
|
-
"
|
|
250
|
-
|
|
251
|
-
"model": "claude-opus-4-1-20250805",
|
|
252
|
-
},
|
|
241
|
+
"message": make_beta_message(
|
|
242
|
+
content=[{"type": "text", "text": "Starting to read..."}]
|
|
243
|
+
),
|
|
253
244
|
},
|
|
254
245
|
{
|
|
255
246
|
"type": "result",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from conftest import make_beta_message
|
|
5
6
|
import pytest
|
|
6
7
|
|
|
7
8
|
from clawd_code_sdk._errors import MessageParseError
|
|
@@ -56,13 +57,12 @@ class TestContentBlockDispatch:
|
|
|
56
57
|
"""Thinking blocks parse with signature preserved."""
|
|
57
58
|
data = {
|
|
58
59
|
"type": "assistant",
|
|
59
|
-
"message":
|
|
60
|
-
|
|
60
|
+
"message": make_beta_message(
|
|
61
|
+
content=[
|
|
61
62
|
{"type": "thinking", "thinking": "hmm...", "signature": "sig-abc"},
|
|
62
63
|
{"type": "text", "text": "answer"},
|
|
63
64
|
],
|
|
64
|
-
|
|
65
|
-
},
|
|
65
|
+
),
|
|
66
66
|
}
|
|
67
67
|
msg = parse_message(data)
|
|
68
68
|
assert isinstance(msg, AssistantMessage)
|
|
@@ -100,10 +100,9 @@ class TestParentToolUseId:
|
|
|
100
100
|
def test_assistant_message(self):
|
|
101
101
|
data = {
|
|
102
102
|
"type": "assistant",
|
|
103
|
-
"message":
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
},
|
|
103
|
+
"message": make_beta_message(
|
|
104
|
+
content=[{"type": "text", "text": "hi"}],
|
|
105
|
+
),
|
|
107
106
|
"parent_tool_use_id": "toolu_xyz",
|
|
108
107
|
}
|
|
109
108
|
msg = parse_message(data)
|
|
@@ -116,11 +115,10 @@ class TestAssistantErrorExtraction:
|
|
|
116
115
|
def test_error_from_message_level(self):
|
|
117
116
|
data = {
|
|
118
117
|
"type": "assistant",
|
|
119
|
-
"message":
|
|
120
|
-
|
|
121
|
-
"
|
|
122
|
-
|
|
123
|
-
},
|
|
118
|
+
"message": make_beta_message(
|
|
119
|
+
content=[{"type": "text", "text": "API Error: bad key"}],
|
|
120
|
+
error="authentication_failed",
|
|
121
|
+
),
|
|
124
122
|
}
|
|
125
123
|
msg = parse_message(data)
|
|
126
124
|
assert isinstance(msg, AssistantMessage) and msg.error == "authentication_failed"
|
|
@@ -129,10 +127,9 @@ class TestAssistantErrorExtraction:
|
|
|
129
127
|
data = {
|
|
130
128
|
"type": "assistant",
|
|
131
129
|
"error": "rate_limit",
|
|
132
|
-
"message":
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
},
|
|
130
|
+
"message": make_beta_message(
|
|
131
|
+
content=[{"type": "text", "text": "Rate limited"}],
|
|
132
|
+
),
|
|
136
133
|
}
|
|
137
134
|
msg = parse_message(data)
|
|
138
135
|
assert isinstance(msg, AssistantMessage) and msg.error == "rate_limit"
|
|
@@ -140,10 +137,9 @@ class TestAssistantErrorExtraction:
|
|
|
140
137
|
def test_no_error(self):
|
|
141
138
|
data = {
|
|
142
139
|
"type": "assistant",
|
|
143
|
-
"message":
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
},
|
|
140
|
+
"message": make_beta_message(
|
|
141
|
+
content=[{"type": "text", "text": "ok"}],
|
|
142
|
+
),
|
|
147
143
|
}
|
|
148
144
|
msg = parse_message(data)
|
|
149
145
|
assert isinstance(msg, AssistantMessage) and msg.error is None
|
|
@@ -8,6 +8,7 @@ import json
|
|
|
8
8
|
from unittest.mock import AsyncMock
|
|
9
9
|
|
|
10
10
|
import anyio
|
|
11
|
+
from conftest import make_beta_message
|
|
11
12
|
import pytest
|
|
12
13
|
|
|
13
14
|
from clawd_code_sdk import (
|
|
@@ -73,18 +74,15 @@ def _create_mock_transport_with_messages(messages: list[dict]) -> AsyncMock:
|
|
|
73
74
|
|
|
74
75
|
ASSISTANT_MSG = {
|
|
75
76
|
"type": "assistant",
|
|
76
|
-
"message":
|
|
77
|
-
"
|
|
78
|
-
|
|
79
|
-
"model": "claude-sonnet-4-5-20250514",
|
|
80
|
-
},
|
|
77
|
+
"message": make_beta_message(
|
|
78
|
+
content=[{"type": "text", "text": "Hello, world!"}], model="claude-sonnet-4-5-20250514"
|
|
79
|
+
),
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
TOOL_USE_MSG = {
|
|
84
83
|
"type": "assistant",
|
|
85
|
-
"message":
|
|
86
|
-
|
|
87
|
-
"content": [
|
|
84
|
+
"message": make_beta_message(
|
|
85
|
+
content=[
|
|
88
86
|
{"type": "text", "text": "Let me read that."},
|
|
89
87
|
{
|
|
90
88
|
"type": "tool_use",
|
|
@@ -93,8 +91,8 @@ TOOL_USE_MSG = {
|
|
|
93
91
|
"input": {"path": "/tmp/test.py"},
|
|
94
92
|
},
|
|
95
93
|
],
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
model="claude-sonnet-4-5-20250514",
|
|
95
|
+
),
|
|
98
96
|
}
|
|
99
97
|
|
|
100
98
|
RESULT_MSG = asdict(
|
|
@@ -11,6 +11,7 @@ from typing import TYPE_CHECKING
|
|
|
11
11
|
from unittest.mock import AsyncMock, patch
|
|
12
12
|
|
|
13
13
|
import anyio
|
|
14
|
+
from conftest import make_beta_message
|
|
14
15
|
import pytest
|
|
15
16
|
|
|
16
17
|
from clawd_code_sdk import (
|
|
@@ -324,11 +325,7 @@ class TestClaudeSDKClientStreaming:
|
|
|
324
325
|
# Then yield the actual messages
|
|
325
326
|
yield {
|
|
326
327
|
"type": "assistant",
|
|
327
|
-
"message": {
|
|
328
|
-
"role": "assistant",
|
|
329
|
-
"content": [{"type": "text", "text": "Hello!"}],
|
|
330
|
-
"model": "claude-opus-4-1-20250805",
|
|
331
|
-
},
|
|
328
|
+
"message": make_beta_message(content=[{"type": "text", "text": "Hello!"}]),
|
|
332
329
|
}
|
|
333
330
|
yield {
|
|
334
331
|
"type": "user",
|
|
@@ -394,11 +391,7 @@ class TestClaudeSDKClientStreaming:
|
|
|
394
391
|
# Then yield the actual messages
|
|
395
392
|
yield {
|
|
396
393
|
"type": "assistant",
|
|
397
|
-
"message": {
|
|
398
|
-
"role": "assistant",
|
|
399
|
-
"content": [{"type": "text", "text": "Answer"}],
|
|
400
|
-
"model": "claude-opus-4-1-20250805",
|
|
401
|
-
},
|
|
394
|
+
"message": make_beta_message(content=[{"type": "text", "text": "Answer"}]),
|
|
402
395
|
}
|
|
403
396
|
yield {
|
|
404
397
|
"type": "result",
|
|
@@ -420,11 +413,9 @@ class TestClaudeSDKClientStreaming:
|
|
|
420
413
|
# This should not be yielded
|
|
421
414
|
yield {
|
|
422
415
|
"type": "assistant",
|
|
423
|
-
"message":
|
|
424
|
-
"
|
|
425
|
-
|
|
426
|
-
},
|
|
427
|
-
"model": "claude-opus-4-1-20250805",
|
|
416
|
+
"message": make_beta_message(
|
|
417
|
+
content=[{"type": "text", "text": "Should not see this"}]
|
|
418
|
+
),
|
|
428
419
|
}
|
|
429
420
|
|
|
430
421
|
mock_transport.read_messages = mock_receive
|
|
@@ -549,11 +540,9 @@ class TestClaudeSDKClientStreaming:
|
|
|
549
540
|
await asyncio.sleep(0.1)
|
|
550
541
|
yield {
|
|
551
542
|
"type": "assistant",
|
|
552
|
-
"message":
|
|
553
|
-
"
|
|
554
|
-
|
|
555
|
-
"model": "claude-opus-4-1-20250805",
|
|
556
|
-
},
|
|
543
|
+
"message": make_beta_message(
|
|
544
|
+
content=[{"type": "text", "text": "Response 1"}]
|
|
545
|
+
),
|
|
557
546
|
}
|
|
558
547
|
await asyncio.sleep(0.1)
|
|
559
548
|
yield {
|
|
@@ -811,19 +800,11 @@ class TestClaudeSDKClientEdgeCases:
|
|
|
811
800
|
# Then yield the actual messages
|
|
812
801
|
yield {
|
|
813
802
|
"type": "assistant",
|
|
814
|
-
"message": {
|
|
815
|
-
"role": "assistant",
|
|
816
|
-
"content": [{"type": "text", "text": "Hello"}],
|
|
817
|
-
"model": "claude-opus-4-1-20250805",
|
|
818
|
-
},
|
|
803
|
+
"message": make_beta_message(content=[{"type": "text", "text": "Hello"}]),
|
|
819
804
|
}
|
|
820
805
|
yield {
|
|
821
806
|
"type": "assistant",
|
|
822
|
-
"message": {
|
|
823
|
-
"role": "assistant",
|
|
824
|
-
"content": [{"type": "text", "text": "World"}],
|
|
825
|
-
"model": "claude-opus-4-1-20250805",
|
|
826
|
-
},
|
|
807
|
+
"message": make_beta_message(content=[{"type": "text", "text": "World"}]),
|
|
827
808
|
}
|
|
828
809
|
yield {
|
|
829
810
|
"type": "result",
|
|
@@ -911,11 +892,9 @@ class TestAsyncGeneratorCleanup:
|
|
|
911
892
|
for i in range(5):
|
|
912
893
|
yield {
|
|
913
894
|
"type": "assistant",
|
|
914
|
-
"message":
|
|
915
|
-
"
|
|
916
|
-
|
|
917
|
-
"model": "claude-opus-4-1-20250805",
|
|
918
|
-
},
|
|
895
|
+
"message": make_beta_message(
|
|
896
|
+
content=[{"type": "text", "text": f"Message {i}"}]
|
|
897
|
+
),
|
|
919
898
|
}
|
|
920
899
|
|
|
921
900
|
mock_transport.read_messages = mock_receive
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/src/clawd_code_sdk/_internal/message_parser.py
RENAMED
|
File without changes
|
|
File without changes
|
{clawd_code_sdk-0.2.1 → clawd_code_sdk-0.2.2}/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
|
|
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
|