Skip to content

Commit 0f9cc50

Browse files
jackfranklinDevtools-frontend LUCI CQ
authored andcommitted
AI: put calculator onto Network Request Context
Long term the plan here is to do something better to remove the need for the calculator entirely, but doing it this way means at least that the NetworkAgent doesn't have to import the entire Network Panel. R=alexrudenko@chromium.org Bug: 442509324, 442817305 Change-Id: Id76380cd32599de35c622ebea5784731a21c9558 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6911676 Commit-Queue: Jack Franklin <jacktfranklin@chromium.org> Reviewed-by: Alex Rudenko <alexrudenko@chromium.org> Auto-Submit: Jack Franklin <jacktfranklin@chromium.org>
1 parent bd4d221 commit 0f9cc50

File tree

10 files changed

+59
-25
lines changed

10 files changed

+59
-25
lines changed

front_end/models/ai_assistance/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ devtools_module("ai_assistance") {
3737
"../../core/host:bundle",
3838
"../../core/i18n:bundle",
3939
"../../core/root:bundle",
40+
"../../models/network_time_calculator:bundle",
4041
"../../panels/elements:bundle",
4142
"../../panels/network:bundle",
4243
"../../panels/timeline/utils:bundle",

front_end/models/ai_assistance/ConversationHandler.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import * as Root from '../../core/root/root.js';
1010
import * as SDK from '../../core/sdk/sdk.js';
1111
import * as Snackbars from '../../ui/components/snackbars/snackbars.js';
1212
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
13+
import * as NetworkTimeCalculator from '../network_time_calculator/network_time_calculator.js';
1314

1415
import {
1516
type AiAgent,
@@ -313,11 +314,15 @@ export class ConversationHandler {
313314
if (!request) {
314315
return this.#generateErrorResponse(`Can't find request with the given selector ${requestUrl}`);
315316
}
317+
318+
const calculator = new NetworkTimeCalculator.NetworkTransferTimeCalculator();
319+
calculator.updateBoundaries(request);
320+
316321
return this.#createAndDoExternalConversation({
317322
conversationType: ConversationType.NETWORK,
318323
aiAgent: networkAgent,
319324
prompt,
320-
selected: new RequestContext(request),
325+
selected: new RequestContext(request, calculator),
321326
});
322327
}
323328

front_end/models/ai_assistance/agents/NetworkAgent.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {describeWithMockConnection} from '../../../testing/MockConnection.js';
1313
import {createNetworkPanelForMockConnection} from '../../../testing/NetworkHelpers.js';
1414
import * as RenderCoordinator from '../../../ui/components/render_coordinator/render_coordinator.js';
1515
import * as Logs from '../../logs/logs.js';
16+
import * as NetworkTimeCalculator from '../../network_time_calculator/network_time_calculator.js';
1617
import {
1718
NetworkAgent,
1819
RequestContext,
@@ -67,6 +68,7 @@ describeWithMockConnection('NetworkAgent', () => {
6768
});
6869
describe('run', () => {
6970
let selectedNetworkRequest: SDK.NetworkRequest.NetworkRequest;
71+
let calculator: NetworkTimeCalculator.NetworkTransferTimeCalculator;
7072
const timingInfo: Protocol.Network.ResourceTiming = {
7173
requestTime: 500,
7274
proxyStart: 0,
@@ -128,6 +130,9 @@ describeWithMockConnection('NetworkAgent', () => {
128130
[initiatedNetworkRequest2, selectedNetworkRequest],
129131
]),
130132
});
133+
134+
calculator = new NetworkTimeCalculator.NetworkTransferTimeCalculator();
135+
calculator.updateBoundaries(selectedNetworkRequest);
131136
});
132137

