mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 17:32:41 +00:00
New proposal for chat variable resolver (#205572)
* Tweak ChatFollowup * Remove API TODOs * New proposal for chat variable resolver * Bump distro * Enforce same-extension followup * Add participant proposal to integration test folder * Allow no participant for a followup
This commit is contained in:
parent
74724fbcb0
commit
efc04b885e
|
@ -10,6 +10,7 @@
|
|||
"chatParticipant",
|
||||
"languageModels",
|
||||
"defaultChatParticipant",
|
||||
"chatVariableResolver",
|
||||
"contribViewsRemote",
|
||||
"contribStatusBarItems",
|
||||
"createFileSystemWatcher",
|
||||
|
|
|
@ -74,7 +74,7 @@ suite('chat', () => {
|
|||
});
|
||||
|
||||
test('participant and variable', async () => {
|
||||
disposables.push(chat.registerVariable('myVar', 'My variable', {
|
||||
disposables.push(chat.registerChatVariableResolver('myVar', 'My variable', {
|
||||
resolve(_name, _context, _token) {
|
||||
return [{ level: ChatVariableLevel.Full, value: 'myValue' }];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.87.0",
|
||||
"distro": "af73a537ea203329debad3df7ca7b42b4799473f",
|
||||
"distro": "b314654a31bdba8cd2b0c7548e931916d03416bf",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
|
|
|
@ -1409,8 +1409,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||
checkProposedApiEnabled(extension, 'chatProvider');
|
||||
return extHostChatProvider.registerLanguageModel(extension, id, provider, metadata);
|
||||
},
|
||||
registerVariable(name: string, description: string, resolver: vscode.ChatVariableResolver) {
|
||||
checkProposedApiEnabled(extension, 'chatParticipant');
|
||||
registerChatVariableResolver(name: string, description: string, resolver: vscode.ChatVariableResolver) {
|
||||
checkProposedApiEnabled(extension, 'chatVariableResolver');
|
||||
return extHostChatVariables.registerVariableResolver(extension, name, description, resolver);
|
||||
},
|
||||
registerMappedEditsProvider(selector: vscode.DocumentSelector, provider: vscode.MappedEditsProvider) {
|
||||
|
|
|
@ -9,12 +9,13 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
|||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { DisposableMap, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { StopWatch } from 'vs/base/common/stopwatch';
|
||||
import { assertType } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { ExtHostChatAgentsShape2, IChatAgentCompletionItem, IChatAgentHistoryEntryDto, IMainContext, MainContext, MainThreadChatAgentsShape2 } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { CommandsConverter, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||
|
@ -261,6 +262,16 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
|
|||
|
||||
const ehResult = typeConvert.ChatAgentResult.to(result);
|
||||
return (await agent.provideFollowups(ehResult, token))
|
||||
.filter(f => {
|
||||
// The followup must refer to a participant that exists from the same extension
|
||||
const isValid = !f.participant || Iterable.some(
|
||||
this._agents.values(),
|
||||
a => a.id === f.participant && ExtensionIdentifier.equals(a.extension.identifier, agent.extension.identifier));
|
||||
if (!isValid) {
|
||||
this._logService.warn(`[@${agent.id}] ChatFollowup refers to an invalid participant: ${f.participant}`);
|
||||
}
|
||||
return isValid;
|
||||
})
|
||||
.map(f => typeConvert.ChatFollowup.from(f, request));
|
||||
}
|
||||
|
||||
|
|
|
@ -2201,18 +2201,16 @@ export namespace ChatFollowup {
|
|||
agentId: followup.participant ?? request?.agentId ?? '',
|
||||
subCommand: followup.command ?? request?.command,
|
||||
message: followup.prompt,
|
||||
title: followup.title,
|
||||
tooltip: followup.tooltip,
|
||||
title: followup.label
|
||||
};
|
||||
}
|
||||
|
||||
export function to(followup: IChatFollowup): vscode.ChatFollowup {
|
||||
return {
|
||||
prompt: followup.message,
|
||||
title: followup.title,
|
||||
label: followup.title,
|
||||
participant: followup.agentId,
|
||||
command: followup.subCommand,
|
||||
tooltip: followup.tooltip,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ export const allApiProposals = Object.freeze({
|
|||
chatParticipantAdditions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts',
|
||||
chatProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.chatProvider.d.ts',
|
||||
chatTab: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.chatTab.d.ts',
|
||||
chatVariableResolver: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.chatVariableResolver.d.ts',
|
||||
codeActionAI: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.codeActionAI.d.ts',
|
||||
codeActionRanges: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.codeActionRanges.d.ts',
|
||||
codiconDecoration: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.codiconDecoration.d.ts',
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
declare module 'vscode' {
|
||||
|
||||
// TODO@API name: Turn?
|
||||
export class ChatRequestTurn {
|
||||
|
||||
/**
|
||||
|
@ -36,7 +35,6 @@ declare module 'vscode' {
|
|||
private constructor(prompt: string, command: string | undefined, variables: ChatResolvedVariable[], participant: { extensionId: string; participant: string });
|
||||
}
|
||||
|
||||
// TODO@API name: Turn?
|
||||
export class ChatResponseTurn {
|
||||
|
||||
/**
|
||||
|
@ -185,9 +183,14 @@ declare module 'vscode' {
|
|||
*/
|
||||
prompt: string;
|
||||
|
||||
/**
|
||||
* A title to show the user, when it is different than the message.
|
||||
*/
|
||||
label?: string;
|
||||
|
||||
/**
|
||||
* By default, the followup goes to the same participant/command. But this property can be set to invoke a different participant.
|
||||
* TODO@API do extensions need to specify the extensionID of the participant here as well?
|
||||
* Followups can only invoke a participant that was contributed by the same extension.
|
||||
*/
|
||||
participant?: string;
|
||||
|
||||
|
@ -195,17 +198,6 @@ declare module 'vscode' {
|
|||
* By default, the followup goes to the same participant/command. But this property can be set to invoke a different command.
|
||||
*/
|
||||
command?: string;
|
||||
|
||||
/**
|
||||
* A tooltip to show when hovering over the followup.
|
||||
*/
|
||||
tooltip?: string;
|
||||
|
||||
/**
|
||||
* A title to show the user, when it is different than the message.
|
||||
*/
|
||||
// TODO@API title vs tooltip?
|
||||
title?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -400,9 +392,6 @@ declare module 'vscode' {
|
|||
* @param value
|
||||
* @returns This stream.
|
||||
*/
|
||||
// TODO@API is this always inline or not
|
||||
// TODO@API is this markdown or string?
|
||||
// TODO@API this influences the rendering, it inserts new lines which is likely a bug
|
||||
progress(value: string): ChatResponseStream;
|
||||
|
||||
/**
|
||||
|
@ -414,8 +403,6 @@ declare module 'vscode' {
|
|||
* @param value A uri or location
|
||||
* @returns This stream.
|
||||
*/
|
||||
// TODO@API support non-file uris, like http://example.com
|
||||
// TODO@API support mapped edits
|
||||
reference(value: Uri | Location): ChatResponseStream;
|
||||
|
||||
/**
|
||||
|
@ -426,8 +413,6 @@ declare module 'vscode' {
|
|||
push(part: ChatResponsePart): ChatResponseStream;
|
||||
}
|
||||
|
||||
// TODO@API should the name suffix differentiate between rendered items (XYZPart)
|
||||
// and metadata like XYZItem
|
||||
export class ChatResponseTextPart {
|
||||
value: string;
|
||||
constructor(value: string);
|
||||
|
@ -457,7 +442,6 @@ declare module 'vscode' {
|
|||
|
||||
export class ChatResponseProgressPart {
|
||||
value: string;
|
||||
// TODO@API inline
|
||||
constructor(value: string);
|
||||
}
|
||||
|
||||
|
@ -489,21 +473,11 @@ declare module 'vscode' {
|
|||
* @returns A new chat participant
|
||||
*/
|
||||
export function createChatParticipant(name: string, handler: ChatRequestHandler): ChatParticipant;
|
||||
|
||||
/**
|
||||
* Register a variable which can be used in a chat request to any participant.
|
||||
* @param name The name of the variable, to be used in the chat input as `#name`.
|
||||
* @param description A description of the variable for the chat input suggest widget.
|
||||
* @param resolver Will be called to provide the chat variable's value when it is used.
|
||||
*/
|
||||
// TODO@API NAME: registerChatVariable, registerChatVariableResolver
|
||||
export function registerVariable(name: string, description: string, resolver: ChatVariableResolver): Disposable;
|
||||
}
|
||||
|
||||
/**
|
||||
* The detail level of this chat variable value.
|
||||
*/
|
||||
// TODO@API maybe for round2
|
||||
export enum ChatVariableLevel {
|
||||
Short = 1,
|
||||
Medium = 2,
|
||||
|
@ -526,21 +500,4 @@ declare module 'vscode' {
|
|||
*/
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface ChatVariableContext {
|
||||
/**
|
||||
* The message entered by the user, which includes this variable.
|
||||
*/
|
||||
prompt: string;
|
||||
}
|
||||
|
||||
export interface ChatVariableResolver {
|
||||
/**
|
||||
* A callback to resolve the value of a chat variable.
|
||||
* @param name The name of the variable.
|
||||
* @param context Contextual information about this chat request.
|
||||
* @param token A cancellation token.
|
||||
*/
|
||||
resolve(name: string, context: ChatVariableContext, token: CancellationToken): ProviderResult<ChatVariableValue[]>;
|
||||
}
|
||||
}
|
||||
|
|
52
src/vscode-dts/vscode.proposed.chatVariableResolver.d.ts
vendored
Normal file
52
src/vscode-dts/vscode.proposed.chatVariableResolver.d.ts
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* 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' {
|
||||
|
||||
export namespace chat {
|
||||
|
||||
/**
|
||||
* Register a variable which can be used in a chat request to any participant.
|
||||
* @param name The name of the variable, to be used in the chat input as `#name`.
|
||||
* @param description A description of the variable for the chat input suggest widget.
|
||||
* @param resolver Will be called to provide the chat variable's value when it is used.
|
||||
*/
|
||||
export function registerChatVariableResolver(name: string, description: string, resolver: ChatVariableResolver): Disposable;
|
||||
}
|
||||
|
||||
export interface ChatVariableValue {
|
||||
/**
|
||||
* The detail level of this chat variable value. If possible, variable resolvers should try to offer shorter values that will consume fewer tokens in an LLM prompt.
|
||||
*/
|
||||
level: ChatVariableLevel;
|
||||
|
||||
/**
|
||||
* The variable's value, which can be included in an LLM prompt as-is, or the chat participant may decide to read the value and do something else with it.
|
||||
*/
|
||||
value: string | Uri;
|
||||
|
||||
/**
|
||||
* A description of this value, which could be provided to the LLM as a hint.
|
||||
*/
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface ChatVariableContext {
|
||||
/**
|
||||
* The message entered by the user, which includes this variable.
|
||||
*/
|
||||
prompt: string;
|
||||
}
|
||||
|
||||
export interface ChatVariableResolver {
|
||||
/**
|
||||
* A callback to resolve the value of a chat variable.
|
||||
* @param name The name of the variable.
|
||||
* @param context Contextual information about this chat request.
|
||||
* @param token A cancellation token.
|
||||
*/
|
||||
resolve(name: string, context: ChatVariableContext, token: CancellationToken): ProviderResult<ChatVariableValue[]>;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue