Adopt tools change

This commit is contained in:
Rob Lourens
2024-08-05 15:34:56 -07:00
parent 6541ce2cbf
commit 80947131b6
4 changed files with 67 additions and 279 deletions

View File

@ -1,22 +1,31 @@
import * as vscode from 'vscode';
const PARTICIPANT_ID = 'chat-sample.tools';
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(registerChatTool());
context.subscriptions.push(registerChatParticipant());
}
function registerChatTool() {
return vscode.lm.registerTool('chat-sample.activeTabCount', {
async invoke(parameters, token) {
return {
toString() {
const activeTabCount = vscode.window.tabGroups.activeTabGroup.tabs.length;
return `There are ${activeTabCount} tabs open.`;
},
};
},
});
}
function registerChatParticipant() {
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'
family: 'gpt-4o'
});
const chat = models[0];
if (!chat) {
console.log('NO MODELS')
return {};
}
const model = models[0];
stream.markdown(`Available tools: ${vscode.lm.tools.map(tool => tool.name).join(', ')}\n\n`);
const options: vscode.LanguageModelChatRequestOptions = {
@ -25,24 +34,23 @@ export function activate(context: vscode.ExtensionContext) {
name: tool.name.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)
vscode.LanguageModelChatMessage.User(request.prompt),
];
const runWithFunctions = async () => {
let didReceiveFunctionUse = false;
const response = await chat.sendRequest(messages, options, token);
const response = await model.sendRequest(messages, options, token);
for await (const part of response.stream) {
if (part instanceof vscode.LanguageModelChatResponseTextPart) {
stream.markdown(part.value)
stream.markdown(part.value);
} else if (part instanceof vscode.LanguageModelChatResponseFunctionUsePart) {
const tool = vscode.lm.tools.find(tool => tool.name.replace(/\./g, '_') === part.name);
if (!tool) {
@ -50,22 +58,27 @@ export function activate(context: vscode.ExtensionContext) {
continue;
}
let parameters: any;
try {
parameters = JSON.parse(part.parameters);
} catch (err) {
throw new Error(`Got invalid tool use parameters: "${part.parameters}". (${(err as Error).message})`);
}
const resultPromise = vscode.lm.invokeTool(tool.name, JSON.parse(part.parameters), token);
stream.progress(`FUNCTION_CALL: ${tool.name} with \`${part.parameters}\``, async (progress) => {
await resultPromise;
});
stream.progress(`FUNCTION_CALL: ${tool.name} with ${part.parameters}`);
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.name, result)
messages.push(message)
message.content2 = new vscode.LanguageModelChatMessageFunctionResultPart(tool.name.replace(/\./g, '_'), result.toString());
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.name}. The user cannot see this result, so you should explain it to the user if referencing it in your answer.`))
messages.push(vscode.LanguageModelChatMessage.User(`Above is the result of calling the function ${tool.name}. The user cannot see this result, so you should explain it to the user if referencing it in your answer.`));
didReceiveFunctionUse = true;
}
}
@ -76,11 +89,13 @@ export function activate(context: vscode.ExtensionContext) {
}
};
await runWithFunctions()
await runWithFunctions();
};
const toolUser = vscode.chat.createChatParticipant(PARTICIPANT_ID, handler);
const toolUser = vscode.chat.createChatParticipant('chat-sample.tools', handler);
toolUser.iconPath = new vscode.ThemeIcon('tools');
return toolUser;
}