mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-12 12:54:07 -07:00
feat: instrument adaptive thinking metrics in telemetry and chat logs
This commit is contained in:
@@ -658,6 +658,11 @@ export class GeminiClient {
|
|||||||
if (adaptiveConfig) {
|
if (adaptiveConfig) {
|
||||||
modelConfigKey.thinkingBudget = adaptiveConfig.thinkingBudget;
|
modelConfigKey.thinkingBudget = adaptiveConfig.thinkingBudget;
|
||||||
modelConfigKey.thinkingLevel = adaptiveConfig.thinkingLevel;
|
modelConfigKey.thinkingLevel = adaptiveConfig.thinkingLevel;
|
||||||
|
this.getChat().recordAdaptiveThinking({
|
||||||
|
complexity: adaptiveConfig.complexity,
|
||||||
|
thinkingBudget: adaptiveConfig.thinkingBudget,
|
||||||
|
thinkingLevel: adaptiveConfig.thinkingLevel,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -260,6 +260,14 @@ export class GeminiChat {
|
|||||||
this.systemInstruction = sysInstr;
|
this.systemInstruction = sysInstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recordAdaptiveThinking(info: {
|
||||||
|
complexity: number;
|
||||||
|
thinkingBudget?: number;
|
||||||
|
thinkingLevel?: string;
|
||||||
|
}) {
|
||||||
|
this.chatRecordingService.recordAdaptiveThinking(info);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a message to the model and returns the response in chunks.
|
* Sends a message to the model and returns the response in chunks.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -83,6 +83,11 @@ export type ConversationRecordExtra =
|
|||||||
thoughts?: Array<ThoughtSummary & { timestamp: string }>;
|
thoughts?: Array<ThoughtSummary & { timestamp: string }>;
|
||||||
tokens?: TokensSummary | null;
|
tokens?: TokensSummary | null;
|
||||||
model?: string;
|
model?: string;
|
||||||
|
adaptiveThinking?: {
|
||||||
|
complexity: number;
|
||||||
|
thinkingBudget?: number;
|
||||||
|
thinkingLevel?: string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,6 +135,11 @@ export class ChatRecordingService {
|
|||||||
private projectHash: string;
|
private projectHash: string;
|
||||||
private queuedThoughts: Array<ThoughtSummary & { timestamp: string }> = [];
|
private queuedThoughts: Array<ThoughtSummary & { timestamp: string }> = [];
|
||||||
private queuedTokens: TokensSummary | null = null;
|
private queuedTokens: TokensSummary | null = null;
|
||||||
|
private queuedAdaptiveThinking?: {
|
||||||
|
complexity: number;
|
||||||
|
thinkingBudget?: number;
|
||||||
|
thinkingLevel?: string;
|
||||||
|
};
|
||||||
private config: Config;
|
private config: Config;
|
||||||
|
|
||||||
constructor(config: Config) {
|
constructor(config: Config) {
|
||||||
@@ -186,6 +196,7 @@ export class ChatRecordingService {
|
|||||||
// Clear any queued data since this is a fresh start
|
// Clear any queued data since this is a fresh start
|
||||||
this.queuedThoughts = [];
|
this.queuedThoughts = [];
|
||||||
this.queuedTokens = null;
|
this.queuedTokens = null;
|
||||||
|
this.queuedAdaptiveThinking = undefined;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Handle disk full (ENOSPC) gracefully - disable recording but allow CLI to continue
|
// Handle disk full (ENOSPC) gracefully - disable recording but allow CLI to continue
|
||||||
if (
|
if (
|
||||||
@@ -230,6 +241,11 @@ export class ChatRecordingService {
|
|||||||
type: ConversationRecordExtra['type'];
|
type: ConversationRecordExtra['type'];
|
||||||
content: PartListUnion;
|
content: PartListUnion;
|
||||||
displayContent?: PartListUnion;
|
displayContent?: PartListUnion;
|
||||||
|
adaptiveThinking?: {
|
||||||
|
complexity: number;
|
||||||
|
thinkingBudget?: number;
|
||||||
|
thinkingLevel?: string;
|
||||||
|
};
|
||||||
}): void {
|
}): void {
|
||||||
if (!this.conversationFile) return;
|
if (!this.conversationFile) return;
|
||||||
|
|
||||||
@@ -247,9 +263,12 @@ export class ChatRecordingService {
|
|||||||
thoughts: this.queuedThoughts,
|
thoughts: this.queuedThoughts,
|
||||||
tokens: this.queuedTokens,
|
tokens: this.queuedTokens,
|
||||||
model: message.model,
|
model: message.model,
|
||||||
|
adaptiveThinking:
|
||||||
|
message.adaptiveThinking || this.queuedAdaptiveThinking,
|
||||||
});
|
});
|
||||||
this.queuedThoughts = [];
|
this.queuedThoughts = [];
|
||||||
this.queuedTokens = null;
|
this.queuedTokens = null;
|
||||||
|
this.queuedAdaptiveThinking = undefined;
|
||||||
} else {
|
} else {
|
||||||
// Or else just add it.
|
// Or else just add it.
|
||||||
conversation.messages.push(msg);
|
conversation.messages.push(msg);
|
||||||
@@ -261,6 +280,18 @@ export class ChatRecordingService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queues adaptive thinking info to be recorded with the next Gemini message.
|
||||||
|
*/
|
||||||
|
recordAdaptiveThinking(info: {
|
||||||
|
complexity: number;
|
||||||
|
thinkingBudget?: number;
|
||||||
|
thinkingLevel?: string;
|
||||||
|
}): void {
|
||||||
|
if (!this.conversationFile) return;
|
||||||
|
this.queuedAdaptiveThinking = info;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Records a thought from the assistant's reasoning process.
|
* Records a thought from the assistant's reasoning process.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -553,7 +553,7 @@ function toGenerateContentConfigAttributes(
|
|||||||
if (!config) {
|
if (!config) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return {
|
const attributes: LogAttributes = {
|
||||||
'gen_ai.request.temperature': config.temperature,
|
'gen_ai.request.temperature': config.temperature,
|
||||||
'gen_ai.request.top_p': config.topP,
|
'gen_ai.request.top_p': config.topP,
|
||||||
'gen_ai.request.top_k': config.topK,
|
'gen_ai.request.top_k': config.topK,
|
||||||
@@ -568,6 +568,20 @@ function toGenerateContentConfigAttributes(
|
|||||||
toSystemInstruction(config.systemInstruction),
|
toSystemInstruction(config.systemInstruction),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (config.thinkingConfig) {
|
||||||
|
const thinkingConfig = config.thinkingConfig;
|
||||||
|
if (thinkingConfig.thinkingBudget !== undefined) {
|
||||||
|
attributes['gen_ai.request.thinking_budget'] =
|
||||||
|
thinkingConfig.thinkingBudget;
|
||||||
|
}
|
||||||
|
if (thinkingConfig.thinkingLevel !== undefined) {
|
||||||
|
attributes['gen_ai.request.thinking_level'] =
|
||||||
|
thinkingConfig.thinkingLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ApiResponseEvent implements BaseTelemetryEvent {
|
export class ApiResponseEvent implements BaseTelemetryEvent {
|
||||||
@@ -632,6 +646,17 @@ export class ApiResponseEvent implements BaseTelemetryEvent {
|
|||||||
status_code: this.status_code,
|
status_code: this.status_code,
|
||||||
finish_reasons: this.finish_reasons,
|
finish_reasons: this.finish_reasons,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (this.prompt.generate_content_config?.thinkingConfig) {
|
||||||
|
const thinkingConfig = this.prompt.generate_content_config.thinkingConfig;
|
||||||
|
if (thinkingConfig.thinkingBudget !== undefined) {
|
||||||
|
attributes['thinking_budget'] = thinkingConfig.thinkingBudget;
|
||||||
|
}
|
||||||
|
if (thinkingConfig.thinkingLevel !== undefined) {
|
||||||
|
attributes['thinking_level'] = thinkingConfig.thinkingLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.response_text) {
|
if (this.response_text) {
|
||||||
attributes['response_text'] = this.response_text;
|
attributes['response_text'] = this.response_text;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user