diff --git a/src/claude_agent_sdk/_internal/message_parser.py b/src/claude_agent_sdk/_internal/message_parser.py index d020d5b9b..398ce8351 100644 --- a/src/claude_agent_sdk/_internal/message_parser.py +++ b/src/claude_agent_sdk/_internal/message_parser.py @@ -153,6 +153,7 @@ def parse_message(data: dict[str, Any]) -> Message | None: is_error=data["is_error"], num_turns=data["num_turns"], session_id=data["session_id"], + stop_reason=data.get("stop_reason"), total_cost_usd=data.get("total_cost_usd"), usage=data.get("usage"), result=data.get("result"), diff --git a/src/claude_agent_sdk/types.py b/src/claude_agent_sdk/types.py index 3ea89d5a4..d9d5e19b3 100644 --- a/src/claude_agent_sdk/types.py +++ b/src/claude_agent_sdk/types.py @@ -677,6 +677,7 @@ class ResultMessage: is_error: bool num_turns: int session_id: str + stop_reason: str | None = None total_cost_usd: float | None = None usage: dict[str, Any] | None = None result: str | None = None diff --git a/tests/test_message_parser.py b/tests/test_message_parser.py index be44431b8..349337086 100644 --- a/tests/test_message_parser.py +++ b/tests/test_message_parser.py @@ -313,6 +313,45 @@ def test_parse_valid_result_message(self): message = parse_message(data) assert isinstance(message, ResultMessage) assert message.subtype == "success" + assert message.stop_reason is None + + def test_parse_result_message_with_stop_reason(self): + """Test parsing a result message with stop_reason field. + + The stop_reason field mirrors the Anthropic API's stop_reason on the + final assistant turn (e.g., "end_turn", "max_tokens", "tool_use"). + """ + data = { + "type": "result", + "subtype": "success", + "duration_ms": 1000, + "duration_api_ms": 500, + "is_error": False, + "num_turns": 2, + "session_id": "session_123", + "stop_reason": "end_turn", + "result": "Done", + } + message = parse_message(data) + assert isinstance(message, ResultMessage) + assert message.stop_reason == "end_turn" + assert message.result == "Done" + + def test_parse_result_message_with_null_stop_reason(self): + """Test parsing a result message with explicit null stop_reason.""" + data = { + "type": "result", + "subtype": "error_max_turns", + "duration_ms": 1000, + "duration_api_ms": 500, + "is_error": True, + "num_turns": 10, + "session_id": "session_123", + "stop_reason": None, + } + message = parse_message(data) + assert isinstance(message, ResultMessage) + assert message.stop_reason is None def test_parse_invalid_data_type(self): """Test that non-dict data raises MessageParseError."""