3
3
from __future__ import annotations
4
4
5
5
from contextlib import contextmanager
6
- from typing import Any , Mapping , Protocol , Type
6
+ from typing import Any , Mapping , Protocol , Type , cast
7
7
8
- from agents import custom_span , get_current_span , trace
8
+ from agents import CustomSpanData , custom_span , get_current_span , trace
9
9
from agents .tracing import (
10
10
get_trace_provider ,
11
11
)
12
- from agents .tracing .spans import NoOpSpan
12
+ from agents .tracing .provider import DefaultTraceProvider
13
+ from agents .tracing .scope import Scope
14
+ from agents .tracing .spans import NoOpSpan , SpanImpl
13
15
14
16
import temporalio .activity
15
17
import temporalio .api .common .v1
@@ -65,11 +67,15 @@ def context_from_header(
65
67
else workflow .info ().workflow_type
66
68
)
67
69
data = (
68
- {"activityId" : activity .info ().activity_id }
70
+ {
71
+ "activityId" : activity .info ().activity_id ,
72
+ "activity" : activity .info ().activity_type ,
73
+ }
69
74
if activity .in_activity ()
70
75
else None
71
76
)
72
- if get_trace_provider ().get_current_trace () is None :
77
+ current_trace = get_trace_provider ().get_current_trace ()
78
+ if current_trace is None :
73
79
metadata = {
74
80
"temporal:workflowId" : activity .info ().workflow_id
75
81
if activity .in_activity ()
@@ -79,16 +85,21 @@ def context_from_header(
79
85
else workflow .info ().run_id ,
80
86
"temporal:workflowType" : workflow_type ,
81
87
}
82
- with trace (
88
+ current_trace = trace (
83
89
span_info ["traceName" ],
84
90
trace_id = span_info ["traceId" ],
85
91
metadata = metadata ,
86
- ) as t :
87
- with custom_span (name = span_name , parent = t , data = data ):
88
- yield
89
- else :
90
- with custom_span (name = span_name , parent = None , data = data ):
91
- yield
92
+ )
93
+ Scope .set_current_trace (current_trace )
94
+ current_span = get_trace_provider ().get_current_span ()
95
+ if current_span is None :
96
+ current_span = get_trace_provider ().create_span (
97
+ span_data = CustomSpanData (name = "" , data = {}), span_id = span_info ["spanId" ]
98
+ )
99
+ Scope .set_current_span (current_span )
100
+
101
+ with custom_span (name = span_name , parent = current_span , data = data ):
102
+ yield
92
103
93
104
94
105
class OpenAIAgentsTracingInterceptor (
@@ -115,7 +126,7 @@ class OpenAIAgentsTracingInterceptor(
115
126
worker = Worker(client, task_queue="my-task-queue", interceptors=[interceptor])
116
127
"""
117
128
118
- def __init__ ( # type: ignore[reportMissingSuperCall]
129
+ def __init__ (
119
130
self ,
120
131
payload_converter : temporalio .converter .PayloadConverter = temporalio .converter .default ().payload_converter ,
121
132
) -> None :
@@ -325,32 +336,55 @@ class _ContextPropagationWorkflowOutboundInterceptor(
325
336
async def signal_child_workflow (
326
337
self , input : temporalio .worker .SignalChildWorkflowInput
327
338
) -> None :
328
- set_header_from_context (input , temporalio .workflow .payload_converter ())
329
- return await self .next .signal_child_workflow (input )
339
+ with custom_span (
340
+ name = "temporal:signalChildWorkflow" ,
341
+ data = {"workflowId" : input .child_workflow_id },
342
+ ):
343
+ set_header_from_context (input , temporalio .workflow .payload_converter ())
344
+ await self .next .signal_child_workflow (input )
330
345
331
346
async def signal_external_workflow (
332
347
self , input : temporalio .worker .SignalExternalWorkflowInput
333
348
) -> None :
334
- set_header_from_context (input , temporalio .workflow .payload_converter ())
335
- return await self .next .signal_external_workflow (input )
349
+ with custom_span (
350
+ name = "temporal:signalExternalWorkflow" ,
351
+ data = {"workflowId" : input .workflow_id },
352
+ ):
353
+ set_header_from_context (input , temporalio .workflow .payload_converter ())
354
+ await self .next .signal_external_workflow (input )
336
355
337
356
def start_activity (
338
357
self , input : temporalio .worker .StartActivityInput
339
358
) -> temporalio .workflow .ActivityHandle :
340
- with custom_span (
341
- name = f"temporal:startActivity:{ input .activity } " ,
342
- ):
343
- set_header_from_context (input , temporalio .workflow .payload_converter ())
344
- return self .next .start_activity (input )
359
+ span = custom_span (
360
+ name = "temporal:startActivity" , data = {"activity" : input .activity }
361
+ )
362
+ span .start (mark_as_current = True )
363
+ set_header_from_context (input , temporalio .workflow .payload_converter ())
364
+ handle = self .next .start_activity (input )
365
+ handle .add_done_callback (lambda _ : span .finish ())
366
+ return handle
345
367
346
368
async def start_child_workflow (
347
369
self , input : temporalio .worker .StartChildWorkflowInput
348
370
) -> temporalio .workflow .ChildWorkflowHandle :
371
+ span = custom_span (
372
+ name = "temporal:startChildWorkflow" , data = {"workflow" : input .workflow }
373
+ )
374
+ span .start (mark_as_current = True )
349
375
set_header_from_context (input , temporalio .workflow .payload_converter ())
350
- return await self .next .start_child_workflow (input )
376
+ handle = await self .next .start_child_workflow (input )
377
+ handle .add_done_callback (lambda _ : span .finish ())
378
+ return handle
351
379
352
380
def start_local_activity (
353
381
self , input : temporalio .worker .StartLocalActivityInput
354
382
) -> temporalio .workflow .ActivityHandle :
383
+ span = custom_span (
384
+ name = "temporal:startLocalActivity" , data = {"activity" : input .activity }
385
+ )
386
+ span .start (mark_as_current = True )
355
387
set_header_from_context (input , temporalio .workflow .payload_converter ())
356
- return self .next .start_local_activity (input )
388
+ handle = self .next .start_local_activity (input )
389
+ handle .add_done_callback (lambda _ : span .finish ())
390
+ return handle
0 commit comments