chrome-devtools-frontend
Version:
Chrome DevTools UI
70 lines (61 loc) • 3.18 kB
text/typescript
// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import * as Common from '../../core/common/common.js';
import * as Host from '../../core/host/host.js';
import * as i18n from '../../core/i18n/i18n.js';
import * as AiCodeCompletion from '../../models/ai_code_completion/ai_code_completion.js';
import type * as TextEditor from '../../ui/components/text_editor/text_editor.js';
export class StylesAiCodeCompletionProvider {
#aidaClient: Host.AidaClient.AidaClient = new Host.AidaClient.AidaClient();
#aiCodeCompletionSetting = Common.Settings.Settings.instance().createSetting('ai-code-completion-enabled', false);
#aiCodeCompletion?: AiCodeCompletion.AiCodeCompletion.AiCodeCompletion;
#aiCodeCompletionConfig?: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig;
#boundOnUpdateAiCodeCompletionState = this.#updateAiCodeCompletionState.bind(this);
private constructor(aiCodeCompletionConfig: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig) {
const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
if (!AiCodeCompletion.AiCodeCompletion.AiCodeCompletion.isAiCodeCompletionStylesEnabled(devtoolsLocale.locale)) {
throw new Error('AI code completion feature in Styles is not enabled.');
}
this.#aiCodeCompletionConfig = aiCodeCompletionConfig;
Host.AidaClient.HostConfigTracker.instance().addEventListener(
Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnUpdateAiCodeCompletionState);
this.#aiCodeCompletionSetting.addChangeListener(this.#boundOnUpdateAiCodeCompletionState);
void this.#updateAiCodeCompletionState();
}
static createInstance(aiCodeCompletionConfig: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig):
StylesAiCodeCompletionProvider {
return new StylesAiCodeCompletionProvider(aiCodeCompletionConfig);
}
#setupAiCodeCompletion(): void {
if (!this.#aiCodeCompletionConfig) {
return;
}
if (this.#aiCodeCompletion) {
// early return as this means that code completion was previously setup
return;
}
this.#aiCodeCompletion = new AiCodeCompletion.AiCodeCompletion.AiCodeCompletion(
{aidaClient: this.#aidaClient}, this.#aiCodeCompletionConfig.panel, undefined,
this.#aiCodeCompletionConfig.completionContext.stopSequences);
this.#aiCodeCompletionConfig.onFeatureEnabled();
}
#cleanupAiCodeCompletion(): void {
if (!this.#aiCodeCompletion) {
// early return as this means there is no code completion to clean up
return;
}
this.#aiCodeCompletion = undefined;
this.#aiCodeCompletionConfig?.onFeatureDisabled();
}
async #updateAiCodeCompletionState(): Promise<void> {
const aidaAvailability = await Host.AidaClient.AidaClient.checkAccessPreconditions();
const isAvailable = aidaAvailability === Host.AidaClient.AidaAccessPreconditions.AVAILABLE;
const isEnabled = this.#aiCodeCompletionSetting.get();
if (isAvailable && isEnabled) {
this.#setupAiCodeCompletion();
} else {
this.#cleanupAiCodeCompletion();
}
}
}