add sample

This commit is contained in:
Connor Peet
2024-08-13 11:24:01 -07:00
parent 884a34abd1
commit 6f380ac68f
9 changed files with 984 additions and 20 deletions

View File

@ -9,6 +9,9 @@
"version": "0.0.1",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@vscode/prompt-tsx": "^0.2.6-alpha"
},
"devDependencies": {
"@types/node": "^18",
"@typescript-eslint/eslint-plugin": "^7.14.0",
@ -385,6 +388,11 @@
"dts": "index.js"
}
},
"node_modules/@vscode/prompt-tsx": {
"version": "0.2.6-alpha",
"resolved": "https://registry.npmjs.org/@vscode/prompt-tsx/-/prompt-tsx-0.2.6-alpha.tgz",
"integrity": "sha512-eijaM5kMFez6rHgSIivBvBBiYA9n0IeHXXinML74JqQV/lgCqoGNQ9Hlzh38P8KJLJ8aV8f14q6vPRIXbJfteg=="
},
"node_modules/acorn": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
@ -1857,6 +1865,11 @@
"prompts": "^2.4.2"
}
},
"@vscode/prompt-tsx": {
"version": "0.2.6-alpha",
"resolved": "https://registry.npmjs.org/@vscode/prompt-tsx/-/prompt-tsx-0.2.6-alpha.tgz",
"integrity": "sha512-eijaM5kMFez6rHgSIivBvBBiYA9n0IeHXXinML74JqQV/lgCqoGNQ9Hlzh38P8KJLJ8aV8f14q6vPRIXbJfteg=="
},
"acorn": {
"version": "8.12.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",

View File

@ -1,5 +1,7 @@
{
"enabledApiProposals": [],
"enabledApiProposals": [
"lmTools"
],
"name": "proposed-api-sample",
"displayName": "proposed-api-sample",
"description": "Sample showing how to use Proposed API",
@ -22,6 +24,12 @@
"command": "extension.helloWorld",
"title": "Hello World"
}
],
"languageModelTools": [
{
"name": "myTestTool",
"description": "My test tool"
}
]
},
"scripts": {
@ -37,8 +45,11 @@
"@types/node": "^18",
"@typescript-eslint/eslint-plugin": "^7.14.0",
"@typescript-eslint/parser": "^7.14.0",
"@vscode/dts": "^0.4.0",
"eslint": "^8.26.0",
"typescript": "^5.5.2",
"@vscode/dts": "^0.4.0"
"typescript": "^5.5.2"
},
"dependencies": {
"@vscode/prompt-tsx": "^0.2.6-alpha"
}
}

View File

@ -0,0 +1,38 @@
import { BasePromptElementProps, PromptElement, PromptSizing, AssistantMessage, UserMessage, PromptPiece } from '@vscode/prompt-tsx';
import * as vscode from 'vscode';
export interface PromptProps extends BasePromptElementProps {
userQuery: PromptPiece;
}
export interface PromptState {
creationScript: string;
}
export class TestPrompt extends PromptElement<PromptProps, PromptState> {
render(state: PromptState, sizing: PromptSizing) {
return (
<>
<UserMessage>
Here are the creation scripts that were used to create the tables in my database. Pay close attention to the tables and columns that are available in my database:<br />
</UserMessage>
{this.props.userQuery}
</>
);
}
}
export class MyCustomPrompt extends PromptElement {
render(state: void, sizing: PromptSizing): Promise<PromptPiece | undefined> | PromptPiece | undefined {
return <AssistantMessage>
You are a SQL expert.<br />
Your task is to help the user craft SQL queries that perform their task.<br />
You should suggest SQL queries that are performant and correct.<br />
Return your suggested SQL query in a Markdown code block that begins with ```sql and ends with ```.<br />
</AssistantMessage>
}
}
export const myPromptEl = <MyCustomPrompt />;

View File

