mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-23 00:01:24 -07:00
feat(context): implement observation masking for tool outputs (#18389)
This commit is contained in:
@@ -46,6 +46,7 @@ import type {
|
||||
ApprovalModeSwitchEvent,
|
||||
ApprovalModeDurationEvent,
|
||||
PlanExecutionEvent,
|
||||
ToolOutputMaskingEvent,
|
||||
} from '../types.js';
|
||||
import { EventMetadataKey } from './event-metadata-key.js';
|
||||
import type { Config } from '../../config/config.js';
|
||||
@@ -108,6 +109,7 @@ export enum EventNames {
|
||||
APPROVAL_MODE_SWITCH = 'approval_mode_switch',
|
||||
APPROVAL_MODE_DURATION = 'approval_mode_duration',
|
||||
PLAN_EXECUTION = 'plan_execution',
|
||||
TOOL_OUTPUT_MASKING = 'tool_output_masking',
|
||||
}
|
||||
|
||||
export interface LogResponse {
|
||||
@@ -1217,8 +1219,40 @@ export class ClearcutLogger {
|
||||
},
|
||||
];
|
||||
|
||||
const logEvent = this.createLogEvent(
|
||||
EventNames.TOOL_OUTPUT_TRUNCATED,
|
||||
data,
|
||||
);
|
||||
this.enqueueLogEvent(logEvent);
|
||||
this.flushIfNeeded();
|
||||
}
|
||||
|
||||
logToolOutputMaskingEvent(event: ToolOutputMaskingEvent): void {
|
||||
const data: EventValue[] = [
|
||||
{
|
||||
gemini_cli_key:
|
||||
EventMetadataKey.GEMINI_CLI_TOOL_OUTPUT_MASKING_TOKENS_BEFORE,
|
||||
value: event.tokens_before.toString(),
|
||||
},
|
||||
{
|
||||
gemini_cli_key:
|
||||
EventMetadataKey.GEMINI_CLI_TOOL_OUTPUT_MASKING_TOKENS_AFTER,
|
||||
value: event.tokens_after.toString(),
|
||||
},
|
||||
{
|
||||
gemini_cli_key:
|
||||
EventMetadataKey.GEMINI_CLI_TOOL_OUTPUT_MASKING_MASKED_COUNT,
|
||||
value: event.masked_count.toString(),
|
||||
},
|
||||
{
|
||||
gemini_cli_key:
|
||||
EventMetadataKey.GEMINI_CLI_TOOL_OUTPUT_MASKING_TOTAL_PRUNABLE_TOKENS,
|
||||
value: event.total_prunable_tokens.toString(),
|
||||
},
|
||||
];
|
||||
|
||||
this.enqueueLogEvent(
|
||||
this.createLogEvent(EventNames.TOOL_OUTPUT_TRUNCATED, data),
|
||||
this.createLogEvent(EventNames.TOOL_OUTPUT_MASKING, data),
|
||||
);
|
||||
this.flushIfNeeded();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// Defines valid event metadata keys for Clearcut logging.
|
||||
export enum EventMetadataKey {
|
||||
// Deleted enums: 24
|
||||
// Next ID: 148
|
||||
// Next ID: 152
|
||||
|
||||
GEMINI_CLI_KEY_UNKNOWN = 0,
|
||||
|
||||
@@ -561,4 +561,20 @@ export enum EventMetadataKey {
|
||||
|
||||
// Logs the classifier threshold used.
|
||||
GEMINI_CLI_ROUTING_CLASSIFIER_THRESHOLD = 147,
|
||||
|
||||
// ==========================================================================
|
||||
// Tool Output Masking Event Keys
|
||||
// ==========================================================================
|
||||
|
||||
// Logs the total tokens in the prunable block before masking.
|
||||
GEMINI_CLI_TOOL_OUTPUT_MASKING_TOKENS_BEFORE = 148,
|
||||
|
||||
// Logs the total tokens in the masked remnants after masking.
|
||||
GEMINI_CLI_TOOL_OUTPUT_MASKING_TOKENS_AFTER = 149,
|
||||
|
||||
// Logs the number of tool outputs masked in this operation.
|
||||
GEMINI_CLI_TOOL_OUTPUT_MASKING_MASKED_COUNT = 150,
|
||||
|
||||
// Logs the total prunable tokens identified at the trigger point.
|
||||
GEMINI_CLI_TOOL_OUTPUT_MASKING_TOTAL_PRUNABLE_TOKENS = 151,
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ import type {
|
||||
StartupStatsEvent,
|
||||
LlmLoopCheckEvent,
|
||||
PlanExecutionEvent,
|
||||
ToolOutputMaskingEvent,
|
||||
} from './types.js';
|
||||
import {
|
||||
recordApiErrorMetrics,
|
||||
@@ -163,6 +164,21 @@ export function logToolOutputTruncated(
|
||||
});
|
||||
}
|
||||
|
||||
export function logToolOutputMasking(
|
||||
config: Config,
|
||||
event: ToolOutputMaskingEvent,
|
||||
): void {
|
||||
ClearcutLogger.getInstance(config)?.logToolOutputMaskingEvent(event);
|
||||
bufferTelemetryEvent(() => {
|
||||
const logger = logs.getLogger(SERVICE_NAME);
|
||||
const logRecord: LogRecord = {
|
||||
body: event.toLogBody(),
|
||||
attributes: event.toOpenTelemetryAttributes(config),
|
||||
};
|
||||
logger.emit(logRecord);
|
||||
});
|
||||
}
|
||||
|
||||
export function logFileOperation(
|
||||
config: Config,
|
||||
event: FileOperationEvent,
|
||||
|
||||
@@ -1376,6 +1376,49 @@ export class ToolOutputTruncatedEvent implements BaseTelemetryEvent {
|
||||
}
|
||||
}
|
||||
|
||||
export const EVENT_TOOL_OUTPUT_MASKING = 'gemini_cli.tool_output_masking';
|
||||
|
||||
export class ToolOutputMaskingEvent implements BaseTelemetryEvent {
|
||||
'event.name': 'tool_output_masking';
|
||||
'event.timestamp': string;
|
||||
tokens_before: number;
|
||||
tokens_after: number;
|
||||
masked_count: number;
|
||||
total_prunable_tokens: number;
|
||||
|
||||
constructor(details: {
|
||||
tokens_before: number;
|
||||
tokens_after: number;
|
||||
masked_count: number;
|
||||
total_prunable_tokens: number;
|
||||
}) {
|
||||
this['event.name'] = 'tool_output_masking';
|
||||
this['event.timestamp'] = new Date().toISOString();
|
||||
this.tokens_before = details.tokens_before;
|
||||
this.tokens_after = details.tokens_after;
|
||||
this.masked_count = details.masked_count;
|
||||
this.total_prunable_tokens = details.total_prunable_tokens;
|
||||
}
|
||||
|
||||
toOpenTelemetryAttributes(config: Config): LogAttributes {
|
||||
return {
|
||||
...getCommonAttributes(config),
|
||||
'event.name': EVENT_TOOL_OUTPUT_MASKING,
|
||||
'event.timestamp': this['event.timestamp'],
|
||||
tokens_before: this.tokens_before,
|
||||
tokens_after: this.tokens_after,
|
||||
masked_count: this.masked_count,
|
||||
total_prunable_tokens: this.total_prunable_tokens,
|
||||
};
|
||||
}
|
||||
|
||||
toLogBody(): string {
|
||||
return `Tool output masking (Masked ${this.masked_count} tool outputs. Saved ${
|
||||
this.tokens_before - this.tokens_after
|
||||
} tokens)`;
|
||||
}
|
||||
}
|
||||
|
||||
export const EVENT_EXTENSION_UNINSTALL = 'gemini_cli.extension_uninstall';
|
||||
export class ExtensionUninstallEvent implements BaseTelemetryEvent {
|
||||
'event.name': 'extension_uninstall';
|
||||
@@ -1602,6 +1645,7 @@ export type TelemetryEvent =
|
||||
| LlmLoopCheckEvent
|
||||
| StartupStatsEvent
|
||||
| WebFetchFallbackAttemptEvent
|
||||
| ToolOutputMaskingEvent
|
||||
| EditStrategyEvent
|
||||
| PlanExecutionEvent
|
||||
| RewindEvent
|
||||
|
||||
Reference in New Issue
Block a user