Skip to content

Commit 681cad9

Browse files
Samiya CaurDevtools-frontend LUCI CQ
authored andcommitted
[AI Assistance] Add for "deployed" files how they are loaded by adding request initiator chain as part of the context sent to AIDA
Bug: 373594521 Change-Id: I38ae306335f3c8d45ec6d5655226799fda48a345 Fixed: 373594521 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6090774 Reviewed-by: Alex Rudenko <[email protected]> Commit-Queue: Samiya Caur <[email protected]>
1 parent 6774eb9 commit 681cad9

File tree

3 files changed

+87
-4
lines changed

3 files changed

+87
-4
lines changed

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

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import * as Common from '../../../core/common/common.js';
66
import * as Host from '../../../core/host/host.js';
77
import type * as Platform from '../../../core/platform/platform.js';
88
import * as SDK from '../../../core/sdk/sdk.js';
9+
import type * as Protocol from '../../../generated/protocol.js';
910
import * as Bindings from '../../../models/bindings/bindings.js';
11+
import * as Logs from '../../../models/logs/logs.js';
1012
import * as Workspace from '../../../models/workspace/workspace.js';
1113
import {
1214
createTarget,
@@ -48,6 +50,10 @@ describeWithMockConnection('FileAgent', () => {
4850
Bindings.IgnoreListManager.IgnoreListManager.instance({forceNew: true, debuggerWorkspaceBinding});
4951
});
5052

53+
afterEach(() => {
54+
sinon.restore();
55+
});
56+
5157
describe('buildRequest', () => {
5258
beforeEach(() => {
5359
sinon.restore();
@@ -164,6 +170,52 @@ describeWithMockConnection('FileAgent', () => {
164170
return uiSourceCode;
165171
}
166172

173+
function createNetworkRequest(): SDK.NetworkRequest.NetworkRequest {
174+
const networkRequest = SDK.NetworkRequest.NetworkRequest.create(
175+
'requestId' as Protocol.Network.RequestId,
176+
'https://www.example.com/script.js' as Platform.DevToolsPath.UrlString, '' as Platform.DevToolsPath.UrlString,
177+
null, null, null);
178+
networkRequest.statusCode = 200;
179+
networkRequest.setRequestHeaders([{name: 'content-type', value: 'bar1'}]);
180+
networkRequest.responseHeaders = [{name: 'content-type', value: 'bar2'}, {name: 'x-forwarded-for', value: 'bar3'}];
181+
182+
const initiatorNetworkRequest = SDK.NetworkRequest.NetworkRequest.create(
183+
'requestId' as Protocol.Network.RequestId, 'https://www.initiator.com' as Platform.DevToolsPath.UrlString,
184+
'' as Platform.DevToolsPath.UrlString, null, null, null);
185+
const initiatedNetworkRequest1 = SDK.NetworkRequest.NetworkRequest.create(
186+
'requestId' as Protocol.Network.RequestId, 'https://www.example.com/1' as Platform.DevToolsPath.UrlString,
187+
'' as Platform.DevToolsPath.UrlString, null, null, null);
188+
const initiatedNetworkRequest2 = SDK.NetworkRequest.NetworkRequest.create(
189+
'requestId' as Protocol.Network.RequestId, 'https://www.example.com/2' as Platform.DevToolsPath.UrlString,
190+
'' as Platform.DevToolsPath.UrlString, null, null, null);
191+
192+
sinon.stub(Logs.NetworkLog.NetworkLog.instance(), 'initiatorGraphForRequest')
193+
.withArgs(networkRequest)
194+
.returns({
195+
initiators: new Set([networkRequest, initiatorNetworkRequest]),
196+
initiated: new Map([
197+
[networkRequest, initiatorNetworkRequest],
198+
[initiatedNetworkRequest1, networkRequest],
199+
[initiatedNetworkRequest2, networkRequest],
200+
]),
201+
})
202+
.withArgs(initiatedNetworkRequest1)
203+
.returns({
204+
initiators: new Set([]),
205+
initiated: new Map([
206+
[initiatedNetworkRequest1, networkRequest],
207+
]),
208+
})
209+
.withArgs(initiatedNetworkRequest2)
210+
.returns({
211+
initiators: new Set([]),
212+
initiated: new Map([
213+
[initiatedNetworkRequest2, networkRequest],
214+
]),
215+
});
216+
return networkRequest;
217+
}
218+
167219
describe('run', () => {
168220
const testArguments = [
169221
{
@@ -297,6 +349,29 @@ lorem ipsum
297349
\`\`\``);
298350
});
299351

352+
it('formats file with associated request initiator chain', async () => {
353+
const networkRequest = createNetworkRequest();
354+
const uiSourceCode = await createUISourceCode({
355+
content: 'lorem ipsum',
356+
requestContentData: true,
357+
url: networkRequest.url(),
358+
});
359+
sinon.stub(SDK.ResourceTreeModel.ResourceTreeModel.prototype, 'resourceForURL')
360+
.withArgs(networkRequest.url())
361+
.returns({request: networkRequest} as SDK.Resource.Resource);
362+
assert.strictEqual(formatFile(uiSourceCode), `File name: script.js
363+
URL: https://www.example.com/script.js
364+
Request initiator chain:
365+
- URL: <redacted cross-origin initiator URL>
366+
\t- URL: https://www.example.com/script.js
367+
\t\t- URL: https://www.example.com/1
368+
\t\t- URL: https://www.example.com/2
369+
File content:
370+
\`\`\`
371+
lorem ipsum
372+
\`\`\``);
373+
});
374+
300375
it('formats file content of a binary file', async () => {
301376
const uiSourceCode = await createUISourceCode({
302377
resourceType: Common.ResourceType.resourceTypes.Image,

front_end/panels/ai_assistance/agents/FileAgent.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,20 @@ import {
1818
type RequestOptions,
1919
ResponseType,
2020
} from './AiAgent.js';
21+
import {formatRequestInitiatorChain} from './NetworkAgent.js';
2122

2223
const preamble =
2324
`You are a highly skilled software engineer with expertise in various programming languages and frameworks.
2425
You are provided with the content of a file from the Chrome DevTools Sources panel. To aid your analysis, you've been given the below links to understand the context of the code and its relationship to other files. When answering questions, prioritize providing these links directly.
2526
* Source-mapped from: If this code is the source for a mapped file, you'll have a link to that generated file.
2627
* Source map: If this code has an associated source map, you'll have link to the source map.
28+
* If there is a request which caused the file to be loaded, you will be provided with the request initiator chain with URLs for those requests.
2729
2830
Analyze the code and provide the following information:
2931
* Describe the primary functionality of the code. What does it do? Be specific and concise. If the code snippet is too small or unclear to determine the functionality, state that explicitly.
3032
* If possible, identify the framework or library the code is associated with (e.g., React, Angular, jQuery). List any key technologies, APIs, or patterns used in the code (e.g., Fetch API, WebSockets, object-oriented programming).
3133
* (Only provide if available and accessible externally) External Resources: Suggest relevant documentation that could help a developer understand the code better. Prioritize official documentation if available. Do not provide any internal resources.
34+
* (ONLY if request initiator chain is provided) Why the file was loaded?
3235
3336
# Considerations
3437
* Keep your analysis concise and focused, highlighting only the most critical aspects for a software engineer.
@@ -161,9 +164,14 @@ export function formatFile(selectedFile: Workspace.UISourceCode.UISourceCode): s
161164
`File name: ${selectedFile.displayName()}`,
162165
`URL: ${selectedFile.url()}`,
163166
sourceMapDetails,
164-
`File content:
165-
${formatFileContent(selectedFile)}`,
166167
];
168+
const resource = Bindings.ResourceUtils.resourceForURL(selectedFile.url());
169+
if (resource?.request) {
170+
lines.push(`Request initiator chain:
171+
${formatRequestInitiatorChain(resource?.request)}`);
172+
}
173+
lines.push(`File content:
174+
${formatFileContent(selectedFile)}`);
167175
return lines.filter(line => line.trim() !== '').join('\n');
168176
}
169177

@@ -196,7 +204,7 @@ export function formatSourceMapDetails(
196204
}
197205
} else if (selectedFile.contentType().isScript()) {
198206
for (const script of debuggerWorkspaceBinding.scriptsForUISourceCode(selectedFile)) {
199-
if (script.sourceMapURL !== undefined) {
207+
if (script.sourceMapURL !== undefined && script.sourceMapURL !== '') {
200208
sourceMapUrls.push(script.sourceMapURL);
201209
}
202210
}

front_end/panels/ai_assistance/agents/NetworkAgent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ function formatRequestInitiated(
378378
* Note: nothing here should include information from origins other than
379379
* the request's origin.
380380
*/
381-
function formatRequestInitiatorChain(request: SDK.NetworkRequest.NetworkRequest): string {
381+
export function formatRequestInitiatorChain(request: SDK.NetworkRequest.NetworkRequest): string {
382382
const allowedOrigin = new URL(request.url()).origin;
383383
let initiatorChain = '';
384384
let lineStart = '- URL: ';

0 commit comments

Comments
 (0)