fix arize observability bugs - #26526
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Greptile SummaryThis PR fixes several Arize/Phoenix observability bugs: refactors image-trace payload handling with a size cap, adds a router-level parent span to group retries and fallbacks under one root in Phoenix, fixes guardrail span parenting, and adds fallback event spans.
Confidence Score: 3/5Not safe to merge as-is — the constant MIME-type expression in One clear P1 logic bug (
|
| Filename | Overview |
|---|---|
| litellm/integrations/arize/_utils.py | Large refactor adding image-trace, chain-output, fallback-span, and response-ID utilities. Contains a P1 "application/json" or None constant expression bug that always forces JSON MIME type on plain-text tool/MCP results. |
| litellm/integrations/arize/arize_phoenix.py | Adds router-level parent span management, guardrail-context fix, fallback event spans, and a no-op async_post_call_success_hook; logic looks correct but depends on the _utils.py fixes. |
| litellm/router.py | Adds _start_router_parent_spans / _end_router_parent_spans hooks around the outer fallback call; asyncio.CancelledError can escape final_exception capture, causing cancelled spans to be recorded as OK. |
Sequence Diagram
sequenceDiagram
participant Client
participant Router
participant ArizePhoenix
participant OTelExporter
Client->>Router: async_function_with_fallbacks (fallback_depth=0)
Router->>ArizePhoenix: start_router_parent_span(kwargs)
ArizePhoenix->>OTelExporter: start span "litellm_proxy_request" (CHAIN)
Router->>Router: async_function_with_retries (attempt 1)
Router->>ArizePhoenix: _handle_success / _handle_failure
ArizePhoenix->>OTelExporter: child span "litellm_request" (LLM)
alt Fallback triggered
Router->>Router: async_function_with_fallbacks_common_utils
Router->>ArizePhoenix: log_success_fallback_event / log_failure_fallback_event
ArizePhoenix->>OTelExporter: sibling span "fallback: modelA -> modelB"
Router->>Router: async_function_with_retries (fallback_depth=1)
Router->>ArizePhoenix: _handle_success
ArizePhoenix->>OTelExporter: child span "litellm_request" (LLM, retry)
end
Router->>ArizePhoenix: end_router_parent_span(kwargs, exception)
ArizePhoenix->>OTelExporter: end span "litellm_proxy_request"
Reviews (5): Last reviewed commit: "fix lint" | Re-trigger Greptile
Arize/Phoenix observability instrumentation improvementsThis PR refactors image output tracing (with base64 size limits), adds parent span management for router-level fallback chains, and unifies structured output extraction for the Arize/Phoenix integration. The changes are confined to tracing/observability code that writes span attributes via Status: 0 open |
| if isinstance(response_obj, dict): | ||
| provider_id = response_obj.get("id") | ||
| if provider_id: | ||
| return str(provider_id) |
There was a problem hiding this comment.
_resolve_response_id misses non-dict response objects
isinstance(response_obj, dict) is False for LiteLLM's ModelResponse / EmbeddingResponse objects, which are Pydantic BaseModel subclasses — not plain dicts. Those objects do expose a custom .get() method (see litellm/types/utils.py), but they are not detected here. As a result, every SDK-path LLM call silently skips the provider-issued ID (e.g. chatcmpl-XXX) and instead records litellm_call_id as llm.response.id, making it impossible to correlate Phoenix spans with the upstream provider's traces.
# Before: only captures dict responses
if isinstance(response_obj, dict):
provider_id = response_obj.get("id")
# Fix: accept any object that has .get()
if hasattr(response_obj, "get"):
provider_id = response_obj.get("id")
Relevant issues
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
tests/test_litellm/directory, Adding at least 1 test is a hard requirement - see detailsmake test-unit@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewDelays in PR merge?
If you're seeing a delay in your PR being merged, ping the LiteLLM Team on Slack (#pr-review).
CI (LiteLLM team)
Branch creation CI run
Link:
CI run for the last commit
Link:
Merge / cherry-pick CI run
Links:
Screenshots / Proof of Fix
Type
🆕 New Feature
🐛 Bug Fix
🧹 Refactoring
📖 Documentation
🚄 Infrastructure
✅ Test
Changes