mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 09:08:48 +01:00
Replace chat "command followups" with command button content (#204512)
* Delete CommandFollowups and make inline chat use its own types for command followups * Add command button, render it properly * Manage the lifecycle of commands from chat command buttons * Handle stale session command in type converter * Fix
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
"--vscode-chat-requestBorder",
|
||||
"--vscode-chat-slashCommandBackground",
|
||||
"--vscode-chat-slashCommandForeground",
|
||||
"--vscode-chat-list-background",
|
||||
"--vscode-checkbox-background",
|
||||
"--vscode-checkbox-border",
|
||||
"--vscode-checkbox-foreground",
|
||||
|
||||
@@ -208,7 +208,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
rpcProtocol.set(ExtHostContext.ExtHostInteractive, new ExtHostInteractive(rpcProtocol, extHostNotebook, extHostDocumentsAndEditors, extHostCommands, extHostLogService));
|
||||
const extHostInteractiveEditor = rpcProtocol.set(ExtHostContext.ExtHostInlineChat, new ExtHostInteractiveEditor(rpcProtocol, extHostCommands, extHostDocuments, extHostLogService));
|
||||
const extHostChatProvider = rpcProtocol.set(ExtHostContext.ExtHostChatProvider, new ExtHostChatProvider(rpcProtocol, extHostLogService));
|
||||
const extHostChatAgents2 = rpcProtocol.set(ExtHostContext.ExtHostChatAgents2, new ExtHostChatAgents2(rpcProtocol, extHostChatProvider, extHostLogService));
|
||||
const extHostChatAgents2 = rpcProtocol.set(ExtHostContext.ExtHostChatAgents2, new ExtHostChatAgents2(rpcProtocol, extHostChatProvider, extHostLogService, extHostCommands));
|
||||
const extHostChatVariables = rpcProtocol.set(ExtHostContext.ExtHostChatVariables, new ExtHostChatVariables(rpcProtocol));
|
||||
const extHostChat = rpcProtocol.set(ExtHostContext.ExtHostChat, new ExtHostChat(rpcProtocol));
|
||||
const extHostAiRelatedInformation = rpcProtocol.set(ExtHostContext.ExtHostAiRelatedInformation, new ExtHostRelatedInformation(rpcProtocol));
|
||||
|
||||
@@ -53,10 +53,10 @@ import { CallHierarchyItem } from 'vs/workbench/contrib/callHierarchy/common/cal
|
||||
import { IChatAgentCommand, IChatAgentMetadata, IChatAgentRequest, IChatAgentResult } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { IChatProgressResponseContent } from 'vs/workbench/contrib/chat/common/chatModel';
|
||||
import { IChatMessage, IChatResponseFragment, IChatResponseProviderMetadata } from 'vs/workbench/contrib/chat/common/chatProvider';
|
||||
import { IChatDynamicRequest, IChatFollowup, IChatProgress, IChatReplyFollowup, IChatResponseErrorDetails, IChatUserActionEvent, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatDynamicRequest, IChatProgress, IChatResponseErrorDetails, IChatUserActionEvent, InteractiveSessionVoteDirection, IChatFollowup } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatRequestVariableValue, IChatVariableData } from 'vs/workbench/contrib/chat/common/chatVariables';
|
||||
import { DebugConfigurationProviderTriggerKind, MainThreadDebugVisualization, IAdapterDescriptor, IConfig, IDebugSessionReplMode, IDebugVisualization, IDebugVisualizationContext } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IInlineChatBulkEditResponse, IInlineChatEditResponse, IInlineChatProgressItem, IInlineChatRequest, IInlineChatSession, InlineChatResponseFeedbackKind } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { IInlineChatBulkEditResponse, IInlineChatEditResponse, IInlineChatFollowup, IInlineChatProgressItem, IInlineChatRequest, IInlineChatSession, InlineChatResponseFeedbackKind } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import * as notebookCommon from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellExecutionUpdateType } from 'vs/workbench/contrib/notebook/common/notebookExecutionService';
|
||||
import { ICellExecutionComplete, ICellExecutionStateUpdate } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
|
||||
@@ -1225,7 +1225,7 @@ export interface ExtHostChatAgentsShape2 {
|
||||
$acceptAction(handle: number, sessionId: string, requestId: string, action: IChatUserActionEvent): void;
|
||||
$invokeCompletionProvider(handle: number, query: string, token: CancellationToken): Promise<IChatAgentCompletionItem[]>;
|
||||
$provideWelcomeMessage(handle: number, token: CancellationToken): Promise<(string | IMarkdownString)[] | undefined>;
|
||||
$provideSampleQuestions(handle: number, token: CancellationToken): Promise<IChatReplyFollowup[] | undefined>;
|
||||
$provideSampleQuestions(handle: number, token: CancellationToken): Promise<IChatFollowup[] | undefined>;
|
||||
$releaseSession(sessionId: string): void;
|
||||
}
|
||||
|
||||
@@ -1251,7 +1251,7 @@ export type IInlineChatResponseDto = Dto<IInlineChatEditResponse | Omit<IInlineC
|
||||
export interface ExtHostInlineChatShape {
|
||||
$prepareSession(handle: number, uri: UriComponents, range: ISelection, token: CancellationToken): Promise<IInlineChatSession | undefined>;
|
||||
$provideResponse(handle: number, session: IInlineChatSession, request: IInlineChatRequest, token: CancellationToken): Promise<IInlineChatResponseDto | undefined>;
|
||||
$provideFollowups(handle: number, sessionId: number, responseId: number, token: CancellationToken): Promise<IChatFollowup[] | undefined>;
|
||||
$provideFollowups(handle: number, sessionId: number, responseId: number, token: CancellationToken): Promise<IInlineChatFollowup[] | undefined>;
|
||||
$handleFeedback(handle: number, sessionId: number, responseId: number, kind: InlineChatResponseFeedbackKind): void;
|
||||
$releaseSession(handle: number, sessionId: number): void;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { StopWatch } from 'vs/base/common/stopwatch';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -16,10 +17,11 @@ import { 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 { ExtHostChatProvider } from 'vs/workbench/api/common/extHostChatProvider';
|
||||
import { CommandsConverter, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import { IChatAgentCommand, IChatAgentRequest, IChatAgentResult } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { IChatFollowup, IChatProgress, IChatReplyFollowup, IChatUserActionEvent, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatFollowup, IChatProgress, IChatUserActionEvent, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { checkProposedApiEnabled, isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { Dto } from 'vs/workbench/services/extensions/common/proxyIdentifier';
|
||||
import type * as vscode from 'vscode';
|
||||
@@ -35,7 +37,8 @@ class ChatAgentResponseStream {
|
||||
private readonly _extension: IExtensionDescription,
|
||||
private readonly _request: IChatAgentRequest,
|
||||
private readonly _proxy: MainThreadChatAgentsShape2,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
private readonly _logService: ILogService,
|
||||
private readonly _commandsConverter: CommandsConverter,
|
||||
) { }
|
||||
|
||||
close() {
|
||||
@@ -99,6 +102,14 @@ class ChatAgentResponseStream {
|
||||
_report(dto);
|
||||
return this;
|
||||
},
|
||||
button(command) {
|
||||
throwIfDone(this.anchor);
|
||||
_report({
|
||||
kind: 'command',
|
||||
command: that._commandsConverter.toInternal(command, new DisposableStore()) // ??
|
||||
});
|
||||
return this;
|
||||
},
|
||||
progress(value) {
|
||||
throwIfDone(this.progress);
|
||||
const part = new extHostTypes.ChatResponseProgressPart(value);
|
||||
@@ -150,6 +161,7 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
|
||||
mainContext: IMainContext,
|
||||
private readonly _extHostChatProvider: ExtHostChatProvider,
|
||||
private readonly _logService: ILogService,
|
||||
private readonly commands: ExtHostCommands,
|
||||
) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadChatAgents2);
|
||||
}
|
||||
@@ -175,7 +187,7 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
|
||||
|
||||
this._extHostChatProvider.$updateAllowlist([{ extension: agent.extension.identifier, allowed: true }]);
|
||||
|
||||
const stream = new ChatAgentResponseStream(agent.extension, request, this._proxy, this._logService);
|
||||
const stream = new ChatAgentResponseStream(agent.extension, request, this._proxy, this._logService, this.commands.converter);
|
||||
try {
|
||||
const convertedHistory = await this.prepareHistory(agent, request, context);
|
||||
const task = agent.invoke(
|
||||
@@ -220,7 +232,7 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
|
||||
|| h.result;
|
||||
return {
|
||||
request: typeConvert.ChatAgentRequest.to(h.request),
|
||||
response: coalesce(h.response.map(r => typeConvert.ChatResponseProgress.toProgressContent(r))),
|
||||
response: coalesce(h.response.map(r => typeConvert.ChatResponseProgress.toProgressContent(r, this.commands.converter))),
|
||||
result
|
||||
} satisfies vscode.ChatAgentHistoryEntry;
|
||||
})));
|
||||
@@ -289,7 +301,14 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
|
||||
// handled by $acceptFeedback
|
||||
return;
|
||||
}
|
||||
agent.acceptAction(Object.freeze({ action: action.action, result }));
|
||||
|
||||
if (action.action.kind === 'command') {
|
||||
const action2: vscode.ChatAgentCommandAction = { kind: 'command', commandButton: typeConvert.ChatResponseProgress.toProgressContent(action.action.commandButton, this.commands.converter) as vscode.ChatAgentCommandButton };
|
||||
agent.acceptAction(Object.freeze({ action: action2, result }));
|
||||
return;
|
||||
} else {
|
||||
agent.acceptAction(Object.freeze({ action: action.action, result }));
|
||||
}
|
||||
}
|
||||
|
||||
async $invokeCompletionProvider(handle: number, query: string, token: CancellationToken): Promise<IChatAgentCompletionItem[]> {
|
||||
@@ -311,7 +330,7 @@ export class ExtHostChatAgents2 implements ExtHostChatAgentsShape2 {
|
||||
return await agent.provideWelcomeMessage(token);
|
||||
}
|
||||
|
||||
async $provideSampleQuestions(handle: number, token: CancellationToken): Promise<IChatReplyFollowup[] | undefined> {
|
||||
async $provideSampleQuestions(handle: number, token: CancellationToken): Promise<IChatFollowup[] | undefined> {
|
||||
const agent = this._agents.get(handle);
|
||||
if (!agent) {
|
||||
return;
|
||||
@@ -409,7 +428,7 @@ class ExtHostChatAgent<TResult extends vscode.ChatAgentResult2> {
|
||||
});
|
||||
}
|
||||
|
||||
async provideSampleQuestions(token: CancellationToken): Promise<IChatReplyFollowup[]> {
|
||||
async provideSampleQuestions(token: CancellationToken): Promise<IChatFollowup[]> {
|
||||
if (!this._welcomeMessageProvider || !this._welcomeMessageProvider.provideSampleQuestions) {
|
||||
return [];
|
||||
}
|
||||
@@ -418,7 +437,7 @@ class ExtHostChatAgent<TResult extends vscode.ChatAgentResult2> {
|
||||
return [];
|
||||
}
|
||||
|
||||
return content?.map(f => typeConvert.ChatReplyFollowup.from(f));
|
||||
return content?.map(f => typeConvert.ChatFollowup.from(f));
|
||||
}
|
||||
|
||||
get apiAgent(): vscode.ChatAgent2<TResult> {
|
||||
|
||||
@@ -3,23 +3,22 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { raceCancellation } from 'vs/base/common/async';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { ISelection } from 'vs/editor/common/core/selection';
|
||||
import { IInlineChatSession, IInlineChatRequest, InlineChatResponseFeedbackKind, InlineChatResponseType } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { IRelaxedExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { ExtHostInlineChatShape, IInlineChatResponseDto, IMainContext, MainContext, MainThreadInlineChatShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ApiCommand, ApiCommandArgument, ApiCommandResult, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
||||
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import { IInlineChatFollowup, IInlineChatRequest, IInlineChatSession, InlineChatResponseFeedbackKind, InlineChatResponseType } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import type * as vscode from 'vscode';
|
||||
import { ApiCommand, ApiCommandArgument, ApiCommandResult, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { raceCancellation } from 'vs/base/common/async';
|
||||
import { IChatFollowup } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
|
||||
class ProviderWrapper {
|
||||
|
||||
@@ -228,14 +227,14 @@ export class ExtHostInteractiveEditor implements ExtHostInlineChatShape {
|
||||
}
|
||||
}
|
||||
|
||||
async $provideFollowups(handle: number, sessionId: number, responseId: number, token: CancellationToken): Promise<IChatFollowup[] | undefined> {
|
||||
async $provideFollowups(handle: number, sessionId: number, responseId: number, token: CancellationToken): Promise<IInlineChatFollowup[] | undefined> {
|
||||
const entry = this._inputProvider.get(handle);
|
||||
const sessionData = this._inputSessions.get(sessionId);
|
||||
const response = sessionData?.responses[responseId];
|
||||
if (entry && response && entry.provider.provideFollowups) {
|
||||
const task = Promise.resolve(entry.provider.provideFollowups(sessionData.session, response, token));
|
||||
const followups = await raceCancellation(task, token);
|
||||
return followups?.map(typeConvert.ChatFollowup.from);
|
||||
return followups?.map(typeConvert.ChatInlineFollowup.from);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ import { DEFAULT_EDITOR_ASSOCIATION, SaveReason } from 'vs/workbench/common/edit
|
||||
import { IViewBadge } from 'vs/workbench/common/views';
|
||||
import { IChatAgentRequest } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import * as chatProvider from 'vs/workbench/contrib/chat/common/chatProvider';
|
||||
import { IChatContentInlineReference, IChatContentReference, IChatFollowup, IChatMarkdownContent, IChatProgressMessage, IChatReplyFollowup, IChatResponseCommandFollowup, IChatTreeData } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatContentInlineReference, IChatContentReference, IChatFollowup, IChatMarkdownContent, IChatProgressMessage, IChatTreeData } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatRequestVariableValue } from 'vs/workbench/contrib/chat/common/chatVariables';
|
||||
import { InlineChatResponseFeedbackKind } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { IInlineChatCommandFollowup, IInlineChatFollowup, IInlineChatReplyFollowup, InlineChatResponseFeedbackKind } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import * as notebooks from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange';
|
||||
import * as search from 'vs/workbench/contrib/search/common/search';
|
||||
@@ -2190,8 +2190,8 @@ export namespace DataTransfer {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace ChatReplyFollowup {
|
||||
export function from(followup: vscode.ChatAgentReplyFollowup | vscode.InteractiveEditorReplyFollowup): IChatReplyFollowup {
|
||||
export namespace ChatFollowup {
|
||||
export function from(followup: vscode.ChatAgentFollowup): IChatFollowup {
|
||||
return {
|
||||
kind: 'reply',
|
||||
message: followup.message,
|
||||
@@ -2201,21 +2201,25 @@ export namespace ChatReplyFollowup {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace ChatFollowup {
|
||||
export function from(followup: string | vscode.ChatAgentFollowup): IChatFollowup {
|
||||
if (typeof followup === 'string') {
|
||||
return <IChatReplyFollowup>{ title: followup, message: followup, kind: 'reply' };
|
||||
} else if ('commandId' in followup) {
|
||||
return <IChatResponseCommandFollowup>{
|
||||
export namespace ChatInlineFollowup {
|
||||
export function from(followup: vscode.InteractiveEditorFollowup): IInlineChatFollowup {
|
||||
if ('commandId' in followup) {
|
||||
return {
|
||||
kind: 'command',
|
||||
title: followup.title ?? '',
|
||||
commandId: followup.commandId ?? '',
|
||||
when: followup.when ?? '',
|
||||
args: followup.args
|
||||
};
|
||||
} satisfies IInlineChatCommandFollowup;
|
||||
} else {
|
||||
return ChatReplyFollowup.from(followup);
|
||||
return {
|
||||
kind: 'reply',
|
||||
message: followup.message,
|
||||
title: followup.title,
|
||||
tooltip: followup.tooltip,
|
||||
} satisfies IInlineChatReplyFollowup;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2513,7 +2517,7 @@ export namespace ChatResponseProgress {
|
||||
}
|
||||
}
|
||||
|
||||
export function toProgressContent(progress: extHostProtocol.IChatContentProgressDto): vscode.ChatAgentContentProgress | undefined {
|
||||
export function toProgressContent(progress: extHostProtocol.IChatContentProgressDto, commandsConverter: Command.ICommandsConverter): vscode.ChatAgentContentProgress | undefined {
|
||||
switch (progress.kind) {
|
||||
case 'markdownContent':
|
||||
// For simplicity, don't sent back the 'extended' types, so downgrade markdown to just some text
|
||||
@@ -2528,6 +2532,11 @@ export namespace ChatResponseProgress {
|
||||
};
|
||||
case 'treeData':
|
||||
return { treeData: revive(progress.treeData) };
|
||||
case 'command':
|
||||
// If the command isn't in the converter, then this session may have been restored, and the command args don't exist anymore
|
||||
return {
|
||||
command: commandsConverter.fromInternal(progress.command) ?? { command: progress.command.id, title: progress.command.title },
|
||||
};
|
||||
default:
|
||||
// Unknown type, eg something in history that was removed? Ignore
|
||||
return undefined;
|
||||
|
||||
@@ -10,10 +10,11 @@ import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IChatFollowup } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IInlineChatFollowup } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
export class ChatFollowups<T extends IChatFollowup> extends Disposable {
|
||||
export class ChatFollowups<T extends IChatFollowup | IInlineChatFollowup> extends Disposable {
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
followups: T[],
|
||||
|
||||
@@ -37,7 +37,7 @@ import { ChatFollowups } from 'vs/workbench/contrib/chat/browser/chatFollowups';
|
||||
import { IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { CONTEXT_CHAT_INPUT_CURSOR_AT_TOP, CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_IN_CHAT_INPUT } from 'vs/workbench/contrib/chat/common/chatContextKeys';
|
||||
import { chatAgentLeader } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
import { IChatReplyFollowup } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatFollowup } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatResponseViewModel } from 'vs/workbench/contrib/chat/common/chatViewModel';
|
||||
import { IChatHistoryEntry, IChatWidgetHistoryService } from 'vs/workbench/contrib/chat/common/chatWidgetHistoryService';
|
||||
import { getSimpleCodeEditorWidgetOptions, getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions';
|
||||
@@ -64,7 +64,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
|
||||
private _onDidBlur = this._register(new Emitter<void>());
|
||||
readonly onDidBlur = this._onDidBlur.event;
|
||||
|
||||
private _onDidAcceptFollowup = this._register(new Emitter<{ followup: IChatReplyFollowup; response: IChatResponseViewModel | undefined }>());
|
||||
private _onDidAcceptFollowup = this._register(new Emitter<{ followup: IChatFollowup; response: IChatResponseViewModel | undefined }>());
|
||||
readonly onDidAcceptFollowup = this._onDidAcceptFollowup.event;
|
||||
|
||||
private inputEditorHeight = 0;
|
||||
@@ -338,7 +338,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
|
||||
}
|
||||
}
|
||||
|
||||
async renderFollowups(items: IChatReplyFollowup[] | undefined, response: IChatResponseViewModel | undefined): Promise<void> {
|
||||
async renderFollowups(items: IChatFollowup[] | undefined, response: IChatResponseViewModel | undefined): Promise<void> {
|
||||
if (!this.options.renderFollowups) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ import { IChatAgentMetadata } from 'vs/workbench/contrib/chat/common/chatAgents'
|
||||
import { CONTEXT_CHAT_RESPONSE_SUPPORT_ISSUE_REPORTING, CONTEXT_REQUEST, CONTEXT_RESPONSE, CONTEXT_RESPONSE_FILTERED, CONTEXT_RESPONSE_VOTE } from 'vs/workbench/contrib/chat/common/chatContextKeys';
|
||||
import { IChatProgressRenderableResponseContent } from 'vs/workbench/contrib/chat/common/chatModel';
|
||||
import { chatAgentLeader, chatSubcommandLeader } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
import { IChatContentReference, IChatProgressMessage, IChatReplyFollowup, IChatResponseProgressFileTreeData, IChatService, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatCommandButton, IChatContentReference, IChatFollowup, IChatProgressMessage, IChatResponseProgressFileTreeData, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatProgressMessageRenderData, IChatRenderData, IChatResponseMarkdownRenderData, IChatResponseViewModel, IChatWelcomeMessageViewModel, isRequestVM, isResponseVM, isWelcomeVM } from 'vs/workbench/contrib/chat/common/chatViewModel';
|
||||
import { IWordCountResult, getNWords } from 'vs/workbench/contrib/chat/common/chatWordCounter';
|
||||
import { createFileIconThemableTreeContainerScope } from 'vs/workbench/contrib/files/browser/views/explorerView';
|
||||
@@ -110,8 +110,8 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
||||
private readonly renderer: MarkdownRenderer;
|
||||
private readonly markdownDecorationsRenderer: ChatMarkdownDecorationsRenderer;
|
||||
|
||||
protected readonly _onDidClickFollowup = this._register(new Emitter<IChatReplyFollowup>());
|
||||
readonly onDidClickFollowup: Event<IChatReplyFollowup> = this._onDidClickFollowup.event;
|
||||
protected readonly _onDidClickFollowup = this._register(new Emitter<IChatFollowup>());
|
||||
readonly onDidClickFollowup: Event<IChatFollowup> = this._onDidClickFollowup.event;
|
||||
|
||||
protected readonly _onDidChangeItemHeight = this._register(new Emitter<IItemHeightChangeParams>());
|
||||
readonly onDidChangeItemHeight: Event<IItemHeightChangeParams> = this._onDidChangeItemHeight.event;
|
||||
@@ -133,12 +133,11 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IConfigurationService configService: IConfigurationService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
@IOpenerService private readonly openerService: IOpenerService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IChatService private readonly chatService: IChatService,
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
) {
|
||||
super();
|
||||
this.renderer = this.instantiationService.createInstance(MarkdownRenderer, {});
|
||||
@@ -336,7 +335,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
||||
const renderableResponse = annotateSpecialMarkdownContent(element.response.value);
|
||||
this.basicRenderElement(renderableResponse, element, index, templateData);
|
||||
} else if (isRequestVM(element)) {
|
||||
const markdown = 'kind' in element.message ?
|
||||
const markdown = 'message' in element.message ?
|
||||
element.message.message :
|
||||
this.markdownDecorationsRenderer.convertParsedRequestToMarkdown(element.message);
|
||||
this.basicRenderElement([{ content: new MarkdownString(markdown), kind: 'markdownContent' }], element, index, templateData);
|
||||
@@ -438,8 +437,9 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
||||
? this.renderTreeData(data.treeData, element, templateData, fileTreeIndex++)
|
||||
: data.kind === 'markdownContent'
|
||||
? this.renderMarkdown(data.content, element, templateData, fillInIncompleteTokens)
|
||||
: onlyProgressMessagesAfterI(value, index) ? this.renderProgressMessage(data, false)
|
||||
: undefined;
|
||||
: data.kind === 'progressMessage' && onlyProgressMessagesAfterI(value, index) ? this.renderProgressMessage(data, false) // TODO render command
|
||||
: data.kind === 'command' ? this.renderCommandButton(element, data)
|
||||
: undefined;
|
||||
if (result) {
|
||||
templateData.value.appendChild(result.element);
|
||||
templateData.elementDisposables.add(result);
|
||||
@@ -453,28 +453,6 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
||||
errorDetails.appendChild($('span', undefined, renderedError.element));
|
||||
}
|
||||
|
||||
if (isResponseVM(element) && element.commandFollowups?.length) {
|
||||
const followupsContainer = dom.append(templateData.value, $('.interactive-response-followups'));
|
||||
templateData.elementDisposables.add(new ChatFollowups(
|
||||
followupsContainer,
|
||||
element.commandFollowups,
|
||||
defaultButtonStyles,
|
||||
followup => {
|
||||
this.chatService.notifyUserAction({
|
||||
providerId: element.providerId,
|
||||
agentId: element.agent?.id,
|
||||
sessionId: element.sessionId,
|
||||
requestId: element.requestId,
|
||||
action: {
|
||||
kind: 'command',
|
||||
command: followup,
|
||||
}
|
||||
});
|
||||
return this.commandService.executeCommand(followup.commandId, ...(followup.args ?? []));
|
||||
},
|
||||
templateData.contextKeyService));
|
||||
}
|
||||
|
||||
const newHeight = templateData.rowContainer.offsetHeight;
|
||||
const fireEvent = !element.currentRenderedHeight || element.currentRenderedHeight !== newHeight;
|
||||
element.currentRenderedHeight = newHeight;
|
||||
@@ -551,6 +529,8 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
||||
isAtEndOfResponse: onlyProgressMessagesAfterI(renderableResponse, index),
|
||||
isLast: index === renderableResponse.length - 1,
|
||||
} satisfies IChatProgressMessageRenderData;
|
||||
} else if (part.kind === 'command') {
|
||||
partsToRender[index] = part;
|
||||
} else {
|
||||
const wordCountResult = this.getDataForProgressiveRender(element, contentToMarkdown(part.content), { renderedWordCount: 0, lastRenderTime: 0 });
|
||||
if (wordCountResult !== undefined) {
|
||||
@@ -566,7 +546,7 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
||||
}
|
||||
|
||||
// Did this part's content change?
|
||||
else if (part.kind !== 'treeData' && !isInteractiveProgressTreeData(renderedPart) && !isProgressMessageRenderData(renderedPart)) {
|
||||
else if ((part.kind === 'markdownContent' || part.kind === 'progressMessage') && isMarkdownRenderData(renderedPart)) { // TODO
|
||||
const wordCountResult = this.getDataForProgressiveRender(element, contentToMarkdown(part.content), renderedPart);
|
||||
// Check if there are any new words to render
|
||||
if (wordCountResult !== undefined && renderedPart.renderedWordCount !== wordCountResult?.actualWordCount) {
|
||||
@@ -622,6 +602,8 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
} else if (isCommandButtonRenderData(partToRender)) {
|
||||
result = this.renderCommandButton(element, partToRender);
|
||||
}
|
||||
|
||||
// Avoid doing progressive rendering for multiple markdown parts simultaneously
|
||||
@@ -821,6 +803,23 @@ export class ChatListItemRenderer extends Disposable implements ITreeRenderer<Ch
|
||||
return result;
|
||||
}
|
||||
|
||||
private renderCommandButton(element: ChatTreeItem, commandButton: IChatCommandButton): IMarkdownRenderResult {
|
||||
const container = $('.chat-command-button');
|
||||
const disposables = new DisposableStore();
|
||||
const button = disposables.add(new Button(container, { ...defaultButtonStyles, supportIcons: true, title: commandButton.command.tooltip }));
|
||||
button.label = commandButton.command.title;
|
||||
button.enabled = !isResponseVM(element) || !element.isStale;
|
||||
|
||||
// TODO still need telemetry for command buttons
|
||||
disposables.add(button.onDidClick(() => this.commandService.executeCommand(commandButton.command.id, ...(commandButton.command.arguments ?? []))));
|
||||
return {
|
||||
dispose() {
|
||||
disposables.dispose();
|
||||
},
|
||||
element: container
|
||||
};
|
||||
}
|
||||
|
||||
private renderMarkdown(markdown: IMarkdownString, element: ChatTreeItem, templateData: IChatListItemTemplate, fillInIncompleteTokens = false): IMarkdownRenderResult {
|
||||
const disposables = new DisposableStore();
|
||||
let codeBlockIndex = 0;
|
||||
@@ -988,17 +987,6 @@ export class ChatAccessibilityProvider implements IListAccessibilityProvider<Cha
|
||||
private _getLabelWithCodeBlockCount(element: IChatResponseViewModel): string {
|
||||
const accessibleViewHint = this._accessibleViewService.getOpenAriaHint(AccessibilityVerbositySettingId.Chat);
|
||||
let label: string = '';
|
||||
let commandFollowUpInfo;
|
||||
const commandFollowupLength = element.commandFollowups?.length ?? 0;
|
||||
switch (commandFollowupLength) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
commandFollowUpInfo = localize('commandFollowUpInfo', "Command: {0}", element.commandFollowups![0].title);
|
||||
break;
|
||||
default:
|
||||
commandFollowUpInfo = localize('commandFollowUpInfoMany', "Commands: {0}", element.commandFollowups!.map(followup => followup.title).join(', '));
|
||||
}
|
||||
const fileTreeCount = element.response.value.filter((v) => !('value' in v))?.length ?? 0;
|
||||
let fileTreeCountHint = '';
|
||||
switch (fileTreeCount) {
|
||||
@@ -1023,7 +1011,7 @@ export class ChatAccessibilityProvider implements IListAccessibilityProvider<Cha
|
||||
label = accessibleViewHint ? localize('multiCodeBlockHint', "{0} {1} code blocks: {2}", fileTreeCountHint, codeBlockCount, element.response.asString(), accessibleViewHint) : localize('multiCodeBlock', "{0} {1} code blocks", fileTreeCountHint, codeBlockCount, element.response.asString());
|
||||
break;
|
||||
}
|
||||
return commandFollowUpInfo ? commandFollowUpInfo + ', ' + label : label;
|
||||
return label;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1360,6 +1348,14 @@ function isProgressMessageRenderData(item: IChatRenderData): item is IChatProgre
|
||||
return item && 'isAtEndOfResponse' in item;
|
||||
}
|
||||
|
||||
function isCommandButtonRenderData(item: IChatRenderData): item is IChatCommandButton {
|
||||
return item && 'kind' in item && item.kind === 'command';
|
||||
}
|
||||
|
||||
function isMarkdownRenderData(item: IChatRenderData): item is IChatResponseMarkdownRenderData {
|
||||
return item && 'renderedWordCount' in item;
|
||||
}
|
||||
|
||||
function onlyProgressMessagesAfterI(items: ReadonlyArray<IChatProgressRenderableResponseContent>, i: number): boolean {
|
||||
return items.slice(i).every(isProgressMessage);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import { ChatViewPane } from 'vs/workbench/contrib/chat/browser/chatViewPane';
|
||||
import { CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_SESSION, CONTEXT_RESPONSE_FILTERED } from 'vs/workbench/contrib/chat/common/chatContextKeys';
|
||||
import { IChatContributionService } from 'vs/workbench/contrib/chat/common/chatContributionService';
|
||||
import { ChatModelInitState, IChatModel } from 'vs/workbench/contrib/chat/common/chatModel';
|
||||
import { IChatReplyFollowup, IChatService } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatFollowup, IChatService } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { ChatViewModel, IChatResponseViewModel, isRequestVM, isResponseVM, isWelcomeVM } from 'vs/workbench/contrib/chat/common/chatViewModel';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IParsedChatRequest } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
@@ -292,7 +292,7 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
||||
}
|
||||
}
|
||||
|
||||
private async renderFollowups(items: IChatReplyFollowup[] | undefined, response?: IChatResponseViewModel): Promise<void> {
|
||||
private async renderFollowups(items: IChatFollowup[] | undefined, response?: IChatResponseViewModel): Promise<void> {
|
||||
this.inputPart.renderFollowups(items, response);
|
||||
|
||||
if (this.bodyDimension) {
|
||||
|
||||
@@ -418,20 +418,6 @@
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.interactive-session-followups .monaco-button {
|
||||
text-align: left;
|
||||
width: initial;
|
||||
}
|
||||
|
||||
.interactive-session-followups .monaco-button .codicon {
|
||||
margin-left: 0;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.interactive-item-container .interactive-response-followups .monaco-button {
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.interactive-session .interactive-input-part .interactive-input-followups {
|
||||
margin: 0px 20px;
|
||||
}
|
||||
@@ -626,3 +612,19 @@
|
||||
font-size: 14px;
|
||||
color: var(--vscode-debugIcon-startForeground) !important;
|
||||
}
|
||||
|
||||
.interactive-item-container .chat-command-button {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.interactive-item-container .chat-command-button .monaco-button {
|
||||
text-align: left;
|
||||
width: initial;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
.interactive-item-container .chat-command-button .monaco-button .codicon {
|
||||
margin-left: 0;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { ProviderResult } from 'vs/editor/common/languages';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IChatProgressResponseContent } from 'vs/workbench/contrib/chat/common/chatModel';
|
||||
import { IChatFollowup, IChatProgress, IChatReplyFollowup, IChatResponseErrorDetails } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatFollowup, IChatProgress, IChatResponseErrorDetails } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatRequestVariableValue } from 'vs/workbench/contrib/chat/common/chatVariables';
|
||||
|
||||
//#region agent service, commands etc
|
||||
@@ -35,7 +35,7 @@ export interface IChatAgent extends IChatAgentData {
|
||||
lastSlashCommands?: IChatAgentCommand[];
|
||||
provideSlashCommands(token: CancellationToken): Promise<IChatAgentCommand[]>;
|
||||
provideWelcomeMessage?(token: CancellationToken): ProviderResult<(string | IMarkdownString)[] | undefined>;
|
||||
provideSampleQuestions?(token: CancellationToken): ProviderResult<IChatReplyFollowup[] | undefined>;
|
||||
provideSampleQuestions?(token: CancellationToken): ProviderResult<IChatFollowup[] | undefined>;
|
||||
}
|
||||
|
||||
export interface IChatAgentCommand {
|
||||
|
||||
@@ -16,7 +16,7 @@ import { OffsetRange } from 'vs/editor/common/core/offsetRange';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IChatAgentCommand, IChatAgentData, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { ChatRequestTextPart, IParsedChatRequest, reviveParsedChatRequest } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
import { IChat, IChatAgentMarkdownContentWithVulnerability, IChatContent, IChatContentInlineReference, IChatContentReference, IChatFollowup, IChatMarkdownContent, IChatProgress, IChatProgressMessage, IChatReplyFollowup, IChatResponse, IChatResponseErrorDetails, IChatResponseProgressFileTreeData, IChatTreeData, IChatUsedContext, InteractiveSessionVoteDirection, isIUsedContext } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChat, IChatAgentMarkdownContentWithVulnerability, IChatContent, IChatContentInlineReference, IChatContentReference, IChatMarkdownContent, IChatProgress, IChatProgressMessage, IChatFollowup, IChatResponse, IChatResponseErrorDetails, IChatResponseProgressFileTreeData, IChatTreeData, IChatUsedContext, InteractiveSessionVoteDirection, isIUsedContext, IChatCommandButton } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatRequestVariableValue } from 'vs/workbench/contrib/chat/common/chatVariables';
|
||||
|
||||
export interface IChatRequestVariableData {
|
||||
@@ -33,7 +33,7 @@ export interface IChatRequestModel {
|
||||
readonly username: string;
|
||||
readonly avatarIconUri?: URI;
|
||||
readonly session: IChatModel;
|
||||
readonly message: IParsedChatRequest | IChatReplyFollowup;
|
||||
readonly message: IParsedChatRequest | IChatFollowup;
|
||||
readonly variableData: IChatRequestVariableData;
|
||||
readonly response?: IChatResponseModel;
|
||||
}
|
||||
@@ -43,7 +43,8 @@ export type IChatProgressResponseContent =
|
||||
| IChatAgentMarkdownContentWithVulnerability
|
||||
| IChatTreeData
|
||||
| IChatContentInlineReference
|
||||
| IChatProgressMessage;
|
||||
| IChatProgressMessage
|
||||
| IChatCommandButton;
|
||||
|
||||
export type IChatProgressRenderableResponseContent = Exclude<IChatProgressResponseContent, IChatContentInlineReference | IChatAgentMarkdownContentWithVulnerability>;
|
||||
|
||||
@@ -68,6 +69,8 @@ export interface IChatResponseModel {
|
||||
readonly response: IResponse;
|
||||
readonly isComplete: boolean;
|
||||
readonly isCanceled: boolean;
|
||||
/** A stale response is one that has been persisted and rehydrated, so e.g. Commands that have their arguments stored in the EH are gone. */
|
||||
readonly isStale: boolean;
|
||||
readonly vote: InteractiveSessionVoteDirection | undefined;
|
||||
readonly followups?: IChatFollowup[] | undefined;
|
||||
readonly errorDetails?: IChatResponseErrorDetails;
|
||||
@@ -159,7 +162,7 @@ export class Response implements IResponse {
|
||||
}
|
||||
|
||||
this._updateRepr(quiet);
|
||||
} else if (progress.kind === 'treeData' || progress.kind === 'inlineReference' || progress.kind === 'markdownVuln' || progress.kind === 'progressMessage') {
|
||||
} else {
|
||||
this._responseParts.push(progress);
|
||||
this._updateRepr(quiet);
|
||||
}
|
||||
@@ -171,6 +174,8 @@ export class Response implements IResponse {
|
||||
return '';
|
||||
} else if (part.kind === 'inlineReference') {
|
||||
return basename('uri' in part.inlineReference ? part.inlineReference.uri : part.inlineReference);
|
||||
} else if (part.kind === 'command') {
|
||||
return part.command.title;
|
||||
} else {
|
||||
return part.content.value;
|
||||
}
|
||||
@@ -255,6 +260,11 @@ export class ChatResponseModel extends Disposable implements IChatResponseModel
|
||||
return this._progressMessages;
|
||||
}
|
||||
|
||||
private _isStale: boolean = false;
|
||||
public get isStale(): boolean {
|
||||
return this._isStale;
|
||||
}
|
||||
|
||||
constructor(
|
||||
_response: IMarkdownString | ReadonlyArray<IMarkdownString | IChatResponseProgressFileTreeData | IChatContentInlineReference | IChatAgentMarkdownContentWithVulnerability>,
|
||||
public readonly session: ChatModel,
|
||||
@@ -268,6 +278,10 @@ export class ChatResponseModel extends Disposable implements IChatResponseModel
|
||||
followups?: ReadonlyArray<IChatFollowup>
|
||||
) {
|
||||
super();
|
||||
|
||||
// If we are creating a response with some existing content, consider it stale
|
||||
this._isStale = Array.isArray(_response) && (_response.length !== 0 || isMarkdownString(_response) && _response.value.length !== 0);
|
||||
|
||||
this._followups = followups ? [...followups] : undefined;
|
||||
this._response = new Response(_response);
|
||||
this._register(this._response.onDidChangeValue(() => this._onDidChange.fire()));
|
||||
@@ -368,7 +382,7 @@ export interface ISerializableChatRequestData {
|
||||
|
||||
export interface IExportableChatData {
|
||||
providerId: string;
|
||||
welcomeMessage: (string | IChatReplyFollowup[])[] | undefined;
|
||||
welcomeMessage: (string | IChatFollowup[])[] | undefined;
|
||||
requests: ISerializableChatRequestData[];
|
||||
requesterUsername: string;
|
||||
responderUsername: string;
|
||||
@@ -646,7 +660,7 @@ export class ChatModel extends Disposable implements IChatModel {
|
||||
|
||||
if (progress.kind === 'vulnerability') {
|
||||
request.response.updateContent({ kind: 'markdownVuln', content: { value: progress.content }, vulnerabilities: progress.vulnerabilities }, quiet);
|
||||
} else if (progress.kind === 'content' || progress.kind === 'markdownContent' || progress.kind === 'treeData' || progress.kind === 'inlineReference' || progress.kind === 'markdownVuln' || progress.kind === 'progressMessage') {
|
||||
} else if (progress.kind === 'content' || progress.kind === 'markdownContent' || progress.kind === 'treeData' || progress.kind === 'inlineReference' || progress.kind === 'markdownVuln' || progress.kind === 'progressMessage' || progress.kind === 'command') {
|
||||
request.response.updateContent(progress, quiet);
|
||||
} else if (progress.kind === 'usedContext' || progress.kind === 'reference') {
|
||||
request.response.applyReference(progress);
|
||||
@@ -772,12 +786,12 @@ export class ChatModel extends Disposable implements IChatModel {
|
||||
}
|
||||
}
|
||||
|
||||
export type IChatWelcomeMessageContent = IMarkdownString | IChatReplyFollowup[];
|
||||
export type IChatWelcomeMessageContent = IMarkdownString | IChatFollowup[];
|
||||
|
||||
export interface IChatWelcomeMessageModel {
|
||||
readonly id: string;
|
||||
readonly content: IChatWelcomeMessageContent[];
|
||||
readonly sampleQuestions: IChatReplyFollowup[];
|
||||
readonly sampleQuestions: IChatFollowup[];
|
||||
readonly username: string;
|
||||
readonly avatarIconUri?: URI;
|
||||
|
||||
@@ -794,7 +808,7 @@ export class ChatWelcomeMessageModel implements IChatWelcomeMessageModel {
|
||||
constructor(
|
||||
private readonly session: ChatModel,
|
||||
public readonly content: IChatWelcomeMessageContent[],
|
||||
public readonly sampleQuestions: IChatReplyFollowup[]
|
||||
public readonly sampleQuestions: IChatFollowup[]
|
||||
) {
|
||||
this._id = 'welcome_' + ChatWelcomeMessageModel.nextId++;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { Location, ProviderResult } from 'vs/editor/common/languages';
|
||||
import { Command, Location, ProviderResult } from 'vs/editor/common/languages';
|
||||
import { FileType } from 'vs/platform/files/common/files';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IChatAgentCommand, IChatAgentData } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
@@ -142,6 +142,11 @@ export interface IChatAgentMarkdownContentWithVulnerability {
|
||||
kind: 'markdownVuln';
|
||||
}
|
||||
|
||||
export interface IChatCommandButton {
|
||||
command: Command;
|
||||
kind: 'command';
|
||||
}
|
||||
|
||||
export type IChatProgress =
|
||||
| IChatContent
|
||||
| IChatMarkdownContent
|
||||
@@ -152,30 +157,21 @@ export type IChatProgress =
|
||||
| IChatContentReference
|
||||
| IChatContentInlineReference
|
||||
| IChatAgentDetection
|
||||
| IChatProgressMessage;
|
||||
| IChatProgressMessage
|
||||
| IChatCommandButton;
|
||||
|
||||
export interface IChatProvider {
|
||||
readonly id: string;
|
||||
prepareSession(token: CancellationToken): ProviderResult<IChat | undefined>;
|
||||
}
|
||||
|
||||
export interface IChatReplyFollowup {
|
||||
export interface IChatFollowup {
|
||||
kind: 'reply';
|
||||
message: string;
|
||||
title?: string;
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
export interface IChatResponseCommandFollowup {
|
||||
kind: 'command';
|
||||
commandId: string;
|
||||
args?: any[];
|
||||
title: string; // supports codicon strings
|
||||
when?: string;
|
||||
}
|
||||
|
||||
export type IChatFollowup = IChatReplyFollowup | IChatResponseCommandFollowup;
|
||||
|
||||
// Name has to match the one in vscode.d.ts for some reason
|
||||
export enum InteractiveSessionVoteDirection {
|
||||
Down = 0,
|
||||
@@ -218,12 +214,12 @@ export interface IChatTerminalAction {
|
||||
|
||||
export interface IChatCommandAction {
|
||||
kind: 'command';
|
||||
command: IChatResponseCommandFollowup;
|
||||
commandButton: IChatCommandButton;
|
||||
}
|
||||
|
||||
export interface IChatFollowupAction {
|
||||
kind: 'followUp';
|
||||
followup: IChatReplyFollowup;
|
||||
followup: IChatFollowup;
|
||||
}
|
||||
|
||||
export interface IChatBugReportAction {
|
||||
|
||||
@@ -235,8 +235,8 @@ export class ChatService extends Disposable implements IChatService {
|
||||
newFile: !!action.action.newFile
|
||||
});
|
||||
} else if (action.action.kind === 'command') {
|
||||
const command = CommandsRegistry.getCommand(action.action.command.commandId);
|
||||
const commandId = command ? action.action.command.commandId : 'INVALID';
|
||||
const command = CommandsRegistry.getCommand(action.action.commandButton.command.id);
|
||||
const commandId = command ? action.action.commandButton.command.id : 'INVALID';
|
||||
this.telemetryService.publicLog2<ChatCommandEvent, ChatCommandClassification>('interactiveSessionCommand', {
|
||||
providerId: action.providerId,
|
||||
commandId
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IChatAgentCommand, IChatAgentData } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { ChatModelInitState, IChatModel, IChatRequestModel, IChatResponseModel, IChatWelcomeMessageContent, IResponse } from 'vs/workbench/contrib/chat/common/chatModel';
|
||||
import { IParsedChatRequest } from 'vs/workbench/contrib/chat/common/chatParserTypes';
|
||||
import { IChatContentReference, IChatProgressMessage, IChatReplyFollowup, IChatResponseCommandFollowup, IChatResponseErrorDetails, IChatResponseProgressFileTreeData, IChatUsedContext, InteractiveSessionVoteDirection } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatContentReference, IChatProgressMessage, IChatFollowup, IChatResponseErrorDetails, IChatResponseProgressFileTreeData, IChatUsedContext, InteractiveSessionVoteDirection, IChatCommandButton } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { countWords } from 'vs/workbench/contrib/chat/common/chatWordCounter';
|
||||
|
||||
export function isRequestVM(item: unknown): item is IChatRequestViewModel {
|
||||
@@ -60,7 +60,7 @@ export interface IChatRequestViewModel {
|
||||
readonly dataId: string;
|
||||
readonly username: string;
|
||||
readonly avatarIconUri?: URI;
|
||||
readonly message: IParsedChatRequest | IChatReplyFollowup;
|
||||
readonly message: IParsedChatRequest | IChatFollowup;
|
||||
readonly messageText: string;
|
||||
currentRenderedHeight: number | undefined;
|
||||
}
|
||||
@@ -88,7 +88,7 @@ export interface IChatProgressMessageRenderData {
|
||||
isLast: boolean;
|
||||
}
|
||||
|
||||
export type IChatRenderData = IChatResponseProgressFileTreeData | IChatResponseMarkdownRenderData | IChatProgressMessageRenderData;
|
||||
export type IChatRenderData = IChatResponseProgressFileTreeData | IChatResponseMarkdownRenderData | IChatProgressMessageRenderData | IChatCommandButton;
|
||||
export interface IChatResponseRenderData {
|
||||
renderedParts: IChatRenderData[];
|
||||
}
|
||||
@@ -118,9 +118,9 @@ export interface IChatResponseViewModel {
|
||||
readonly progressMessages: ReadonlyArray<IChatProgressMessage>;
|
||||
readonly isComplete: boolean;
|
||||
readonly isCanceled: boolean;
|
||||
readonly isStale: boolean;
|
||||
readonly vote: InteractiveSessionVoteDirection | undefined;
|
||||
readonly replyFollowups?: IChatReplyFollowup[];
|
||||
readonly commandFollowups?: IChatResponseCommandFollowup[];
|
||||
readonly replyFollowups?: IChatFollowup[];
|
||||
readonly errorDetails?: IChatResponseErrorDetails;
|
||||
readonly contentUpdateTimings?: IChatLiveUpdateData;
|
||||
renderData?: IChatResponseRenderData;
|
||||
@@ -331,11 +331,7 @@ export class ChatResponseViewModel extends Disposable implements IChatResponseVi
|
||||
}
|
||||
|
||||
get replyFollowups() {
|
||||
return this._model.followups?.filter((f): f is IChatReplyFollowup => f.kind === 'reply');
|
||||
}
|
||||
|
||||
get commandFollowups() {
|
||||
return this._model.followups?.filter((f): f is IChatResponseCommandFollowup => f.kind === 'command');
|
||||
return this._model.followups?.filter((f): f is IChatFollowup => f.kind === 'reply');
|
||||
}
|
||||
|
||||
get errorDetails() {
|
||||
@@ -350,6 +346,10 @@ export class ChatResponseViewModel extends Disposable implements IChatResponseVi
|
||||
return this._model.requestId;
|
||||
}
|
||||
|
||||
get isStale() {
|
||||
return this._model.isStale;
|
||||
}
|
||||
|
||||
renderData: IChatResponseRenderData | undefined = undefined;
|
||||
agentAvatarHasBeenRendered?: boolean;
|
||||
currentRenderedHeight: number | undefined;
|
||||
@@ -436,6 +436,6 @@ export interface IChatWelcomeMessageViewModel {
|
||||
readonly username: string;
|
||||
readonly avatarIconUri?: URI;
|
||||
readonly content: IChatWelcomeMessageContent[];
|
||||
readonly sampleQuestions: IChatReplyFollowup[];
|
||||
readonly sampleQuestions: IChatFollowup[];
|
||||
currentRenderedHeight?: number;
|
||||
}
|
||||
|
||||
@@ -3,66 +3,65 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./inlineChat';
|
||||
import { DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IActiveCodeEditor, ICodeEditor, IDiffEditorConstructionOptions } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditorLayoutInfo, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/browser/zoneWidget';
|
||||
import { CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_VISIBLE, MENU_INLINE_CHAT_INPUT, MENU_INLINE_CHAT_WIDGET_STATUS, MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE, CTX_INLINE_CHAT_MESSAGE_CROP_STATE, IInlineChatSlashCommand, MENU_INLINE_CHAT_WIDGET_FEEDBACK, ACTION_REGENERATE_RESPONSE, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_INNER_CURSOR_START, CTX_INLINE_CHAT_INNER_CURSOR_END, CTX_INLINE_CHAT_RESPONSE_FOCUSED, ACTION_ACCEPT_CHANGES, MENU_INLINE_CHAT_WIDGET } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model';
|
||||
import { Dimension, addDisposableListener, getActiveElement, getTotalHeight, getTotalWidth, h, reset } from 'vs/base/browser/dom';
|
||||
import { Emitter, Event, MicrotaskEmitter } from 'vs/base/common/event';
|
||||
import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration';
|
||||
import { ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions';
|
||||
import { SnippetController2 } from 'vs/editor/contrib/snippet/browser/snippetController2';
|
||||
import { IModelService } from 'vs/editor/common/services/model';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
|
||||
import { HiddenItemStrategy, MenuWorkbenchToolBar } from 'vs/platform/actions/browser/toolbar';
|
||||
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
|
||||
import { SuggestController } from 'vs/editor/contrib/suggest/browser/suggestController';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { DEFAULT_FONT_FAMILY } from 'vs/workbench/browser/style';
|
||||
import { CompletionItem, CompletionItemInsertTextRule, CompletionItemKind, CompletionItemProvider, CompletionList, ProviderResult } from 'vs/editor/common/languages';
|
||||
import { ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { FileKind } from 'vs/platform/files/common/files';
|
||||
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
|
||||
import { LanguageSelector } from 'vs/editor/common/languageSelector';
|
||||
import { asRange, invertLineRange } from 'vs/workbench/contrib/inlineChat/browser/utils';
|
||||
import { ICodeEditorViewState, ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { LineRange } from 'vs/editor/common/core/lineRange';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
|
||||
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
|
||||
import { ExpansionState, HunkData } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession';
|
||||
import { renderFormattedText } from 'vs/base/browser/formattedTextRenderer';
|
||||
import * as aria from 'vs/base/browser/ui/aria/aria';
|
||||
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
|
||||
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
|
||||
import { Emitter, Event, MicrotaskEmitter } from 'vs/base/common/event';
|
||||
import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { Lazy } from 'vs/base/common/lazy';
|
||||
import { DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { assertType } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import 'vs/css!./inlineChat';
|
||||
import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration';
|
||||
import { IActiveCodeEditor, ICodeEditor, IDiffEditorConstructionOptions } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions';
|
||||
import { ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { EmbeddedCodeEditorWidget, EmbeddedDiffEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
|
||||
import { EditorLayoutInfo, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { LineRange } from 'vs/editor/common/core/lineRange';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { ICodeEditorViewState, ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { LanguageSelector } from 'vs/editor/common/languageSelector';
|
||||
import { CompletionItem, CompletionItemInsertTextRule, CompletionItemKind, CompletionItemProvider, CompletionList, ProviderResult } from 'vs/editor/common/languages';
|
||||
import { IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model';
|
||||
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
|
||||
import { IModelService } from 'vs/editor/common/services/model';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { SnippetController2 } from 'vs/editor/contrib/snippet/browser/snippetController2';
|
||||
import { SuggestController } from 'vs/editor/contrib/suggest/browser/suggestController';
|
||||
import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/browser/zoneWidget';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { IWorkbenchButtonBarOptions, MenuWorkbenchButtonBar } from 'vs/platform/actions/browser/buttonbar';
|
||||
import { SlashCommandContentWidget } from 'vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget';
|
||||
import { HiddenItemStrategy, MenuWorkbenchToolBar } from 'vs/platform/actions/browser/toolbar';
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { FileKind } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { editorBackground, editorForeground, inputBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { DEFAULT_FONT_FAMILY } from 'vs/workbench/browser/style';
|
||||
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
|
||||
import { IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
|
||||
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
|
||||
import { assertType } from 'vs/base/common/types';
|
||||
import { renderFormattedText } from 'vs/base/browser/formattedTextRenderer';
|
||||
import { IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { ChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatOptions';
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { editorForeground, inputBackground, editorBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { Lazy } from 'vs/base/common/lazy';
|
||||
import { ChatResponseViewModel } from 'vs/workbench/contrib/chat/common/chatViewModel';
|
||||
import { ChatModel, ChatResponseModel } from 'vs/workbench/contrib/chat/common/chatModel';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { ChatListItemRenderer, IChatListItemRendererOptions, IChatRendererDelegate } from 'vs/workbench/contrib/chat/browser/chatListRenderer';
|
||||
import { IUntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { IChatFollowup } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { ChatFollowups } from 'vs/workbench/contrib/chat/browser/chatFollowups';
|
||||
import { ChatListItemRenderer, IChatListItemRendererOptions, IChatRendererDelegate } from 'vs/workbench/contrib/chat/browser/chatListRenderer';
|
||||
import { ChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatOptions';
|
||||
import { SlashCommandContentWidget } from 'vs/workbench/contrib/chat/browser/chatSlashCommandContentWidget';
|
||||
import { IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
|
||||
import { ChatModel, ChatResponseModel } from 'vs/workbench/contrib/chat/common/chatModel';
|
||||
import { ChatResponseViewModel } from 'vs/workbench/contrib/chat/common/chatViewModel';
|
||||
import { ExpansionState, HunkData } from 'vs/workbench/contrib/inlineChat/browser/inlineChatSession';
|
||||
import { asRange, invertLineRange } from 'vs/workbench/contrib/inlineChat/browser/utils';
|
||||
import { ACTION_ACCEPT_CHANGES, ACTION_REGENERATE_RESPONSE, ACTION_VIEW_IN_CHAT, CTX_INLINE_CHAT_EMPTY, CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_INNER_CURSOR_END, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_INNER_CURSOR_START, CTX_INLINE_CHAT_MESSAGE_CROP_STATE, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, CTX_INLINE_CHAT_RESPONSE_FOCUSED, CTX_INLINE_CHAT_VISIBLE, IInlineChatFollowup, IInlineChatSlashCommand, MENU_INLINE_CHAT_INPUT, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_FEEDBACK, MENU_INLINE_CHAT_WIDGET_MARKDOWN_MESSAGE, MENU_INLINE_CHAT_WIDGET_STATUS } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { IUntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel';
|
||||
|
||||
const defaultAriaLabel = localize('aria-label', "Inline Chat Input");
|
||||
|
||||
@@ -631,9 +630,9 @@ export class InlineChatWidget {
|
||||
return resultingAppender;
|
||||
}
|
||||
|
||||
updateFollowUps(items: IChatFollowup[], onFollowup: (followup: IChatFollowup) => void): void;
|
||||
updateFollowUps(items: IInlineChatFollowup[], onFollowup: (followup: IInlineChatFollowup) => void): void;
|
||||
updateFollowUps(items: undefined): void;
|
||||
updateFollowUps(items: IChatFollowup[] | undefined, onFollowup?: ((followup: IChatFollowup) => void)) {
|
||||
updateFollowUps(items: IInlineChatFollowup[] | undefined, onFollowup?: ((followup: IInlineChatFollowup) => void)) {
|
||||
this._followUpDisposables.clear();
|
||||
this._elements.followUps.classList.toggle('hidden', !items || items.length === 0);
|
||||
reset(this._elements.followUps);
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { ISelection } from 'vs/editor/common/core/selection';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { ProviderResult, TextEdit, WorkspaceEdit } from 'vs/editor/common/languages';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -20,7 +20,6 @@ import { IProgress } from 'vs/platform/progress/common/progress';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { diffInserted, diffRemoved, editorHoverHighlight, editorWidgetBackground, editorWidgetBorder, focusBorder, inputBackground, inputPlaceholderForeground, registerColor, transparent, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { Extensions as ExtensionsMigration, IConfigurationMigrationRegistry } from 'vs/workbench/common/configuration';
|
||||
import { IChatFollowup } from 'vs/workbench/contrib/chat/common/chatService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export interface IInlineChatSlashCommand {
|
||||
@@ -98,6 +97,23 @@ export const enum InlineChatResponseFeedbackKind {
|
||||
Bug = 4
|
||||
}
|
||||
|
||||
export interface IInlineChatReplyFollowup {
|
||||
kind: 'reply';
|
||||
message: string;
|
||||
title?: string;
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
export interface IInlineChatCommandFollowup {
|
||||
kind: 'command';
|
||||
commandId: string;
|
||||
args?: any[];
|
||||
title: string; // supports codicon strings
|
||||
when?: string;
|
||||
}
|
||||
|
||||
export type IInlineChatFollowup = IInlineChatReplyFollowup | IInlineChatCommandFollowup;
|
||||
|
||||
export interface IInlineChatSessionProvider {
|
||||
|
||||
debugName: string;
|
||||
@@ -108,7 +124,7 @@ export interface IInlineChatSessionProvider {
|
||||
|
||||
provideResponse(item: IInlineChatSession, request: IInlineChatRequest, progress: IProgress<IInlineChatProgressItem>, token: CancellationToken): ProviderResult<IInlineChatResponse>;
|
||||
|
||||
provideFollowups?(session: IInlineChatSession, response: IInlineChatResponse, token: CancellationToken): ProviderResult<IChatFollowup[]>;
|
||||
provideFollowups?(session: IInlineChatSession, response: IInlineChatResponse, token: CancellationToken): ProviderResult<IInlineChatFollowup[]>;
|
||||
|
||||
handleInlineChatResponseFeedback?(session: IInlineChatSession, response: IInlineChatResponse, kind: InlineChatResponseFeedbackKind): void;
|
||||
}
|
||||
|
||||
+12
-13
@@ -150,19 +150,10 @@ declare module 'vscode' {
|
||||
provideSubCommands(token: CancellationToken): ProviderResult<ChatAgentSubCommand[]>;
|
||||
}
|
||||
|
||||
// TODO@API This should become a progress type, and use vscode.Command
|
||||
// TODO@API what's the when-property for? how about not returning it in the first place?
|
||||
export interface ChatAgentCommandFollowup {
|
||||
commandId: string;
|
||||
args?: any[];
|
||||
title: string; // supports codicon strings
|
||||
when?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A followup question suggested by the model.
|
||||
*/
|
||||
export interface ChatAgentReplyFollowup {
|
||||
export interface ChatAgentFollowup {
|
||||
/**
|
||||
* The message to send to the chat.
|
||||
*/
|
||||
@@ -179,8 +170,6 @@ declare module 'vscode' {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export type ChatAgentFollowup = ChatAgentCommandFollowup | ChatAgentReplyFollowup;
|
||||
|
||||
/**
|
||||
* Will be invoked once after each request to get suggested followup questions to show the user. The user can click the followup to send it to the chat.
|
||||
*/
|
||||
@@ -287,6 +276,8 @@ declare module 'vscode' {
|
||||
|
||||
anchor(value: Uri | Location, title?: string): ChatAgentResponseStream;
|
||||
|
||||
button(command: Command): ChatAgentResponseStream;
|
||||
|
||||
// TODO@API this influences the rendering, it inserts new lines which is likely a bug
|
||||
progress(value: string): ChatAgentResponseStream;
|
||||
|
||||
@@ -347,7 +338,8 @@ declare module 'vscode' {
|
||||
export type ChatAgentContentProgress =
|
||||
| ChatAgentContent
|
||||
| ChatAgentFileTree
|
||||
| ChatAgentInlineContentReference;
|
||||
| ChatAgentInlineContentReference
|
||||
| ChatAgentCommandButton;
|
||||
|
||||
/**
|
||||
* @deprecated use ChatAgentResponseStream instead
|
||||
@@ -394,6 +386,13 @@ declare module 'vscode' {
|
||||
title?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a {@link Command command} as a button in the chat response.
|
||||
*/
|
||||
export interface ChatAgentCommandButton {
|
||||
command: Command;
|
||||
}
|
||||
|
||||
/**
|
||||
* A piece of the chat response's content. Will be merged with other progress pieces as needed, and rendered as markdown.
|
||||
*/
|
||||
|
||||
@@ -113,7 +113,7 @@ declare module 'vscode' {
|
||||
export interface ChatAgentCommandAction {
|
||||
// eslint-disable-next-line local/vscode-dts-string-type-literals
|
||||
kind: 'command';
|
||||
command: ChatAgentCommandFollowup;
|
||||
commandButton: ChatAgentCommandButton;
|
||||
}
|
||||
|
||||
export interface ChatAgentSessionFollowupAction {
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ declare module 'vscode' {
|
||||
|
||||
export interface ChatAgentWelcomeMessageProvider {
|
||||
provideWelcomeMessage(token: CancellationToken): ProviderResult<ChatAgentWelcomeMessageContent[]>;
|
||||
provideSampleQuestions?(token: CancellationToken): ProviderResult<ChatAgentReplyFollowup[]>;
|
||||
provideSampleQuestions?(token: CancellationToken): ProviderResult<ChatAgentFollowup[]>;
|
||||
}
|
||||
|
||||
export interface ChatAgent2<TResult extends ChatAgentResult2> {
|
||||
|
||||
+1
-1
@@ -121,7 +121,7 @@ declare module 'vscode' {
|
||||
inputPlaceholder?: string;
|
||||
}
|
||||
|
||||
export type InteractiveWelcomeMessageContent = string | MarkdownString | ChatAgentReplyFollowup[];
|
||||
export type InteractiveWelcomeMessageContent = string | MarkdownString | ChatAgentFollowup[];
|
||||
|
||||
export interface InteractiveSessionProvider<S extends InteractiveSession = InteractiveSession> {
|
||||
prepareSession(token: CancellationToken): ProviderResult<S>;
|
||||
|
||||
Reference in New Issue
Block a user