Skip to content

Commit 7d233dd

Browse files
gemini-cli-robotlp-pegDavidAPiercegalz10
authored
fix(patch): cherry-pick 2194da2 to release/v0.41.0-preview.0-pr-26153 to patch version v0.41.0-preview.0 and create version 0.41.0-preview.1 (#26269)
Co-authored-by: lp-peg <35035802+lp-peg@users.noreply.github.com> Co-authored-by: David Pierce <davidapierce@google.com> Co-authored-by: Gal Zahavi <38544478+galz10@users.noreply.github.com>
1 parent a5befa0 commit 7d233dd

4 files changed

Lines changed: 437 additions & 57 deletions

File tree

packages/core/src/telemetry/conseca-logger.test.ts

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
import type { Config } from '../config/config.js';
2020
import * as sdk from './sdk.js';
2121
import { ClearcutLogger } from './clearcut-logger/clearcut-logger.js';
22+
import { EventMetadataKey } from './clearcut-logger/event-metadata-key.js';
2223

2324
vi.mock('@opentelemetry/api-logs');
2425
vi.mock('./sdk.js');
@@ -144,4 +145,174 @@ describe('conseca-logger', () => {
144145

145146
expect(mockLogger.emit).not.toHaveBeenCalled();
146147
});
148+
149+
it('should omit user_prompt/trusted_content/policy from OTEL when logPrompts is disabled', () => {
150+
const configNoPrompts = {
151+
getTelemetryEnabled: vi.fn().mockReturnValue(true),
152+
getSessionId: vi.fn().mockReturnValue('test-session-id'),
153+
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
154+
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
155+
isInteractive: vi.fn().mockReturnValue(true),
156+
getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }),
157+
getContentGeneratorConfig: vi.fn().mockReturnValue({ authType: 'oauth' }),
158+
} as unknown as Config;
159+
160+
const event = new ConsecaPolicyGenerationEvent(
161+
'sensitive prompt',
162+
'sensitive content',
163+
'sensitive policy',
164+
);
165+
166+
logConsecaPolicyGeneration(configNoPrompts, event);
167+
168+
const attrs = mockLogger.emit.mock.calls[0][0].attributes as Record<
169+
string,
170+
unknown
171+
>;
172+
expect(attrs['user_prompt']).toBeUndefined();
173+
expect(attrs['trusted_content']).toBeUndefined();
174+
expect(attrs['policy']).toBeUndefined();
175+
expect(attrs['event.name']).toBe(EVENT_CONSECA_POLICY_GENERATION);
176+
});
177+
178+
it('should omit user_prompt/trusted_content/policy from Clearcut when logPrompts is disabled', () => {
179+
const configNoPrompts = {
180+
getTelemetryEnabled: vi.fn().mockReturnValue(true),
181+
getSessionId: vi.fn().mockReturnValue('test-session-id'),
182+
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
183+
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
184+
isInteractive: vi.fn().mockReturnValue(true),
185+
getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }),
186+
getContentGeneratorConfig: vi.fn().mockReturnValue({ authType: 'oauth' }),
187+
} as unknown as Config;
188+
189+
const event = new ConsecaPolicyGenerationEvent(
190+
'sensitive prompt',
191+
'sensitive content',
192+
'sensitive policy',
193+
'some error',
194+
);
195+
196+
logConsecaPolicyGeneration(configNoPrompts, event);
197+
198+
expect(mockClearcutLogger.createLogEvent).toHaveBeenCalledWith(
199+
expect.anything(),
200+
[
201+
{
202+
gemini_cli_key: EventMetadataKey.CONSECA_ERROR,
203+
value: 'some error',
204+
},
205+
],
206+
);
207+
});
208+
209+
it('should include user_prompt/trusted_content/policy in OTEL when logPrompts is enabled', () => {
210+
const event = new ConsecaPolicyGenerationEvent(
211+
'visible prompt',
212+
'visible content',
213+
'visible policy',
214+
);
215+
216+
logConsecaPolicyGeneration(mockConfig, event);
217+
218+
const attrs = mockLogger.emit.mock.calls[0][0].attributes as Record<
219+
string,
220+
unknown
221+
>;
222+
expect(attrs['user_prompt']).toBe('visible prompt');
223+
expect(attrs['trusted_content']).toBe('visible content');
224+
expect(attrs['policy']).toBe('visible policy');
225+
});
226+
227+
it('should omit sensitive fields from verdict OTEL when logPrompts is disabled', () => {
228+
const configNoPrompts = {
229+
getTelemetryEnabled: vi.fn().mockReturnValue(true),
230+
getSessionId: vi.fn().mockReturnValue('test-session-id'),
231+
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
232+
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
233+
isInteractive: vi.fn().mockReturnValue(true),
234+
getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }),
235+
getContentGeneratorConfig: vi.fn().mockReturnValue({ authType: 'oauth' }),
236+
} as unknown as Config;
237+
238+
const event = new ConsecaVerdictEvent(
239+
'sensitive prompt',
240+
'sensitive policy',
241+
'sensitive tool call',
242+
'allow',
243+
'sensitive rationale',
244+
);
245+
246+
logConsecaVerdict(configNoPrompts, event);
247+
248+
const attrs = mockLogger.emit.mock.calls[0][0].attributes as Record<
249+
string,
250+
unknown
251+
>;
252+
expect(attrs['user_prompt']).toBeUndefined();
253+
expect(attrs['policy']).toBeUndefined();
254+
expect(attrs['tool_call']).toBeUndefined();
255+
expect(attrs['verdict_rationale']).toBeUndefined();
256+
// verdict (the allow/deny result) is not sensitive and should be present
257+
expect(attrs['verdict']).toBe('allow');
258+
});
259+
260+
it('should omit sensitive fields from verdict Clearcut when logPrompts is disabled', () => {
261+
const configNoPrompts = {
262+
getTelemetryEnabled: vi.fn().mockReturnValue(true),
263+
getSessionId: vi.fn().mockReturnValue('test-session-id'),
264+
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
265+
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
266+
isInteractive: vi.fn().mockReturnValue(true),
267+
getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }),
268+
getContentGeneratorConfig: vi.fn().mockReturnValue({ authType: 'oauth' }),
269+
} as unknown as Config;
270+
271+
const event = new ConsecaVerdictEvent(
272+
'sensitive prompt',
273+
'sensitive policy',
274+
'sensitive tool call',
275+
'allow',
276+
'sensitive rationale',
277+
'some error',
278+
);
279+
280+
logConsecaVerdict(configNoPrompts, event);
281+
282+
expect(mockClearcutLogger.createLogEvent).toHaveBeenCalledWith(
283+
expect.anything(),
284+
[
285+
{
286+
gemini_cli_key: EventMetadataKey.CONSECA_VERDICT_RESULT,
287+
value: '"allow"',
288+
},
289+
{
290+
gemini_cli_key: EventMetadataKey.CONSECA_ERROR,
291+
value: 'some error',
292+
},
293+
],
294+
);
295+
});
296+
297+
it('should include sensitive fields in verdict OTEL when logPrompts is enabled', () => {
298+
const event = new ConsecaVerdictEvent(
299+
'visible prompt',
300+
'visible policy',
301+
'visible tool call',
302+
'deny',
303+
'visible rationale',
304+
);
305+
306+
logConsecaVerdict(mockConfig, event);
307+
308+
const attrs = mockLogger.emit.mock.calls[0][0].attributes as Record<
309+
string,
310+
unknown
311+
>;
312+
expect(attrs['user_prompt']).toBe('visible prompt');
313+
expect(attrs['policy']).toBe('visible policy');
314+
expect(attrs['tool_call']).toBe('visible tool call');
315+
expect(attrs['verdict_rationale']).toBe('visible rationale');
316+
expect(attrs['verdict']).toBe('deny');
317+
});
147318
});

