chrome-devtools-frontend 1.0.1544076 → 1.0.1547147

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 (178) hide show
  1. package/config/typescript/tsconfig.eslint.json +1 -0
  2. package/docs/styleguide/ux/styles.md +1 -1
  3. package/eslint.config.mjs +1 -1
  4. package/front_end/Images/src/arrow-down.svg +8 -1
  5. package/front_end/Images/src/arrow-up.svg +8 -1
  6. package/front_end/core/common/ParsedURL.ts +1 -1
  7. package/front_end/core/common/common.ts +0 -2
  8. package/front_end/core/host/AidaClient.ts +1 -1
  9. package/front_end/core/host/InspectorFrontendHostAPI.ts +0 -1
  10. package/front_end/core/host/UserMetrics.ts +0 -5
  11. package/front_end/core/platform/HostRuntime.ts +18 -0
  12. package/front_end/core/platform/KeyboardUtilities.ts +2 -2
  13. package/front_end/core/platform/StringUtilities.ts +1 -1
  14. package/front_end/core/platform/api/HostRuntime.ts +20 -0
  15. package/front_end/core/platform/api/api.ts +7 -0
  16. package/front_end/core/platform/browser/HostRuntime.ts +14 -0
  17. package/front_end/core/platform/browser/browser.ts +7 -0
  18. package/front_end/core/platform/node/HostRuntime.ts +13 -0
  19. package/front_end/core/platform/node/node.ts +7 -0
  20. package/front_end/core/platform/platform.ts +2 -2
  21. package/front_end/core/protocol_client/CDPConnection.ts +3 -3
  22. package/front_end/core/protocol_client/DevToolsCDPConnection.ts +2 -1
  23. package/front_end/core/sdk/CSSMetadata.ts +17 -5
  24. package/front_end/core/sdk/NetworkManager.ts +6 -8
  25. package/front_end/core/sdk/NetworkRequest.ts +4 -0
  26. package/front_end/core/sdk/SDKModel.ts +4 -2
  27. package/front_end/core/sdk/SourceMapScopesInfo.ts +141 -23
  28. package/front_end/core/sdk/Target.ts +5 -14
  29. package/front_end/core/sdk/TargetManager.ts +39 -18
  30. package/front_end/core/sdk/sdk-meta.ts +62 -0
  31. package/front_end/devtools_compatibility.js +0 -1
  32. package/front_end/entrypoints/main/MainImpl.ts +2 -2
  33. package/front_end/foundation/Universe.ts +2 -2
  34. package/front_end/generated/Deprecation.ts +11 -0
  35. package/front_end/generated/InspectorBackendCommands.ts +3 -6
  36. package/front_end/generated/SupportedCSSProperties.js +4 -25
  37. package/front_end/generated/protocol-mapping.d.ts +0 -15
  38. package/front_end/generated/protocol-proxy-api.d.ts +0 -11
  39. package/front_end/generated/protocol.ts +5 -36
  40. package/front_end/models/ai_assistance/AiConversation.ts +188 -0
  41. package/front_end/models/ai_assistance/AiHistoryStorage.ts +1 -172
  42. package/front_end/models/ai_assistance/ConversationHandler.ts +5 -5
  43. package/front_end/models/ai_assistance/agents/AiAgent.ts +1 -3
  44. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +6 -2
  45. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +1 -1
  46. package/front_end/models/ai_assistance/agents/StylingAgent.ts +3 -9
  47. package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
  48. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +313 -313
  49. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +8 -6
  50. package/front_end/models/ai_assistance/performance/AICallTree.snapshot.txt +33 -33
  51. package/front_end/models/ai_assistance/performance/AICallTree.ts +9 -3
  52. package/front_end/models/bindings/CSSWorkspaceBinding.ts +5 -3
  53. package/front_end/models/bindings/SASSSourceMapping.ts +6 -4
  54. package/front_end/models/cpu_profile/CPUProfileDataModel.ts +10 -7
  55. package/front_end/models/crux-manager/CrUXManager.ts +7 -4
  56. package/front_end/models/issues_manager/GenericIssue.ts +12 -9
  57. package/front_end/models/javascript_metadata/NativeFunctions.js +4 -0
  58. package/front_end/models/trace/handlers/SamplesHandler.ts +3 -0
  59. package/front_end/models/trace/helpers/Trace.ts +13 -0
  60. package/front_end/models/trace/types/TraceEvents.ts +2 -1
  61. package/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +29 -0
  62. package/front_end/models/workspace/IgnoreListManager.ts +1 -2
  63. package/front_end/models/workspace/UISourceCode.ts +50 -0
  64. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +11 -10
  65. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +8 -0
  66. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -2
  67. package/front_end/panels/ai_assistance/components/UserActionRow.ts +2 -1
  68. package/front_end/panels/animation/AnimationTimeline.ts +0 -8
  69. package/front_end/panels/application/ApplicationPanelSidebar.ts +6 -7
  70. package/front_end/panels/application/{components/FrameDetailsView.ts → FrameDetailsView.ts} +140 -171
  71. package/front_end/panels/application/{components/OriginTrialTreeView.ts → OriginTrialTreeView.ts} +9 -9
  72. package/front_end/panels/application/application.ts +4 -0
  73. package/front_end/panels/application/components/StackTrace.ts +89 -88
  74. package/front_end/panels/application/components/components.ts +2 -4
  75. package/front_end/panels/application/{components/frameDetailsReportView.css → frameDetailsReportView.css} +5 -1
  76. package/front_end/panels/common/AiCodeGenerationTeaser.ts +80 -0
  77. package/front_end/panels/common/BadgeNotification.ts +2 -1
  78. package/front_end/panels/common/DOMLinkifier.ts +7 -2
  79. package/front_end/panels/common/GdpSignUpDialog.ts +2 -1
  80. package/front_end/panels/common/common.ts +2 -1
  81. package/front_end/panels/console/ConsolePrompt.ts +3 -1
  82. package/front_end/panels/console/ConsoleViewport.ts +1 -2
  83. package/front_end/panels/elements/ElementIssueUtils.ts +2 -2
  84. package/front_end/panels/elements/ElementStatePaneWidget.ts +2 -1
  85. package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
  86. package/front_end/panels/elements/StylePropertyTreeElement.ts +23 -19
  87. package/front_end/panels/elements/StylesSidebarPane.ts +1 -1
  88. package/front_end/panels/elements/cssValueTraceView.css +1 -1
  89. package/front_end/panels/elements/elements-meta.ts +1 -22
  90. package/front_end/panels/explain/components/ConsoleInsight.ts +44 -57
  91. package/front_end/panels/explain/components/consoleInsight.css +46 -1
  92. package/front_end/panels/layer_viewer/LayerTreeOutline.ts +1 -2
  93. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +3 -6
  94. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +19 -0
  95. package/front_end/panels/network/RequestConditionsDrawer.ts +54 -24
  96. package/front_end/panels/network/networkLogView.css +11 -0
  97. package/front_end/panels/network/networkTimingTable.css +8 -6
  98. package/front_end/panels/network/requestConditionsDrawer.css +10 -1
  99. package/front_end/panels/profiler/ProfilesPanel.ts +1 -2
  100. package/front_end/panels/settings/FrameworkIgnoreListSettingsTab.ts +2 -1
  101. package/front_end/panels/settings/KeybindsSettingsTab.ts +20 -21
  102. package/front_end/panels/settings/SettingsScreen.ts +3 -2
  103. package/front_end/panels/sources/CoveragePlugin.ts +5 -5
  104. package/front_end/panels/sources/Plugin.ts +1 -1
  105. package/front_end/panels/sources/ProfilePlugin.ts +22 -14
  106. package/front_end/panels/sources/UISourceCodeFrame.ts +2 -1
  107. package/front_end/panels/sources/sources-meta.ts +0 -62
  108. package/front_end/panels/timeline/README.md +1 -9
  109. package/front_end/panels/timeline/ThreadAppender.ts +0 -7
  110. package/front_end/panels/timeline/TimelinePanel.ts +1 -1
  111. package/front_end/panels/timeline/TimelineUIUtils.ts +2 -0
  112. package/front_end/panels/timeline/components/ExportTraceOptions.ts +15 -1
  113. package/front_end/panels/timeline/components/LiveMetricsView.ts +51 -6
  114. package/front_end/panels/timeline/components/MetricCard.ts +2 -2
  115. package/front_end/panels/timeline/components/exportTraceOptions.css +11 -2
  116. package/front_end/panels/timeline/components/insights/NodeLink.ts +2 -3
  117. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -1
  118. package/front_end/panels/timeline/timeline-meta.ts +0 -10
  119. package/front_end/panels/timeline/timeline.ts +0 -2
  120. package/front_end/panels/whats_new/ReleaseNoteView.ts +2 -1
  121. package/front_end/panels/whats_new/WhatsNewImpl.ts +3 -2
  122. package/front_end/third_party/chromium/README.chromium +1 -1
  123. package/front_end/tsconfig.json +1 -0
  124. package/front_end/ui/components/buttons/Button.docs.ts +6 -5
  125. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +1 -0
  126. package/front_end/ui/components/snackbars/Snackbars.docs.ts +1 -1
  127. package/front_end/ui/components/spinners/Spinners.docs.ts +1 -1
  128. package/front_end/ui/components/survey_link/SurveyLink.docs.ts +2 -1
  129. package/front_end/ui/components/switch/Switch.docs.ts +1 -1
  130. package/front_end/ui/components/tooltips/Tooltip.docs.ts +3 -3
  131. package/front_end/ui/helpers/OpenInNewTab.ts +87 -0
  132. package/front_end/ui/helpers/helpers.ts +5 -0
  133. package/front_end/ui/legacy/ARIAUtils.ts +2 -2
  134. package/front_end/ui/legacy/ActionRegistration.ts +11 -0
  135. package/front_end/ui/legacy/ContextMenu.docs.ts +12 -11
  136. package/front_end/ui/legacy/RadioButton.docs.ts +1 -1
  137. package/front_end/ui/legacy/SelectMenu.docs.ts +1 -1
  138. package/front_end/ui/legacy/Slider.docs.ts +1 -1
  139. package/front_end/ui/legacy/SoftDropDown.ts +2 -2
  140. package/front_end/ui/legacy/TextPrompt.ts +3 -2
  141. package/front_end/ui/legacy/Treeoutline.ts +2 -1
  142. package/front_end/ui/legacy/UIUtils.ts +11 -43
  143. package/front_end/ui/legacy/Widget.ts +3 -2
  144. package/front_end/ui/legacy/XLink.ts +4 -4
  145. package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +2 -1
  146. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +2 -2
  147. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +144 -143
  148. package/front_end/ui/legacy/components/perf_ui/LineLevelProfile.ts +62 -39
  149. package/front_end/ui/legacy/components/perf_ui/OverviewGrid.ts +1 -1
  150. package/front_end/ui/legacy/components/perf_ui/TimelineGrid.ts +2 -2
  151. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +2 -7
  152. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +1 -2
  153. package/front_end/ui/legacy/components/utils/Linkifier.ts +2 -1
  154. package/front_end/ui/legacy/inspectorCommon.css +2 -2
  155. package/front_end/ui/legacy/legacy.ts +2 -0
  156. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  157. package/mcp/tsconfig.json +16 -0
  158. package/package.json +2 -2
  159. package/front_end/core/common/Linkifier.ts +0 -55
  160. package/front_end/panels/explain/components/consoleInsightSourcesList.css +0 -51
  161. package/front_end/panels/timeline/CLSLinkifier.ts +0 -58
  162. package/front_end/ui/components/docs/README.md +0 -6
  163. package/front_end/ui/components/docs/building-ui-documentation/ComponentEvents.md +0 -54
  164. package/front_end/ui/components/docs/building-ui-documentation/ComponentPerformance.md +0 -136
  165. package/front_end/ui/components/docs/building-ui-documentation/CreatingComponents.md +0 -242
  166. package/front_end/ui/components/docs/building-ui-documentation/README.md +0 -23
  167. package/front_end/ui/components/docs/building-ui-documentation/StylingComponents.md +0 -66
  168. package/front_end/ui/components/docs/building-ui-documentation/TestingComponents.md +0 -111
  169. package/front_end/ui/components/docs/component_docs.ts +0 -24
  170. package/front_end/ui/components/docs/component_docs_styles.css +0 -53
  171. package/front_end/ui/components/docs/create_breadcrumbs.ts +0 -44
  172. package/front_end/ui/components/docs/slider/basic.html +0 -20
  173. package/front_end/ui/components/docs/switch/basic.html +0 -20
  174. /package/front_end/models/issues_manager/descriptions/{genericFormAriaLabelledByToNonExistingId.md → genericFormAriaLabelledByToNonExistingIdError.md} +0 -0
  175. /package/front_end/models/issues_manager/descriptions/{genericFormLabelHasNeitherForNorNestedInput.md → genericFormLabelHasNeitherForNorNestedInputError.md} +0 -0
  176. /package/front_end/panels/application/{components/originTrialTokenRows.css → originTrialTokenRows.css} +0 -0
  177. /package/front_end/panels/application/{components/originTrialTreeView.css → originTrialTreeView.css} +0 -0
  178. /package/front_end/{core/platform → ui/legacy}/DOMUtilities.ts +0 -0
