mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
Session-Level Conversation History Management (#1113)
This commit is contained in:
@@ -69,7 +69,7 @@ import {
|
||||
DEFAULT_OTLP_ENDPOINT,
|
||||
DEFAULT_TELEMETRY_TARGET,
|
||||
initializeTelemetry,
|
||||
logCliConfiguration,
|
||||
logStartSession,
|
||||
logRipgrepFallback,
|
||||
RipgrepFallbackEvent,
|
||||
StartSessionEvent,
|
||||
@@ -93,6 +93,12 @@ import {
|
||||
import { DEFAULT_QWEN_EMBEDDING_MODEL, DEFAULT_QWEN_MODEL } from './models.js';
|
||||
import { Storage } from './storage.js';
|
||||
import { DEFAULT_DASHSCOPE_BASE_URL } from '../core/openaiContentGenerator/constants.js';
|
||||
import { ChatRecordingService } from '../services/chatRecordingService.js';
|
||||
import {
|
||||
SessionService,
|
||||
type ResumedSessionData,
|
||||
} from '../services/sessionService.js';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
// Re-export types
|
||||
export type { AnyToolInvocation, FileFilteringOptions, MCPOAuthConfig };
|
||||
@@ -110,6 +116,42 @@ export enum ApprovalMode {
|
||||
|
||||
export const APPROVAL_MODES = Object.values(ApprovalMode);
|
||||
|
||||
/**
|
||||
* Information about an approval mode including display name and description.
|
||||
*/
|
||||
export interface ApprovalModeInfo {
|
||||
id: ApprovalMode;
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detailed information about each approval mode.
|
||||
* Used for UI display and protocol responses.
|
||||
*/
|
||||
export const APPROVAL_MODE_INFO: Record<ApprovalMode, ApprovalModeInfo> = {
|
||||
[ApprovalMode.PLAN]: {
|
||||
id: ApprovalMode.PLAN,
|
||||
name: 'Plan',
|
||||
description: 'Analyze only, do not modify files or execute commands',
|
||||
},
|
||||
[ApprovalMode.DEFAULT]: {
|
||||
id: ApprovalMode.DEFAULT,
|
||||
name: 'Default',
|
||||
description: 'Require approval for file edits or shell commands',
|
||||
},
|
||||
[ApprovalMode.AUTO_EDIT]: {
|
||||
id: ApprovalMode.AUTO_EDIT,
|
||||
name: 'Auto Edit',
|
||||
description: 'Automatically approve file edits',
|
||||
},
|
||||
[ApprovalMode.YOLO]: {
|
||||
id: ApprovalMode.YOLO,
|
||||
name: 'YOLO',
|
||||
description: 'Automatically approve all tools',
|
||||
},
|
||||
};
|
||||
|
||||
export interface AccessibilitySettings {
|
||||
disableLoadingPhrases?: boolean;
|
||||
screenReader?: boolean;
|
||||
@@ -211,7 +253,8 @@ export interface SandboxConfig {
|
||||
}
|
||||
|
||||
export interface ConfigParameters {
|
||||
sessionId: string;
|
||||
sessionId?: string;
|
||||
sessionData?: ResumedSessionData;
|
||||
embeddingModel?: string;
|
||||
sandbox?: SandboxConfig;
|
||||
targetDir: string;
|
||||
@@ -315,10 +358,11 @@ function normalizeConfigOutputFormat(
|
||||
}
|
||||
|
||||
export class Config {
|
||||
private sessionId: string;
|
||||
private sessionData?: ResumedSessionData;
|
||||
private toolRegistry!: ToolRegistry;
|
||||
private promptRegistry!: PromptRegistry;
|
||||
private subagentManager!: SubagentManager;
|
||||
private readonly sessionId: string;
|
||||
private fileSystemService: FileSystemService;
|
||||
private contentGeneratorConfig!: ContentGeneratorConfig;
|
||||
private contentGenerator!: ContentGenerator;
|
||||
@@ -358,6 +402,8 @@ export class Config {
|
||||
};
|
||||
private fileDiscoveryService: FileDiscoveryService | null = null;
|
||||
private gitService: GitService | undefined = undefined;
|
||||
private sessionService: SessionService | undefined = undefined;
|
||||
private chatRecordingService: ChatRecordingService | undefined = undefined;
|
||||
private readonly checkpointing: boolean;
|
||||
private readonly proxy: string | undefined;
|
||||
private readonly cwd: string;
|
||||
@@ -415,7 +461,8 @@ export class Config {
|
||||
private readonly useSmartEdit: boolean;
|
||||
|
||||
constructor(params: ConfigParameters) {
|
||||
this.sessionId = params.sessionId;
|
||||
this.sessionId = params.sessionId ?? randomUUID();
|
||||
this.sessionData = params.sessionData;
|
||||
this.embeddingModel = params.embeddingModel ?? DEFAULT_QWEN_EMBEDDING_MODEL;
|
||||
this.fileSystemService = new StandardFileSystemService();
|
||||
this.sandbox = params.sandbox;
|
||||
@@ -540,6 +587,7 @@ export class Config {
|
||||
setGlobalDispatcher(new ProxyAgent(this.getProxy() as string));
|
||||
}
|
||||
this.geminiClient = new GeminiClient(this);
|
||||
this.chatRecordingService = new ChatRecordingService(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -561,6 +609,8 @@ export class Config {
|
||||
this.toolRegistry = await this.createToolRegistry();
|
||||
|
||||
await this.geminiClient.initialize();
|
||||
|
||||
logStartSession(this, new StartSessionEvent(this));
|
||||
}
|
||||
|
||||
getContentGenerator(): ContentGenerator {
|
||||
@@ -606,7 +656,6 @@ export class Config {
|
||||
this.contentGenerator = await createContentGenerator(
|
||||
newContentGeneratorConfig,
|
||||
this,
|
||||
this.getSessionId(),
|
||||
isInitialAuth,
|
||||
);
|
||||
// Only assign to instance properties after successful initialization
|
||||
@@ -617,9 +666,6 @@ export class Config {
|
||||
|
||||
// Reset the session flag since we're explicitly changing auth and using default model
|
||||
this.inFallbackMode = false;
|
||||
|
||||
// Logging the cli configuration here as the auth related configuration params would have been loaded by this point
|
||||
logCliConfiguration(this, new StartSessionEvent(this, this.toolRegistry));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -646,6 +692,26 @@ export class Config {
|
||||
return this.sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a new session and resets session-scoped services.
|
||||
*/
|
||||
startNewSession(sessionId?: string): string {
|
||||
this.sessionId = sessionId ?? randomUUID();
|
||||
this.sessionData = undefined;
|
||||
this.chatRecordingService = new ChatRecordingService(this);
|
||||
if (this.initialized) {
|
||||
logStartSession(this, new StartSessionEvent(this));
|
||||
}
|
||||
return this.sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resumed session data if this session was resumed from a previous one.
|
||||
*/
|
||||
getResumedSessionData(): ResumedSessionData | undefined {
|
||||
return this.sessionData;
|
||||
}
|
||||
|
||||
shouldLoadMemoryFromIncludeDirectories(): boolean {
|
||||
return this.loadMemoryFromIncludeDirectories;
|
||||
}
|
||||
@@ -1128,6 +1194,26 @@ export class Config {
|
||||
return this.gitService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the chat recording service.
|
||||
*/
|
||||
getChatRecordingService(): ChatRecordingService {
|
||||
if (!this.chatRecordingService) {
|
||||
this.chatRecordingService = new ChatRecordingService(this);
|
||||
}
|
||||
return this.chatRecordingService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or creates a SessionService for managing chat sessions.
|
||||
*/
|
||||
getSessionService(): SessionService {
|
||||
if (!this.sessionService) {
|
||||
this.sessionService = new SessionService(this.targetDir);
|
||||
}
|
||||
return this.sessionService;
|
||||
}
|
||||
|
||||
getFileExclusions(): FileExclusions {
|
||||
return this.fileExclusions;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user