chrome-devtools-frontend 1.0.1582745 → 1.0.1585538

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/front_end/core/host/InspectorFrontendHostAPI.ts +1 -0
  2. package/front_end/core/host/InspectorFrontendHostStub.ts +2 -0
  3. package/front_end/core/root/Runtime.ts +12 -11
  4. package/front_end/core/sdk/CSSMatchedStyles.ts +3 -0
  5. package/front_end/core/sdk/CSSMetadata.ts +3 -0
  6. package/front_end/core/sdk/NetworkManager.ts +63 -115
  7. package/front_end/entrypoint_template.html +1 -5
  8. package/front_end/entrypoints/main/MainImpl.ts +1 -0
  9. package/front_end/generated/Deprecation.ts +21 -0
  10. package/front_end/generated/InspectorBackendCommands.ts +5 -3
  11. package/front_end/generated/SupportedCSSProperties.js +6 -2
  12. package/front_end/generated/protocol-mapping.d.ts +2 -1
  13. package/front_end/generated/protocol-proxy-api.d.ts +2 -1
  14. package/front_end/generated/protocol.ts +14 -0
  15. package/front_end/models/ai_assistance/AiConversation.ts +34 -2
  16. package/front_end/models/ai_assistance/BuiltInAi.ts +1 -2
  17. package/front_end/models/ai_assistance/agents/AiAgent.ts +3 -10
  18. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +1 -1
  19. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +17 -9
  20. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +0 -24
  21. package/front_end/models/ai_code_generation/AiCodeGeneration.ts +5 -0
  22. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +16 -8
  23. package/front_end/models/computed_style/ComputedStyleModel.ts +20 -15
  24. package/front_end/models/greendev/Prototypes.ts +1 -5
  25. package/front_end/models/issues_manager/CorsIssue.ts +2 -9
  26. package/front_end/models/issues_manager/descriptions/corsLocalNetworkAccessPermissionDenied.md +2 -2
  27. package/front_end/models/javascript_metadata/NativeFunctions.js +20 -0
  28. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +28 -39
  29. package/front_end/panels/ai_assistance/components/ChatInput.ts +73 -95
  30. package/front_end/panels/ai_assistance/components/ChatMessage.ts +4 -2
  31. package/front_end/panels/ai_assistance/components/ChatView.ts +0 -2
  32. package/front_end/panels/autofill/AutofillView.ts +4 -8
  33. package/front_end/panels/common/AiCodeGenerationTeaser.ts +37 -8
  34. package/front_end/panels/console/ConsoleView.ts +1 -2
  35. package/front_end/panels/console/ConsoleViewMessage.ts +18 -11
  36. package/front_end/panels/elements/ComputedStyleWidget.ts +80 -48
  37. package/front_end/panels/elements/ElementStatePaneWidget.ts +1 -1
  38. package/front_end/panels/elements/ElementsPanel.ts +18 -5
  39. package/front_end/panels/elements/ElementsTreeElement.ts +459 -435
  40. package/front_end/panels/elements/EventListenersWidget.ts +2 -4
  41. package/front_end/panels/elements/NodeStackTraceWidget.ts +1 -3
  42. package/front_end/panels/elements/PropertiesWidget.ts +1 -2
  43. package/front_end/panels/elements/StylePropertyTreeElement.ts +18 -2
  44. package/front_end/panels/elements/computedStyleWidget.css +25 -0
  45. package/front_end/panels/issues/AffectedResourcesView.ts +1 -2
  46. package/front_end/panels/network/NetworkDataGridNode.ts +0 -8
  47. package/front_end/panels/network/NetworkLogView.ts +64 -105
  48. package/front_end/panels/network/RequestConditionsDrawer.ts +168 -233
  49. package/front_end/panels/network/network-meta.ts +4 -27
  50. package/front_end/panels/settings/SettingsScreen.ts +12 -4
  51. package/front_end/panels/settings/WorkspaceSettingsTab.ts +1 -1
  52. package/front_end/panels/snippets/SnippetsQuickOpen.ts +6 -9
  53. package/front_end/panels/sources/CallStackSidebarPane.ts +6 -8
  54. package/front_end/panels/sources/DebuggerPlugin.ts +2 -1
  55. package/front_end/panels/sources/GoToLineQuickOpen.ts +0 -4
  56. package/front_end/panels/sources/OpenFileQuickOpen.ts +0 -4
  57. package/front_end/panels/sources/OutlineQuickOpen.ts +0 -4
  58. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +3 -1
  59. package/front_end/panels/sources/sources-meta.ts +9 -6
  60. package/front_end/panels/timeline/TimelineFlameChartView.ts +0 -12
  61. package/front_end/panels/timeline/TimelinePanel.ts +35 -15
  62. package/front_end/panels/timeline/components/Sidebar.ts +21 -0
  63. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +1 -20
  64. package/front_end/panels/timeline/components/insights/InsightRenderer.ts +0 -1
  65. package/front_end/third_party/chromium/README.chromium +1 -1
  66. package/front_end/third_party/puppeteer/README.chromium +2 -2
  67. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts +1 -1
  68. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  69. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +1 -1
  70. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js +2 -3
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js.map +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
  75. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
  76. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/encoding.d.ts.map +1 -1
  77. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/encoding.js +5 -3
  78. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/encoding.js.map +1 -1
  79. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  81. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +8 -6
  82. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts +1 -1
  83. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +1 -1
  85. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
  86. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js +2 -3
  88. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
  90. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
  91. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/encoding.d.ts.map +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/encoding.js +5 -3
  93. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/encoding.js.map +1 -1
  94. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  96. package/front_end/third_party/puppeteer/package/package.json +4 -4
  97. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +1 -1
  98. package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +2 -2
  99. package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +4 -3
  100. package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
  101. package/front_end/third_party/puppeteer/package/src/util/encoding.ts +5 -3
  102. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  103. package/front_end/ui/components/linkifier/LinkifierImpl.ts +3 -0
  104. package/front_end/ui/components/linkifier/LinkifierUtils.ts +3 -0
  105. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +8 -0
  106. package/front_end/ui/components/text_editor/AiCodeGenerationParser.ts +29 -7
  107. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +42 -18
  108. package/front_end/ui/components/text_editor/config.ts +6 -0
  109. package/front_end/ui/legacy/InspectorView.ts +41 -15
  110. package/front_end/ui/legacy/Toolbar.ts +12 -4
  111. package/front_end/ui/legacy/UIUtils.ts +56 -7
  112. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +4 -3
  113. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +2 -1
  114. package/front_end/ui/legacy/components/quick_open/HelpQuickOpen.ts +8 -2
  115. package/front_end/ui/legacy/components/quick_open/QuickOpen.ts +8 -8
  116. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +12 -9
  117. package/front_end/ui/legacy/components/utils/Linkifier.ts +116 -87
  118. package/front_end/ui/legacy/legacy.ts +0 -2
  119. package/front_end/ui/visual_logging/KnownContextValues.ts +4 -0
  120. package/mcp/HostBindings.ts +3 -0
  121. package/package.json +1 -1
  122. package/front_end/models/issues_manager/descriptions/corsInsecurePrivateNetwork.md +0 -10
  123. package/front_end/models/issues_manager/descriptions/corsPreflightAllowPrivateNetworkError.md +0 -10
  124. package/front_end/models/issues_manager/descriptions/corsPrivateNetworkPermissionDenied.md +0 -10
  125. package/front_end/panels/elements/computedStyleSidebarPane.css +0 -18
  126. package/front_end/ui/legacy/Floaty.ts +0 -438
  127. package/front_end/ui/legacy/floaty.css +0 -77
