Skip to content

feat(otel): enrich root span with gen_ai attributes and improve output format - #10816

Merged
alexhancock merged 1 commit into
aaif-goose:mainfrom
thesteve0:more-otel-work
Jul 31, 2026
Merged

feat(otel): enrich root span with gen_ai attributes and improve output format#10816
alexhancock merged 1 commit into
aaif-goose:mainfrom
thesteve0:more-otel-work

Conversation

@thesteve0

Copy link
Copy Markdown
Contributor

Summary

  • Add gen_ai.* semantic convention attributes (operation.name, input.messages, output.messages, usage.*) to root spans (reply/reply_stream) so MLflow can populate Request, Response, and Token columns
  • Fix span hierarchy by explicitly parenting reply_stream under reply with parent: — prevents duplicate traces caused by async stream lazy evaluation breaking span context propagation
  • Consolidate consecutive streaming text/reasoning tokens into single entries in OTEL output — eliminates per-token {"type":"text","content":"..."} JSON objects that made traces unreadable
  • Use OpenAI-compatible flat message format ({"role":"user","content":"..."}) on root spans so MLflow's _try_extract_messages can parse them for the overview preview columns
  • Accumulate token usage across LLM calls within a turn and record aggregated totals on both reply_stream and reply spans

Closes #10815

Test change rationale

Updated the provider_stream_records_gen_ai_span_attributes test assertion to expect consolidated text ("hello world") instead of two separate streaming tokens ("hello ", "world"). This reflects the intentional behavior improvement — the previous per-token output produced dozens of tiny JSON objects that were unreadable in trace dashboards.

Test plan

  • cargo test -p goose gen_ai — all 5 tests pass
  • cargo clippy -p goose --all-targets -- -D warnings — clean
  • Live validation: sent traces to MLflow 3.10.1 (simple Q&A, tool-use, multi-question) — Request/Response/Token columns populated, consolidated output, proper parent-child span hierarchy

🤖 Generated with Claude Code

…t format

Add gen_ai.* semantic convention attributes to root spans (reply/reply_stream)
so MLflow can display Request, Response, and Token columns. Fix span hierarchy
by explicitly parenting reply_stream under reply to prevent duplicate traces.

Consolidate consecutive streaming text/reasoning tokens into single entries
in OTEL output instead of per-token JSON objects. Use OpenAI-compatible
message format on root spans for MLflow overview compatibility.

Closes aaif-goose#10815

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ec5cdd6df5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +2051 to +2052
gen_ai.usage.input_tokens = tracing::field::Empty,
gen_ai.usage.output_tokens = tracing::field::Empty,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Declare cache-token fields on the aggregate spans

When a turn includes cache read/write tokens, the new aggregate reply/reply_stream usage recording drops them: record_usage records gen_ai.usage.cache_read.input_tokens and gen_ai.usage.cache_creation.input_tokens, but tracing only accepts fields declared at the span callsite. This span (and the reply span above) declares only input/output tokens, so cache-token records are ignored and the root telemetry remains incomplete for providers that report cache usage.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good feature for a future PR

@thesteve0

Copy link
Copy Markdown
Contributor Author

Chat sessions before
image

And After
image

Trace before
image

and after
image

Individual Trace output now
image

@alexhancock alexhancock self-assigned this Jul 30, 2026

@michaelneale michaelneale left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

makes sense.

@alexhancock

Copy link
Copy Markdown
Collaborator

This is excellent - thank you @thesteve0

@alexhancock
alexhancock merged commit 3016108 into aaif-goose:main Jul 31, 2026
24 checks passed
@thesteve0

Copy link
Copy Markdown
Contributor Author

Thanks this has been really fun. I think from here on out I am going to try using Goose and Qwen 3.6 35B 8bit to see how well it goes. I have has some good preliminary results so far on smaller side projects

Let me know if there is something in particular you think would be good to add to the OTEL output

lifeizhou-ap added a commit that referenced this pull request Aug 3, 2026
* main: (103 commits)
  fix: parse PyPI requirements for OSV checks (#10510)
  fix(telegram): contain voice file extensions (#10456)
  Revert "feat(security): chunk command-classifier input with overlapping windows" (#10416) (#10870)
  docs: update Discord invite (#10863)
  fix(security): preserve denied tool request precedence (#10612)
  fix(hints): contain subdirectory hint discovery (#10545)
  chore(deps): bump pem from 3.0.6 to 4.0.0 (#10853)
  chore(deps): bump base64 from 0.22.1 to 0.23.0 (#10851)
  chore(deps): bump jsonwebtoken from 10.4.0 to 11.0.0 (#10850)
  chore(deps): bump astral-sh/setup-uv from 8.3.2 to 9.0.0 (#10847)
  chore(deps): bump docker/login-action from 4.5.1 to 4.5.2 (#10846)
  chore(deps): bump github/codeql-action from 4 to 4.37.3 (#10845)
  chore(deps): bump actions/stale from 10.4.0 to 11.0.0 (#10844)
  feat(dictation): add LOCAL_WHISPER_LANGUAGE for multilingual local transcription (#10634)
  fix(desktop): clear stale validation error when reopening the schedule modal (#10627)
  fix(docs): resolve CVE-2026-13149 in both brace-expansion copies (#10842)
  feat(provider): add Friendli as declarative provider (#10762)
  fix: sanitize shell/subprocess call in linux.rs (#10748)
  fix(desktop): unlink destination before copying binaries (#10705)
  feat(otel): enrich root span with gen_ai attributes and improve output format (#10816)
  ...
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.

Enhance Root Span OTEL output

3 participants