1616
1717import json
1818from dataclasses import asdict , is_dataclass
19- from typing import Any , Mapping , Sequence
19+ from typing import Any , Dict , Mapping , Optional , Sequence
2020
2121from opentelemetry .util .genai .extended_semconv .gen_ai_extended_attributes import (
2222 GEN_AI_SESSION_ID ,
3939)
4040
4141_PROVIDER = "agno"
42+ _SKILL_TOOL_NAMES = {
43+ "get_skill_instructions" ,
44+ "get_skill_reference" ,
45+ "get_skill_script" ,
46+ }
4247
4348
4449def _json_default (value : Any ) -> Any :
@@ -82,6 +87,95 @@ def _to_dict(value: Any) -> dict[str, Any] | None:
8287 return None
8388
8489
90+ def _mapping_from_any (value : Any ) -> Dict [str , Any ]:
91+ data = _to_dict (value )
92+ if data is not None :
93+ return data
94+ if isinstance (value , str ):
95+ try :
96+ loaded = json .loads (value )
97+ except Exception :
98+ return {}
99+ return loaded if isinstance (loaded , dict ) else {}
100+ return {}
101+
102+
103+ def _first_text (* values : Any ) -> Optional [str ]:
104+ for value in values :
105+ if value is None :
106+ continue
107+ text = str (value ).strip ()
108+ if text :
109+ return text
110+ return None
111+
112+
113+ def _extract_skill_metadata (value : Any ) -> Dict [str , Any ]:
114+ data = _mapping_from_any (value )
115+ if not data :
116+ return {}
117+ frontmatter = _mapping_from_any (data .get ("frontmatter" ))
118+ metadata = _mapping_from_any (data .get ("metadata" )) or _mapping_from_any (
119+ frontmatter .get ("metadata" )
120+ )
121+ return {
122+ "name" : _first_text (
123+ data .get ("skill_name" ),
124+ data .get ("skill" ),
125+ data .get ("name" ),
126+ frontmatter .get ("name" ),
127+ ),
128+ "id" : _first_text (
129+ data .get ("skill_id" ),
130+ data .get ("id" ),
131+ metadata .get ("id" ),
132+ ),
133+ "description" : _first_text (
134+ data .get ("skill_description" ),
135+ data .get ("description" ),
136+ frontmatter .get ("description" ),
137+ ),
138+ "version" : _first_text (
139+ data .get ("skill_version" ),
140+ data .get ("version" ),
141+ metadata .get ("version" ),
142+ ),
143+ }
144+
145+
146+ def _apply_skill_metadata (
147+ invocation : ExecuteToolInvocation , metadata : Mapping [str , Any ]
148+ ) -> None :
149+ name = _first_text (metadata .get ("name" ))
150+ if name :
151+ invocation .skill_name = invocation .skill_name or name
152+ invocation .skill_id = (
153+ invocation .skill_id or _first_text (metadata .get ("id" )) or name
154+ )
155+ elif metadata .get ("id" ):
156+ invocation .skill_id = invocation .skill_id or _first_text (
157+ metadata .get ("id" )
158+ )
159+
160+ description = _first_text (metadata .get ("description" ))
161+ if description :
162+ invocation .skill_description = (
163+ invocation .skill_description or description
164+ )
165+
166+ version = _first_text (metadata .get ("version" ))
167+ if version :
168+ invocation .skill_version = invocation .skill_version or version
169+
170+
171+ def _apply_agno_skill_tool_metadata (
172+ invocation : ExecuteToolInvocation , data : Any
173+ ) -> None :
174+ if invocation .tool_name not in _SKILL_TOOL_NAMES :
175+ return
176+ _apply_skill_metadata (invocation , _extract_skill_metadata (data ))
177+
178+
85179def _get_value (value : Any , name : str , default : Any = None ) -> Any :
86180 if isinstance (value , Mapping ):
87181 return value .get (name , default )
@@ -555,14 +649,16 @@ def update_llm_invocation_from_response(
555649
556650def create_tool_invocation (function_call : Any ) -> ExecuteToolInvocation :
557651 function = getattr (function_call , "function" , None )
558- return ExecuteToolInvocation (
652+ invocation = ExecuteToolInvocation (
559653 tool_name = getattr (function , "name" , None ) or "unknown_tool" ,
560654 provider = _PROVIDER ,
561655 tool_call_id = getattr (function_call , "call_id" , None ),
562656 tool_description = getattr (function , "description" , None ),
563657 tool_type = "function" ,
564658 tool_call_arguments = getattr (function_call , "arguments" , None ),
565659 )
660+ _apply_agno_skill_tool_metadata (invocation , invocation .tool_call_arguments )
661+ return invocation
566662
567663
568664def update_tool_invocation_from_response (
@@ -572,3 +668,4 @@ def update_tool_invocation_from_response(
572668 invocation .tool_call_result = (
573669 result if isinstance (result , str ) else _stringify (result )
574670 )
671+ _apply_agno_skill_tool_metadata (invocation , result )
0 commit comments