Skip to content

Commit e73fae1

Browse files
wolfibDevtools-frontend LUCI CQ
authored andcommitted
[Console Insights] Render 'related content' section containing
references This CL adds a section containing references to related content to console insights answers. This section is only being rendered if AIDA's response contains `factualityMetadata`, which is only the case when AIDA uses Search RAG. Currently Search RAG needs to be enabled via command line, so this change has no effect on non-testers of Search RAG. Screenshot: https://i.imgur.com/zzCzjL7.png Bug: 381228083 Change-Id: Iaf265e96c6eb58e2a238806b280ccd804a35420f Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6105676 Reviewed-by: Alex Rudenko <[email protected]> Auto-Submit: Wolfgang Beyer <[email protected]> Commit-Queue: Alex Rudenko <[email protected]> Commit-Queue: Wolfgang Beyer <[email protected]>
1 parent 7dcc4ff commit e73fae1

File tree

6 files changed

+96
-28
lines changed

6 files changed

+96
-28
lines changed

front_end/core/host/AidaClient.test.ts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ describeWithEnvironment('AidaClient', () => {
293293
const response = JSON.stringify([
294294
{
295295
textChunk: {text: 'Chunk1\n'},
296-
metadata: {rpcGlobalId: 123, attributionMetadata: {attributionAction: 'NO_ACTION', citations: []}},
296+
metadata: {rpcGlobalId: 123},
297297
},
298298
{
299299
textChunk: {text: 'Chunk2\n'},
@@ -319,13 +319,10 @@ describeWithEnvironment('AidaClient', () => {
319319
'Chunk2\n',
320320
metadata: {
321321
rpcGlobalId: 123,
322-
attributionMetadata: [
323-
{attributionAction: Host.AidaClient.RecitationAction.NO_ACTION, citations: []},
324-
{
325-
attributionAction: Host.AidaClient.RecitationAction.CITE,
326-
citations: [{startIndex: 0, endIndex: 1, url: 'https://example.com'}],
327-
},
328-
],
322+
attributionMetadata: {
323+
attributionAction: Host.AidaClient.RecitationAction.CITE,
324+
citations: [{startIndex: 0, endIndex: 1, url: 'https://example.com'}],
325+
},
329326
},
330327
completed: false,
331328
},
@@ -334,13 +331,10 @@ describeWithEnvironment('AidaClient', () => {
334331
'Chunk2\n',
335332
metadata: {
336333
rpcGlobalId: 123,
337-
attributionMetadata: [
338-
{attributionAction: Host.AidaClient.RecitationAction.NO_ACTION, citations: []},
339-
{
340-
attributionAction: Host.AidaClient.RecitationAction.CITE,
341-
citations: [{startIndex: 0, endIndex: 1, url: 'https://example.com'}],
342-
},
343-
],
334+
attributionMetadata: {
335+
attributionAction: Host.AidaClient.RecitationAction.CITE,
336+
citations: [{startIndex: 0, endIndex: 1, url: 'https://example.com'}],
337+
},
344338
},
345339
functionCalls: undefined,
346340
completed: true,

front_end/core/host/AidaClient.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,18 @@ export interface AidaFunctionCallResponse {
208208
args: Record<string, unknown>;
209209
}
210210

211+
export interface FactualityFact {
212+
sourceUri?: string;
213+
}
214+
215+
export interface FactualityMetadata {
216+
facts: FactualityFact[];
217+
}
218+
211219
export interface AidaResponseMetadata {
212220
rpcGlobalId?: RpcGlobalId;
213-
attributionMetadata?: AttributionMetadata[];
221+
attributionMetadata?: AttributionMetadata;
222+
factualityMetadata?: FactualityMetadata;
214223
}
215224

216225
export interface AidaResponse {
@@ -326,7 +335,7 @@ export class AidaClient {
326335
const text = [];
327336
let inCodeChunk = false;
328337
const functionCalls: AidaFunctionCallResponse[] = [];
329-
const metadata: AidaResponseMetadata = {rpcGlobalId: 0};
338+
let metadata: AidaResponseMetadata = {rpcGlobalId: 0};
330339
while ((chunk = await stream.read())) {
331340
let textUpdated = false;
332341
// The AIDA response is a JSON array of objects, split at the object
@@ -355,15 +364,9 @@ export class AidaClient {
355364

356365
for (const result of results) {
357366
if ('metadata' in result) {
358-
metadata.rpcGlobalId = result.metadata.rpcGlobalId;
359-
if ('attributionMetadata' in result.metadata) {
360-
if (!metadata.attributionMetadata) {
361-
metadata.attributionMetadata = [];
362-
}
363-
metadata.attributionMetadata.push(result.metadata.attributionMetadata);
364-
if (result.metadata.attributionMetadata.attributionAction === RecitationAction.BLOCK) {
365-
throw new AidaBlockError();
366-
}
367+
metadata = result.metadata;
368+
if (metadata?.attributionMetadata?.attributionAction === RecitationAction.BLOCK) {
369+
throw new AidaBlockError();
367370
}
368371
}
369372
if ('textChunk' in result) {

front_end/panels/ai_assistance/agents/StylingAgent.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,10 +1014,10 @@ STOP`,
10141014
explanation: 'ANSWER: this is the answer',
10151015
metadata: {
10161016
rpcGlobalId: 123,
1017-
attributionMetadata: [{
1017+
attributionMetadata: {
10181018
attributionAction: Host.AidaClient.RecitationAction.ACTION_UNSPECIFIED,
10191019
citations: [],
1020-
}],
1020+
},
10211021
},
10221022
completed: true,
10231023
};

front_end/panels/explain/components/ConsoleInsight.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,40 @@ describeWithEnvironment('ConsoleInsight', () => {
235235
const content = component.shadowRoot!.querySelector('main')!.innerText.trim();
236236
assert.strictEqual(content, 'Check your internet connection and try again.');
237237
});
238+
239+
it('displays factuality metadata as related content', async () => {
240+
function getAidaClientWithMetadata() {
241+
return {
242+
async *
243+
fetch() {
244+
yield {
245+
explanation: 'test',
246+
metadata: {
247+
rpcGlobalId: 0,
248+
factualityMetadata: {
249+
facts: [
250+
{sourceUri: 'https://www.firstSource.test/someInfo'},
251+
{sourceUri: 'https://www.anotherSource.test/page'},
252+
],
253+
},
254+
},
255+
completed: true,
256+
};
257+
},
258+
registerClientEvent: sinon.spy(),
259+
};
260+
}
261+
262+
component = new Explain.ConsoleInsight(
263+
getTestPromptBuilder(), getAidaClientWithMetadata(), Host.AidaClient.AidaAccessPreconditions.AVAILABLE);
264+
renderElementIntoDOM(component);
265+
await drainMicroTasks();
266+
const details = component.shadowRoot!.querySelector('details');
267+
assert.strictEqual(details!.querySelector('summary')!.textContent?.trim(), 'Sources and related content');
268+
const xLinks = details!.querySelectorAll('x-link');
269+
assert.strictEqual(xLinks[0].textContent?.trim(), 'https://www.firstSource.test/someInfo');
270+
assert.strictEqual(xLinks[0].getAttribute('href'), 'https://www.firstSource.test/someInfo');
271+
assert.strictEqual(xLinks[1].textContent?.trim(), 'https://www.anotherSource.test/page');
272+
assert.strictEqual(xLinks[1].getAttribute('href'), 'https://www.anotherSource.test/page');
273+
});
238274
});

front_end/panels/explain/components/ConsoleInsight.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ const UIStrings = {
131131
* @description Text for a link to Chrome DevTools Settings.
132132
*/
133133
settingsLink: '`Console insights` in Settings',
134+
/**
135+
* @description The title of the list of references/recitations that were used to generate the insight.
136+
*/
137+
references: 'Sources and related content',
134138
};
135139
const str_ = i18n.i18n.registerUIStrings('panels/explain/components/ConsoleInsight.ts', UIStrings);
136140
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -563,6 +567,34 @@ export class ConsoleInsight extends HTMLElement {
563567
// clang-format on
564568
}
565569

570+
#maybeRenderRelatedContent(): LitHtml.LitTemplate {
571+
if (this.#state.type !== State.INSIGHT || !this.#state.metadata.factualityMetadata?.facts.length) {
572+
return LitHtml.nothing;
573+
}
574+
// clang-format off
575+
return html`
576+
<details jslog=${VisualLogging.expand('references').track({click: true})}>
577+
<summary>${i18nString(UIStrings.references)}</summary>
578+
<ul>
579+
${this.#state.metadata?.factualityMetadata?.facts.map(fact => {
580+
return fact.sourceUri ? html`
581+
<li>
582+
<x-link
583+
href=${fact.sourceUri}
584+
class="link"
585+
jslog=${VisualLogging.link('references.console-insights').track({click: true})}
586+
>
587+
${fact.sourceUri}
588+
</x-link>
589+
</li>
590+
` : LitHtml.nothing;
591+
})}
592+
</ul>
593+
</details>
594+
`;
595+
// clang-format on
596+
}
597+
566598
#renderMain(): LitHtml.TemplateResult {
567599
const jslog = `${VisualLogging.section(this.#state.type).track({resize: true})}`;
568600
// clang-format off
@@ -587,6 +619,7 @@ export class ConsoleInsight extends HTMLElement {
587619
.data=${{tokens: this.#state.tokens, renderer: this.#renderer, animationEnabled: true} as MarkdownView.MarkdownView.MarkdownViewData}>
588620
</devtools-markdown-view>`: this.#state.explanation
589621
}
622+
${this.#maybeRenderRelatedContent()}
590623
<details jslog=${VisualLogging.expand('sources').track({click: true})}>
591624
<summary>${i18nString(UIStrings.inputData)}</summary>
592625
<devtools-console-insight-sources-list .sources=${this.#state.sources} .isPageReloadRecommended=${this.#state.isPageReloadRecommended}>

front_end/ui/visual_logging/KnownContextValues.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2733,6 +2733,8 @@ export const knownContextValues = new Set([
27332733
'redirect-source-request-url',
27342734
'reduce',
27352735
'reduced-contrast',
2736+
'references',
2737+
'references.console-insights',
27362738
'refresh',
27372739
'refresh-caches',
27382740
'refresh-database',

0 commit comments

Comments
 (0)