Skip to content

Commit fd7158c

Browse files
authored
have special rendering for tools and tool sets so that we can always render them as the short name (microsoft#249894)
fixes microsoft#247864
1 parent 963bf2e commit fd7158c

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

src/vs/workbench/contrib/chat/browser/chatAttachmentWidgets.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { IOpenerService, OpenInternalOptions } from '../../../../platform/opener
2525
import { IThemeService, FolderThemeIcon } from '../../../../platform/theme/common/themeService.js';
2626
import { IResourceLabel, ResourceLabels, IFileLabelOptions } from '../../../browser/labels.js';
2727
import { revealInSideBarCommand } from '../../files/browser/fileActions.contribution.js';
28-
import { IChatRequestPasteVariableEntry, IChatRequestVariableEntry, IElementVariableEntry, INotebookOutputVariableEntry, ISCMHistoryItemVariableEntry, OmittedState } from '../common/chatModel.js';
28+
import { IChatRequestPasteVariableEntry, IChatRequestToolEntry, IChatRequestToolSetEntry, IChatRequestVariableEntry, IElementVariableEntry, INotebookOutputVariableEntry, ISCMHistoryItemVariableEntry, OmittedState } from '../common/chatModel.js';
2929
import { ILanguageModelChatMetadataAndIdentifier, ILanguageModelsService } from '../common/languageModels.js';
3030
import { chatAttachmentResourceContextKey } from './chatContentParts/chatAttachmentsContentPart.js';
3131
import { KeyCode } from '../../../../base/common/keyCodes.js';
@@ -52,6 +52,8 @@ import { ResourceContextKey } from '../../../common/contextkeys.js';
5252
import { Location, SymbolKind } from '../../../../editor/common/languages.js';
5353
import { IChatContentReference } from '../common/chatService.js';
5454
import { getHistoryItemEditorTitle, getHistoryItemHoverContent } from '../../scm/browser/util.js';
55+
import { ILanguageModelToolsService, ToolSet } from '../common/languageModelToolsService.js';
56+
import { Iterable } from '../../../../base/common/iterator.js';
5557

5658
abstract class AbstractChatAttachmentWidget extends Disposable {
5759
public readonly element: HTMLElement;
@@ -465,6 +467,54 @@ export class DefaultChatAttachmentWidget extends AbstractChatAttachmentWidget {
465467
}
466468
}
467469

470+
export class ToolSetOrToolItemAttachmentWidget extends AbstractChatAttachmentWidget {
471+
constructor(
472+
attachment: IChatRequestToolSetEntry | IChatRequestToolEntry,
473+
currentLanguageModel: ILanguageModelChatMetadataAndIdentifier | undefined,
474+
options: { shouldFocusClearButton: boolean; supportsDeletion: boolean },
475+
container: HTMLElement,
476+
contextResourceLabels: ResourceLabels,
477+
hoverDelegate: IHoverDelegate,
478+
@ILanguageModelToolsService toolsService: ILanguageModelToolsService,
479+
@ICommandService commandService: ICommandService,
480+
@IOpenerService openerService: IOpenerService,
481+
@IHoverService hoverService: IHoverService
482+
) {
483+
super(attachment, options, container, contextResourceLabels, hoverDelegate, currentLanguageModel, commandService, openerService);
484+
485+
486+
const toolOrToolSet = Iterable.find(toolsService.getTools(), tool => tool.id === attachment.id) ?? Iterable.find(toolsService.toolSets.get(), toolSet => toolSet.id === attachment.id);
487+
488+
let name = attachment.name;
489+
const icon = attachment.icon ?? Codicon.tools;
490+
491+
if (toolOrToolSet) {
492+
name = toolOrToolSet.toolReferenceName ?? name;
493+
}
494+
495+
this.label.setLabel(`$(${icon.id})\u00A0${name}`, undefined);
496+
497+
this.element.style.cursor = 'pointer';
498+
this.element.ariaLabel = localize('chat.attachment', "Attached context, {0}", name);
499+
500+
let hoverContent: string | undefined;
501+
502+
if (toolOrToolSet instanceof ToolSet) {
503+
hoverContent = localize('toolset', "{0} - {1}", toolOrToolSet.description ?? toolOrToolSet.displayName, toolOrToolSet.source.label);
504+
} else if (toolOrToolSet) {
505+
hoverContent = localize('tool', "{0} - {1}", toolOrToolSet.userDescription ?? toolOrToolSet.modelDescription, toolOrToolSet.source.label);
506+
}
507+
508+
if (hoverContent) {
509+
this._register(hoverService.setupManagedHover(hoverDelegate, this.element, hoverContent, { trapFocus: true }));
510+
}
511+
512+
this.attachClearButton();
513+
}
514+
515+
516+
}
517+
468518
export class NotebookCellOutputChatAttachmentWidget extends AbstractChatAttachmentWidget {
469519
constructor(
470520
resource: URI,

src/vs/workbench/contrib/chat/browser/chatContentParts/chatAttachmentsContentPart.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { IInstantiationService } from '../../../../../platform/instantiation/com
1616
import { ResourceLabels } from '../../../../browser/labels.js';
1717
import { IChatRequestVariableEntry, isElementVariableEntry, isImageVariableEntry, isNotebookOutputVariableEntry, isPasteVariableEntry, isSCMHistoryItemVariableEntry } from '../../common/chatModel.js';
1818
import { ChatResponseReferencePartStatusKind, IChatContentReference } from '../../common/chatService.js';
19-
import { DefaultChatAttachmentWidget, ElementChatAttachmentWidget, FileAttachmentWidget, ImageAttachmentWidget, NotebookCellOutputChatAttachmentWidget, PasteAttachmentWidget, SCMHistoryItemAttachmentWidget } from '../chatAttachmentWidgets.js';
19+
import { DefaultChatAttachmentWidget, ElementChatAttachmentWidget, FileAttachmentWidget, ImageAttachmentWidget, NotebookCellOutputChatAttachmentWidget, PasteAttachmentWidget, SCMHistoryItemAttachmentWidget, ToolSetOrToolItemAttachmentWidget } from '../chatAttachmentWidgets.js';
2020

2121
export const chatAttachmentResourceContextKey = new RawContextKey<string>('chatAttachmentResource', undefined, { type: 'URI', description: localize('resource', "The full value of the chat attachment resource, including scheme and path") });
2222

@@ -53,7 +53,9 @@ export class ChatAttachmentsContentPart extends Disposable {
5353
const correspondingContentReference = this.contentReferences.find((ref) => (typeof ref.reference === 'object' && 'variableName' in ref.reference && ref.reference.variableName === attachment.name) || (URI.isUri(ref.reference) && basename(ref.reference.path) === attachment.name));
5454

5555
let widget;
56-
if (isElementVariableEntry(attachment)) {
56+
if (attachment.kind === 'tool' || attachment.kind === 'toolset') {
57+
widget = this.instantiationService.createInstance(ToolSetOrToolItemAttachmentWidget, attachment, undefined, { shouldFocusClearButton: false, supportsDeletion: false }, container, this._contextResourceLabels, hoverDelegate);
58+
} else if (isElementVariableEntry(attachment)) {
5759
widget = this.instantiationService.createInstance(ElementChatAttachmentWidget, attachment, undefined, { shouldFocusClearButton: false, supportsDeletion: false }, container, this._contextResourceLabels, hoverDelegate);
5860
} else if (isImageVariableEntry(attachment)) {
5961
widget = this.instantiationService.createInstance(ImageAttachmentWidget, resource, attachment, undefined, { shouldFocusClearButton: false, supportsDeletion: false }, container, this._contextResourceLabels, hoverDelegate);

src/vs/workbench/contrib/chat/browser/chatInputPart.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ import { PromptInstructionsAttachmentsCollectionWidget } from './attachments/pro
8787
import { IChatWidget } from './chat.js';
8888
import { ChatAttachmentModel } from './chatAttachmentModel.js';
8989
import { toChatVariable } from './chatAttachmentModel/chatPromptAttachmentsCollection.js';
90-
import { DefaultChatAttachmentWidget, ElementChatAttachmentWidget, FileAttachmentWidget, ImageAttachmentWidget, NotebookCellOutputChatAttachmentWidget, PasteAttachmentWidget, SCMHistoryItemAttachmentWidget } from './chatAttachmentWidgets.js';
90+
import { DefaultChatAttachmentWidget, ElementChatAttachmentWidget, FileAttachmentWidget, ImageAttachmentWidget, NotebookCellOutputChatAttachmentWidget, PasteAttachmentWidget, SCMHistoryItemAttachmentWidget, ToolSetOrToolItemAttachmentWidget } from './chatAttachmentWidgets.js';
9191
import { IDisposableReference } from './chatContentParts/chatCollections.js';
9292
import { CollapsibleListPool, IChatCollapsibleListItem } from './chatContentParts/chatReferencesContentPart.js';
9393
import { ChatDragAndDrop } from './chatDragAndDrop.js';
@@ -1245,7 +1245,9 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
12451245

12461246
let attachmentWidget;
12471247
const options = { shouldFocusClearButton, supportsDeletion: true };
1248-
if (resource && isNotebookOutputVariableEntry(attachment)) {
1248+
if (attachment.kind === 'tool' || attachment.kind === 'toolset') {
1249+
attachmentWidget = this.instantiationService.createInstance(ToolSetOrToolItemAttachmentWidget, attachment, this._currentLanguageModel, options, container, this._contextResourceLabels, hoverDelegate);
1250+
} else if (resource && isNotebookOutputVariableEntry(attachment)) {
12491251
attachmentWidget = this.instantiationService.createInstance(NotebookCellOutputChatAttachmentWidget, resource, attachment, this._currentLanguageModel, options, container, this._contextResourceLabels, hoverDelegate);
12501252
} else if (resource && (attachment.kind === 'file' || attachment.kind === 'directory')) {
12511253
attachmentWidget = this.instantiationService.createInstance(FileAttachmentWidget, resource, range, attachment, undefined, this._currentLanguageModel, options, container, this._contextResourceLabels, hoverDelegate);

src/vs/workbench/contrib/chat/browser/contrib/chatInputCompletions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ class ToolCompletions extends Disposable {
11091109
range,
11101110
detail,
11111111
insertText: withLeader + ' ',
1112-
kind: CompletionItemKind.Text,
1112+
kind: CompletionItemKind.Tool,
11131113
sortText: 'z',
11141114
});
11151115

0 commit comments

Comments
 (0)