Skip to content

Commit d9e7b94

Browse files
Samiya CaurDevtools-frontend LUCI CQ
authored andcommitted
Update code to handle BLOCK attribution action
- Also updated citation warning to only show when there is a citation Bug: 433966130, 433510479, 433884684 Change-Id: Iba8596461dc75512e265d87d8be249a22df9edce Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6798165 Reviewed-by: Ergün Erdoğmuş <[email protected]> Commit-Queue: Samiya Caur <[email protected]>
1 parent 266060b commit d9e7b94

File tree

4 files changed

+88
-20
lines changed

4 files changed

+88
-20
lines changed

front_end/models/ai_code_completion/AiCodeCompletion.test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,67 @@ describeWithEnvironment('AiCodeCompletion', () => {
100100
sinon.assert.calledOnce(mockAidaClient.completeCode);
101101
assert.strictEqual(mockAidaClient.completeCode.firstCall.args[0].prefix, 'pre');
102102
});
103+
104+
it('does not dispatch suggestion or citation if recitation action is BLOCK', async () => {
105+
const editor = sinon.createStubInstance(TextEditor.TextEditor.TextEditor);
106+
const mockAidaClient = sinon.createStubInstance(Host.AidaClient.AidaClient, {
107+
completeCode: Promise.resolve({
108+
generatedSamples: [{
109+
generationString: 'suggestion',
110+
sampleId: 1,
111+
score: 1,
112+
attributionMetadata: {
113+
attributionAction: Host.AidaClient.RecitationAction.BLOCK,
114+
citations: [{uri: 'https://www.example.com'}],
115+
}
116+
}],
117+
metadata: {},
118+
}),
119+
});
120+
const aiCodeCompletion = new AiCodeCompletion.AiCodeCompletion(
121+
{aidaClient: mockAidaClient},
122+
editor,
123+
);
124+
const dispatchSpy = sinon.spy(aiCodeCompletion, 'dispatchEventToListeners');
125+
126+
aiCodeCompletion.onTextChanged('prefix', '\n', 1);
127+
128+
await clock.tickAsync(AiCodeCompletion.AIDA_REQUEST_DEBOUNCE_TIMEOUT_MS + 1);
129+
sinon.assert.calledOnce(mockAidaClient.completeCode);
130+
await clock.tickAsync(AiCodeCompletion.DELAY_BEFORE_SHOWING_RESPONSE_MS + 1);
131+
sinon.assert.notCalled(editor.dispatch);
132+
sinon.assert.calledWith(dispatchSpy, sinon.match(AiCodeCompletion.Events.RESPONSE_RECEIVED), sinon.match({}));
133+
});
134+
135+
it('dispatches response received event with citations', async () => {
136+
const editor = sinon.createStubInstance(TextEditor.TextEditor.TextEditor);
137+
const citations = [{uri: 'https://example.com'}];
138+
const mockAidaClient = sinon.createStubInstance(Host.AidaClient.AidaClient, {
139+
completeCode: Promise.resolve({
140+
generatedSamples: [{
141+
generationString: 'suggestion',
142+
sampleId: 1,
143+
score: 1,
144+
attributionMetadata: {
145+
attributionAction: Host.AidaClient.RecitationAction.CITE,
146+
citations,
147+
},
148+
}],
149+
metadata: {},
150+
}),
151+
});
152+
const aiCodeCompletion = new AiCodeCompletion.AiCodeCompletion(
153+
{aidaClient: mockAidaClient},
154+
editor,
155+
);
156+
const dispatchSpy = sinon.spy(aiCodeCompletion, 'dispatchEventToListeners');
157+
158+
aiCodeCompletion.onTextChanged('prefix', '\n', 1);
159+
160+
await clock.tickAsync(AiCodeCompletion.AIDA_REQUEST_DEBOUNCE_TIMEOUT_MS + 1);
161+
await clock.tickAsync(AiCodeCompletion.DELAY_BEFORE_SHOWING_RESPONSE_MS + 1);
162+
163+
sinon.assert.calledWith(
164+
dispatchSpy, sinon.match(AiCodeCompletion.Events.RESPONSE_RECEIVED), sinon.match({citations}));
165+
});
103166
});

