Skip to content

feat: Send GenAI spans as V2 envelope items#6079

Draft
alexander-alderman-webb wants to merge 9 commits intomasterfrom
webb/gen-ai-v2
Draft

feat: Send GenAI spans as V2 envelope items#6079
alexander-alderman-webb wants to merge 9 commits intomasterfrom
webb/gen-ai-v2

Conversation

@alexander-alderman-webb
Copy link
Copy Markdown
Contributor

Description

Issues

Reminders

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 15, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (ci) Cancel in-progress PR workflows on new commit push by joshuarli in #5994
  • Send GenAI spans as V2 envelope items by alexander-alderman-webb in #6079

Bug Fixes 🐛

  • (google_genai) Redact binary data in inline_data and fix multi-part message extraction by ericapisani in #5977
  • (profiler) Stop nulling buffer on teardown by ericapisani in #6075

Internal Changes 🔧

  • (celery) Remove unused NoOpMgr from utils by sentrivana in #6078
  • (pydantic-ai) Remove dead Model.request patch by alexander-alderman-webb in #5956
  • (tests) Replace deprecated enable_tracingwith traces_sample_rate by sentrivana in #6077
  • Set explicit base-branch for codecov action by ericapisani in #5992

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 15, 2026

Codecov Results 📊

6 passed | Total: 6 | Pass Rate: 100% | Execution Time: 6.52s

📊 Comparison with Base Branch

Metric Change
Total Tests 📉 -1
Passed Tests 📉 -1
Failed Tests
Skipped Tests

All tests are passing successfully.

❌ Patch coverage is 19.30%. Project has 16721 uncovered lines.
✅ Project coverage is 22.05%. Comparing base (base) to head (head).

Files with missing lines (1)
File Patch % Lines
client.py 45.85% ⚠️ 352 Missing and 68 partials
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    21.84%    22.05%    +0.21%
==========================================
  Files          190       190         —
  Lines        21351     21452      +101
  Branches      7066      7146       +80
==========================================
+ Hits          4662      4731       +69
- Misses       16689     16721       +32
- Partials       379       388        +9

Generated by Codecov Action

Comment on lines +1118 to +1128
"item_count": len(gen_ai_spans),
},
payload=PayloadRef(
json={
"items": [
_serialized_v1_span_to_serialized_v2_span(
span, event
)
for span in gen_ai_spans
if isinstance(span, dict)
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

item_count header may not match actual items due to isinstance filtering

The item_count header is set to len(gen_ai_spans) but the actual items list filters spans with if isinstance(span, dict). If any span in gen_ai_spans is not a dict (e.g., an AnnotatedValue or other type), the header will report more items than are actually present in the payload. This could cause issues with downstream processing that relies on the item_count header being accurate.

Verification

Verified by examining: (1) _split_gen_ai_spans at lines 255-277, which iterates spans and appends to gen_ai_spans list without type checking (it only calls .get() on spans, assuming dict-like behavior); (2) The spans in event_opt["spans"] could potentially contain non-dict types as seen in other parts of the codebase that check for AnnotatedValue. The filtering on line 1127 guards against this but creates a mismatch with the count on line 1118.

Suggested fix: Either filter gen_ai_spans before calculating item_count, or compute item_count from the filtered list.

Suggested change
"item_count": len(gen_ai_spans),
},
payload=PayloadRef(
json={
"items": [
_serialized_v1_span_to_serialized_v2_span(
span, event
)
for span in gen_ai_spans
if isinstance(span, dict)
]
gen_ai_spans = [span for span in gen_ai_spans if isinstance(span, dict)]
span, event_opt

Identified by Warden find-bugs · BKJ-YKB

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.

1 participant