mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-04-27 16:55:44 +08:00
lmTools API updates (#1111)
* Adopt API updates * More api adoptions * Bump prompt-tsx * Remove supportedResultMimeTypes
This commit is contained in:
10
chat-tools-sample/package-lock.json
generated
10
chat-tools-sample/package-lock.json
generated
@ -10,14 +10,14 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.5.9",
|
||||
"@types/vscode": "^1.94.0",
|
||||
"@vscode/prompt-tsx": "^0.3.0-alpha.3",
|
||||
"@vscode/prompt-tsx": "^0.3.0-alpha.8",
|
||||
"eslint": "^7.22.0",
|
||||
"run-script-os": "^1.1.6",
|
||||
"tslint": "^6.1.3",
|
||||
"typescript": "^4.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.93.0"
|
||||
"vscode": "^1.95.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aashutoshrathi/word-wrap": {
|
||||
@ -219,9 +219,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@vscode/prompt-tsx": {
|
||||
"version": "0.3.0-alpha.3",
|
||||
"resolved": "https://registry.npmjs.org/@vscode/prompt-tsx/-/prompt-tsx-0.3.0-alpha.3.tgz",
|
||||
"integrity": "sha512-SJSgjkET0meUowh1n/k7inFbbo7I6R3JkOLI7tmgZc5HfJ+5blkh8ge0iyMk6t0GVHbBNh9gG6OQXceNk4F0IQ==",
|
||||
"version": "0.3.0-alpha.8",
|
||||
"resolved": "https://registry.npmjs.org/@vscode/prompt-tsx/-/prompt-tsx-0.3.0-alpha.8.tgz",
|
||||
"integrity": "sha512-uhGZve/mhrSkFNU1zvhcbbPL8laT8Ytlk3q5sswE8XnveiCb7eANk7Ea4IkKI3KvbThX3p3cl3xOauHuqrhlSg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
|
||||
@ -65,10 +65,7 @@
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"supportedContentTypes": [
|
||||
"text/plain"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "chat-tools-sample_findFiles",
|
||||
@ -90,10 +87,7 @@
|
||||
"required": [
|
||||
"pattern"
|
||||
]
|
||||
},
|
||||
"supportedContentTypes": [
|
||||
"text/plain"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "chat-tools-sample_runInTerminal",
|
||||
@ -114,10 +108,7 @@
|
||||
"required": [
|
||||
"command"
|
||||
]
|
||||
},
|
||||
"supportedContentTypes": [
|
||||
"text/plain"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -130,7 +121,7 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.5.9",
|
||||
"@types/vscode": "^1.94.0",
|
||||
"@vscode/prompt-tsx": "^0.3.0-alpha.3",
|
||||
"@vscode/prompt-tsx": "^0.3.0-alpha.8",
|
||||
"eslint": "^7.22.0",
|
||||
"run-script-os": "^1.1.6",
|
||||
"tslint": "^6.1.3",
|
||||
|
||||
@ -17,7 +17,7 @@ function registerChatTool(context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
interface IToolCall {
|
||||
tool: vscode.LanguageModelToolDescription;
|
||||
tool: vscode.LanguageModelToolInformation;
|
||||
call: vscode.LanguageModelToolCallPart;
|
||||
result: Thenable<vscode.LanguageModelToolResult>;
|
||||
}
|
||||
@ -58,11 +58,10 @@ function registerChatParticipant(context: vscode.ExtensionContext) {
|
||||
const runWithFunctions = async (): Promise<void> => {
|
||||
const requestedTool = toolReferences.shift();
|
||||
if (requestedTool) {
|
||||
options.toolChoice = requestedTool.id;
|
||||
// options.tools = allTools.filter(tool => tool.name === requestedTool.id);
|
||||
options.tools = JSON.parse(`[{"type":"function","function":{"name":"copilot_codebase","description":"Search for relevant file chunks, symbols, and other info about the current workspace or codebase","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The query to search the codebase for. Should contain all relevant context. Can be a full natural language sentence, or keywords."}},"required":["query"]}}},{"type":"function","function":{"name":"copilot_vscodeAPI","description":"Use VS Code API references to answer questions about VS Code extension development.","parameters":{"type":"object","properties":{"query":{"type":"string","description":"The query to search vscode documentation for. Should contain all relevant context."}},"required":["query"]}}},{"type":"function","function":{"name":"ada-data_findFiles","description":"Search for files in the current workspace","parameters":{"type":"object","properties":{"pattern":{"type":"string","description":"Search for files that match this glob pattern"}},"required":["pattern"]}}},{"type":"function","function":{"name":"ada-data_runPython","description":"Execute Python code locally using Pyodide, providing access to Python's extensive functionality. This tool extends the LLM's capabilities by allowing it to run Python code for a wide range of computational tasks and data manipulations that it cannot perform directly. When you know the workspace folder path and the file path, use the relative path to the file when generating code.","parameters":{"type":"object","properties":{"code":{"type":"string","description":"The Python code to run"}},"required":["code"]}}}`)
|
||||
options.toolMode = vscode.LanguageModelChatToolMode.Required;
|
||||
options.tools = allTools.filter(tool => tool.name === requestedTool.name);
|
||||
} else {
|
||||
options.toolChoice = undefined;
|
||||
options.toolMode = undefined;
|
||||
options.tools = [...allTools];
|
||||
}
|
||||
|
||||
@ -78,11 +77,9 @@ function registerChatParticipant(context: vscode.ExtensionContext) {
|
||||
throw new Error('Got invalid tool choice: ' + part.name);
|
||||
}
|
||||
|
||||
// TODO support prompt-tsx here
|
||||
const requestedContentType = 'text/plain';
|
||||
toolCalls.push({
|
||||
call: part,
|
||||
result: vscode.lm.invokeTool(tool.name, { parameters: part.parameters, toolInvocationToken: request.toolInvocationToken, requestedContentTypes: [requestedContentType] }, token),
|
||||
result: vscode.lm.invokeTool(tool.name, { parameters: part.parameters, toolInvocationToken: request.toolInvocationToken }, token),
|
||||
tool
|
||||
});
|
||||
}
|
||||
@ -90,13 +87,13 @@ function registerChatParticipant(context: vscode.ExtensionContext) {
|
||||
|
||||
if (toolCalls.length) {
|
||||
const assistantMsg = vscode.LanguageModelChatMessage.Assistant('');
|
||||
assistantMsg.content2 = toolCalls.map(toolCall => new vscode.LanguageModelToolCallPart(toolCall.tool.name, toolCall.call.toolCallId, toolCall.call.parameters));
|
||||
assistantMsg.content2 = toolCalls.map(toolCall => new vscode.LanguageModelToolCallPart(toolCall.tool.name, (toolCall.call.callId), 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
|
||||
const message = vscode.LanguageModelChatMessage.User('');
|
||||
|
||||
message.content2 = [new vscode.LanguageModelToolResultPart(toolCall.call.toolCallId, (await toolCall.result)['text/plain']!)];
|
||||
message.content2 = [new vscode.LanguageModelToolResultPart(toolCall.call.callId, (await toolCall.result).content)];
|
||||
messages.push(message);
|
||||
}
|
||||
|
||||
|
||||
@ -20,16 +20,14 @@ export class TabCountTool implements vscode.LanguageModelTool<ITabCountParameter
|
||||
: params.tabGroup === 3
|
||||
? '3rd'
|
||||
: `${params.tabGroup}th`;
|
||||
return {
|
||||
'text/plain': `There are ${group.tabs.length} tabs open in the ${nth} tab group.`,
|
||||
};
|
||||
return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(`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.` };
|
||||
return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(`There are ${group.tabs.length} tabs open.`)]);
|
||||
}
|
||||
}
|
||||
|
||||
async prepareToolInvocation(
|
||||
async prepareInvocation(
|
||||
options: vscode.LanguageModelToolInvocationPrepareOptions<ITabCountParameters>,
|
||||
token: vscode.CancellationToken
|
||||
) {
|
||||
@ -67,18 +65,11 @@ export class FindFilesTool implements vscode.LanguageModelTool<IFindFilesParamet
|
||||
token
|
||||
);
|
||||
|
||||
const result: vscode.LanguageModelToolResult = {};
|
||||
if (options.requestedContentTypes.includes('text/plain')) {
|
||||
const strFiles = files.map((f) => f.fsPath).join('\n');
|
||||
result[
|
||||
'text/plain'
|
||||
] = `Found ${files.length} files matching "${params.pattern}":\n${strFiles}`;
|
||||
}
|
||||
|
||||
return result;
|
||||
const strFiles = files.map((f) => f.fsPath).join('\n');
|
||||
return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(`Found ${files.length} files matching "${params.pattern}":\n${strFiles}`)]);
|
||||
}
|
||||
|
||||
async prepareToolInvocation(
|
||||
async prepareInvocation(
|
||||
options: vscode.LanguageModelToolInvocationPrepareOptions<IFindFilesParameters>,
|
||||
token: vscode.CancellationToken
|
||||
) {
|
||||
@ -123,7 +114,6 @@ export class RunInTerminalTool
|
||||
options: vscode.LanguageModelToolInvocationOptions<IRunInTerminalParameters>,
|
||||
token: vscode.CancellationToken
|
||||
) {
|
||||
const result: vscode.LanguageModelToolResult = {};
|
||||
const params = options.parameters as IRunInTerminalParameters;
|
||||
|
||||
const terminal = vscode.window.createTerminal('Language Model Tool User');
|
||||
@ -131,10 +121,7 @@ export class RunInTerminalTool
|
||||
try {
|
||||
await waitForShellIntegration(terminal, 5000);
|
||||
} catch(e) {
|
||||
if (options.requestedContentTypes.includes('text/plain')) {
|
||||
result['text/plain'] = (e as Error).message;
|
||||
}
|
||||
return result;
|
||||
return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart((e as Error).message)]);
|
||||
}
|
||||
|
||||
const execution = terminal.shellIntegration!.executeCommand(params.command);
|
||||
@ -145,14 +132,10 @@ export class RunInTerminalTool
|
||||
terminalResult += chunk;
|
||||
}
|
||||
|
||||
if (options.requestedContentTypes.includes('text/plain')) {
|
||||
result['text/plain'] = terminalResult;
|
||||
}
|
||||
|
||||
return result;
|
||||
return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(terminalResult)]);
|
||||
}
|
||||
|
||||
async prepareToolInvocation(
|
||||
async prepareInvocation(
|
||||
options: vscode.LanguageModelToolInvocationPrepareOptions<IRunInTerminalParameters>,
|
||||
token: vscode.CancellationToken
|
||||
) {
|
||||
|
||||
@ -13,9 +13,12 @@ import {
|
||||
Chunk,
|
||||
ToolMessage,
|
||||
PromptReference,
|
||||
TextChunk,
|
||||
} from '@vscode/prompt-tsx';
|
||||
import * as vscode from 'vscode';
|
||||
import { isTsxToolUserMetadata } from './tsxParticipant';
|
||||
import { PromptElementJSON } from '@vscode/prompt-tsx/dist/base/jsonTypes';
|
||||
import { ToolResult } from '@vscode/prompt-tsx/dist/base/promptElements';
|
||||
|
||||
export interface ToolCallRound {
|
||||
response: string;
|
||||
@ -89,13 +92,13 @@ class ToolCalls extends PromptElement<ToolCallsProps, void> {
|
||||
}
|
||||
|
||||
private renderOneToolCallRound(round: ToolCallRound) {
|
||||
const assistantToolCalls: ToolCall[] = round.toolCalls.map(tc => ({ type: 'function', function: { name: tc.name, arguments: JSON.stringify(tc.parameters) }, id: tc.toolCallId }));
|
||||
const assistantToolCalls: ToolCall[] = round.toolCalls.map(tc => ({ type: 'function', function: { name: tc.name, arguments: JSON.stringify(tc.parameters) }, id: tc.callId }));
|
||||
// TODO- just need to adopt prompt-tsx update in vscode-copilot
|
||||
return (
|
||||
<Chunk>
|
||||
<AssistantMessage toolCalls={assistantToolCalls}>{round.response || 'placeholder'}</AssistantMessage>
|
||||
<AssistantMessage toolCalls={assistantToolCalls}>{round.response}</AssistantMessage>
|
||||
{round.toolCalls.map(toolCall =>
|
||||
<ToolCallElement toolCall={toolCall} toolInvocationToken={this.props.toolInvocationToken} toolCallResult={this.props.toolCallResults[toolCall.toolCallId]}></ToolCallElement>)}
|
||||
<ToolCallElement toolCall={toolCall} toolInvocationToken={this.props.toolInvocationToken} toolCallResult={this.props.toolCallResults[toolCall.callId]}></ToolCallElement>)}
|
||||
</Chunk>);
|
||||
}
|
||||
}
|
||||
@ -111,31 +114,34 @@ class ToolCallElement extends PromptElement<ToolCallElementProps, void> {
|
||||
const tool = vscode.lm.tools.find(t => t.name === this.props.toolCall.name);
|
||||
if (!tool) {
|
||||
console.error(`Tool not found: ${this.props.toolCall.name}`);
|
||||
return <ToolMessage toolCallId={this.props.toolCall.toolCallId}>Tool not found</ToolMessage>;
|
||||
return <ToolMessage toolCallId={this.props.toolCall.callId}>Tool not found</ToolMessage>;
|
||||
}
|
||||
|
||||
const contentType = agentSupportedContentTypes.find(type => tool.supportedContentTypes.includes(type));
|
||||
if (!contentType) {
|
||||
console.error(`Tool does not support any of the agent's content types: ${tool.name}`);
|
||||
return <ToolMessage toolCallId={this.props.toolCall.toolCallId}>Tool unsupported</ToolMessage>;
|
||||
}
|
||||
|
||||
const tokenOptions: vscode.LanguageModelToolInvocationOptions<unknown>['tokenOptions'] = {
|
||||
const tokenizationOptions: vscode.LanguageModelToolTokenizationOptions = {
|
||||
tokenBudget: sizing.tokenBudget,
|
||||
countTokens: async (content: string) => sizing.countTokens(content),
|
||||
};
|
||||
|
||||
const toolResult = this.props.toolCallResult ??
|
||||
await vscode.lm.invokeTool(this.props.toolCall.name, { parameters: this.props.toolCall.parameters, requestedContentTypes: [contentType], toolInvocationToken: this.props.toolInvocationToken, tokenOptions }, dummyCancellationToken);
|
||||
const message = (
|
||||
<ToolMessage toolCallId={this.props.toolCall.toolCallId}>
|
||||
<meta value={new ToolResultMetadata(this.props.toolCall.toolCallId, toolResult)}></meta>
|
||||
{contentType === 'text/plain' ?
|
||||
toolResult[contentType] :
|
||||
<elementJSON data={toolResult[contentType]}></elementJSON>}
|
||||
await vscode.lm.invokeTool(this.props.toolCall.name, { parameters: this.props.toolCall.parameters, toolInvocationToken: this.props.toolInvocationToken, tokenizationOptions }, dummyCancellationToken);
|
||||
|
||||
// Important- since these parts may have been serialized/deserialized via ChatResult metadata, we need to check their types
|
||||
// in a more flexible way. Extensions should not have to do this, vscode will have a better solution in the future.
|
||||
toolResult.content = toolResult.content.map(part => {
|
||||
if (part instanceof vscode.LanguageModelTextPart || part instanceof vscode.LanguageModelPromptTsxPart) {
|
||||
return part;
|
||||
} else if ((part as vscode.LanguageModelPromptTsxPart).mime) {
|
||||
return new vscode.LanguageModelPromptTsxPart((part as vscode.LanguageModelPromptTsxPart).value, (part as vscode.LanguageModelPromptTsxPart).mime);
|
||||
} else if (typeof (part as vscode.LanguageModelTextPart).value === 'string') {
|
||||
return new vscode.LanguageModelTextPart((part as vscode.LanguageModelTextPart).value);
|
||||
}
|
||||
})
|
||||
return (
|
||||
<ToolMessage toolCallId={this.props.toolCall.callId}>
|
||||
<meta value={new ToolResultMetadata(this.props.toolCall.callId, toolResult)}></meta>
|
||||
<ToolResult data={toolResult} />
|
||||
</ToolMessage>
|
||||
);
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -66,10 +66,10 @@ export function registerTsxChatParticipant(context: vscode.ExtensionContext) {
|
||||
const runWithFunctions = async (): Promise<void> => {
|
||||
const requestedTool = toolReferences.shift();
|
||||
if (requestedTool) {
|
||||
options.toolChoice = requestedTool.id;
|
||||
options.tools = allTools.filter(tool => tool.name === requestedTool.id);
|
||||
options.toolMode = vscode.LanguageModelChatToolMode.Required;
|
||||
options.tools = allTools.filter(tool => tool.name === requestedTool.name);
|
||||
} else {
|
||||
options.toolChoice = undefined;
|
||||
options.toolMode = undefined;
|
||||
options.tools = allTools;
|
||||
}
|
||||
|
||||
|
||||
218
chat-tools-sample/vscode.proposed.lmTools.d.ts
vendored
218
chat-tools-sample/vscode.proposed.lmTools.d.ts
vendored
@ -3,87 +3,164 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// version: 9
|
||||
// version: 10
|
||||
// https://github.com/microsoft/vscode/issues/213274
|
||||
|
||||
declare module 'vscode' {
|
||||
|
||||
// TODO@API capabilities
|
||||
|
||||
// API -> LM: an tool/function that is available to the language model
|
||||
/**
|
||||
* A tool that is available to the language model via {@link LanguageModelChatRequestOptions}. A language model uses all the
|
||||
* properties of this interface to decide which tool to call, and how to call it.
|
||||
*/
|
||||
export interface LanguageModelChatTool {
|
||||
/**
|
||||
* The name of the tool.
|
||||
*/
|
||||
name: string;
|
||||
|
||||
/**
|
||||
* The description of the tool.
|
||||
*/
|
||||
description: string;
|
||||
|
||||
/**
|
||||
* A JSON schema for the parameters this tool accepts.
|
||||
*/
|
||||
parametersSchema?: object;
|
||||
}
|
||||
|
||||
// API -> LM: add tools as request option
|
||||
/**
|
||||
* A tool-calling mode for the language model to use.
|
||||
*/
|
||||
export enum LanguageModelChatToolMode {
|
||||
/**
|
||||
* The language model can choose to call a tool or generate a message. Is the default.
|
||||
*/
|
||||
Auto = 1,
|
||||
|
||||
/**
|
||||
* The language model must call one of the provided tools. Note- some models only support a single tool when using this
|
||||
* mode. TODO@API - do we throw, or just pick the first tool? Or only offer an API that allows callers to pick a single
|
||||
* tool? Go back to `toolChoice?: string`?
|
||||
*/
|
||||
Required = 2
|
||||
}
|
||||
|
||||
export interface LanguageModelChatRequestOptions {
|
||||
// TODO@API this will be a heterogeneous array of different types of tools
|
||||
|
||||
/**
|
||||
* An optional list of tools that are available to the language model. These could be registered tools available via
|
||||
* {@link lm.tools}, or private tools that are just implemented within the calling extension.
|
||||
*
|
||||
* If the LLM requests to call one of these tools, it will return a {@link LanguageModelToolCallPart} in
|
||||
* {@link LanguageModelChatResponse.stream}. It's the caller's responsibility to invoke the tool. If it's a tool
|
||||
* registered in {@link lm.tools}, that means calling {@link lm.invokeTool}.
|
||||
*
|
||||
* Then, the tool result can be provided to the LLM by creating an Assistant-type {@link LanguageModelChatMessage} with a
|
||||
* {@link LanguageModelToolCallPart}, followed by a User-type message with a {@link LanguageModelToolResultPart}.
|
||||
*/
|
||||
tools?: LanguageModelChatTool[];
|
||||
|
||||
/**
|
||||
* Force a specific tool to be used.
|
||||
* The tool-selecting mode to use. {@link LanguageModelChatToolMode.Auto} by default.
|
||||
*/
|
||||
toolChoice?: string;
|
||||
toolMode?: LanguageModelChatToolMode;
|
||||
}
|
||||
|
||||
// LM -> USER: function that should be used
|
||||
/**
|
||||
* A language model response part indicating a tool call, returned from a {@link LanguageModelChatResponse}, and also can be
|
||||
* included as a content part on a {@link LanguageModelChatMessage}, to represent a previous tool call in a chat request.
|
||||
*/
|
||||
export class LanguageModelToolCallPart {
|
||||
/**
|
||||
* The name of the tool to call.
|
||||
*/
|
||||
name: string;
|
||||
toolCallId: string;
|
||||
|
||||
/**
|
||||
* The ID of the tool call. This is a unique identifier for the tool call within the chat request.
|
||||
*/
|
||||
callId: string;
|
||||
|
||||
/**
|
||||
* The parameters with which to call the tool.
|
||||
*/
|
||||
parameters: object;
|
||||
|
||||
constructor(name: string, toolCallId: string, parameters: object);
|
||||
/**
|
||||
* Create a new LanguageModelToolCallPart.
|
||||
*/
|
||||
constructor(name: string, callId: string, parameters: object);
|
||||
}
|
||||
|
||||
// LM -> USER: text chunk
|
||||
/**
|
||||
* A language model response part containing a piece of text, returned from a {@link LanguageModelChatResponse}.
|
||||
*/
|
||||
export class LanguageModelTextPart {
|
||||
/**
|
||||
* The text content of the part.
|
||||
*/
|
||||
value: string;
|
||||
|
||||
constructor(value: string);
|
||||
}
|
||||
|
||||
export interface LanguageModelChatResponse {
|
||||
stream: AsyncIterable<LanguageModelTextPart | LanguageModelToolCallPart>;
|
||||
/**
|
||||
* A language model response part containing a PromptElementJSON from `@vscode/prompt-tsx`.
|
||||
*/
|
||||
export class LanguageModelPromptTsxPart {
|
||||
/**
|
||||
* The content of the part.
|
||||
*/
|
||||
value: unknown;
|
||||
|
||||
/**
|
||||
* The mimeType of this part, exported from the `@vscode/prompt-tsx` library.
|
||||
*/
|
||||
mime: string;
|
||||
|
||||
constructor(value: unknown, mime: string);
|
||||
}
|
||||
|
||||
export interface LanguageModelChatResponse {
|
||||
/**
|
||||
* A stream of parts that make up the response. Could be extended with more types in the future.
|
||||
*/
|
||||
stream: AsyncIterable<LanguageModelTextPart | LanguageModelToolCallPart | unknown>;
|
||||
}
|
||||
|
||||
// USER -> LM: the result of a function call
|
||||
/**
|
||||
* The result of a tool call. Can only be included in the content of a User message.
|
||||
*/
|
||||
export class LanguageModelToolResultPart {
|
||||
toolCallId: string;
|
||||
content: string;
|
||||
/**
|
||||
* The ID of the tool call.
|
||||
*/
|
||||
callId: string;
|
||||
|
||||
constructor(toolCallId: string, content: string);
|
||||
/**
|
||||
* The value of the tool result.
|
||||
*/
|
||||
content: (LanguageModelTextPart | LanguageModelPromptTsxPart | unknown)[];
|
||||
|
||||
constructor(callId: string, content: (LanguageModelTextPart | LanguageModelPromptTsxPart | unknown)[]);
|
||||
}
|
||||
|
||||
export interface LanguageModelChatMessage {
|
||||
/**
|
||||
* A heterogeneous array of other things that a message can contain as content.
|
||||
* Some parts would be message-type specific for some models and wouldn't go together,
|
||||
* but it's up to the chat provider to decide what to do about that.
|
||||
* Can drop parts that are not valid for the message type.
|
||||
* LanguageModelToolResultPart: only on User messages
|
||||
* LanguageModelToolCallPart: only on Assistant messages
|
||||
* A heterogeneous array of other things that a message can contain as content. Some parts may be message-type specific
|
||||
* for some models.
|
||||
*/
|
||||
content2: (string | LanguageModelToolResultPart | LanguageModelToolCallPart)[];
|
||||
}
|
||||
|
||||
// Tool registration/invoking between extensions
|
||||
|
||||
/**
|
||||
* A result returned from a tool invocation.
|
||||
*/
|
||||
// TODO@API should we align this with NotebookCellOutput and NotebookCellOutputItem
|
||||
export interface LanguageModelToolResult {
|
||||
/**
|
||||
* The result can contain arbitrary representations of the content. A tool user can set
|
||||
* {@link LanguageModelToolInvocationOptions.requested} to request particular types, and a tool implementation should only
|
||||
* compute the types that were requested. `text/plain` is recommended to be supported by all tools, which would indicate
|
||||
* any text-based content. Another example might be a `PromptElementJSON` from `@vscode/prompt-tsx`, using the
|
||||
* `contentType` exported by that library.
|
||||
*/
|
||||
[contentType: string]: any;
|
||||
export class LanguageModelToolResult {
|
||||
content: (LanguageModelTextPart | LanguageModelPromptTsxPart | unknown)[];
|
||||
|
||||
constructor(content: (LanguageModelTextPart | LanguageModelPromptTsxPart | unknown)[]);
|
||||
}
|
||||
|
||||
export namespace lm {
|
||||
@ -97,12 +174,13 @@ declare module 'vscode' {
|
||||
/**
|
||||
* A list of all available tools.
|
||||
*/
|
||||
export const tools: ReadonlyArray<LanguageModelToolDescription>;
|
||||
export const tools: readonly LanguageModelToolInformation[];
|
||||
|
||||
/**
|
||||
* Invoke a tool with the given parameters.
|
||||
* TODO@API describe tool calling flow here, LanguageModelToolInvocationOptions
|
||||
*/
|
||||
export function invokeTool(id: string, options: LanguageModelToolInvocationOptions<object>, token: CancellationToken): Thenable<LanguageModelToolResult>;
|
||||
export function invokeTool(name: string, options: LanguageModelToolInvocationOptions<object>, token: CancellationToken): Thenable<LanguageModelToolResult>;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,39 +204,36 @@ declare module 'vscode' {
|
||||
|
||||
/**
|
||||
* The parameters with which to invoke the tool. The parameters must match the schema defined in
|
||||
* {@link LanguageModelToolDescription.parametersSchema}
|
||||
* {@link LanguageModelToolInformation.parametersSchema}
|
||||
*/
|
||||
parameters: T;
|
||||
|
||||
/**
|
||||
* A tool user can request that particular content types be returned from the tool, depending on what the tool user
|
||||
* supports. All tools are recommended to support `text/plain`. See {@link LanguageModelToolResult}.
|
||||
* Options to hint at how many tokens the tool should return in its response, and enable the tool to count tokens
|
||||
* accurately.
|
||||
*/
|
||||
requestedContentTypes: string[];
|
||||
tokenizationOptions?: LanguageModelToolTokenizationOptions;
|
||||
}
|
||||
|
||||
export interface LanguageModelToolTokenizationOptions {
|
||||
/**
|
||||
* If known, the maximum number of tokens the tool should emit in its result.
|
||||
*/
|
||||
tokenBudget: number;
|
||||
|
||||
/**
|
||||
* Options to hint at how many tokens the tool should return in its response.
|
||||
* Count the number of tokens in a message using the model specific tokenizer-logic.
|
||||
* @param text A string.
|
||||
* @param token Optional cancellation token. See {@link CancellationTokenSource} for how to create one.
|
||||
* @returns A thenable that resolves to the number of tokens.
|
||||
*/
|
||||
tokenOptions?: {
|
||||
/**
|
||||
* If known, the maximum number of tokens the tool should emit in its result.
|
||||
*/
|
||||
tokenBudget: number;
|
||||
|
||||
/**
|
||||
* Count the number of tokens in a message using the model specific tokenizer-logic.
|
||||
* @param text A string.
|
||||
* @param token Optional cancellation token. See {@link CancellationTokenSource} for how to create one.
|
||||
* @returns A thenable that resolves to the number of tokens.
|
||||
*/
|
||||
countTokens(text: string, token?: CancellationToken): Thenable<number>;
|
||||
};
|
||||
countTokens(text: string, token?: CancellationToken): Thenable<number>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A description of an available tool.
|
||||
* Information about a registered tool available in {@link lm.tools}.
|
||||
*/
|
||||
export interface LanguageModelToolDescription {
|
||||
export interface LanguageModelToolInformation {
|
||||
/**
|
||||
* A unique name for the tool.
|
||||
*/
|
||||
@ -172,18 +247,13 @@ declare module 'vscode' {
|
||||
/**
|
||||
* A JSON schema for the parameters this tool accepts.
|
||||
*/
|
||||
readonly parametersSchema?: object;
|
||||
|
||||
/**
|
||||
* The list of content types that the tool has declared support for. See {@link LanguageModelToolResult}.
|
||||
*/
|
||||
readonly supportedContentTypes: string[];
|
||||
readonly parametersSchema: object | undefined;
|
||||
|
||||
/**
|
||||
* A set of tags, declared by the tool, that roughly describe the tool's capabilities. A tool user may use these to filter
|
||||
* the set of tools to just ones that are relevant for the task at hand.
|
||||
*/
|
||||
readonly tags: string[];
|
||||
readonly tags: readonly string[];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,7 +273,7 @@ declare module 'vscode' {
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for {@link LanguageModelTool.prepareToolInvocation}.
|
||||
* Options for {@link LanguageModelTool.prepareInvocation}.
|
||||
*/
|
||||
export interface LanguageModelToolInvocationPrepareOptions<T> {
|
||||
/**
|
||||
@ -218,18 +288,22 @@ declare module 'vscode' {
|
||||
export interface LanguageModelTool<T> {
|
||||
/**
|
||||
* Invoke the tool with the given parameters and return a result.
|
||||
*
|
||||
* The provided {@link LanguageModelToolInvocationOptions.parameters} have been validated against the schema declared for
|
||||
* this tool.
|
||||
*/
|
||||
invoke(options: LanguageModelToolInvocationOptions<T>, token: CancellationToken): ProviderResult<LanguageModelToolResult>;
|
||||
|
||||
/**
|
||||
* Called once before a tool is invoked. May be implemented to signal that a tool needs user confirmation before running,
|
||||
* and to customize the progress message that appears while the tool is running.
|
||||
* and to customize the progress message that appears while the tool is running. Must be free of side-effects. A call to
|
||||
* `prepareInvocation` is not necessarily followed by a call to `invoke`.
|
||||
*/
|
||||
prepareToolInvocation?(options: LanguageModelToolInvocationPrepareOptions<T>, token: CancellationToken): ProviderResult<PreparedToolInvocation>;
|
||||
prepareInvocation?(options: LanguageModelToolInvocationPrepareOptions<T>, token: CancellationToken): ProviderResult<PreparedToolInvocation>;
|
||||
}
|
||||
|
||||
/**
|
||||
* The result of a call to {@link LanguageModelTool.prepareToolInvocation}.
|
||||
* The result of a call to {@link LanguageModelTool.prepareInvocation}.
|
||||
*/
|
||||
export interface PreparedToolInvocation {
|
||||
/**
|
||||
@ -248,9 +322,9 @@ declare module 'vscode' {
|
||||
*/
|
||||
export interface ChatLanguageModelToolReference {
|
||||
/**
|
||||
* The tool's ID. Refers to a tool listed in {@link lm.tools}.
|
||||
* The tool name. Refers to a tool listed in {@link lm.tools}.
|
||||
*/
|
||||
readonly id: string;
|
||||
readonly name: string;
|
||||
|
||||
/**
|
||||
* The start and end index of the reference in the {@link ChatRequest.prompt prompt}. When undefined, the reference was
|
||||
|
||||
Reference in New Issue
Block a user