Session-Level Conversation History Management (#1113)

This commit is contained in:
tanzhenxin 2025-12-03 18:04:48 +08:00 committed by GitHub
parent a7abd8d09f
commit 0a75d85ac9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
114 changed files with 9257 additions and 4039 deletions

View file

@ -4,11 +4,6 @@
* SPDX-License-Identifier: Apache-2.0
*/
import type {
FileFilteringOptions,
MCPServerConfig,
} from '@qwen-code/qwen-code-core';
import { extensionsCommand } from '../commands/extensions.js';
import {
ApprovalMode,
Config,
@ -26,7 +21,12 @@ import {
Storage,
InputFormat,
OutputFormat,
SessionService,
type ResumedSessionData,
type FileFilteringOptions,
type MCPServerConfig,
} from '@qwen-code/qwen-code-core';
import { extensionsCommand } from '../commands/extensions.js';
import type { Settings } from './settings.js';
import yargs, { type Argv } from 'yargs';
import { hideBin } from 'yargs/helpers';
@ -129,6 +129,10 @@ export interface CliArgs {
inputFormat?: string | undefined;
outputFormat: string | undefined;
includePartialMessages?: boolean;
/** Resume the most recent session for the current project */
continue: boolean | undefined;
/** Resume a specific session by its ID */
resume: string | undefined;
}
function normalizeOutputFormat(
@ -396,6 +400,17 @@ export async function parseArguments(settings: Settings): Promise<CliArgs> {
'Include partial assistant messages when using stream-json output.',
default: false,
})
.option('continue', {
type: 'boolean',
description:
'Resume the most recent session for the current project.',
default: false,
})
.option('resume', {
type: 'string',
description:
'Resume a specific session by its ID. Use without an ID to show session picker.',
})
.deprecateOption(
'show-memory-usage',
'Use the "ui.showMemoryUsage" setting in settings.json instead. This flag will be removed in a future version.',
@ -451,6 +466,9 @@ export async function parseArguments(settings: Settings): Promise<CliArgs> {
) {
return '--input-format stream-json requires --output-format stream-json';
}
if (argv['continue'] && argv['resume']) {
return 'Cannot use both --continue and --resume together. Use --continue to resume the latest session, or --resume <sessionId> to resume a specific session.';
}
return true;
}),
)
@ -565,7 +583,6 @@ export async function loadCliConfig(
settings: Settings,
extensions: Extension[],
extensionEnablementManager: ExtensionEnablementManager,
sessionId: string,
argv: CliArgs,
cwd: string = process.cwd(),
): Promise<Config> {
@ -797,8 +814,33 @@ export async function loadCliConfig(
const vlmSwitchMode =
argv.vlmSwitchMode || settings.experimental?.vlmSwitchMode;
let sessionId: string | undefined;
let sessionData: ResumedSessionData | undefined;
if (argv.continue || argv.resume) {
const sessionService = new SessionService(cwd);
if (argv.continue) {
sessionData = await sessionService.loadLastSession();
if (sessionData) {
sessionId = sessionData.conversation.sessionId;
}
}
if (argv.resume) {
sessionId = argv.resume;
sessionData = await sessionService.loadSession(argv.resume);
if (!sessionData) {
const message = `No saved session found with ID ${argv.resume}. Run \`qwen --resume\` without an ID to choose from existing sessions.`;
console.log(message);
process.exit(1);
}
}
}
return new Config({
sessionId,
sessionData,
embeddingModel: DEFAULT_QWEN_EMBEDDING_MODEL,
sandbox: sandboxConfig,
targetDir: cwd,