@@ -731,38 +731,67 @@ class SandboxSettings(TypedDict, total=False):
731731
732732
733733# Content block types
734- @dataclass
734+
735+
736+ def _truncate (text : str , max_length : int = 80 ) -> str :
737+ """Truncate text for repr display."""
738+ if len (text ) <= max_length :
739+ return text
740+ return text [: max_length - 3 ] + "..."
741+
742+
743+ @dataclass (repr = False )
735744class TextBlock :
736745 """Text content block."""
737746
738747 text : str
739748
749+ def __repr__ (self ) -> str :
750+ return f"TextBlock(text='{ _truncate (self .text )} ')"
740751
741- @dataclass
752+
753+ @dataclass (repr = False )
742754class ThinkingBlock :
743755 """Thinking content block."""
744756
745757 thinking : str
746758 signature : str
747759
760+ def __repr__ (self ) -> str :
761+ return f"ThinkingBlock(thinking='{ _truncate (self .thinking )} ')"
748762
749- @dataclass
763+
764+ @dataclass (repr = False )
750765class ToolUseBlock :
751766 """Tool use content block."""
752767
753768 id : str
754769 name : str
755770 input : dict [str , Any ]
756771
772+ def __repr__ (self ) -> str :
773+ return f"ToolUseBlock(id='{ self .id } ', name='{ self .name } ')"
757774
758- @dataclass
775+
776+ @dataclass (repr = False )
759777class ToolResultBlock :
760778 """Tool result content block."""
761779
762780 tool_use_id : str
763781 content : str | list [dict [str , Any ]] | None = None
764782 is_error : bool | None = None
765783
784+ def __repr__ (self ) -> str :
785+ parts = [f"tool_use_id='{ self .tool_use_id } '" ]
786+ if self .content is not None :
787+ if isinstance (self .content , str ):
788+ parts .append (f"content='{ _truncate (self .content )} '" )
789+ else :
790+ parts .append (f"content={ self .content !r} " )
791+ if self .is_error :
792+ parts .append ("is_error=True" )
793+ return f"ToolResultBlock({ ', ' .join (parts )} )"
794+
766795
767796ContentBlock = TextBlock | ThinkingBlock | ToolUseBlock | ToolResultBlock
768797
@@ -778,7 +807,7 @@ class ToolResultBlock:
778807]
779808
780809
781- @dataclass
810+ @dataclass ( repr = False )
782811class UserMessage :
783812 """User message."""
784813
@@ -787,8 +816,13 @@ class UserMessage:
787816 parent_tool_use_id : str | None = None
788817 tool_use_result : dict [str , Any ] | None = None
789818
819+ def __repr__ (self ) -> str :
820+ if isinstance (self .content , str ):
821+ return f"UserMessage(content='{ _truncate (self .content )} ')"
822+ return f"UserMessage(content={ self .content !r} )"
790823
791- @dataclass
824+
825+ @dataclass (repr = False )
792826class AssistantMessage :
793827 """Assistant message with content blocks."""
794828
@@ -798,14 +832,23 @@ class AssistantMessage:
798832 error : AssistantMessageError | None = None
799833 usage : dict [str , Any ] | None = None
800834
835+ def __repr__ (self ) -> str :
836+ parts = [f"model='{ self .model } '" , f"content={ self .content !r} " ]
837+ if self .error is not None :
838+ parts .append (f"error='{ self .error } '" )
839+ return f"AssistantMessage({ ', ' .join (parts )} )"
801840
802- @dataclass
841+
842+ @dataclass (repr = False )
803843class SystemMessage :
804844 """System message with metadata."""
805845
806846 subtype : str
807847 data : dict [str , Any ]
808848
849+ def __repr__ (self ) -> str :
850+ return f"SystemMessage(subtype='{ self .subtype } ')"
851+
809852
810853class TaskUsage (TypedDict ):
811854 """Usage statistics reported in task_progress and task_notification messages."""
@@ -819,7 +862,7 @@ class TaskUsage(TypedDict):
819862TaskNotificationStatus = Literal ["completed" , "failed" , "stopped" ]
820863
821864
822- @dataclass
865+ @dataclass ( repr = False )
823866class TaskStartedMessage (SystemMessage ):
824867 """System message emitted when a task starts.
825868
@@ -835,8 +878,11 @@ class TaskStartedMessage(SystemMessage):
835878 tool_use_id : str | None = None
836879 task_type : str | None = None
837880
881+ def __repr__ (self ) -> str :
882+ return f"TaskStartedMessage(task_id='{ self .task_id } ', description='{ _truncate (self .description )} ')"
838883
839- @dataclass
884+
885+ @dataclass (repr = False )
840886class TaskProgressMessage (SystemMessage ):
841887 """System message emitted while a task is in progress.
842888
@@ -853,8 +899,11 @@ class TaskProgressMessage(SystemMessage):
853899 tool_use_id : str | None = None
854900 last_tool_name : str | None = None
855901
902+ def __repr__ (self ) -> str :
903+ return f"TaskProgressMessage(task_id='{ self .task_id } ', description='{ _truncate (self .description )} ')"
856904
857- @dataclass
905+
906+ @dataclass (repr = False )
858907class TaskNotificationMessage (SystemMessage ):
859908 """System message emitted when a task completes, fails, or is stopped.
860909
@@ -872,8 +921,13 @@ class TaskNotificationMessage(SystemMessage):
872921 tool_use_id : str | None = None
873922 usage : TaskUsage | None = None
874923
924+ def __repr__ (self ) -> str :
925+ return (
926+ f"TaskNotificationMessage(task_id='{ self .task_id } ', status='{ self .status } ')"
927+ )
875928
876- @dataclass
929+
930+ @dataclass (repr = False )
877931class ResultMessage :
878932 """Result message with cost and usage information."""
879933
@@ -889,8 +943,18 @@ class ResultMessage:
889943 result : str | None = None
890944 structured_output : Any = None
891945
946+ def __repr__ (self ) -> str :
947+ parts = [f"num_turns={ self .num_turns } " ]
948+ if self .is_error :
949+ parts .append ("is_error=True" )
950+ if self .total_cost_usd is not None :
951+ parts .append (f"total_cost_usd={ self .total_cost_usd } " )
952+ if self .stop_reason is not None :
953+ parts .append (f"stop_reason='{ self .stop_reason } '" )
954+ return f"ResultMessage({ ', ' .join (parts )} )"
892955
893- @dataclass
956+
957+ @dataclass (repr = False )
894958class StreamEvent :
895959 """Stream event for partial message updates during streaming."""
896960
@@ -899,6 +963,9 @@ class StreamEvent:
899963 event : dict [str , Any ] # The raw Anthropic API stream event
900964 parent_tool_use_id : str | None = None
901965
966+ def __repr__ (self ) -> str :
967+ return f"StreamEvent(session_id='{ self .session_id } ')"
968+
902969
903970# Rate limit types — see https://docs.claude.com/en/docs/claude-code/rate-limits
904971RateLimitStatus = Literal ["allowed" , "allowed_warning" , "rejected" ]
@@ -907,7 +974,7 @@ class StreamEvent:
907974]
908975
909976
910- @dataclass
977+ @dataclass ( repr = False )
911978class RateLimitInfo :
912979 """Rate limit status emitted by the CLI when rate limit state changes.
913980
@@ -932,8 +999,16 @@ class RateLimitInfo:
932999 overage_disabled_reason : str | None = None
9331000 raw : dict [str , Any ] = field (default_factory = dict )
9341001
1002+ def __repr__ (self ) -> str :
1003+ parts = [f"status='{ self .status } '" ]
1004+ if self .utilization is not None :
1005+ parts .append (f"utilization={ self .utilization } " )
1006+ if self .rate_limit_type is not None :
1007+ parts .append (f"rate_limit_type='{ self .rate_limit_type } '" )
1008+ return f"RateLimitInfo({ ', ' .join (parts )} )"
9351009
936- @dataclass
1010+
1011+ @dataclass (repr = False )
9371012class RateLimitEvent :
9381013 """Rate limit event emitted when rate limit info changes.
9391014
@@ -946,6 +1021,9 @@ class RateLimitEvent:
9461021 uuid : str
9471022 session_id : str
9481023
1024+ def __repr__ (self ) -> str :
1025+ return f"RateLimitEvent(status='{ self .rate_limit_info .status } ')"
1026+
9491027
9501028Message = (
9511029 UserMessage
0 commit comments