mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-06-13 07:10:26 +08:00
Update for tools changes
This commit is contained in:
@ -49,7 +49,10 @@
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"supportedContentTypes": [
|
||||
"text/plain"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "chat-sample_catVoice",
|
||||
@ -58,7 +61,11 @@
|
||||
"modelDescription": "Speak in a cat voice",
|
||||
"userDescription": "Speak in a cat voice",
|
||||
"icon": "$(files)",
|
||||
"canBeInvokedManually": true
|
||||
"canBeInvokedManually": true,
|
||||
"supportedContentTypes": [
|
||||
"text/plain",
|
||||
"application/vnd.codechat.prompt+json.1"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { contentType, renderElementJSON } from '@vscode/prompt-tsx';
|
||||
import { contentType as promptTsxContentType, renderElementJSON } from '@vscode/prompt-tsx';
|
||||
import * as vscode from 'vscode';
|
||||
import { CatToolPrompt } from './play';
|
||||
import { CatVoiceToolResult } from './tools';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
registerChatTool(context);
|
||||
@ -10,12 +10,16 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
function registerChatTool(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(vscode.lm.registerTool('chat-sample_catVoice', {
|
||||
async invoke(options, token) {
|
||||
return {
|
||||
[contentType]: await renderElementJSON(CatToolPrompt, {}, options.tokenOptions, token),
|
||||
toString() {
|
||||
return 'Reply in the voice of a cat! Use cat analogies when appropriate.';
|
||||
},
|
||||
};
|
||||
const result: vscode.LanguageModelToolResult = {};
|
||||
if (options.requestedContentTypes.includes(promptTsxContentType)) {
|
||||
result[promptTsxContentType] = await renderElementJSON(CatVoiceToolResult, {}, options.tokenOptions, token);
|
||||
}
|
||||
|
||||
if (options.requestedContentTypes.includes('text/plain')) {
|
||||
result['text/plain'] = 'Reply in the voice of a cat! Use cat analogies when appropriate.';
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
}));
|
||||
|
||||
@ -25,19 +29,15 @@ function registerChatTool(context: vscode.ExtensionContext) {
|
||||
|
||||
context.subscriptions.push(vscode.lm.registerTool('chat-sample_tabCount', {
|
||||
async invoke(options, token) {
|
||||
return {
|
||||
toString() {
|
||||
const params = options.parameters as ITabCountParameters;
|
||||
if (typeof params.tabGroup === 'number') {
|
||||
const group = vscode.window.tabGroups.all[Math.max(params.tabGroup - 1, 0)];
|
||||
const nth = params.tabGroup === 1 ? '1st' : params.tabGroup === 2 ? '2nd' : params.tabGroup === 3 ? '3rd' : `${params.tabGroup}th`;
|
||||
return `There are ${group.tabs.length} tabs open in the ${nth} tab group.`;
|
||||
} else {
|
||||
const group = vscode.window.tabGroups.activeTabGroup;
|
||||
return `There are ${group.tabs.length} tabs open.`;
|
||||
}
|
||||
},
|
||||
};
|
||||
const params = options.parameters as ITabCountParameters;
|
||||
if (typeof params.tabGroup === 'number') {
|
||||
const group = vscode.window.tabGroups.all[Math.max(params.tabGroup - 1, 0)];
|
||||
const nth = params.tabGroup === 1 ? '1st' : params.tabGroup === 2 ? '2nd' : params.tabGroup === 3 ? '3rd' : `${params.tabGroup}th`;
|
||||
return { 'text/plain': `There are ${group.tabs.length} tabs open in the ${nth} tab group.` };
|
||||
} else {
|
||||
const group = vscode.window.tabGroups.activeTabGroup;
|
||||
return { 'text/plain': `There are ${group.tabs.length} tabs open.` };
|
||||
}
|
||||
},
|
||||
}));
|
||||
}
|
||||
@ -107,28 +107,31 @@ function registerChatParticipant(context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
stream.progress(`Calling tool: ${tool.id} with ${part.parameters}`);
|
||||
// TODO support prompt-tsx here
|
||||
const requestedContentType = 'text/plain';
|
||||
toolCalls.push({
|
||||
call: part,
|
||||
result: vscode.lm.invokeTool(tool.id, { parameters: JSON.parse(part.parameters), toolInvocationToken: request.toolInvocationToken }, token),
|
||||
result: vscode.lm.invokeTool(tool.id, { parameters: JSON.parse(part.parameters), toolInvocationToken: request.toolInvocationToken, requestedContentTypes: [requestedContentType] }, token),
|
||||
tool
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (toolCalls.length) {
|
||||
let assistantMsg = vscode.LanguageModelChatMessage.Assistant('');
|
||||
const assistantMsg = vscode.LanguageModelChatMessage.Assistant('');
|
||||
assistantMsg.content2 = toolCalls.map(toolCall => new vscode.LanguageModelChatResponseToolCallPart(toolCall.tool.id, toolCall.call.toolCallId, toolCall.call.parameters));
|
||||
messages.push(assistantMsg);
|
||||
for (const toolCall of toolCalls) {
|
||||
// NOTE that the result of calling a function is a special content type of a USER-message
|
||||
let message = vscode.LanguageModelChatMessage.User('');
|
||||
const message = vscode.LanguageModelChatMessage.User('');
|
||||
|
||||
message.content2 = [new vscode.LanguageModelChatMessageToolResultPart(toolCall.call.toolCallId, (await toolCall.result).toString())];
|
||||
messages.push(message);
|
||||
}
|
||||
|
||||
// IMPORTANT The prompt must end with a USER message (with no tool call)
|
||||
messages.push(vscode.LanguageModelChatMessage.User(`Above is the result of calling the functions ${toolCalls.map(call => call.tool.id).join(', ')}. The user cannot see this result, so you should explain it to the user if referencing it in your answer.`));
|
||||
|
||||
|
||||
// RE-enter
|
||||
return runWithFunctions();
|
||||
}
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
import {
|
||||
BasePromptElementProps,
|
||||
PromptElement,
|
||||
PromptSizing,
|
||||
TextChunk,
|
||||
UserMessage
|
||||
} from '@vscode/prompt-tsx';
|
||||
|
||||
export interface PromptProps extends BasePromptElementProps {
|
||||
userQuery: string;
|
||||
}
|
||||
|
||||
export class PlayPrompt extends PromptElement<PromptProps, void> {
|
||||
render(state: void, sizing: PromptSizing) {
|
||||
return (
|
||||
<>
|
||||
<UserMessage>
|
||||
You are a cat! Reply in the voice of a cat, using cat analogies when
|
||||
appropriate. Be concise to prepare for cat play time. Give a small random
|
||||
python code sample (that has cat names for variables).
|
||||
</UserMessage>
|
||||
<UserMessage>{this.props.userQuery}</UserMessage>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class CatToolPrompt extends PromptElement<BasePromptElementProps, void> {
|
||||
render(state: void, sizing: PromptSizing) {
|
||||
return (
|
||||
<>
|
||||
<TextChunk>
|
||||
Reply in the voice of a cat! Use cat analogies when appropriate.
|
||||
</TextChunk>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
19
chat-sample/src/tools.tsx
Normal file
19
chat-sample/src/tools.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import {
|
||||
BasePromptElementProps,
|
||||
PromptElement,
|
||||
PromptSizing,
|
||||
TextChunk,
|
||||
UserMessage
|
||||
} from '@vscode/prompt-tsx';
|
||||
|
||||
export class CatVoiceToolResult extends PromptElement<BasePromptElementProps, void> {
|
||||
render(state: void, sizing: PromptSizing) {
|
||||
return (
|
||||
<>
|
||||
<TextChunk>
|
||||
Reply in the voice of a cat! Use cat analogies when appropriate.
|
||||
</TextChunk>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -214,6 +214,8 @@ declare module 'vscode' {
|
||||
* The `data` for any confirmations that were rejected
|
||||
*/
|
||||
rejectedConfirmationData?: any[];
|
||||
|
||||
userSelectedModel?: LanguageModelChat;
|
||||
}
|
||||
|
||||
// TODO@API fit this into the stream
|
||||
@ -248,10 +250,6 @@ declare module 'vscode' {
|
||||
|
||||
export type ChatExtendedRequestHandler = (request: ChatRequest, context: ChatContext, response: ChatResponseStream, token: CancellationToken) => ProviderResult<ChatResult | void>;
|
||||
|
||||
export interface ChatRequest {
|
||||
toolInvocationToken: ChatParticipantToolToken;
|
||||
}
|
||||
|
||||
export interface ChatResult {
|
||||
nextQuestion?: {
|
||||
prompt: string;
|
||||
@ -310,7 +308,14 @@ declare module 'vscode' {
|
||||
codeBlockIndex: number;
|
||||
totalCharacters: number;
|
||||
newFile?: boolean;
|
||||
userAction?: string;
|
||||
}
|
||||
|
||||
export interface ChatApplyAction {
|
||||
// eslint-disable-next-line local/vscode-dts-string-type-literals
|
||||
kind: 'apply';
|
||||
codeBlockIndex: number;
|
||||
totalCharacters: number;
|
||||
newFile?: boolean;
|
||||
codeMapper?: string;
|
||||
}
|
||||
|
||||
@ -345,7 +350,7 @@ declare module 'vscode' {
|
||||
|
||||
export interface ChatUserActionEvent {
|
||||
readonly result: ChatResult;
|
||||
readonly action: ChatCopyAction | ChatInsertAction | ChatTerminalAction | ChatCommandAction | ChatFollowupAction | ChatBugReportAction | ChatEditorAction;
|
||||
readonly action: ChatCopyAction | ChatInsertAction | ChatApplyAction | ChatTerminalAction | ChatCommandAction | ChatFollowupAction | ChatBugReportAction | ChatEditorAction;
|
||||
}
|
||||
|
||||
export interface ChatPromptReference {
|
||||
|
||||
31
chat-sample/vscode.proposed.lmTools.d.ts
vendored
31
chat-sample/vscode.proposed.lmTools.d.ts
vendored
@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// version: 6
|
||||
// version: 7
|
||||
// https://github.com/microsoft/vscode/issues/213274
|
||||
|
||||
declare module 'vscode' {
|
||||
@ -73,14 +73,10 @@ declare module 'vscode' {
|
||||
|
||||
export interface LanguageModelToolResult {
|
||||
/**
|
||||
* The result can contain arbitrary representations of the content. An example might be a `PromptElementJSON` from `@vscode/prompt-tsx`, using the `contentType` exported by that library.
|
||||
* The result can contain arbitrary representations of the content. Use {@link LanguageModelToolInvocationOptions.requested} to request particular types.
|
||||
* `text/plain` is required to be supported by all tools. Another example might be a `PromptElementJSON` from `@vscode/prompt-tsx`, using the `contentType` exported by that library.
|
||||
*/
|
||||
[contentType: string]: any;
|
||||
|
||||
/**
|
||||
* A string representation of the result which can be incorporated back into an LLM prompt without any special handling.
|
||||
*/
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
// Tool registration/invoking between extensions
|
||||
@ -98,7 +94,6 @@ declare module 'vscode' {
|
||||
|
||||
/**
|
||||
* Invoke a tool with the given parameters.
|
||||
* TODO@API Could request a set of contentTypes to be returned so they don't all need to be computed?
|
||||
*/
|
||||
export function invokeTool(id: string, options: LanguageModelToolInvocationOptions, token: CancellationToken): Thenable<LanguageModelToolResult>;
|
||||
}
|
||||
@ -106,6 +101,11 @@ declare module 'vscode' {
|
||||
export type ChatParticipantToolToken = unknown;
|
||||
|
||||
export interface LanguageModelToolInvocationOptions {
|
||||
/**
|
||||
* When this tool is being invoked within the context of a chat request, this token should be passed from {@link ChatRequest.toolInvocationToken}.
|
||||
* In that case, a progress bar will be automatically shown for the tool invocation in the chat response view. If the tool is being invoked
|
||||
* outside of a chat request, `undefined` should be passed instead.
|
||||
*/
|
||||
toolInvocationToken: ChatParticipantToolToken | undefined;
|
||||
|
||||
/**
|
||||
@ -113,6 +113,11 @@ declare module 'vscode' {
|
||||
*/
|
||||
parameters: Object;
|
||||
|
||||
/**
|
||||
* A tool invoker can request that particular content types be returned from the tool. All tools are required to support `text/plain`.
|
||||
*/
|
||||
requestedContentTypes: string[];
|
||||
|
||||
/**
|
||||
* Options to hint at how many tokens the tool should return in its response.
|
||||
*/
|
||||
@ -154,6 +159,11 @@ declare module 'vscode' {
|
||||
* A JSON schema for the parameters this tool accepts.
|
||||
*/
|
||||
parametersSchema?: JSONSchema;
|
||||
|
||||
/**
|
||||
* The list of content types that the tool has declared support for.
|
||||
*/
|
||||
supportedContentTypes: string[];
|
||||
}
|
||||
|
||||
export interface LanguageModelTool {
|
||||
@ -188,6 +198,11 @@ declare module 'vscode' {
|
||||
* string-manipulation of the prompt.
|
||||
*/
|
||||
readonly toolReferences: readonly ChatLanguageModelToolReference[];
|
||||
|
||||
/**
|
||||
* A token that can be passed to {@link lm.invokeTool} when invoking a tool inside the context of handling a chat request.
|
||||
*/
|
||||
readonly toolInvocationToken: ChatParticipantToolToken;
|
||||
}
|
||||
|
||||
export interface ChatRequestTurn {
|
||||
|
||||
Reference in New Issue
Block a user