mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-06-13 07:10:26 +08:00
88 lines
3.6 KiB
TypeScript
88 lines
3.6 KiB
TypeScript
import * as vscode from 'vscode';
|
|
|
|
const PARTICIPANT_ID = 'chat-sample.tools';
|
|
|
|
export function activate(context: vscode.ExtensionContext) {
|
|
|
|
const handler: vscode.ChatRequestHandler = async (request: vscode.ChatRequest, chatContext: vscode.ChatContext, stream: vscode.ChatResponseStream, token: vscode.CancellationToken) => {
|
|
const models = await vscode.lm.selectChatModels({
|
|
vendor: 'copilot',
|
|
family: 'gpt-4-turbo'
|
|
});
|
|
|
|
const chat = models[0];
|
|
|
|
if (!chat) {
|
|
console.log('NO MODELS')
|
|
return {};
|
|
}
|
|
|
|
stream.markdown(`Available tools: ${vscode.lm.tools.map(tool => tool.id).join(', ')}\n\n`);
|
|
|
|
const options: vscode.LanguageModelChatRequestOptions = {
|
|
tools: vscode.lm.tools.map((tool): vscode.LanguageModelChatFunction => {
|
|
return {
|
|
name: tool.id.replace(/\./g, '_'),
|
|
description: tool.description,
|
|
parametersSchema: tool.parametersSchema ?? {}
|
|
}
|
|
}),
|
|
justification: 'Just because!',
|
|
}
|
|
|
|
const messages = [
|
|
vscode.LanguageModelChatMessage.User(`There is a selection of tools that may give helpful context to answer the user's query. If you aren't sure which tool is relevant, you can call multiple tools.`),
|
|
vscode.LanguageModelChatMessage.User(request.prompt)
|
|
];
|
|
const runWithFunctions = async () => {
|
|
|
|
let didReceiveFunctionUse = false;
|
|
|
|
const response = await chat.sendRequest(messages, options, token);
|
|
|
|
for await (const part of response.stream) {
|
|
if (part instanceof vscode.LanguageModelChatResponseTextPart) {
|
|
stream.markdown(part.value)
|
|
} else if (part instanceof vscode.LanguageModelChatResponseFunctionUsePart) {
|
|
const tool = vscode.lm.tools.find(tool => tool.id.replace(/\./g, '_') === part.name);
|
|
if (!tool) {
|
|
// BAD tool choice?
|
|
continue;
|
|
}
|
|
|
|
const resultPromise = vscode.lm.invokeTool(tool.id, JSON.parse(part.parameters), token);
|
|
stream.progress(`FUNCTION_CALL: ${tool.id} with \`${part.parameters}\``, async (progress) => {
|
|
await resultPromise;
|
|
});
|
|
|
|
const result = await resultPromise;
|
|
|
|
// NOTE that the result of calling a function is a special content type of a USER-message
|
|
let message = vscode.LanguageModelChatMessage.User('');
|
|
message.content2 = new vscode.LanguageModelChatMessageFunctionResultPart(tool.id, result)
|
|
messages.push(message)
|
|
|
|
// IMPORTANT
|
|
// IMPORTANT working around CAPI always wanting to end with a `User`-message
|
|
// IMPORTANT
|
|
messages.push(vscode.LanguageModelChatMessage.User(`Above is the result of calling the function ${tool.id}. The user cannot see this result, so you should explain it to the user if referencing it in your answer.`))
|
|
didReceiveFunctionUse = true;
|
|
}
|
|
}
|
|
|
|
if (didReceiveFunctionUse) {
|
|
// RE-enter
|
|
return runWithFunctions();
|
|
}
|
|
};
|
|
|
|
await runWithFunctions()
|
|
};
|
|
|
|
const toolUser = vscode.chat.createChatParticipant(PARTICIPANT_ID, handler);
|
|
toolUser.iconPath = new vscode.ThemeIcon('tools');
|
|
}
|
|
|
|
|
|
export function deactivate() { }
|