11"""AgentScope-specific span creation and stream aggregation."""
22
3+ import contextlib
34from contextlib import aclosing
45from typing import Any
56
@@ -200,29 +201,34 @@ async def _fanout_pipeline_wrapper(wrapped: Any, instance: Any, args: Any, kwarg
200201async def _toolkit_call_tool_function_wrapper (wrapped : Any , instance : Any , args : Any , kwargs : dict [str , Any ]) -> Any :
201202 tool_call = args [0 ] if args else kwargs .get ("tool_call" )
202203 tool_name = _tool_name (tool_call )
203- with start_span (
204- name = f"{ tool_name } .execute" ,
205- type = SpanTypeAttribute .TOOL ,
206- input = _clean (
207- {
208- "tool_name" : tool_name ,
209- "tool_call" : tool_call ,
210- }
211- ),
212- metadata = _clean ({"toolkit_class" : instance .__class__ .__name__ }),
213- ) as span :
204+ with contextlib .ExitStack () as stack :
205+ span = stack .enter_context (
206+ start_span (
207+ name = f"{ tool_name } .execute" ,
208+ type = SpanTypeAttribute .TOOL ,
209+ input = _clean (
210+ {
211+ "tool_name" : tool_name ,
212+ "tool_call" : tool_call ,
213+ }
214+ ),
215+ metadata = _clean ({"toolkit_class" : instance .__class__ .__name__ }),
216+ )
217+ )
214218 try :
215219 result = await wrapped (* args , ** kwargs )
216220 if _is_async_iterator (result ):
221+ deferred = stack .pop_all ()
217222
218223 async def _trace ():
219- last_chunk = None
220- async with aclosing (result ) as agen :
221- async for chunk in agen :
222- last_chunk = chunk
223- yield chunk
224- if last_chunk is not None :
225- span .log (output = last_chunk )
224+ with deferred :
225+ last_chunk = None
226+ async with aclosing (result ) as agen :
227+ async for chunk in agen :
228+ last_chunk = chunk
229+ yield chunk
230+ if last_chunk is not None :
231+ span .log (output = last_chunk )
226232
227233 return _trace ()
228234
@@ -241,24 +247,29 @@ def _is_async_iterator(value: Any) -> bool:
241247
242248
243249async def _model_call_wrapper (wrapped : Any , instance : Any , args : Any , kwargs : dict [str , Any ]) -> Any :
244- with start_span (
245- name = f"{ _model_provider_name (instance )} .call" ,
246- type = SpanTypeAttribute .LLM ,
247- input = _model_call_input (args , kwargs ),
248- metadata = _model_call_metadata (instance , kwargs ),
249- ) as span :
250+ with contextlib .ExitStack () as stack :
251+ span = stack .enter_context (
252+ start_span (
253+ name = f"{ _model_provider_name (instance )} .call" ,
254+ type = SpanTypeAttribute .LLM ,
255+ input = _model_call_input (args , kwargs ),
256+ metadata = _model_call_metadata (instance , kwargs ),
257+ )
258+ )
250259 try :
251260 result = await wrapped (* args , ** kwargs )
252261 if _is_async_iterator (result ):
262+ deferred = stack .pop_all ()
253263
254264 async def _trace ():
255- last_chunk = None
256- async with aclosing (result ) as agen :
257- async for chunk in agen :
258- last_chunk = chunk
259- yield chunk
260- if last_chunk is not None :
261- span .log (output = _model_call_output (last_chunk ), metrics = _extract_metrics (last_chunk ))
265+ with deferred :
266+ last_chunk = None
267+ async with aclosing (result ) as agen :
268+ async for chunk in agen :
269+ last_chunk = chunk
270+ yield chunk
271+ if last_chunk is not None :
272+ span .log (output = _model_call_output (last_chunk ), metrics = _extract_metrics (last_chunk ))
262273
263274 return _trace ()
264275
0 commit comments