Add 'isExclusive' flag for tool selection (#247267)

* Add 'isExclusive' flag for tool selection
For prompts with tools to exclude non-selected tools

* Fix
This commit is contained in:
Rob Lourens
2025-04-23 18:42:00 -07:00
committed by GitHub
parent ed40c856ec
commit d9bc5b09ea
9 changed files with 36 additions and 20 deletions

View File

@@ -36,7 +36,7 @@ const _allApiProposals = {
},
chatParticipantPrivate: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.chatParticipantPrivate.d.ts',
version: 8
version: 9
},
chatProvider: {
proposal: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.chatProvider.d.ts',

View File

@@ -560,12 +560,16 @@ export class ExtHostChatAgents2 extends Disposable implements ExtHostChatAgentsS
return this._diagnostics.getDiagnostics();
}
private getToolsForRequest(extension: IExtensionDescription, request: Dto<IChatAgentRequest>) {
private getToolsForRequest(extension: IExtensionDescription, request: Dto<IChatAgentRequest>): vscode.ChatRequestToolSelection | undefined {
if (!isNonEmptyArray(request.userSelectedTools)) {
return undefined;
}
const selector = new Set(request.userSelectedTools);
return this._tools.getTools(extension).filter(candidate => selector.has(candidate.name));
const tools = this._tools.getTools(extension).filter(candidate => selector.has(candidate.name));
return {
tools,
isExclusive: request.toolSelectionIsExclusive,
};
}
private async prepareHistoryTurns(extension: Readonly<IRelaxedExtensionDescription>, agentId: string, context: { history: IChatAgentHistoryEntryDto[] }): Promise<(vscode.ChatRequestTurn | vscode.ChatResponseTurn)[]> {

View File

@@ -2898,7 +2898,7 @@ export namespace ChatResponsePart {
}
export namespace ChatAgentRequest {
export function to(request: IChatAgentRequest, location2: vscode.ChatRequestEditorData | vscode.ChatRequestNotebookData | undefined, model: vscode.LanguageModelChat, diagnostics: readonly [vscode.Uri, readonly vscode.Diagnostic[]][], tools: vscode.LanguageModelToolInformation[] | undefined, extension: IRelaxedExtensionDescription): vscode.ChatRequest {
export function to(request: IChatAgentRequest, location2: vscode.ChatRequestEditorData | vscode.ChatRequestNotebookData | undefined, model: vscode.LanguageModelChat, diagnostics: readonly [vscode.Uri, readonly vscode.Diagnostic[]][], toolSelection: vscode.ChatRequestToolSelection | undefined, extension: IRelaxedExtensionDescription): vscode.ChatRequest {
const toolReferences = request.variables.variables.filter(v => v.kind === 'tool');
const variableReferences = request.variables.variables.filter(v => v.kind !== 'tool');
const requestWithAllProps: vscode.ChatRequest = {
@@ -2915,7 +2915,7 @@ export namespace ChatAgentRequest {
rejectedConfirmationData: request.rejectedConfirmationData,
location2,
toolInvocationToken: Object.freeze({ sessionId: request.sessionId }) as never,
tools,
toolSelection,
model,
editedFileEvents: request.editedFileEvents,
};

View File

@@ -1243,7 +1243,7 @@ export class ChatWidget extends Disposable implements IChatWidget {
parserContext: { selectedAgent: this._lastSelectedAgent, mode: this.inputPart.currentMode },
attachedContext,
noCommandDetection: options?.noCommandDetection,
userSelectedTools: this.input.currentMode === ChatMode.Agent ? this.inputPart.selectedToolsModel.tools.get().map(tool => tool.id) : undefined
userSelectedTools: this.input.currentMode === ChatMode.Agent ? this.inputPart.selectedToolsModel.tools.get().map(tool => tool.id) : undefined,
});
if (result) {

View File

@@ -138,6 +138,7 @@ export interface IChatAgentRequest {
rejectedConfirmationData?: any[];
userSelectedModelId?: string;
userSelectedTools?: string[];
toolSelectionIsExclusive?: boolean;
editedFileEvents?: IChatAgentEditedFileEvent[];
}

View File

@@ -466,6 +466,7 @@ export interface IChatSendRequestOptions {
mode?: ChatMode;
userSelectedModelId?: string;
userSelectedTools?: string[];
toolSelectionIsExclusive?: boolean;
location?: ChatAgentLocation;
locationData?: IChatLocationData;
parserContext?: IChatParserContext;

View File

@@ -768,6 +768,7 @@ export class ChatService extends Disposable implements IChatService {
rejectedConfirmationData: options?.rejectedConfirmationData,
userSelectedModelId: options?.userSelectedModelId,
userSelectedTools: options?.userSelectedTools,
toolSelectionIsExclusive: options?.toolSelectionIsExclusive,
editedFileEvents: request.editedFileEvents
} satisfies IChatAgentRequest;
};

View File

@@ -227,19 +227,6 @@ declare module 'vscode' {
}
export interface ChatRequest {
/**
* A list of tools that the user selected for this request, when `undefined` any tool
* from {@link lm.tools} should be used.
*
* Tools can be called with {@link lm.invokeTool} with input that match their
* declared `inputSchema`.
*/
readonly tools: readonly LanguageModelToolInformation[] | undefined;
}
/**
* Does this piggy-back on the existing ChatRequest, or is it a different type of request entirely?
* Does it show up in history?

View File

@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// version: 8
// version: 9
declare module 'vscode' {
@@ -240,4 +240,26 @@ declare module 'vscode' {
}
// #endregion
export interface ChatRequestToolSelection {
/**
* A list of tools that the user selected for this request.
* Tools can be called with {@link lm.invokeTool} with input that match their
* declared `inputSchema`.
*/
readonly tools: readonly LanguageModelToolInformation[];
/**
* When true, only this set of tools (and toolReferences) should be used. When false, the base set of agent tools can also be included.
*/
readonly isExclusive?: boolean;
}
export interface ChatRequest {
/**
* A list of tools that the user selected for this request, when `undefined` any tool
* from {@link lm.tools} should be used.
*/
readonly toolSelection: ChatRequestToolSelection | undefined;
}
}