chrome-devtools-frontend 1.0.1598808 → 1.0.1601661
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/.agents/README.md +13 -0
- package/{agents/prompts/creating-a-model.md → .agents/skills/creating-a-model/SKILL.md} +7 -1
- package/{agents/prompts/devtools-imports.md → .agents/skills/devtools-imports/SKILL.md} +10 -5
- package/{agents/prompts/merging-devtools-module.md → .agents/skills/merging-devtools-module/SKILL.md} +5 -0
- package/{agents/prompts/ui-widgets.md → .agents/skills/ui-widgets/SKILL.md} +5 -0
- package/{agents/prompts/verification.md → .agents/skills/verification/SKILL.md} +5 -0
- package/front_end/core/common/Settings.ts +24 -1
- package/front_end/core/dom_extension/DOMExtension.ts +1 -0
- package/front_end/core/host/AidaClient.ts +5 -2
- package/front_end/core/host/AidaGcaTranslation.ts +377 -0
- package/front_end/core/host/GcaTypes.ts +520 -0
- package/front_end/core/host/UserMetrics.ts +0 -3
- package/front_end/core/host/host.ts +4 -0
- package/front_end/core/root/ExperimentNames.ts +0 -3
- package/front_end/core/sdk/CPUThrottlingManager.ts +12 -9
- package/front_end/core/sdk/ResourceTreeModel.ts +1 -1
- package/front_end/core/sdk/SourceMap.ts +4 -2
- package/front_end/entrypoints/main/MainImpl.ts +1 -12
- package/front_end/generated/Deprecation.ts +16 -0
- package/front_end/generated/InspectorBackendCommands.ts +4 -6
- package/front_end/generated/protocol.ts +46 -77
- package/front_end/models/ai_assistance/AiConversation.ts +49 -22
- package/front_end/models/ai_assistance/AiHistoryStorage.snapshot.txt +1 -1
- package/front_end/models/ai_assistance/AiHistoryStorage.ts +1 -0
- package/front_end/models/ai_assistance/ConversationHandler.ts +16 -11
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +76 -36
- package/front_end/models/ai_assistance/agents/AiAgent.ts +26 -2
- package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +0 -1
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +11 -0
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +39 -0
- package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +53 -12
- package/front_end/models/ai_assistance/agents/FileAgent.ts +0 -15
- package/front_end/models/ai_assistance/agents/NetworkAgent.ts +0 -5
- package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +57 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +87 -15
- package/front_end/models/ai_assistance/agents/PerformanceAnnotationsAgent.ts +0 -10
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +0 -6
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -5
- package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
- package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.snapshot.txt +84 -0
- package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.ts +172 -0
- package/front_end/models/breakpoints/BreakpointManager.ts +20 -12
- package/front_end/models/emulation/DeviceModeModel.ts +5 -1
- package/front_end/models/emulation/EmulatedDevices.ts +3 -2
- package/front_end/models/javascript_metadata/NativeFunctions.js +60 -0
- package/front_end/models/lighthouse/LighthouseReporterTypes.ts +104 -10
- package/front_end/models/lighthouse/RunTypes.ts +42 -0
- package/front_end/models/lighthouse/lighthouse.ts +2 -0
- package/front_end/models/live-metrics/web-vitals-injected/web-vitals-injected.ts +59 -35
- package/front_end/models/stack_trace/StackTrace.ts +5 -0
- package/front_end/models/stack_trace/StackTraceImpl.ts +7 -1
- package/front_end/models/stack_trace/StackTraceModel.ts +2 -1
- package/front_end/models/stack_trace/stack_trace.ts +4 -0
- package/front_end/models/trace/ModelImpl.ts +4 -0
- package/front_end/models/trace/helpers/SamplesIntegrator.ts +1 -8
- package/front_end/models/trace/types/Configuration.ts +0 -5
- package/front_end/panels/accessibility/AccessibilityNodeView.ts +7 -3
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +163 -74
- package/front_end/panels/ai_assistance/ExportConversation.ts +25 -0
- package/front_end/panels/ai_assistance/ai_assistance.ts +2 -0
- package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +120 -32
- package/front_end/panels/ai_assistance/components/ChatView.ts +44 -0
- package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +240 -0
- package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +4 -12
- package/front_end/panels/ai_assistance/components/StylingAgentMarkdownRenderer.ts +5 -27
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +115 -17
- package/front_end/panels/ai_assistance/components/chatMessage.css +65 -1
- package/front_end/panels/ai_assistance/components/chatView.css +8 -0
- package/front_end/panels/ai_assistance/components/exportForAgentsDialog.css +82 -0
- package/front_end/panels/ai_assistance/components/walkthroughView.css +9 -1
- package/front_end/panels/animation/AnimationTimeline.ts +5 -5
- package/front_end/panels/application/AppManifestView.ts +13 -7
- package/front_end/panels/application/FrameDetailsView.ts +4 -4
- package/front_end/panels/application/preloading/PreloadingView.ts +2 -4
- package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +6 -3
- package/front_end/panels/application/preloading/components/PreloadingString.ts +15 -2
- package/front_end/panels/application/preloading/helper/PreloadingForward.ts +31 -2
- package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +3 -2
- package/front_end/panels/common/DOMLinkifier.ts +10 -8
- package/front_end/panels/console/ConsoleView.ts +24 -2
- package/front_end/panels/console/ConsoleViewMessage.ts +22 -23
- package/front_end/panels/console/console.ts +0 -2
- package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +5 -5
- package/front_end/panels/elements/ElementsTreeElement.ts +2 -3
- package/front_end/panels/elements/PropertiesWidget.ts +5 -3
- package/front_end/panels/elements/StandaloneStylesContainer.ts +21 -9
- package/front_end/panels/elements/StylePropertiesSection.ts +98 -50
- package/front_end/panels/elements/StylePropertyTreeElement.ts +38 -4
- package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +43 -35
- package/front_end/panels/elements/StylesSidebarPane.ts +154 -24
- package/front_end/panels/elements/components/ComputedStyleTrace.ts +3 -2
- package/front_end/panels/event_listeners/EventListenersView.ts +16 -4
- package/front_end/panels/explain/components/ConsoleInsight.ts +6 -9
- package/front_end/panels/explain/explain-meta.ts +5 -0
- package/front_end/panels/issues/AffectedResourcesView.ts +5 -9
- package/front_end/panels/issues/AffectedSelectivePermissionsInterventionView.ts +1 -1
- package/front_end/panels/lighthouse/LighthouseController.ts +154 -164
- package/front_end/panels/lighthouse/LighthousePanel.ts +5 -9
- package/front_end/panels/lighthouse/LighthouseProtocolService.ts +1 -0
- package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +9 -6
- package/front_end/panels/lighthouse/LighthouseStartView.ts +7 -6
- package/front_end/panels/lighthouse/LighthouseStatusView.ts +32 -8
- package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +7 -3
- package/front_end/panels/network/NetworkDataGridNode.ts +34 -0
- package/front_end/panels/network/NetworkLogViewColumns.ts +10 -0
- package/front_end/panels/network/RequestPayloadView.ts +4 -1
- package/front_end/panels/network/RequestTimingView.ts +8 -2
- package/front_end/panels/performance_monitor/performanceMonitor.css +6 -4
- package/front_end/panels/recorder/RecorderController.ts +52 -14
- package/front_end/panels/recorder/components/RecordingView.ts +2 -1
- package/front_end/panels/recorder/models/RecordingStorage.ts +15 -20
- package/front_end/panels/sensors/SensorsView.ts +333 -157
- package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +18 -4
- package/front_end/panels/sources/DebuggerPausedMessage.ts +6 -6
- package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +2 -3
- package/front_end/panels/sources/NavigatorView.ts +11 -7
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +1 -1
- package/front_end/panels/sources/SourcesPanel.ts +12 -34
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +5 -1
- package/front_end/panels/sources/sources-meta.ts +6 -0
- package/front_end/panels/timeline/StatusDialog.ts +159 -83
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +6 -2
- package/front_end/panels/timeline/TimelineController.ts +0 -4
- package/front_end/panels/timeline/TimelineDetailsView.ts +35 -3
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +6 -1
- package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +9 -4
- package/front_end/panels/timeline/TimelinePanel.ts +36 -11
- package/front_end/panels/timeline/TimelineTreeView.ts +14 -3
- package/front_end/panels/timeline/TimelineUIUtils.ts +5 -57
- package/front_end/panels/timeline/components/InteractionBreakdown.ts +2 -1
- package/front_end/panels/timeline/components/LiveMetricsView.ts +2 -2
- package/front_end/panels/timeline/components/NetworkRequestTooltip.ts +3 -7
- package/front_end/panels/timeline/components/Sidebar.ts +11 -19
- package/front_end/panels/timeline/components/SidebarInsightsTab.ts +2 -1
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +60 -27
- package/front_end/panels/timeline/components/TimelineRangeSummaryView.ts +66 -0
- package/front_end/panels/timeline/components/TimelineSummary.ts +7 -19
- package/front_end/panels/timeline/components/components.ts +2 -0
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +55 -28
- package/front_end/panels/timeline/components/insights/NodeLink.ts +3 -3
- package/front_end/panels/timeline/components/insights/baseInsightComponent.css +7 -0
- package/front_end/panels/timeline/components/insights/insights.ts +0 -2
- package/front_end/panels/timeline/components/timelineRangeSummaryView.css +20 -0
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +7 -7
- package/front_end/panels/timeline/timeline-meta.ts +11 -0
- package/front_end/panels/timeline/timelineDetailsView.css +0 -9
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.js +11 -2
- package/front_end/third_party/web-vitals/package/src/attribution/onINP.ts +11 -2
- package/front_end/third_party/web-vitals/patches/0001-Add-onEachInteraction-to-onINP-options.patch +65 -4
- package/front_end/ui/kit/link/link.css +2 -2
- package/front_end/ui/legacy/Widget.ts +5 -3
- package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +7 -2
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +57 -35
- package/front_end/ui/legacy/components/source_frame/PreviewFactory.ts +1 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +6 -1
- package/package.json +1 -1
- package/agents/prompts/README.md +0 -18
- package/front_end/panels/timeline/components/insights/InsightRenderer.ts +0 -93
- /package/front_end/{panels/console → models/stack_trace}/ErrorStackParser.ts +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# .agents
|
|
2
|
+
|
|
3
|
+
This directory contains workspace-specific agent expertise and skills.
|
|
4
|
+
|
|
5
|
+
## Skills
|
|
6
|
+
|
|
7
|
+
Workspace skills are located in `.agents/skills/`. These represent on-demand expertise that the AI agent can activate to complete specialized tasks.
|
|
8
|
+
|
|
9
|
+
To use a skill, the agent will autonomously identify it based on its description and pull in the instructions using the `activate_skill` tool.
|
|
10
|
+
|
|
11
|
+
## Contributing
|
|
12
|
+
|
|
13
|
+
Contributions to existing skills or adding new ones are encouraged via CLs.
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
```
|
|
2
|
+
---
|
|
3
|
+
name: devtools-model-management
|
|
4
|
+
description: Guidelines for creating, migrating, and registering models in front_end/models/. Covers BUILD.gn, devtools_grd_files.gni, and entrypoints.
|
|
5
|
+
---
|
|
6
|
+
|
|
1
7
|
# Creating or Migrating a Model in DevTools
|
|
2
8
|
|
|
3
9
|
This guide outlines the standard procedure for creating a new model or migrating an existing one to `front_end/models/`.
|
|
@@ -48,4 +54,4 @@ The build system does not auto-detect new modules. You must manually register th
|
|
|
48
54
|
* **Circular Dependencies:** Occur when internal files import from the directory's own barrel file.
|
|
49
55
|
* **Missing Tests:** Failing to add the target to `front_end/BUILD.gn` means tests exist but never run.
|
|
50
56
|
* **Legacy Exports:** Forgetting to remove the class from the old location's `files` or `exports` allows old patterns to persist.
|
|
51
|
-
* **Build Errors:** Including the barrel file in `devtools_module` sources causes duplicate definition errors.
|
|
57
|
+
* **Build Errors:** Including the barrel file in `devtools_module` sources causes duplicate definition errors.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devtools-imports
|
|
3
|
+
description: Conventions for importing code in Devtools to avoid build errors. Covers cross-module imports, internal imports, and the "import * as" requirement.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Imports
|
|
2
7
|
|
|
3
8
|
This codebase follows a special convention for importing code that must be followed to avoid build errors.
|
|
@@ -16,23 +21,23 @@ Within each module there are multiple TypeScript files. *The file that is named
|
|
|
16
21
|
|
|
17
22
|
When you want to reuse code from other modules, *you must import that module via its entrypoint*. Imagine we are in `front_end/panels/timeline/TimelinePanel.ts`. This import is GOOD:
|
|
18
23
|
|
|
19
|
-
```
|
|
24
|
+
```ts
|
|
20
25
|
import * as Trace from '../models/trace/trace.js'; // import the entrypoint
|
|
21
26
|
```
|
|
22
27
|
|
|
23
28
|
This import is BAD because we import a file that is NOT the entrypoint:
|
|
24
29
|
|
|
25
|
-
```
|
|
30
|
+
```ts
|
|
26
31
|
import * as ModelImpl from '../models/trace/ModelImpl.js' // NEVER ALLOWED
|
|
27
32
|
```
|
|
28
33
|
|
|
29
34
|
Additionally, you **must import using the `import * as` syntax**.
|
|
30
35
|
|
|
31
|
-
```
|
|
36
|
+
```ts
|
|
32
37
|
import {ModelImpl, X, Y} from '../models/trace/trace.js'; // BAD
|
|
33
38
|
```
|
|
34
39
|
|
|
35
|
-
```
|
|
40
|
+
```ts
|
|
36
41
|
import * as Trace from '../models/trace/trace.js'; // GOOD
|
|
37
42
|
```
|
|
38
43
|
|
|
@@ -42,6 +47,6 @@ If you are within the same module, it is OK to import from files directly rather
|
|
|
42
47
|
|
|
43
48
|
For example, if you are editing `front_end/models/trace/ModelImpl.ts` this would be acceptable:
|
|
44
49
|
|
|
45
|
-
```
|
|
50
|
+
```ts
|
|
46
51
|
import {Foo} from './Foo.js'; // allowed because Foo.ts is in the same directory.
|
|
47
52
|
```
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devtools-module-merging
|
|
3
|
+
description: Workflow for merging a DevTools submodule into its parent module. Covers BUILD.gn consolidation and updating devtools_grd_files.gni.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Workflow: Merging a DevTools Submodule into its Parent
|
|
2
7
|
|
|
3
8
|
This document outlines the process for merging a submodule (e.g., `panels/timeline/extensions`) into its parent module (e.g., `panels/timeline`) within the DevTools build system. The goal is to simplify the build configuration by consolidating `BUILD.gn` files while keeping the original source file directory structure.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devtools-ui-widgets
|
|
3
|
+
description: Guidelines for building UI widgets using the MVP architecture in DevTools. Covers Widget lifecycle, lit-html views, and state management.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
## UI Widget Framework Guide (MVP Architecture)
|
|
2
7
|
|
|
3
8
|
Adhere strictly to the Model-View-Presenter (MVP) architecture.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devtools-verification
|
|
3
|
+
description: MANDATORY: Activate this skill ANY TIME you need to build the project, run tests, or verify code health in DevTools. You MUST use this skill before executing commands like npm test, npm run build, autoninja, or linters, as it contains critical, repository-specific instructions on how to correctly format these commands, filter test runs, and interpret failures.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Instructions on how to verify your changes
|
|
2
7
|
|
|
3
8
|
## Testing
|
|
@@ -688,7 +688,7 @@ export class VersionController {
|
|
|
688
688
|
static readonly SYNCED_VERSION_SETTING_NAME = 'syncedInspectorVersion';
|
|
689
689
|
static readonly LOCAL_VERSION_SETTING_NAME = 'localInspectorVersion';
|
|
690
690
|
|
|
691
|
-
static readonly CURRENT_VERSION =
|
|
691
|
+
static readonly CURRENT_VERSION = 42;
|
|
692
692
|
|
|
693
693
|
readonly #settings: Settings;
|
|
694
694
|
readonly #globalVersionSetting: Setting<number>;
|
|
@@ -1480,6 +1480,29 @@ export class VersionController {
|
|
|
1480
1480
|
}
|
|
1481
1481
|
}
|
|
1482
1482
|
|
|
1483
|
+
/**
|
|
1484
|
+
* The recording in recorder panel may have unreasonably long titles
|
|
1485
|
+
* or a lot of steps which can cause renderer crashes.
|
|
1486
|
+
* Similar to https://crbug.com/40918380
|
|
1487
|
+
*/
|
|
1488
|
+
updateVersionFrom41To42(): void {
|
|
1489
|
+
const recordingsSetting = this.#settings.createSetting<Array<{flow: {steps: unknown[], title: string}}>>(
|
|
1490
|
+
'recorder-recordings-ng',
|
|
1491
|
+
[],
|
|
1492
|
+
);
|
|
1493
|
+
const recordings = recordingsSetting.get();
|
|
1494
|
+
if (recordings.length === 0) {
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
for (const recording of recordings) {
|
|
1499
|
+
recording.flow.title = Platform.StringUtilities.trimEndWithMaxLength(recording.flow.title, 300);
|
|
1500
|
+
recording.flow.steps = recording.flow.steps.slice(0, 4096);
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
recordingsSetting.set(recordings);
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1483
1506
|
/*
|
|
1484
1507
|
* Any new migration should be added before this comment.
|
|
1485
1508
|
*
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
38
38
|
// @ts-nocheck This file is not checked by TypeScript Compiler as it has a lot of legacy code.
|
|
39
|
+
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
39
40
|
|
|
40
41
|
import * as Platform from '../platform/platform.js';
|
|
41
42
|
|
|
@@ -67,10 +67,10 @@ interface BaseFunctionParam {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
export interface FunctionPrimitiveParams extends BaseFunctionParam {
|
|
70
|
-
type: ParametersTypes.BOOLEAN|ParametersTypes.INTEGER|ParametersTypes.STRING
|
|
70
|
+
type: ParametersTypes.BOOLEAN|ParametersTypes.INTEGER|ParametersTypes.STRING;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
interface FunctionArrayParam extends BaseFunctionParam {
|
|
73
|
+
export interface FunctionArrayParam extends BaseFunctionParam {
|
|
74
74
|
type: ParametersTypes.ARRAY;
|
|
75
75
|
items: FunctionPrimitiveParams;
|
|
76
76
|
}
|
|
@@ -301,6 +301,9 @@ export enum UseCase {
|
|
|
301
301
|
|
|
302
302
|
// Code generation use case is expected to generate code from scratch
|
|
303
303
|
CODE_GENERATION = 1,
|
|
304
|
+
|
|
305
|
+
// Code transformation or code editing use case.
|
|
306
|
+
CODE_TRANSFORMATION = 2,
|
|
304
307
|
}
|
|
305
308
|
|
|
306
309
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
@@ -0,0 +1,377 @@
|
|
|
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 AIDA from './AidaClient.js';
|
|
6
|
+
import * as GCA from './GcaTypes.js';
|
|
7
|
+
|
|
8
|
+
type AidaRequest = AIDA.DoConversationRequest|AIDA.CompletionRequest|AIDA.GenerateCodeRequest;
|
|
9
|
+
|
|
10
|
+
function createBaseGcaRequest(request: AidaRequest, contents: GCA.Content[]): GCA.GenerateContentRequest {
|
|
11
|
+
const gcaRequest: GCA.GenerateContentRequest = {contents};
|
|
12
|
+
mapCommonAidaRequestFields(request, gcaRequest);
|
|
13
|
+
buildLabels(request, gcaRequest);
|
|
14
|
+
|
|
15
|
+
if ('preamble' in request && request.preamble) {
|
|
16
|
+
gcaRequest.system_instruction = {
|
|
17
|
+
role: 'user',
|
|
18
|
+
parts: [{text: request.preamble}],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return gcaRequest;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function aidaDoConversationRequestToGcaRequest(request: AIDA.DoConversationRequest): GCA.GenerateContentRequest {
|
|
26
|
+
const contents: GCA.Content[] = [];
|
|
27
|
+
|
|
28
|
+
if (request.historical_contexts) {
|
|
29
|
+
contents.push(...request.historical_contexts.map(convertAidaContentToGcaContent));
|
|
30
|
+
}
|
|
31
|
+
contents.push(convertAidaContentToGcaContent(request.current_message));
|
|
32
|
+
|
|
33
|
+
const gcaRequest = createBaseGcaRequest(request, contents);
|
|
34
|
+
|
|
35
|
+
if (request.function_declarations) {
|
|
36
|
+
gcaRequest.tools = [{
|
|
37
|
+
function_declarations: request.function_declarations.map(fd => ({
|
|
38
|
+
name: fd.name,
|
|
39
|
+
description: fd.description,
|
|
40
|
+
parameters: convertAidaParamToGcaSchema(fd.parameters),
|
|
41
|
+
})),
|
|
42
|
+
}];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return gcaRequest;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function mapCommonAidaRequestFields(aidaRequest: AidaRequest, gcaRequest: GCA.GenerateContentRequest): void {
|
|
49
|
+
if (aidaRequest.options?.model_id) {
|
|
50
|
+
gcaRequest.model = aidaRequest.options.model_id;
|
|
51
|
+
}
|
|
52
|
+
if (aidaRequest.metadata.string_session_id) {
|
|
53
|
+
gcaRequest.session_id = aidaRequest.metadata.string_session_id;
|
|
54
|
+
}
|
|
55
|
+
if (aidaRequest.options?.temperature !== undefined) {
|
|
56
|
+
gcaRequest.generation_config = {
|
|
57
|
+
...gcaRequest.generation_config,
|
|
58
|
+
temperature: aidaRequest.options.temperature,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function gcaResponseToAidaDoConversationResponse(response: GCA.GenerateContentResponse):
|
|
64
|
+
AIDA.DoConversationResponse {
|
|
65
|
+
const candidate = response.candidates[0];
|
|
66
|
+
const functionCalls: AIDA.AidaFunctionCallResponse[] = [];
|
|
67
|
+
|
|
68
|
+
if (candidate?.content?.parts) {
|
|
69
|
+
for (const part of candidate.content.parts) {
|
|
70
|
+
if (part.function_call) {
|
|
71
|
+
functionCalls.push({
|
|
72
|
+
name: part.function_call.name,
|
|
73
|
+
args: part.function_call.args || {},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
explanation: extractTextFromGcaParts(candidate?.content?.parts),
|
|
81
|
+
metadata: {
|
|
82
|
+
rpcGlobalId: response.response_id,
|
|
83
|
+
},
|
|
84
|
+
functionCalls: functionCalls.length > 0 ?
|
|
85
|
+
(functionCalls as [AIDA.AidaFunctionCallResponse, ...AIDA.AidaFunctionCallResponse[]]) :
|
|
86
|
+
undefined,
|
|
87
|
+
completed: true,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function extractTextFromGcaParts(parts: GCA.Part[]|undefined): string {
|
|
92
|
+
if (!parts) {
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
return parts.map(p => p.text || '').join('');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function aidaEventToGcaTelemetryRequest(clientEvent: AIDA.AidaRegisterClientEvent): GCA.SendTelemetryRequest {
|
|
99
|
+
const feedbackMetrics: GCA.FeedbackMetric[] = [];
|
|
100
|
+
const responseId = String(clientEvent.corresponding_aida_rpc_global_id);
|
|
101
|
+
const eventTime = new Date().toISOString();
|
|
102
|
+
|
|
103
|
+
if (clientEvent.do_conversation_client_event) {
|
|
104
|
+
const feedback = clientEvent.do_conversation_client_event.user_feedback;
|
|
105
|
+
if (feedback.sentiment) {
|
|
106
|
+
let interaction: GCA.InteractionType = GCA.InteractionType.INTERACTION_TYPE_UNSPECIFIED;
|
|
107
|
+
if (feedback.sentiment === AIDA.Rating.POSITIVE) {
|
|
108
|
+
interaction = GCA.InteractionType.THUMBS_UP;
|
|
109
|
+
} else if (feedback.sentiment === AIDA.Rating.NEGATIVE) {
|
|
110
|
+
interaction = GCA.InteractionType.THUMBS_DOWN;
|
|
111
|
+
}
|
|
112
|
+
feedbackMetrics.push({
|
|
113
|
+
event_time: eventTime,
|
|
114
|
+
response_id: responseId,
|
|
115
|
+
suggestion_interaction: {interaction},
|
|
116
|
+
});
|
|
117
|
+
}
|
|
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
|
+
|
|
125
|
+
return {feedback_metrics: feedbackMetrics};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
129
|
+
function convertCodeTelemetry(
|
|
130
|
+
event: {user_acceptance?: AIDA.UserAcceptance, user_impression?: AIDA.UserImpression}|undefined, method: GCA.Method,
|
|
131
|
+
responseId: string, eventTime: string): GCA.FeedbackMetric[] {
|
|
132
|
+
if (!event) {
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
if ('user_impression' in event && event.user_impression) {
|
|
136
|
+
const impression = event.user_impression;
|
|
137
|
+
return [{
|
|
138
|
+
event_time: eventTime,
|
|
139
|
+
response_id: responseId,
|
|
140
|
+
suggestion_offered: {
|
|
141
|
+
method,
|
|
142
|
+
status: GCA.SuggestionStatus.NO_ERROR,
|
|
143
|
+
response_latency: `${impression.latency.duration.seconds + impression.latency.duration.nanos / 1e9}s`,
|
|
144
|
+
},
|
|
145
|
+
}];
|
|
146
|
+
}
|
|
147
|
+
if ('user_acceptance' in event && event.user_acceptance) {
|
|
148
|
+
const acceptance = event.user_acceptance;
|
|
149
|
+
return [{
|
|
150
|
+
event_time: eventTime,
|
|
151
|
+
response_id: responseId,
|
|
152
|
+
suggestion_interaction: {
|
|
153
|
+
interaction: GCA.InteractionType.ACCEPT,
|
|
154
|
+
candidate_index: acceptance.sample.sample_id,
|
|
155
|
+
},
|
|
156
|
+
}];
|
|
157
|
+
}
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
161
|
+
|
|
162
|
+
export function aidaCompletionRequestToGcaRequest(request: AIDA.CompletionRequest): GCA.GenerateContentRequest {
|
|
163
|
+
const contents: GCA.Content[] = [
|
|
164
|
+
{
|
|
165
|
+
role: 'user',
|
|
166
|
+
parts: [{text: request.prefix + (request.suffix || '')}],
|
|
167
|
+
},
|
|
168
|
+
];
|
|
169
|
+
|
|
170
|
+
const gcaRequest = createBaseGcaRequest(request, contents);
|
|
171
|
+
|
|
172
|
+
if (request.options?.stop_sequences) {
|
|
173
|
+
gcaRequest.generation_config = {
|
|
174
|
+
...gcaRequest.generation_config,
|
|
175
|
+
stop_sequences: request.options.stop_sequences,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (request.additional_files) {
|
|
180
|
+
gcaRequest.aicode = {
|
|
181
|
+
experience: 'completion',
|
|
182
|
+
files: request.additional_files.map(f => ({
|
|
183
|
+
file_uri: f.path,
|
|
184
|
+
inclusion_reason: [AidaReasonToGcaInclusionReason[f.included_reason]],
|
|
185
|
+
})),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return gcaRequest;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
193
|
+
function buildLabels(request: AidaRequest, gcaRequest: GCA.GenerateContentRequest): void {
|
|
194
|
+
const labels: Record<string, string> = {};
|
|
195
|
+
if (request.client) {
|
|
196
|
+
labels['client'] = request.client;
|
|
197
|
+
}
|
|
198
|
+
if ('functionality_type' in request && request.functionality_type !== undefined) {
|
|
199
|
+
labels['functionality_type'] = AIDA.FunctionalityType[request.functionality_type];
|
|
200
|
+
}
|
|
201
|
+
if ('client_feature' in request && request.client_feature !== undefined) {
|
|
202
|
+
labels['client_feature'] = AIDA.ClientFeature[request.client_feature];
|
|
203
|
+
}
|
|
204
|
+
if ('last_user_action' in request && request.last_user_action !== undefined) {
|
|
205
|
+
labels['last_user_action'] = AIDA.EditType[request.last_user_action];
|
|
206
|
+
}
|
|
207
|
+
if ('use_case' in request && request.use_case !== undefined) {
|
|
208
|
+
labels['use_case'] = AIDA.UseCase[request.use_case];
|
|
209
|
+
}
|
|
210
|
+
const options = request.options as {
|
|
211
|
+
inference_language?: string,
|
|
212
|
+
expect_code_output?: boolean,
|
|
213
|
+
} | undefined;
|
|
214
|
+
if (options?.inference_language) {
|
|
215
|
+
labels['inference_language'] = options.inference_language;
|
|
216
|
+
}
|
|
217
|
+
if (options?.expect_code_output !== undefined) {
|
|
218
|
+
labels['expect_code_output'] = String(options.expect_code_output);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (Object.keys(labels).length > 0) {
|
|
222
|
+
gcaRequest.labels = labels;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
226
|
+
|
|
227
|
+
const AidaReasonToGcaInclusionReason: Record<AIDA.Reason, GCA.InclusionReason> = {
|
|
228
|
+
[AIDA.Reason.UNKNOWN]: GCA.InclusionReason.INCLUSION_REASON_UNSPECIFIED,
|
|
229
|
+
[AIDA.Reason.CURRENTLY_OPEN]: GCA.InclusionReason.OPEN,
|
|
230
|
+
// Intentional mapping due to type mismatch
|
|
231
|
+
// TODO(liviurau): find a way to validate this mapping
|
|
232
|
+
[AIDA.Reason.RECENTLY_OPENED]: GCA.InclusionReason.RECENTLY_CLOSED,
|
|
233
|
+
[AIDA.Reason.RECENTLY_EDITED]: GCA.InclusionReason.RECENTLY_EDITED,
|
|
234
|
+
[AIDA.Reason.COLOCATED]: GCA.InclusionReason.COLOCATED,
|
|
235
|
+
[AIDA.Reason.RELATED_FILE]: GCA.InclusionReason.RELATED,
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export function gcaResponseToAidaCompletionResponse(response: GCA.GenerateContentResponse): AIDA.CompletionResponse {
|
|
239
|
+
const {samples, metadata} = gcaResponseToAidaSamplesAndMetadata(response);
|
|
240
|
+
return {
|
|
241
|
+
generatedSamples: samples,
|
|
242
|
+
metadata,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function gcaResponseToAidaSamplesAndMetadata(response: GCA.GenerateContentResponse): {
|
|
247
|
+
samples: AIDA.GenerationSample[],
|
|
248
|
+
metadata: AIDA.ResponseMetadata,
|
|
249
|
+
} {
|
|
250
|
+
return {
|
|
251
|
+
samples: response.candidates.map(gcaCandidateToAidaGenerationSample),
|
|
252
|
+
metadata: {
|
|
253
|
+
rpcGlobalId: response.response_id,
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export function aidaGenerateCodeRequestToGcaRequest(request: AIDA.GenerateCodeRequest): GCA.GenerateContentRequest {
|
|
259
|
+
const gcaRequest = createBaseGcaRequest(request, [convertAidaContentToGcaContent(request.current_message)]);
|
|
260
|
+
|
|
261
|
+
if (request.context_files) {
|
|
262
|
+
gcaRequest.aicode = {
|
|
263
|
+
experience: 'generate_code',
|
|
264
|
+
files: request.context_files.map(f => ({
|
|
265
|
+
file_uri: f.path,
|
|
266
|
+
programming_language: f.programming_language,
|
|
267
|
+
})),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return gcaRequest;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export function gcaResponseToAidaGenerateCodeResponse(response: GCA.GenerateContentResponse):
|
|
275
|
+
AIDA.GenerateCodeResponse {
|
|
276
|
+
return gcaResponseToAidaSamplesAndMetadata(response);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function gcaCandidateToAidaGenerationSample(candidate: GCA.Candidate): AIDA.GenerationSample {
|
|
280
|
+
const generationSample: AIDA.GenerationSample = {
|
|
281
|
+
generationString: extractTextFromGcaParts(candidate.content?.parts),
|
|
282
|
+
score: 0,
|
|
283
|
+
sampleId: candidate.index,
|
|
284
|
+
};
|
|
285
|
+
if (candidate.citation_metadata) {
|
|
286
|
+
generationSample.attributionMetadata = {
|
|
287
|
+
attributionAction: AIDA.RecitationAction.CITE,
|
|
288
|
+
citations: candidate.citation_metadata.citations.map(c => ({
|
|
289
|
+
startIndex: c.start_index,
|
|
290
|
+
endIndex: c.end_index,
|
|
291
|
+
uri: c.uri,
|
|
292
|
+
})),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
return generationSample;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function convertAidaContentToGcaContent(content: AIDA.Content): GCA.Content {
|
|
299
|
+
// TODO(liviurau): decide how to map AIDA.Role.SYSTEM
|
|
300
|
+
// currently it will default to 'user'
|
|
301
|
+
let role: GCA.Role = 'user';
|
|
302
|
+
|
|
303
|
+
if (content.role === AIDA.Role.MODEL) {
|
|
304
|
+
role = 'model';
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
role,
|
|
308
|
+
parts: content.parts.map(convertAidaPartToGcaPart),
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function convertAidaPartToGcaPart(part: AIDA.Part): GCA.Part {
|
|
313
|
+
if ('text' in part) {
|
|
314
|
+
return {text: part.text};
|
|
315
|
+
}
|
|
316
|
+
if ('functionCall' in part) {
|
|
317
|
+
return {
|
|
318
|
+
function_call: {
|
|
319
|
+
name: part.functionCall.name,
|
|
320
|
+
args: part.functionCall.args,
|
|
321
|
+
},
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
if ('functionResponse' in part) {
|
|
325
|
+
const fResponse: Record<string, unknown> = {};
|
|
326
|
+
if ('result' in part.functionResponse.response) {
|
|
327
|
+
fResponse.output = part.functionResponse.response['result'];
|
|
328
|
+
} else if ('output' in part.functionResponse.response) {
|
|
329
|
+
fResponse.output = part.functionResponse.response['output'];
|
|
330
|
+
} else if (!('error' in part.functionResponse.response)) {
|
|
331
|
+
fResponse.output = part.functionResponse.response;
|
|
332
|
+
}
|
|
333
|
+
if ('error' in part.functionResponse.response) {
|
|
334
|
+
fResponse.error = part.functionResponse.response['error'];
|
|
335
|
+
}
|
|
336
|
+
return {
|
|
337
|
+
function_response: {
|
|
338
|
+
name: part.functionResponse.name,
|
|
339
|
+
response: fResponse,
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
if ('inlineData' in part) {
|
|
344
|
+
return {
|
|
345
|
+
inline_data: {
|
|
346
|
+
mime_type: part.inlineData.mimeType,
|
|
347
|
+
data: part.inlineData.data,
|
|
348
|
+
},
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
return {};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
type FunctionParam<T extends string|number|symbol = string> =
|
|
355
|
+
AIDA.FunctionObjectParam<T>|AIDA.FunctionArrayParam|AIDA.FunctionPrimitiveParams;
|
|
356
|
+
|
|
357
|
+
function convertAidaParamToGcaSchema<T extends string|number|symbol = string>(param: FunctionParam<T>): GCA.Schema {
|
|
358
|
+
const schema: GCA.Schema = {
|
|
359
|
+
type: param.type as unknown as GCA.Type,
|
|
360
|
+
description: param.description,
|
|
361
|
+
};
|
|
362
|
+
if (param.nullable) {
|
|
363
|
+
schema.nullable = param.nullable;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (param.type === AIDA.ParametersTypes.ARRAY && param.items) {
|
|
367
|
+
schema.items = convertAidaParamToGcaSchema(param.items);
|
|
368
|
+
} else if (param.type === AIDA.ParametersTypes.OBJECT && param.properties) {
|
|
369
|
+
schema.properties = {};
|
|
370
|
+
for (const [key, value] of Object.entries(param.properties)) {
|
|
371
|
+
schema.properties[key] = convertAidaParamToGcaSchema(value as FunctionParam);
|
|
372
|
+
}
|
|
373
|
+
schema.required = param.required.map(r => r.toString());
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return schema;
|
|
377
|
+
}
|