front_end/models/ai_code_completion/AiCodeCompletion.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ export class AiCodeCompletion extends Common.ObjectWrapper.ObjectWrapper<EventTy
7474
try {
7575
const response = await this.#aidaClient.completeCode(request);
7676
if (response && response.generatedSamples.length > 0 && response.generatedSamples[0].generationString) {
77+
if (response.generatedSamples[0].attributionMetadata?.attributionAction ===
78+
Host.AidaClient.RecitationAction.BLOCK) {
79+
this.dispatchEventToListeners(Events.RESPONSE_RECEIVED, {});
80+
return;
81+
}
82+
7783
const remainderDelay = Math.max(DELAY_BEFORE_SHOWING_RESPONSE_MS - (performance.now() - startTime), 0);
7884
// Delays the rendering of the Code completion
7985
setTimeout(() => {

front_end/panels/common/AiCodeCompletionSummaryToolbar.ts

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,21 @@ export type View = (input: ViewInput, output: ViewOutput, target: HTMLElement) =
6666

6767
export const DEFAULT_SUMMARY_TOOLBAR_VIEW: View = (input, output, target) => {
6868
// clang-format off
69-
const viewSourcesSpan = input.citations && input.citations.length > 0 ?
70-
html`<span class="link" role="link" aria-details=${input.citationsTooltipId}>
71-
${lockedString(UIStrings.viewSources)}&nbsp;${lockedString('(' + input.citations.length + ')')}</span>` : nothing;
72-
const viewSourcesTooltip = input.citations && input.citations.length > 0 ?
73-
html`<devtools-tooltip
74-
id=${input.citationsTooltipId}
75-
variant=${'rich'}
76-
jslogContext=${input.panelName + '.ai-code-completion-citations'}
77-
><div class="citations-tooltip-container">
78-
${Directives.repeat(input.citations, citation => html`<x-link
79-
href=${citation}
80-
jslog=${VisualLogging.link(input.panelName + '.ai-code-completion-citations.citation-link').track({
81-
click: true
82-
})}>${citation}</x-link>`)}</div></devtools-tooltip>` : nothing;
69+
const recitationNotice = input.citations && input.citations.length > 0 ?
70+
html`<div class="ai-code-completion-recitation-notice">${lockedString(UIStrings.generatedCodeMayBeSubjectToALicense)}
71+
<span class="link" role="link" aria-details=${input.citationsTooltipId}>
72+
${lockedString(UIStrings.viewSources)}&nbsp;${lockedString('(' + input.citations.length + ')')}</span>
73+
<devtools-tooltip
74+
id=${input.citationsTooltipId}
75+
variant=${'rich'}
76+
jslogContext=${input.panelName + '.ai-code-completion-citations'}
77+
><div class="citations-tooltip-container">
78+
${Directives.repeat(input.citations, citation => html`<x-link
79+
href=${citation}
80+
jslog=${VisualLogging.link(input.panelName + '.ai-code-completion-citations.citation-link').track({
81+
click: true
82+
})}>${citation}</x-link>`)}</div></devtools-tooltip>
83+
</div>` : nothing;
8384

8485
render(
8586
html`
@@ -130,13 +131,10 @@ export const DEFAULT_SUMMARY_TOOLBAR_VIEW: View = (input, output, target) => {
130131
@click=${input.onManageInSettingsTooltipClick}
131132
>${lockedString(UIStrings.manageInSettings)}</div></div></devtools-tooltip>
132133
</div>
133-
<div class="ai-code-completion-recitation-notice">${lockedString(UIStrings.generatedCodeMayBeSubjectToALicense)}
134-
${viewSourcesSpan}
135-
${viewSourcesTooltip}
136-
</div>
134+
${recitationNotice}
137135
</div>
138136
`, target);
139-
// clang-format on
137+
// clang-format on
140138
};
141139

142140
const MINIMUM_LOADING_STATE_TIMEOUT = 1000;

front_end/panels/common/aiCodeCompletionSummaryToolbar.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
}
2020

2121
.ai-code-completion-disclaimer {
22-
border-right: var(--sys-size-1) solid var(--sys-color-divider);
2322
padding-right: var(--sys-size-5);
2423
gap: 5px;
2524
display: flex;
@@ -33,6 +32,8 @@
3332
}
3433

3534
.ai-code-completion-recitation-notice {
35+
border-left: var(--sys-size-1) solid var(--sys-color-divider);
36+
3637
span.link {
3738
padding-left: var(--sys-size-3);
3839
}

0 commit comments

Comments
 (0)