packages/core/src/telemetry/conseca-logger.ts

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { isTelemetrySdkInitialized } from './sdk.js';
1111
import {
1212
ClearcutLogger,
1313
EventNames,
14+
type EventValue,
1415
} from './clearcut-logger/clearcut-logger.js';
1516
import { EventMetadataKey } from './clearcut-logger/event-metadata-key.js';
1617
import { safeJsonStringify } from '../utils/safeJsonStringify.js';
@@ -27,20 +28,24 @@ export function logConsecaPolicyGeneration(
2728
debugLogger.debug('Conseca Policy Generation Event:', event);
2829
const clearcutLogger = ClearcutLogger.getInstance(config);
2930
if (clearcutLogger) {
30-
const data = [
31-
{
32-
gemini_cli_key: EventMetadataKey.CONSECA_USER_PROMPT,
33-
value: safeJsonStringify(event.user_prompt),
34-
},
35-
{
36-
gemini_cli_key: EventMetadataKey.CONSECA_TRUSTED_CONTENT,
37-
value: safeJsonStringify(event.trusted_content),
38-
},
39-
{
40-
gemini_cli_key: EventMetadataKey.CONSECA_GENERATED_POLICY,
41-
value: safeJsonStringify(event.policy),
42-
},
43-
];
31+
const data: EventValue[] = [];
32+
33+
if (config.getTelemetryLogPromptsEnabled()) {
34+
data.push(
35+
{
36+
gemini_cli_key: EventMetadataKey.CONSECA_USER_PROMPT,
37+
value: safeJsonStringify(event.user_prompt),
38+
},
39+
{
40+
gemini_cli_key: EventMetadataKey.CONSECA_TRUSTED_CONTENT,
41+
value: safeJsonStringify(event.trusted_content),
42+
},
43+
{
44+
gemini_cli_key: EventMetadataKey.CONSECA_GENERATED_POLICY,
45+
value: safeJsonStringify(event.policy),
46+
},
47+
);
48+
}
4449

4550
if (event.error) {
4651
data.push({
@@ -71,29 +76,34 @@ export function logConsecaVerdict(
7176
debugLogger.debug('Conseca Verdict Event:', event);
7277
const clearcutLogger = ClearcutLogger.getInstance(config);
7378
if (clearcutLogger) {
74-
const data = [
75-
{
76-
gemini_cli_key: EventMetadataKey.CONSECA_USER_PROMPT,
77-
value: safeJsonStringify(event.user_prompt),
78-
},
79-
{
80-
gemini_cli_key: EventMetadataKey.CONSECA_GENERATED_POLICY,
81-
value: safeJsonStringify(event.policy),
82-
},
83-
{
84-
gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_NAME,
85-
value: safeJsonStringify(event.tool_call),
86-
},
79+
const data: EventValue[] = [
8780
{
8881
gemini_cli_key: EventMetadataKey.CONSECA_VERDICT_RESULT,
8982
value: safeJsonStringify(event.verdict),
9083
},
91-
{
92-
gemini_cli_key: EventMetadataKey.CONSECA_VERDICT_RATIONALE,
93-
value: event.verdict_rationale,
94-
},
9584
];
9685

86+
if (config.getTelemetryLogPromptsEnabled()) {
87+
data.push(
88+
{
89+
gemini_cli_key: EventMetadataKey.CONSECA_USER_PROMPT,
90+
value: safeJsonStringify(event.user_prompt),
91+
},
92+
{
93+
gemini_cli_key: EventMetadataKey.CONSECA_GENERATED_POLICY,
94+
value: safeJsonStringify(event.policy),
95+
},
96+
{
97+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_TOOL_CALL_NAME,
98+
value: safeJsonStringify(event.tool_call),
99+
},
100+
{
101+
gemini_cli_key: EventMetadataKey.CONSECA_VERDICT_RATIONALE,
102+
value: event.verdict_rationale,
103+
},
104+
);
105+
}
106+
97107
if (event.error) {
98108
data.push({
99109
gemini_cli_key: EventMetadataKey.CONSECA_ERROR,

0 commit comments

Comments
 (0)