Skip to content

Commit 6304f1f

Browse files
committed
openai-agents-v2: Populate instructions and tool definitions from Response obj
1 parent 93bea2d commit 6304f1f

2 files changed

Lines changed: 75 additions & 0 deletions

File tree

instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/src/opentelemetry/instrumentation/openai_agents/span_processor.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,10 +1056,20 @@ def _build_content_payload(self, span: Span[Any]) -> ContentPayload:
10561056

10571057
elif _is_instance_of(span_data, ResponseSpanData):
10581058
span_input = getattr(span_data, "input", None)
1059+
response_obj = getattr(span_data, "response", None)
10591060
if capture_messages and span_input:
10601061
payload.input_messages = (
10611062
self._normalize_messages_to_role_parts(span_input)
10621063
)
1064+
1065+
if (
1066+
capture_system
1067+
and response_obj
1068+
and hasattr(response_obj, "instructions")
1069+
):
1070+
payload.system_instructions = self._normalize_to_text_parts(
1071+
response_obj.instructions
1072+
)
10631073
if capture_system and span_input:
10641074
sys_instr = self._collect_system_instructions(span_input)
10651075
if sys_instr:
@@ -2029,6 +2039,32 @@ def _get_attributes_from_response_span_data(
20292039
if output_tokens is not None:
20302040
yield GEN_AI_USAGE_OUTPUT_TOKENS, output_tokens
20312041

2042+
# Tool definitions from response
2043+
if self._capture_tool_definitions and hasattr(
2044+
span_data.response, "tools"
2045+
):
2046+
2047+
def _serialize_tool_value(value: Any) -> Optional[str]:
2048+
if value is None:
2049+
return None
2050+
return {
2051+
"name": getattr(value, "name", None),
2052+
"type": getattr(value, "type", None),
2053+
"description": getattr(value, "description", None),
2054+
"parameters": getattr(value, "parameters", None),
2055+
}
2056+
2057+
yield (
2058+
GEN_AI_TOOL_DEFINITIONS,
2059+
safe_json_dumps(
2060+
list(
2061+
map(
2062+
_serialize_tool_value, span_data.response.tools
2063+
)
2064+
)
2065+
),
2066+
)
2067+
20322068
# Input/output messages
20332069
if (
20342070
self.include_sensitive_data

instrumentation-genai/opentelemetry-instrumentation-openai-agents-v2/tests/test_tracer.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,11 +484,26 @@ def __init__(self, input_tokens: int, output_tokens: int) -> None:
484484
self.input_tokens = input_tokens
485485
self.output_tokens = output_tokens
486486

487+
class _FunctionTool:
488+
def __init__(self) -> None:
489+
self.name = "get_current_weather"
490+
self.type = "function"
491+
self.description = "Get the current weather in a given location"
492+
self.parameters = {
493+
"type": "object",
494+
"properties": {
495+
"location": {"title": "Location", "type": "string"},
496+
},
497+
"required": ["location"],
498+
}
499+
487500
class _Response:
488501
def __init__(self) -> None:
489502
self.id = "resp-123"
503+
self.instructions = "You are a helpful assistant."
490504
self.model = "gpt-4o-mini"
491505
self.usage = _Usage(42, 9)
506+
self.tools = [_FunctionTool()]
492507
self.output = [{"finish_reason": "stop"}]
493508

494509
try:
@@ -516,6 +531,30 @@ def __init__(self) -> None:
516531
assert response.attributes[GenAI.GEN_AI_RESPONSE_FINISH_REASONS] == (
517532
"stop",
518533
)
534+
535+
system_instructions = json.loads(
536+
response.attributes[GenAI.GEN_AI_SYSTEM_INSTRUCTIONS]
537+
)
538+
assert system_instructions == [
539+
{"type": "text", "content": "You are a helpful assistant."}
540+
]
541+
tool_definitions = json.loads(
542+
response.attributes[GenAI.GEN_AI_TOOL_DEFINITIONS]
543+
)
544+
assert tool_definitions == [
545+
{
546+
"type": "function",
547+
"name": "get_current_weather",
548+
"description": "Get the current weather in a given location",
549+
"parameters": {
550+
"type": "object",
551+
"properties": {
552+
"location": {"title": "Location", "type": "string"},
553+
},
554+
"required": ["location"],
555+
},
556+
}
557+
]
519558
finally:
520559
instrumentor.uninstrument()
521560
exporter.clear()

0 commit comments

Comments
 (0)