Merge tag 'v0.3.0' into chore/sync-gemini-cli-v0.3.0

This commit is contained in:
mingholy.lmh
2025-09-10 21:01:40 +08:00
583 changed files with 30160 additions and 10770 deletions

View File

@@ -4,32 +4,55 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { LogAttributes, LogRecord, logs } from '@opentelemetry/api-logs';
import type { LogAttributes, LogRecord } from '@opentelemetry/api-logs';
import { logs } from '@opentelemetry/api-logs';
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
import { Config } from '../config/config.js';
import type { Config } from '../config/config.js';
import { safeJsonStringify } from '../utils/safeJsonStringify.js';
import { UserAccountManager } from '../utils/userAccountManager.js';
import {
EVENT_API_ERROR,
EVENT_API_REQUEST,
EVENT_API_RESPONSE,
EVENT_CHAT_COMPRESSION,
EVENT_CLI_CONFIG,
EVENT_CONTENT_RETRY,
EVENT_CONTENT_RETRY_FAILURE,
EVENT_CONVERSATION_FINISHED,
EVENT_FLASH_FALLBACK,
EVENT_IDE_CONNECTION,
EVENT_INVALID_CHUNK,
EVENT_NEXT_SPEAKER_CHECK,
EVENT_SLASH_COMMAND,
EVENT_TOOL_CALL,
EVENT_USER_PROMPT,
SERVICE_NAME,
EVENT_CHAT_COMPRESSION,
EVENT_INVALID_CHUNK,
EVENT_CONTENT_RETRY,
EVENT_CONTENT_RETRY_FAILURE,
} from './constants.js';
import {
recordApiErrorMetrics,
recordApiResponseMetrics,
recordChatCompressionMetrics,
recordContentRetry,
recordContentRetryFailure,
recordFileOperationMetric,
recordInvalidChunk,
recordTokenUsageMetrics,
recordToolCallMetrics,
} from './metrics.js';
import { QwenLogger } from './qwen-logger/qwen-logger.js';
import { isTelemetrySdkInitialized } from './sdk.js';
import type {
ApiErrorEvent,
ApiRequestEvent,
ApiResponseEvent,
ChatCompressionEvent,
ContentRetryEvent,
ContentRetryFailureEvent,
ConversationFinishedEvent,
FileOperationEvent,
FlashFallbackEvent,
IdeConnectionEvent,
InvalidChunkEvent,
KittySequenceOverflowEvent,
LoopDetectedEvent,
NextSpeakerCheckEvent,
@@ -37,32 +60,19 @@ import {
StartSessionEvent,
ToolCallEvent,
UserPromptEvent,
ChatCompressionEvent,
InvalidChunkEvent,
ContentRetryEvent,
ContentRetryFailureEvent,
} from './types.js';
import {
recordApiErrorMetrics,
recordTokenUsageMetrics,
recordApiResponseMetrics,
recordToolCallMetrics,
recordChatCompressionMetrics,
recordInvalidChunk,
recordContentRetry,
recordContentRetryFailure,
} from './metrics.js';
import { QwenLogger } from './qwen-logger/qwen-logger.js';
import { isTelemetrySdkInitialized } from './sdk.js';
import { uiTelemetryService, UiEvent } from './uiTelemetry.js';
import { safeJsonStringify } from '../utils/safeJsonStringify.js';
import type { UiEvent } from './uiTelemetry.js';
import { uiTelemetryService } from './uiTelemetry.js';
const shouldLogUserPrompts = (config: Config): boolean =>
config.getTelemetryLogPromptsEnabled();
function getCommonAttributes(config: Config): LogAttributes {
const userAccountManager = new UserAccountManager();
const email = userAccountManager.getCachedGoogleAccount();
return {
'session.id': config.getSessionId(),
...(email && { 'user.email': email }),
};
}
@@ -88,6 +98,9 @@ export function logCliConfiguration(
file_filtering_respect_git_ignore: event.file_filtering_respect_git_ignore,
debug_mode: event.debug_enabled,
mcp_servers: event.mcp_servers,
mcp_servers_count: event.mcp_servers_count,
mcp_tools: event.mcp_tools,
mcp_tools_count: event.mcp_tools_count,
};
const logger = logs.getLogger(SERVICE_NAME);
@@ -107,8 +120,13 @@ export function logUserPrompt(config: Config, event: UserPromptEvent): void {
'event.name': EVENT_USER_PROMPT,
'event.timestamp': new Date().toISOString(),
prompt_length: event.prompt_length,
prompt_id: event.prompt_id,
};
if (event.auth_type) {
attributes['auth_type'] = event.auth_type;
}
if (shouldLogUserPrompts(config)) {
attributes['prompt'] = event.prompt;
}
@@ -161,6 +179,24 @@ export function logToolCall(config: Config, event: ToolCallEvent): void {
);
}
export function logFileOperation(
config: Config,
event: FileOperationEvent,
): void {
QwenLogger.getInstance(config)?.logFileOperationEvent(event);
if (!isTelemetrySdkInitialized()) return;
recordFileOperationMetric(
config,
event.operation,
event.lines,
event.mimetype,
event.extension,
event.diff_stat,
event.programming_language,
);
}
export function logApiRequest(config: Config, event: ApiRequestEvent): void {
// QwenLogger.getInstance(config)?.logApiRequestEvent(event);
if (!isTelemetrySdkInitialized()) return;
@@ -393,6 +429,27 @@ export function logIdeConnection(
logger.emit(logRecord);
}
export function logConversationFinishedEvent(
config: Config,
event: ConversationFinishedEvent,
): void {
QwenLogger.getInstance(config)?.logConversationFinishedEvent(event);
if (!isTelemetrySdkInitialized()) return;
const attributes: LogAttributes = {
...getCommonAttributes(config),
...event,
'event.name': EVENT_CONVERSATION_FINISHED,
};
const logger = logs.getLogger(SERVICE_NAME);
const logRecord: LogRecord = {
body: `Conversation finished.`,
attributes,
};
logger.emit(logRecord);
}
export function logChatCompression(
config: Config,
event: ChatCompressionEvent,