update(telemetry): OTel API response event with finish reasons (#13849)

Co-authored-by: Shnatu <snatu@google.com>
This commit is contained in:
Shardul Natu
2025-11-26 20:46:40 -08:00
committed by GitHub
parent 450734e333
commit 6a43b31218
3 changed files with 7 additions and 3 deletions

View File

@@ -361,6 +361,7 @@ Captures Gemini API requests, responses, and errors.
- `response_text` (string, optional)
- `prompt_id` (string)
- `auth_type` (string)
- `finish_reasons` (array of strings)
- `gemini_cli.api_error`: API request failed.
- **Attributes**:

View File

@@ -409,6 +409,7 @@ describe('loggers', () => {
attributes: expect.objectContaining({
'event.name': EVENT_API_RESPONSE,
prompt_id: 'prompt-id-1',
finish_reasons: ['stop'],
}),
});

View File

@@ -31,6 +31,7 @@ import type { AgentTerminateMode } from '../agents/types.js';
import { getCommonAttributes } from './telemetryAttributes.js';
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
import { safeJsonStringify } from '../utils/safeJsonStringify.js';
import type { OTelFinishReason } from './semantic.js';
import {
toInputMessages,
toOutputMessages,
@@ -545,6 +546,7 @@ export class ApiResponseEvent implements BaseTelemetryEvent {
prompt: GenAIPromptDetails;
response: GenAIResponseDetails;
usage: GenAIUsageDetails;
finish_reasons: OTelFinishReason[];
constructor(
model: string,
@@ -573,6 +575,7 @@ export class ApiResponseEvent implements BaseTelemetryEvent {
tool_token_count: usage_data?.toolUsePromptTokenCount ?? 0,
total_token_count: usage_data?.totalTokenCount ?? 0,
};
this.finish_reasons = toFinishReasons(this.response.candidates);
}
toLogRecord(config: Config): LogRecord {
@@ -591,6 +594,7 @@ export class ApiResponseEvent implements BaseTelemetryEvent {
prompt_id: this.prompt.prompt_id,
auth_type: this.auth_type,
status_code: this.status_code,
finish_reasons: this.finish_reasons,
};
if (this.response_text) {
attributes['response_text'] = this.response_text;
@@ -613,9 +617,7 @@ export class ApiResponseEvent implements BaseTelemetryEvent {
'event.name': EVENT_GEN_AI_OPERATION_DETAILS,
'event.timestamp': this['event.timestamp'],
'gen_ai.response.id': this.response.response_id,
'gen_ai.response.finish_reasons': toFinishReasons(
this.response.candidates,
),
'gen_ai.response.finish_reasons': this.finish_reasons,
'gen_ai.output.messages': JSON.stringify(
toOutputMessages(this.response.candidates),
),