@@ -202,15 +202,7 @@ def on_llm_start(
202202 if key in all_params and all_params [key ] is not None :
203203 set_data_normalized (span , attribute , all_params [key ], unpack = False )
204204
205- # Handle tools separately with simplified format
206- tools = all_params .get ("tools" )
207- if tools is not None :
208- simplified_tools = _simplify_langchain_tools (tools )
209- if simplified_tools :
210- span .set_data (
211- SPANDATA .GEN_AI_REQUEST_AVAILABLE_TOOLS ,
212- safe_serialize (simplified_tools ),
213- )
205+ _set_tools_on_span (span , all_params .get ("tools" ))
214206
215207 if should_send_default_pii () and self .include_prompts :
216208 span .set_data (SPANDATA .GEN_AI_REQUEST_MESSAGES , safe_serialize (prompts ))
@@ -255,15 +247,7 @@ def on_chat_model_start(self, serialized, messages, *, run_id, **kwargs):
255247 if key in all_params and all_params [key ] is not None :
256248 set_data_normalized (span , attribute , all_params [key ], unpack = False )
257249
258- # Handle tools separately with simplified format
259- tools = all_params .get ("tools" )
260- if tools is not None :
261- simplified_tools = _simplify_langchain_tools (tools )
262- if simplified_tools :
263- span .set_data (
264- SPANDATA .GEN_AI_REQUEST_AVAILABLE_TOOLS ,
265- safe_serialize (simplified_tools ),
266- )
250+ _set_tools_on_span (span , all_params .get ("tools" ))
267251
268252 if should_send_default_pii () and self .include_prompts :
269253 # Flatten the nested list structure to a single list of message dicts
@@ -566,24 +550,22 @@ def _simplify_langchain_tools(tools):
566550 for tool in tools :
567551 try :
568552 if isinstance (tool , dict ):
569- # Handle OpenAI-style tool format
553+
570554 if "function" in tool and isinstance (tool ["function" ], dict ):
571555 func = tool ["function" ]
572556 simplified_tool = {
573557 "name" : func .get ("name" ),
574558 "description" : func .get ("description" ),
575559 }
576- if simplified_tool ["name" ]: # Only add if name exists
560+ if simplified_tool ["name" ]:
577561 simplified_tools .append (simplified_tool )
578- # Handle direct tool dict format
579562 elif "name" in tool :
580563 simplified_tool = {
581564 "name" : tool .get ("name" ),
582565 "description" : tool .get ("description" ),
583566 }
584567 simplified_tools .append (simplified_tool )
585568 else :
586- # Try to extract from any dict structure
587569 name = (
588570 tool .get ("name" )
589571 or tool .get ("tool_name" )
@@ -598,7 +580,6 @@ def _simplify_langchain_tools(tools):
598580 }
599581 )
600582 elif hasattr (tool , "name" ):
601- # Handle tool objects with name attribute
602583 simplified_tool = {
603584 "name" : getattr (tool , "name" , None ),
604585 "description" : getattr (tool , "description" , None )
@@ -607,25 +588,34 @@ def _simplify_langchain_tools(tools):
607588 if simplified_tool ["name" ]:
608589 simplified_tools .append (simplified_tool )
609590 elif hasattr (tool , "__name__" ):
610- # Handle callable objects
611591 simplified_tools .append (
612592 {
613593 "name" : tool .__name__ ,
614594 "description" : getattr (tool , "__doc__" , None ),
615595 }
616596 )
617597 else :
618- # Fallback - try to convert to string
619598 tool_str = str (tool )
620599 if tool_str and tool_str != "" :
621600 simplified_tools .append ({"name" : tool_str , "description" : None })
622601 except Exception :
623- # Skip problematic tools rather than failing
624602 continue
625603
626604 return simplified_tools if simplified_tools else None
627605
628606
607+ def _set_tools_on_span (span , tools ):
608+ # type: (Span, Any) -> None
609+ """Set available tools data on a span if tools are provided."""
610+ if tools is not None :
611+ simplified_tools = _simplify_langchain_tools (tools )
612+ if simplified_tools :
613+ span .set_data (
614+ SPANDATA .GEN_AI_REQUEST_AVAILABLE_TOOLS ,
615+ safe_serialize (simplified_tools ),
616+ )
617+
618+
629619def _wrap_configure (f ):
630620 # type: (Callable[..., Any]) -> Callable[..., Any]
631621
@@ -733,13 +723,7 @@ def new_invoke(self, *args, **kwargs):
733723 span .set_data (SPANDATA .GEN_AI_OPERATION_NAME , "invoke_agent" )
734724 span .set_data (SPANDATA .GEN_AI_RESPONSE_STREAMING , False )
735725
736- if tools :
737- simplified_tools = _simplify_langchain_tools (tools )
738- if simplified_tools :
739- span .set_data (
740- SPANDATA .GEN_AI_REQUEST_AVAILABLE_TOOLS ,
741- safe_serialize (simplified_tools ),
742- )
726+ _set_tools_on_span (span , tools )
743727
744728 # Run the agent
745729 result = f (self , * args , ** kwargs )
@@ -792,13 +776,7 @@ def new_stream(self, *args, **kwargs):
792776 span .set_data (SPANDATA .GEN_AI_OPERATION_NAME , "invoke_agent" )
793777 span .set_data (SPANDATA .GEN_AI_RESPONSE_STREAMING , True )
794778
795- if tools :
796- simplified_tools = _simplify_langchain_tools (tools )
797- if simplified_tools :
798- span .set_data (
799- SPANDATA .GEN_AI_REQUEST_AVAILABLE_TOOLS ,
800- safe_serialize (simplified_tools ),
801- )
779+ _set_tools_on_span (span , tools )
802780
803781 input = args [0 ].get ("input" ) if len (args ) >= 1 else None
804782 if (
0 commit comments