1919 from claude_agent_sdk import (
2020 query as original_query ,
2121 ClaudeSDKClient ,
22- AssistantMessage ,
23- ResultMessage ,
24- TextBlock ,
25- ToolUseBlock ,
26- ToolResultBlock ,
2722 )
2823except ImportError :
2924 raise DidNotEnable ("claude-agent-sdk not installed" )
3631GEN_AI_SYSTEM = "claude-agent-sdk-python"
3732
3833
34+ def _is_assistant_message (message : "Any" ) -> bool :
35+ """Check if message is an AssistantMessage using duck typing."""
36+ return hasattr (message , "content" ) and hasattr (message , "model" )
37+
38+
39+ def _is_result_message (message : "Any" ) -> bool :
40+ """Check if message is a ResultMessage using duck typing."""
41+ return hasattr (message , "usage" ) and hasattr (message , "total_cost_usd" )
42+
43+
44+ def _is_text_block (block : "Any" ) -> bool :
45+ """Check if block is a TextBlock using duck typing."""
46+ # TextBlock has 'text' but not 'tool_use_id' or 'name'
47+ return (
48+ hasattr (block , "text" )
49+ and not hasattr (block , "tool_use_id" )
50+ and not hasattr (block , "name" )
51+ )
52+
53+
54+ def _is_tool_use_block (block : "Any" ) -> bool :
55+ """Check if block is a ToolUseBlock using duck typing."""
56+ # ToolUseBlock has 'id', 'name', and 'input'
57+ return hasattr (block , "id" ) and hasattr (block , "name" ) and hasattr (block , "input" )
58+
59+
60+ def _is_tool_result_block (block : "Any" ) -> bool :
61+ """Check if block is a ToolResultBlock using duck typing."""
62+ # ToolResultBlock has 'tool_use_id'
63+ return hasattr (block , "tool_use_id" )
64+
65+
3966class ClaudeAgentSDKIntegration (Integration ):
4067 identifier = "claude_agent_sdk"
4168 origin = f"auto.ai.{ identifier } "
@@ -101,22 +128,20 @@ def _set_span_input_data(
101128
102129
103130def _extract_text_from_message (message : "Any" ) -> "Optional[str]" :
104- if not isinstance (message , AssistantMessage ):
131+ if not _is_assistant_message (message ):
105132 return None
106133 text_parts = [
107- block .text
108- for block in getattr (message , "content" , [])
109- if isinstance (block , TextBlock ) and hasattr (block , "text" )
134+ block .text for block in getattr (message , "content" , []) if _is_text_block (block )
110135 ]
111136 return "" .join (text_parts ) if text_parts else None
112137
113138
114139def _extract_tool_calls (message : "Any" ) -> "Optional[list]" :
115- if not isinstance (message , AssistantMessage ):
140+ if not _is_assistant_message (message ):
116141 return None
117142 tool_calls = []
118143 for block in getattr (message , "content" , []):
119- if isinstance (block , ToolUseBlock ):
144+ if _is_tool_use_block (block ):
120145 tool_call = {"name" : getattr (block , "name" , "unknown" )}
121146 tool_input = getattr (block , "input" , None )
122147 if tool_input is not None :
@@ -138,7 +163,7 @@ def _extract_message_data(messages: list) -> dict:
138163 }
139164
140165 for message in messages :
141- if isinstance (message , AssistantMessage ):
166+ if _is_assistant_message (message ):
142167 text = _extract_text_from_message (message )
143168 if text :
144169 data ["response_texts" ].append (text )
@@ -150,7 +175,7 @@ def _extract_message_data(messages: list) -> dict:
150175 if not data ["response_model" ]:
151176 data ["response_model" ] = getattr (message , "model" , None )
152177
153- elif isinstance (message , ResultMessage ):
178+ elif _is_result_message (message ):
154179 data ["total_cost" ] = getattr (message , "total_cost_usd" , None )
155180 usage = getattr (message , "usage" , None )
156181 if isinstance (usage , dict ):
@@ -264,8 +289,8 @@ def _end_invoke_agent_span(
264289
265290
266291def _create_execute_tool_span (
267- tool_use : "ToolUseBlock " ,
268- tool_result : "Optional[ToolResultBlock ]" ,
292+ tool_use : "Any " ,
293+ tool_result : "Optional[Any ]" ,
269294 integration : "ClaudeAgentSDKIntegration" ,
270295) -> "Span" :
271296 tool_name = getattr (tool_use , "name" , "unknown" )
@@ -306,14 +331,14 @@ def _process_tool_executions(
306331 tool_results = {}
307332
308333 for message in messages :
309- if not isinstance (message , AssistantMessage ):
334+ if not _is_assistant_message (message ):
310335 continue
311336 for block in getattr (message , "content" , []):
312- if isinstance (block , ToolUseBlock ):
337+ if _is_tool_use_block (block ):
313338 tool_id = getattr (block , "id" , None )
314339 if tool_id :
315340 tool_uses [tool_id ] = block
316- elif isinstance (block , ToolResultBlock ):
341+ elif _is_tool_result_block (block ):
317342 tool_use_id = getattr (block , "tool_use_id" , None )
318343 if tool_use_id :
319344 tool_results [tool_use_id ] = block
0 commit comments