Add disableBackgroundKeepAlive option for chat sessions (#278979)

* Add disableBackgroundKeepAlive for quick chat ChatModels

* Named interface

---------

Co-authored-by: Benjamin Pasero <benjamin.pasero@gmail.com>
This commit is contained in:
Rob Lourens
2025-11-23 22:20:40 -08:00
committed by GitHub
parent 0b0efb84e0
commit f46b8a4886
5 changed files with 15 additions and 8 deletions

View File

@@ -395,7 +395,7 @@ class QuickChat extends Disposable {
}
private updateModel(): void {
this.modelRef ??= this.chatService.startSession(ChatAgentLocation.Chat, CancellationToken.None);
this.modelRef ??= this.chatService.startSession(ChatAgentLocation.Chat, CancellationToken.None, { disableBackgroundKeepAlive: true });
const model = this.modelRef?.object;
if (!model) {
throw new Error('Could not start chat session');

View File

@@ -1645,7 +1645,7 @@ export class ChatModel extends Disposable implements IChatModel {
constructor(
initialData: ISerializableChatData | IExportableChatData | undefined,
initialModelProps: { initialLocation: ChatAgentLocation; canUseTools: boolean; resource?: URI; sessionId?: string },
initialModelProps: { initialLocation: ChatAgentLocation; canUseTools: boolean; resource?: URI; sessionId?: string; disableBackgroundKeepAlive?: boolean },
@ILogService private readonly logService: ILogService,
@IChatAgentService private readonly chatAgentService: IChatAgentService,
@IChatEditingService private readonly chatEditingService: IChatEditingService,
@@ -1713,7 +1713,7 @@ export class ChatModel extends Disposable implements IChatModel {
// Retain a reference to itself when a request is in progress, so the ChatModel stays alive in the background
// only while running a request. TODO also keep it alive for 5min or so so we don't have to dispose/restore too often?
if (this.initialLocation === ChatAgentLocation.Chat && configurationService.getValue<boolean>('chat.localBackgroundSessions')) {
if (this.initialLocation === ChatAgentLocation.Chat && configurationService.getValue<boolean>('chat.localBackgroundSessions') && !initialModelProps.disableBackgroundKeepAlive) {
const selfRef = this._register(new MutableDisposable<IChatModelReference>());
this._register(autorun(r => {
const inProgress = this.requestInProgress.read(r);

View File

@@ -21,6 +21,7 @@ export interface IStartSessionProps {
readonly sessionId?: string;
readonly canUseTools: boolean;
readonly transferEditingSession?: IChatEditingSession;
readonly disableBackgroundKeepAlive?: boolean;
}
export interface ChatModelStoreDelegate {

View File

@@ -945,7 +945,7 @@ export interface IChatService {
isEnabled(location: ChatAgentLocation): boolean;
hasSessions(): boolean;
startSession(location: ChatAgentLocation, token: CancellationToken, options?: { canUseTools?: boolean }): IChatModelReference;
startSession(location: ChatAgentLocation, token: CancellationToken, options?: IChatSessionStartOptions): IChatModelReference;
/**
* Get an active session without holding a reference to it.
@@ -1014,3 +1014,8 @@ export interface IChatSessionContext {
}
export const KEYWORD_ACTIVIATION_SETTING_ID = 'accessibility.voice.keywordActivation';
export interface IChatSessionStartOptions {
canUseTools?: boolean;
disableBackgroundKeepAlive?: boolean;
}

View File

@@ -33,7 +33,7 @@ import { ChatModel, ChatRequestModel, ChatRequestRemovalReason, IChatModel, ICha
import { ChatModelStore, IStartSessionProps } from './chatModelStore.js';
import { chatAgentLeader, ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart, ChatRequestTextPart, chatSubcommandLeader, getPromptText, IParsedChatRequest } from './chatParserTypes.js';
import { ChatRequestParser } from './chatRequestParser.js';
import { ChatMcpServersStarting, IChatCompleteResponse, IChatDetail, IChatFollowup, IChatModelReference, IChatProgress, IChatSendRequestData, IChatSendRequestOptions, IChatSendRequestResponseState, IChatService, IChatSessionContext, IChatTransferredSessionData, IChatUserActionEvent } from './chatService.js';
import { ChatMcpServersStarting, IChatCompleteResponse, IChatDetail, IChatFollowup, IChatModelReference, IChatProgress, IChatSendRequestData, IChatSendRequestOptions, IChatSendRequestResponseState, IChatService, IChatSessionContext, IChatSessionStartOptions, IChatTransferredSessionData, IChatUserActionEvent } from './chatService.js';
import { ChatRequestTelemetry, ChatServiceTelemetry } from './chatServiceTelemetry.js';
import { IChatSessionsService } from './chatSessionsService.js';
import { ChatSessionStore, IChatTransfer2 } from './chatSessionStore.js';
@@ -413,7 +413,7 @@ export class ChatService extends Disposable implements IChatService {
await this._chatSessionStore.clearAllSessions();
}
startSession(location: ChatAgentLocation, token: CancellationToken, options?: { canUseTools?: boolean }): IChatModelReference {
startSession(location: ChatAgentLocation, token: CancellationToken, options?: IChatSessionStartOptions): IChatModelReference {
this.trace('startSession');
const sessionId = generateUuid();
const sessionResource = LocalChatSessionUri.forSession(sessionId);
@@ -424,12 +424,13 @@ export class ChatService extends Disposable implements IChatService {
sessionResource,
sessionId,
canUseTools: options?.canUseTools ?? true,
disableBackgroundKeepAlive: options?.disableBackgroundKeepAlive
});
}
private _startSession(props: IStartSessionProps): ChatModel {
const { initialData, location, token, sessionResource, sessionId, canUseTools, transferEditingSession } = props;
const model = this.instantiationService.createInstance(ChatModel, initialData, { initialLocation: location, canUseTools, resource: sessionResource, sessionId });
const { initialData, location, token, sessionResource, sessionId, canUseTools, transferEditingSession, disableBackgroundKeepAlive } = props;
const model = this.instantiationService.createInstance(ChatModel, initialData, { initialLocation: location, canUseTools, resource: sessionResource, sessionId, disableBackgroundKeepAlive });
if (location === ChatAgentLocation.Chat) {
model.startEditingSession(true, transferEditingSession);
}