Skip to content

Commit

Permalink
feat: Restart Navie automatically when flipping VSCode LM option
Browse files Browse the repository at this point in the history
  • Loading branch information
dividedmind authored and dustinbyrne committed Sep 11, 2024
1 parent 979cdc6 commit 3e7c90a
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 63 deletions.
65 changes: 3 additions & 62 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<AppMap

const processService = new NodeProcessService(context);

initializeCopilotIntegration(context);
ChatCompletion.initialize(context);

AssetService.register(context);
const dependenciesInstalled = AssetService.updateAll();
Expand All @@ -247,7 +247,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<AppMap
vscode.commands.registerCommand('appmap.rpc.restart', async () => {
await rpcService.restartServer();
vscode.window.showInformationMessage('Navie restarted successfully.');
})
}),
ChatCompletion.onSettingsChanged(rpcService.restartServer, rpcService)
);

const webview = ChatSearchWebview.register(
Expand Down Expand Up @@ -330,63 +331,3 @@ export async function activate(context: vscode.ExtensionContext): Promise<AppMap
throw exception;
}
}

function initializeCopilotIntegration(context: vscode.ExtensionContext) {
// TODO: make the messages and handling generic for all LM extensions

const hasLM = 'lm' in vscode && 'selectChatModels' in vscode.lm;

if (ExtensionSettings.useVsCodeLM && checkAvailability())
context.subscriptions.push(new ChatCompletion());

context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration(async (e) => {
if (e.affectsConfiguration('appMap.navie.useVSCodeLM')) {
// Only suggest reloading if it's been disabled or if it's enabled and the extension is available
if (
(!ExtensionSettings.useVsCodeLM && (await ChatCompletion.instance)) ||
(ExtensionSettings.useVsCodeLM && checkAvailability())
)
notifyReload();
}
})
);

// eslint-disable-next-line @typescript-eslint/no-unused-vars
let _onModelChange: vscode.Disposable;

function checkAvailability() {
if (!hasLM)
vscode.window.showErrorMessage(
'AppMap: VS Code LM backend for Navie is enabled, but the LanguageModel API is not available.\nPlease update your VS Code to the latest version.'
);
else if (!vscode.extensions.getExtension('github.copilot')) {
vscode.window
.showErrorMessage(
'AppMap: VS Code LM backend for Navie is enabled, but the GitHub Copilot extension is not installed.\nPlease install it from the marketplace and reload the window.',
'Install Copilot'
)
.then((selection) => {
if (selection === 'Install Copilot') {
vscode.commands.executeCommand(
'workbench.extensions.installExtension',
'github.copilot'
);
_onModelChange ||= vscode.lm.onDidChangeChatModels(
notifyReload,
undefined,
context.subscriptions
);
}
});
} else return true;
}

async function notifyReload() {
const result = await vscode.window.showInformationMessage(
'AppMap: The Copilot integration has been updated. Please reload the window to apply the changes.',
'Reload'
);
if (result === 'Reload') vscode.commands.executeCommand('workbench.action.reloadWindow');
}
}
59 changes: 58 additions & 1 deletion src/services/chatCompletion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import { createServer } from 'node:http';
import { debuglog } from 'node:util';
import { isNativeError } from 'node:util/types';

import {
import vscode, {
CancellationTokenSource,
Disposable,
ExtensionContext,
LanguageModelChat,
LanguageModelChatMessage,
LanguageModelChatResponse,
lm,
} from 'vscode';

import ExtensionSettings from '../configuration/extensionSettings';

const debug = debuglog('appmap-vscode:chat-completion');

interface Message {
Expand Down Expand Up @@ -157,6 +160,60 @@ export default class ChatCompletion implements Disposable {
if ((await instance) === this) instance = undefined;
this.server.close();
}

private static settingsChanged = new vscode.EventEmitter<void>();
static onSettingsChanged = ChatCompletion.settingsChanged.event;

static initialize(context: ExtensionContext) {
// TODO: make the messages and handling generic for all LM extensions

const hasLM = 'lm' in vscode && 'selectChatModels' in vscode.lm;

if (ExtensionSettings.useVsCodeLM && checkAvailability())
context.subscriptions.push(new ChatCompletion());

context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration(async (e) => {
if (e.affectsConfiguration('appMap.navie.useVSCodeLM')) {
const instance = await ChatCompletion.instance;
if (!ExtensionSettings.useVsCodeLM && instance) await instance.dispose();
else if (ExtensionSettings.useVsCodeLM && checkAvailability())
context.subscriptions.push(new ChatCompletion());
this.settingsChanged.fire();
}
})
);

function checkAvailability() {
if (!hasLM)
vscode.window.showErrorMessage(
'AppMap: VS Code LM backend for Navie is enabled, but the LanguageModel API is not available.\nPlease update your VS Code to the latest version.'
);
else if (!vscode.extensions.getExtension('github.copilot')) {
vscode.window
.showErrorMessage(
'AppMap: VS Code LM backend for Navie is enabled, but the GitHub Copilot extension is not installed.\nPlease install it from the marketplace and reload the window.',
'Install Copilot'
)
.then((selection) => {
if (selection === 'Install Copilot') {
vscode.lm.onDidChangeChatModels(
() => {
context.subscriptions.push(new ChatCompletion());
ChatCompletion.settingsChanged.fire();
},
undefined,
context.subscriptions
);
vscode.commands.executeCommand(
'workbench.extensions.installExtension',
'github.copilot'
);
}
});
} else return true;
}
}
}

async function sendChatCompletionResponse(
Expand Down

0 comments on commit 3e7c90a

Please sign in to comment.