@@ -127,6 +127,11 @@ class TracedData(pydantic.BaseModel):
127127 request_model : Optional [str ] = pydantic .Field (default = None )
128128 response_model : Optional [str ] = pydantic .Field (default = None )
129129
130+ # Reasoning attributes
131+ request_reasoning_summary : Optional [str ] = pydantic .Field (default = None )
132+ request_reasoning_effort : Optional [str ] = pydantic .Field (default = None )
133+ response_reasoning_effort : Optional [str ] = pydantic .Field (default = None )
134+
130135
131136responses : dict [str , TracedData ] = {}
132137
@@ -193,6 +198,45 @@ def set_data_attributes(traced_response: TracedData, span: Span):
193198 usage .input_tokens_details .cached_tokens ,
194199 )
195200
201+ reasoning_tokens = None
202+ tokens_details = (
203+ usage .get ("output_tokens_details" ) if isinstance (usage , dict )
204+ else getattr (usage , "output_tokens_details" , None )
205+ )
206+
207+ if tokens_details :
208+ reasoning_tokens = (
209+ tokens_details .get ("reasoning_tokens" , None ) if isinstance (tokens_details , dict )
210+ else getattr (tokens_details , "reasoning_tokens" , None )
211+ )
212+
213+ if hasattr (SpanAttributes , 'LLM_USAGE_REASONING_TOKENS' ):
214+ _set_span_attribute (
215+ span ,
216+ SpanAttributes .LLM_USAGE_REASONING_TOKENS ,
217+ reasoning_tokens or 0 ,
218+ )
219+
220+ # Reasoning attributes - only set if they exist in SpanAttributes
221+ if hasattr (SpanAttributes , 'LLM_REQUEST_REASONING_SUMMARY' ):
222+ _set_span_attribute (
223+ span ,
224+ f"{ SpanAttributes .LLM_REQUEST_REASONING_SUMMARY } " ,
225+ traced_response .request_reasoning_summary or (),
226+ )
227+ if hasattr (SpanAttributes , 'LLM_REQUEST_REASONING_EFFORT' ):
228+ _set_span_attribute (
229+ span ,
230+ f"{ SpanAttributes .LLM_REQUEST_REASONING_EFFORT } " ,
231+ traced_response .request_reasoning_effort or (),
232+ )
233+ if hasattr (SpanAttributes , 'LLM_RESPONSE_REASONING_EFFORT' ):
234+ _set_span_attribute (
235+ span ,
236+ f"{ SpanAttributes .LLM_RESPONSE_REASONING_EFFORT } " ,
237+ traced_response .response_reasoning_effort or (),
238+ )
239+
196240 if should_send_prompts ():
197241 prompt_index = 0
198242 if traced_response .tools :
@@ -428,6 +472,18 @@ def responses_get_or_create_wrapper(tracer: Tracer, wrapped, instance, args, kwa
428472 "model" , existing_data .get ("request_model" , "" )
429473 ),
430474 response_model = existing_data .get ("response_model" , "" ),
475+ # Reasoning attributes
476+ request_reasoning_summary = (
477+ kwargs .get ("reasoning" , {}).get (
478+ "summary" , existing_data .get ("request_reasoning_summary" )
479+ )
480+ ),
481+ request_reasoning_effort = (
482+ kwargs .get ("reasoning" , {}).get (
483+ "effort" , existing_data .get ("request_reasoning_effort" )
484+ )
485+ ),
486+ response_reasoning_effort = kwargs .get ("reasoning" , {}).get ("effort" ),
431487 )
432488 except Exception :
433489 traced_data = None
@@ -479,6 +535,18 @@ def responses_get_or_create_wrapper(tracer: Tracer, wrapped, instance, args, kwa
479535 output_text = existing_data .get ("output_text" , parsed_response_output_text ),
480536 request_model = existing_data .get ("request_model" , kwargs .get ("model" )),
481537 response_model = existing_data .get ("response_model" , parsed_response .model ),
538+ # Reasoning attributes
539+ request_reasoning_summary = (
540+ kwargs .get ("reasoning" , {}).get (
541+ "summary" , existing_data .get ("request_reasoning_summary" )
542+ )
543+ ),
544+ request_reasoning_effort = (
545+ kwargs .get ("reasoning" , {}).get (
546+ "effort" , existing_data .get ("request_reasoning_effort" )
547+ )
548+ ),
549+ response_reasoning_effort = kwargs .get ("reasoning" , {}).get ("effort" ),
482550 )
483551 responses [parsed_response .id ] = traced_data
484552 except Exception :
@@ -542,6 +610,18 @@ async def async_responses_get_or_create_wrapper(
542610 output_text = kwargs .get ("output_text" , existing_data .get ("output_text" )),
543611 request_model = kwargs .get ("model" , existing_data .get ("request_model" )),
544612 response_model = existing_data .get ("response_model" ),
613+ # Reasoning attributes
614+ request_reasoning_summary = (
615+ kwargs .get ("reasoning" , {}).get (
616+ "summary" , existing_data .get ("request_reasoning_summary" )
617+ )
618+ ),
619+ request_reasoning_effort = (
620+ kwargs .get ("reasoning" , {}).get (
621+ "effort" , existing_data .get ("request_reasoning_effort" )
622+ )
623+ ),
624+ response_reasoning_effort = kwargs .get ("reasoning" , {}).get ("effort" ),
545625 )
546626 except Exception :
547627 traced_data = None
@@ -594,6 +674,18 @@ async def async_responses_get_or_create_wrapper(
594674 output_text = existing_data .get ("output_text" , parsed_response_output_text ),
595675 request_model = existing_data .get ("request_model" , kwargs .get ("model" )),
596676 response_model = existing_data .get ("response_model" , parsed_response .model ),
677+ # Reasoning attributes
678+ request_reasoning_summary = (
679+ kwargs .get ("reasoning" , {}).get (
680+ "summary" , existing_data .get ("request_reasoning_summary" )
681+ )
682+ ),
683+ request_reasoning_effort = (
684+ kwargs .get ("reasoning" , {}).get (
685+ "effort" , existing_data .get ("request_reasoning_effort" )
686+ )
687+ ),
688+ response_reasoning_effort = kwargs .get ("reasoning" , {}).get ("effort" ),
597689 )
598690 responses [parsed_response .id ] = traced_data
599691 except Exception :
@@ -695,6 +787,11 @@ def __init__(
695787 output_text = "" ,
696788 request_model = self ._request_kwargs .get ("model" , "" ),
697789 response_model = "" ,
790+ request_reasoning_summary = self ._request_kwargs .get ("reasoning" , {}).get (
791+ "summary"
792+ ),
793+ request_reasoning_effort = self ._request_kwargs .get ("reasoning" , {}).get ("effort" ),
794+ response_reasoning_effort = None ,
698795 )
699796
700797 self ._complete_response_data = None
0 commit comments