@@ -0,0 +1,188 @@
1
+ // Copyright 2024 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import {type ContextDetail, type ResponseData, ResponseType} from './agents/AiAgent.js';
6
+ import {AiHistoryStorage, type ConversationType, type SerializedConversation} from './AiHistoryStorage.js';
7
+
8
+ export const NOT_FOUND_IMAGE_DATA = '';
9
+ const MAX_TITLE_LENGTH = 80;
10
+
11
+ export class AiConversation {
12
+ readonly id: string;
13
+ type: ConversationType;
14
+ #isReadOnly: boolean;
15
+ readonly history: ResponseData[];
16
+ #isExternal: boolean;
17
+
18
+ static generateContextDetailsMarkdown(details: ContextDetail[]): string {
19
+ const detailsMarkdown: string[] = [];
20
+ for (const detail of details) {
21
+ const text = `\`\`\`\`${detail.codeLang || ''}\n${detail.text.trim()}\n\`\`\`\``;
22
+ detailsMarkdown.push(`**${detail.title}:**\n${text}`);
23
+ }
24
+ return detailsMarkdown.join('\n\n');
25
+ }
26
+
27
+ constructor(
28
+ type: ConversationType,
29
+ data: ResponseData[] = [],
30
+ id: string = crypto.randomUUID(),
31
+ isReadOnly = true,
32
+ isExternal = false,
33
+ ) {
34
+ this.type = type;
35
+ this.id = id;
36
+ this.#isReadOnly = isReadOnly;
37
+ this.#isExternal = isExternal;
38
+ this.history = this.#reconstructHistory(data);
39
+ }
40
+
41
+ get isReadOnly(): boolean {
42
+ return this.#isReadOnly;
43
+ }
44
+
45
+ get title(): string|undefined {
46
+ const query = this.history.find(response => response.type === ResponseType.USER_QUERY)?.query;
47
+
48
+ if (!query) {
49
+ return;
50
+ }
51
+
52
+ if (this.#isExternal) {
53
+ return `[External] ${query.substring(0, MAX_TITLE_LENGTH - 11)}${
54
+ query.length > MAX_TITLE_LENGTH - 11 ? '…' : ''}`;
55
+ }
56
+ return `${query.substring(0, MAX_TITLE_LENGTH)}${query.length > MAX_TITLE_LENGTH ? '…' : ''}`;
57
+ }
58
+
59
+ get isEmpty(): boolean {
60
+ return this.history.length === 0;
61
+ }
62
+
63
+ #reconstructHistory(historyWithoutImages: ResponseData[]): ResponseData[] {
64
+ const imageHistory = AiHistoryStorage.instance().getImageHistory();
65
+ if (imageHistory && imageHistory.length > 0) {
66
+ const history: ResponseData[] = [];
67
+ for (const data of historyWithoutImages) {
68
+ if (data.type === ResponseType.USER_QUERY && data.imageId) {
69
+ const image = imageHistory.find(item => item.id === data.imageId);
70
+ const inlineData = image ? {data: image.data, mimeType: image.mimeType} :
71
+ {data: NOT_FOUND_IMAGE_DATA, mimeType: 'image/jpeg'};
72
+ history.push({...data, imageInput: {inlineData}});
73
+ } else {
74
+ history.push(data);
75
+ }
76
+ }
77
+ return history;
78
+ }
79
+ return historyWithoutImages;
80
+ }
81
+
82
+ getConversationMarkdown(): string {
83
+ const contentParts: string[] = [];
84
+ contentParts.push(
85
+ '# Exported Chat from Chrome DevTools AI Assistance\n\n' +
86
+ `**Export Timestamp (UTC):** ${new Date().toISOString()}\n\n` +
87
+ '---',
88
+ );
89
+ for (const item of this.history) {
90
+ switch (item.type) {
91
+ case ResponseType.USER_QUERY: {
92
+ contentParts.push(`## User\n\n${item.query}`);
93
+ if (item.imageInput) {
94
+ contentParts.push('User attached an image');
95
+ }
96
+ contentParts.push('## AI');
97
+ break;
98
+ }
99
+ case ResponseType.CONTEXT: {
100
+ contentParts.push(`### ${item.title}`);
101
+ if (item.details && item.details.length > 0) {
102
+ contentParts.push(AiConversation.generateContextDetailsMarkdown(item.details));
103
+ }
104
+ break;
105
+ }
106
+ case ResponseType.TITLE: {
107
+ contentParts.push(`### ${item.title}`);
108
+ break;
109
+ }
110
+ case ResponseType.THOUGHT: {
111
+ contentParts.push(`${item.thought}`);
112
+ break;
113
+ }
114
+ case ResponseType.ACTION: {
115
+ // We want to export only actions with output field
116
+ if (!item.output) {
117
+ break;
118
+ }
119
+ if (item.code) {
120
+ contentParts.push(`**Code executed:**\n\`\`\`\n${item.code.trim()}\n\`\`\``);
121
+ }
122
+ contentParts.push(`**Data returned:**\n\`\`\`\n${item.output}\n\`\`\``);
123
+ break;
124
+ }
125
+ case ResponseType.ANSWER: {
126
+ if (item.complete) {
127
+ contentParts.push(`### Answer\n\n${item.text.trim()}`);
128
+ }
129
+ break;
130
+ }
131
+ }
132
+ }
133
+ return contentParts.join('\n\n');
134
+ }
135
+
136
+ archiveConversation(): void {
137
+ this.#isReadOnly = true;
138
+ }
139
+
140
+ async addHistoryItem(item: ResponseData): Promise<void> {
141
+ this.history.push(item);
142
+ await AiHistoryStorage.instance().upsertHistoryEntry(this.serialize());
143
+ if (item.type === ResponseType.USER_QUERY) {
144
+ if (item.imageId && item.imageInput && 'inlineData' in item.imageInput) {
145
+ const inlineData = item.imageInput.inlineData;
146
+ await AiHistoryStorage.instance().upsertImage({
147
+ id: item.imageId,
148
+ data: inlineData.data,
149
+ mimeType: inlineData.mimeType,
150
+ });
151
+ }
152
+ }
153
+ }
154
+
155
+ serialize(): SerializedConversation {
156
+ return {
157
+ id: this.id,
158
+ history: this.history.map(item => {
159
+ if (item.type === ResponseType.USER_QUERY) {
160
+ return {...item, imageInput: undefined};
161
+ }
162
+ // Remove the `confirm()`-function because `structuredClone()` throws on functions
163
+ if (item.type === ResponseType.SIDE_EFFECT) {
164
+ return {...item, confirm: undefined};
165
+ }
166
+ return item;
167
+ }),
168
+ type: this.type,
169
+ isExternal: this.#isExternal,
170
+ };
171
+ }
172
+
173
+ static fromSerializedConversation(serializedConversation: SerializedConversation): AiConversation {
174
+ const history = serializedConversation.history.map(entry => {
175
+ if (entry.type === ResponseType.SIDE_EFFECT) {
176
+ return {...entry, confirm: () => {}};
177
+ }
178
+ return entry;
179
+ });
180
+ return new AiConversation(
181
+ serializedConversation.type,
182
+ history,
183
+ serializedConversation.id,
184
+ true,
185
+ serializedConversation.isExternal,
186
+ );
187
+ }
188
+ }
@@ -5,9 +5,7 @@
5
5
 
