Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions src/claude_code_sdk/_internal/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,9 @@ def _parse_message(self, data: dict[str, Any]) -> Message | None:

match data["type"]:
case "user":
# Extract just the content from the nested structure
return UserMessage(content=data["message"]["content"])

case "assistant":
# Parse content blocks
content_blocks: list[ContentBlock] = []
for block in data["message"]["content"]:
match block["type"]:
Expand Down Expand Up @@ -79,20 +77,18 @@ def _parse_message(self, data: dict[str, Any]) -> Message | None:
case "system":
return SystemMessage(
subtype=data["subtype"],
data=data, # Pass through all data
data=data,
)

case "result":
# Map total_cost to total_cost_usd for consistency
return ResultMessage(
subtype=data["subtype"],
cost_usd=data["cost_usd"],
duration_ms=data["duration_ms"],
duration_api_ms=data["duration_api_ms"],
is_error=data["is_error"],
num_turns=data["num_turns"],
session_id=data["session_id"],
total_cost_usd=data["total_cost"],
total_cost_usd=data.get("total_cost_usd"),
usage=data.get("usage"),
result=data.get("result"),
)
Expand Down
8 changes: 5 additions & 3 deletions src/claude_code_sdk/_internal/transport/subprocess_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,16 +190,18 @@ async def read_stderr() -> None:

try:
data = json.loads(line_str)
yield data
try:
yield data
except GeneratorExit:
# Handle generator cleanup gracefully
return
except json.JSONDecodeError as e:
if line_str.startswith("{") or line_str.startswith("["):
raise SDKJSONDecodeError(line_str, e) from e
continue

except anyio.ClosedResourceError:
pass
finally:
tg.cancel_scope.cancel()

await self._process.wait()
if self._process.returncode is not None and self._process.returncode != 0:
Expand Down
3 changes: 1 addition & 2 deletions src/claude_code_sdk/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,12 @@ class ResultMessage:
"""Result message with cost and usage information."""

subtype: str
cost_usd: float
duration_ms: int
duration_api_ms: int
is_error: bool
num_turns: int
session_id: str
total_cost_usd: float
total_cost_usd: float | None = None
usage: dict[str, Any] | None = None
result: str | None = None

Expand Down
3 changes: 1 addition & 2 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,12 @@ async def mock_receive():
yield {
"type": "result",
"subtype": "success",
"cost_usd": 0.001,
"duration_ms": 1000,
"duration_api_ms": 800,
"is_error": False,
"num_turns": 1,
"session_id": "test-session",
"total_cost": 0.001,
"total_cost_usd": 0.001,
}

mock_transport.receive_messages = mock_receive
Expand Down
8 changes: 3 additions & 5 deletions tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,12 @@ async def mock_receive():
yield {
"type": "result",
"subtype": "success",
"cost_usd": 0.001,
"duration_ms": 1000,
"duration_api_ms": 800,
"is_error": False,
"num_turns": 1,
"session_id": "test-session",
"total_cost": 0.001,
"total_cost_usd": 0.001,
}

mock_transport.receive_messages = mock_receive
Expand All @@ -71,7 +70,7 @@ async def mock_receive():

# Check result message
assert isinstance(messages[1], ResultMessage)
assert messages[1].cost_usd == 0.001
assert messages[1].total_cost_usd == 0.001
assert messages[1].session_id == "test-session"

anyio.run(_test)
Expand Down Expand Up @@ -109,13 +108,12 @@ async def mock_receive():
yield {
"type": "result",
"subtype": "success",
"cost_usd": 0.002,
"duration_ms": 1500,
"duration_api_ms": 1200,
"is_error": False,
"num_turns": 1,
"session_id": "test-session-2",
"total_cost": 0.002,
"total_cost_usd": 0.002,
}

mock_transport.receive_messages = mock_receive
Expand Down
3 changes: 1 addition & 2 deletions tests/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ def test_result_message(self):
"""Test creating a ResultMessage."""
msg = ResultMessage(
subtype="success",
cost_usd=0.01,
duration_ms=1500,
duration_api_ms=1200,
is_error=False,
Expand All @@ -54,7 +53,7 @@ def test_result_message(self):
total_cost_usd=0.01,
)
assert msg.subtype == "success"
assert msg.cost_usd == 0.01
assert msg.total_cost_usd == 0.01
assert msg.session_id == "session-123"


Expand Down