diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts index f640014499e..5c85d398811 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts @@ -82,7 +82,7 @@ export namespace Schemas { export const vscodeChatCodeCompareBlock = 'vscode-chat-code-compare-block'; /** Scheme used for the chat input editor. */ - export const vscodeChatSesssion = 'vscode-chat-editor'; + export const vscodeChatEditor = 'vscode-chat-editor'; /** Scheme used for the chat input part */ export const vscodeChatInput = 'chatSessionInput'; diff --git a/src/vs/workbench/api/browser/mainThreadChatSessions.ts b/src/vs/workbench/api/browser/mainThreadChatSessions.ts index c39fb191867..5420e75f683 100644 --- a/src/vs/workbench/api/browser/mainThreadChatSessions.ts +++ b/src/vs/workbench/api/browser/mainThreadChatSessions.ts @@ -4,16 +4,19 @@ *--------------------------------------------------------------------------------------------*/ import { CancellationToken } from '../../../base/common/cancellation.js'; -import { Event, Emitter } from '../../../base/common/event.js'; +import { Emitter, Event } from '../../../base/common/event.js'; import { Disposable, DisposableMap } from '../../../base/common/lifecycle.js'; import { revive } from '../../../base/common/marshalling.js'; import { URI, UriComponents } from '../../../base/common/uri.js'; import { ILogService } from '../../../platform/log/common/log.js'; +import { ChatUri } from '../../contrib/chat/browser/chatEditorInput.js'; import { IChatContentInlineReference, IChatProgress } from '../../contrib/chat/common/chatService.js'; import { ChatSession, IChatSessionContentProvider, IChatSessionItem, IChatSessionItemProvider, IChatSessionsService } from '../../contrib/chat/common/chatSessionsService.js'; +import { EditorGroupColumn } from '../../services/editor/common/editorGroupColumn.js'; +import { IEditorService } from '../../services/editor/common/editorService.js'; import { extHostNamedCustomer, IExtHostContext } from '../../services/extensions/common/extHostCustomers.js'; import { Dto } from '../../services/extensions/common/proxyIdentifier.js'; -import { ExtHostContext, IChatProgressDto, MainContext, MainThreadChatSessionsShape } from '../common/extHost.protocol.js'; +import { ExtHostChatSessionsShape, ExtHostContext, IChatProgressDto, MainContext, MainThreadChatSessionsShape } from '../common/extHost.protocol.js'; @extHostNamedCustomer(MainContext.MainThreadChatSessions) export class MainThreadChatSessions extends Disposable implements MainThreadChatSessionsShape { @@ -26,12 +29,17 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat // Store completion emitters for sessions: key is `${handle}_${requestId}` private readonly _completionEmitters = new Map>(); + private readonly _proxy: ExtHostChatSessionsShape; + constructor( private readonly _extHostContext: IExtHostContext, @IChatSessionsService private readonly _chatSessionsService: IChatSessionsService, + @IEditorService private readonly _editorService: IEditorService, @ILogService private readonly _logService: ILogService, ) { super(); + + this._proxy = this._extHostContext.getProxy(ExtHostContext.ExtHostChatSessions); } $registerChatSessionItemProvider(handle: number, chatSessionType: string): void { @@ -45,11 +53,9 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat } private async _provideChatSessionItems(handle: number, token: CancellationToken): Promise { - const proxy = this._extHostContext.getProxy(ExtHostContext.ExtHostChatSessions); - try { // Get all results as an array from the RPC call - const sessions = await proxy.$provideChatSessionItems(handle, token); + const sessions = await this._proxy.$provideChatSessionItems(handle, token); return sessions.map(session => ({ ...session, id: session.id, @@ -62,10 +68,8 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat } private async _provideChatSessionContent(handle: number, id: string, token: CancellationToken): Promise { - const proxy = this._extHostContext.getProxy(ExtHostContext.ExtHostChatSessions); - try { - const sessionContent = await proxy.$provideChatSessionContent(handle, id, token); + const sessionContent = await this._proxy.$provideChatSessionContent(handle, id, token); const _progressEmitter = new Emitter; const _completionEmitter = new Emitter(); let progressEvent: Event | undefined = undefined; @@ -203,4 +207,12 @@ export class MainThreadChatSessions extends Disposable implements MainThreadChat } return undefined; } + + async $showChatSession(chatSessionType: string, sessionId: string, position: EditorGroupColumn | undefined): Promise { + // TODO: support open in panel + await this._editorService.openEditor({ + resource: ChatUri.generateForSession(chatSessionType, sessionId), + options: {}, + }, position); + } } diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 1147ac2f608..52d2ac845a5 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -952,6 +952,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I checkProposedApiEnabled(extension, 'chatStatusItem'); return extHostChatStatus.createChatStatusItem(extension, id); }, + showChatSession: (chatSessionType: string, sessionId: string, options?: vscode.ChatSessionShowOptions) => { + checkProposedApiEnabled(extension, 'chatSessionsProvider'); + return extHostChatSessions.showChatSession(extension, chatSessionType, sessionId, options); + }, }; // namespace: workspace diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index a1436add673..7688c0de159 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -3126,11 +3126,11 @@ export interface MainThreadChatSessionsShape extends IDisposable { $handleProgressChunk(handle: number, requestId: string, chunks: (IChatProgressDto | [IChatProgressDto, number])[]): Promise; $handleAnchorResolve(handle: number, requestId: string, requestHandle: string, anchor: Dto): void; $handleProgressComplete(handle: number, requestId: string): void; - + $showChatSession(chatSessionType: string, sessionId: string, position: EditorGroupColumn | undefined): Promise; } export interface ExtHostChatSessionsShape { - $provideChatSessionItems(handle: number, token: CancellationToken): Promise; + $provideChatSessionItems(handle: number, token: CancellationToken): Promise[]>; $provideChatSessionContent(handle: number, id: string, token: CancellationToken): Promise; } diff --git a/src/vs/workbench/api/common/extHostChatSessions.ts b/src/vs/workbench/api/common/extHostChatSessions.ts index a512101f86a..54ea839ed25 100644 --- a/src/vs/workbench/api/common/extHostChatSessions.ts +++ b/src/vs/workbench/api/common/extHostChatSessions.ts @@ -4,22 +4,22 @@ *--------------------------------------------------------------------------------------------*/ import type * as vscode from 'vscode'; +import { coalesce } from '../../../base/common/arrays.js'; +import { CancellationToken } from '../../../base/common/cancellation.js'; import { Disposable, DisposableStore } from '../../../base/common/lifecycle.js'; import { MarshalledId } from '../../../base/common/marshallingIds.js'; +import { IExtensionDescription } from '../../../platform/extensions/common/extensions.js'; import { ILogService } from '../../../platform/log/common/log.js'; +import { IChatAgentRequest } from '../../contrib/chat/common/chatAgents.js'; +import { IChatSessionItem } from '../../contrib/chat/common/chatSessionsService.js'; +import { ChatAgentLocation } from '../../contrib/chat/common/constants.js'; import { Proxied } from '../../services/extensions/common/proxyIdentifier.js'; import { ChatSessionDto, ExtHostChatSessionsShape, IChatAgentProgressShape, MainContext, MainThreadChatSessionsShape } from './extHost.protocol.js'; +import { ChatAgentResponseStream } from './extHostChatAgents2.js'; import { CommandsConverter, ExtHostCommands } from './extHostCommands.js'; import { IExtHostRpcService } from './extHostRpcService.js'; -import { IChatSessionItem } from '../../contrib/chat/common/chatSessionsService.js'; -import { CancellationToken } from '../../../base/common/cancellation.js'; import * as typeConvert from './extHostTypeConverters.js'; import * as extHostTypes from './extHostTypes.js'; -import { coalesce } from '../../../base/common/arrays.js'; -import { ChatAgentResponseStream } from './extHostChatAgents2.js'; -import { IChatAgentRequest } from '../../contrib/chat/common/chatAgents.js'; -import { IExtensionDescription } from '../../../platform/extensions/common/extensions.js'; -import { ChatAgentLocation } from '../../contrib/chat/common/constants.js'; class ExtHostChatSession { private _stream: ChatAgentResponseStream; @@ -82,29 +82,29 @@ export class ExtHostChatSessions extends Disposable implements ExtHostChatSessio this._chatSessionItemProviders.set(handle, { provider, extension, disposable: disposables }); this._proxy.$registerChatSessionItemProvider(handle, chatSessionType); - return { - dispose: () => { - this._chatSessionItemProviders.delete(handle); - disposables.dispose(); - this._proxy.$unregisterChatSessionItemProvider(handle); - } - }; + return new extHostTypes.Disposable(() => { + this._chatSessionItemProviders.delete(handle); + disposables.dispose(); + this._proxy.$unregisterChatSessionItemProvider(handle); + }); } - registerChatSessionContentProvider(extension: IExtensionDescription, chatSessionType: string, provider: vscode.ChatSessionContentProvider) { + registerChatSessionContentProvider(extension: IExtensionDescription, chatSessionType: string, provider: vscode.ChatSessionContentProvider): vscode.Disposable { const handle = this._nextChatSessionContentProviderHandle++; const disposables = new DisposableStore(); this._chatSessionContentProviders.set(handle, { provider, extension, disposable: disposables }); this._proxy.$registerChatSessionContentProvider(handle, chatSessionType); - return { - dispose: () => { - this._chatSessionContentProviders.delete(handle); - disposables.dispose(); - this._proxy.$unregisterChatSessionContentProvider(handle); - } - }; + return new extHostTypes.Disposable(() => { + this._chatSessionContentProviders.delete(handle); + disposables.dispose(); + this._proxy.$unregisterChatSessionContentProvider(handle); + }); + } + + async showChatSession(_extension: IExtensionDescription, chatSessionType: string, sessionId: string, options: vscode.ChatSessionShowOptions | undefined): Promise { + await this._proxy.$showChatSession(chatSessionType, sessionId, typeConvert.ViewColumn.from(options?.viewColumn)); } async $provideChatSessionItems(handle: number, token: vscode.CancellationToken): Promise { diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts index edbf91f8db3..0df6cf19958 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts @@ -7,7 +7,7 @@ import { isAncestorOfActiveElement } from '../../../../../base/browser/dom.js'; import { toAction, WorkbenchActionExecutedClassification, WorkbenchActionExecutedEvent } from '../../../../../base/common/actions.js'; import { coalesce } from '../../../../../base/common/arrays.js'; import { timeout } from '../../../../../base/common/async.js'; -import { CancellationToken, CancellationTokenSource } from '../../../../../base/common/cancellation.js'; +import { CancellationTokenSource } from '../../../../../base/common/cancellation.js'; import { Codicon } from '../../../../../base/common/codicons.js'; import { fromNowByDay, safeIntl } from '../../../../../base/common/date.js'; import { Event } from '../../../../../base/common/event.js'; @@ -21,7 +21,6 @@ import { URI } from '../../../../../base/common/uri.js'; import { ICodeEditor } from '../../../../../editor/browser/editorBrowser.js'; import { EditorAction2 } from '../../../../../editor/browser/editorExtensions.js'; import { Position } from '../../../../../editor/common/core/position.js'; -import { OffsetRange } from '../../../../../editor/common/core/ranges/offsetRange.js'; import { SuggestController } from '../../../../../editor/contrib/suggest/browser/suggestController.js'; import { localize, localize2 } from '../../../../../nls.js'; import { IActionViewItemService } from '../../../../../platform/actions/browser/actionViewItemService.js'; @@ -55,9 +54,8 @@ import { IChatAgentData, IChatAgentService } from '../../common/chatAgents.js'; import { ChatContextKeys } from '../../common/chatContextKeys.js'; import { IChatEditingSession, ModifiedFileEntryState } from '../../common/chatEditingService.js'; import { ChatEntitlement, IChatEntitlementService } from '../../common/chatEntitlementService.js'; -import { IChatRequestModel } from '../../common/chatModel.js'; import { ChatMode, IChatMode, IChatModeService } from '../../common/chatModes.js'; -import { ChatRequestTextPart, extractAgentAndCommand, IParsedChatRequest } from '../../common/chatParserTypes.js'; +import { extractAgentAndCommand } from '../../common/chatParserTypes.js'; import { IChatDetail, IChatProgress, IChatService } from '../../common/chatService.js'; import { IChatSessionItem, IChatSessionsService } from '../../common/chatSessionsService.js'; import { IChatRequestViewModel, IChatResponseViewModel, isRequestVM } from '../../common/chatViewModel.js'; @@ -67,7 +65,7 @@ import { CopilotUsageExtensionFeatureId } from '../../common/languageModelStats. import { ILanguageModelToolsService } from '../../common/languageModelToolsService.js'; import { ChatViewId, IChatWidget, IChatWidgetService, showChatView, showCopilotView } from '../chat.js'; import { IChatEditorOptions } from '../chatEditor.js'; -import { ChatEditorInput, shouldShowClearEditingSessionConfirmation, showClearEditingSessionConfirmation } from '../chatEditorInput.js'; +import { ChatEditorInput, ChatUri, shouldShowClearEditingSessionConfirmation, showClearEditingSessionConfirmation } from '../chatEditorInput.js'; import { ChatViewPane } from '../chatViewPane.js'; import { convertBufferToScreenshotVariable } from '../contrib/screenshot.js'; import { clearChatEditor } from './chatClear.js'; @@ -810,7 +808,7 @@ export function registerChatActions() { // TODO: This is a temporary change that will be replaced by opening a new chat instance const codingAgentItem = item as ICodingAgentPickerItem; if (codingAgentItem.session) { - await this.showChatSessionInEditor(chatSessionsService, codingAgentItem.session.providerType, codingAgentItem.session.session, editorService, chatWidgetService); + await this.showChatSessionInEditor(codingAgentItem.session.providerType, codingAgentItem.session.session, editorService); } } @@ -873,83 +871,12 @@ export function registerChatActions() { } } - private async showChatSessionInEditor(chatSessionService: IChatSessionsService, providerType: string, session: IChatSessionItem, editorService: IEditorService, chatWidgetService: IChatWidgetService) { + private async showChatSessionInEditor(providerType: string, session: IChatSessionItem, editorService: IEditorService) { // Open the chat editor await editorService.openEditor({ - resource: ChatEditorInput.getNewEditorUri(), + resource: ChatUri.generateForSession(providerType, session.id), options: {} satisfies IChatEditorOptions }); - - const content = await chatSessionService.provideChatSessionContent(providerType, session.id, CancellationToken.None); - - // Wait a bit for the editor to be ready, then get the widget - setTimeout(() => { - const widget = chatWidgetService.lastFocusedWidget; - if (widget) { - const agentMessage = `@${providerType} `; - widget.setInput(agentMessage); - - const model = widget.viewModel?.model; - - if (!model) { - return; - } - - let lastRequest: IChatRequestModel | undefined; - content.history.forEach(message => { - if (message.type === 'request') { - const requestText = message.prompt; - - const parsedRequest: IParsedChatRequest = { - text: requestText, - parts: [new ChatRequestTextPart( - new OffsetRange(0, requestText.length), - { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: requestText.length + 1 }, - requestText - )] - }; - lastRequest = model.addRequest(parsedRequest, - { variables: [] }, // variableData - 0, // attempt - undefined, // chatAgent - will use default - undefined, // slashCommand - undefined, // confirmation - undefined, // locationData - undefined, // attachments - true // isCompleteAddedRequest - this indicates it's a complete request, not user input - ); - } else { - // response - if (lastRequest) { - for (const part of message.parts) { - model.acceptResponseProgress(lastRequest, part); - } - } - } - }); - - if (content.progressEvent) { - content.progressEvent(e => { - if (lastRequest) { - for (const progress of e) { - - if (progress.kind === 'progressMessage' && progress.content.value === 'Session completed') { - model.completeResponse(lastRequest); - } else { - model.acceptResponseProgress(lastRequest, progress); - } - } - } - }); - } else { - if (lastRequest) { - model.completeResponse(lastRequest); - } - } - - // widget.lockToCodingAgent(selectedAgent); - } - }, 100); } }); diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index 133fc0c676b..7f764c0c565 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -554,7 +554,7 @@ class ChatResolverContribution extends Disposable { super(); this._register(editorResolverService.registerEditor( - `${Schemas.vscodeChatSesssion}:**/**`, + `${Schemas.vscodeChatEditor}:**/**`, { id: ChatEditorInput.EditorID, label: nls.localize('chat', "Chat"), @@ -562,7 +562,7 @@ class ChatResolverContribution extends Disposable { }, { singlePerResource: true, - canSupportResource: resource => resource.scheme === Schemas.vscodeChatSesssion + canSupportResource: resource => resource.scheme === Schemas.vscodeChatEditor }, { createEditorInput: ({ resource, options }) => { diff --git a/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts b/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts index e4ff9246db0..96746bc1948 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditorInput.ts @@ -16,12 +16,16 @@ import { registerIcon } from '../../../../platform/theme/common/iconRegistry.js' import { EditorInputCapabilities, IEditorIdentifier, IEditorSerializer, IUntypedEditorInput } from '../../../common/editor.js'; import { EditorInput, IEditorCloseHandler } from '../../../common/editor/editorInput.js'; import type { IChatEditorOptions } from './chatEditor.js'; -import { IChatModel } from '../common/chatModel.js'; +import { IChatModel, IChatRequestModel } from '../common/chatModel.js'; import { IChatService } from '../common/chatService.js'; import { ChatAgentLocation } from '../common/constants.js'; import { ConfirmResult, IDialogService } from '../../../../platform/dialogs/common/dialogs.js'; import { IChatEditingSession, ModifiedFileEntryState } from '../common/chatEditingService.js'; import { IClearEditingSessionConfirmationOptions } from './actions/chatActions.js'; +import { decodeBase64, encodeBase64, VSBuffer } from '../../../../base/common/buffer.js'; +import { IChatSessionsService } from '../common/chatSessionsService.js'; +import { OffsetRange } from '../../../../editor/common/core/ranges/offsetRange.js'; +import { IParsedChatRequest, ChatRequestTextPart } from '../common/chatParserTypes.js'; const ChatEditorIcon = registerIcon('chat-editor-label-icon', Codicon.commentDiscussion, nls.localize('chatEditorLabelIcon', 'Icon of the chat editor label.')); @@ -36,6 +40,8 @@ export class ChatEditorInput extends EditorInput implements IEditorCloseHandler private model: IChatModel | undefined; + private readonly parsedResource: ChatSessionIdentifier; + static getNewEditorUri(): URI { const handle = Math.floor(Math.random() * 1e9); return ChatUri.generate(handle); @@ -55,13 +61,15 @@ export class ChatEditorInput extends EditorInput implements IEditorCloseHandler readonly options: IChatEditorOptions, @IChatService private readonly chatService: IChatService, @IDialogService private readonly dialogService: IDialogService, + @IChatSessionsService private readonly chatSessionsService: IChatSessionsService, ) { super(); const parsed = ChatUri.parse(resource); - if (typeof parsed?.handle !== 'number') { + if (!parsed || (parsed.type === 'handle' && typeof parsed.handle !== 'number')) { throw new Error('Invalid chat URI'); } + this.parsedResource = parsed; this.sessionId = (options.target && 'sessionId' in options.target) ? options.target.sessionId : @@ -129,7 +137,69 @@ export class ChatEditorInput extends EditorInput implements IEditorCloseHandler this.sessionId = this.model.sessionId; this._register(this.model.onDidChange(() => this._onDidChangeLabel.fire())); - return this._register(new ChatEditorModel(this.model)); + const chatEditorModel = this._register(new ChatEditorModel(this.model)); + + // TODO: This should not live here + if (this.parsedResource.type === 'session') { + const chatSessionType = this.parsedResource.chatSessionType; + const content = await this.chatSessionsService.provideChatSessionContent(chatSessionType, this.parsedResource.sessionId, CancellationToken.None); + + let lastRequest: IChatRequestModel | undefined; + for (const message of content.history) { + if (message.type === 'request') { + const requestText = message.prompt; + + const parsedRequest: IParsedChatRequest = { + text: requestText, + parts: [new ChatRequestTextPart( + new OffsetRange(0, requestText.length), + { startLineNumber: 1, startColumn: 1, endLineNumber: 1, endColumn: requestText.length + 1 }, + requestText + )] + }; + lastRequest = this.model.addRequest(parsedRequest, + { variables: [] }, // variableData + 0, // attempt + undefined, // chatAgent - will use default + undefined, // slashCommand + undefined, // confirmation + undefined, // locationData + undefined, // attachments + true // isCompleteAddedRequest - this indicates it's a complete request, not user input + ); + } else { + // response + if (lastRequest) { + for (const part of message.parts) { + this.model.acceptResponseProgress(lastRequest, part); + } + } + } + } + + if (content.progressEvent) { + content.progressEvent(e => { + if (lastRequest) { + for (const progress of e) { + + if (progress.kind === 'progressMessage' && progress.content.value === 'Session completed') { + this.model?.completeResponse(lastRequest); + } else { + this.model?.acceptResponseProgress(lastRequest, progress); + } + } + } + }); + } else { + if (lastRequest) { + this.model.completeResponse(lastRequest); + } + } + + + } + + return chatEditorModel; } override dispose(): void { @@ -169,20 +239,46 @@ export class ChatEditorModel extends Disposable { } } +type ChatSessionIdentifier = { + type: 'handle'; + handle: number; +} | { + type: 'session'; + chatSessionType: string; + sessionId: string; +}; + export namespace ChatUri { - export const scheme = Schemas.vscodeChatSesssion; + export const scheme = Schemas.vscodeChatEditor; + export const customSessionAuthority = 'custom-session'; export function generate(handle: number): URI { return URI.from({ scheme, path: `chat-${handle}` }); } - export function parse(resource: URI): { handle: number } | undefined { + export function generateForSession(chatSessionType: string, id: string): URI { + const encodedId = encodeBase64(VSBuffer.wrap(new TextEncoder().encode(id)), false, true); + return URI.from({ scheme, authority: customSessionAuthority, path: '/' + chatSessionType + '/' + encodedId }); + } + + export function parse(resource: URI): ChatSessionIdentifier | undefined { if (resource.scheme !== scheme) { return undefined; } + if (resource.authority === customSessionAuthority) { + const parts = resource.path.split('/'); + if (parts.length !== 3) { + return undefined; + } + + const chatSessionType = parts[1]; + const decodedSessionId = decodeBase64(parts[2]); + return { type: 'session', chatSessionType, sessionId: new TextDecoder().decode(decodedSessionId.buffer) }; + } + const match = resource.path.match(/chat-(\d+)/); const handleStr = match?.[1]; if (typeof handleStr !== 'string') { @@ -194,7 +290,7 @@ export namespace ChatUri { return undefined; } - return { handle }; + return { type: 'handle', handle }; } } diff --git a/src/vscode-dts/vscode.proposed.chatSessionsProvider.d.ts b/src/vscode-dts/vscode.proposed.chatSessionsProvider.d.ts index 02f502969b1..1300c23f4c0 100644 --- a/src/vscode-dts/vscode.proposed.chatSessionsProvider.d.ts +++ b/src/vscode-dts/vscode.proposed.chatSessionsProvider.d.ts @@ -11,7 +11,7 @@ declare module 'vscode' { /** * Label of the extension that registers the provider. */ - readonly label: string; + readonly label: string; // TODO: move to contribution or registration /** * Event that the provider can fire to signal that chat sessions have changed. @@ -21,10 +21,18 @@ declare module 'vscode' { // /** // * Create a new chat session item // */ - // createChatSessionItem(prompt: string, context: ChatContext): any; + // provideNewChatSessionItem(context: { + // // This interface should be extracted + // readonly triggerChat?: { + // readonly prompt: string; + // readonly history: ReadonlyArray; + // }; + // }, token: CancellationToken): Thenable | ChatSessionItem; /** * Provides a list of chat sessions. + * + * TODO: Do we need a flag to try auth if needed? */ provideChatSessionItems(token: CancellationToken): ProviderResult; } @@ -118,6 +126,19 @@ declare module 'vscode' { * @param chatSessionType A unique identifier for the chat session type. This is used to differentiate between different chat session providers. */ export function registerChatSessionContentProvider(chatSessionType: string, provider: ChatSessionContentProvider): Disposable; + } + export interface ChatSessionShowOptions { + /** + * The editor view column to show the chat session in. + * + * If not provided, the chat session will be shown in the chat panel instead. + */ + readonly viewColumn?: ViewColumn; + } + + export namespace window { + + export function showChatSession(chatSessionType: string, id: string, options: ChatSessionShowOptions): Thenable; } }