Path: blob/main/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/customSessionTitleServiceImpl.ts
13405 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, ChatContext, ChatRequestTurn2 } from 'vscode';6import { IVSCodeExtensionContext } from '../../../../platform/extContext/common/extensionContext';7import { ILogService } from '../../../../platform/log/common/logService';8import { SequencerByKey } from '../../../../util/vs/base/common/async';9import { IInstantiationService } from '../../../../util/vs/platform/instantiation/common/instantiation';10import { ChatTitleProvider } from '../../../prompt/node/title';11import { IChatSessionMetadataStore } from '../../common/chatSessionMetadataStore';12import { ICustomSessionTitleService } from '../common/customSessionTitleService';1314const CUSTOM_SESSION_TITLE_MEMENTO_KEY = 'github.copilot.cli.customSessionTitles';1516export class CustomSessionTitleService implements ICustomSessionTitleService {17declare readonly _serviceBrand: undefined;18private readonly _keyedSessionGenerator = new SequencerByKey<string>();1920constructor(21@IVSCodeExtensionContext private readonly context: IVSCodeExtensionContext,22@IInstantiationService private readonly instantiationService: IInstantiationService,23@ILogService private readonly logService: ILogService,24@IChatSessionMetadataStore private readonly chatSessionMetadataStore: IChatSessionMetadataStore,25) { }2627private _getCustomSessionTitles(): { [sessionId: string]: { title: string; updatedAt: number } | undefined } {28return this.context.globalState.get<{ [sessionId: string]: { title: string; updatedAt: number } | undefined }>(CUSTOM_SESSION_TITLE_MEMENTO_KEY, {});29}3031public async getCustomSessionTitle(sessionId: string): Promise<string | undefined> {32// First check the metadata store (new storage location).33const metadataTitle = await this.chatSessionMetadataStore.getCustomTitle(sessionId);34if (metadataTitle) {35return metadataTitle;36}3738// Fall back to global storage (legacy) and migrate if found.39const entries = this._getCustomSessionTitles();40const entry = entries[sessionId];41if (!entry) {42return undefined;43}44delete entries[sessionId];4546// Migrate: store in metadata file and remove from global storage.47await Promise.all([48this.chatSessionMetadataStore.setCustomTitle(sessionId, entry.title),49this.context.globalState.update(CUSTOM_SESSION_TITLE_MEMENTO_KEY, Object.keys(entries).length > 0 ? entries : undefined)50]);5152return entry.title;53}5455public async setCustomSessionTitle(sessionId: string, title: string): Promise<void> {56await this.chatSessionMetadataStore.setCustomTitle(sessionId, title);57}5859public async generateSessionTitle(sessionId: string, request: { prompt?: string; command?: string }, token: CancellationToken): Promise<string | undefined> {60return this._keyedSessionGenerator.queue(sessionId, () => this.generateSessionTitleImpl(sessionId, request, token));61}6263private async generateSessionTitleImpl(sessionId: string, request: { prompt?: string; command?: string }, token: CancellationToken): Promise<string | undefined> {64if (!request.prompt && !request.command) {65return undefined;66}67try {68const titleProvider = this.instantiationService.createInstance(ChatTitleProvider);69// Construct a minimal ChatContext with the current request as a history entry so provideChatTitle can find it70const requestTurn = new ChatRequestTurn2(request.prompt ?? '', request.command, [], '', [], [], undefined, undefined, undefined);71const fakeContext: ChatContext = {72history: [requestTurn],73yieldRequested: false,74};75const title = await titleProvider.provideChatTitle(fakeContext, token);76if (title) {77return title;78}79} catch (error) {80this.logService.error('Failed to generate session title', error);81}82}8384}858687