前回までにやってきたこと#
- VSCode Extension開発環境のセットアップ
- package.jsonにviews設定を追加してWebviewを有効化
今回やること#
- WebViewにtextareaとボタンを追加してユーザーインターフェースを作成
- vscode.lm APIを使ったLLMとの通信機能を実装
- ユーザー入力に対するLLMの応答表示機能を追加
- 基本的なチャット機能を完成
VSCode Extension AI Agent作成 - VSCode LM API連携#
WebViewにtextareaを追加し、vscode.lm APIでLLMを呼び出していきましょう!
前のファイルからWebViewに表示するHTMLを変更します src/extension.tsを以下のように変更してください。
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
const provider = new MagiViewProvider();
context.subscriptions.push(
vscode.window.registerWebviewViewProvider(
"main.view",
provider,
),
);
}
class MagiViewProvider implements vscode.WebviewViewProvider {
public async resolveWebviewView(webviewView: vscode.WebviewView) {
webviewView.webview.options = {
enableScripts: true,
};
//ここから挿入
webviewView.webview.onDidReceiveMessage(async (data) => {
if (data.type === 'promptEntered') {
webviewView.webview.postMessage({
type: 'addElement',
text: data.text
});
const models = await vscode.lm.selectChatModels({ vendor: 'copilot', family: 'gpt-4.1' });
const model = models[0];
const messages = [vscode.LanguageModelChatMessage.User(data.text)];
const response = await model.sendRequest(messages);
let returnTextFromVscodeLm = '';
for await (const fragment of response.text) {
returnTextFromVscodeLm += fragment;
}
webviewView.webview.postMessage({
type: 'addElement',
text: returnTextFromVscodeLm
});
//ここまで挿入
}
});
webviewView.webview.html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Agent</title>
</head>
<body>
Hello World!
<!-- ここから挿入 -->
<textarea id="input-textarea" data-testid="input-textarea" rows="4" style="width:100%" placeholder="Enter text and press Enter..."></textarea>
<div id="output" data-testid="output"></div>
<script>
const vscode = acquireVsCodeApi();
const textarea = document.getElementById('input-textarea');
const output = document.getElementById('output');
textarea.addEventListener('keydown', function(event) {
// Enterキーが押された時
if (event.key === 'Enter') {
// IMEの変換中(composing状態)でない場合のみ処理
if (!event.isComposing) {
event.preventDefault(); // デフォルトの改行を防ぐ
const text = textarea.value.trim();
if (text) {
// VS Codeにメッセージを送信
vscode.postMessage({
type: 'promptEntered',
text: text
});
textarea.value = '';
}
}
}
});
// VS Codeからのメッセージを受け取る
window.addEventListener('message', event => {
const message = event.data;
if (message.type === 'addElement') {
const newDiv = document.createElement('div');
newDiv.textContent = message.text;
output.appendChild(newDiv);
}
});
// composition系のイベントも念のため処理
let isComposing = false;
textarea.addEventListener('compositionstart', function() {
isComposing = true;
});
textarea.addEventListener('compositionend', function() {
isComposing = false;
});
</script>
<!-- ここまで挿入 -->
</body>
</html>`;
}
}
動かしてみる。#
npm run compile
でプロジェクトをビルドしてから、
Visual Studio CodeのメニューのRun→Start Debuggingを押すと新しくVisuao Studio Codeが立ち上がります。
すでにExtensionを立ち上げている場合はソースを表示しているVisual Studio Codeの
で、再起動矢印を押すと反映されます。
textareaに入力してEnterキーを押すと、生成AIが応答して画面に表示されます。 お手軽に生成AIをアプリケーションに取り込めるのは素晴らしいですね!
コードの解説#
要点を解説していきます。
vscode.lm#
vscode.lm APIを使うことで、Visual Studio Codeの拡張機能からLLM(大規模言語モデル)にアクセスできます。 このサンプルでは selectChatModels({ vendor: 'copilot', family: 'gpt-4.1' }) でCopilotのGPT-4.1モデルを選択していますが、API自体は他のベンダーやモデルファミリーも選択できます。 用途や必要に応じて、利用可能なモデル一覧から選択して使ってください。。
UI→バックエンド通信 vscode.postMessage/webviewView.webview.onDidReceiveMessage#
VSCode拡張のWebViewでは、UI(フロントエンド)とバックエンド(拡張本体)は分離されています。 UIからバックエンドに処理を依頼するには、vscode.postMessage でメッセージを送信し、バックエンド側で webviewView.webview.onDidReceiveMessage で受信します。 vscode.lm APIはバックエンドで利用できるため、LLMへの問い合わせは必ずバックエンドで行い、その結果をUIに返すようにしています。
バックエンド→UI通信 webviewView.webview.postMessage/window.addEventListener#
バックエンドからUIへデータを返すには、webviewView.webview.postMessage を使ってメッセージを送信します。 UI側では window.addEventListener('message', ...) で受信し、受け取った内容を画面に反映します。 この仕組みにより、LLMの応答などバックエンドで取得したデータをUIに表示できます。
今回やったこと#
LLMをアプリケーションに組み込むことができました。意外と簡単だったのでは? - HTMLにtextarea、メッセージ表示エリアを追加 - JavaScript側でユーザー入力とメッセージ受信の処理を実装 - vscode.lm APIを使ってLLMとの通信機能を実装 - 基本的なチャット機能が動作することを確認
次にやること#
次はLLMに機能を提供して、生成AIがコードを書けるようにします。