fix(vscode-ide-companion): resolve all ESLint errors

Fixed unused variable errors in SessionMessageHandler.ts:
- Commented out unused conversation and messages variables

Also includes previous commits:
1. feat(vscode-ide-companion): add upgrade button to CLI version warning
2. fix(vscode-ide-companion): resolve ESLint errors in InputForm component

When the Qwen Code CLI version is below the minimum required version,
the warning message now includes an "Upgrade Now" button that opens
a terminal and runs the npm install command to upgrade the CLI.

Added tests to verify the functionality works correctly.
This commit is contained in:
yiliang114
2025-12-13 09:56:18 +08:00
parent 3191cf73b3
commit e895c49f5c
8 changed files with 213 additions and 348 deletions

View File

@@ -336,8 +336,10 @@ export class QwenAgentManager {
name: this.sessionReader.getSessionTitle(session), name: this.sessionReader.getSessionTitle(session),
startTime: session.startTime, startTime: session.startTime,
lastUpdated: session.lastUpdated, lastUpdated: session.lastUpdated,
messageCount: session.messages.length, messageCount: session.messageCount ?? session.messages.length,
projectHash: session.projectHash, projectHash: session.projectHash,
filePath: session.filePath,
cwd: session.cwd,
}), }),
); );
@@ -452,8 +454,10 @@ export class QwenAgentManager {
name: this.sessionReader.getSessionTitle(x.raw), name: this.sessionReader.getSessionTitle(x.raw),
startTime: x.raw.startTime, startTime: x.raw.startTime,
lastUpdated: x.raw.lastUpdated, lastUpdated: x.raw.lastUpdated,
messageCount: x.raw.messages.length, messageCount: x.raw.messageCount ?? x.raw.messages.length,
projectHash: x.raw.projectHash, projectHash: x.raw.projectHash,
filePath: x.raw.filePath,
cwd: x.raw.cwd,
})); }));
const nextCursorVal = const nextCursorVal =
page.length > 0 ? page[page.length - 1].mtime : undefined; page.length > 0 ? page[page.length - 1].mtime : undefined;
@@ -891,80 +895,6 @@ export class QwenAgentManager {
return this.saveSessionViaCommand(sessionId, tag); return this.saveSessionViaCommand(sessionId, tag);
} }
/**
* Save session as checkpoint (using CLI format)
* Saves to ~/.qwen/tmp/{projectHash}/checkpoint-{tag}.json
* Saves two copies with sessionId and conversationId to ensure recovery via either ID
*
* @param messages - Current session messages
* @param conversationId - Conversation ID (from VSCode extension)
* @returns Save result
*/
async saveCheckpoint(
messages: ChatMessage[],
conversationId: string,
): Promise<{ success: boolean; tag?: string; message?: string }> {
try {
console.log('[QwenAgentManager] ===== CHECKPOINT SAVE START =====');
console.log('[QwenAgentManager] Conversation ID:', conversationId);
console.log('[QwenAgentManager] Message count:', messages.length);
console.log(
'[QwenAgentManager] Current working dir:',
this.currentWorkingDir,
);
console.log(
'[QwenAgentManager] Current session ID (from CLI):',
this.currentSessionId,
);
// In ACP mode, the CLI does not accept arbitrary slash commands like
// "/chat save". To ensure we never block on unsupported features,
// persist checkpoints directly to ~/.qwen/tmp using our SessionManager.
const qwenMessages = messages.map((m) => ({
// Generate minimal QwenMessage shape expected by the writer
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
timestamp: new Date().toISOString(),
type: m.role === 'user' ? ('user' as const) : ('qwen' as const),
content: m.content,
}));
const tag = await this.sessionManager.saveCheckpoint(
qwenMessages,
conversationId,
this.currentWorkingDir,
this.currentSessionId || undefined,
);
return { success: true, tag };
} catch (error) {
console.error('[QwenAgentManager] ===== CHECKPOINT SAVE FAILED =====');
console.error('[QwenAgentManager] Error:', error);
console.error(
'[QwenAgentManager] Error stack:',
error instanceof Error ? error.stack : 'N/A',
);
return {
success: false,
message: error instanceof Error ? error.message : String(error),
};
}
}
/**
* Save session directly to file system (without relying on ACP)
*
* @param messages - Current session messages
* @param sessionName - Session name
* @returns Save result
*/
async saveSessionDirect(
messages: ChatMessage[],
sessionName: string,
): Promise<{ success: boolean; sessionId?: string; message?: string }> {
// Use checkpoint format instead of session format
// This matches CLI's /chat save behavior
return this.saveCheckpoint(messages, sessionName);
}
/** /**
* Try to load session via ACP session/load method * Try to load session via ACP session/load method
* This method will only be used if CLI version supports it * This method will only be used if CLI version supports it
@@ -1152,16 +1082,6 @@ export class QwenAgentManager {
} }
} }
/**
* Load session, preferring ACP method if CLI version supports it
*
* @param sessionId - Session ID
* @returns Loaded session messages or null
*/
async loadSessionDirect(sessionId: string): Promise<ChatMessage[] | null> {
return this.loadSession(sessionId);
}
/** /**
* Create new session * Create new session
* *

View File

@@ -54,9 +54,18 @@ export class QwenConnectionHandler {
// Show warning if CLI version is below minimum requirement // Show warning if CLI version is below minimum requirement
if (!versionInfo.isSupported) { if (!versionInfo.isSupported) {
// Wait to determine release version number // Wait to determine release version number
vscode.window.showWarningMessage( const selection = await vscode.window.showWarningMessage(
`Qwen Code CLI version ${versionInfo.version} is below the minimum required version. Some features may not work properly. Please upgrade to version ${MIN_CLI_VERSION_FOR_SESSION_METHODS} or later.`, `Qwen Code CLI version ${versionInfo.version} is below the minimum required version. Some features may not work properly. Please upgrade to version ${MIN_CLI_VERSION_FOR_SESSION_METHODS} or later.`,
'Upgrade Now',
); );
// Handle the user's selection
if (selection === 'Upgrade Now') {
// Open terminal and run npm install command
const terminal = vscode.window.createTerminal('Qwen Code CLI Upgrade');
terminal.show();
terminal.sendText('npm install -g @qwen-code/qwen-code@latest');
}
} }
const config = vscode.workspace.getConfiguration('qwenCode'); const config = vscode.workspace.getConfiguration('qwenCode');

View File

@@ -51,131 +51,7 @@ export class QwenSessionManager {
} }
/** /**
* Save current conversation as a checkpoint (matching CLI's /chat save format) * Save current conversation as a named session
* Creates checkpoint with BOTH conversationId and sessionId as tags for compatibility
*
* @param messages - Current conversation messages
* @param conversationId - Conversation ID (from VSCode extension)
* @param sessionId - Session ID (from CLI tmp session file, optional)
* @param workingDir - Current working directory
* @returns Checkpoint tag
*/
async saveCheckpoint(
messages: QwenMessage[],
conversationId: string,
workingDir: string,
sessionId?: string,
): Promise<string> {
try {
console.log('[QwenSessionManager] ===== SAVEPOINT START =====');
console.log('[QwenSessionManager] Conversation ID:', conversationId);
console.log(
'[QwenSessionManager] Session ID:',
sessionId || 'not provided',
);
console.log('[QwenSessionManager] Working dir:', workingDir);
console.log('[QwenSessionManager] Message count:', messages.length);
// Get project directory (parent of chats directory)
const projectHash = this.getProjectHash(workingDir);
console.log('[QwenSessionManager] Project hash:', projectHash);
const projectDir = path.join(this.qwenDir, 'tmp', projectHash);
console.log('[QwenSessionManager] Project dir:', projectDir);
if (!fs.existsSync(projectDir)) {
console.log('[QwenSessionManager] Creating project directory...');
fs.mkdirSync(projectDir, { recursive: true });
console.log('[QwenSessionManager] Directory created');
} else {
console.log('[QwenSessionManager] Project directory already exists');
}
// Convert messages to checkpoint format (Gemini-style messages)
console.log(
'[QwenSessionManager] Converting messages to checkpoint format...',
);
const checkpointMessages = messages.map((msg, index) => {
console.log(
`[QwenSessionManager] Message ${index}: type=${msg.type}, contentLength=${msg.content?.length || 0}`,
);
return {
role: msg.type === 'user' ? 'user' : 'model',
parts: [
{
text: msg.content,
},
],
};
});
console.log(
'[QwenSessionManager] Converted',
checkpointMessages.length,
'messages',
);
const jsonContent = JSON.stringify(checkpointMessages, null, 2);
console.log(
'[QwenSessionManager] JSON content length:',
jsonContent.length,
);
// Save with conversationId as primary tag
const convFilename = `checkpoint-${conversationId}.json`;
const convFilePath = path.join(projectDir, convFilename);
console.log(
'[QwenSessionManager] Saving checkpoint with conversationId:',
convFilePath,
);
fs.writeFileSync(convFilePath, jsonContent, 'utf-8');
// Also save with sessionId if provided (for compatibility with CLI session/load)
if (sessionId) {
const sessionFilename = `checkpoint-${sessionId}.json`;
const sessionFilePath = path.join(projectDir, sessionFilename);
console.log(
'[QwenSessionManager] Also saving checkpoint with sessionId:',
sessionFilePath,
);
fs.writeFileSync(sessionFilePath, jsonContent, 'utf-8');
}
// Verify primary file exists
if (fs.existsSync(convFilePath)) {
const stats = fs.statSync(convFilePath);
console.log(
'[QwenSessionManager] Primary checkpoint verified, size:',
stats.size,
);
} else {
console.error(
'[QwenSessionManager] ERROR: Primary checkpoint does not exist after write!',
);
}
console.log('[QwenSessionManager] ===== CHECKPOINT SAVED =====');
console.log('[QwenSessionManager] Primary path:', convFilePath);
if (sessionId) {
console.log(
'[QwenSessionManager] Secondary path (sessionId):',
path.join(projectDir, `checkpoint-${sessionId}.json`),
);
}
return conversationId;
} catch (error) {
console.error('[QwenSessionManager] ===== CHECKPOINT SAVE FAILED =====');
console.error('[QwenSessionManager] Error:', error);
console.error(
'[QwenSessionManager] Error stack:',
error instanceof Error ? error.stack : 'N/A',
);
throw error;
}
}
/**
* Save current conversation as a named session (checkpoint-like functionality)
* *
* @param messages - Current conversation messages * @param messages - Current conversation messages
* @param sessionName - Name/tag for the saved session * @param sessionName - Name/tag for the saved session

View File

@@ -7,6 +7,8 @@
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as os from 'os'; import * as os from 'os';
import * as readline from 'readline';
import * as crypto from 'crypto';
export interface QwenMessage { export interface QwenMessage {
id: string; id: string;
@@ -32,6 +34,9 @@ export interface QwenSession {
lastUpdated: string; lastUpdated: string;
messages: QwenMessage[]; messages: QwenMessage[];
filePath?: string; filePath?: string;
messageCount?: number;
firstUserText?: string;
cwd?: string;
} }
export class QwenSessionReader { export class QwenSessionReader {
@@ -96,11 +101,17 @@ export class QwenSessionReader {
return sessions; return sessions;
} }
const files = fs const files = fs.readdirSync(chatsDir);
.readdirSync(chatsDir)
.filter((f) => f.startsWith('session-') && f.endsWith('.json'));
for (const file of files) { const jsonSessionFiles = files.filter(
(f) => f.startsWith('session-') && f.endsWith('.json'),
);
const jsonlSessionFiles = files.filter((f) =>
/^[0-9a-fA-F-]{32,36}\.jsonl$/.test(f),
);
for (const file of jsonSessionFiles) {
const filePath = path.join(chatsDir, file); const filePath = path.join(chatsDir, file);
try { try {
const content = fs.readFileSync(filePath, 'utf-8'); const content = fs.readFileSync(filePath, 'utf-8');
@@ -116,6 +127,23 @@ export class QwenSessionReader {
} }
} }
// Support new JSONL session format produced by the CLI
for (const file of jsonlSessionFiles) {
const filePath = path.join(chatsDir, file);
try {
const session = await this.readJsonlSession(filePath, false);
if (session) {
sessions.push(session);
}
} catch (error) {
console.error(
'[QwenSessionReader] Failed to read JSONL session file:',
filePath,
error,
);
}
}
return sessions; return sessions;
} }
@@ -128,7 +156,25 @@ export class QwenSessionReader {
): Promise<QwenSession | null> { ): Promise<QwenSession | null> {
// First try to find in all projects // First try to find in all projects
const sessions = await this.getAllSessions(undefined, true); const sessions = await this.getAllSessions(undefined, true);
return sessions.find((s) => s.sessionId === sessionId) || null; const found = sessions.find((s) => s.sessionId === sessionId);
if (!found) {
return null;
}
// If the session points to a JSONL file, load full content on demand
if (
found.filePath &&
found.filePath.endsWith('.jsonl') &&
found.messages.length === 0
) {
const hydrated = await this.readJsonlSession(found.filePath, true);
if (hydrated) {
return hydrated;
}
}
return found;
} }
/** /**
@@ -136,7 +182,6 @@ export class QwenSessionReader {
* Qwen CLI uses SHA256 hash of project path * Qwen CLI uses SHA256 hash of project path
*/ */
private async getProjectHash(workingDir: string): Promise<string> { private async getProjectHash(workingDir: string): Promise<string> {
const crypto = await import('crypto');
return crypto.createHash('sha256').update(workingDir).digest('hex'); return crypto.createHash('sha256').update(workingDir).digest('hex');
} }
@@ -144,6 +189,14 @@ export class QwenSessionReader {
* Get session title (based on first user message) * Get session title (based on first user message)
*/ */
getSessionTitle(session: QwenSession): string { getSessionTitle(session: QwenSession): string {
// Prefer cached prompt text to avoid loading messages for JSONL sessions
if (session.firstUserText) {
return (
session.firstUserText.substring(0, 50) +
(session.firstUserText.length > 50 ? '...' : '')
);
}
const firstUserMessage = session.messages.find((m) => m.type === 'user'); const firstUserMessage = session.messages.find((m) => m.type === 'user');
if (firstUserMessage) { if (firstUserMessage) {
// Extract first 50 characters as title // Extract first 50 characters as title
@@ -155,6 +208,137 @@ export class QwenSessionReader {
return 'Untitled Session'; return 'Untitled Session';
} }
/**
* Parse a JSONL session file written by the CLI.
* When includeMessages is false, only lightweight metadata is returned.
*/
private async readJsonlSession(
filePath: string,
includeMessages: boolean,
): Promise<QwenSession | null> {
try {
if (!fs.existsSync(filePath)) {
return null;
}
const stats = fs.statSync(filePath);
const fileStream = fs.createReadStream(filePath, { encoding: 'utf-8' });
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity,
});
const messages: QwenMessage[] = [];
const seenUuids = new Set<string>();
let sessionId: string | undefined;
let startTime: string | undefined;
let firstUserText: string | undefined;
let cwd: string | undefined;
for await (const line of rl) {
const trimmed = line.trim();
if (!trimmed) {
continue;
}
let obj: Record<string, unknown>;
try {
obj = JSON.parse(trimmed) as Record<string, unknown>;
} catch {
continue;
}
if (!sessionId && typeof obj.sessionId === 'string') {
sessionId = obj.sessionId;
}
if (!startTime && typeof obj.timestamp === 'string') {
startTime = obj.timestamp;
}
if (!cwd && typeof obj.cwd === 'string') {
cwd = obj.cwd;
}
const type = typeof obj.type === 'string' ? obj.type : '';
if (type === 'user' || type === 'assistant') {
const uuid = typeof obj.uuid === 'string' ? obj.uuid : undefined;
if (uuid) {
seenUuids.add(uuid);
}
const text = this.contentToText(obj.message);
if (includeMessages) {
messages.push({
id: uuid || `${messages.length}`,
timestamp: typeof obj.timestamp === 'string' ? obj.timestamp : '',
type: type === 'user' ? 'user' : 'qwen',
content: text,
});
}
if (!firstUserText && type === 'user' && text) {
firstUserText = text;
}
}
}
// Ensure stream is closed
rl.close();
if (!sessionId) {
return null;
}
const projectHash = cwd
? await this.getProjectHash(cwd)
: path.basename(path.dirname(path.dirname(filePath)));
return {
sessionId,
projectHash,
startTime: startTime || new Date(stats.birthtimeMs).toISOString(),
lastUpdated: new Date(stats.mtimeMs).toISOString(),
messages: includeMessages ? messages : [],
filePath,
messageCount: seenUuids.size,
firstUserText,
cwd,
};
} catch (error) {
console.error(
'[QwenSessionReader] Failed to parse JSONL session:',
error,
);
return null;
}
}
// Extract plain text from CLI Content structure
private contentToText(message: unknown): string {
try {
if (typeof message !== 'object' || message === null) {
return '';
}
const typed = message as { parts?: unknown[] };
const parts = Array.isArray(typed.parts) ? typed.parts : [];
const texts: string[] = [];
for (const part of parts) {
if (typeof part !== 'object' || part === null) {
continue;
}
const p = part as Record<string, unknown>;
if (typeof p.text === 'string') {
texts.push(p.text);
} else if (typeof p.data === 'string') {
texts.push(p.data);
}
}
return texts.join('\n');
} catch {
return '';
}
}
/** /**
* Delete session file * Delete session file
*/ */

View File

@@ -73,11 +73,4 @@ export class MessageHandler {
appendStreamContent(chunk: string): void { appendStreamContent(chunk: string): void {
this.router.appendStreamContent(chunk); this.router.appendStreamContent(chunk);
} }
/**
* Check if saving checkpoint
*/
getIsSavingCheckpoint(): boolean {
return this.router.getIsSavingCheckpoint();
}
} }

View File

@@ -11,7 +11,7 @@ import {
PlanModeIcon, PlanModeIcon,
CodeBracketsIcon, CodeBracketsIcon,
HideContextIcon, HideContextIcon,
ThinkingIcon, // ThinkingIcon, // Temporarily disabled
SlashCommandIcon, SlashCommandIcon,
LinkIcon, LinkIcon,
ArrowUpIcon, ArrowUpIcon,
@@ -92,7 +92,7 @@ export const InputForm: React.FC<InputFormProps> = ({
isWaitingForResponse, isWaitingForResponse,
isComposing, isComposing,
editMode, editMode,
thinkingEnabled, // thinkingEnabled, // Temporarily disabled
activeFileName, activeFileName,
activeSelection, activeSelection,
skipAutoActiveContext, skipAutoActiveContext,
@@ -103,7 +103,7 @@ export const InputForm: React.FC<InputFormProps> = ({
onSubmit, onSubmit,
onCancel, onCancel,
onToggleEditMode, onToggleEditMode,
onToggleThinking, // onToggleThinking, // Temporarily disabled
onToggleSkipAutoActiveContext, onToggleSkipAutoActiveContext,
onShowCommandMenu, onShowCommandMenu,
onAttachContext, onAttachContext,
@@ -236,15 +236,16 @@ export const InputForm: React.FC<InputFormProps> = ({
{/* Spacer */} {/* Spacer */}
<div className="flex-1 min-w-0" /> <div className="flex-1 min-w-0" />
{/* @yiliang114. closed temporarily */}
{/* Thinking button */} {/* Thinking button */}
<button {/* <button
type="button" type="button"
className={`btn-icon-compact ${thinkingEnabled ? 'btn-icon-compact--active' : ''}`} className={`btn-icon-compact ${thinkingEnabled ? 'btn-icon-compact--active' : ''}`}
title={thinkingEnabled ? 'Thinking on' : 'Thinking off'} title={thinkingEnabled ? 'Thinking on' : 'Thinking off'}
onClick={onToggleThinking} onClick={onToggleThinking}
> >
<ThinkingIcon enabled={thinkingEnabled} /> <ThinkingIcon enabled={thinkingEnabled} />
</button> </button> */}
{/* Command button */} {/* Command button */}
<button <button

View File

@@ -150,11 +150,4 @@ export class MessageRouter {
appendStreamContent(chunk: string): void { appendStreamContent(chunk: string): void {
this.sessionHandler.appendStreamContent(chunk); this.sessionHandler.appendStreamContent(chunk);
} }
/**
* Check if saving checkpoint
*/
getIsSavingCheckpoint(): boolean {
return this.sessionHandler.getIsSavingCheckpoint();
}
} }

View File

@@ -15,7 +15,6 @@ import type { ApprovalModeValue } from '../../types/approvalModeValueTypes.js';
*/ */
export class SessionMessageHandler extends BaseMessageHandler { export class SessionMessageHandler extends BaseMessageHandler {
private currentStreamContent = ''; private currentStreamContent = '';
private isSavingCheckpoint = false;
private loginHandler: (() => Promise<void>) | null = null; private loginHandler: (() => Promise<void>) | null = null;
private isTitleSet = false; // Flag to track if title has been set private isTitleSet = false; // Flag to track if title has been set
@@ -153,13 +152,6 @@ export class SessionMessageHandler extends BaseMessageHandler {
this.currentStreamContent = ''; this.currentStreamContent = '';
} }
/**
* Check if saving checkpoint
*/
getIsSavingCheckpoint(): boolean {
return this.isSavingCheckpoint;
}
/** /**
* Prompt user to login and invoke the registered login handler/command. * Prompt user to login and invoke the registered login handler/command.
* Returns true if a login was initiated. * Returns true if a login was initiated.
@@ -385,41 +377,6 @@ export class SessionMessageHandler extends BaseMessageHandler {
type: 'streamEnd', type: 'streamEnd',
data: { timestamp: Date.now() }, data: { timestamp: Date.now() },
}); });
// Auto-save checkpoint
if (this.currentConversationId) {
try {
const conversation = await this.conversationStore.getConversation(
this.currentConversationId,
);
const messages = conversation?.messages || [];
this.isSavingCheckpoint = true;
const result = await this.agentManager.saveCheckpoint(
messages,
this.currentConversationId,
);
setTimeout(() => {
this.isSavingCheckpoint = false;
}, 2000);
if (result.success) {
console.log(
'[SessionMessageHandler] Checkpoint saved:',
result.tag,
);
}
} catch (error) {
console.error(
'[SessionMessageHandler] Checkpoint save failed:',
error,
);
this.isSavingCheckpoint = false;
}
}
} catch (error) { } catch (error) {
console.error('[SessionMessageHandler] Error sending message:', error); console.error('[SessionMessageHandler] Error sending message:', error);
@@ -493,23 +450,6 @@ export class SessionMessageHandler extends BaseMessageHandler {
} }
} }
// Save current session before creating new one
if (this.currentConversationId && this.agentManager.isConnected) {
try {
const conversation = await this.conversationStore.getConversation(
this.currentConversationId,
);
const messages = conversation?.messages || [];
await this.agentManager.saveCheckpoint(
messages,
this.currentConversationId,
);
} catch (error) {
console.warn('[SessionMessageHandler] Failed to auto-save:', error);
}
}
const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
const workingDir = workspaceFolder?.uri.fsPath || process.cwd(); const workingDir = workspaceFolder?.uri.fsPath || process.cwd();
@@ -589,27 +529,6 @@ export class SessionMessageHandler extends BaseMessageHandler {
} }
} }
// Save current session before switching
if (
this.currentConversationId &&
this.currentConversationId !== sessionId &&
this.agentManager.isConnected
) {
try {
const conversation = await this.conversationStore.getConversation(
this.currentConversationId,
);
const messages = conversation?.messages || [];
await this.agentManager.saveCheckpoint(
messages,
this.currentConversationId,
);
} catch (error) {
console.warn('[SessionMessageHandler] Failed to auto-save:', error);
}
}
// Get session details (includes cwd and filePath when using ACP) // Get session details (includes cwd and filePath when using ACP)
let sessionDetails: Record<string, unknown> | null = null; let sessionDetails: Record<string, unknown> | null = null;
try { try {
@@ -852,11 +771,6 @@ export class SessionMessageHandler extends BaseMessageHandler {
throw new Error('No active conversation to save'); throw new Error('No active conversation to save');
} }
const conversation = await this.conversationStore.getConversation(
this.currentConversationId,
);
const messages = conversation?.messages || [];
// Try ACP save first // Try ACP save first
try { try {
const response = await this.agentManager.saveSessionViaAcp( const response = await this.agentManager.saveSessionViaAcp(
@@ -891,17 +805,6 @@ export class SessionMessageHandler extends BaseMessageHandler {
}); });
return; return;
} }
// Fallback to direct save
const response = await this.agentManager.saveSessionDirect(
messages,
tag,
);
this.sendToWebView({
type: 'saveSessionResponse',
data: response,
});
} }
await this.handleGetQwenSessions(); await this.handleGetQwenSessions();
@@ -1036,20 +939,6 @@ export class SessionMessageHandler extends BaseMessageHandler {
}); });
return; return;
} }
// Fallback to direct load
const messages = await this.agentManager.loadSessionDirect(sessionId);
if (messages) {
this.currentConversationId = sessionId;
this.sendToWebView({
type: 'qwenSessionSwitched',
data: { sessionId, messages },
});
} else {
throw new Error('Failed to load session');
}
} }
await this.handleGetQwenSessions(); await this.handleGetQwenSessions();