mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-30 23:14:32 -07:00
Respect logPrompts flag for logging sensitive fields (#26153)
Co-authored-by: David Pierce <davidapierce@google.com> Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
||||
import type { Config } from '../config/config.js';
|
||||
import * as sdk from './sdk.js';
|
||||
import { ClearcutLogger } from './clearcut-logger/clearcut-logger.js';
|
||||
import { EventMetadataKey } from './clearcut-logger/event-metadata-key.js';
|
||||
|
||||
vi.mock('@opentelemetry/api-logs');
|
||||
vi.mock('./sdk.js');
|
||||
@@ -144,4 +145,174 @@ describe('conseca-logger', () => {
|
||||
|
||||
expect(mockLogger.emit).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should omit user_prompt/trusted_content/policy from OTEL when logPrompts is disabled', () => {
|
||||
const configNoPrompts = {
|
||||
getTelemetryEnabled: vi.fn().mockReturnValue(true),
|
||||
getSessionId: vi.fn().mockReturnValue('test-session-id'),
|
||||
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
|
||||
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
|
||||
isInteractive: vi.fn().mockReturnValue(true),
|
||||
getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }),
|
||||
getContentGeneratorConfig: vi.fn().mockReturnValue({ authType: 'oauth' }),
|
||||
} as unknown as Config;
|
||||
|
||||
const event = new ConsecaPolicyGenerationEvent(
|
||||
'sensitive prompt',
|
||||
'sensitive content',
|
||||
'sensitive policy',
|
||||
);
|
||||
|
||||
logConsecaPolicyGeneration(configNoPrompts, event);
|
||||
|
||||
const attrs = mockLogger.emit.mock.calls[0][0].attributes as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
expect(attrs['user_prompt']).toBeUndefined();
|
||||
expect(attrs['trusted_content']).toBeUndefined();
|
||||
expect(attrs['policy']).toBeUndefined();
|
||||
expect(attrs['event.name']).toBe(EVENT_CONSECA_POLICY_GENERATION);
|
||||
});
|
||||
|
||||
it('should omit user_prompt/trusted_content/policy from Clearcut when logPrompts is disabled', () => {
|
||||
const configNoPrompts = {
|
||||
getTelemetryEnabled: vi.fn().mockReturnValue(true),
|
||||
getSessionId: vi.fn().mockReturnValue('test-session-id'),
|
||||
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
|
||||
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
|
||||
isInteractive: vi.fn().mockReturnValue(true),
|
||||
getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }),
|
||||
getContentGeneratorConfig: vi.fn().mockReturnValue({ authType: 'oauth' }),
|
||||
} as unknown as Config;
|
||||
|
||||
const event = new ConsecaPolicyGenerationEvent(
|
||||
'sensitive prompt',
|
||||
'sensitive content',
|
||||
'sensitive policy',
|
||||
'some error',
|
||||
);
|
||||
|
||||
logConsecaPolicyGeneration(configNoPrompts, event);
|
||||
|
||||
expect(mockClearcutLogger.createLogEvent).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
[
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_ERROR,
|
||||
value: 'some error',
|
||||
},
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
it('should include user_prompt/trusted_content/policy in OTEL when logPrompts is enabled', () => {
|
||||
const event = new ConsecaPolicyGenerationEvent(
|
||||
'visible prompt',
|
||||
'visible content',
|
||||
'visible policy',
|
||||
);
|
||||
|
||||
logConsecaPolicyGeneration(mockConfig, event);
|
||||
|
||||
const attrs = mockLogger.emit.mock.calls[0][0].attributes as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
expect(attrs['user_prompt']).toBe('visible prompt');
|
||||
expect(attrs['trusted_content']).toBe('visible content');
|
||||
expect(attrs['policy']).toBe('visible policy');
|
||||
});
|
||||
|
||||
it('should omit sensitive fields from verdict OTEL when logPrompts is disabled', () => {
|
||||
const configNoPrompts = {
|
||||
getTelemetryEnabled: vi.fn().mockReturnValue(true),
|
||||
getSessionId: vi.fn().mockReturnValue('test-session-id'),
|
||||
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
|
||||
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
|
||||
isInteractive: vi.fn().mockReturnValue(true),
|
||||
getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }),
|
||||
getContentGeneratorConfig: vi.fn().mockReturnValue({ authType: 'oauth' }),
|
||||
} as unknown as Config;
|
||||
|
||||
const event = new ConsecaVerdictEvent(
|
||||
'sensitive prompt',
|
||||
'sensitive policy',
|
||||
'sensitive tool call',
|
||||
'allow',
|
||||
'sensitive rationale',
|
||||
);
|
||||
|
||||
logConsecaVerdict(configNoPrompts, event);
|
||||
|
||||
const attrs = mockLogger.emit.mock.calls[0][0].attributes as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
expect(attrs['user_prompt']).toBeUndefined();
|
||||
expect(attrs['policy']).toBeUndefined();
|
||||
expect(attrs['tool_call']).toBeUndefined();
|
||||
expect(attrs['verdict_rationale']).toBeUndefined();
|
||||
// verdict (the allow/deny result) is not sensitive and should be present
|
||||
expect(attrs['verdict']).toBe('allow');
|
||||
});
|
||||
|
||||
it('should omit sensitive fields from verdict Clearcut when logPrompts is disabled', () => {
|
||||
const configNoPrompts = {
|
||||
getTelemetryEnabled: vi.fn().mockReturnValue(true),
|
||||
getSessionId: vi.fn().mockReturnValue('test-session-id'),
|
||||
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
|
||||
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
|
||||
isInteractive: vi.fn().mockReturnValue(true),
|
||||
getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }),
|
||||
getContentGeneratorConfig: vi.fn().mockReturnValue({ authType: 'oauth' }),
|
||||
} as unknown as Config;
|
||||
|
||||
const event = new ConsecaVerdictEvent(
|
||||
'sensitive prompt',
|
||||
'sensitive policy',
|
||||
'sensitive tool call',
|
||||
'allow',
|
||||
'sensitive rationale',
|
||||
'some error',
|
||||
);
|
||||
|
||||
logConsecaVerdict(configNoPrompts, event);
|
||||
|
||||
expect(mockClearcutLogger.createLogEvent).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
[
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_VERDICT_RESULT,
|
||||
value: '"allow"',
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_ERROR,
|
||||
value: 'some error',
|
||||
},
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
it('should include sensitive fields in verdict OTEL when logPrompts is enabled', () => {
|
||||
const event = new ConsecaVerdictEvent(
|
||||
'visible prompt',
|
||||
'visible policy',
|
||||
'visible tool call',
|
||||
'deny',
|
||||
'visible rationale',
|
||||
);
|
||||
|
||||
logConsecaVerdict(mockConfig, event);
|
||||
|
||||
const attrs = mockLogger.emit.mock.calls[0][0].attributes as Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
expect(attrs['user_prompt']).toBe('visible prompt');
|
||||
expect(attrs['policy']).toBe('visible policy');
|
||||
expect(attrs['tool_call']).toBe('visible tool call');
|
||||
expect(attrs['verdict_rationale']).toBe('visible rationale');
|
||||
expect(attrs['verdict']).toBe('deny');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,6 +11,7 @@ import { isTelemetrySdkInitialized } from './sdk.js';
|
||||
import {
|
||||
ClearcutLogger,
|
||||
EventNames,
|
||||
type EventValue,
|
||||
} from './clearcut-logger/clearcut-logger.js';
|
||||
import { EventMetadataKey } from './clearcut-logger/event-metadata-key.js';
|
||||
import { safeJsonStringify } from '../utils/safeJsonStringify.js';
|
||||
@@ -27,20 +28,24 @@ export function logConsecaPolicyGeneration(
|
||||
debugLogger.debug('Conseca Policy Generation Event:', event);
|
||||
const clearcutLogger = ClearcutLogger.getInstance(config);
|
||||
if (clearcutLogger) {
|
||||
const data = [
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_USER_PROMPT,
|
||||
value: safeJsonStringify(event.user_prompt),
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_TRUSTED_CONTENT,
|
||||
value: safeJsonStringify(event.trusted_content),
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_GENERATED_POLICY,
|
||||
value: safeJsonStringify(event.policy),
|
||||
},
|
||||
];
|
||||
const data: EventValue[] = [];
|
||||
|
||||
if (config.getTelemetryLogPromptsEnabled()) {
|
||||
data.push(
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_USER_PROMPT,
|
||||
value: safeJsonStringify(event.user_prompt),
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_TRUSTED_CONTENT,
|
||||
value: safeJsonStringify(event.trusted_content),
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_GENERATED_POLICY,
|
||||
value: safeJsonStringify(event.policy),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (event.error) {
|
||||
data.push({
|
||||
@@ -71,29 +76,34 @@ export function logConsecaVerdict(
|
||||
debugLogger.debug('Conseca Verdict Event:', event);
|
||||
const clearcutLogger = ClearcutLogger.getInstance(config);
|
||||
if (clearcutLogger) {
|
||||
const data = [
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_USER_PROMPT,
|
||||
value: safeJsonStringify(event.user_prompt),
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_GENERATED_POLICY,
|
||||
value: safeJsonStringify(event.policy),
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_NAME,
|
||||
value: safeJsonStringify(event.tool_call),
|
||||
},
|
||||
const data: EventValue[] = [
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_VERDICT_RESULT,
|
||||
value: safeJsonStringify(event.verdict),
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_VERDICT_RATIONALE,
|
||||
value: event.verdict_rationale,
|
||||
},
|
||||
];
|
||||
|
||||
if (config.getTelemetryLogPromptsEnabled()) {
|
||||
data.push(
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_USER_PROMPT,
|
||||
value: safeJsonStringify(event.user_prompt),
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_GENERATED_POLICY,
|
||||
value: safeJsonStringify(event.policy),
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_NAME,
|
||||
value: safeJsonStringify(event.tool_call),
|
||||
},
|
||||
{
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_VERDICT_RATIONALE,
|
||||
value: event.verdict_rationale,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (event.error) {
|
||||
data.push({
|
||||
gemini_cli_key: EventMetadataKey.CONSECA_ERROR,
|
||||
|
||||
@@ -642,6 +642,54 @@ describe('loggers', () => {
|
||||
}),
|
||||
});
|
||||
});
|
||||
it('should not include response_text when logPrompts is disabled', () => {
|
||||
const mockConfigNoPrompts = {
|
||||
getSessionId: () => 'test-session-id',
|
||||
getTargetDir: () => 'target-dir',
|
||||
getUsageStatisticsEnabled: () => true,
|
||||
getTelemetryEnabled: () => true,
|
||||
getTelemetryLogPromptsEnabled: () => false,
|
||||
getTelemetryTracesEnabled: () => false,
|
||||
isInteractive: () => false,
|
||||
getExperiments: () => undefined,
|
||||
getExperimentsAsync: async () => undefined,
|
||||
getContentGeneratorConfig: () => undefined,
|
||||
} as unknown as Config;
|
||||
|
||||
const event = new ApiResponseEvent(
|
||||
'test-model',
|
||||
100,
|
||||
{ prompt_id: 'prompt-id-noprompts', contents: [] },
|
||||
{ candidates: [] },
|
||||
AuthType.LOGIN_WITH_GOOGLE,
|
||||
{},
|
||||
'this response should be hidden',
|
||||
);
|
||||
|
||||
logApiResponse(mockConfigNoPrompts, event);
|
||||
|
||||
const firstEmitCall = mockLogger.emit.mock.calls[0][0];
|
||||
expect(firstEmitCall.attributes['response_text']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should include response_text when logPrompts is enabled', () => {
|
||||
const event = new ApiResponseEvent(
|
||||
'test-model',
|
||||
100,
|
||||
{ prompt_id: 'prompt-id-withprompts', contents: [] },
|
||||
{ candidates: [] },
|
||||
AuthType.LOGIN_WITH_GOOGLE,
|
||||
{},
|
||||
'this response should be visible',
|
||||
);
|
||||
|
||||
logApiResponse(mockConfig, event);
|
||||
|
||||
const firstEmitCall = mockLogger.emit.mock.calls[0][0];
|
||||
expect(firstEmitCall.attributes['response_text']).toBe(
|
||||
'this response should be visible',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('logApiError', () => {
|
||||
@@ -1076,6 +1124,10 @@ describe('loggers', () => {
|
||||
expect(attributes['gen_ai.provider.name']).toBe('gcp.vertex_ai');
|
||||
// Ensure prompt messages are NOT included
|
||||
expect(attributes['gen_ai.input.messages']).toBeUndefined();
|
||||
|
||||
// Ensure request_text is also NOT included in the first (toLogRecord) log
|
||||
const firstLogCall = mockLogger.emit.mock.calls[0][0];
|
||||
expect(firstLogCall.attributes['request_text']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should correctly derive model from prompt details if available in semantic log', () => {
|
||||
@@ -1373,16 +1425,20 @@ describe('loggers', () => {
|
||||
error_type: undefined,
|
||||
mcp_server_name: undefined,
|
||||
extension_id: undefined,
|
||||
metadata: {
|
||||
model_added_lines: 1,
|
||||
model_removed_lines: 2,
|
||||
model_added_chars: 3,
|
||||
model_removed_chars: 4,
|
||||
user_added_lines: 5,
|
||||
user_removed_lines: 6,
|
||||
user_added_chars: 7,
|
||||
user_removed_chars: 8,
|
||||
},
|
||||
metadata: JSON.stringify(
|
||||
{
|
||||
model_added_lines: 1,
|
||||
model_removed_lines: 2,
|
||||
model_added_chars: 3,
|
||||
model_removed_chars: 4,
|
||||
user_added_lines: 5,
|
||||
user_removed_lines: 6,
|
||||
user_added_chars: 7,
|
||||
user_removed_chars: 8,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
content_length: 13,
|
||||
},
|
||||
});
|
||||
@@ -1455,12 +1511,16 @@ describe('loggers', () => {
|
||||
body: 'Tool call: ask_user. Decision: accept. Success: true. Duration: 100ms.',
|
||||
attributes: expect.objectContaining({
|
||||
function_name: 'ask_user',
|
||||
metadata: expect.objectContaining({
|
||||
ask_user: {
|
||||
question_types: ['choice'],
|
||||
dismissed: false,
|
||||
metadata: JSON.stringify(
|
||||
{
|
||||
ask_user: {
|
||||
question_types: ['choice'],
|
||||
dismissed: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
null,
|
||||
2,
|
||||
),
|
||||
}),
|
||||
});
|
||||
});
|
||||
@@ -1867,6 +1927,99 @@ describe('loggers', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('logToolCall — logPrompts flag', () => {
|
||||
it('should omit function_args when logPrompts is disabled', () => {
|
||||
const mockConfigNoPrompts = {
|
||||
getSessionId: () => 'test-session-id',
|
||||
getTargetDir: () => 'target-dir',
|
||||
getUsageStatisticsEnabled: () => true,
|
||||
getTelemetryEnabled: () => true,
|
||||
getTelemetryLogPromptsEnabled: () => false,
|
||||
getTelemetryTracesEnabled: () => false,
|
||||
isInteractive: () => false,
|
||||
getExperiments: () => undefined,
|
||||
getExperimentsAsync: async () => undefined,
|
||||
getContentGeneratorConfig: () => undefined,
|
||||
} as unknown as Config;
|
||||
|
||||
const call: CompletedToolCall = {
|
||||
status: CoreToolCallStatus.Success,
|
||||
request: {
|
||||
name: 'run_bash',
|
||||
args: { command: 'echo sensitive' },
|
||||
callId: 'call-1',
|
||||
isClientInitiated: false,
|
||||
prompt_id: 'prompt-noprompts',
|
||||
},
|
||||
response: {
|
||||
callId: 'call-1',
|
||||
responseParts: [],
|
||||
resultDisplay: undefined,
|
||||
error: undefined,
|
||||
errorType: undefined,
|
||||
contentLength: undefined,
|
||||
},
|
||||
tool: undefined as unknown as AnyDeclarativeTool,
|
||||
invocation: {} as AnyToolInvocation,
|
||||
durationMs: 50,
|
||||
};
|
||||
const event = new ToolCallEvent(call);
|
||||
logToolCall(mockConfigNoPrompts, event);
|
||||
|
||||
const emitted = mockLogger.emit.mock.calls[0][0] as {
|
||||
attributes: Record<string, unknown>;
|
||||
};
|
||||
expect(emitted.attributes['function_args']).toBeUndefined();
|
||||
expect(emitted.attributes['function_name']).toBe('run_bash');
|
||||
});
|
||||
|
||||
it('should include function_args when logPrompts is enabled', () => {
|
||||
const mockConfigWithPrompts = {
|
||||
getSessionId: () => 'test-session-id',
|
||||
getTargetDir: () => 'target-dir',
|
||||
getUsageStatisticsEnabled: () => true,
|
||||
getTelemetryEnabled: () => true,
|
||||
getTelemetryLogPromptsEnabled: () => true,
|
||||
getTelemetryTracesEnabled: () => false,
|
||||
isInteractive: () => false,
|
||||
getExperiments: () => undefined,
|
||||
getExperimentsAsync: async () => undefined,
|
||||
getContentGeneratorConfig: () => undefined,
|
||||
} as unknown as Config;
|
||||
|
||||
const call: CompletedToolCall = {
|
||||
status: CoreToolCallStatus.Success,
|
||||
request: {
|
||||
name: 'run_bash',
|
||||
args: { command: 'echo visible' },
|
||||
callId: 'call-2',
|
||||
isClientInitiated: false,
|
||||
prompt_id: 'prompt-withprompts',
|
||||
},
|
||||
response: {
|
||||
callId: 'call-2',
|
||||
responseParts: [],
|
||||
resultDisplay: undefined,
|
||||
error: undefined,
|
||||
errorType: undefined,
|
||||
contentLength: undefined,
|
||||
},
|
||||
tool: undefined as unknown as AnyDeclarativeTool,
|
||||
invocation: {} as AnyToolInvocation,
|
||||
durationMs: 50,
|
||||
};
|
||||
const event = new ToolCallEvent(call);
|
||||
logToolCall(mockConfigWithPrompts, event);
|
||||
|
||||
const emitted = mockLogger.emit.mock.calls[0][0] as {
|
||||
attributes: Record<string, unknown>;
|
||||
};
|
||||
expect(emitted.attributes['function_args']).toBe(
|
||||
JSON.stringify({ command: 'echo visible' }, null, 2),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('logMalformedJsonResponse', () => {
|
||||
beforeEach(() => {
|
||||
vi.spyOn(ClearcutLogger.prototype, 'logMalformedJsonResponseEvent');
|
||||
|
||||
@@ -231,6 +231,17 @@ export class UserPromptEvent implements BaseTelemetryEvent {
|
||||
}
|
||||
|
||||
export const EVENT_TOOL_CALL = 'gemini_cli.tool_call';
|
||||
|
||||
const TOOL_CALL_METADATA_SAFE_KEYS = [
|
||||
'model_added_lines',
|
||||
'model_removed_lines',
|
||||
'model_added_chars',
|
||||
'model_removed_chars',
|
||||
'user_added_lines',
|
||||
'user_removed_lines',
|
||||
'user_added_chars',
|
||||
'user_removed_chars',
|
||||
] as const;
|
||||
export class ToolCallEvent implements BaseTelemetryEvent {
|
||||
'event.name': 'tool_call';
|
||||
'event.timestamp': string;
|
||||
@@ -355,7 +366,6 @@ export class ToolCallEvent implements BaseTelemetryEvent {
|
||||
'event.name': EVENT_TOOL_CALL,
|
||||
'event.timestamp': this['event.timestamp'],
|
||||
function_name: this.function_name,
|
||||
function_args: safeJsonStringify(this.function_args, 2),
|
||||
duration_ms: this.duration_ms,
|
||||
success: this.success,
|
||||
decision: this.decision,
|
||||
@@ -367,8 +377,22 @@ export class ToolCallEvent implements BaseTelemetryEvent {
|
||||
extension_id: this.extension_id,
|
||||
start_time: this.start_time,
|
||||
end_time: this.end_time,
|
||||
metadata: this.metadata,
|
||||
};
|
||||
if (config.getTelemetryLogPromptsEnabled() && this.function_args) {
|
||||
attributes['function_args'] = safeJsonStringify(this.function_args, 2);
|
||||
}
|
||||
if (this.metadata) {
|
||||
const metadata = config.getTelemetryLogPromptsEnabled()
|
||||
? this.metadata
|
||||
: Object.fromEntries(
|
||||
Object.entries(this.metadata).filter(([k]) =>
|
||||
(TOOL_CALL_METADATA_SAFE_KEYS as readonly string[]).includes(k),
|
||||
),
|
||||
);
|
||||
if (Object.keys(metadata).length > 0) {
|
||||
attributes['metadata'] = safeJsonStringify(metadata, 2);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.error) {
|
||||
attributes[CoreToolCallStatus.Error] = this.error;
|
||||
@@ -423,8 +447,10 @@ export class ApiRequestEvent implements BaseTelemetryEvent {
|
||||
'event.timestamp': this['event.timestamp'],
|
||||
model: this.model,
|
||||
prompt_id: this.prompt.prompt_id,
|
||||
request_text: this.request_text,
|
||||
};
|
||||
if (config.getTelemetryLogPromptsEnabled() && this.request_text) {
|
||||
attributes['request_text'] = this.request_text;
|
||||
}
|
||||
if (this.role) {
|
||||
attributes['role'] = this.role;
|
||||
}
|
||||
@@ -692,7 +718,7 @@ export class ApiResponseEvent implements BaseTelemetryEvent {
|
||||
if (this.role) {
|
||||
attributes['role'] = this.role;
|
||||
}
|
||||
if (this.response_text) {
|
||||
if (config.getTelemetryLogPromptsEnabled() && this.response_text) {
|
||||
attributes['response_text'] = this.response_text;
|
||||
}
|
||||
if (this.status_code) {
|
||||
@@ -954,11 +980,20 @@ export class ConsecaPolicyGenerationEvent implements BaseTelemetryEvent {
|
||||
...getCommonAttributes(config),
|
||||
'event.name': EVENT_CONSECA_POLICY_GENERATION,
|
||||
'event.timestamp': this['event.timestamp'],
|
||||
user_prompt: this.user_prompt,
|
||||
trusted_content: this.trusted_content,
|
||||
policy: this.policy,
|
||||
};
|
||||
|
||||
if (config.getTelemetryLogPromptsEnabled()) {
|
||||
if (this.user_prompt) {
|
||||
attributes['user_prompt'] = this.user_prompt;
|
||||
}
|
||||
if (this.trusted_content) {
|
||||
attributes['trusted_content'] = this.trusted_content;
|
||||
}
|
||||
if (this.policy) {
|
||||
attributes['policy'] = this.policy;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.error) {
|
||||
attributes['error'] = this.error;
|
||||
}
|
||||
@@ -1005,13 +1040,24 @@ export class ConsecaVerdictEvent implements BaseTelemetryEvent {
|
||||
...getCommonAttributes(config),
|
||||
'event.name': EVENT_CONSECA_VERDICT,
|
||||
'event.timestamp': this['event.timestamp'],
|
||||
user_prompt: this.user_prompt,
|
||||
policy: this.policy,
|
||||
tool_call: this.tool_call,
|
||||
verdict: this.verdict,
|
||||
verdict_rationale: this.verdict_rationale,
|
||||
};
|
||||
|
||||
if (config.getTelemetryLogPromptsEnabled()) {
|
||||
if (this.user_prompt) {
|
||||
attributes['user_prompt'] = this.user_prompt;
|
||||
}
|
||||
if (this.policy) {
|
||||
attributes['policy'] = this.policy;
|
||||
}
|
||||
if (this.tool_call) {
|
||||
attributes['tool_call'] = this.tool_call;
|
||||
}
|
||||
if (this.verdict_rationale) {
|
||||
attributes['verdict_rationale'] = this.verdict_rationale;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.error) {
|
||||
attributes['error'] = this.error;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user