133138
it('generates an answer', async () => {
@@ -141,7 +146,7 @@ describeWithMockConnection('NetworkAgent', () => {
141146
});
142147

143148
const responses =
144-
await Array.fromAsync(agent.run('test', {selected: new RequestContext(selectedNetworkRequest)}));
149+
await Array.fromAsync(agent.run('test', {selected: new RequestContext(selectedNetworkRequest, calculator)}));
145150
assert.deepEqual(responses, [
146151
{
147152
type: ResponseType.USER_QUERY,

front_end/models/ai_assistance/agents/NetworkAgent.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as Host from '../../../core/host/host.js';
66
import * as i18n from '../../../core/i18n/i18n.js';
77
import * as Root from '../../../core/root/root.js';
88
import type * as SDK from '../../../core/sdk/sdk.js';
9+
import type * as NetworkTimeCalculator from '../../network_time_calculator/network_time_calculator.js';
910
import {NetworkRequestFormatter} from '../data_formatters/NetworkRequestFormatter.js';
1011

1112
import {
@@ -93,10 +94,13 @@ const lockedString = i18n.i18n.lockedString;
9394

9495
export class RequestContext extends ConversationContext<SDK.NetworkRequest.NetworkRequest> {
9596
#request: SDK.NetworkRequest.NetworkRequest;
97+
#calculator: NetworkTimeCalculator.NetworkTransferTimeCalculator;
9698

97-
constructor(request: SDK.NetworkRequest.NetworkRequest) {
99+
constructor(
100+
request: SDK.NetworkRequest.NetworkRequest, calculator: NetworkTimeCalculator.NetworkTransferTimeCalculator) {
98101
super();
99102
this.#request = request;
103+
this.#calculator = calculator;
100104
}
101105

102106
override getOrigin(): string {
@@ -107,6 +111,10 @@ export class RequestContext extends ConversationContext<SDK.NetworkRequest.Netwo
107111
return this.#request;
108112
}
109113

114+
get calculator(): NetworkTimeCalculator.NetworkTimeCalculator {
115+
return this.#calculator;
116+
}
117+
110118
override getTitle(): string {
111119
return this.#request.name();
112120
}
@@ -133,34 +141,33 @@ export class NetworkAgent extends AiAgent<SDK.NetworkRequest.NetworkRequest> {
133141
}
134142

135143
async *
136-
handleContextDetails(selectedNetworkRequest: ConversationContext<SDK.NetworkRequest.NetworkRequest>|null):
137-
AsyncGenerator<ContextResponse, void, void> {
144+
handleContextDetails(selectedNetworkRequest: RequestContext|null): AsyncGenerator<ContextResponse, void, void> {
138145
if (!selectedNetworkRequest) {
139146
return;
140147
}
141148

142149
yield {
143150
type: ResponseType.CONTEXT,
144151
title: lockedString(UIStringsNotTranslate.analyzingNetworkData),
145-
details: createContextDetailsForNetworkAgent(selectedNetworkRequest.getItem()),
152+
details: createContextDetailsForNetworkAgent(selectedNetworkRequest),
146153
};
147154
}
148155

149-
override async enhanceQuery(
150-
query: string,
151-
selectedNetworkRequest: ConversationContext<SDK.NetworkRequest.NetworkRequest>|null): Promise<string> {
156+
override async enhanceQuery(query: string, selectedNetworkRequest: RequestContext|null): Promise<string> {
152157
const networkEnchantmentQuery = selectedNetworkRequest ?
153158
`# Selected network request \n${
154-
new NetworkRequestFormatter(selectedNetworkRequest.getItem())
159+
new NetworkRequestFormatter(selectedNetworkRequest.getItem(), selectedNetworkRequest.calculator)
155160
.formatNetworkRequest()}\n\n# User request\n\n` :
156161
'';
157162
return `${networkEnchantmentQuery}${query}`;
158163
}
159164
}
160165

161-
function createContextDetailsForNetworkAgent(request: SDK.NetworkRequest.NetworkRequest):
162-
[ContextDetail, ...ContextDetail[]] {
163-
const formatter = new NetworkRequestFormatter(request);
166+
function createContextDetailsForNetworkAgent(
167+
selectedNetworkRequest: RequestContext,
168+
): [ContextDetail, ...ContextDetail[]] {
169+
const request = selectedNetworkRequest.getItem();
170+
const formatter = new NetworkRequestFormatter(request, selectedNetworkRequest.calculator);
164171
const requestContextDetail: ContextDetail = {
165172
title: lockedString(UIStringsNotTranslate.request),
166173
text: lockedString(UIStringsNotTranslate.requestUrl) + ': ' + request.url() + '\n\n' +

front_end/models/ai_assistance/data_formatters/FileFormatter.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44

55
import * as Bindings from '../../bindings/bindings.js';
6+
import * as NetworkTimeCalculator from '../../network_time_calculator/network_time_calculator.js';
67
import type * as Workspace from '../../workspace/workspace.js';
78

89
import {NetworkRequestFormatter} from './NetworkRequestFormatter.js';
@@ -62,8 +63,10 @@ export class FileFormatter {
6263
];
6364
const resource = Bindings.ResourceUtils.resourceForURL(this.#file.url());
6465
if (resource?.request) {
66+
const calculator = new NetworkTimeCalculator.NetworkTransferTimeCalculator();
67+
calculator.updateBoundaries(resource.request);
6568
lines.push(`Request initiator chain:
66-
${new NetworkRequestFormatter(resource.request).formatRequestInitiatorChain()}`);
69+
${new NetworkRequestFormatter(resource.request, calculator).formatRequestInitiatorChain()}`);
6770
}
6871
lines.push(`File content:
6972
${this.#formatFileContent()}`);

front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as i18n from '../../../core/i18n/i18n.js';
66
import type * as SDK from '../../../core/sdk/sdk.js';
77
import * as Network from '../../../panels/network/network.js';
88
import * as Logs from '../../logs/logs.js';
9+
import type * as NetworkTimeCalculator from '../../network_time_calculator/network_time_calculator.js';
910

1011
const MAX_HEADERS_SIZE = 1000;
1112

@@ -22,6 +23,7 @@ function sanitizeHeaders(headers: Array<{name: string, value: string}>): Array<{
2223
}
2324

2425
export class NetworkRequestFormatter {
26+
#calculator: NetworkTimeCalculator.NetworkTransferTimeCalculator;
2527
static allowHeader(headerName: string): boolean {
2628
return allowedHeaders.has(headerName.toLowerCase().trim());
2729
}
@@ -45,8 +47,10 @@ export class NetworkRequestFormatter {
4547

4648
#request: SDK.NetworkRequest.NetworkRequest;
4749

48-
constructor(request: SDK.NetworkRequest.NetworkRequest) {
50+
constructor(
51+
request: SDK.NetworkRequest.NetworkRequest, calculator: NetworkTimeCalculator.NetworkTransferTimeCalculator) {
4952
this.#request = request;
53+
this.#calculator = calculator;
5054
}
5155

5256
formatRequestHeaders(): string {
@@ -99,9 +103,8 @@ Request initiator chain:\n${this.formatRequestInitiatorChain()}`;
99103
}
100104

101105
formatNetworkRequestTiming(): string {
102-
const calculator = Network.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator();
103106
const results = Network.RequestTimingView.RequestTimingView.calculateRequestTimeRanges(
104-
this.#request, calculator.minimumBoundary());
107+
this.#request, this.#calculator.minimumBoundary());
105108

106109
function getDuration(name: string): string|undefined {
107110
const result = results.find(r => r.name === name);
@@ -114,11 +117,11 @@ Request initiator chain:\n${this.formatRequestInitiatorChain()}`;
114117
const labels = [
115118
{
116119
label: 'Queued at (timestamp)',
117-
value: calculator.formatValue(this.#request.issueTime(), 2),
120+
value: this.#calculator.formatValue(this.#request.issueTime(), 2),
118121
},
119122
{
120123
label: 'Started at (timestamp)',
121-
value: calculator.formatValue(this.#request.startTime, 2),
124+
value: this.#calculator.formatValue(this.#request.startTime, 2),
122125
},
123126
{
124127
label: 'Queueing (duration)',

front_end/models/network_time_calculator/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ devtools_entrypoint("bundle") {
2525

2626
visibility = [
2727
":*",
28+
"../*",
2829
"../../panels/network/*",
2930
"../../ui/legacy/components/perf_ui/*",
3031
]

front_end/panels/ai_assistance/AiAssistancePanel.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as Host from '../../core/host/host.js';
77
import * as Platform from '../../core/platform/platform.js';
88
import * as SDK from '../../core/sdk/sdk.js';
99
import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
10+
import * as NetworkTimeCalculator from '../../models/network_time_calculator/network_time_calculator.js';
1011
import * as Workspace from '../../models/workspace/workspace.js';
1112
import {
1213
cleanup,
@@ -264,7 +265,9 @@ describeWithMockConnection('AI Assistance Panel', () => {
264265
{
265266
flavor: SDK.NetworkRequest.NetworkRequest,
266267
createContext: () => {
267-
return new AiAssistanceModel.RequestContext(sinon.createStubInstance(SDK.NetworkRequest.NetworkRequest));
268+
return new AiAssistanceModel.RequestContext(
269+
sinon.createStubInstance(SDK.NetworkRequest.NetworkRequest),
270+
sinon.createStubInstance(NetworkTimeCalculator.NetworkTransferDurationCalculator));
268271
},
269272
action: 'drjones.network-floating-button'
270273
},
@@ -458,7 +461,6 @@ describeWithMockConnection('AI Assistance Panel', () => {
458461
assert.isFalse(view.input.showChatActions);
459462
assert.isFalse(view.input.showActiveConversationActions);
460463
});
461-
462464
});
463465

464466
describe('history interactions', () => {

front_end/panels/ai_assistance/AiAssistancePanel.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import * as UI from '../../ui/legacy/legacy.js';
2020
import * as Lit from '../../ui/lit/lit.js';
2121
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
2222
import * as NetworkForward from '../network/forward/forward.js';
23+
import * as NetworkPanel from '../network/network.js';
2324
import * as TimelinePanel from '../timeline/timeline.js';
2425
import * as TimelineUtils from '../timeline/utils/utils.js';
2526

@@ -428,7 +429,8 @@ function createRequestContext(request: SDK.NetworkRequest.NetworkRequest|null):
428429
if (!request) {
429430
return null;
430431
}
431-
return new AiAssistanceModel.RequestContext(request);
432+
const calculator = NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator();
433+
return new AiAssistanceModel.RequestContext(request, calculator);
432434
}
433435

434436
function createPerformanceTraceContext(focus: TimelineUtils.AIContext.AgentFocus|null):
@@ -826,7 +828,12 @@ export class AiAssistancePanel extends UI.Panel.Panel {
826828
return;
827829
}
828830

829-
this.#selectedRequest = Boolean(ev.data) ? new AiAssistanceModel.RequestContext(ev.data) : null;
831+
if (Boolean(ev.data)) {
832+
const calculator = NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator();
833+
this.#selectedRequest = new AiAssistanceModel.RequestContext(ev.data, calculator);
834+
} else {
835+
this.#selectedRequest = null;
836+
}
830837
this.#updateConversationState({agent: this.#conversationAgent});
831838
};
832839

front_end/panels/network/NetworkLogView.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
513513
private readonly progressBarContainer: Element;
514514
private readonly networkLogLargeRowsSetting: Common.Settings.Setting<boolean>;
515515
private rowHeightInternal: number;
516-
private readonly timeCalculatorInternal: NetworkTimeCalculator.NetworkTimeCalculator;
516+
private readonly timeCalculatorInternal: NetworkTimeCalculator.NetworkTransferTimeCalculator;
517517
private readonly durationCalculator: NetworkTimeCalculator.NetworkTimeCalculator;
518518
private calculatorInternal: NetworkTimeCalculator.NetworkTimeCalculator;
519519
private readonly columnsInternal: NetworkLogViewColumns;
@@ -1330,7 +1330,7 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
13301330
}
13311331
}
13321332

1333-
timeCalculator(): NetworkTimeCalculator.NetworkTimeCalculator {
1333+
timeCalculator(): NetworkTimeCalculator.NetworkTransferTimeCalculator {
13341334
return this.timeCalculatorInternal;
13351335
}
13361336

0 commit comments

Comments
 (0)