Path: blob/main/src/vs/workbench/contrib/chat/browser/chat.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { IMouseWheelEvent } from '../../../../base/browser/mouseEvent.js';6import { Event } from '../../../../base/common/event.js';7import { IDisposable } from '../../../../base/common/lifecycle.js';8import { URI } from '../../../../base/common/uri.js';9import { ICodeEditor } from '../../../../editor/browser/editorBrowser.js';10import { Selection } from '../../../../editor/common/core/selection.js';11import { EditDeltaInfo } from '../../../../editor/common/textModelEditSource.js';12import { MenuId } from '../../../../platform/actions/common/actions.js';13import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';14import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';15import { IWorkbenchLayoutService } from '../../../services/layout/browser/layoutService.js';16import { IViewsService } from '../../../services/views/common/viewsService.js';17import { IChatAgentCommand, IChatAgentData } from '../common/chatAgents.js';18import { IChatResponseModel } from '../common/chatModel.js';19import { IParsedChatRequest } from '../common/chatParserTypes.js';20import { CHAT_PROVIDER_ID } from '../common/chatParticipantContribTypes.js';21import { IChatElicitationRequest, IChatSendRequestOptions } from '../common/chatService.js';22import { IChatRequestViewModel, IChatResponseViewModel, IChatViewModel } from '../common/chatViewModel.js';23import { ChatAgentLocation, ChatModeKind } from '../common/constants.js';24import { ChatAttachmentModel } from './chatAttachmentModel.js';25import { ChatInputPart } from './chatInputPart.js';26import { ChatViewPane } from './chatViewPane.js';27import { IChatViewState, IChatWidgetContrib } from './chatWidget.js';28import { ICodeBlockActionContext } from './codeBlockPart.js';2930export const IChatWidgetService = createDecorator<IChatWidgetService>('chatWidgetService');3132export interface IChatWidgetService {3334readonly _serviceBrand: undefined;3536/**37* Returns the most recently focused widget if any.38*/39readonly lastFocusedWidget: IChatWidget | undefined;4041readonly onDidAddWidget: Event<IChatWidget>;4243getAllWidgets(): ReadonlyArray<IChatWidget>;44getWidgetByInputUri(uri: URI): IChatWidget | undefined;45getWidgetBySessionId(sessionId: string): IChatWidget | undefined;46getWidgetsByLocations(location: ChatAgentLocation): ReadonlyArray<IChatWidget>;47}4849export async function showChatView(viewsService: IViewsService): Promise<IChatWidget | undefined> {50return (await viewsService.openView<ChatViewPane>(ChatViewId))?.widget;51}5253export function showCopilotView(viewsService: IViewsService, layoutService: IWorkbenchLayoutService): Promise<IChatWidget | undefined> {5455// Ensure main window is in front56if (layoutService.activeContainer !== layoutService.mainContainer) {57layoutService.mainContainer.focus();58}5960return showChatView(viewsService);61}6263export const IQuickChatService = createDecorator<IQuickChatService>('quickChatService');64export interface IQuickChatService {65readonly _serviceBrand: undefined;66readonly onDidClose: Event<void>;67readonly enabled: boolean;68readonly focused: boolean;69toggle(options?: IQuickChatOpenOptions): void;70focus(): void;71open(options?: IQuickChatOpenOptions): void;72close(): void;73openInChatView(): void;74}7576export interface IQuickChatOpenOptions {77/**78* The query for quick chat.79*/80query: string;81/**82* Whether the query is partial and will await more input from the user.83*/84isPartialQuery?: boolean;85/**86* An optional selection range to apply to the query text box.87*/88selection?: Selection;89}9091export const IChatAccessibilityService = createDecorator<IChatAccessibilityService>('chatAccessibilityService');92export interface IChatAccessibilityService {93readonly _serviceBrand: undefined;94acceptRequest(): number;95acceptResponse(response: IChatResponseViewModel | string | undefined, requestId: number, isVoiceInput?: boolean): void;96acceptElicitation(message: IChatElicitationRequest): void;97}9899export interface IChatCodeBlockInfo {100readonly ownerMarkdownPartId: string;101readonly codeBlockIndex: number;102readonly elementId: string;103readonly uri: URI | undefined;104readonly uriPromise: Promise<URI | undefined>;105codemapperUri: URI | undefined;106readonly isStreaming: boolean;107readonly chatSessionId: string;108focus(): void;109readonly languageId?: string | undefined;110readonly editDeltaInfo?: EditDeltaInfo | undefined;111}112113export interface IChatFileTreeInfo {114treeDataId: string;115treeIndex: number;116focus(): void;117}118119export type ChatTreeItem = IChatRequestViewModel | IChatResponseViewModel;120121export interface IChatListItemRendererOptions {122readonly renderStyle?: 'compact' | 'minimal';123readonly noHeader?: boolean;124readonly noFooter?: boolean;125readonly editableCodeBlock?: boolean;126readonly renderDetectedCommandsWithRequest?: boolean;127readonly restorable?: boolean;128readonly editable?: boolean;129readonly renderTextEditsAsSummary?: (uri: URI) => boolean;130readonly referencesExpandedWhenEmptyResponse?: boolean | ((mode: ChatModeKind) => boolean);131readonly progressMessageAtBottomOfResponse?: boolean | ((mode: ChatModeKind) => boolean);132}133134export interface IChatWidgetViewOptions {135autoScroll?: boolean | ((mode: ChatModeKind) => boolean);136renderInputOnTop?: boolean;137renderFollowups?: boolean;138renderStyle?: 'compact' | 'minimal';139supportsFileReferences?: boolean;140filter?: (item: ChatTreeItem) => boolean;141rendererOptions?: IChatListItemRendererOptions;142menus?: {143/**144* The menu that is inside the input editor, use for send, dictation145*/146executeToolbar?: MenuId;147/**148* The menu that next to the input editor, use for close, config etc149*/150inputSideToolbar?: MenuId;151/**152* The telemetry source for all commands of this widget153*/154telemetrySource?: string;155};156defaultElementHeight?: number;157editorOverflowWidgetsDomNode?: HTMLElement;158enableImplicitContext?: boolean;159enableWorkingSet?: 'explicit' | 'implicit';160supportsChangingModes?: boolean;161dndContainer?: HTMLElement;162}163164export interface IChatViewViewContext {165viewId: string;166}167168export interface IChatResourceViewContext {169isQuickChat?: boolean;170isInlineChat?: boolean;171}172173export type IChatWidgetViewContext = IChatViewViewContext | IChatResourceViewContext | {};174175export interface IChatAcceptInputOptions {176noCommandDetection?: boolean;177isVoiceInput?: boolean;178}179180export interface IChatWidget {181readonly domNode: HTMLElement;182readonly onDidChangeViewModel: Event<void>;183readonly onDidAcceptInput: Event<void>;184readonly onDidHide: Event<void>;185readonly onDidShow: Event<void>;186readonly onDidSubmitAgent: Event<{ agent: IChatAgentData; slashCommand?: IChatAgentCommand }>;187readonly onDidChangeAgent: Event<{ agent: IChatAgentData; slashCommand?: IChatAgentCommand }>;188readonly onDidChangeParsedInput: Event<void>;189readonly location: ChatAgentLocation;190readonly viewContext: IChatWidgetViewContext;191readonly viewModel: IChatViewModel | undefined;192readonly inputEditor: ICodeEditor;193readonly supportsFileReferences: boolean;194readonly parsedInput: IParsedChatRequest;195readonly lockedAgentId: string | undefined;196lastSelectedAgent: IChatAgentData | undefined;197readonly scopedContextKeyService: IContextKeyService;198readonly input: ChatInputPart;199readonly attachmentModel: ChatAttachmentModel;200201readonly supportsChangingModes: boolean;202203getContrib<T extends IChatWidgetContrib>(id: string): T | undefined;204reveal(item: ChatTreeItem): void;205focus(item: ChatTreeItem): void;206getSibling(item: ChatTreeItem, type: 'next' | 'previous'): ChatTreeItem | undefined;207getFocus(): ChatTreeItem | undefined;208setInput(query?: string): void;209getInput(): string;210refreshParsedInput(): void;211logInputHistory(): void;212acceptInput(query?: string, options?: IChatAcceptInputOptions): Promise<IChatResponseModel | undefined>;213startEditing(requestId: string): void;214finishedEditing(completedEdit?: boolean): void;215rerunLastRequest(): Promise<void>;216setInputPlaceholder(placeholder: string): void;217resetInputPlaceholder(): void;218focusLastMessage(): void;219focusInput(): void;220hasInputFocus(): boolean;221getModeRequestOptions(): Partial<IChatSendRequestOptions>;222getCodeBlockInfoForEditor(uri: URI): IChatCodeBlockInfo | undefined;223getCodeBlockInfosForResponse(response: IChatResponseViewModel): IChatCodeBlockInfo[];224getFileTreeInfosForResponse(response: IChatResponseViewModel): IChatFileTreeInfo[];225getLastFocusedFileTreeForResponse(response: IChatResponseViewModel): IChatFileTreeInfo | undefined;226clear(): void;227/**228* Wait for this widget to have a VM with a fully initialized model and editing session.229* Sort of a hack. See https://github.com/microsoft/vscode/issues/247484230*/231waitForReady(): Promise<void>;232getViewState(): IChatViewState;233lockToCodingAgent(name: string, displayName: string, agentId?: string): void;234235delegateScrollFromMouseWheelEvent(event: IMouseWheelEvent): void;236}237238239export interface ICodeBlockActionContextProvider {240getCodeBlockContext(editor?: ICodeEditor): ICodeBlockActionContext | undefined;241}242243export const IChatCodeBlockContextProviderService = createDecorator<IChatCodeBlockContextProviderService>('chatCodeBlockContextProviderService');244export interface IChatCodeBlockContextProviderService {245readonly _serviceBrand: undefined;246readonly providers: ICodeBlockActionContextProvider[];247registerProvider(provider: ICodeBlockActionContextProvider, id: string): IDisposable;248}249250export const ChatViewId = `workbench.panel.chat.view.${CHAT_PROVIDER_ID}`;251252253