6
6
  import * as Common from '../../core/common/common.js';
7
7
 
8
- import {type ContextDetail, type ResponseData, ResponseType, type SerializedResponseData} from './agents/AiAgent.js';
9
-
10
- const MAX_TITLE_LENGTH = 80;
8
+ import {ResponseType, type SerializedResponseData} from './agents/AiAgent.js';
11
9
 
12
10
  export const enum ConversationType {
13
11
  STYLING = 'freestyler',
@@ -16,8 +14,6 @@ export const enum ConversationType {
16
14
  PERFORMANCE = 'drjones-performance-full',
17
15
  }
18
16
 
19
- export const NOT_FOUND_IMAGE_DATA = '';
20
-
21
17
  export interface SerializedConversation {
22
18
  id: string;
23
19
  type: ConversationType;
@@ -35,173 +31,6 @@ export interface SerializedImage {
35
31
  data: string;
36
32
  }
37
33
 
38
- export class Conversation {
39
- readonly id: string;
40
- readonly type: ConversationType;
41
- #isReadOnly: boolean;
42
- readonly history: ResponseData[];
43
- #isExternal: boolean;
44
-
45
- static generateContextDetailsMarkdown(details: ContextDetail[]): string {
46
- const detailsMarkdown: string[] = [];
47
- for (const detail of details) {
48
- const text = `\`\`\`\`${detail.codeLang || ''}\n${detail.text.trim()}\n\`\`\`\``;
49
- detailsMarkdown.push(`**${detail.title}:**\n${text}`);
50
- }
51
- return detailsMarkdown.join('\n\n');
52
- }
53
-
54
- constructor(
55
- type: ConversationType, data: ResponseData[] = [], id: string = crypto.randomUUID(), isReadOnly = true,
56
- isExternal = false) {
57
- this.type = type;
58
- this.id = id;
59
- this.#isReadOnly = isReadOnly;
60
- this.#isExternal = isExternal;
61
- this.history = this.#reconstructHistory(data);
62
- }
63
-
64
- get isReadOnly(): boolean {
65
- return this.#isReadOnly;
66
- }
67
-
68
- get title(): string|undefined {
69
- const query = this.history.find(response => response.type === ResponseType.USER_QUERY)?.query;
70
-
71
- if (!query) {
72
- return;
73
- }
74
-
75
- if (this.#isExternal) {
76
- return `[External] ${query.substring(0, MAX_TITLE_LENGTH - 11)}${
77
- query.length > MAX_TITLE_LENGTH - 11 ? '…' : ''}`;
78
- }
79
- return `${query.substring(0, MAX_TITLE_LENGTH)}${query.length > MAX_TITLE_LENGTH ? '…' : ''}`;
80
- }
81
-
82
- get isEmpty(): boolean {
83
- return this.history.length === 0;
84
- }
85
-
86
- #reconstructHistory(historyWithoutImages: ResponseData[]): ResponseData[] {
87
- const imageHistory = AiHistoryStorage.instance().getImageHistory();
88
- if (imageHistory && imageHistory.length > 0) {
89
- const history: ResponseData[] = [];
90
- for (const data of historyWithoutImages) {
91
- if (data.type === ResponseType.USER_QUERY && data.imageId) {
92
- const image = imageHistory.find(item => item.id === data.imageId);
93
- const inlineData = image ? {data: image.data, mimeType: image.mimeType} :
94
- {data: NOT_FOUND_IMAGE_DATA, mimeType: 'image/jpeg'};
95
- history.push({...data, imageInput: {inlineData}});
96
- } else {
97
- history.push(data);
98
- }
99
- }
100
- return history;
101
- }
102
- return historyWithoutImages;
103
- }
104
-
105
- getConversationMarkdown(): string {
106
- const contentParts: string[] = [];
107
- contentParts.push(
108
- '# Exported Chat from Chrome DevTools AI Assistance\n\n' +
109
- `**Export Timestamp (UTC):** ${new Date().toISOString()}\n\n` +
110
- '---',
111
- );
112
- for (const item of this.history) {
113
- switch (item.type) {
114
- case ResponseType.USER_QUERY: {
115
- contentParts.push(`## User\n\n${item.query}`);
116
- if (item.imageInput) {
117
- contentParts.push('User attached an image');
118
- }
119
- contentParts.push('## AI');
120
- break;
121
- }
122
- case ResponseType.CONTEXT: {
123
- contentParts.push(`### ${item.title}`);
124
- if (item.details && item.details.length > 0) {
125
- contentParts.push(Conversation.generateContextDetailsMarkdown(item.details));
126
- }
127
- break;
128
- }
129
- case ResponseType.TITLE: {
130
- contentParts.push(`### ${item.title}`);
131
- break;
132
- }
133
- case ResponseType.THOUGHT: {
134
- contentParts.push(`${item.thought}`);
135
- break;
136
- }
137
- case ResponseType.ACTION: {
138
- // We want to export only actions with output field
139
- if (!item.output) {
140
- break;
141
- }
142
- if (item.code) {
143
- contentParts.push(`**Code executed:**\n\`\`\`\n${item.code.trim()}\n\`\`\``);
144
- }
145
- contentParts.push(`**Data returned:**\n\`\`\`\n${item.output}\n\`\`\``);
146
- break;
147
- }
148
- case ResponseType.ANSWER: {
149
- if (item.complete) {
150
- contentParts.push(`### Answer\n\n${item.text.trim()}`);
151
- }
152
- break;
153
- }
154
- }
155
- }
156
- return contentParts.join('\n\n');
157
- }
158
-
159
- archiveConversation(): void {
160
- this.#isReadOnly = true;
161
- }
162
-
163
- async addHistoryItem(item: ResponseData): Promise<void> {
164
- this.history.push(item);
165
- await AiHistoryStorage.instance().upsertHistoryEntry(this.serialize());
166
- if (item.type === ResponseType.USER_QUERY) {
167
- if (item.imageId && item.imageInput && 'inlineData' in item.imageInput) {
168
- const inlineData = item.imageInput.inlineData;
169
- await AiHistoryStorage.instance().upsertImage(
170
- {id: item.imageId, data: inlineData.data, mimeType: inlineData.mimeType});
171
- }
172
- }
173
- }
174
-
175
- serialize(): SerializedConversation {
176
- return {
177
- id: this.id,
178
- history: this.history.map(item => {
179
- if (item.type === ResponseType.USER_QUERY) {
180
- return {...item, imageInput: undefined};
181
- }
182
- // Remove the `confirm()`-function because `structuredClone()` throws on functions
183
- if (item.type === ResponseType.SIDE_EFFECT) {
184
- return {...item, confirm: undefined};
185
- }
186
- return item;
187
- }),
188
- type: this.type,
189
- isExternal: this.#isExternal,
190
- };
191
- }
192
-
193
- static fromSerializedConversation(serializedConversation: SerializedConversation): Conversation {
194
- const history = serializedConversation.history.map(entry => {
195
- if (entry.type === ResponseType.SIDE_EFFECT) {
196
- return {...entry, confirm: () => {}};
197
- }
198
- return entry;
199
- });
200
- return new Conversation(
201
- serializedConversation.type, history, serializedConversation.id, true, serializedConversation.isExternal);
202
- }
203
- }
204
-
205
34
  let instance: AiHistoryStorage|null = null;
206
35
 
207
36
  const DEFAULT_MAX_STORAGE_SIZE = 50 * 1024 * 1024;
@@ -21,8 +21,8 @@ import {FileAgent} from './agents/FileAgent.js';
21
21
  import {NetworkAgent, RequestContext} from './agents/NetworkAgent.js';
22
22
  import {PerformanceAgent, type PerformanceTraceContext} from './agents/PerformanceAgent.js';
23
23
  import {NodeContext, StylingAgent} from './agents/StylingAgent.js';
24
+ import {AiConversation} from './AiConversation.js';
24
25
  import {
25
- Conversation,
26
26
  ConversationType,
27
27
  } from './AiHistoryStorage.js';
28
28
  import {getDisabledReasons} from './AiUtils.js';
@@ -42,7 +42,7 @@ interface ExternalNetworkRequestParameters {
42
42
 
43
43
  export interface ExternalPerformanceAIConversationData {
44
44
  conversationHandler: ConversationHandler;
45
- conversation: Conversation;
45
+ conversation: AiConversation;
46
46
  agent: AiAgent<unknown>;
47
47
  selected: PerformanceTraceContext;
48
48
  }
@@ -207,7 +207,7 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
207
207
 
208
208
  async *
209
209
  handleConversationWithHistory(
210
- items: AsyncIterable<ResponseData, void, void>, conversation: Conversation|undefined):
210
+ items: AsyncIterable<ResponseData, void, void>, conversation: AiConversation|undefined):
211
211
  AsyncGenerator<ResponseData, void, void> {
212
212
  for await (const data of items) {
213
213
  // We don't want to save partial responses to the conversation history.
@@ -225,7 +225,7 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
225
225
  selected: NodeContext|PerformanceTraceContext|RequestContext|null,
226
226
  }): AsyncGenerator<ExternalRequestResponse, ExternalRequestResponse> {
227
227
  const {conversationType, aiAgent, prompt, selected} = opts;
228
- const conversation = new Conversation(
228
+ const conversation = new AiConversation(
229
229
  conversationType,
230
230
  [],
231
231
  aiAgent.id,
@@ -236,7 +236,7 @@ export class ConversationHandler extends Common.ObjectWrapper.ObjectWrapper<Even
236
236
  }
237
237
 
238
238
  async * #doExternalConversation(opts: {
239
- conversation: Conversation,
239
+ conversation: AiConversation,
240
240
  aiAgent: AiAgent<unknown>,
241
241
  prompt: string,
242
242
  selected: NodeContext|PerformanceTraceContext|RequestContext|null,
@@ -682,9 +682,7 @@ export abstract class AiAgent<T> {
682
682
 
683
683
  yield {
684
684
  type: ResponseType.SIDE_EFFECT,
685
- confirm: (result: boolean) => {
686
- sideEffectConfirmationPromiseWithResolvers.resolve(result);
687
- },
685
+ confirm: sideEffectConfirmationPromiseWithResolvers.resolve,
688
686
  };
689
687
 
690
688
  const approvedRun = await sideEffectConfirmationPromiseWithResolvers.promise;
@@ -492,7 +492,7 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
492
492
  this.#addFacts(options.selected);
493
493
  }
494
494
 
495
- return yield* super.run(initialQuery, options);
495
+ yield* super.run(initialQuery, options);
496
496
  }
497
497
 
498
498
  #createFactForTraceSummary(): void {
@@ -870,7 +870,11 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
870
870
  }
871
871
 
872
872
  const tree = AICallTree.fromEvent(event, parsedTrace);
873
- const callTree = tree ? this.#formatter.formatCallTree(tree) : 'No call tree found';
873
+ if (!tree) {
874
+ return {error: 'No call tree found'};
875
+ }
876
+
877
+ const callTree = this.#formatter.formatCallTree(tree);
874
878
 
875
879
  const key = `getDetailedCallTree(${args.eventKey})`;
876
880
  this.#cacheFunctionResult(focus, key, callTree);
@@ -119,7 +119,7 @@ Content:
119
119
  "metadata": {
120
120
  "disable_user_content_logging": false,
121
121
  "string_session_id": "sessionId",
122
- "user_tier": 2,
122
+ "user_tier": 3,
123
123
  "client_version": "unit_test+function_calling"
124
124
  },
125
125
  "functionality_type": 5,
@@ -327,11 +327,8 @@ export class StylingAgent extends AiAgent<SDK.DOMModel.DOMNode> {
327
327
  action: `getStyles(${JSON.stringify(params.elements)}, ${JSON.stringify(params.styleProperties)})`,
328
328
  };
329
329
  },
