この記事の内容は、『以下の公式手順「Your First Extension」の内容をもとにしたシンプルな VS Code の拡張機能の作成』と、『作成した拡張機能に少しだけ手を加えて「Language Model API」を雑に組み込む』というのをやってみた話です。
●Your First Extension | Visual Studio Code Extension API
https://code.visualstudio.com/api/get-started/your-first-extension
それで以下のように、API経由で簡易に GitHub Copilot の回答を得る、というお試しをやります。
今回の内容をやってみたきっかけ
今回の内容をやった背景について書くと、以下の記事でとりあげた『拡張機能「Recline」の中で使われている VSCode Extension API の「Language Model API」を知って、実際に試してみたくなったことがきっかけ』です。
●「Recline」で使われている VSCode Extension API の「Language Model API」の公式情報: API の使い方など - Qiita
https://qiita.com/youtoy/items/c4e70aa794b03d86ed08
この API を使うと、自作の VS Code の拡張機能から GitHub Copilot とのやりとりを扱うことができます。
●Language Model API | Visual Studio Code Extension API
https://code.visualstudio.com/api/extension-guides/language-model
まずは公式サンプルのシンプルな拡張機能を作ってみる
上記の API は拡張機能用の API のため拡張機能を作る必要があるのですが、今まで VS Code用の拡張機能を作ったことはありませんでした。
それで、まずは冒頭に掲載した公式手順を見て「Hello World」を出力するシンプルな拡張機能の作成から着手していきました。
下準備1
Yeoman をグローバルにインストールしないやり方で進めてみます。
具体的には以下のコマンドで下準備を進めます。
npx --package yo --package generator-code -- yo code
上記のコマンドの実行後に出力された内容の最初の部分と、上記のコマンドについて書かれた公式ページをポストしていたものを掲載します。
下準備2
この後は、以下のように設定してみました。
あまり深い意味はなく、自分の好みだったり適当に決めたりした感じです。
実行してみる
上記で作成されたものを VS Code で開くと、以下のようになりました(※ extension.js を開いた状態です)。
まずは、今の状態のものを実行してみます。
この時は「F5」キーを押してデバッグ実行をしました。
(もちろん、以下のメニューをたどって実行したり、画面左の「実行とデバッグ」のアイコンから進めていったりしても大丈夫です)
デバック実行をした後、新しいウィンドウが開きます。
そのウィンドウの中で「Ctrl + Shift + P」のショートカットキーを使ってコマンドパレットを開き、以下のように「Hello World」のスペルを入力して処理を実行しました(※ 途中まで入力した状態で Hello World のコマンドが候補に出てくるので、それで実行すれば OK)。
その後、ウィンドウ右下に以下の表示が出て、拡張機能が正常に動作したことを確認できました。
雑に「Language Model API」を組み込む
それでは「Language Model API」を組み込んで GitHub Copilot のレスポンスを得られるようにしてみます。
Language Model API を使う処理では、「モデルの読み込み ⇒ プロンプトの送信 ⇒ レスポンスの受信」という流れを作れば試せそうでした。
上記サンプルは「処理の実行 ⇒ テキストの出力」という流れだったので、この処理の間に上記の Language Model API による処理を単純に組み込みます。
コード
Language Model API を使った処理を追加実装したコードは、以下のとおりです。
const vscode = require("vscode");
const MODEL_SELECTOR = {
vendor: "copilot",
// family: "gpt-4o",
};
const craftedPrompt = [vscode.LanguageModelChatMessage.User("あなたは誰?")];
async function getFullResponse(chatResponse) {
let fullText = "";
for await (const fragment of chatResponse.text) {
fullText += fragment;
}
return fullText;
}
function activate(context) {
console.log('Congratulations, your extension "test" is now active!');
const disposable = vscode.commands.registerCommand(
"test.helloWorld",
async () => {
const [model] = await vscode.lm.selectChatModels(MODEL_SELECTOR);
if (model) {
const chatResponse = await model.sendRequest(
craftedPrompt,
{},
new vscode.CancellationTokenSource().token
);
vscode.window.showInformationMessage("Hello World from test!");
const fullResponse = await getFullResponse(chatResponse);
vscode.window.showInformationMessage(fullResponse);
} else {
vscode.window.showErrorMessage("Failed to select model");
}
}
);
context.subscriptions.push(disposable);
}
function deactivate() {}
module.exports = {
activate,
deactivate,
};
いったん、モデル指定の部分は「vendor: "copilot"
」のみのシンプルな記述で試してみました。
得られた結果
その結果、以下のレスポンスを得られたのを確認できました。
Language Model API を使った処理を実行した際、以下のダイアログが出たので利用を許可する操作も行っています。
モデルを「claude-3.5-sonnet」にして実行してみる
前の記事でも書いたのですが、記事執筆時点で選べるモデルは以下のように複数あります。
この中の「claude-3.5-sonnet」を指定して、先ほどのプログラムを実行する、というのも試してみました。具体的には、モデル指定の部分を以下としました。
const MODEL_SELECTOR = {
vendor: "copilot",
family: "claude-3.5-sonnet",
};
その結果、冒頭にも掲載していたように Anthropic・Claude の名前が含まれるレスポンスを得られました