chrome-devtools-frontend 1.0.1533544 → 1.0.1534717
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.
- package/docs/contributing/infrastructure.md +32 -0
- package/front_end/Images/src/justify-content-stretch.svg +4 -0
- package/front_end/core/host/InspectorFrontendHost.ts +1 -1
- package/front_end/core/host/InspectorFrontendHostAPI.ts +33 -29
- package/front_end/core/host/UserMetrics.ts +26 -1
- package/front_end/core/protocol_client/CDPConnection.ts +39 -0
- package/front_end/core/protocol_client/InspectorBackend.ts +0 -98
- package/front_end/core/root/Runtime.ts +1 -0
- package/front_end/core/sdk/CSSMatchedStyles.ts +2 -2
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +18 -8
- package/front_end/core/sdk/NetworkManager.ts +0 -16
- package/front_end/core/sdk/RehydratingConnection.ts +1 -1
- package/front_end/devtools_compatibility.js +202 -7
- package/front_end/generated/protocol-mapping.d.ts +3 -0
- package/front_end/models/ai_assistance/BuiltInAi.ts +141 -56
- package/front_end/panels/common/BadgeNotification.ts +1 -3
- package/front_end/panels/console/ConsoleInsightTeaser.ts +76 -60
- package/front_end/panels/console/ConsoleViewMessage.ts +4 -2
- package/front_end/panels/console/consoleInsightTeaser.css +4 -0
- package/front_end/panels/console/consoleView.css +1 -1
- package/front_end/panels/elements/StylePropertyTreeElement.ts +46 -8
- package/front_end/panels/elements/components/CSSPropertyIconResolver.ts +1 -0
- package/front_end/panels/elements/components/StylePropertyEditor.ts +65 -0
- package/front_end/panels/network/components/ResponseHeaderSection.ts +1 -2
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.js +4 -4
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +10 -10
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.js +4 -4
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/package.json +1 -1
- package/front_end/third_party/puppeteer/package/src/api/ElementHandle.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/api/Frame.ts +4 -4
- package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +8 -1
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/components/dialogs/Dialog.ts +7 -17
- package/front_end/ui/components/docs/style_property_editor/masonry.html +21 -0
- package/front_end/ui/components/docs/style_property_editor/masonry.ts +50 -0
- package/front_end/ui/components/text_editor/TextEditor.ts +2 -3
- package/front_end/ui/components/text_editor/config.ts +1 -3
- package/front_end/ui/legacy/UIUtils.ts +5 -0
- package/front_end/ui/legacy/components/inline_editor/CSSAngle.ts +1 -1
- package/front_end/ui/legacy/components/perf_ui/BrickBreaker.ts +2 -2
- package/front_end/ui/legacy/components/perf_ui/Font.ts +1 -14
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
- package/inspector_overlay/testing/InspectorOverlayHelpers.ts +2 -10
- package/package.json +1 -1
- package/front_end/services/window_bounds/WindowBoundsService.ts +0 -27
- package/front_end/services/window_bounds/window_bounds.ts +0 -9
|
@@ -53,9 +53,19 @@
|
|
|
53
53
|
_addExtensionCallback = null;
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
|
-
* @type {
|
|
56
|
+
* @type {Promise<string>}
|
|
57
57
|
*/
|
|
58
|
-
|
|
58
|
+
_initialTargetIdPromise;
|
|
59
|
+
/**
|
|
60
|
+
* @type {(param:string) => void}
|
|
61
|
+
*/
|
|
62
|
+
_setInitialTargetId;
|
|
63
|
+
|
|
64
|
+
constructor() {
|
|
65
|
+
this._initialTargetIdPromise = new Promise(resolve => {
|
|
66
|
+
this._setInitialTargetId = resolve;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
59
69
|
|
|
60
70
|
/**
|
|
61
71
|
* @param id
|
|
@@ -337,7 +347,7 @@
|
|
|
337
347
|
* @param targetId {string}
|
|
338
348
|
*/
|
|
339
349
|
setInitialTargetId(targetId) {
|
|
340
|
-
this.
|
|
350
|
+
this._setInitialTargetId(targetId);
|
|
341
351
|
}
|
|
342
352
|
|
|
343
353
|
/**
|
|
@@ -433,7 +443,8 @@
|
|
|
433
443
|
TimelineNavigationSettingState: 'DevTools.TimelineNavigationSettingState',
|
|
434
444
|
SyncSetting: 'DevTools.SyncSetting',
|
|
435
445
|
SwatchActivated: 'DevTools.SwatchActivated',
|
|
436
|
-
AnimationPlaybackRateChanged: 'DevTools.AnimationPlaybackRateChanged'
|
|
446
|
+
AnimationPlaybackRateChanged: 'DevTools.AnimationPlaybackRateChanged',
|
|
447
|
+
BuiltInAiAvailability: 'DevTools.BuiltInAiAvailability'
|
|
437
448
|
// LINT.ThenChange(/front_end/core/host/InspectorFrontendHostAPI.ts:EnumeratedHistogram)
|
|
438
449
|
};
|
|
439
450
|
|
|
@@ -448,6 +459,34 @@
|
|
|
448
459
|
*/
|
|
449
460
|
events;
|
|
450
461
|
|
|
462
|
+
/**
|
|
463
|
+
* @returns
|
|
464
|
+
*/
|
|
465
|
+
getSelectionBackgroundColor() {
|
|
466
|
+
return '#6e86ff';
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* @returns
|
|
471
|
+
*/
|
|
472
|
+
getSelectionForegroundColor() {
|
|
473
|
+
return '#ffffff';
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* @returns
|
|
478
|
+
*/
|
|
479
|
+
getInactiveSelectionBackgroundColor() {
|
|
480
|
+
return '#c9c8c8';
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* @returns
|
|
485
|
+
*/
|
|
486
|
+
getInactiveSelectionForegroundColor() {
|
|
487
|
+
return '#323232';
|
|
488
|
+
}
|
|
489
|
+
|
|
451
490
|
/**
|
|
452
491
|
* @returns
|
|
453
492
|
*/
|
|
@@ -982,12 +1021,21 @@
|
|
|
982
1021
|
}
|
|
983
1022
|
|
|
984
1023
|
// Backward-compatible methods below this line --------------------------------------------
|
|
1024
|
+
/**
|
|
1025
|
+
* Support for legacy front-ends (<M65).
|
|
1026
|
+
* @returns
|
|
1027
|
+
*/
|
|
1028
|
+
isUnderTest() {
|
|
1029
|
+
return false;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
// Backward-compatible methods end before line --------------------------------------------
|
|
985
1033
|
|
|
986
1034
|
/**
|
|
987
1035
|
* @returns
|
|
988
1036
|
*/
|
|
989
1037
|
initialTargetId() {
|
|
990
|
-
return DevToolsAPI.
|
|
1038
|
+
return DevToolsAPI._initialTargetIdPromise;
|
|
991
1039
|
}
|
|
992
1040
|
|
|
993
1041
|
/**
|
|
@@ -1106,8 +1154,155 @@
|
|
|
1106
1154
|
}
|
|
1107
1155
|
|
|
1108
1156
|
function installBackwardsCompatibility() {
|
|
1109
|
-
|
|
1110
|
-
|
|
1157
|
+
const majorVersion = getRemoteMajorVersion();
|
|
1158
|
+
if (!majorVersion) {
|
|
1159
|
+
return;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
/** @type {!Array<string>} */
|
|
1163
|
+
const styleRules = [];
|
|
1164
|
+
// Shadow DOM V0 polyfill
|
|
1165
|
+
if (majorVersion <= 73 && !Element.prototype.createShadowRoot) {
|
|
1166
|
+
Element.prototype.createShadowRoot = function() {
|
|
1167
|
+
try {
|
|
1168
|
+
return this.attachShadow({mode: 'open'});
|
|
1169
|
+
} catch {
|
|
1170
|
+
// some elements we use to add shadow roots can no
|
|
1171
|
+
// longer have shadow roots.
|
|
1172
|
+
const fakeShadowHost = document.createElement('span');
|
|
1173
|
+
this.appendChild(fakeShadowHost);
|
|
1174
|
+
fakeShadowHost.className = 'fake-shadow-host';
|
|
1175
|
+
return fakeShadowHost.createShadowRoot();
|
|
1176
|
+
}
|
|
1177
|
+
};
|
|
1178
|
+
|
|
1179
|
+
const origAdd = DOMTokenList.prototype.add;
|
|
1180
|
+
DOMTokenList.prototype.add = function(...tokens) {
|
|
1181
|
+
if (tokens[0].startsWith('insertion-point') || tokens[0].startsWith('tabbed-pane-header')) {
|
|
1182
|
+
this._myElement.slot = '.' + tokens[0];
|
|
1183
|
+
}
|
|
1184
|
+
return origAdd.apply(this, tokens);
|
|
1185
|
+
};
|
|
1186
|
+
|
|
1187
|
+
const origCreateElement = Document.prototype.createElement;
|
|
1188
|
+
Document.prototype.createElement = function(tagName, ...rest) {
|
|
1189
|
+
if (tagName === 'content') {
|
|
1190
|
+
tagName = 'slot';
|
|
1191
|
+
}
|
|
1192
|
+
const element = origCreateElement.call(this, tagName, ...rest);
|
|
1193
|
+
element.classList._myElement = element;
|
|
1194
|
+
return element;
|
|
1195
|
+
};
|
|
1196
|
+
|
|
1197
|
+
Object.defineProperty(HTMLSlotElement.prototype, 'select', {
|
|
1198
|
+
set(selector) {
|
|
1199
|
+
this.name = selector;
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
// Custom Elements V0 polyfill
|
|
1205
|
+
if (majorVersion <= 73 && !Document.prototype.hasOwnProperty('registerElement')) {
|
|
1206
|
+
const fakeRegistry = new Map();
|
|
1207
|
+
Document.prototype.registerElement = function(typeExtension, options) {
|
|
1208
|
+
const {prototype, extends: localName} = options;
|
|
1209
|
+
const document = this;
|
|
1210
|
+
const callback = function() {
|
|
1211
|
+
const element = document.createElement(localName || typeExtension);
|
|
1212
|
+
const skip = new Set(['constructor', '__proto__']);
|
|
1213
|
+
for (const key of Object.keys(Object.getOwnPropertyDescriptors(prototype.__proto__ || {}))) {
|
|
1214
|
+
if (skip.has(key)) {
|
|
1215
|
+
continue;
|
|
1216
|
+
}
|
|
1217
|
+
element[key] = prototype[key];
|
|
1218
|
+
}
|
|
1219
|
+
element.setAttribute('is', typeExtension);
|
|
1220
|
+
if (element['createdCallback']) {
|
|
1221
|
+
element['createdCallback']();
|
|
1222
|
+
}
|
|
1223
|
+
return element;
|
|
1224
|
+
};
|
|
1225
|
+
fakeRegistry.set(typeExtension, callback);
|
|
1226
|
+
return callback;
|
|
1227
|
+
};
|
|
1228
|
+
|
|
1229
|
+
const origCreateElement = Document.prototype.createElement;
|
|
1230
|
+
Document.prototype.createElement = function(tagName, fakeCustomElementType) {
|
|
1231
|
+
const fakeConstructor = fakeRegistry.get(fakeCustomElementType);
|
|
1232
|
+
if (fakeConstructor) {
|
|
1233
|
+
return fakeConstructor();
|
|
1234
|
+
}
|
|
1235
|
+
return origCreateElement.call(this, tagName, fakeCustomElementType);
|
|
1236
|
+
};
|
|
1237
|
+
|
|
1238
|
+
// DevTools front-ends mistakenly assume that
|
|
1239
|
+
// classList.toggle('a', undefined) works as
|
|
1240
|
+
// classList.toggle('a', false) rather than as
|
|
1241
|
+
// classList.toggle('a');
|
|
1242
|
+
const originalDOMTokenListToggle = DOMTokenList.prototype.toggle;
|
|
1243
|
+
DOMTokenList.prototype.toggle = function(token, force) {
|
|
1244
|
+
if (arguments.length === 1) {
|
|
1245
|
+
force = !this.contains(token);
|
|
1246
|
+
}
|
|
1247
|
+
return originalDOMTokenListToggle.call(this, token, Boolean(force));
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
if (majorVersion <= 66) {
|
|
1252
|
+
/** @type {(!function(number, number):Element|undefined)} */
|
|
1253
|
+
ShadowRoot.prototype.__originalShadowRootElementFromPoint;
|
|
1254
|
+
|
|
1255
|
+
if (!ShadowRoot.prototype.__originalShadowRootElementFromPoint) {
|
|
1256
|
+
ShadowRoot.prototype.__originalShadowRootElementFromPoint = ShadowRoot.prototype.elementFromPoint;
|
|
1257
|
+
/**
|
|
1258
|
+
* @param x
|
|
1259
|
+
* @param y
|
|
1260
|
+
* @returns
|
|
1261
|
+
*/
|
|
1262
|
+
ShadowRoot.prototype.elementFromPoint = function(x, y) {
|
|
1263
|
+
const originalResult = ShadowRoot.prototype.__originalShadowRootElementFromPoint.apply(this, arguments);
|
|
1264
|
+
if (this.host && originalResult === this.host) {
|
|
1265
|
+
return null;
|
|
1266
|
+
}
|
|
1267
|
+
return originalResult;
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
if (majorVersion <= 71) {
|
|
1273
|
+
styleRules.push(
|
|
1274
|
+
'.coverage-toolbar-container, .animation-timeline-toolbar-container, .computed-properties { flex-basis: auto; }');
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
installExtraStyleRules(styleRules);
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
/**
|
|
1281
|
+
* @param styleRules
|
|
1282
|
+
*/
|
|
1283
|
+
function installExtraStyleRules(styleRules) {
|
|
1284
|
+
if (!styleRules.length) {
|
|
1285
|
+
return;
|
|
1286
|
+
}
|
|
1287
|
+
const styleText = styleRules.join('\n');
|
|
1288
|
+
document.head.appendChild(createStyleElement(styleText));
|
|
1289
|
+
|
|
1290
|
+
const origCreateShadowRoot = HTMLElement.prototype.createShadowRoot;
|
|
1291
|
+
HTMLElement.prototype.createShadowRoot = function(...args) {
|
|
1292
|
+
const shadowRoot = origCreateShadowRoot.call(this, ...args);
|
|
1293
|
+
shadowRoot.appendChild(createStyleElement(styleText));
|
|
1294
|
+
return shadowRoot;
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
/**
|
|
1299
|
+
* @param styleText
|
|
1300
|
+
* @returns
|
|
1301
|
+
*/
|
|
1302
|
+
function createStyleElement(styleText) {
|
|
1303
|
+
const style = document.createElement('style');
|
|
1304
|
+
style.textContent = styleText;
|
|
1305
|
+
return style;
|
|
1111
1306
|
}
|
|
1112
1307
|
|
|
1113
1308
|
installBackwardsCompatibility();
|
|
@@ -2,49 +2,78 @@
|
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
+
import * as Host from '../../core/host/host.js';
|
|
5
6
|
import * as Root from '../../core/root/root.js';
|
|
6
7
|
|
|
7
8
|
let builtInAiInstance: BuiltInAi|undefined;
|
|
8
|
-
let availability
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
type: 'object',
|
|
12
|
-
properties: {
|
|
13
|
-
header: {type: 'string', maxLength: 60, description: 'Label for the console message which is being analyzed'},
|
|
14
|
-
// No hard `maxLength` for `explanation`. This would often result in responses which are cut off in the middle of a
|
|
15
|
-
// sentence. Instead provide a soft `maxLength` via the prompt.
|
|
16
|
-
explanation: {
|
|
17
|
-
type: 'string',
|
|
18
|
-
description: 'Actual explanation of the console message being analyzed',
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
required: ['header', 'explanation'],
|
|
22
|
-
additionalProperties: false,
|
|
23
|
-
};
|
|
9
|
+
let availability: LanguageModelAvailability|undefined;
|
|
10
|
+
let hasGpu: boolean|undefined;
|
|
11
|
+
let isFirstRun = true;
|
|
24
12
|
|
|
25
13
|
export interface LanguageModel {
|
|
26
14
|
promptStreaming: (arg0: string, opts?: {
|
|
27
|
-
responseConstraint: Object,
|
|
28
15
|
signal?: AbortSignal,
|
|
29
16
|
}) => AsyncGenerator<string>;
|
|
30
17
|
clone: () => LanguageModel;
|
|
31
18
|
destroy: () => void;
|
|
32
19
|
}
|
|
33
20
|
|
|
21
|
+
export const enum LanguageModelAvailability {
|
|
22
|
+
UNAVAILABLE = 'unavailable',
|
|
23
|
+
DOWNLOADABLE = 'downloadable',
|
|
24
|
+
DOWNLOADING = 'downloading',
|
|
25
|
+
AVAILABLE = 'available',
|
|
26
|
+
DISABLED = 'disabled',
|
|
27
|
+
}
|
|
28
|
+
|
|
34
29
|
export class BuiltInAi {
|
|
35
30
|
#consoleInsightsSession: LanguageModel;
|
|
36
31
|
|
|
37
|
-
static async
|
|
32
|
+
static async getLanguageModelAvailability(): Promise<LanguageModelAvailability> {
|
|
38
33
|
if (!Root.Runtime.hostConfig.devToolsAiPromptApi?.enabled) {
|
|
39
|
-
return
|
|
34
|
+
return LanguageModelAvailability.DISABLED;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
// @ts-expect-error
|
|
38
|
+
availability = await window.LanguageModel.availability({expectedOutputs: [{type: 'text', languages: ['en']}]}) as
|
|
39
|
+
LanguageModelAvailability;
|
|
40
|
+
return availability;
|
|
41
|
+
} catch {
|
|
42
|
+
return LanguageModelAvailability.UNAVAILABLE;
|
|
40
43
|
}
|
|
41
|
-
// @ts-expect-error
|
|
42
|
-
availability = await window.LanguageModel.availability({expectedOutputs: [{type: 'text', languages: ['en']}]});
|
|
43
|
-
return availability === 'available';
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
static cachedIsAvailable(): boolean {
|
|
47
|
-
return availability ===
|
|
47
|
+
return availability === LanguageModelAvailability.AVAILABLE;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static isGpuAvailable(): boolean {
|
|
51
|
+
const hasGpuHelper = (): boolean => {
|
|
52
|
+
const canvas = document.createElement('canvas');
|
|
53
|
+
try {
|
|
54
|
+
const webgl = canvas.getContext('webgl');
|
|
55
|
+
if (!webgl) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
const debugInfo = webgl.getExtension('WEBGL_debug_renderer_info');
|
|
59
|
+
if (!debugInfo) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
const renderer = webgl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
|
|
63
|
+
if (renderer.includes('SwiftShader')) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
} catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
if (hasGpu !== undefined) {
|
|
73
|
+
return hasGpu;
|
|
74
|
+
}
|
|
75
|
+
hasGpu = hasGpuHelper();
|
|
76
|
+
return hasGpu;
|
|
48
77
|
}
|
|
49
78
|
|
|
50
79
|
private constructor(consoleInsightsSession: LanguageModel) {
|
|
@@ -53,40 +82,97 @@ export class BuiltInAi {
|
|
|
53
82
|
|
|
54
83
|
static async instance(): Promise<BuiltInAi|undefined> {
|
|
55
84
|
if (builtInAiInstance === undefined) {
|
|
56
|
-
if (
|
|
57
|
-
|
|
85
|
+
if (isFirstRun) {
|
|
86
|
+
const languageModelAvailability = await BuiltInAi.getLanguageModelAvailability();
|
|
87
|
+
const hasGpu = BuiltInAi.isGpuAvailable();
|
|
88
|
+
if (hasGpu) {
|
|
89
|
+
switch (languageModelAvailability) {
|
|
90
|
+
case LanguageModelAvailability.UNAVAILABLE:
|
|
91
|
+
Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.UNAVAILABLE_HAS_GPU);
|
|
92
|
+
break;
|
|
93
|
+
case LanguageModelAvailability.DOWNLOADABLE:
|
|
94
|
+
Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADABLE_HAS_GPU);
|
|
95
|
+
break;
|
|
96
|
+
case LanguageModelAvailability.DOWNLOADING:
|
|
97
|
+
Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADING_HAS_GPU);
|
|
98
|
+
break;
|
|
99
|
+
case LanguageModelAvailability.AVAILABLE:
|
|
100
|
+
Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.AVAILABLE_HAS_GPU);
|
|
101
|
+
break;
|
|
102
|
+
case LanguageModelAvailability.DISABLED:
|
|
103
|
+
Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DISABLED_HAS_GPU);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
switch (languageModelAvailability) {
|
|
108
|
+
case LanguageModelAvailability.UNAVAILABLE:
|
|
109
|
+
Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.UNAVAILABLE_NO_GPU);
|
|
110
|
+
break;
|
|
111
|
+
case LanguageModelAvailability.DOWNLOADABLE:
|
|
112
|
+
Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADABLE_NO_GPU);
|
|
113
|
+
break;
|
|
114
|
+
case LanguageModelAvailability.DOWNLOADING:
|
|
115
|
+
Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DOWNLOADING_NO_GPU);
|
|
116
|
+
break;
|
|
117
|
+
case LanguageModelAvailability.AVAILABLE:
|
|
118
|
+
Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.AVAILABLE_NO_GPU);
|
|
119
|
+
break;
|
|
120
|
+
case LanguageModelAvailability.DISABLED:
|
|
121
|
+
Host.userMetrics.builtInAiAvailability(Host.UserMetrics.BuiltInAiAvailability.DISABLED_NO_GPU);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
isFirstRun = false;
|
|
126
|
+
if (!Root.Runtime.hostConfig.devToolsAiPromptApi?.allowWithoutGpu && !hasGpu) {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
if (languageModelAvailability !== LanguageModelAvailability.AVAILABLE) {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
if (!Root.Runtime.hostConfig.devToolsAiPromptApi?.allowWithoutGpu && !BuiltInAi.isGpuAvailable()) {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
if ((await BuiltInAi.getLanguageModelAvailability()) !== LanguageModelAvailability.AVAILABLE) {
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
58
139
|
}
|
|
59
|
-
// @ts-expect-error
|
|
60
|
-
const consoleInsightsSession = await window.LanguageModel.create({
|
|
61
|
-
initialPrompts: [{
|
|
62
|
-
role: 'system',
|
|
63
|
-
content: `
|
|
64
|
-
You are an expert web developer. Your goal is to help a human web developer who
|
|
65
|
-
is using Chrome DevTools to debug a web site or web app. The Chrome DevTools
|
|
66
|
-
console is showing a message which is either an error or a warning. Please help
|
|
67
|
-
the user understand the problematic console message.
|
|
68
140
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
141
|
+
try {
|
|
142
|
+
// @ts-expect-error
|
|
143
|
+
const consoleInsightsSession = await window.LanguageModel.create({
|
|
144
|
+
initialPrompts: [{
|
|
145
|
+
role: 'system',
|
|
146
|
+
content: `
|
|
147
|
+
You are an expert web developer. Your goal is to help a human web developer who
|
|
148
|
+
is using Chrome DevTools to debug a web site or web app. The Chrome DevTools
|
|
149
|
+
console is showing a message which is either an error or a warning. Please help
|
|
150
|
+
the user understand the problematic console message.
|
|
151
|
+
|
|
152
|
+
Your instructions are as follows:
|
|
153
|
+
- Explain the reason why the error or warning is showing up.
|
|
154
|
+
- The explanation has a maximum length of 200 characters. Anything beyond this
|
|
155
|
+
length will be cut off. Make sure that your explanation is at most 200 characters long.
|
|
156
|
+
- Your explanation should not end in the middle of a sentence.
|
|
157
|
+
- Your explanation should consist of a single paragraph only. Do not include any
|
|
158
|
+
headings or code blocks. Only write a single paragraph of text.
|
|
159
|
+
- Your response should be concise and to the point. Avoid lengthy explanations
|
|
160
|
+
or unnecessary details.
|
|
161
|
+
`
|
|
162
|
+
}],
|
|
163
|
+
expectedInputs: [{
|
|
164
|
+
type: 'text',
|
|
165
|
+
languages: ['en'],
|
|
166
|
+
}],
|
|
167
|
+
expectedOutputs: [{
|
|
168
|
+
type: 'text',
|
|
169
|
+
languages: ['en'],
|
|
170
|
+
}],
|
|
171
|
+
}) as LanguageModel;
|
|
172
|
+
builtInAiInstance = new BuiltInAi(consoleInsightsSession);
|
|
173
|
+
} catch {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
90
176
|
}
|
|
91
177
|
return builtInAiInstance;
|
|
92
178
|
}
|
|
@@ -101,7 +187,6 @@ Your instructions are as follows:
|
|
|
101
187
|
const session = await this.#consoleInsightsSession.clone();
|
|
102
188
|
const stream = session.promptStreaming(prompt, {
|
|
103
189
|
signal: abortController.signal,
|
|
104
|
-
responseConstraint: RESPONSE_SCHEMA,
|
|
105
190
|
});
|
|
106
191
|
for await (const chunk of stream) {
|
|
107
192
|
yield chunk;
|
|
@@ -6,7 +6,6 @@ import * as Common from '../../core/common/common.js';
|
|
|
6
6
|
import * as Host from '../../core/host/host.js';
|
|
7
7
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
8
8
|
import * as Badges from '../../models/badges/badges.js';
|
|
9
|
-
import * as WindowBoundsService from '../../services/window_bounds/window_bounds.js';
|
|
10
9
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
11
10
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
12
11
|
import * as Lit from '../../ui/lit/lit.js';
|
|
@@ -166,8 +165,7 @@ export class BadgeNotification extends UI.Widget.Widget {
|
|
|
166
165
|
|
|
167
166
|
#positionNotification(): void {
|
|
168
167
|
const boundingRect = this.contentElement.getBoundingClientRect();
|
|
169
|
-
const container =
|
|
170
|
-
WindowBoundsService.WindowBoundsService.WindowBoundsServiceImpl.instance().getDevToolsBoundingElement();
|
|
168
|
+
const container = UI.UIUtils.getDevToolsBoundingElement();
|
|
171
169
|
this.contentElement.positionAt(
|
|
172
170
|
LEFT_OFFSET, container.clientHeight - boundingRect.height - BOTTOM_OFFSET, container);
|
|
173
171
|
}
|