chrome-devtools-frontend 1.0.1611825 → 1.0.1613465
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/front_end/Images/src/flowsheet.svg +1 -0
- package/front_end/core/common/Color.ts +3 -2
- package/front_end/core/platform/StringUtilities.ts +5 -0
- package/front_end/core/sdk/NetworkManager.ts +7 -0
- package/front_end/generated/InspectorBackendCommands.ts +2 -2
- package/front_end/generated/protocol.ts +12 -2
- package/front_end/models/greendev/Prototypes.ts +7 -4
- package/front_end/models/har/HARFormat.ts +30 -0
- package/front_end/models/har/Importer.ts +12 -1
- package/front_end/models/har/Log.ts +28 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +62 -22
- package/front_end/panels/ai_assistance/PatchWidget.ts +7 -23
- package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +3 -3
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +7 -0
- package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
- package/front_end/panels/ai_assistance/components/ChatView.ts +4 -0
- package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +12 -6
- package/front_end/panels/ai_assistance/components/OptInChangeDialog.ts +179 -0
- package/front_end/panels/ai_assistance/components/optInChangeDialog.css +95 -0
- package/front_end/panels/ai_assistance/components/walkthroughView.css +1 -1
- package/front_end/panels/application/CookieItemsView.ts +3 -2
- package/front_end/panels/changes/ChangesView.ts +0 -12
- package/front_end/panels/common/common.ts +0 -1
- package/front_end/panels/console/ConsolePrompt.ts +2 -2
- package/front_end/panels/elements/StylePropertyTreeElement.ts +2 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +3 -1
- package/front_end/panels/elements/elements-meta.ts +14 -0
- package/front_end/panels/network/NetworkLogView.ts +58 -28
- package/front_end/panels/recorder/RecorderController.ts +4 -4
- package/front_end/panels/settings/AISettingsTab.ts +39 -3
- package/front_end/panels/settings/SettingsScreen.ts +2 -2
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/legacy/SplitWidget.ts +9 -6
- package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +3 -3
- package/front_end/ui/legacy/components/source_frame/FontView.ts +101 -88
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +4 -4
- package/front_end/ui/visual_logging/KnownContextValues.ts +6 -0
- package/package.json +1 -1
- package/front_end/panels/common/CopyChangesToPrompt.ts +0 -233
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="currentColor"><path d="M168-456v192-432V-456Zm383.79 312q15.21 0 25.71-10.29t10.5-25.5q0-15.21-10.29-25.71t-25.5-10.5q-15.21 0-25.71 10.29t-10.5 25.5q0 15.21 10.29 25.71t25.5 10.5Zm240-360q15.21 0 25.71-10.29t10.5-25.5q0-15.21-10.29-25.71t-25.5-10.5q-15.21 0-25.71 10.29t-10.5 25.5q0 15.21 10.29 25.71t25.5 10.5ZM240-528h204v-72H240v72Zm0 168h204v-72H240v72Zm-72 168q-29.7 0-50.85-21.16Q96-234.32 96-264.04v-432.24Q96-726 117.15-747T168-768h624q29.7 0 50.85 21.15Q864-725.7 864-696H168v432h204v72H168Zm307.5 88.52Q444-134.96 444-179.92 444-215 464-243t52-39v-102h240v-54q-32-11-52-38.92t-20-63.05q0-45.03 31.5-76.53T792-648q45 0 76.5 31.48t31.5 76.44Q900-505 880-477t-52 39v126H588v30q32 11 52 38.92t20 63.05q0 45.03-31.5 76.53T552-72q-45 0-76.5-31.48Z"/></svg>
|
|
@@ -684,6 +684,7 @@ export interface Color {
|
|
|
684
684
|
|
|
685
685
|
const EPSILON = 0.01;
|
|
686
686
|
const WIDE_RANGE_EPSILON = 1; // For comparisons on channels with a wider range than [0,1]
|
|
687
|
+
const STRICT_EPSILON = 1e-4;
|
|
687
688
|
function equals(a: number[], b: number[], accuracy?: number): boolean;
|
|
688
689
|
function equals(a: number|null, b: number|null, accuracy?: number): boolean;
|
|
689
690
|
function equals(a: number|null|number[], b: number|null|number[], accuracy = EPSILON): boolean {
|
|
@@ -994,7 +995,7 @@ export class LCH implements Color {
|
|
|
994
995
|
// See "powerless" component definitions in
|
|
995
996
|
// https://www.w3.org/TR/css-color-4/#specifying-lab-lch
|
|
996
997
|
isHuePowerless(): boolean {
|
|
997
|
-
return equals(this.c, 0);
|
|
998
|
+
return equals(this.c, 0, STRICT_EPSILON);
|
|
998
999
|
}
|
|
999
1000
|
static fromSpec(spec: ColorParameterSpec, text: string): LCH|null {
|
|
1000
1001
|
const L = parsePercentage(spec[0], [0, 100]) ?? parseNumber(spec[0]);
|
|
@@ -1592,7 +1593,7 @@ export class HSL implements Color {
|
|
|
1592
1593
|
this.l = clamp(l, {min: 0, max: 1});
|
|
1593
1594
|
s = equals(this.l, 0) || equals(this.l, 1) ? 0 : s;
|
|
1594
1595
|
this.s = clamp(s, {min: 0, max: 1});
|
|
1595
|
-
h = equals(this.s, 0) ? 0 : h;
|
|
1596
|
+
h = equals(this.s, 0, STRICT_EPSILON) ? 0 : h;
|
|
1596
1597
|
this.h = normalizeHue(h * 360) / 360;
|
|
1597
1598
|
this.alpha = clamp(alpha ?? null, {min: 0, max: 1});
|
|
1598
1599
|
this.#authoredText = authoredText;
|
|
@@ -276,6 +276,7 @@ export const removeURLFragment = (inputStr: string): string => {
|
|
|
276
276
|
};
|
|
277
277
|
|
|
278
278
|
const SPECIAL_REGEX_CHARACTERS = '^[]{}()\\.^$*+?|-,';
|
|
279
|
+
const SPECIAL_URL_PATTERN_CHARACTERS = '?+*(){}\\:';
|
|
279
280
|
|
|
280
281
|
export const regexSpecialCharacters = function(): string {
|
|
281
282
|
return SPECIAL_REGEX_CHARACTERS;
|
|
@@ -450,6 +451,10 @@ export const escapeForRegExp = (str: string): string => {
|
|
|
450
451
|
return escapeCharacters(str, SPECIAL_REGEX_CHARACTERS);
|
|
451
452
|
};
|
|
452
453
|
|
|
454
|
+
export const escapeForURLPattern = (text: string): string => {
|
|
455
|
+
return escapeCharacters(text, SPECIAL_URL_PATTERN_CHARACTERS);
|
|
456
|
+
};
|
|
457
|
+
|
|
453
458
|
export const naturalOrderComparator = (a: string, b: string): number => {
|
|
454
459
|
const chunk = /^\d+|^\D+/;
|
|
455
460
|
let chunkA, chunkB, numA, numB;
|
|
@@ -32,6 +32,10 @@ const UIStrings = {
|
|
|
32
32
|
* @description Explanation why no content is shown for WebSocket connection.
|
|
33
33
|
*/
|
|
34
34
|
noContentForWebSocket: 'Content for WebSockets is currently not supported',
|
|
35
|
+
/**
|
|
36
|
+
* @description Explanation why no content is shown for Server-Sent Events (SSE).
|
|
37
|
+
*/
|
|
38
|
+
noContentForSSE: 'Content for Server-Sent Events (SSE) is currently not supported',
|
|
35
39
|
/**
|
|
36
40
|
* @description Explanation why no content is shown for redirect response.
|
|
37
41
|
*/
|
|
@@ -215,6 +219,9 @@ export class NetworkManager extends SDKModel<EventTypes> {
|
|
|
215
219
|
return {error: i18nString(UIStrings.noContentForWebSocket)};
|
|
216
220
|
}
|
|
217
221
|
if (!request.finished) {
|
|
222
|
+
if (Boolean(request.eventSourceMessages()?.length)) {
|
|
223
|
+
return {error: i18nString(UIStrings.noContentForSSE)};
|
|
224
|
+
}
|
|
218
225
|
await request.once(NetworkRequestEvents.FINISHED_LOADING);
|
|
219
226
|
}
|
|
220
227
|
if (request.isRedirect()) {
|
|
@@ -867,7 +867,7 @@ inspectorBackend.registerCommand("Network.continueInterceptedRequest", [{"name":
|
|
|
867
867
|
inspectorBackend.registerCommand("Network.deleteCookies", [{"name": "name", "type": "string", "optional": false, "description": "Name of the cookies to remove.", "typeRef": null}, {"name": "url", "type": "string", "optional": true, "description": "If specified, deletes all the cookies with the given name where domain and path match provided URL.", "typeRef": null}, {"name": "domain", "type": "string", "optional": true, "description": "If specified, deletes only cookies with the exact domain.", "typeRef": null}, {"name": "path", "type": "string", "optional": true, "description": "If specified, deletes only cookies with the exact path.", "typeRef": null}, {"name": "partitionKey", "type": "object", "optional": true, "description": "If specified, deletes only cookies with the the given name and partitionKey where all partition key attributes match the cookie partition key attribute.", "typeRef": "Network.CookiePartitionKey"}], [], "Deletes browser cookies with matching name and url or domain/path/partitionKey pair.");
|
|
868
868
|
inspectorBackend.registerCommand("Network.disable", [], [], "Disables network tracking, prevents network events from being sent to the client.");
|
|
869
869
|
inspectorBackend.registerCommand("Network.emulateNetworkConditions", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}, {"name": "packetLoss", "type": "number", "optional": true, "description": "WebRTC packet loss (percent, 0-100). 0 disables packet loss emulation, 100 drops all the packets.", "typeRef": null}, {"name": "packetQueueLength", "type": "number", "optional": true, "description": "WebRTC packet queue length (packet). 0 removes any queue length limitations.", "typeRef": null}, {"name": "packetReordering", "type": "boolean", "optional": true, "description": "WebRTC packetReordering feature.", "typeRef": null}], [], "Activates emulation of network conditions. This command is deprecated in favor of the emulateNetworkConditionsByRule and overrideNetworkState commands, which can be used together to the same effect.");
|
|
870
|
-
inspectorBackend.registerCommand("Network.emulateNetworkConditionsByRule", [{"name": "offline", "type": "boolean", "optional":
|
|
870
|
+
inspectorBackend.registerCommand("Network.emulateNetworkConditionsByRule", [{"name": "offline", "type": "boolean", "optional": true, "description": "True to emulate internet disconnection. Deprecated, use the offline property in matchedNetworkConditions or emulateOfflineServiceWorker instead.", "typeRef": null}, {"name": "emulateOfflineServiceWorker", "type": "boolean", "optional": true, "description": "True to emulate offline service worker.", "typeRef": null}, {"name": "matchedNetworkConditions", "type": "array", "optional": false, "description": "Configure conditions for matching requests. If multiple entries match a request, the first entry wins. Global conditions can be configured by leaving the urlPattern for the conditions empty. These global conditions are also applied for throttling of p2p connections.", "typeRef": "Network.NetworkConditions"}], ["ruleIds"], "Activates emulation of network conditions for individual requests using URL match patterns. Unlike the deprecated Network.emulateNetworkConditions this method does not affect `navigator` state. Use Network.overrideNetworkState to explicitly modify `navigator` behavior.");
|
|
871
871
|
inspectorBackend.registerCommand("Network.overrideNetworkState", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}], [], "Override the state of navigator.onLine and navigator.connection.");
|
|
872
872
|
inspectorBackend.registerCommand("Network.enable", [{"name": "maxTotalBufferSize", "type": "number", "optional": true, "description": "Buffer size in bytes to use when preserving network payloads (XHRs, etc). This is the maximum number of bytes that will be collected by this DevTools session.", "typeRef": null}, {"name": "maxResourceBufferSize", "type": "number", "optional": true, "description": "Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}, {"name": "maxPostDataSize", "type": "number", "optional": true, "description": "Longest post body size (in bytes) that would be included in requestWillBeSent notification", "typeRef": null}, {"name": "reportDirectSocketTraffic", "type": "boolean", "optional": true, "description": "Whether DirectSocket chunk send/receive events should be reported.", "typeRef": null}, {"name": "enableDurableMessages", "type": "boolean", "optional": true, "description": "Enable storing response bodies outside of renderer, so that these survive a cross-process navigation. Requires maxTotalBufferSize to be set. Currently defaults to false. This field is being deprecated in favor of the dedicated configureDurableMessages command, due to the possibility of deadlocks when awaiting Network.enable before issuing Runtime.runIfWaitingForDebugger.", "typeRef": null}], [], "Enables network tracking, network events will now be delivered to the client.");
|
|
873
873
|
inspectorBackend.registerCommand("Network.configureDurableMessages", [{"name": "maxTotalBufferSize", "type": "number", "optional": true, "description": "Buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}, {"name": "maxResourceBufferSize", "type": "number", "optional": true, "description": "Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}], [], "Configures storing response bodies outside of renderer, so that these survive a cross-process navigation. If maxTotalBufferSize is not set, durable messages are disabled.");
|
|
@@ -923,7 +923,7 @@ inspectorBackend.registerType("Network.SignedExchangeSignature", [{"name": "labe
|
|
|
923
923
|
inspectorBackend.registerType("Network.SignedExchangeHeader", [{"name": "requestUrl", "type": "string", "optional": false, "description": "Signed exchange request URL.", "typeRef": null}, {"name": "responseCode", "type": "number", "optional": false, "description": "Signed exchange response code.", "typeRef": null}, {"name": "responseHeaders", "type": "object", "optional": false, "description": "Signed exchange response headers.", "typeRef": "Network.Headers"}, {"name": "signatures", "type": "array", "optional": false, "description": "Signed exchange response signature.", "typeRef": "Network.SignedExchangeSignature"}, {"name": "headerIntegrity", "type": "string", "optional": false, "description": "Signed exchange header integrity hash in the form of `sha256-<base64-hash-value>`.", "typeRef": null}]);
|
|
924
924
|
inspectorBackend.registerType("Network.SignedExchangeError", [{"name": "message", "type": "string", "optional": false, "description": "Error message.", "typeRef": null}, {"name": "signatureIndex", "type": "number", "optional": true, "description": "The index of the signature which caused the error.", "typeRef": null}, {"name": "errorField", "type": "string", "optional": true, "description": "The field which caused the error.", "typeRef": "Network.SignedExchangeErrorField"}]);
|
|
925
925
|
inspectorBackend.registerType("Network.SignedExchangeInfo", [{"name": "outerResponse", "type": "object", "optional": false, "description": "The outer response of signed HTTP exchange which was received from network.", "typeRef": "Network.Response"}, {"name": "hasExtraInfo", "type": "boolean", "optional": false, "description": "Whether network response for the signed exchange was accompanied by extra headers.", "typeRef": null}, {"name": "header", "type": "object", "optional": true, "description": "Information about the signed exchange header.", "typeRef": "Network.SignedExchangeHeader"}, {"name": "securityDetails", "type": "object", "optional": true, "description": "Security details for the signed exchange header.", "typeRef": "Network.SecurityDetails"}, {"name": "errors", "type": "array", "optional": true, "description": "Errors occurred while handling the signed exchange.", "typeRef": "Network.SignedExchangeError"}]);
|
|
926
|
-
inspectorBackend.registerType("Network.NetworkConditions", [{"name": "urlPattern", "type": "string", "optional": false, "description": "Only matching requests will be affected by these conditions. Patterns use the URLPattern constructor string syntax (https://urlpattern.spec.whatwg.org/) and must be absolute. If the pattern is empty, all requests are matched (including p2p connections).", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}, {"name": "packetLoss", "type": "number", "optional": true, "description": "WebRTC packet loss (percent, 0-100). 0 disables packet loss emulation, 100 drops all the packets.", "typeRef": null}, {"name": "packetQueueLength", "type": "number", "optional": true, "description": "WebRTC packet queue length (packet). 0 removes any queue length limitations.", "typeRef": null}, {"name": "packetReordering", "type": "boolean", "optional": true, "description": "WebRTC packetReordering feature.", "typeRef": null}]);
|
|
926
|
+
inspectorBackend.registerType("Network.NetworkConditions", [{"name": "urlPattern", "type": "string", "optional": false, "description": "Only matching requests will be affected by these conditions. Patterns use the URLPattern constructor string syntax (https://urlpattern.spec.whatwg.org/) and must be absolute. If the pattern is empty, all requests are matched (including p2p connections).", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}, {"name": "packetLoss", "type": "number", "optional": true, "description": "WebRTC packet loss (percent, 0-100). 0 disables packet loss emulation, 100 drops all the packets.", "typeRef": null}, {"name": "packetQueueLength", "type": "number", "optional": true, "description": "WebRTC packet queue length (packet). 0 removes any queue length limitations.", "typeRef": null}, {"name": "packetReordering", "type": "boolean", "optional": true, "description": "WebRTC packetReordering feature.", "typeRef": null}, {"name": "offline", "type": "boolean", "optional": true, "description": "True to emulate internet disconnection.", "typeRef": null}]);
|
|
927
927
|
inspectorBackend.registerType("Network.BlockPattern", [{"name": "urlPattern", "type": "string", "optional": false, "description": "URL pattern to match. Patterns use the URLPattern constructor string syntax (https://urlpattern.spec.whatwg.org/) and must be absolute. Example: `*://*:*/*.css`.", "typeRef": null}, {"name": "block", "type": "boolean", "optional": false, "description": "Whether or not to block the pattern. If false, a matching request will not be blocked even if it matches a later `BlockPattern`.", "typeRef": null}]);
|
|
928
928
|
inspectorBackend.registerType("Network.DirectTCPSocketOptions", [{"name": "noDelay", "type": "boolean", "optional": false, "description": "TCP_NODELAY option", "typeRef": null}, {"name": "keepAliveDelay", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "sendBufferSize", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "receiveBufferSize", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "dnsQueryType", "type": "string", "optional": true, "description": "", "typeRef": "Network.DirectSocketDnsQueryType"}]);
|
|
929
929
|
inspectorBackend.registerType("Network.DirectUDPSocketOptions", [{"name": "remoteAddr", "type": "string", "optional": true, "description": "", "typeRef": null}, {"name": "remotePort", "type": "number", "optional": true, "description": "Unsigned int 16.", "typeRef": null}, {"name": "localAddr", "type": "string", "optional": true, "description": "", "typeRef": null}, {"name": "localPort", "type": "number", "optional": true, "description": "Unsigned int 16.", "typeRef": null}, {"name": "dnsQueryType", "type": "string", "optional": true, "description": "", "typeRef": "Network.DirectSocketDnsQueryType"}, {"name": "sendBufferSize", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "receiveBufferSize", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "multicastLoopback", "type": "boolean", "optional": true, "description": "", "typeRef": null}, {"name": "multicastTimeToLive", "type": "number", "optional": true, "description": "Unsigned int 8.", "typeRef": null}, {"name": "multicastAllowAddressSharing", "type": "boolean", "optional": true, "description": "", "typeRef": null}]);
|
|
@@ -11376,6 +11376,10 @@ export namespace Network {
|
|
|
11376
11376
|
* WebRTC packetReordering feature.
|
|
11377
11377
|
*/
|
|
11378
11378
|
packetReordering?: boolean;
|
|
11379
|
+
/**
|
|
11380
|
+
* True to emulate internet disconnection.
|
|
11381
|
+
*/
|
|
11382
|
+
offline?: boolean;
|
|
11379
11383
|
}
|
|
11380
11384
|
|
|
11381
11385
|
export interface BlockPattern {
|
|
@@ -12154,9 +12158,15 @@ export namespace Network {
|
|
|
12154
12158
|
|
|
12155
12159
|
export interface EmulateNetworkConditionsByRuleRequest {
|
|
12156
12160
|
/**
|
|
12157
|
-
* True to emulate internet disconnection.
|
|
12161
|
+
* True to emulate internet disconnection. Deprecated, use the offline property in matchedNetworkConditions
|
|
12162
|
+
* or emulateOfflineServiceWorker instead.
|
|
12163
|
+
* @deprecated
|
|
12158
12164
|
*/
|
|
12159
|
-
offline
|
|
12165
|
+
offline?: boolean;
|
|
12166
|
+
/**
|
|
12167
|
+
* True to emulate offline service worker.
|
|
12168
|
+
*/
|
|
12169
|
+
emulateOfflineServiceWorker?: boolean;
|
|
12160
12170
|
/**
|
|
12161
12171
|
* Configure conditions for matching requests. If multiple entries match a request, the first entry wins. Global
|
|
12162
12172
|
* conditions can be configured by leaving the urlPattern for the conditions empty. These global conditions are
|
|
@@ -9,7 +9,7 @@ let instance: Prototypes|null = null;
|
|
|
9
9
|
|
|
10
10
|
export interface GreenDevSettings {
|
|
11
11
|
aiAnnotations: Common.Settings.Setting<boolean>;
|
|
12
|
-
|
|
12
|
+
beyondStyling: Common.Settings.Setting<boolean>;
|
|
13
13
|
breakpointDebuggerAgent: Common.Settings.Setting<boolean>;
|
|
14
14
|
emulationCapabilities: Common.Settings.Setting<boolean>;
|
|
15
15
|
}
|
|
@@ -42,8 +42,11 @@ export class Prototypes {
|
|
|
42
42
|
false,
|
|
43
43
|
Common.Settings.SettingStorageType.LOCAL,
|
|
44
44
|
);
|
|
45
|
-
const
|
|
46
|
-
|
|
45
|
+
const beyondStyling = settings.createSetting(
|
|
46
|
+
'greendev-beyond-styling-enabled',
|
|
47
|
+
false,
|
|
48
|
+
Common.Settings.SettingStorageType.LOCAL,
|
|
49
|
+
);
|
|
47
50
|
const breakpointDebuggerAgent = settings.createSetting(
|
|
48
51
|
'greendev-breakpoint-debugger-agent-enabled',
|
|
49
52
|
false,
|
|
@@ -55,6 +58,6 @@ export class Prototypes {
|
|
|
55
58
|
Common.Settings.SettingStorageType.LOCAL,
|
|
56
59
|
);
|
|
57
60
|
|
|
58
|
-
return {aiAnnotations,
|
|
61
|
+
return {aiAnnotations, beyondStyling, breakpointDebuggerAgent, emulationCapabilities};
|
|
59
62
|
}
|
|
60
63
|
}
|
|
@@ -171,6 +171,7 @@ export class HAREntry extends HARBase {
|
|
|
171
171
|
this.custom.set('initiator', this.importInitiator(data['_initiator']));
|
|
172
172
|
this.custom.set('priority', HARBase.optionalString(data['_priority']));
|
|
173
173
|
this.custom.set('resourceType', HARBase.optionalString(data['_resourceType']));
|
|
174
|
+
this.custom.set('eventSourceMessages', this.#importEventSourceMessages(data['_eventSourceMessages']));
|
|
174
175
|
this.custom.set('webSocketMessages', this.importWebSocketMessages(data['_webSocketMessages']));
|
|
175
176
|
}
|
|
176
177
|
|
|
@@ -196,6 +197,21 @@ export class HAREntry extends HARBase {
|
|
|
196
197
|
}
|
|
197
198
|
return outputMessages;
|
|
198
199
|
}
|
|
200
|
+
|
|
201
|
+
#importEventSourceMessages(inputMessages: any): HAREventSourceMessage[]|undefined {
|
|
202
|
+
if (!Array.isArray(inputMessages)) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const outputMessages = [];
|
|
207
|
+
for (const message of inputMessages) {
|
|
208
|
+
if (typeof message !== 'object') {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
outputMessages.push(new HAREventSourceMessage(message));
|
|
212
|
+
}
|
|
213
|
+
return outputMessages;
|
|
214
|
+
}
|
|
199
215
|
}
|
|
200
216
|
|
|
201
217
|
class HARRequest extends HARBase {
|
|
@@ -480,3 +496,17 @@ class HARWebSocketMessage extends HARBase {
|
|
|
480
496
|
this.type = HARBase.optionalString(data['type']);
|
|
481
497
|
}
|
|
482
498
|
}
|
|
499
|
+
|
|
500
|
+
class HAREventSourceMessage extends HARBase {
|
|
501
|
+
time: number|undefined;
|
|
502
|
+
eventName: string|undefined;
|
|
503
|
+
eventId: string|undefined;
|
|
504
|
+
data: string|undefined;
|
|
505
|
+
constructor(data: any) {
|
|
506
|
+
super(data);
|
|
507
|
+
this.time = HARBase.optionalNumber(data['time']);
|
|
508
|
+
this.eventName = HARBase.optionalString(data['eventName']);
|
|
509
|
+
this.eventId = HARBase.optionalString(data['eventId']);
|
|
510
|
+
this.data = HARBase.optionalString(data['data']);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
@@ -137,7 +137,18 @@ export class Importer {
|
|
|
137
137
|
async () =>
|
|
138
138
|
new TextUtils.ContentData.ContentData(contentText ?? '', isBase64, mimeType ?? '', charset ?? undefined));
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
const importedEventSourceMessages = entry.customAsArray('eventSourceMessages');
|
|
141
|
+
|
|
142
|
+
if (importedEventSourceMessages) {
|
|
143
|
+
for (const message of importedEventSourceMessages) {
|
|
144
|
+
if (message.time === undefined || message.eventName === undefined || message.eventId === undefined) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
// message.data may be undefined, if saved in a sanitized context
|
|
148
|
+
|
|
149
|
+
request.addEventSourceMessage(message.time, message.eventName, message.eventId, message.data);
|
|
150
|
+
}
|
|
151
|
+
} else if (request.mimeType === Platform.MimeType.MimeType.EVENTSTREAM && contentText) {
|
|
141
152
|
const issueTime = entry.startedDateTime.getTime() / 1000;
|
|
142
153
|
const onEvent = (eventName: string, data: string, eventId: string): void => {
|
|
143
154
|
request.addEventSourceMessage(issueTime, eventName, eventId, data);
|
|
@@ -176,6 +176,26 @@ export class Entry {
|
|
|
176
176
|
delete entry._webSocketMessages;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
const eventSourceMessages = harEntry.request.eventSourceMessages();
|
|
180
|
+
if (eventSourceMessages?.length) {
|
|
181
|
+
const messages = [];
|
|
182
|
+
for (const message of eventSourceMessages) {
|
|
183
|
+
const messageDTO: EventSourceMessageDTO = {
|
|
184
|
+
time: message.time,
|
|
185
|
+
eventName: message.eventName,
|
|
186
|
+
eventId: message.eventId,
|
|
187
|
+
};
|
|
188
|
+
if (!options.sanitize) {
|
|
189
|
+
// Omit the data when sanitizing, as it could contain sensitive information.
|
|
190
|
+
messageDTO.data = message.data;
|
|
191
|
+
}
|
|
192
|
+
messages.push(messageDTO);
|
|
193
|
+
}
|
|
194
|
+
entry._eventSourceMessages = messages;
|
|
195
|
+
} else {
|
|
196
|
+
delete entry._eventSourceMessages;
|
|
197
|
+
}
|
|
198
|
+
|
|
179
199
|
return entry;
|
|
180
200
|
}
|
|
181
201
|
|
|
@@ -490,6 +510,7 @@ export interface EntryDTO {
|
|
|
490
510
|
_priority: Protocol.Network.ResourcePriority|null;
|
|
491
511
|
_resourceType: string;
|
|
492
512
|
_webSocketMessages?: Object[];
|
|
513
|
+
_eventSourceMessages?: EventSourceMessageDTO[];
|
|
493
514
|
cache: Object;
|
|
494
515
|
connection?: string;
|
|
495
516
|
pageref?: string;
|
|
@@ -540,3 +561,10 @@ export interface LogDTO {
|
|
|
540
561
|
pages: Page[];
|
|
541
562
|
entries: EntryDTO[];
|
|
542
563
|
}
|
|
564
|
+
|
|
565
|
+
export interface EventSourceMessageDTO {
|
|
566
|
+
time: number;
|
|
567
|
+
eventName: string;
|
|
568
|
+
eventId: string;
|
|
569
|
+
data?: string;
|
|
570
|
+
}
|
|
@@ -44,6 +44,7 @@ import {
|
|
|
44
44
|
import {DisabledWidget} from './components/DisabledWidget.js';
|
|
45
45
|
import {ExploreWidget} from './components/ExploreWidget.js';
|
|
46
46
|
import {MarkdownRendererWithCodeBlock} from './components/MarkdownRendererWithCodeBlock.js';
|
|
47
|
+
import {OptInChangeDialog} from './components/OptInChangeDialog.js';
|
|
47
48
|
import {PerformanceAgentMarkdownRenderer} from './components/PerformanceAgentMarkdownRenderer.js';
|
|
48
49
|
import {StylingAgentMarkdownRenderer} from './components/StylingAgentMarkdownRenderer.js';
|
|
49
50
|
import {
|
|
@@ -252,6 +253,16 @@ const UIStringsNotTranslate = {
|
|
|
252
253
|
*/
|
|
253
254
|
inputDisclaimerForAccessibilityEnterpriseNoLogging:
|
|
254
255
|
'Chat messages and the selected Lighthouse report are sent to Google. The content you submit and that is generated by this feature will not be used to improve Google’s AI models. This is an experimental AI feature and won’t always get it right.',
|
|
256
|
+
/**
|
|
257
|
+
* @description Disclaimer text right after the chat input when V2 is enabled.
|
|
258
|
+
*/
|
|
259
|
+
inputDisclaimerV2:
|
|
260
|
+
'Chat messages, data accessible for this site via DevTools panels and Web APIs, and items you select such as network requests, files, and performance traces are sent to Google and may be seen by human reviewers to improve this feature. This is an experimental AI feature and won’t always get it right.',
|
|
261
|
+
/**
|
|
262
|
+
* @description Disclaimer text right after the chat input when V2 is enabled and enterprise logging is off.
|
|
263
|
+
*/
|
|
264
|
+
inputDisclaimerEnterpriseNoLoggingV2:
|
|
265
|
+
'Chat messages, data accessible for this site via DevTools panels and Web APIs, and items you select such as network requests, files, and performance traces are sent to Google. The content submitted to and generated by this feature will not be used to improve Google’s AI models. This is an experimental AI feature and won’t always get it right.',
|
|
255
266
|
} as const;
|
|
256
267
|
|
|
257
268
|
const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/AiAssistancePanel.ts', UIStrings);
|
|
@@ -779,11 +790,32 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
779
790
|
return await this.#conversationSummaryAgent.summarizeConversation(markdown);
|
|
780
791
|
},
|
|
781
792
|
onTextSubmit: async (
|
|
782
|
-
|
|
783
793
|
text: string, imageInput?: Host.AidaClient.Part,
|
|
784
794
|
multimodalInputType?: AiAssistanceModel.AiAgent.MultimodalInputType) => {
|
|
785
|
-
|
|
786
|
-
|
|
795
|
+
const submit = (): void => {
|
|
796
|
+
Host.userMetrics.actionTaken(Host.UserMetrics.Action.AiAssistanceQuerySubmitted);
|
|
797
|
+
void this.#startConversation(text, imageInput, multimodalInputType);
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
const isAIV2Enabled = Root.Runtime.hostConfig.devToolsAiAssistanceV2?.enabled;
|
|
801
|
+
const seenSetting =
|
|
802
|
+
Common.Settings.Settings.instance().moduleSetting('ai-assistance-v2-opt-in-change-dialog-seen');
|
|
803
|
+
if (isAIV2Enabled && !seenSetting.get()) {
|
|
804
|
+
OptInChangeDialog.show({
|
|
805
|
+
onGotIt: () => {
|
|
806
|
+
seenSetting.set(true);
|
|
807
|
+
submit();
|
|
808
|
+
},
|
|
809
|
+
onManageSettings: () => {
|
|
810
|
+
seenSetting.set(true);
|
|
811
|
+
this.#viewOutput.chatView?.setInputValue(text);
|
|
812
|
+
void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
|
|
813
|
+
},
|
|
814
|
+
});
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
submit();
|
|
787
819
|
},
|
|
788
820
|
onInspectElementClick: this.#handleSelectElementClick.bind(this),
|
|
789
821
|
onFeedbackSubmit: this.#handleFeedbackSubmit.bind(this),
|
|
@@ -1396,46 +1428,54 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1396
1428
|
return i18nString(UIStrings.inputDisclaimerForEmptyState);
|
|
1397
1429
|
}
|
|
1398
1430
|
|
|
1399
|
-
const
|
|
1431
|
+
const loggingEnabled = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue !==
|
|
1400
1432
|
Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
|
|
1433
|
+
|
|
1434
|
+
if (Root.Runtime.hostConfig.devToolsAiAssistanceV2?.enabled) {
|
|
1435
|
+
if (loggingEnabled) {
|
|
1436
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerV2);
|
|
1437
|
+
}
|
|
1438
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerEnterpriseNoLoggingV2);
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1401
1441
|
switch (this.#conversation.type) {
|
|
1402
1442
|
case AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING:
|
|
1403
|
-
if (
|
|
1404
|
-
return lockedString(UIStringsNotTranslate.
|
|
1443
|
+
if (loggingEnabled) {
|
|
1444
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForStyling);
|
|
1405
1445
|
}
|
|
1406
|
-
return lockedString(UIStringsNotTranslate.
|
|
1446
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForStylingEnterpriseNoLogging);
|
|
1407
1447
|
case AiAssistanceModel.AiHistoryStorage.ConversationType.FILE:
|
|
1408
|
-
if (
|
|
1409
|
-
return lockedString(UIStringsNotTranslate.
|
|
1448
|
+
if (loggingEnabled) {
|
|
1449
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForFile);
|
|
1410
1450
|
}
|
|
1411
|
-
return lockedString(UIStringsNotTranslate.
|
|
1451
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForFileEnterpriseNoLogging);
|
|
1412
1452
|
case AiAssistanceModel.AiHistoryStorage.ConversationType.NETWORK:
|
|
1413
|
-
if (
|
|
1414
|
-
return lockedString(UIStringsNotTranslate.
|
|
1453
|
+
if (loggingEnabled) {
|
|
1454
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForNetwork);
|
|
1415
1455
|
}
|
|
1416
|
-
return lockedString(UIStringsNotTranslate.
|
|
1456
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForNetworkEnterpriseNoLogging);
|
|
1417
1457
|
|
|
1418
1458
|
// It is deliberate that both Performance agents use the same disclaimer
|
|
1419
1459
|
// text and this has been approved by Privacy.
|
|
1420
1460
|
case AiAssistanceModel.AiHistoryStorage.ConversationType.PERFORMANCE:
|
|
1421
|
-
if (
|
|
1422
|
-
return lockedString(UIStringsNotTranslate.
|
|
1461
|
+
if (loggingEnabled) {
|
|
1462
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForPerformance);
|
|
1423
1463
|
}
|
|
1424
|
-
return lockedString(UIStringsNotTranslate.
|
|
1464
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForPerformanceEnterpriseNoLogging);
|
|
1425
1465
|
|
|
1426
1466
|
case AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY:
|
|
1427
|
-
if (
|
|
1428
|
-
return lockedString(UIStringsNotTranslate.
|
|
1467
|
+
if (loggingEnabled) {
|
|
1468
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForAccessibility);
|
|
1429
1469
|
}
|
|
1430
|
-
return lockedString(UIStringsNotTranslate.
|
|
1470
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForAccessibilityEnterpriseNoLogging);
|
|
1431
1471
|
|
|
1432
1472
|
case AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT:
|
|
1433
1473
|
|
|
1434
1474
|
case AiAssistanceModel.AiHistoryStorage.ConversationType.NONE:
|
|
1435
|
-
if (
|
|
1436
|
-
return lockedString(UIStringsNotTranslate.
|
|
1475
|
+
if (loggingEnabled) {
|
|
1476
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForNoContext);
|
|
1437
1477
|
}
|
|
1438
|
-
return lockedString(UIStringsNotTranslate.
|
|
1478
|
+
return lockedString(UIStringsNotTranslate.inputDisclaimerForNoContextEnterpriseNoLogging);
|
|
1439
1479
|
}
|
|
1440
1480
|
}
|
|
1441
1481
|
|
|
@@ -13,7 +13,6 @@ import * as i18n from '../../core/i18n/i18n.js';
|
|
|
13
13
|
import * as Platform from '../../core/platform/platform.js';
|
|
14
14
|
import * as Root from '../../core/root/root.js';
|
|
15
15
|
import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
|
|
16
|
-
import * as GreenDev from '../../models/greendev/greendev.js';
|
|
17
16
|
import * as Persistence from '../../models/persistence/persistence.js';
|
|
18
17
|
import * as Workspace from '../../models/workspace/workspace.js';
|
|
19
18
|
import * as WorkspaceDiff from '../../models/workspace_diff/workspace_diff.js';
|
|
@@ -273,20 +272,6 @@ const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
273
272
|
nothing}`;
|
|
274
273
|
}
|
|
275
274
|
|
|
276
|
-
function renderCopyPrompt(changedCode?: string): LitTemplate {
|
|
277
|
-
if (!GreenDev.Prototypes.instance().isEnabled('copyToGemini') || !changedCode) {
|
|
278
|
-
return nothing;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
// clang-format off
|
|
282
|
-
return html`<devtools-widget class="copy-to-prompt"
|
|
283
|
-
${widget(PanelCommon.CopyChangesToPrompt, {
|
|
284
|
-
workspaceDiff: input.workspaceDiff,
|
|
285
|
-
patchAgentCSSChange: changedCode,
|
|
286
|
-
})}></devtools-widget>`;
|
|
287
|
-
// clang-format on
|
|
288
|
-
}
|
|
289
|
-
|
|
290
275
|
function renderFooter(): LitTemplate {
|
|
291
276
|
if (input.savedToDisk) {
|
|
292
277
|
return nothing;
|
|
@@ -357,7 +342,6 @@ const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
357
342
|
</div>
|
|
358
343
|
` :
|
|
359
344
|
html`
|
|
360
|
-
${renderCopyPrompt(input.changeSummary)}
|
|
361
345
|
<devtools-button
|
|
362
346
|
@click=${input.onApplyToWorkspace}
|
|
363
347
|
.jslogContext=${'patch-widget.apply-to-workspace'}
|
|
@@ -435,7 +419,7 @@ export class PatchWidget extends UI.Widget.Widget {
|
|
|
435
419
|
#project?: Workspace.Workspace.Project;
|
|
436
420
|
#patchSources?: string;
|
|
437
421
|
#savedToDisk?: boolean;
|
|
438
|
-
#
|
|
422
|
+
#loggingEnabled: boolean; // Whether the enterprise setting is `ALLOW_WITHOUT_LOGGING` or not.
|
|
439
423
|
#patchSuggestionState = PatchSuggestionState.INITIAL;
|
|
440
424
|
#workspaceDiff = WorkspaceDiff.WorkspaceDiff.workspaceDiff();
|
|
441
425
|
#workspace = Workspace.Workspace.WorkspaceImpl.instance();
|
|
@@ -450,7 +434,7 @@ export class PatchWidget extends UI.Widget.Widget {
|
|
|
450
434
|
}) {
|
|
451
435
|
super(element);
|
|
452
436
|
this.#aidaClient = opts?.aidaClient ?? new Host.AidaClient.AidaClient();
|
|
453
|
-
this.#
|
|
437
|
+
this.#loggingEnabled = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue !==
|
|
454
438
|
Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
|
|
455
439
|
this.#view = view;
|
|
456
440
|
|
|
@@ -514,9 +498,9 @@ export class PatchWidget extends UI.Widget.Widget {
|
|
|
514
498
|
projectPath,
|
|
515
499
|
projectType: this.#getSelectedProjectType(projectPath),
|
|
516
500
|
savedToDisk: this.#savedToDisk,
|
|
517
|
-
applyToWorkspaceTooltipText: this.#
|
|
518
|
-
lockedString(UIStringsNotTranslate.
|
|
519
|
-
lockedString(UIStringsNotTranslate.
|
|
501
|
+
applyToWorkspaceTooltipText: this.#loggingEnabled ?
|
|
502
|
+
lockedString(UIStringsNotTranslate.applyToWorkspaceTooltip) :
|
|
503
|
+
lockedString(UIStringsNotTranslate.applyToWorkspaceTooltipNoLogging),
|
|
520
504
|
onLearnMoreTooltipClick: this.#onLearnMoreTooltipClick.bind(this),
|
|
521
505
|
onApplyToWorkspace: this.#onApplyToWorkspace.bind(this),
|
|
522
506
|
onCancel: () => {
|
|
@@ -566,8 +550,8 @@ export class PatchWidget extends UI.Widget.Widget {
|
|
|
566
550
|
},
|
|
567
551
|
{
|
|
568
552
|
iconName: 'google',
|
|
569
|
-
content: this.#
|
|
570
|
-
|
|
553
|
+
content: this.#loggingEnabled ? lockedString(UIStringsNotTranslate.freDisclaimerTextPrivacy) :
|
|
554
|
+
lockedString(UIStringsNotTranslate.freDisclaimerTextPrivacyNoLogging),
|
|
571
555
|
},
|
|
572
556
|
{
|
|
573
557
|
iconName: 'warning',
|
|
@@ -233,14 +233,14 @@ export class SelectWorkspaceDialog extends UI.Widget.VBox {
|
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
override performUpdate(): void {
|
|
236
|
-
const
|
|
236
|
+
const loggingEnabled = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue !==
|
|
237
237
|
Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
|
|
238
238
|
|
|
239
239
|
const viewInput = {
|
|
240
240
|
folders: this.#folders,
|
|
241
241
|
selectedIndex: this.#selectedIndex,
|
|
242
|
-
selectProjectRootText:
|
|
243
|
-
|
|
242
|
+
selectProjectRootText: loggingEnabled ? lockedString(UIStringsNotTranslate.selectProjectRoot) :
|
|
243
|
+
lockedString(UIStringsNotTranslate.selectProjectRootNoLogging),
|
|
244
244
|
showAutomaticWorkspaceNudge: this.#automaticFileSystemManager.automaticFileSystem === null &&
|
|
245
245
|
this.#automaticFileSystemManager.availability === 'available',
|
|
246
246
|
onProjectSelected: (index: number) => {
|
|
@@ -161,6 +161,13 @@ Common.Settings.registerSettingExtension({
|
|
|
161
161
|
},
|
|
162
162
|
});
|
|
163
163
|
|
|
164
|
+
Common.Settings.registerSettingExtension({
|
|
165
|
+
category: Common.Settings.SettingCategory.AI,
|
|
166
|
+
settingName: 'ai-assistance-v2-opt-in-change-dialog-seen',
|
|
167
|
+
settingType: Common.Settings.SettingType.BOOLEAN,
|
|
168
|
+
defaultValue: false,
|
|
169
|
+
});
|
|
170
|
+
|
|
164
171
|
UI.ActionRegistration.registerActionExtension({
|
|
165
172
|
actionId: 'freestyler.main-menu',
|
|
166
173
|
contextTypes(): [] {
|
|
@@ -11,6 +11,7 @@ export * from './SelectWorkspaceDialog.js';
|
|
|
11
11
|
export * as ChatMessage from './components/ChatMessage.js';
|
|
12
12
|
export * as ExploreWidget from './components/ExploreWidget.js';
|
|
13
13
|
export * as ExportForAgentsDialog from './components/ExportForAgentsDialog.js';
|
|
14
|
+
export * as OptInChangeDialog from './components/OptInChangeDialog.js';
|
|
14
15
|
export * as PatchWidget from './PatchWidget.js';
|
|
15
16
|
export * as DisabledWidget from './components/DisabledWidget.js';
|
|
16
17
|
export * as WalkthroughView from './components/WalkthroughView.js';
|
|
@@ -282,6 +282,10 @@ export class ChatView extends HTMLElement {
|
|
|
282
282
|
textArea.focus();
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
setInputValue(text: string): void {
|
|
286
|
+
this.#output.input?.getWidget()?.setInputValue(text);
|
|
287
|
+
}
|
|
288
|
+
|
|
285
289
|
restoreScrollPosition(): void {
|
|
286
290
|
if (this.#scrollTop === undefined) {
|
|
287
291
|
return;
|
|
@@ -59,6 +59,8 @@ export const enum StateType {
|
|
|
59
59
|
CONVERSATION = 'conversation',
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
const DEFAULT_STATE_TYPE = StateType.PROMPT;
|
|
63
|
+
|
|
62
64
|
export interface State {
|
|
63
65
|
activeType: StateType;
|
|
64
66
|
promptText: string;
|
|
@@ -78,9 +80,7 @@ type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
|
|
|
78
80
|
export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
79
81
|
const isPrompt = input.state.activeType === StateType.PROMPT;
|
|
80
82
|
const buttonText = isPrompt ? i18nString(UIStrings.copyToClipboard) : i18nString(UIStrings.saveAsMarkdown);
|
|
81
|
-
const exportText = isPrompt
|
|
82
|
-
i18nString(UIStrings.generatingSummary) :
|
|
83
|
-
(isPrompt ? input.state.promptText : input.state.conversationText);
|
|
83
|
+
const exportText = isPrompt ? input.state.promptText : input.state.conversationText;
|
|
84
84
|
// clang-format off
|
|
85
85
|
|
|
86
86
|
render(html`
|
|
@@ -116,13 +116,13 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
|
116
116
|
</label>
|
|
117
117
|
</div>
|
|
118
118
|
<main>
|
|
119
|
-
${input.state.isPromptLoading ? html`
|
|
119
|
+
${isPrompt && input.state.isPromptLoading ? html`
|
|
120
120
|
<span class="prompt-loading">
|
|
121
121
|
<devtools-spinner></devtools-spinner>
|
|
122
122
|
${i18nString(UIStrings.generatingSummary)}
|
|
123
123
|
</span>
|
|
124
124
|
` : Lit.nothing}
|
|
125
|
-
<textarea readonly .value=${input.state.isPromptLoading ? '' : exportText}></textarea>
|
|
125
|
+
<textarea readonly .value=${isPrompt && input.state.isPromptLoading ? '' : exportText}></textarea>
|
|
126
126
|
</main>
|
|
127
127
|
<div class="disclaimer">${i18nString(UIStrings.disclaimer)}</div>
|
|
128
128
|
<footer>
|
|
@@ -144,6 +144,7 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
|
|
|
144
144
|
};
|
|
145
145
|
|
|
146
146
|
export class ExportForAgentsDialog extends UI.Widget.VBox {
|
|
147
|
+
static #lastSelectedType: StateType = DEFAULT_STATE_TYPE;
|
|
147
148
|
readonly #view: View;
|
|
148
149
|
readonly #dialog: UI.Dialog.Dialog;
|
|
149
150
|
#state: State;
|
|
@@ -160,7 +161,7 @@ export class ExportForAgentsDialog extends UI.Widget.VBox {
|
|
|
160
161
|
super();
|
|
161
162
|
this.#dialog = options.dialog;
|
|
162
163
|
this.#state = {
|
|
163
|
-
activeType:
|
|
164
|
+
activeType: ExportForAgentsDialog.#lastSelectedType,
|
|
164
165
|
promptText: typeof options.promptText === 'string' ? options.promptText : '',
|
|
165
166
|
conversationText: options.markdownText,
|
|
166
167
|
isPromptLoading: typeof options.promptText !== 'string',
|
|
@@ -179,8 +180,13 @@ export class ExportForAgentsDialog extends UI.Widget.VBox {
|
|
|
179
180
|
this.requestUpdate();
|
|
180
181
|
}
|
|
181
182
|
|
|
183
|
+
static clearPersistedViewState(): void {
|
|
184
|
+
ExportForAgentsDialog.#lastSelectedType = DEFAULT_STATE_TYPE;
|
|
185
|
+
}
|
|
186
|
+
|
|
182
187
|
#onStateChange = (newState: StateType): void => {
|
|
183
188
|
this.#state.activeType = newState;
|
|
189
|
+
ExportForAgentsDialog.#lastSelectedType = newState;
|
|
184
190
|
this.requestUpdate();
|
|
185
191
|
};
|
|
186
192
|
|