feat(streaming): Support ai_track decorator - #6895
Conversation
| client = sentry_sdk.get_client() | ||
|
|
||
| curr_pipeline = _ai_pipeline_name.get() | ||
| op = span_kwargs.pop("op", "ai.run" if curr_pipeline else "ai.pipeline") |
There was a problem hiding this comment.
Bug: Using span_kwargs.pop("op") mutates the shared span_kwargs dictionary, causing subsequent calls to the decorated function to lose the custom op and use a default value.
Severity: MEDIUM
Suggested Fix
Instead of mutating span_kwargs with .pop(), use .get() to retrieve the op value. To prevent passing op along with other keyword arguments, create a copy of the dictionary for the start_span call, excluding the op key. For example: op = span_kwargs.get("op", ...) and other_kwargs = {k: v for k, v in span_kwargs.items() if k != 'op'}.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: sentry_sdk/ai/monitoring.py#L37
Potential issue: The `span_kwargs` dictionary is created once when the `@ai_track`
decorator is applied and is shared across all calls to the decorated function. The code
uses `span_kwargs.pop("op", ...)` to retrieve the operation name, which mutates the
dictionary by permanently removing the `op` key. Consequently, only the first call to a
decorated function with a custom `op` (e.g., `@ai_track("description", op="custom.op")`)
will use the correct operation. All subsequent calls will find the `op` key missing and
will incorrectly fall back to the default value, such as "ai.run".
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Pre-existing issue
| for k, v in kwargs.pop("sentry_data", {}).items(): | ||
| span.set_attribute(k, v) | ||
|
|
||
| if curr_pipeline: |
There was a problem hiding this comment.
Bug: In streaming mode, extra keyword arguments passed to the @ai_track decorator, other than op, are silently ignored instead of being passed to start_span.
Severity: MEDIUM
Suggested Fix
Create a copy of the span_kwargs dictionary, remove the op key, and then pass the remaining arguments to the start_span call in the streaming path. This can be done with other_kwargs = {k: v for k, v in span_kwargs.items() if k != 'op'} and then spreading them into the function call: start_span(..., **other_kwargs).
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: sentry_sdk/ai/monitoring.py#L45-L48
Potential issue: In the new streaming mode code path for the `@ai_track` decorator, any
additional keyword arguments passed to the decorator (e.g., `origin`, `only_if_parent`)
are ignored. The code extracts the `op` but does not forward the rest of the
`span_kwargs` to the `sentry_sdk.traces.start_span` function. This creates an
inconsistency where the decorator's behavior changes depending on whether streaming is
active, silently dropping user-provided span keyword arguments in streaming mode while
correctly applying them in non-streaming mode.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
Correct, intentional
Codecov Results 📊✅ 98293 passed | ⏭️ 6614 skipped | Total: 104907 | Pass Rate: 93.7% | Execution Time: 352m 29s 📊 Comparison with Base Branch
➖ Removed Tests (2)View removed tests
All tests are passing successfully. ❌ Patch coverage is 70.37%. Project has 2520 uncovered lines. Files with missing lines (1)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
- Coverage 89.72% 89.69% -0.03%
==========================================
Files 193 193 —
Lines 24394 24437 +43
Branches 8644 8660 +16
==========================================
+ Hits 21886 21917 +31
- Misses 2508 2520 +12
- Partials 1400 1400 —Generated by Codecov Action |
Description
Make the
@ai_trackdecorator work with span streaming.sentry_dataandsentry_tagswill both set attributes in streaming mode, instead.Issues
Closes #6893
Reminders
uv run ruff.feat:,fix:,ref:,meta:)