diff --git a/litellm/integrations/arize/_utils.py b/litellm/integrations/arize/_utils.py index e40089a8e6f..3ad7dda0796 100644 --- a/litellm/integrations/arize/_utils.py +++ b/litellm/integrations/arize/_utils.py @@ -277,19 +277,20 @@ def _set_embedding_outputs(span: "Span", response_obj, embedding_attrs, span_att ) +# Items can arrive as Pydantic models (SDK path) or dicts (proxy path). +# Read both via a uniform accessor so dict-shaped output[] arrays from +# Responses API don't get silently skipped. +def _get(obj, key, default=None): + if hasattr(obj, "get"): + return obj.get(key, default) + return getattr(obj, key, default) + + def _set_structured_outputs(span: "Span", response_obj, msg_attrs, span_attrs): output_items = response_obj.get("output", []) for i, item in enumerate(output_items): prefix = f"{span_attrs.LLM_OUTPUT_MESSAGES}.{i}" - # Items can arrive as Pydantic models (SDK path) or dicts (proxy path). - # Read both via a uniform accessor so dict-shaped output[] arrays from - # Responses API don't get silently skipped. - def _get(obj, key, default=None): - if hasattr(obj, "get"): - return obj.get(key, default) - return getattr(obj, key, default) - item_type = _get(item, "type") if item_type is None: continue @@ -718,7 +719,7 @@ def _extract_chain_output( - Reranker → ``results`` JSON - Anything else → ``standard_logging_payload["response"]`` """ - + if isinstance(response_obj, BaseModel): try: response_obj = response_obj.model_dump() diff --git a/litellm/integrations/arize/arize_phoenix.py b/litellm/integrations/arize/arize_phoenix.py index df941419849..563d1b493c1 100644 --- a/litellm/integrations/arize/arize_phoenix.py +++ b/litellm/integrations/arize/arize_phoenix.py @@ -5,7 +5,6 @@ from litellm._logging import verbose_logger from litellm.integrations.arize import _utils from litellm.integrations.arize._utils import ArizeOTELAttributes from litellm.types.integrations.arize_phoenix import ArizePhoenixConfig -from opentelemetry import trace as _trace if TYPE_CHECKING: from opentelemetry.sdk.trace import TracerProvider @@ -238,6 +237,8 @@ class ArizePhoenixLogger(OpenTelemetry): # type: ignore # Guardrail context: in proxy mode it's a sibling of litellm_request # under litellm_proxy_request. In SDK mode there is no proxy parent, # so we parent it to the litellm_request span to avoid an orphan. + from opentelemetry import trace as _trace + guardrail_ctx = ( ctx if parent_span is not None else _trace.set_span_in_context(span) ) @@ -289,6 +290,8 @@ class ArizePhoenixLogger(OpenTelemetry): # type: ignore self._record_exception_on_span(span=span, kwargs=kwargs) # See _handle_success for guardrail context rationale. + from opentelemetry import trace as _trace + guardrail_ctx = ( ctx if parent_span is not None else _trace.set_span_in_context(span) )