mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-09 16:24:45 +01:00
Implement past tense invocation message and tooltip for tool calls (#238635)
* Implement past tense invocation message and tooltip for tool calls * Fix * Clean up
This commit is contained in:
@@ -12,7 +12,7 @@ import { revive } from '../../../base/common/marshalling.js';
|
||||
import { generateUuid } from '../../../base/common/uuid.js';
|
||||
import { IExtensionDescription } from '../../../platform/extensions/common/extensions.js';
|
||||
import { IPreparedToolInvocation, isToolInvocationContext, IToolInvocation, IToolInvocationContext, IToolResult } from '../../contrib/chat/common/languageModelToolsService.js';
|
||||
import { isProposedApiEnabled } from '../../services/extensions/common/extensions.js';
|
||||
import { checkProposedApiEnabled, isProposedApiEnabled } from '../../services/extensions/common/extensions.js';
|
||||
import { ExtHostLanguageModelToolsShape, IMainContext, IToolDataDto, MainContext, MainThreadLanguageModelToolsShape } from './extHost.protocol.js';
|
||||
import * as typeConvert from './extHostTypeConverters.js';
|
||||
|
||||
@@ -136,16 +136,18 @@ export class ExtHostLanguageModelTools implements ExtHostLanguageModelToolsShape
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (result.pastTenseMessage || result.tooltip) {
|
||||
checkProposedApiEnabled(item.extension, 'chatParticipantPrivate');
|
||||
}
|
||||
|
||||
return {
|
||||
confirmationMessages: result.confirmationMessages ? {
|
||||
title: result.confirmationMessages.title,
|
||||
message: typeof result.confirmationMessages.message === 'string' ? result.confirmationMessages.message : typeConvert.MarkdownString.from(result.confirmationMessages.message),
|
||||
} : undefined,
|
||||
invocationMessage: typeof result.invocationMessage === 'string' ?
|
||||
result.invocationMessage :
|
||||
(result.invocationMessage ?
|
||||
typeConvert.MarkdownString.from(result.invocationMessage) :
|
||||
undefined),
|
||||
invocationMessage: typeConvert.MarkdownString.fromStrict(result.invocationMessage),
|
||||
pastTenseMessage: typeConvert.MarkdownString.fromStrict(result.pastTenseMessage),
|
||||
tooltip: result.tooltip ? typeConvert.MarkdownString.fromStrict(result.tooltip) : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
import * as dom from '../../../../../base/browser/dom.js';
|
||||
import { Codicon } from '../../../../../base/common/codicons.js';
|
||||
import { Emitter, Relay } from '../../../../../base/common/event.js';
|
||||
import { MarkdownString } from '../../../../../base/common/htmlContent.js';
|
||||
import { IMarkdownString, MarkdownString } from '../../../../../base/common/htmlContent.js';
|
||||
import { Disposable, DisposableStore, IDisposable } from '../../../../../base/common/lifecycle.js';
|
||||
import { MarkdownRenderer } from '../../../../../editor/browser/widget/markdownRenderer/browser/markdownRenderer.js';
|
||||
import { localize } from '../../../../../nls.js';
|
||||
import { IHoverService } from '../../../../../platform/hover/browser/hover.js';
|
||||
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IChatProgressMessage, IChatToolInvocation, IChatToolInvocationSerialized } from '../../common/chatService.js';
|
||||
import { IChatRendererContent } from '../../common/chatViewModel.js';
|
||||
@@ -75,6 +76,7 @@ class ChatToolInvocationSubPart extends Disposable {
|
||||
context: IChatContentPartRenderContext,
|
||||
renderer: MarkdownRenderer,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IHoverService hoverService: IHoverService,
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -93,9 +95,17 @@ class ChatToolInvocationSubPart extends Disposable {
|
||||
this._onDidChangeHeight.input = confirmWidget.onDidChangeHeight;
|
||||
toolInvocation.confirmed.p.then(() => this._onNeedsRerender.fire());
|
||||
} else {
|
||||
const content = typeof toolInvocation.invocationMessage === 'string' ?
|
||||
new MarkdownString().appendText(toolInvocation.invocationMessage + '…') :
|
||||
new MarkdownString(toolInvocation.invocationMessage.value + '…');
|
||||
let content: IMarkdownString;
|
||||
if (toolInvocation.isComplete && toolInvocation.isConfirmed !== false && toolInvocation.pastTenseMessage) {
|
||||
content = typeof toolInvocation.pastTenseMessage === 'string' ?
|
||||
new MarkdownString().appendText(toolInvocation.pastTenseMessage) :
|
||||
toolInvocation.pastTenseMessage;
|
||||
} else {
|
||||
content = typeof toolInvocation.invocationMessage === 'string' ?
|
||||
new MarkdownString().appendText(toolInvocation.invocationMessage + '…') :
|
||||
new MarkdownString(toolInvocation.invocationMessage.value + '…');
|
||||
}
|
||||
|
||||
const progressMessage: IChatProgressMessage = {
|
||||
kind: 'progressMessage',
|
||||
content
|
||||
@@ -105,6 +115,10 @@ class ChatToolInvocationSubPart extends Disposable {
|
||||
toolInvocation.isComplete ?
|
||||
Codicon.check : undefined;
|
||||
const progressPart = this._register(instantiationService.createInstance(ChatProgressContentPart, progressMessage, renderer, context, undefined, true, iconOverride));
|
||||
if (toolInvocation.tooltip) {
|
||||
this._register(hoverService.setupDelayedHover(progressPart.domNode, { content: toolInvocation.tooltip, additionalClasses: ['chat-tool-hover'] }));
|
||||
}
|
||||
|
||||
this.domNode = progressPart.domNode;
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ export class LanguageModelToolsService extends Disposable implements ILanguageMo
|
||||
const defaultMessage = localize('toolInvocationMessage', "Using {0}", `"${tool.data.displayName}"`);
|
||||
const invocationMessage = prepared?.invocationMessage ?? defaultMessage;
|
||||
if (tool.data.id !== 'vscode_editFile') {
|
||||
toolInvocation = new ChatToolInvocation(invocationMessage, prepared?.confirmationMessages);
|
||||
toolInvocation = new ChatToolInvocation(invocationMessage, prepared?.pastTenseMessage, prepared?.tooltip, prepared?.confirmationMessages);
|
||||
model.acceptResponseProgress(request, toolInvocation);
|
||||
if (prepared?.confirmationMessages) {
|
||||
const userConfirmed = await toolInvocation.confirmed.p;
|
||||
|
||||
@@ -392,14 +392,15 @@ have to be updated for changes to the rules above, or to support more deeply nes
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.interactive-item-container .monaco-tokenized-source,
|
||||
.interactive-item-container code {
|
||||
font-family: var(--monaco-monospace-font);
|
||||
font-size: 12px;
|
||||
color: var(--vscode-textPreformat-foreground);
|
||||
background-color: var(--vscode-textPreformat-background);
|
||||
padding: 1px 3px;
|
||||
border-radius: 4px;
|
||||
.chat-tool-hover, .interactive-item-container {
|
||||
.monaco-tokenized-source, code {
|
||||
font-family: var(--monaco-monospace-font);
|
||||
font-size: 12px;
|
||||
color: var(--vscode-textPreformat-foreground);
|
||||
background-color: var(--vscode-textPreformat-background);
|
||||
padding: 1px 3px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.interactive-item-container.interactive-item-compact {
|
||||
@@ -1447,6 +1448,10 @@ have to be updated for changes to the rules above, or to support more deeply nes
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.interactive-item-container .chat-confirmation-widget .rendered-markdown [data-code] {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.interactive-item-container .chat-command-button .monaco-button .codicon {
|
||||
margin-left: 0;
|
||||
margin-top: 1px;
|
||||
|
||||
@@ -38,6 +38,8 @@ export class ChatToolInvocation implements IChatToolInvocation {
|
||||
|
||||
constructor(
|
||||
public readonly invocationMessage: string | IMarkdownString,
|
||||
public readonly pastTenseMessage: string | IMarkdownString | undefined,
|
||||
public readonly tooltip: string | IMarkdownString | undefined,
|
||||
private _confirmationMessages: IToolConfirmationMessages | undefined) {
|
||||
if (!_confirmationMessages) {
|
||||
// No confirmation needed
|
||||
@@ -63,6 +65,8 @@ export class ChatToolInvocation implements IChatToolInvocation {
|
||||
return {
|
||||
kind: 'toolInvocationSerialized',
|
||||
invocationMessage: this.invocationMessage,
|
||||
pastTenseMessage: this.pastTenseMessage,
|
||||
tooltip: this.tooltip,
|
||||
isConfirmed: this._isConfirmed ?? false,
|
||||
isComplete: this._isComplete,
|
||||
};
|
||||
|
||||
@@ -203,6 +203,8 @@ export interface IChatToolInvocation {
|
||||
/** A 3-way: undefined=don't know yet. */
|
||||
isConfirmed: boolean | undefined;
|
||||
invocationMessage: string | IMarkdownString;
|
||||
pastTenseMessage: string | IMarkdownString | undefined;
|
||||
tooltip: string | IMarkdownString | undefined;
|
||||
|
||||
isComplete: boolean;
|
||||
isCompleteDeferred: DeferredPromise<void>;
|
||||
@@ -214,6 +216,8 @@ export interface IChatToolInvocation {
|
||||
*/
|
||||
export interface IChatToolInvocationSerialized {
|
||||
invocationMessage: string | IMarkdownString;
|
||||
pastTenseMessage: string | IMarkdownString | undefined;
|
||||
tooltip: string | IMarkdownString | undefined;
|
||||
isConfirmed: boolean;
|
||||
isComplete: boolean;
|
||||
kind: 'toolInvocationSerialized';
|
||||
|
||||
@@ -66,6 +66,8 @@ export interface IToolConfirmationMessages {
|
||||
|
||||
export interface IPreparedToolInvocation {
|
||||
invocationMessage?: string | IMarkdownString;
|
||||
pastTenseMessage?: string | IMarkdownString;
|
||||
tooltip?: string | IMarkdownString;
|
||||
confirmationMessages?: IToolConfirmationMessages;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,4 +122,9 @@ declare module 'vscode' {
|
||||
export interface LanguageModelToolInvocationOptions<T> {
|
||||
chatRequestId?: string;
|
||||
}
|
||||
|
||||
export interface PreparedToolInvocation {
|
||||
pastTenseMessage?: string | MarkdownString;
|
||||
tooltip?: string | MarkdownString;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user