feat(otel): emit gen_ai.response.finish_reasons on the agent span#31332
Merged
Conversation
7 tasks
- Add `buildArrayAttr` helper for OTLP string-array attributes - Extend `AgentRuntimeMetrics` typedef with `stopReason` field - Extract `stop_reason` from agent stdio log result JSON - Emit `gen_ai.response.finish_reasons` on the dedicated agent span - Add three tests covering present/absent/max_tokens scenarios - Document `gen_ai.response.finish_reasons` in frontmatter.md Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Add gen_ai.response.finish_reasons to the agent span
feat(otel): emit gen_ai.response.finish_reasons on the agent span
May 10, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Adds support for emitting gen_ai.response.finish_reasons on the dedicated agent span by extracting stop_reason from the agent stdio result line and encoding it as an OTLP arrayValue attribute, enabling observability backends to distinguish normal completions from truncations like max_tokens.
Changes:
- Add
buildArrayAttr()helper to encodestring[]OTLP attributes viaarrayValue. - Extend
readAgentRuntimeMetrics()to capturestop_reasonand attach it to the agent span asgen_ai.response.finish_reasons. - Update docs and add unit tests verifying the attribute is included/omitted appropriately.
Show a summary per file
| File | Description |
|---|---|
| docs/src/content/docs/reference/frontmatter.md | Documents gen_ai.response.finish_reasons as an agent span attribute. |
| actions/setup/js/send_otlp_span.cjs | Parses stop_reason and emits gen_ai.response.finish_reasons on the agent span using a new array-attribute helper. |
| actions/setup/js/send_otlp_span.test.cjs | Adds coverage for inclusion/omission of gen_ai.response.finish_reasons based on presence of stop_reason. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 3/3 changed files
- Comments generated: 0
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
✨ Enhancement
What does this improve?
readAgentRuntimeMetricsalready parsed the agent's stdioresultJSON line but discardedstop_reason. Without it,gen_ai.response.finish_reasonswas never set on thegh-aw.<job>.agentspan, making it impossible to distinguish successful completions from silentmax_tokenstruncations in any OTel backend.Implementation approach:
buildArrayAttrhelper — new function that produces a properly-encoded OTLParrayValueattribute (required forgen_ai.response.finish_reasonswhich isstring[]in the GenAI semconv)readAgentRuntimeMetrics— extractsstop_reasonfrom the result JSON alongside the existingnum_turns/total_cost_usd; stored asstopReasononAgentRuntimeMetricssendJobConclusionSpan— pushesgen_ai.response.finish_reasons: [stopReason]ontoagentAttributeswhen present; omitted when the field is absent (e.g. cancelled/timed-out runs)The resulting agent span now enables backend queries like:
Docs:
gen_ai.response.finish_reasonsadded to the agent span attributes table infrontmatter.md.