@@ -850,6 +850,18 @@ export namespace Audits {
850
850
  insight?: CookieIssueInsight;
851
851
  }
852
852
 
853
+ export const enum PerformanceIssueType {
854
+ DocumentCookie = 'DocumentCookie',
855
+ }
856
+
857
+ /**
858
+ * Details for a performance issue.
859
+ */
860
+ export interface PerformanceIssueDetails {
861
+ performanceIssueType: PerformanceIssueType;
862
+ sourceCodeLocation?: SourceCodeLocation;
863
+ }
864
+
853
865
  export const enum MixedContentResolutionStatus {
854
866
  MixedContentBlocked = 'MixedContentBlocked',
855
867
  MixedContentAutomaticallyUpgraded = 'MixedContentAutomaticallyUpgraded',
@@ -1564,6 +1576,7 @@ export namespace Audits {
1564
1576
  ConnectionAllowlistIssue = 'ConnectionAllowlistIssue',
1565
1577
  UserReidentificationIssue = 'UserReidentificationIssue',
1566
1578
  PermissionElementIssue = 'PermissionElementIssue',
1579
+ PerformanceIssue = 'PerformanceIssue',
1567
1580
  }
1568
1581
 
1569
1582
  /**
@@ -1603,6 +1616,7 @@ export namespace Audits {
1603
1616
  connectionAllowlistIssueDetails?: ConnectionAllowlistIssueDetails;
1604
1617
  userReidentificationIssueDetails?: UserReidentificationIssueDetails;
1605
1618
  permissionElementIssueDetails?: PermissionElementIssueDetails;
1619
+ performanceIssueDetails?: PerformanceIssueDetails;
1606
1620
  }
1607
1621
 
1608
1622
  /**
@@ -14,7 +14,8 @@ import {
14
14
  type ConversationContext,
15
15
  type MultimodalInput,
16
16
  type ResponseData,
17
- ResponseType
17
+ ResponseType,
18
+ type UserQuery
18
19
  } from './agents/AiAgent.js';
19
20
  import {ContextSelectionAgent} from './agents/ContextSelectionAgent.js';
20
21
  import {FileAgent, FileContext} from './agents/FileAgent.js';
@@ -56,6 +57,7 @@ export class AiConversation {
56
57
  undefined,
57
58
  serializedConversation.isExternal,
58
59
  undefined,
60
+ undefined,
59
61
  );
60
62
  }
61
63
 
@@ -77,6 +79,7 @@ export class AiConversation {
77
79
 
78
80
  #performanceRecordAndReload?: () => Promise<Trace.TraceModel.ParsedTrace>;
79
81
  #onInspectElement?: () => Promise<SDK.DOMModel.DOMNode|null>;
82
+ #networkTimeCalculator?: NetworkTimeCalculator.NetworkTransferTimeCalculator;
80
83
 
81
84
  constructor(
82
85
  type: ConversationType,
@@ -88,11 +91,13 @@ export class AiConversation {
88
91
  isExternal = false,
89
92
  performanceRecordAndReload?: () => Promise<Trace.TraceModel.ParsedTrace>,
90
93
  onInspectElement?: () => Promise<SDK.DOMModel.DOMNode|null>,
94
+ networkTimeCalculator?: NetworkTimeCalculator.NetworkTransferTimeCalculator,
91
95
  ) {
92
96
  this.#changeManager = changeManager;
93
97
  this.#aidaClient = aidaClient;
94
98
  this.#performanceRecordAndReload = performanceRecordAndReload;
95
99
  this.#onInspectElement = onInspectElement;
100
+ this.#networkTimeCalculator = networkTimeCalculator;
96
101
 
97
102
  this.id = id;
98
103
  this.#isReadOnly = isReadOnly;
@@ -288,6 +293,7 @@ export class AiConversation {
288
293
  changeManager: this.#changeManager,
289
294
  performanceRecordAndReload: this.#performanceRecordAndReload,
290
295
  onInspectElement: this.#onInspectElement,
296
+ networkTimeCalculator: this.#networkTimeCalculator,
291
297
  };
292
298
  switch (type) {
293
299
  case ConversationType.STYLING: {
@@ -393,12 +399,20 @@ Time: ${micros(time)}`;
393
399
  run(
394
400
  initialQuery: string,
395
401
  options: {
396
-
397
402
  signal?: AbortSignal,
398
403
  extraContext?: ExtraContext[],
399
404
  multimodalInput?: MultimodalInput,
400
405
  } = {},
401
406
  ): AsyncGenerator<ResponseData, void, void> {
407
+ const userQuery: UserQuery = {
408
+ type: ResponseType.USER_QUERY,
409
+ query: initialQuery,
410
+ imageInput: options.multimodalInput?.input,
411
+ imageId: options.multimodalInput?.id,
412
+ };
413
+ void this.addHistoryItem(userQuery);
414
+ yield userQuery;
415
+
402
416
  if (options.extraContext) {
403
417
  await this.#createFactsForExtraContext(options.extraContext);
404
418
  }
@@ -408,6 +422,18 @@ Time: ${micros(time)}`;
408
422
  throw new Error('Cross-origin context data should not be included');
409
423
  }
410
424
 
425
+ yield* this.#runAgent(initialQuery, options);
426
+ }
427
+
428
+ async *
429
+ #runAgent(
430
+ initialQuery: string,
431
+ options: {
432
+ signal?: AbortSignal,
433
+ extraContext?: ExtraContext[],
434
+ multimodalInput?: MultimodalInput,
435
+ } = {},
436
+ ): AsyncGenerator<ResponseData, void, void> {
411
437
  function shouldAddToHistory(data: ResponseData): boolean {
412
438
  if (data.type === ResponseType.CONTEXT_CHANGE) {
413
439
  return false;
@@ -433,6 +459,12 @@ Time: ${micros(time)}`;
433
459
  if (shouldAddToHistory(data)) {
434
460
  void this.addHistoryItem(data);
435
461
  }
462
+ if (data.type === ResponseType.CONTEXT_CHANGE) {
463
+ this.setContext(data.context);
464
+ yield* this.#runAgent(initialQuery, options);
465
+ return;
466
+ }
467
+
436
468
  yield data;
437
469
  }
438
470
  }
@@ -47,8 +47,7 @@ export class BuiltInAi extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
47
47
  }
48
48
 
49
49
  async getLanguageModelAvailability(): Promise<LanguageModelAvailability> {
50
- if (!Root.Runtime.hostConfig.devToolsConsoleInsightsTeasers?.enabled ||
51
- (Root.Runtime.hostConfig.devToolsAiPromptApi && !Root.Runtime.hostConfig.devToolsAiPromptApi.enabled)) {
50
+ if (!Root.Runtime.hostConfig.devToolsConsoleInsightsTeasers?.enabled) {
52
51
  this.#availability = LanguageModelAvailability.DISABLED;
53
52
  return this.#availability;
54
53
  }
@@ -88,7 +88,7 @@ export interface SideEffectResponse {
88
88
  }
89
89
  export interface ContextChangeResponse {
90
90
  type: ResponseType.CONTEXT_CHANGE;
91
- context: unknown;
91
+ context: ConversationContext<unknown>;
92
92
  }
93
93
 
94
94
  interface SerializedSideEffectResponse extends Omit<SideEffectResponse, 'confirm'> {}
@@ -517,13 +517,6 @@ export abstract class AiAgent<T> {
517
517
  // Request is built here to capture history up to this point.
518
518
  let request = this.buildRequest(query, Host.AidaClient.Role.USER);
519
519
 
520
- yield {
521
- type: ResponseType.USER_QUERY,
522
- query: initialQuery,
523
- imageInput: multimodalInput?.input,
524
- imageId: multimodalInput?.id,
525
- };
526
-
527
520
  yield* this.handleContextDetails(options.selected);
528
521
 
529
522
  for (let i = 0; i < MAX_STEPS; i++) {
@@ -650,7 +643,7 @@ export abstract class AiAgent<T> {
650
643
  name: string,
651
644
  args: Record<string, unknown>,
652
645
  options?: FunctionHandlerOptions&{explanation?: string},
653
- ): AsyncGenerator<FunctionCallResponseData, {result: unknown}|{context: unknown}> {
646
+ ): AsyncGenerator<FunctionCallResponseData, {result: unknown}|{context: ConversationContext<unknown>}> {
654
647
  const call = this.#functionDeclarations.get(name);
655
648
  if (!call) {
656
649
  throw new Error(`Function ${name} is not found.`);
@@ -762,7 +755,7 @@ export abstract class AiAgent<T> {
762
755
  }
763
756
 
764
757
  if ('context' in result) {
765
- return result as {context: unknown};
758
+ return result as {context: ConversationContext<unknown>};
766
759
  }
767
760
 
768
761
  return result as {result: unknown};
@@ -31,7 +31,7 @@ Content:
31
31
  "function_declarations": [
32
32
  {
33
33
  "name": "listNetworkRequests",
34
- "description": "Gives a list of network requests including URL, status code, and duration in ms.",
34
+ "description": "Gives a list of network requests including URL, status code, and duration.",
35
35
  "parameters": {
36
36
  "type": 6,
37
37
  "description": "",
@@ -9,9 +9,9 @@ import * as Platform from '../../../core/platform/platform.js';
9
9
  import * as Root from '../../../core/root/root.js';
10
10
  import * as SDK from '../../../core/sdk/sdk.js';
11
11
  import * as Logs from '../../logs/logs.js';
12
+ import * as NetworkTimeCalculator from '../../network_time_calculator/network_time_calculator.js';
12
13
  import type * as Trace from '../../trace/trace.js';
13
14
  import * as Workspace from '../../workspace/workspace.js';
14
- import {AgentFocus} from '../performance/AIContext.js';
15
15
 
16
16
  import {
17
17
  type AgentOptions,
@@ -19,6 +19,10 @@ import {
19
19
  type ContextResponse,
20
20
  type RequestOptions,
21
21
  } from './AiAgent.js';
22
+ import {FileContext} from './FileAgent.js';
23
+ import {RequestContext} from './NetworkAgent.js';
24
+ import {PerformanceTraceContext} from './PerformanceAgent.js';
25
+ import {NodeContext} from './StylingAgent.js';
22
26
 
23
27
  const lockedString = i18n.i18n.lockedString;
24
28
  /**
@@ -33,8 +37,8 @@ You aim to help developers of all levels, prioritizing teaching web concepts as
33
37
  # Considerations
34
38
  * Determine what the question the domain of the question is - styling, network, sources, performance or other part of DevTools.
35
39
  * Proactively try to gather additional data. If a select specific data can be selected, select one.
40
+ * Always try select single specific context before answering the question.
36
41
  * Avoid making assumptions without sufficient evidence, and always seek further clarification if needed.
37
- * Always explore multiple possible explanations for the observed behavior before settling on a conclusion.
38
42
  * When presenting solutions, clearly distinguish between the primary cause and contributing factors.
39
43
  * Please answer only if you are sure about the answer. Otherwise, explain why you're not able to answer.
40
44
  * When answering, always consider MULTIPLE possible solutions.
@@ -46,7 +50,6 @@ You aim to help developers of all levels, prioritizing teaching web concepts as
46
50
  * Always specify the language for code blocks (e.g., \`\`\`css, \`\`\`javascript).
47
51
  * Keep text responses concise and scannable.
48
52
 
49
- * ALWAYS OUTPUT a list of follow-up queries at the end of your text response. The format is SUGGESTIONS: ["suggestion1", "suggestion2", "suggestion3"]. Make sure that the array and the \`SUGGESTIONS: \` text is in the same line. You're also capable of executing the fix for the issue user mentioned. Reflect this in your suggestions.
50
53
  * **CRITICAL** NEVER write full Python programs - you should only write individual statements that invoke a single function from the provided library.
51
54
  * **CRITICAL** NEVER output text before a function call. Always do a function call first.
52
55
  * **CRITICAL** You are a debugging assistant in DevTools. NEVER provide answers to questions of unrelated topics such as legal advice, financial advice, personal opinions, medical advice, religion, race, politics, sexuality, gender, or any other non web-development topics. Answer "Sorry, I can't answer that. I'm best at questions about debugging web pages." to such questions.
@@ -75,17 +78,20 @@ export class ContextSelectionAgent extends AiAgent<never> {
75
78
 
76
79
  readonly #performanceRecordAndReload?: () => Promise<Trace.TraceModel.ParsedTrace>;
77
80
  readonly #onInspectElement?: () => Promise<SDK.DOMModel.DOMNode|null>;
81
+ readonly #networkTimeCalculator?: NetworkTimeCalculator.NetworkTransferTimeCalculator;
78
82
 
79
83
  constructor(opts: AgentOptions&{
80
84
  performanceRecordAndReload?: () => Promise<Trace.TraceModel.ParsedTrace>,
81
85
  onInspectElement?: () => Promise<SDK.DOMModel.DOMNode|null>,
86
+ networkTimeCalculator?: NetworkTimeCalculator.NetworkTransferTimeCalculator,
82
87
  }) {
83
88
  super(opts);
84
89
  this.#performanceRecordAndReload = opts.performanceRecordAndReload;
85
90
  this.#onInspectElement = opts.onInspectElement;
91
+ this.#networkTimeCalculator = opts.networkTimeCalculator;
86
92
 
87
93
  this.declareFunction<Record<string, never>>('listNetworkRequests', {
88
- description: `Gives a list of network requests including URL, status code, and duration in ms.`,
94
+ description: `Gives a list of network requests including URL, status code, and duration.`,
89
95
  parameters: {
90
96
  type: Host.AidaClient.ParametersTypes.OBJECT,
91
97
  description: '',
@@ -109,10 +115,11 @@ export class ContextSelectionAgent extends AiAgent<never> {
109
115
  if (mainSecurityOrigin && request.securityOrigin() !== mainSecurityOrigin) {
110
116
  continue;
111
117
  }
118
+
112
119
  requests.push({
113
120
  url: request.url(),
114
121
  statusCode: request.statusCode,
115
- duration: request.duration,
122
+ duration: i18n.TimeUtilities.secondsToString(request.duration),
116
123
  });
117
124
  }
118
125
 
@@ -159,8 +166,9 @@ export class ContextSelectionAgent extends AiAgent<never> {
159
166
  });
160
167
 
161
168
  if (request) {
169
+ const calculator = this.#networkTimeCalculator ?? new NetworkTimeCalculator.NetworkTransferTimeCalculator();
162
170
  return {
163
- context: request,
171
+ context: new RequestContext(request, calculator),
164
172
  };
165
173
  }
166
174
 
@@ -222,7 +230,7 @@ export class ContextSelectionAgent extends AiAgent<never> {
222
230
  for (const file of this.#getUISourceCodes()) {
223
231
  if (file.fullDisplayName() === params.name) {
224
232
  return {
225
- context: file,
233
+ context: new FileContext(file),
226
234
  };
227
235
  }
228
236
  }
@@ -255,7 +263,7 @@ export class ContextSelectionAgent extends AiAgent<never> {
255
263
  const result = await this.#performanceRecordAndReload();
256
264
 
257
265
  return {
258
- context: AgentFocus.fromParsedTrace(result),
266
+ context: PerformanceTraceContext.fromParsedTrace(result),
259
267
  };
260
268
  }
261
269
  });
@@ -283,7 +291,7 @@ export class ContextSelectionAgent extends AiAgent<never> {
283
291
  const node = await this.#onInspectElement();
284
292
  if (node) {
285
293
  return {
286
- context: node,
294
+ context: new NodeContext(node),
287
295
  };
288
296
  }
289
297
  return {
@@ -190,10 +190,6 @@ Content:
190
190
  Title: StylingAgent run generates an answer immediately
191
191
  Content:
192
192
  [
193
- {
194
- "type": "user-query",
195
- "query": "test"
196
- },
197
193
  {
198
194
  "type": "context",
199
195
  "title": "Analyzing the prompt",
@@ -274,10 +270,6 @@ Content:
274
270
  Title: StylingAgent run generates an rpcId for the answer
275
271
  Content:
276
272
  [
277
- {
278
- "type": "user-query",
279
- "query": "test"
280
- },
281
273
  {
282
274
  "type": "context",
283
275
  "title": "Analyzing the prompt",
@@ -303,10 +295,6 @@ Content:
303
295
  Title: StylingAgent run throws an error based on the attribution metadata including RecitationAction.BLOCK
304
296
  Content:
305
297
  [
306
- {
307
- "type": "user-query",
308
- "query": "test"
309
- },
310
298
  {
311
299
  "type": "context",
312
300
  "title": "Analyzing the prompt",
@@ -335,10 +323,6 @@ Content:
335
323
  Title: StylingAgent run does not throw an error based on attribution metadata not including RecitationAction.BLOCK
336
324
  Content:
337
325
  [
338
- {
339
- "type": "user-query",
340
- "query": "test"
341
- },
342
326
  {
343
327
  "type": "context",
344
328
  "title": "Analyzing the prompt",
@@ -364,10 +348,6 @@ Content:
364
348
  Title: StylingAgent run generates a response if nothing is returned
365
349
  Content:
366
350
  [
367
- {
368
- "type": "user-query",
369
- "query": "test"
370
- },
371
351
  {
372
352
  "type": "context",
373
353
  "title": "Analyzing the prompt",
@@ -391,10 +371,6 @@ Content:
391
371
  Title: StylingAgent run generates an action response if action and answer both present
392
372
  Content:
393
373
  [
394
- {
395
- "type": "user-query",
396
- "query": "test"
397
- },
398
374
  {
399
375
  "type": "context",
400
376
  "title": "Analyzing the prompt",
@@ -22,6 +22,11 @@ Your role is to act as an expert pair programmer within the Chrome DevTools envi
22
22
  * **Return ONLY code blocks.** * Do NOT include any introductory text, explanations, or concluding remarks.
23
23
  * Do NOT provide step-by-step guides or descriptions of how the code works.
24
24
  * Inline comments within the code are permitted and encouraged for clarity.
25
+
26
+ 3. **Handling Ambiguity:**
27
+ * If the user's request is vague, unclear, or lacks sufficient detail to generate a functional solution, do NOT generate placeholder code.
28
+ * Instead, output a single comment block asking for specific clarification on the desired task or logic.
29
+ * Example output for vague input: // The request is unclear. Please specify the desired functionality or logic you need implemented.
25
30
  `;
26
31
 
27
32
  export const additionalContextForConsole = `
@@ -24,7 +24,7 @@ import {type ResourceScriptFile, ResourceScriptMapping} from './ResourceScriptMa
24
24
  export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObserver<SDK.DebuggerModel.DebuggerModel> {
25
25
  readonly resourceMapping: ResourceMapping;
26
26
  readonly #debuggerModelToData: Map<SDK.DebuggerModel.DebuggerModel, ModelData>;
27
- readonly #liveLocationPromises: Set<Promise<void|Location|StackTraceTopFrameLocation|null>>;
27
+ readonly #liveLocationPromises: Set<unknown>;
28
28
  readonly pluginManager: DebuggerLanguagePluginManager;
29
29
  readonly ignoreListManager: Workspace.IgnoreListManager.IgnoreListManager;
30
30
  readonly workspace: Workspace.Workspace.WorkspaceImpl;
@@ -154,11 +154,11 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
154
154
  * The promise returned by this function is resolved once all *currently*
155
155
  * pending LiveLocations are processed.
156
156
  */
157
- async pendingLiveLocationChangesPromise(): Promise<void|Location|StackTraceTopFrameLocation|null> {
157
+ async pendingLiveLocationChangesPromise(): Promise<void> {
158
158
  await Promise.all(this.#liveLocationPromises);
159
159
  }
160
160
 
161
- private recordLiveLocationChange(promise: Promise<void|Location|StackTraceTopFrameLocation|null>): void {
161
+ private recordLiveLocationChange(promise: Promise<unknown>): void {
162
162
  void promise.then(() => {
163
163
  this.#liveLocationPromises.delete(promise);
164
164
  });
@@ -166,10 +166,14 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
166
166
  }
167
167
 
168
168
  async updateLocations(script: SDK.Script.Script): Promise<void> {
169
- const updatePromises = [script.target()
170
- .model(StackTraceImpl.StackTraceModel.StackTraceModel)
171
- ?.scriptInfoChanged(script, this.#translateRawFrames.bind(this))];
169
+ const stackTraceUpdatePromise = script.target()
170
+ .model(StackTraceImpl.StackTraceModel.StackTraceModel)
171
+ ?.scriptInfoChanged(script, this.#translateRawFrames.bind(this));
172
+ if (stackTraceUpdatePromise) {
173
+ this.recordLiveLocationChange(stackTraceUpdatePromise);
174
+ }
172
175
 
176
+ const updatePromises = [stackTraceUpdatePromise];
173
177
  const modelData = this.#debuggerModelToData.get(script.debuggerModel);
174
178
  if (modelData) {
175
179
  const updatePromise = modelData.updateLocations(script);
@@ -184,7 +188,9 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
184
188
  Promise<StackTrace.StackTrace.StackTrace> {
185
189
  const model =
186
190
  target.model(StackTraceImpl.StackTraceModel.StackTraceModel) as StackTraceImpl.StackTraceModel.StackTraceModel;
187
- return await model.createFromProtocolRuntime(stackTrace, this.#translateRawFrames.bind(this));
191
+ const stackTracePromise = model.createFromProtocolRuntime(stackTrace, this.#translateRawFrames.bind(this));
192
+ this.recordLiveLocationChange(stackTracePromise);
193
+ return await stackTracePromise;
188
194
  }
189
195
 
190
196
  async createStackTraceFromDebuggerPaused(
@@ -192,7 +198,9 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
192
198
  target: SDK.Target.Target): Promise<StackTrace.StackTrace.DebuggableStackTrace> {
193
199
  const model =
194
200
  target.model(StackTraceImpl.StackTraceModel.StackTraceModel) as StackTraceImpl.StackTraceModel.StackTraceModel;
195
- return await model.createFromDebuggerPaused(pausedDetails, this.#translateRawFrames.bind(this));
201
+ const stackTracePromise = model.createFromDebuggerPaused(pausedDetails, this.#translateRawFrames.bind(this));
202
+ this.recordLiveLocationChange(stackTracePromise);
203
+ return await stackTracePromise;
196
204
  }
197
205
 
198
206
  async createLiveLocation(
@@ -125,20 +125,33 @@ export class ComputedStyleModel extends Common.ObjectWrapper.ObjectWrapper<Event
125
125
  }
126
126
 
127
127
  if (!this.computedStylePromise) {
128
- this.computedStylePromise = cssModel.getComputedStyle(nodeId).then(verifyOutdated.bind(this, elementNode));
128
+ this.computedStylePromise = cssModel.getComputedStyle(nodeId).then(style => {
129
+ return this.#validateNodeStyles(elementNode, style);
130
+ });
129
131
  }
130
132
 
131
133
  return await this.computedStylePromise;
134
+ }
132
135
 
133
- function verifyOutdated(
134
- this: ComputedStyleModel, elementNode: SDK.DOMModel.DOMNode, style: Map<string, string>|null): ComputedStyle|
135
- null {
136
- return elementNode === this.elementNode() && style ? new ComputedStyle(elementNode, style) :
137
- null as ComputedStyle | null;
136
+ /**
137
+ * Once we fetch the node's CSS styles, we validate them to ensure that the
138
+ * active Node didn't change between initiating the request to fetch the
139
+ * styles and the request returning. If it did, we discard these styles as
140
+ * outdated.
141
+ */
142
+ #validateNodeStyles(node: SDK.DOMModel.DOMNode, styles: Map<string, string>|null): ComputedStyle|null {
143
+ if (node === this.elementNode() && styles) {
144
+ return new ComputedStyle(node, styles);
138
145
  }
146
+ return null;
139
147
  }
140
148
 
141
- private async fetchMatchedCascade(): Promise<SDK.CSSMatchedStyles.CSSMatchedStyles|null> {
149
+ /**
150
+ * Fetches the CSS cascade for the node, including matched rules, inherited
151
+ * styles, and pseudo-elements.
152
+ * This allows determining which properties are active or overridden.
153
+ */
154
+ async fetchMatchedCascade(): Promise<SDK.CSSMatchedStyles.CSSMatchedStyles|null> {
142
155
  const node = this.node;
143
156
  if (!node || !this.cssModel()) {
144
157
  return null;
@@ -155,14 +168,6 @@ export class ComputedStyleModel extends Common.ObjectWrapper.ObjectWrapper<Event
155
168
  }
156
169
  return matchedStyles.node() === this.node ? matchedStyles : null;
157
170
  }
158
-
159
- async fetchAllComputedStyleInfo(): Promise<{
160
- computedStyle: ComputedStyle | null,
161
- matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles|null,
162
- }> {
163
- const [computedStyle, matchedStyles] = await Promise.all([this.fetchComputedStyle(), this.fetchMatchedCascade()]);
164
- return {computedStyle, matchedStyles};
165
- }
166
171
  }
167
172
 
168
173
  export const enum Events {
@@ -8,7 +8,6 @@ import * as Root from '../../core/root/root.js';
8
8
  let instance: Prototypes|null = null;
9
9
 
10
10
  export interface GreenDevSettings {
11
- inDevToolsFloaty: Common.Settings.Setting<boolean>;
12
11
  aiAnnotations: Common.Settings.Setting<boolean>;
13
12
  copyToGemini: Common.Settings.Setting<boolean>;
14
13
  }
@@ -36,9 +35,6 @@ export class Prototypes {
36
35
 
37
36
  settings(): Readonly<GreenDevSettings> {
38
37
  const settings = Common.Settings.Settings.instance();
39
- const inDevToolsFloaty =
40
- settings.createSetting('greendev-in-devtools-floaty-enabled', false, Common.Settings.SettingStorageType.LOCAL);
41
-
42
38
  const aiAnnotations = settings.createSetting(
43
39
  'greendev-ai-annotations-enabled',
44
40
  false,
@@ -47,6 +43,6 @@ export class Prototypes {
47
43
  const copyToGemini =
48
44
  settings.createSetting('greendev-copy-to-gemini-enabled', false, Common.Settings.SettingStorageType.LOCAL);
49
45
 
50
- return {inDevToolsFloaty, aiAnnotations, copyToGemini};
46
+ return {aiAnnotations, copyToGemini};
51
47
  }
52
48
  }
@@ -106,14 +106,6 @@ export class CorsIssue extends Issue<Protocol.Audits.CorsIssueDetails, IssueCode
106
106
 
107
107
  getDescription(): MarkdownIssueDescription|null {
108
108
  switch (getIssueCode(this.details())) {
109
- case IssueCode.INSECURE_LOCAL_NETWORK:
110
- return {
111
- file: 'corsInsecurePrivateNetwork.md',
112
- links: [{
113
- link: 'https://developer.chrome.com/blog/private-network-access-update',
114
- linkTitle: i18nString(UIStrings.corsLocalNetworkAccess),
115
- }],
116
- };
117
109
  case IssueCode.INVALID_HEADER_VALUES:
118
110
  return {
119
111
  file: 'corsInvalidHeaderValues.md',
@@ -202,11 +194,12 @@ export class CorsIssue extends Issue<Protocol.Audits.CorsIssueDetails, IssueCode
202
194
  linkTitle: i18nString(UIStrings.CORS),
203
195
  }],
204
196
  };
197
+ case IssueCode.INSECURE_LOCAL_NETWORK:
205
198
  case IssueCode.LOCAL_NETWORK_ACCESS_PERMISSION_DENIED:
206
199
  return {
207
200
  file: 'corsLocalNetworkAccessPermissionDenied.md',
208
201
  links: [{
209
- link: 'https://chromestatus.com/feature/5152728072060928',
202
+ link: 'https://developer.chrome.com/blog/local-network-access',
210
203
  linkTitle: i18nString(UIStrings.corsLocalNetworkAccess),
211
204
  }],
212
205
  };
@@ -1,4 +1,4 @@
1
- # Ensure that local network requests are compatible with upcoming restrictions
1
+ # Ensure that local network requests are compatible with restrictions
2
2
 
3
3
  A site requested a resource from a network that it could only access because of
4
4
  its users' privileged network position.
@@ -6,7 +6,7 @@ its users' privileged network position.
6
6
  These requests expose devices and servers to the internet, increasing the risk
7
7
  of a cross-site request forgery (CSRF) attack and/or information leakage.
8
8
 
9
- To mitigate these risks, Chrome will begin requiring the user grant explicit
9
+ To mitigate these risks, Chrome is requiring the user grant explicit
10
10
  permission before a site can make local network requests. Local network requests
11
11
  are those that go to either private IP addresses, .local domains, or loopback
12
12
  addresses. Additionally, Chrome will block local network requests (both
@@ -6627,6 +6627,22 @@ export const NativeFunctions = [
6627
6627
  name: "setFormControlRange",
6628
6628
  signatures: [["element","start","end"]]
6629
6629
  },
6630
+ {
6631
+ name: "getBoxQuads",
6632
+ signatures: [["?options"]]
6633
+ },
6634
+ {
6635
+ name: "convertQuadFromNode",
6636
+ signatures: [["quad","from","?options"]]
6637
+ },
6638
+ {
6639
+ name: "convertRectFromNode",
6640
+ signatures: [["rect","from","?options"]]
6641
+ },
6642
+ {
6643
+ name: "convertPointFromNode",
6644
+ signatures: [["point","from","?options"]]
6645
+ },
6630
6646
  {
6631
6647
  name: "MutationObserver",
6632
6648
  signatures: [["callback"]]
@@ -7369,6 +7385,10 @@ export const NativeFunctions = [
7369
7385
  name: "createScriptURL",
7370
7386
  signatures: [["input","...args"]]
7371
7387
  },
7388
+ {
7389
+ name: "createParserOptions",
7390
+ signatures: [["input"]]
7391
+ },
7372
7392
  {
7373
7393
  name: "URLPattern",
7374
7394
  signatures: [["?input","?options"],["input","baseURL","?options"]]