The Google client span (google.chat_complete) records rich response metadata — token usage (ai.prompt_tokens, ai.completion_tokens, etc.), ai.time_to_first_token_ms, ai.model — but not the response finish reason.
Without it, a MAX_TOKENS truncation is invisible at the source. This bites consumers that combine MaxCompletionTokens with a ResponseSchema: when the model hits the token cap mid-JSON, the output is truncated, and the consumer's json.Unmarshal fails with a generic parse error several layers up — with no signal that the real cause was truncation rather than a transient API error.
Request
Set the response finish reason as a span attribute, e.g. ai.finish_reason, to match the existing ai.* namespace.
For the Google client, the value is available on the final streamed chunk via chunk.Candidates[0].FinishReason, so it fits naturally in the same streaming defer in clients/google/chat_complete.go that already emits the usage-metadata attributes (around the lastUsage block).
Consistency
Ideally the same attribute is added to the Anthropic (anthropic.chat_complete) and OpenAI (openai.chat_complete) client spans, mapping each provider's stop/finish field to a common ai.finish_reason, so the attribute is portable across backends.
Filed via Claude Code: https://claude.ai/code/session_01SxCXEQU7DLKw6p9B7kJ5Ej
The Google client span (
google.chat_complete) records rich response metadata — token usage (ai.prompt_tokens,ai.completion_tokens, etc.),ai.time_to_first_token_ms,ai.model— but not the response finish reason.Without it, a
MAX_TOKENStruncation is invisible at the source. This bites consumers that combineMaxCompletionTokenswith aResponseSchema: when the model hits the token cap mid-JSON, the output is truncated, and the consumer'sjson.Unmarshalfails with a generic parse error several layers up — with no signal that the real cause was truncation rather than a transient API error.Request
Set the response finish reason as a span attribute, e.g.
ai.finish_reason, to match the existingai.*namespace.For the Google client, the value is available on the final streamed chunk via
chunk.Candidates[0].FinishReason, so it fits naturally in the same streamingdeferinclients/google/chat_complete.gothat already emits the usage-metadata attributes (around thelastUsageblock).Consistency
Ideally the same attribute is added to the Anthropic (
anthropic.chat_complete) and OpenAI (openai.chat_complete) client spans, mapping each provider's stop/finish field to a commonai.finish_reason, so the attribute is portable across backends.Filed via Claude Code: https://claude.ai/code/session_01SxCXEQU7DLKw6p9B7kJ5Ej