Skip to content

fix(litellm): Set operation name from call type instead of chat fallback#6792

Open
VihaanAgarwal wants to merge 2 commits into
getsentry:masterfrom
VihaanAgarwal:fix/litellm-operation-name
Open

fix(litellm): Set operation name from call type instead of chat fallback#6792
VihaanAgarwal wants to merge 2 commits into
getsentry:masterfrom
VihaanAgarwal:fix/litellm-operation-name

Conversation

@VihaanAgarwal

Copy link
Copy Markdown

Fixes #6442.

The input callback mapped every call type except embedding/aembedding to chat, so a litellm.image_generation() call showed up in Sentry as chat dall-e-3 with gen_ai.operation.name: chat. Same story for text completions, speech, transcription, rerank and the rest.

This replaces the binary fallback with an explicit table of the call types we can name accurately:

  • completion/acompletion -> chat
  • text_completion/atext_completion -> text_completion
  • embedding/aembedding -> embeddings
  • responses/aresponses -> responses

Each maps to its matching OP.GEN_AI_* span op (the constants for text_completion and responses already exist and are used by the langchain and openai integrations).

For everything else, gen_ai.operation.name is simply not set. Recording a guess is what this issue is about, and litellm has 140+ call types (batch, files, assistants, video...), most of which have no semconv equivalent. The raw call type still ends up in the span name (image_generation dall-e-3), so the spans stay identifiable. I kept gen_ai.chat as the span op fallback for unmapped types so those spans keep flowing into the AI views like before; happy to change that if you'd rather they drop out.

One test tweak: test_response_without_usage built callback kwargs without a call_type and asserted the span was named chat ..., which only held because of the fallback. Real callbacks always carry call_type (litellm's Logging.pre_call sets it), so I added "call_type": "completion" to those kwargs rather than special casing a missing key as chat.

Tests cover all eight mapped call types plus the unknown case. The litellm test module passes locally except test_multiple_providers, which errors at setup on current master too (missing optional provider package in my env).

@VihaanAgarwal VihaanAgarwal requested a review from a team as a code owner July 9, 2026 20:02
Comment thread sentry_sdk/integrations/litellm.py Outdated
Comment on lines +108 to +111
operation, span_op = _CALL_TYPE_OPERATIONS.get(
call_type, (None, consts.OP.GEN_AI_CHAT)
)
span_name = f"{operation or call_type or 'unknown'} {model}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No data is better than wrong data, so please exit early if the key is not in the dictionary.

Comment on lines +3453 to +3458
_input_callback(kwargs)
_success_callback(
kwargs,
MockCompletionResponse(),
datetime.now(),
datetime.now(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tests, the expectation is that you use the library like a user would and assert that the correct telemetry was emitted.
The existing tests have prior art for how to achieve this.

@VihaanAgarwal

Copy link
Copy Markdown
Author

Fair points, both addressed. Unknown call types now bail before any span is created, so nothing gets recorded for them. Also replaced the callback-level tests with ones that go through litellm.text_completion / litellm.responses / litellm.image_generation with mocked transports and assert on the captured spans.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b57b7f9. Configure here.

),
name=f"{operation} {model}",
op=span_op,
name=span_name,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New ops skip prompt capture

Medium Severity

_CALL_TYPE_OPERATIONS now yields text_completion and responses, but prompt recording still only special-cases embeddings and otherwise reads messages. Those call types take prompt and input, so with include_prompts enabled their inputs are never attached to the span.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b57b7f9. Configure here.

Comment thread sentry_sdk/integrations/litellm.py
Comment on lines +3526 to +3532
def test_unknown_call_type_is_not_instrumented(
sentry_init,
capture_events,
get_model_response,
reset_litellm_executor,
):
"""Call types with no accurate operation name emit no span at all."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not test a negative.
We test that telemetry is emitted for certain operations, and not that telemetry doesn't exist sometimes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Only set accurate operation name in litellm

2 participants