Path: blob/main/src/vs/workbench/contrib/chat/common/chatSessionsService.ts
5272 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 { CancellationToken } from '../../../../base/common/cancellation.js';6import { Event, IWaitUntil } from '../../../../base/common/event.js';7import { IMarkdownString } from '../../../../base/common/htmlContent.js';8import { IDisposable } from '../../../../base/common/lifecycle.js';9import { IObservable } from '../../../../base/common/observable.js';10import { ThemeIcon } from '../../../../base/common/themables.js';11import { URI } from '../../../../base/common/uri.js';12import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';13import { IChatAgentAttachmentCapabilities, IChatAgentRequest } from './participants/chatAgents.js';14import { IChatEditingSession } from './editing/chatEditingService.js';15import { IChatModel, IChatRequestVariableData, ISerializableChatModelInputState } from './model/chatModel.js';16import { IChatProgress, IChatService, IChatSessionTiming } from './chatService/chatService.js';17import { Target } from './promptSyntax/service/promptsService.js';1819export const enum ChatSessionStatus {20Failed = 0,21Completed = 1,22InProgress = 2,23NeedsInput = 324}2526export interface IChatSessionCommandContribution {27name: string;28description: string;29when?: string;30}3132export interface IChatSessionProviderOptionItem {33id: string;34name: string;35description?: string;36locked?: boolean;37icon?: ThemeIcon;38default?: boolean;39// [key: string]: any;40}4142export interface IChatSessionProviderOptionGroupCommand {43command: string;44title: string;45tooltip?: string;46arguments?: unknown[];47}4849export interface IChatSessionProviderOptionGroup {50id: string;51name: string;52description?: string;53items: IChatSessionProviderOptionItem[];54searchable?: boolean;55onSearch?: (query: string, token: CancellationToken) => Thenable<IChatSessionProviderOptionItem[]>;56/**57* A context key expression that controls visibility of this option group picker.58* When specified, the picker is only visible when the expression evaluates to true.59* The expression can reference other option group values via `chatSessionOption.<groupId>`.60* Example: `"chatSessionOption.models == 'gpt-4'"`61*/62when?: string;63icon?: ThemeIcon;64/**65* Custom commands to show in the option group's picker UI.66* These will be shown in a separate section at the end of the picker.67*/68commands?: IChatSessionProviderOptionGroupCommand[];69}7071export interface IChatSessionsExtensionPoint {72readonly type: string;73readonly name: string;74readonly displayName: string;75readonly description: string;76readonly when?: string;77readonly icon?: string | { light: string; dark: string };78readonly order?: number;79readonly alternativeIds?: string[];80readonly welcomeTitle?: string;81readonly welcomeMessage?: string;82readonly welcomeTips?: string;83readonly inputPlaceholder?: string;84readonly capabilities?: IChatAgentAttachmentCapabilities;85readonly commands?: IChatSessionCommandContribution[];86readonly canDelegate?: boolean;87readonly isReadOnly?: boolean;88/**89* When set, the chat session will show a filtered mode picker with custom agents90* that have a matching `target` property. This enables contributed chat sessions91* to reuse the standard agent/mode dropdown with filtered custom agents.92* Custom agents without a `target` property are also shown in all filtered lists93*/94readonly customAgentTarget?: Target;95}9697export interface IChatSessionItem {98resource: URI;99label: string;100iconPath?: ThemeIcon;101badge?: string | IMarkdownString;102description?: string | IMarkdownString;103status?: ChatSessionStatus;104tooltip?: string | IMarkdownString;105timing: IChatSessionTiming;106changes?: {107files: number;108insertions: number;109deletions: number;110} | readonly IChatSessionFileChange[] | readonly IChatSessionFileChange2[];111archived?: boolean;112metadata?: { readonly [key: string]: unknown };113}114115export interface IChatSessionFileChange {116modifiedUri: URI;117originalUri?: URI;118insertions: number;119deletions: number;120}121122export interface IChatSessionFileChange2 {123readonly uri: URI;124readonly originalUri?: URI;125readonly modifiedUri?: URI;126readonly insertions: number;127readonly deletions: number;128}129130export type IChatSessionHistoryItem = {131id?: string;132type: 'request';133prompt: string;134participant: string;135command?: string;136variableData?: IChatRequestVariableData;137} | {138type: 'response';139parts: IChatProgress[];140participant: string;141};142143/**144* The session type used for local agent chat sessions.145*/146export const localChatSessionType = 'local';147148/**149* The option ID used for selecting the agent in chat sessions.150*/151export const agentOptionId = 'agent';152153export interface IChatSession extends IDisposable {154readonly onWillDispose: Event<void>;155156readonly sessionResource: URI;157158readonly history: readonly IChatSessionHistoryItem[];159160/**161* Session options as key-value pairs. Keys correspond to option group IDs (e.g., 'models', 'subagents')162* and values are either the selected option item IDs (string) or full option items (for locked state).163*/164readonly options?: Record<string, string | IChatSessionProviderOptionItem>;165166readonly progressObs?: IObservable<IChatProgress[]>;167readonly isCompleteObs?: IObservable<boolean>;168readonly interruptActiveResponseCallback?: () => Promise<boolean>;169170/**171* Editing session transferred from a previously-untitled chat session in `onDidCommitChatSessionItem`.172*/173transferredState?: {174editingSession: IChatEditingSession | undefined;175inputState: ISerializableChatModelInputState | undefined;176};177178requestHandler?: (179request: IChatAgentRequest,180progress: (progress: IChatProgress[]) => void,181// eslint-disable-next-line @typescript-eslint/no-explicit-any182history: any[], // TODO: Nail down types183token: CancellationToken184) => Promise<void>;185}186187export interface IChatSessionContentProvider {188provideChatSessionContent(sessionResource: URI, token: CancellationToken): Promise<IChatSession>;189}190191export interface IChatSessionItemController {192193readonly onDidChangeChatSessionItems: Event<void>;194195get items(): readonly IChatSessionItem[];196197refresh(token: CancellationToken): Promise<void>;198}199200/**201* Event fired when session options need to be sent to the extension.202* Extends IWaitUntil to allow listeners to register async work that will be awaited.203*/204export interface IChatSessionOptionsWillNotifyExtensionEvent extends IWaitUntil {205readonly sessionResource: URI;206readonly updates: ReadonlyArray<{ optionId: string; value: string | IChatSessionProviderOptionItem }>;207}208209export interface IChatSessionsService {210readonly _serviceBrand: undefined;211212// #region Chat session item provider support213readonly onDidChangeItemsProviders: Event<{ readonly chatSessionType: string }>;214readonly onDidChangeSessionItems: Event<{ readonly chatSessionType: string }>;215216readonly onDidChangeAvailability: Event<void>;217readonly onDidChangeInProgress: Event<void>;218219getChatSessionContribution(chatSessionType: string): IChatSessionsExtensionPoint | undefined;220221registerChatSessionItemController(chatSessionType: string, controller: IChatSessionItemController): IDisposable;222activateChatSessionItemProvider(chatSessionType: string): Promise<void>;223224getAllChatSessionContributions(): IChatSessionsExtensionPoint[];225getIconForSessionType(chatSessionType: string): ThemeIcon | URI | undefined;226getWelcomeTitleForSessionType(chatSessionType: string): string | undefined;227getWelcomeMessageForSessionType(chatSessionType: string): string | undefined;228getInputPlaceholderForSessionType(chatSessionType: string): string | undefined;229230/**231* Get the list of current chat session items grouped by session type.232* @param providerTypeFilter If specified, only returns items from the given providers. If undefined, returns items from all providers.233*/234getChatSessionItems(providerTypeFilter: readonly string[] | undefined, token: CancellationToken): Promise<Array<{ readonly chatSessionType: string; readonly items: readonly IChatSessionItem[] }>>;235236/**237* Forces the controllers to refresh their session items, optionally filtered by provider type.238*/239refreshChatSessionItems(providerTypeFilter: readonly string[] | undefined, token: CancellationToken): Promise<void>;240241reportInProgress(chatSessionType: string, count: number): void;242getInProgress(): { displayName: string; count: number }[];243244// #endregion245246// #region Content provider support247readonly onDidChangeContentProviderSchemes: Event<{ readonly added: string[]; readonly removed: string[] }>;248249getContentProviderSchemes(): string[];250251registerChatSessionContentProvider(scheme: string, provider: IChatSessionContentProvider): IDisposable;252canResolveChatSession(sessionResource: URI): Promise<boolean>;253getOrCreateChatSession(sessionResource: URI, token: CancellationToken): Promise<IChatSession>;254255hasAnySessionOptions(sessionResource: URI): boolean;256getSessionOption(sessionResource: URI, optionId: string): string | IChatSessionProviderOptionItem | undefined;257setSessionOption(sessionResource: URI, optionId: string, value: string | IChatSessionProviderOptionItem): boolean;258259/**260* Fired when options for a chat session change.261*/262onDidChangeSessionOptions: Event<URI>;263264/**265* Get the capabilities for a specific session type266*/267getCapabilitiesForSessionType(chatSessionType: string): IChatAgentAttachmentCapabilities | undefined;268269/**270* Get the customAgentTarget for a specific session type.271* When the Target is not `Target.Undefined`, the mode picker should show filtered custom agents matching this target.272*/273getCustomAgentTargetForSessionType(chatSessionType: string): Target;274275onDidChangeOptionGroups: Event<string>;276277getOptionGroupsForSessionType(chatSessionType: string): IChatSessionProviderOptionGroup[] | undefined;278setOptionGroupsForSessionType(chatSessionType: string, handle: number, optionGroups?: IChatSessionProviderOptionGroup[]): void;279/**280* Event fired when session options change and need to be sent to the extension.281* MainThreadChatSessions subscribes to this to forward changes to the extension host.282* Uses IWaitUntil pattern to allow listeners to register async work.283*/284readonly onRequestNotifyExtension: Event<IChatSessionOptionsWillNotifyExtensionEvent>;285notifySessionOptionsChange(sessionResource: URI, updates: ReadonlyArray<{ optionId: string; value: string | IChatSessionProviderOptionItem }>): Promise<void>;286287registerChatModelChangeListeners(chatService: IChatService, chatSessionType: string, onChange: () => void): IDisposable;288getInProgressSessionDescription(chatModel: IChatModel): string | undefined;289}290291export function isSessionInProgressStatus(state: ChatSessionStatus): boolean {292return state === ChatSessionStatus.InProgress || state === ChatSessionStatus.NeedsInput;293}294295export function isIChatSessionFileChange2(obj: unknown): obj is IChatSessionFileChange2 {296const candidate = obj as IChatSessionFileChange2;297return candidate && candidate.uri instanceof URI && typeof candidate.insertions === 'number' && typeof candidate.deletions === 'number';298}299300export const IChatSessionsService = createDecorator<IChatSessionsService>('chatSessionsService');301302303