330
- handler: async (
331
- params,
332
- options,
333
- ) => {
334
- return await this.getStyles(params.elements, params.styleProperties, options);
330
+ handler: async params => {
331
+ return await this.getStyles(params.elements, params.styleProperties);
335
332
  },
336
333
  });
337
334
 
@@ -583,10 +580,7 @@ const data = {
583
580
  return this.context?.getItem() ?? null;
584
581
  }
585
582
 
586
- async getStyles(elements: string[], properties: string[], _options?: {
587
- signal?: AbortSignal,
588
- approved?: boolean,
589
- }): Promise<FunctionCallHandlerResult<unknown>> {
583
+ async getStyles(elements: string[], properties: string[]): Promise<FunctionCallHandlerResult<unknown>> {
590
584
  const result:
591
585
  Record<string, {computed: Record<string, string|undefined>, authored: Record<string, string|undefined>}> = {};
592
586
  for (const uid of elements) {
@@ -10,6 +10,7 @@ import * as PatchAgent from './agents/PatchAgent.js';
10
10
  import * as PerformanceAgent from './agents/PerformanceAgent.js';
11
11
  import * as PerformanceAnnotationsAgent from './agents/PerformanceAnnotationsAgent.js';
12
12
  import * as StylingAgent from './agents/StylingAgent.js';
13
+ import * as AiConversation from './AiConversation.js';
13
14
  import * as AiHistoryStorage from './AiHistoryStorage.js';
14
15
  import * as AiUtils from './AiUtils.js';
15
16
  import * as BuiltInAi from './BuiltInAi.js';
@@ -33,6 +34,7 @@ export {
33
34
  AiAgent,
34
35
  AICallTree,
35
36
  AIContext,
37
+ AiConversation,
36
38
  AiHistoryStorage,
37
39
  AIQueries,
38
40
  AiUtils,