Skip to content

Commit 91ee492

Browse files
committed
Fix ruff errors: remove unused variable; run ruff-format
1 parent 8a90db1 commit 91ee492

File tree

1 file changed

+96
-25
lines changed
  • instrumentation-genai/opentelemetry-instrumentation-openai-agents/src/opentelemetry/instrumentation/openai_agents

1 file changed

+96
-25
lines changed

instrumentation-genai/opentelemetry-instrumentation-openai-agents/src/opentelemetry/instrumentation/openai_agents/genai_semantic_processor.py

Lines changed: 96 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@
3131
SpeechSpanData,
3232
TranscriptionSpanData,
3333
)
34-
from openai.types.responses import (
35-
ResponseOutputMessage,
36-
)
3734

3835
from opentelemetry.context import attach, detach
3936
from opentelemetry.metrics import Histogram, get_meter
@@ -579,6 +576,81 @@ def _normalize_messages_to_role_parts(
579576

580577
return normalized
581578

579+
def _normalize_output_messages_to_role_parts(
580+
self, span_data: Any
581+
) -> list[dict[str, Any]]:
582+
"""Normalize output messages to enforced role+parts schema.
583+
584+
Produces: [{"role": "assistant", "parts": [{"type": "text", "content": "..."}],
585+
optional "finish_reason": "..." }]
586+
"""
587+
messages: list[dict[str, Any]] = []
588+
parts: list[dict[str, Any]] = []
589+
finish_reason: Optional[str] = None
590+
591+
# Response span: prefer consolidated output_text
592+
response = getattr(span_data, "response", None)
593+
if response is not None:
594+
# Collect text content
595+
output_text = getattr(response, "output_text", None)
596+
if isinstance(output_text, str) and output_text:
597+
parts.append({"type": "text", "content": output_text})
598+
else:
599+
output = getattr(response, "output", None)
600+
if isinstance(output, Sequence):
601+
for item in output:
602+
# ResponseOutputMessage may have a string representation
603+
txt = getattr(item, "content", None)
604+
if isinstance(txt, str) and txt:
605+
parts.append({"type": "text", "content": txt})
606+
else:
607+
# Fallback: stringified
608+
parts.append(
609+
{"type": "text", "content": str(item)}
610+
)
611+
# Capture finish_reason from parts when present
612+
fr = getattr(item, "finish_reason", None)
613+
if isinstance(fr, str) and not finish_reason:
614+
finish_reason = fr
615+
616+
# Generation span: use span_data.output
617+
if not parts:
618+
output = getattr(span_data, "output", None)
619+
if isinstance(output, Sequence):
620+
for item in output:
621+
if isinstance(item, dict):
622+
if item.get("type") == "text":
623+
txt = item.get("content") or item.get("text")
624+
if isinstance(txt, str) and txt:
625+
parts.append({"type": "text", "content": txt})
626+
elif "content" in item and isinstance(
627+
item["content"], str
628+
):
629+
parts.append(
630+
{"type": "text", "content": item["content"]}
631+
)
632+
else:
633+
parts.append(
634+
{"type": "text", "content": str(item)}
635+
)
636+
if not finish_reason and isinstance(
637+
item.get("finish_reason"), str
638+
):
639+
finish_reason = item.get("finish_reason")
640+
elif isinstance(item, str):
641+
parts.append({"type": "text", "content": item})
642+
else:
643+
parts.append({"type": "text", "content": str(item)})
644+
645+
# Build assistant message
646+
msg: dict[str, Any] = {"role": "assistant", "parts": parts}
647+
if finish_reason:
648+
msg["finish_reason"] = finish_reason
649+
# Only include if there is content
650+
if parts:
651+
messages.append(msg)
652+
return messages
653+
582654
def _infer_output_type(self, span_data: Any) -> str:
583655
"""Infer gen_ai.output.type for multiple span kinds."""
584656
if isinstance(span_data, FunctionSpanData):
@@ -960,9 +1032,18 @@ def _get_attributes_from_generation_span_data(
9601032
safe_json_dumps(sys_instr),
9611033
)
9621034

963-
# Output messages (leave as-is; not normalized here)
964-
if self._capture_messages and span_data.output:
965-
yield GEN_AI_OUTPUT_MESSAGES, safe_json_dumps(span_data.output)
1035+
# Output messages (normalized to role+parts)
1036+
if self._capture_messages and (
1037+
span_data.output or getattr(span_data, "response", None)
1038+
):
1039+
normalized_out = self._normalize_output_messages_to_role_parts(
1040+
span_data
1041+
)
1042+
if normalized_out:
1043+
yield (
1044+
GEN_AI_OUTPUT_MESSAGES,
1045+
safe_json_dumps(normalized_out),
1046+
)
9661047

9671048
# Output type
9681049
yield (
@@ -1165,27 +1246,17 @@ def _get_attributes_from_response_span_data(
11651246
safe_json_dumps(sys_instr),
11661247
)
11671248

1168-
# Output messages (leave as-is; not normalized here)
1249+
# Output messages (normalized to role+parts)
11691250
if self._capture_messages:
1170-
output_messages = getattr(
1171-
getattr(span_data, "response", None), "output", None
1251+
# normalized from span_data response/output
1252+
normalized_out = self._normalize_output_messages_to_role_parts(
1253+
span_data
11721254
)
1173-
if output_messages:
1174-
collected = []
1175-
for part in output_messages:
1176-
if isinstance(part, ResponseOutputMessage):
1177-
content = getattr(
1178-
getattr(span_data, "response", None),
1179-
"output_text",
1180-
None,
1181-
)
1182-
if content:
1183-
collected.append(content)
1184-
if collected:
1185-
yield (
1186-
GEN_AI_OUTPUT_MESSAGES,
1187-
safe_json_dumps(collected),
1188-
)
1255+
if normalized_out:
1256+
yield (
1257+
GEN_AI_OUTPUT_MESSAGES,
1258+
safe_json_dumps(normalized_out),
1259+
)
11891260

11901261
yield (
11911262
GEN_AI_OUTPUT_TYPE,

0 commit comments

Comments
 (0)