@ -1,4 +1,6 @@
import { renderPrompt } from '@vscode/prompt-tsx';
import * as vscode from 'vscode';
import { myPromptEl, TestPrompt } from './asdf';
export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "proposed-api-sample" is now active!');
@ -8,8 +10,40 @@ export function activate(context: vscode.ExtensionContext) {
* Proposed API as defined in vscode.proposed.<proposalName>.d.ts.
*/
const disposable = vscode.commands.registerCommand('extension.helloWorld', () => {
vscode.window.showInformationMessage('Hello World!');
vscode.lm.registerTool('myTestTool', {
invoke(parameters, token): Promise<vscode.LanguageModelToolResult> {
return Promise.resolve({
'application/json': {
foo: 'bar'
},
'mytype': myPromptEl,
toString() {
return 'hello world!'
}
});
},
});
const disposable = vscode.commands.registerCommand('extension.helloWorld', async () => {
const result = await vscode.lm.invokeTool('myTestTool', {}, new vscode.CancellationTokenSource().token);
console.log(result);
const rendered = await renderPrompt(
TestPrompt,
{ userQuery: result['mytype'] },
{ modelMaxPromptTokens: 4096 },
{
tokenLength(text, token) {
return text.split(' ').length;
},
countMessageTokens(message) {
return message.content.split(' ').length;
}
},
);
console.log(JSON.stringify( rendered, null, 2));
});
context.subscriptions.push(disposable);

View File

@ -6,6 +6,10 @@
"outDir": "out",
"sourceMap": true,
"strict": true,
"jsx": "react",
"jsxFactory": "vscpp",
"jsxFragmentFactory": "vscppf",
"rootDir": "src"
},
"exclude": ["node_modules", ".vscode-test"]

View File

@ -157,7 +157,7 @@ declare module 'vscode' {
* that the returned object is *not* live and changes to the
* document are not reflected.
*
* @param line A line number in [0, lineCount).
* @param line A line number in `[0, lineCount)`.
* @returns A {@link TextLine line}.
*/
lineAt(line: number): TextLine;
@ -4683,7 +4683,7 @@ declare module 'vscode' {
/**
* The currently active {@linkcode SignatureHelp}.
*
* The `activeSignatureHelp` has its [`SignatureHelp.activeSignature`] field updated based on
* The `activeSignatureHelp` has its {@linkcode SignatureHelp.activeSignature activeSignature} field updated based on
* the user arrowing through available signatures.
*/
readonly activeSignatureHelp: SignatureHelp | undefined;
@ -5356,22 +5356,22 @@ declare module 'vscode' {
export class Color {
/**
* The red component of this color in the range [0-1].
* The red component of this color in the range `[0-1]`.
*/
readonly red: number;
/**
* The green component of this color in the range [0-1].
* The green component of this color in the range `[0-1]`.
*/
readonly green: number;
/**
* The blue component of this color in the range [0-1].
* The blue component of this color in the range `[0-1]`.
*/
readonly blue: number;
/**
* The alpha component of this color in the range [0-1].
* The alpha component of this color in the range `[0-1]`.
*/
readonly alpha: number;
@ -6279,7 +6279,9 @@ declare module 'vscode' {
* If the language supports Unicode identifiers (e.g. JavaScript), it is preferable
* to provide a word definition that uses exclusion of known separators.
* e.g.: A regex that matches anything except known separators (and dot is allowed to occur in a floating point number):
* /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g
* ```
* /(-?\d*\.\d\w*)|([^\`\~\!\@\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g
* ```
*/
wordPattern?: RegExp;
/**
@ -7329,6 +7331,18 @@ declare module 'vscode' {
*/
readonly state: TerminalState;
/**
* An object that contains [shell integration](https://code.visualstudio.com/docs/terminal/shell-integration)-powered
* features for the terminal. This will always be `undefined` immediately after the terminal
* is created. Listen to {@link window.onDidChangeTerminalShellIntegration} to be notified
* when shell integration is activated for a terminal.
*
* Note that this object may remain undefined if shell integation never activates. For
* example Command Prompt does not support shell integration and a user's shell setup could
* conflict with the automatic shell integration activation.
*/
readonly shellIntegration: TerminalShellIntegration | undefined;
/**
* Send text to the terminal. The text is written to the stdin of the underlying pty process
* (shell) of the terminal.
@ -7422,6 +7436,309 @@ declare module 'vscode' {
readonly isInteractedWith: boolean;
}
/**
* [Shell integration](https://code.visualstudio.com/docs/terminal/shell-integration)-powered capabilities owned by a terminal.
*/
export interface TerminalShellIntegration {
/**
* The current working directory of the terminal. This {@link Uri} may represent a file on
* another machine (eg. ssh into another machine). This requires the shell integration to
* support working directory reporting.
*/
readonly cwd: Uri | undefined;
/**
* Execute a command, sending ^C as necessary to interrupt any running command if needed.
*
* @param commandLine The command line to execute, this is the exact text that will be sent
* to the terminal.
*
* @example
* // Execute a command in a terminal immediately after being created
* const myTerm = window.createTerminal();
* window.onDidChangeTerminalShellIntegration(async ({ terminal, shellIntegration }) => {
* if (terminal === myTerm) {
* const execution = shellIntegration.executeCommand('echo "Hello world"');
* window.onDidEndTerminalShellExecution(event => {
* if (event.execution === execution) {
* console.log(`Command exited with code ${event.exitCode}`);
* }
* }
* }));
* // Fallback to sendText if there is no shell integration within 3 seconds of launching
* setTimeout(() => {
* if (!myTerm.shellIntegration) {
* myTerm.sendText('echo "Hello world"');
* // Without shell integration, we can't know when the command has finished or what the
* // exit code was.
* }
* }, 3000);
*
* @example
* // Send command to terminal that has been alive for a while
* const commandLine = 'echo "Hello world"';
* if (term.shellIntegration) {
* const execution = shellIntegration.executeCommand({ commandLine });
* window.onDidEndTerminalShellExecution(event => {
* if (event.execution === execution) {
* console.log(`Command exited with code ${event.exitCode}`);
* }
* } else {
* term.sendText(commandLine);
* // Without shell integration, we can't know when the command has finished or what the
* // exit code was.
* }
*/
executeCommand(commandLine: string): TerminalShellExecution;
/**
* Execute a command, sending ^C as necessary to interrupt any running command if needed.
*
* *Note* This is not guaranteed to work as [shell integration](https://code.visualstudio.com/docs/terminal/shell-integration)
* must be activated. Check whether {@link TerminalShellExecution.exitCode} is rejected to
* verify whether it was successful.
*
* @param command A command to run.
* @param args Arguments to launch the executable with which will be automatically escaped
* based on the executable type.
*
* @example
* // Execute a command in a terminal immediately after being created
* const myTerm = window.createTerminal();
* window.onDidActivateTerminalShellIntegration(async ({ terminal, shellIntegration }) => {
* if (terminal === myTerm) {
* const command = shellIntegration.executeCommand({
* command: 'echo',
* args: ['Hello world']
* });
* const code = await command.exitCode;
* console.log(`Command exited with code ${code}`);
* }
* }));
* // Fallback to sendText if there is no shell integration within 3 seconds of launching
* setTimeout(() => {
* if (!myTerm.shellIntegration) {
* myTerm.sendText('echo "Hello world"');
* // Without shell integration, we can't know when the command has finished or what the
* // exit code was.
* }
* }, 3000);
*
* @example
* // Send command to terminal that has been alive for a while
* const commandLine = 'echo "Hello world"';
* if (term.shellIntegration) {
* const command = term.shellIntegration.executeCommand({
* command: 'echo',
* args: ['Hello world']
* });
* const code = await command.exitCode;
* console.log(`Command exited with code ${code}`);
* } else {
* term.sendText(commandLine);
* // Without shell integration, we can't know when the command has finished or what the
* // exit code was.
* }
*/
executeCommand(executable: string, args: string[]): TerminalShellExecution;
}
/**
* A command that was executed in a terminal.
*/
export interface TerminalShellExecution {
/**
* The command line that was executed. The {@link TerminalShellExecutionCommandLineConfidence confidence}
* of this value depends on the specific shell's shell integration implementation. This
* value may become more accurate after {@link window.onDidEndTerminalShellExecution} is
* fired.
*
* @example
* // Log the details of the command line on start and end
* window.onDidStartTerminalShellExecution(event => {
* const commandLine = event.execution.commandLine;
* console.log(`Command started\n${summarizeCommandLine(commandLine)}`);
* });
* window.onDidEndTerminalShellExecution(event => {
* const commandLine = event.execution.commandLine;
* console.log(`Command ended\n${summarizeCommandLine(commandLine)}`);
* });
* function summarizeCommandLine(commandLine: TerminalShellExecutionCommandLine) {
* return [
* ` Command line: ${command.commandLine.value}`,
* ` Confidence: ${command.commandLine.confidence}`,
* ` Trusted: ${command.commandLine.isTrusted}
* ].join('\n');
* }
*/
readonly commandLine: TerminalShellExecutionCommandLine;
/**
* The working directory that was reported by the shell when this command executed. This
* {@link Uri} may represent a file on another machine (eg. ssh into another machine). This
* requires the shell integration to support working directory reporting.
*/
readonly cwd: Uri | undefined;
/**
* Creates a stream of raw data (including escape sequences) that is written to the
* terminal. This will only include data that was written after `read` was called for
* the first time, ie. you must call `read` immediately after the command is executed via
* {@link TerminalShellIntegration.executeCommand} or
* {@link window.onDidStartTerminalShellExecution} to not miss any data.
*
* @example
* // Log all data written to the terminal for a command
* const command = term.shellIntegration.executeCommand({ commandLine: 'echo "Hello world"' });
* const stream = command.read();
* for await (const data of stream) {
* console.log(data);
* }
*/
read(): AsyncIterable<string>;
}
/**
* A command line that was executed in a terminal.
*/
export interface TerminalShellExecutionCommandLine {
/**
* The full command line that was executed, including both the command and its arguments.
*/
readonly value: string;
/**
* Whether the command line value came from a trusted source and is therefore safe to
* execute without user additional confirmation, such as a notification that asks "Do you
* want to execute (command)?". This verification is likely only needed if you are going to
* execute the command again.
*
* This is `true` only when the command line was reported explicitly by the shell
* integration script (ie. {@link TerminalShellExecutionCommandLineConfidence.High high confidence})
* and it used a nonce for verification.
*/
readonly isTrusted: boolean;
/**
* The confidence of the command line value which is determined by how the value was
* obtained. This depends upon the implementation of the shell integration script.
*/
readonly confidence: TerminalShellExecutionCommandLineConfidence;
}
/**
* The confidence of a {@link TerminalShellExecutionCommandLine} value.
*/
enum TerminalShellExecutionCommandLineConfidence {
/**
* The command line value confidence is low. This means that the value was read from the
* terminal buffer using markers reported by the shell integration script. Additionally one
* of the following conditions will be met:
*
* - The command started on the very left-most column which is unusual, or
* - The command is multi-line which is more difficult to accurately detect due to line
* continuation characters and right prompts.
* - Command line markers were not reported by the shell integration script.
*/
Low = 0,
/**
* The command line value confidence is medium. This means that the value was read from the
* terminal buffer using markers reported by the shell integration script. The command is
* single-line and does not start on the very left-most column (which is unusual).
*/
Medium = 1,
/**
* The command line value confidence is high. This means that the value was explicitly sent
* from the shell integration script or the command was executed via the
* {@link TerminalShellIntegration.executeCommand} API.
*/
High = 2
}
/**
* An event signalling that a terminal's shell integration has changed.
*/
export interface TerminalShellIntegrationChangeEvent {
/**
* The terminal that shell integration has been activated in.
*/
readonly terminal: Terminal;
/**
* The shell integration object.
*/
readonly shellIntegration: TerminalShellIntegration;
}
/**
* An event signalling that an execution has started in a terminal.
*/
export interface TerminalShellExecutionStartEvent {
/**
* The terminal that shell integration has been activated in.
*/
readonly terminal: Terminal;
/**
* The shell integration object.
*/
readonly shellIntegration: TerminalShellIntegration;
/**
* The terminal shell execution that has ended.
*/
readonly execution: TerminalShellExecution;
}
/**
* An event signalling that an execution has ended in a terminal.
*/
export interface TerminalShellExecutionEndEvent {
/**
* The terminal that shell integration has been activated in.
*/
readonly terminal: Terminal;
/**
* The shell integration object.
*/
readonly shellIntegration: TerminalShellIntegration;
/**
* The terminal shell execution that has ended.
*/
readonly execution: TerminalShellExecution;
/**
* The exit code reported by the shell.
*
* Note that `undefined` means the shell either did not report an exit code (ie. the shell
* integration script is misbehaving) or the shell reported a command started before the command
* finished (eg. a sub-shell was opened). Generally this should not happen, depending on the use
* case, it may be best to treat this as a failure.
*
* @example
* const execution = shellIntegration.executeCommand({
* command: 'echo',
* args: ['Hello world']
* });
* window.onDidEndTerminalShellExecution(event => {
* if (event.execution === execution) {
* if (event.exitCode === undefined) {
* console.log('Command finished but exit code is unknown');
* } else if (event.exitCode === 0) {
* console.log('Command succeeded');
* } else {
* console.log('Command failed');
* }
* }
* });
*/
readonly exitCode: number | undefined;
}
/**
* Provides information on a line in a terminal in order to provide links for it.
*/
@ -10457,6 +10774,25 @@ declare module 'vscode' {
*/
export const onDidChangeTerminalState: Event<Terminal>;
/**
* Fires when shell integration activates or one of its properties changes in a terminal.
*/
export const onDidChangeTerminalShellIntegration: Event<TerminalShellIntegrationChangeEvent>;
/**
* This will be fired when a terminal command is started. This event will fire only when
* [shell integration](https://code.visualstudio.com/docs/terminal/shell-integration) is
* activated for the terminal.
*/
export const onDidStartTerminalShellExecution: Event<TerminalShellExecutionStartEvent>;
/**
* This will be fired when a terminal command is ended. This event will fire only when
* [shell integration](https://code.visualstudio.com/docs/terminal/shell-integration) is
* activated for the terminal.
*/
export const onDidEndTerminalShellExecution: Event<TerminalShellExecutionEndEvent>;
/**
* Represents the current window's state.
*/
@ -11463,15 +11799,15 @@ declare module 'vscode' {
/**
* If true, then the element will be selected.
*/
select?: boolean;
readonly select?: boolean;
/**
* If true, then the element will be focused.
*/
focus?: boolean;
readonly focus?: boolean;
/**
* If true, then the element will be expanded. If a number is passed, then up to that number of levels of children will be expanded
*/
expand?: boolean | number;
readonly expand?: boolean | number;
}): Thenable<void>;
}
@ -12433,7 +12769,7 @@ declare module 'vscode' {
buttons: readonly QuickInputButton[];
/**
* An event signaling when a button in the title bar was triggered.
* An event signaling when a top level button (buttons stored in {@link buttons}) was triggered.
* This event does not fire for buttons on a {@link QuickPickItem}.
*/
readonly onDidTriggerButton: Event<QuickInputButton>;
@ -16880,6 +17216,11 @@ declare module 'vscode' {
* Note: you cannot use this option with any other options that prompt the user like {@link AuthenticationGetSessionOptions.createIfNone createIfNone}.
*/
silent?: boolean;
/**
* The account that you would like to get a session for. This is passed down to the Authentication Provider to be used for creating the correct session.
*/
account?: AuthenticationSessionAccountInformation;
}
/**
@ -16940,6 +17281,18 @@ declare module 'vscode' {
readonly changed: readonly AuthenticationSession[] | undefined;
}
/**
* The options passed in to the {@link AuthenticationProvider.getSessions} and
* {@link AuthenticationProvider.createSession} call.
*/
export interface AuthenticationProviderSessionOptions {
/**
* The account that is being asked about. If this is passed in, the provider should
* attempt to return the sessions that are only related to this account.
*/
account?: AuthenticationSessionAccountInformation;
}
/**
* A provider for performing authentication to a service.
*/
@ -16954,9 +17307,10 @@ declare module 'vscode' {
* Get a list of sessions.
* @param scopes An optional list of scopes. If provided, the sessions returned should match
* these permissions, otherwise all sessions should be returned.
* @param options Additional options for getting sessions.
* @returns A promise that resolves to an array of authentication sessions.
*/
getSessions(scopes?: readonly string[]): Thenable<readonly AuthenticationSession[]>;
getSessions(scopes: readonly string[] | undefined, options: AuthenticationProviderSessionOptions): Thenable<AuthenticationSession[]>;
/**
* Prompts a user to login.
@ -16969,9 +17323,10 @@ declare module 'vscode' {
* then this should never be called if there is already an existing session matching these
* scopes.
* @param scopes A list of scopes, permissions, that the new session should be created with.
* @param options Additional options for creating a session.
* @returns A promise that resolves to an authentication session.
*/
createSession(scopes: readonly string[]): Thenable<AuthenticationSession>;
createSession(scopes: readonly string[], options: AuthenticationProviderSessionOptions): Thenable<AuthenticationSession>;
/**
* Removes the session corresponding to session id.
@ -17034,6 +17389,20 @@ declare module 'vscode' {
*/
export function getSession(providerId: string, scopes: readonly string[], options?: AuthenticationGetSessionOptions): Thenable<AuthenticationSession | undefined>;
/**
* Get all accounts that the user is logged in to for the specified provider.
* Use this paired with {@link getSession} in order to get an authentication session for a specific account.
*
* Currently, there are only two authentication providers that are contributed from built in extensions
* to the editor that implement GitHub and Microsoft authentication: their providerId's are 'github' and 'microsoft'.
*
* Note: Getting accounts does not imply that your extension has access to that account or its authentication sessions. You can verify access to the account by calling {@link getSession}.
*
* @param providerId The id of the provider to use
* @returns A thenable that resolves to a readonly array of authentication accounts.
*/
export function getAccounts(providerId: string): Thenable<readonly AuthenticationSessionAccountInformation[]>;
/**
* An {@link Event} which fires when the authentication sessions of an authentication provider have
* been added, removed, or changed.
@ -18618,8 +18987,8 @@ declare module 'vscode' {
* An event that fires whenever feedback for a result is received, e.g. when a user up- or down-votes
* a result.
*
* The passed {@link ChatResultFeedback.result result} is guaranteed to be the same instance that was
* previously returned from this chat participant.
* The passed {@link ChatResultFeedback.result result} is guaranteed to have the same properties as the result that was
* previously returned from this chat participant's handler.
*/
onDidReceiveFeedback: Event<ChatResultFeedback>;

View File

@ -0,0 +1,104 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
// https://github.com/microsoft/vscode/issues/59924
/**
* Options that can be set on a findTextInFiles search.
*/
export interface FindTextInFilesOptions {
/**
* A {@link GlobPattern glob pattern} that defines the files to search for. The glob pattern
* will be matched against the file paths of files relative to their workspace. Use a {@link RelativePattern relative pattern}
* to restrict the search results to a {@link WorkspaceFolder workspace folder}.
*/
include?: GlobPattern;
/**
* A {@link GlobPattern glob pattern} that defines files and folders to exclude. The glob pattern
* will be matched against the file paths of resulting matches relative to their workspace. When `undefined`, default excludes will
* apply.
*/
exclude?: GlobPattern;
/**
* Whether to use the default and user-configured excludes. Defaults to true.
*/
useDefaultExcludes?: boolean;
/**
* The maximum number of results to search for
*/
maxResults?: number;
/**
* Whether external files that exclude files, like .gitignore, should be respected.
* See the vscode setting `"search.useIgnoreFiles"`.
*/
useIgnoreFiles?: boolean;
/**
* Whether global files that exclude files, like .gitignore, should be respected.
* See the vscode setting `"search.useGlobalIgnoreFiles"`.
*/
useGlobalIgnoreFiles?: boolean;
/**
* Whether files in parent directories that exclude files, like .gitignore, should be respected.
* See the vscode setting `"search.useParentIgnoreFiles"`.
*/
useParentIgnoreFiles?: boolean;
/**
* Whether symlinks should be followed while searching.
* See the vscode setting `"search.followSymlinks"`.
*/
followSymlinks?: boolean;
/**
* Interpret files using this encoding.
* See the vscode setting `"files.encoding"`
*/
encoding?: string;
/**
* Options to specify the size of the result text preview.
*/
previewOptions?: TextSearchPreviewOptions;
/**
* Number of lines of context to include before each match.
*/
beforeContext?: number;
/**
* Number of lines of context to include after each match.
*/
afterContext?: number;
}
export namespace workspace {
/**
* Search text in files across all {@link workspace.workspaceFolders workspace folders} in the workspace.
* @param query The query parameters for the search - the search string, whether it's case-sensitive, or a regex, or matches whole words.
* @param callback A callback, called for each result
* @param token A token that can be used to signal cancellation to the underlying search engine.
* @return A thenable that resolves when the search is complete.
*/
export function findTextInFiles(query: TextSearchQuery, callback: (result: TextSearchResult) => void, token?: CancellationToken): Thenable<TextSearchComplete>;
/**
* Search text in files across all {@link workspace.workspaceFolders workspace folders} in the workspace.
* @param query The query parameters for the search - the search string, whether it's case-sensitive, or a regex, or matches whole words.
* @param options An optional set of query options. Include and exclude patterns, maxResults, etc.
* @param callback A callback, called for each result
* @param token A token that can be used to signal cancellation to the underlying search engine.
* @return A thenable that resolves when the search is complete.
*/
export function findTextInFiles(query: TextSearchQuery, options: FindTextInFilesOptions, callback: (result: TextSearchResult) => void, token?: CancellationToken): Thenable<TextSearchComplete>;
}
}

View File

@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// version: 3
// https://github.com/microsoft/vscode/issues/213274
declare module 'vscode' {
// TODO@API capabilities
export type JSONSchema = object;
// API -> LM: an tool/function that is available to the language model
export interface LanguageModelChatFunction {
name: string;
description: string;
parametersSchema?: JSONSchema;
}
// API -> LM: add tools as request option
export interface LanguageModelChatRequestOptions {
// TODO@API this will a heterogeneous array of different types of tools
tools?: LanguageModelChatFunction[];
/**
* Force a specific tool to be used.
*/
toolChoice?: string;
}
// LM -> USER: function that should be used
export class LanguageModelChatResponseFunctionUsePart {
name: string;
parameters: any;
constructor(name: string, parameters: any);
}
// LM -> USER: text chunk
export class LanguageModelChatResponseTextPart {
value: string;
constructor(value: string);
}
export interface LanguageModelChatResponse {
stream: AsyncIterable<LanguageModelChatResponseTextPart | LanguageModelChatResponseFunctionUsePart>;
}
// USER -> LM: the result of a function call
export class LanguageModelChatMessageFunctionResultPart {
name: string;
content: string;
isError: boolean;
constructor(name: string, content: string, isError?: boolean);
}
export interface LanguageModelChatMessage {
content2: string | LanguageModelChatMessageFunctionResultPart;
}
export interface LanguageModelToolResult {
/**
* The result can contain arbitrary representations of the content. An example might be 'prompt-tsx' to indicate an element that can be rendered with the @vscode/prompt-tsx 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
export namespace lm {
/**
* Register a LanguageModelTool. The tool must also be registered in the package.json `languageModelTools` contribution point.
*/
export function registerTool(name: string, tool: LanguageModelTool): Disposable;
/**
* A list of all available tools.
*/
export const tools: ReadonlyArray<LanguageModelToolDescription>;
/**
* 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(name: string, parameters: Object, token: CancellationToken): Thenable<LanguageModelToolResult>;
}
// Is the same as LanguageModelChatFunction now, but could have more details in the future
export interface LanguageModelToolDescription {
name: string;
description: string;
parametersSchema?: JSONSchema;
}
export interface LanguageModelTool {
// TODO@API should it be LanguageModelToolResult | string?
invoke(parameters: any, token: CancellationToken): Thenable<LanguageModelToolResult>;
}
}

View File

@ -0,0 +1,281 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode' {
// https://github.com/microsoft/vscode/issues/59921
/**
* The parameters of a query for text search.
*/
export interface TextSearchQuery {
/**
* The text pattern to search for.
*/
pattern: string;
/**
* Whether or not `pattern` should match multiple lines of text.
*/
isMultiline?: boolean;
/**
* Whether or not `pattern` should be interpreted as a regular expression.
*/
isRegExp?: boolean;
/**
* Whether or not the search should be case-sensitive.
*/
isCaseSensitive?: boolean;
/**
* Whether or not to search for whole word matches only.
*/
isWordMatch?: boolean;
}
/**
* A file glob pattern to match file paths against.
* TODO@roblourens merge this with the GlobPattern docs/definition in vscode.d.ts.
* @see {@link GlobPattern}
*/
export type GlobString = string;
/**
* Options common to file and text search
*/
export interface SearchOptions {
/**
* The root folder to search within.
*/
folder: Uri;
/**
* Files that match an `includes` glob pattern should be included in the search.
*/
includes: GlobString[];
/**
* Files that match an `excludes` glob pattern should be excluded from the search.
*/
excludes: GlobString[];
/**
* Whether external files that exclude files, like .gitignore, should be respected.
* See the vscode setting `"search.useIgnoreFiles"`.
*/
useIgnoreFiles: boolean;
/**
* Whether symlinks should be followed while searching.
* See the vscode setting `"search.followSymlinks"`.
*/
followSymlinks: boolean;
/**
* Whether global files that exclude files, like .gitignore, should be respected.
* See the vscode setting `"search.useGlobalIgnoreFiles"`.
*/
useGlobalIgnoreFiles: boolean;
/**
* Whether files in parent directories that exclude files, like .gitignore, should be respected.
* See the vscode setting `"search.useParentIgnoreFiles"`.
*/
useParentIgnoreFiles: boolean;
}
/**
* Options to specify the size of the result text preview.
* These options don't affect the size of the match itself, just the amount of preview text.
*/
export interface TextSearchPreviewOptions {
/**
* The maximum number of lines in the preview.
* Only search providers that support multiline search will ever return more than one line in the match.
*/
matchLines: number;
/**
* The maximum number of characters included per line.
*/
charsPerLine: number;
}
/**
* Options that apply to text search.
*/
export interface TextSearchOptions extends SearchOptions {
/**
* The maximum number of results to be returned.
*/
maxResults: number;
/**
* Options to specify the size of the result text preview.
*/
previewOptions?: TextSearchPreviewOptions;
/**
* Exclude files larger than `maxFileSize` in bytes.
*/
maxFileSize?: number;
/**
* Interpret files using this encoding.
* See the vscode setting `"files.encoding"`
*/
encoding?: string;
/**
* Number of lines of context to include before each match.
*/
beforeContext?: number;
/**
* Number of lines of context to include after each match.
*/
afterContext?: number;
}
/**
* Represents the severity of a TextSearchComplete message.
*/
export enum TextSearchCompleteMessageType {
Information = 1,
Warning = 2,
}
/**
* A message regarding a completed search.
*/
export interface TextSearchCompleteMessage {
/**
* Markdown text of the message.
*/
text: string;
/**
* Whether the source of the message is trusted, command links are disabled for untrusted message sources.
* Messaged are untrusted by default.
*/
trusted?: boolean;
/**
* The message type, this affects how the message will be rendered.
*/
type: TextSearchCompleteMessageType;
}
/**
* Information collected when text search is complete.
*/
export interface TextSearchComplete {
/**
* Whether the search hit the limit on the maximum number of search results.
* `maxResults` on {@linkcode TextSearchOptions} specifies the max number of results.
* - If exactly that number of matches exist, this should be false.
* - If `maxResults` matches are returned and more exist, this should be true.
* - If search hits an internal limit which is less than `maxResults`, this should be true.
*/
limitHit?: boolean;
/**
* Additional information regarding the state of the completed search.
*
* Messages with "Information" style support links in markdown syntax:
* - Click to [run a command](command:workbench.action.OpenQuickPick)
* - Click to [open a website](https://aka.ms)
*
* Commands may optionally return { triggerSearch: true } to signal to the editor that the original search should run be again.
*/
message?: TextSearchCompleteMessage | TextSearchCompleteMessage[];
}
/**
* A preview of the text result.
*/
export interface TextSearchMatchPreview {
/**
* The matching lines of text, or a portion of the matching line that contains the match.
*/
text: string;
/**
* The Range within `text` corresponding to the text of the match.
* The number of matches must match the TextSearchMatch's range property.
*/
matches: Range | Range[];
}
/**
* A match from a text search
*/
export interface TextSearchMatch {
/**
* The uri for the matching document.
*/
uri: Uri;
/**
* The range of the match within the document, or multiple ranges for multiple matches.
*/
ranges: Range | Range[];
/**
* A preview of the text match.
*/
preview: TextSearchMatchPreview;
}
/**
* A line of context surrounding a TextSearchMatch.
*/
export interface TextSearchContext {
/**
* The uri for the matching document.
*/
uri: Uri;
/**
* One line of text.
* previewOptions.charsPerLine applies to this
*/
text: string;
/**
* The line number of this line of context.
*/
lineNumber: number;
}
export type TextSearchResult = TextSearchMatch | TextSearchContext;
/**
* A TextSearchProvider provides search results for text results inside files in the workspace.
*/
export interface TextSearchProvider {
/**
* Provide results that match the given text pattern.
* @param query The parameters for this query.
* @param options A set of options to consider while searching.
* @param progress A progress callback that must be invoked for all results.
* @param token A cancellation token.
*/
provideTextSearchResults(query: TextSearchQuery, options: TextSearchOptions, progress: Progress<TextSearchResult>, token: CancellationToken): ProviderResult<TextSearchComplete>;
}
export namespace workspace {
/**
* Register a text search provider.
*
* Only one provider can be registered per scheme.
*
* @param scheme The provider will be invoked for workspace folders that have this file scheme.
* @param provider The provider.
* @return A {@link Disposable} that unregisters this provider when being disposed.
*/
export function registerTextSearchProvider(scheme: string, provider: TextSearchProvider): Disposable;
}
}