chrome-devtools-frontend 1.0.1603822 → 1.0.1605219
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/AUTHORS +1 -0
- package/front_end/Tests.js +23 -7
- package/front_end/core/host/AidaClient.ts +153 -525
- package/front_end/core/host/AidaClientTypes.ts +470 -0
- package/front_end/core/host/AidaGcaTranslation.ts +231 -122
- package/front_end/core/host/GcaClient.ts +112 -0
- package/front_end/core/host/GcaTypes.ts +107 -155
- package/front_end/core/host/UserMetrics.ts +0 -1
- package/front_end/core/host/host.ts +2 -0
- package/front_end/core/protocol_client/DevToolsCDPConnection.ts +1 -1
- package/front_end/core/root/ExperimentNames.ts +0 -1
- package/front_end/core/root/Runtime.ts +5 -0
- package/front_end/core/sdk/AutofillModel.ts +3 -2
- package/front_end/core/sdk/CSSModel.ts +3 -4
- package/front_end/core/sdk/CSSProperty.ts +1 -1
- package/front_end/core/sdk/ConsoleModel.ts +15 -13
- package/front_end/core/sdk/CookieModel.ts +5 -4
- package/front_end/core/sdk/DOMDebuggerModel.ts +20 -14
- package/front_end/core/sdk/DOMModel.ts +24 -22
- package/front_end/core/sdk/DebuggerModel.ts +21 -36
- package/front_end/core/sdk/EmulationModel.ts +21 -23
- package/front_end/core/sdk/EventBreakpointsModel.ts +16 -6
- package/front_end/core/sdk/HeapProfilerModel.ts +4 -7
- package/front_end/core/sdk/IsolateManager.ts +12 -7
- package/front_end/core/sdk/NetworkManager.ts +35 -28
- package/front_end/core/sdk/OverlayModel.ts +10 -10
- package/front_end/core/sdk/PreloadingModel.ts +3 -4
- package/front_end/core/sdk/ServiceWorkerManager.ts +2 -3
- package/front_end/core/sdk/SourceMapScopesInfo.ts +93 -63
- package/front_end/entrypoints/formatter_worker/FormatterWorker.ts +1 -3
- package/front_end/entrypoints/heap_snapshot_worker/AllocationProfile.ts +22 -48
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +1 -1
- package/front_end/entrypoints/main/MainImpl.ts +0 -4
- package/front_end/generated/InspectorBackendCommands.ts +4 -0
- package/front_end/generated/SupportedCSSProperties.js +68 -2
- package/front_end/generated/protocol-mapping.d.ts +7 -0
- package/front_end/generated/protocol-proxy-api.d.ts +14 -0
- package/front_end/generated/protocol.ts +22 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +31 -17
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +1 -1
- package/front_end/models/bindings/TempFile.ts +1 -4
- package/front_end/models/emulation/DeviceModeModel.ts +21 -26
- package/front_end/models/extensions/ExtensionAPI.ts +1 -1
- package/front_end/models/heap_snapshot_model/HeapSnapshotModel.ts +34 -47
- package/front_end/models/javascript_metadata/NativeFunctions.js +6 -6
- package/front_end/models/trace/insights/LCPDiscovery.ts +14 -6
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +85 -31
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +50 -40
- package/front_end/panels/ai_assistance/components/ChatView.ts +3 -2
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +35 -7
- package/front_end/panels/ai_assistance/components/chatMessage.css +5 -1
- package/front_end/panels/application/ApplicationPanelSidebar.ts +6 -0
- package/front_end/panels/application/IndexedDBViews.ts +0 -9
- package/front_end/panels/application/WebMCPTreeElement.ts +35 -0
- package/front_end/panels/application/WebMCPView.ts +118 -0
- package/front_end/panels/application/application.ts +4 -0
- package/front_end/panels/application/webMCPView.css +65 -0
- package/front_end/panels/common/aiCodeCompletionSummaryToolbar.css +1 -1
- package/front_end/panels/console/consoleView.css +4 -0
- package/front_end/panels/elements/ElementsTreeElement.ts +91 -13
- package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +23 -2
- package/front_end/panels/elements/StylesSidebarPane.ts +85 -20
- package/front_end/panels/elements/elementsPanel.css +14 -0
- package/front_end/panels/elements/elementsTreeOutline.css +18 -0
- package/front_end/panels/network/NetworkLogViewColumns.ts +3 -3
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +15 -19
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +4 -2
- package/front_end/panels/profiler/HeapSnapshotProxy.ts +12 -16
- package/front_end/panels/profiler/HeapSnapshotView.ts +3 -10
- package/front_end/panels/profiler/ProfilesPanel.ts +5 -7
- package/front_end/panels/recorder/components/recordingView.css +0 -6
- package/front_end/panels/sensors/SensorsView.ts +28 -61
- package/front_end/panels/timeline/EventsTimelineTreeView.ts +2 -2
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +35 -36
- package/front_end/panels/timeline/TimelineDetailsView.ts +47 -41
- package/front_end/panels/timeline/TimelinePanel.ts +1 -3
- package/front_end/panels/timeline/TimelineTreeView.ts +13 -13
- package/front_end/panels/timeline/components/LiveMetricsView.ts +852 -824
- package/front_end/panels/timeline/components/liveMetricsView.css +4 -0
- package/front_end/panels/timeline/thirdPartyTreeView.css +2 -2
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/buttons/button.css +2 -2
- package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +0 -11
- package/front_end/ui/legacy/InspectorDrawerView.ts +206 -0
- package/front_end/ui/legacy/InspectorView.ts +41 -91
- package/front_end/ui/legacy/ViewManager.ts +14 -5
- package/front_end/ui/legacy/inspectorDrawerTabbedPane.css +5 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -1
- package/package.json +1 -1
|
@@ -2,18 +2,19 @@
|
|
|
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 AIDA from './
|
|
5
|
+
import * as AIDA from './AidaClientTypes.js';
|
|
6
6
|
import * as GCA from './GcaTypes.js';
|
|
7
7
|
|
|
8
8
|
type AidaRequest = AIDA.DoConversationRequest|AIDA.CompletionRequest|AIDA.GenerateCodeRequest;
|
|
9
9
|
|
|
10
|
-
function createBaseGcaRequest(
|
|
11
|
-
|
|
10
|
+
function createBaseGcaRequest(
|
|
11
|
+
request: AidaRequest, contents: GCA.Content[], experience: string): GCA.GenerateContentRequest {
|
|
12
|
+
const gcaRequest: GCA.GenerateContentRequest = {contents, aicode: {experience}};
|
|
12
13
|
mapCommonAidaRequestFields(request, gcaRequest);
|
|
13
14
|
buildLabels(request, gcaRequest);
|
|
14
15
|
|
|
15
16
|
if ('preamble' in request && request.preamble) {
|
|
16
|
-
gcaRequest.
|
|
17
|
+
gcaRequest.systemInstruction = {
|
|
17
18
|
role: 'user',
|
|
18
19
|
parts: [{text: request.preamble}],
|
|
19
20
|
};
|
|
@@ -23,38 +24,41 @@ function createBaseGcaRequest(request: AidaRequest, contents: GCA.Content[]): GC
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export function aidaDoConversationRequestToGcaRequest(request: AIDA.DoConversationRequest): GCA.GenerateContentRequest {
|
|
26
|
-
|
|
27
|
+
try {
|
|
28
|
+
const contents: GCA.Content[] = [];
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
30
|
+
if (request.historical_contexts) {
|
|
31
|
+
contents.push(...(request.historical_contexts).map(convertAidaContentToGcaContent));
|
|
32
|
+
}
|
|
33
|
+
contents.push(convertAidaContentToGcaContent(request.current_message));
|
|
34
|
+
|
|
35
|
+
const gcaRequest = createBaseGcaRequest(request, contents, 'chat_console_insights');
|
|
36
|
+
|
|
37
|
+
if (request.function_declarations) {
|
|
38
|
+
gcaRequest.tools = [{
|
|
39
|
+
functionDeclarations:
|
|
40
|
+
(request.function_declarations).map(fd => ({
|
|
41
|
+
name: fd.name,
|
|
42
|
+
description: fd.description,
|
|
43
|
+
parameters: convertAidaParamToGcaSchema(fd.parameters),
|
|
44
|
+
})),
|
|
45
|
+
}];
|
|
46
|
+
}
|
|
47
|
+
AIDA.debugLog('Translation succeded:', JSON.stringify(request), JSON.stringify(gcaRequest));
|
|
48
|
+
return gcaRequest;
|
|
49
|
+
} catch (e) {
|
|
50
|
+
AIDA.debugLog('Translation error:', JSON.stringify(request), e);
|
|
51
|
+
throw e;
|
|
43
52
|
}
|
|
44
|
-
|
|
45
|
-
return gcaRequest;
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
function mapCommonAidaRequestFields(aidaRequest: AidaRequest, gcaRequest: GCA.GenerateContentRequest): void {
|
|
49
56
|
if (aidaRequest.options?.model_id) {
|
|
50
57
|
gcaRequest.model = aidaRequest.options.model_id;
|
|
51
58
|
}
|
|
52
|
-
if (aidaRequest.metadata.string_session_id) {
|
|
53
|
-
gcaRequest.session_id = aidaRequest.metadata.string_session_id;
|
|
54
|
-
}
|
|
55
59
|
if (aidaRequest.options?.temperature !== undefined) {
|
|
56
|
-
gcaRequest.
|
|
57
|
-
...gcaRequest.
|
|
60
|
+
gcaRequest.generationConfig = {
|
|
61
|
+
...gcaRequest.generationConfig,
|
|
58
62
|
temperature: aidaRequest.options.temperature,
|
|
59
63
|
};
|
|
60
64
|
}
|
|
@@ -62,24 +66,23 @@ function mapCommonAidaRequestFields(aidaRequest: AidaRequest, gcaRequest: GCA.Ge
|
|
|
62
66
|
|
|
63
67
|
export function gcaResponseToAidaDoConversationResponse(response: GCA.GenerateContentResponse):
|
|
64
68
|
AIDA.DoConversationResponse {
|
|
65
|
-
const candidate = response.candidates[0];
|
|
66
69
|
const functionCalls: AIDA.AidaFunctionCallResponse[] = [];
|
|
67
70
|
|
|
68
|
-
if (
|
|
69
|
-
for (const part of
|
|
70
|
-
if (part.
|
|
71
|
+
if (response.candidates?.[0].content?.parts) {
|
|
72
|
+
for (const part of response.candidates[0].content.parts) {
|
|
73
|
+
if (part.functionCall) {
|
|
71
74
|
functionCalls.push({
|
|
72
|
-
name: part.
|
|
73
|
-
args: part.
|
|
75
|
+
name: part.functionCall.name,
|
|
76
|
+
args: part.functionCall.args || {},
|
|
74
77
|
});
|
|
75
78
|
}
|
|
76
79
|
}
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
return {
|
|
80
|
-
explanation: extractTextFromGcaParts(
|
|
83
|
+
explanation: extractTextFromGcaParts(response.candidates[0].content?.parts),
|
|
81
84
|
metadata: {
|
|
82
|
-
rpcGlobalId: response.
|
|
85
|
+
rpcGlobalId: response.responseId,
|
|
83
86
|
},
|
|
84
87
|
functionCalls: functionCalls.length > 0 ?
|
|
85
88
|
(functionCalls as [AIDA.AidaFunctionCallResponse, ...AIDA.AidaFunctionCallResponse[]]) :
|
|
@@ -96,33 +99,41 @@ function extractTextFromGcaParts(parts: GCA.Part[]|undefined): string {
|
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
export function aidaEventToGcaTelemetryRequest(clientEvent: AIDA.AidaRegisterClientEvent): GCA.SendTelemetryRequest {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
102
|
+
try {
|
|
103
|
+
const feedbackMetrics: GCA.FeedbackMetric[] = [];
|
|
104
|
+
const responseId = String(clientEvent.corresponding_aida_rpc_global_id);
|
|
105
|
+
const eventTime = new Date().toISOString();
|
|
106
|
+
|
|
107
|
+
if (clientEvent.do_conversation_client_event) {
|
|
108
|
+
const feedback = clientEvent.do_conversation_client_event.user_feedback;
|
|
109
|
+
if (feedback.sentiment) {
|
|
110
|
+
let interaction: GCA.InteractionType = GCA.InteractionType.INTERACTION_TYPE_UNSPECIFIED;
|
|
111
|
+
if (feedback.sentiment === AIDA.Rating.POSITIVE) {
|
|
112
|
+
interaction = GCA.InteractionType.THUMBS_UP;
|
|
113
|
+
} else if (feedback.sentiment === AIDA.Rating.NEGATIVE) {
|
|
114
|
+
interaction = GCA.InteractionType.THUMBS_DOWN;
|
|
115
|
+
}
|
|
116
|
+
feedbackMetrics.push({
|
|
117
|
+
eventTime,
|
|
118
|
+
responseId,
|
|
119
|
+
suggestionInteraction: {interaction},
|
|
120
|
+
});
|
|
111
121
|
}
|
|
112
|
-
feedbackMetrics.push({
|
|
113
|
-
event_time: eventTime,
|
|
114
|
-
response_id: responseId,
|
|
115
|
-
suggestion_interaction: {interaction},
|
|
116
|
-
});
|
|
117
122
|
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
feedbackMetrics.push(
|
|
121
|
-
...convertCodeTelemetry(clientEvent.complete_code_client_event, GCA.Method.COMPLETE_CODE, responseId, eventTime));
|
|
122
|
-
feedbackMetrics.push(
|
|
123
|
-
...convertCodeTelemetry(clientEvent.generate_code_client_event, GCA.Method.GENERATE_CODE, responseId, eventTime));
|
|
124
123
|
|
|
125
|
-
|
|
124
|
+
feedbackMetrics.push(...convertCodeTelemetry(
|
|
125
|
+
clientEvent.complete_code_client_event, GCA.Method.COMPLETE_CODE, responseId, eventTime));
|
|
126
|
+
feedbackMetrics.push(...convertCodeTelemetry(
|
|
127
|
+
clientEvent.generate_code_client_event, GCA.Method.GENERATE_CODE, responseId, eventTime));
|
|
128
|
+
const gcaTelemetryRequest: GCA.SendTelemetryRequest = {
|
|
129
|
+
feedbackMetrics,
|
|
130
|
+
};
|
|
131
|
+
AIDA.debugLog('Translation succeeded:', JSON.stringify(clientEvent), JSON.stringify(gcaTelemetryRequest));
|
|
132
|
+
return gcaTelemetryRequest;
|
|
133
|
+
} catch (e) {
|
|
134
|
+
AIDA.debugLog('Translation error:', JSON.stringify(clientEvent), e);
|
|
135
|
+
throw e;
|
|
136
|
+
}
|
|
126
137
|
}
|
|
127
138
|
|
|
128
139
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
@@ -135,23 +146,23 @@ function convertCodeTelemetry(
|
|
|
135
146
|
if ('user_impression' in event && event.user_impression) {
|
|
136
147
|
const impression = event.user_impression;
|
|
137
148
|
return [{
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
149
|
+
eventTime,
|
|
150
|
+
responseId,
|
|
151
|
+
suggestionOffered: {
|
|
141
152
|
method,
|
|
142
153
|
status: GCA.SuggestionStatus.NO_ERROR,
|
|
143
|
-
|
|
154
|
+
responseLatency: `${impression.latency.duration.seconds + impression.latency.duration.nanos / 1e9}s`,
|
|
144
155
|
},
|
|
145
156
|
}];
|
|
146
157
|
}
|
|
147
158
|
if ('user_acceptance' in event && event.user_acceptance) {
|
|
148
159
|
const acceptance = event.user_acceptance;
|
|
149
160
|
return [{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
161
|
+
eventTime,
|
|
162
|
+
responseId,
|
|
163
|
+
suggestionInteraction: {
|
|
153
164
|
interaction: GCA.InteractionType.ACCEPT,
|
|
154
|
-
|
|
165
|
+
candidateIndex: acceptance.sample.sample_id,
|
|
155
166
|
},
|
|
156
167
|
}];
|
|
157
168
|
}
|
|
@@ -160,33 +171,56 @@ function convertCodeTelemetry(
|
|
|
160
171
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
161
172
|
|
|
162
173
|
export function aidaCompletionRequestToGcaRequest(request: AIDA.CompletionRequest): GCA.GenerateContentRequest {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
174
|
+
try {
|
|
175
|
+
let additionalFiles: GCA.SourceFile[] =
|
|
176
|
+
(request.additional_files ?? []).map(f => ({
|
|
177
|
+
fileUri: f.path,
|
|
178
|
+
inclusionReason: [AidaReasonToGcaInclusionReason[f.included_reason]],
|
|
179
|
+
}));
|
|
180
|
+
|
|
181
|
+
const inEditorFile: GCA.SourceFile = inFileEditRequestToSourceFile(request);
|
|
182
|
+
if (inEditorFile) {
|
|
183
|
+
additionalFiles = [inEditorFile, ...additionalFiles];
|
|
184
|
+
}
|
|
171
185
|
|
|
172
|
-
|
|
173
|
-
gcaRequest.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
186
|
+
const gcaRequest = createBaseGcaRequest(request, [], 'complete_code');
|
|
187
|
+
gcaRequest.aicode.files = additionalFiles;
|
|
188
|
+
if (request.options?.stop_sequences) {
|
|
189
|
+
gcaRequest.generationConfig = {
|
|
190
|
+
...gcaRequest.generationConfig,
|
|
191
|
+
stopSequences: request.options.stop_sequences,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
AIDA.debugLog('Translation succeeded:', JSON.stringify(request), JSON.stringify(gcaRequest));
|
|
195
|
+
return gcaRequest;
|
|
196
|
+
} catch (e) {
|
|
197
|
+
AIDA.debugLog('Translation error:', JSON.stringify(request), e);
|
|
198
|
+
throw e;
|
|
177
199
|
}
|
|
200
|
+
}
|
|
178
201
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
202
|
+
function inFileEditRequestToSourceFile(request: AIDA.CompletionRequest): GCA.SourceFile {
|
|
203
|
+
const sourceFile: GCA.SourceFile = {
|
|
204
|
+
inclusionReason: [GCA.InclusionReason.ACTIVE],
|
|
205
|
+
fileUri: 'devtools-code-completion',
|
|
206
|
+
segments: [
|
|
207
|
+
{
|
|
208
|
+
content: request.prefix,
|
|
209
|
+
isSelected: false,
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
content: '',
|
|
213
|
+
isSelected: true, // Cursor position
|
|
214
|
+
}
|
|
215
|
+
],
|
|
216
|
+
};
|
|
217
|
+
if (request.suffix) {
|
|
218
|
+
sourceFile.segments?.push({
|
|
219
|
+
content: request.suffix,
|
|
220
|
+
isSelected: false,
|
|
221
|
+
});
|
|
187
222
|
}
|
|
188
|
-
|
|
189
|
-
return gcaRequest;
|
|
223
|
+
return sourceFile;
|
|
190
224
|
}
|
|
191
225
|
|
|
192
226
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
@@ -207,6 +241,9 @@ function buildLabels(request: AidaRequest, gcaRequest: GCA.GenerateContentReques
|
|
|
207
241
|
if ('use_case' in request && request.use_case !== undefined) {
|
|
208
242
|
labels['use_case'] = AIDA.UseCase[request.use_case];
|
|
209
243
|
}
|
|
244
|
+
if (request.metadata.string_session_id) {
|
|
245
|
+
labels['session_id'] = request.metadata.string_session_id;
|
|
246
|
+
}
|
|
210
247
|
const options = request.options as {
|
|
211
248
|
inference_language?: string,
|
|
212
249
|
expect_code_output?: boolean,
|
|
@@ -217,6 +254,12 @@ function buildLabels(request: AidaRequest, gcaRequest: GCA.GenerateContentReques
|
|
|
217
254
|
if (options?.expect_code_output !== undefined) {
|
|
218
255
|
labels['expect_code_output'] = String(options.expect_code_output);
|
|
219
256
|
}
|
|
257
|
+
if (request.metadata.disable_user_content_logging !== undefined) {
|
|
258
|
+
labels['disable_user_content_logging'] = String(request.metadata.disable_user_content_logging);
|
|
259
|
+
}
|
|
260
|
+
if (request.metadata.client_version) {
|
|
261
|
+
labels['client_version'] = request.metadata.client_version;
|
|
262
|
+
}
|
|
220
263
|
|
|
221
264
|
if (Object.keys(labels).length > 0) {
|
|
222
265
|
gcaRequest.labels = labels;
|
|
@@ -236,11 +279,18 @@ const AidaReasonToGcaInclusionReason: Record<AIDA.Reason, GCA.InclusionReason> =
|
|
|
236
279
|
};
|
|
237
280
|
|
|
238
281
|
export function gcaResponseToAidaCompletionResponse(response: GCA.GenerateContentResponse): AIDA.CompletionResponse {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
282
|
+
try {
|
|
283
|
+
const {samples, metadata} = gcaResponseToAidaSamplesAndMetadata(response);
|
|
284
|
+
const aidaResponse: AIDA.CompletionResponse = {
|
|
285
|
+
generatedSamples: samples,
|
|
286
|
+
metadata,
|
|
287
|
+
};
|
|
288
|
+
AIDA.debugLog('Translation succeeded:', JSON.stringify(response), JSON.stringify(aidaResponse));
|
|
289
|
+
return aidaResponse;
|
|
290
|
+
} catch (e) {
|
|
291
|
+
AIDA.debugLog('Translation error', JSON.stringify(response), e);
|
|
292
|
+
throw e;
|
|
293
|
+
}
|
|
244
294
|
}
|
|
245
295
|
|
|
246
296
|
function gcaResponseToAidaSamplesAndMetadata(response: GCA.GenerateContentResponse): {
|
|
@@ -248,32 +298,41 @@ function gcaResponseToAidaSamplesAndMetadata(response: GCA.GenerateContentRespon
|
|
|
248
298
|
metadata: AIDA.ResponseMetadata,
|
|
249
299
|
} {
|
|
250
300
|
return {
|
|
251
|
-
samples: response.candidates.map(gcaCandidateToAidaGenerationSample),
|
|
301
|
+
samples: (response.candidates ?? []).map(gcaCandidateToAidaGenerationSample),
|
|
252
302
|
metadata: {
|
|
253
|
-
rpcGlobalId: response.
|
|
303
|
+
rpcGlobalId: response.responseId,
|
|
254
304
|
},
|
|
255
305
|
};
|
|
256
306
|
}
|
|
257
307
|
|
|
258
308
|
export function aidaGenerateCodeRequestToGcaRequest(request: AIDA.GenerateCodeRequest): GCA.GenerateContentRequest {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
309
|
+
try {
|
|
310
|
+
const gcaRequest =
|
|
311
|
+
createBaseGcaRequest(request, [convertAidaContentToGcaContent(request.current_message)], 'generate_code');
|
|
312
|
+
if (request.context_files) {
|
|
313
|
+
gcaRequest.aicode.files = (request.context_files).map(f => ({
|
|
314
|
+
fileUri: f.path,
|
|
315
|
+
programmingLanguage: f.programming_language,
|
|
316
|
+
}));
|
|
317
|
+
}
|
|
318
|
+
AIDA.debugLog('Translation succeeded:', JSON.stringify(request), JSON.stringify(gcaRequest));
|
|
319
|
+
return gcaRequest;
|
|
320
|
+
} catch (e) {
|
|
321
|
+
AIDA.debugLog('Translation error', JSON.stringify(request), e);
|
|
322
|
+
throw e;
|
|
269
323
|
}
|
|
270
|
-
|
|
271
|
-
return gcaRequest;
|
|
272
324
|
}
|
|
273
325
|
|
|
274
326
|
export function gcaResponseToAidaGenerateCodeResponse(response: GCA.GenerateContentResponse):
|
|
275
327
|
AIDA.GenerateCodeResponse {
|
|
276
|
-
|
|
328
|
+
try {
|
|
329
|
+
const aidaResponse: AIDA.GenerateCodeResponse = gcaResponseToAidaSamplesAndMetadata(response);
|
|
330
|
+
AIDA.debugLog('Translation succeeded:', JSON.stringify(response), JSON.stringify(aidaResponse));
|
|
331
|
+
return aidaResponse;
|
|
332
|
+
} catch (e) {
|
|
333
|
+
AIDA.debugLog('translation error', JSON.stringify(response), e);
|
|
334
|
+
throw e;
|
|
335
|
+
}
|
|
277
336
|
}
|
|
278
337
|
|
|
279
338
|
function gcaCandidateToAidaGenerationSample(candidate: GCA.Candidate): AIDA.GenerationSample {
|
|
@@ -282,14 +341,14 @@ function gcaCandidateToAidaGenerationSample(candidate: GCA.Candidate): AIDA.Gene
|
|
|
282
341
|
score: 0,
|
|
283
342
|
sampleId: candidate.index,
|
|
284
343
|
};
|
|
285
|
-
if (candidate.
|
|
344
|
+
if (candidate.citationMetadata) {
|
|
286
345
|
generationSample.attributionMetadata = {
|
|
287
346
|
attributionAction: AIDA.RecitationAction.CITE,
|
|
288
|
-
citations: candidate.
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
347
|
+
citations: (candidate.citationMetadata.citations ?? []).map(c => ({
|
|
348
|
+
startIndex: c.startIndex,
|
|
349
|
+
endIndex: c.endIndex,
|
|
350
|
+
uri: c.uri,
|
|
351
|
+
})),
|
|
293
352
|
};
|
|
294
353
|
}
|
|
295
354
|
return generationSample;
|
|
@@ -305,7 +364,7 @@ function convertAidaContentToGcaContent(content: AIDA.Content): GCA.Content {
|
|
|
305
364
|
}
|
|
306
365
|
return {
|
|
307
366
|
role,
|
|
308
|
-
parts: content.parts.map(convertAidaPartToGcaPart),
|
|
367
|
+
parts: (content.parts ?? []).map(convertAidaPartToGcaPart),
|
|
309
368
|
};
|
|
310
369
|
}
|
|
311
370
|
|
|
@@ -315,7 +374,7 @@ function convertAidaPartToGcaPart(part: AIDA.Part): GCA.Part {
|
|
|
315
374
|
}
|
|
316
375
|
if ('functionCall' in part) {
|
|
317
376
|
return {
|
|
318
|
-
|
|
377
|
+
functionCall: {
|
|
319
378
|
name: part.functionCall.name,
|
|
320
379
|
args: part.functionCall.args,
|
|
321
380
|
},
|
|
@@ -334,7 +393,7 @@ function convertAidaPartToGcaPart(part: AIDA.Part): GCA.Part {
|
|
|
334
393
|
fResponse.error = part.functionResponse.response['error'];
|
|
335
394
|
}
|
|
336
395
|
return {
|
|
337
|
-
|
|
396
|
+
functionResponse: {
|
|
338
397
|
name: part.functionResponse.name,
|
|
339
398
|
response: fResponse,
|
|
340
399
|
},
|
|
@@ -342,8 +401,8 @@ function convertAidaPartToGcaPart(part: AIDA.Part): GCA.Part {
|
|
|
342
401
|
}
|
|
343
402
|
if ('inlineData' in part) {
|
|
344
403
|
return {
|
|
345
|
-
|
|
346
|
-
|
|
404
|
+
inlineData: {
|
|
405
|
+
mimeType: part.inlineData.mimeType,
|
|
347
406
|
data: part.inlineData.data,
|
|
348
407
|
},
|
|
349
408
|
};
|
|
@@ -370,8 +429,58 @@ function convertAidaParamToGcaSchema<T extends string|number|symbol = string>(pa
|
|
|
370
429
|
for (const [key, value] of Object.entries(param.properties)) {
|
|
371
430
|
schema.properties[key] = convertAidaParamToGcaSchema(value as FunctionParam);
|
|
372
431
|
}
|
|
373
|
-
schema.required = param.required.map(r => r.toString());
|
|
432
|
+
schema.required = (param.required ?? []).map(r => r.toString());
|
|
374
433
|
}
|
|
375
434
|
|
|
376
435
|
return schema;
|
|
377
436
|
}
|
|
437
|
+
|
|
438
|
+
export function gcaChunkResponseToAidaChunkResponse(response: GCA.GenerateContentResponse): AIDA.AidaChunkResponse[] {
|
|
439
|
+
try {
|
|
440
|
+
const candidate = response.candidates?.[0];
|
|
441
|
+
const parts = candidate?.content?.parts || [];
|
|
442
|
+
const metadata: AIDA.ResponseMetadata = {
|
|
443
|
+
rpcGlobalId: response.responseId,
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
if (candidate?.citationMetadata?.citations) {
|
|
447
|
+
metadata.attributionMetadata = {
|
|
448
|
+
attributionAction: AIDA.RecitationAction.CITE,
|
|
449
|
+
citations: candidate.citationMetadata.citations.map(c => ({
|
|
450
|
+
startIndex: c.startIndex,
|
|
451
|
+
endIndex: c.endIndex,
|
|
452
|
+
uri: c.uri,
|
|
453
|
+
})),
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
const chunks: AIDA.AidaChunkResponse[] = (parts).map(part => {
|
|
457
|
+
const aidaChunkResponse: AIDA.AidaChunkResponse = {metadata};
|
|
458
|
+
if (part.text) {
|
|
459
|
+
aidaChunkResponse.textChunk = {
|
|
460
|
+
text: extractTextFromGcaParts(parts),
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
if (part.functionCall) {
|
|
464
|
+
aidaChunkResponse.functionCallChunk = {
|
|
465
|
+
functionCall: {
|
|
466
|
+
name: part.functionCall.name,
|
|
467
|
+
args: part.functionCall.args || {},
|
|
468
|
+
},
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
if (part.executableCode) {
|
|
472
|
+
aidaChunkResponse.codeChunk = {
|
|
473
|
+
code: part.executableCode.code,
|
|
474
|
+
inferenceLanguage: part.executableCode.language ? AIDA.AidaInferenceLanguage.PYTHON :
|
|
475
|
+
AIDA.AidaInferenceLanguage.UNKNOWN,
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
return aidaChunkResponse;
|
|
479
|
+
});
|
|
480
|
+
AIDA.debugLog('Translation succeeded:', JSON.stringify(response), JSON.stringify(chunks));
|
|
481
|
+
return chunks;
|
|
482
|
+
} catch (e) {
|
|
483
|
+
AIDA.debugLog('Translation error', JSON.stringify(response), e);
|
|
484
|
+
throw e;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Copyright 2026 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 * as Root from '../root/root.js';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
type AidaRegisterClientEvent,
|
|
9
|
+
type CompletionRequest,
|
|
10
|
+
type CompletionResponse,
|
|
11
|
+
debugLog,
|
|
12
|
+
type DoConversationRequest,
|
|
13
|
+
type GenerateCodeRequest,
|
|
14
|
+
type GenerateCodeResponse
|
|
15
|
+
} from './AidaClientTypes.js';
|
|
16
|
+
import {
|
|
17
|
+
aidaCompletionRequestToGcaRequest,
|
|
18
|
+
aidaDoConversationRequestToGcaRequest,
|
|
19
|
+
aidaEventToGcaTelemetryRequest,
|
|
20
|
+
aidaGenerateCodeRequestToGcaRequest,
|
|
21
|
+
gcaResponseToAidaCompletionResponse,
|
|
22
|
+
gcaResponseToAidaGenerateCodeResponse
|
|
23
|
+
} from './AidaGcaTranslation.js';
|
|
24
|
+
import * as DispatchHttpRequestClient from './DispatchHttpRequestClient.js';
|
|
25
|
+
import type {GenerateContentRequest, GenerateContentResponse} from './GcaTypes.js';
|
|
26
|
+
import type {AidaClientResult} from './InspectorFrontendHostAPI.js';
|
|
27
|
+
|
|
28
|
+
const SERVICE_NAME = 'gcaService';
|
|
29
|
+
|
|
30
|
+
const ENDPOINTS = {
|
|
31
|
+
CONTENT: '/v1beta:generateContent',
|
|
32
|
+
SEND_TELEMETRY: '/v1beta:sendTelemetry',
|
|
33
|
+
STREAM_CONTENT: '/v1beta:streamGenerateContent',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export class GcaClient {
|
|
37
|
+
enabled(): boolean|undefined {
|
|
38
|
+
return Root.Runtime.hostConfig.devToolsUseGcaApi?.enabled;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async conversationRequest(request: DoConversationRequest, streamId: number, options?: {signal?: AbortSignal}):
|
|
42
|
+
Promise<void> {
|
|
43
|
+
try {
|
|
44
|
+
const gcaRequest = aidaDoConversationRequestToGcaRequest(request);
|
|
45
|
+
const response = await DispatchHttpRequestClient.makeHttpRequest<GenerateContentResponse>(
|
|
46
|
+
{
|
|
47
|
+
service: SERVICE_NAME,
|
|
48
|
+
path: ENDPOINTS.STREAM_CONTENT,
|
|
49
|
+
method: 'POST',
|
|
50
|
+
body: JSON.stringify(gcaRequest),
|
|
51
|
+
streamId,
|
|
52
|
+
},
|
|
53
|
+
options);
|
|
54
|
+
debugLog('GCA conversation request succeeded:', JSON.stringify(request), JSON.stringify(response));
|
|
55
|
+
} catch (err) {
|
|
56
|
+
debugLog('GCA request failed:', JSON.stringify(request), err);
|
|
57
|
+
throw err;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
registerClientEvent(clientEvent: AidaRegisterClientEvent): Promise<AidaClientResult> {
|
|
62
|
+
const gcaEvent = aidaEventToGcaTelemetryRequest(clientEvent);
|
|
63
|
+
const response = DispatchHttpRequestClient.makeHttpRequest({
|
|
64
|
+
service: SERVICE_NAME,
|
|
65
|
+
path: ENDPOINTS.SEND_TELEMETRY,
|
|
66
|
+
method: 'POST',
|
|
67
|
+
body: JSON.stringify(gcaEvent),
|
|
68
|
+
});
|
|
69
|
+
return response.then(
|
|
70
|
+
result => {
|
|
71
|
+
debugLog('GCA register event succeeded:', JSON.stringify(gcaEvent), JSON.stringify(result));
|
|
72
|
+
return {} as AidaClientResult;
|
|
73
|
+
},
|
|
74
|
+
err => {
|
|
75
|
+
debugLog('GCA register event failed:', JSON.stringify(gcaEvent), err);
|
|
76
|
+
return {error: JSON.stringify(err)} as AidaClientResult;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async completeCode(request: CompletionRequest): Promise<CompletionResponse|null> {
|
|
81
|
+
const gcaRequest = aidaCompletionRequestToGcaRequest(request);
|
|
82
|
+
const result = await this.#requestContent(gcaRequest);
|
|
83
|
+
const aidaResult = result ? gcaResponseToAidaCompletionResponse(result) : null;
|
|
84
|
+
return aidaResult;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async generateCode(request: GenerateCodeRequest, options?: {signal?: AbortSignal}):
|
|
88
|
+
Promise<GenerateCodeResponse|null> {
|
|
89
|
+
const gcaRequest = aidaGenerateCodeRequestToGcaRequest(request);
|
|
90
|
+
const result = await this.#requestContent(gcaRequest, options);
|
|
91
|
+
return result ? gcaResponseToAidaGenerateCodeResponse(result) : null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async #requestContent(request: GenerateContentRequest, options?: {signal?: AbortSignal}):
|
|
95
|
+
Promise<GenerateContentResponse|null> {
|
|
96
|
+
try {
|
|
97
|
+
const response = await DispatchHttpRequestClient.makeHttpRequest<GenerateContentResponse>(
|
|
98
|
+
{
|
|
99
|
+
service: SERVICE_NAME,
|
|
100
|
+
path: ENDPOINTS.CONTENT,
|
|
101
|
+
method: 'POST',
|
|
102
|
+
body: JSON.stringify(request),
|
|
103
|
+
},
|
|
104
|
+
options);
|
|
105
|
+
debugLog('GCA request succeeded:', JSON.stringify(request), JSON.stringify(response));
|
|
106
|
+
return response;
|
|
107
|
+
} catch (err) {
|
|
108
|
+
debugLog('GCA request failed:', JSON.stringify(request), err);
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|