mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-22 01:37:50 +00:00
wip(vscode-ide-companion): 实现 quick win 功能
- 将 WebView 调整到编辑器右侧 - 添加 ChatHeader 组件,实现会话下拉菜单 - 替换模态框为紧凑型下拉菜单 - 更新会话切换逻辑,显示当前标题 - 清理旧的会话选择器样式 基于 Claude Code v2.0.43 UI 分析实现。
This commit is contained in:
327
packages/vscode-ide-companion/docs-tmp/DEBUGGING_DOUBLE_LOGIN.md
Normal file
327
packages/vscode-ide-companion/docs-tmp/DEBUGGING_DOUBLE_LOGIN.md
Normal file
@@ -0,0 +1,327 @@
|
||||
# 🐛 调试"两次登录"问题指南
|
||||
|
||||
## 问题描述
|
||||
|
||||
用户反馈:打开 Qwen Code Chat UI 时,似乎一定会触发两次登录。
|
||||
|
||||
## 已实施的修复
|
||||
|
||||
### 1. ✅ 添加详细日志追踪
|
||||
|
||||
在 `QwenAgentManager.ts` 的 `authenticateWithRetry` 方法中添加了详细日志:
|
||||
|
||||
```typescript
|
||||
private async authenticateWithRetry(authMethod: string, maxRetries: number) {
|
||||
const timestamp = new Date().toISOString();
|
||||
const callStack = new Error().stack;
|
||||
console.log(`[QwenAgentManager] 🔐 AUTHENTICATION CALL STARTED at ${timestamp}`);
|
||||
console.log(`[QwenAgentManager] Auth method: ${authMethod}, Max retries: ${maxRetries}`);
|
||||
console.log(`[QwenAgentManager] Call stack:\n${callStack}`);
|
||||
|
||||
// ... 认证逻辑
|
||||
}
|
||||
```
|
||||
|
||||
**作用**:每次调用 `authenticateWithRetry` 都会打印时间戳和调用栈,方便追踪是否有重复调用。
|
||||
|
||||
### 2. ✅ 修复 agentInitialized 标志未重置问题
|
||||
|
||||
在 `WebViewProvider.ts` 中添加了 `resetAgentState` 方法:
|
||||
|
||||
```typescript
|
||||
resetAgentState(): void {
|
||||
console.log('[WebViewProvider] Resetting agent state');
|
||||
this.agentInitialized = false;
|
||||
this.agentManager.disconnect();
|
||||
}
|
||||
```
|
||||
|
||||
在 `extension.ts` 的 `clearAuthCache` 命令中调用:
|
||||
|
||||
```typescript
|
||||
vscode.commands.registerCommand('qwenCode.clearAuthCache', async () => {
|
||||
await authStateManager.clearAuthState();
|
||||
|
||||
// Reset WebView agent state to force re-authentication
|
||||
if (webViewProvider) {
|
||||
webViewProvider.resetAgentState();
|
||||
}
|
||||
|
||||
vscode.window.showInformationMessage(
|
||||
'Qwen Code authentication cache cleared. You will need to login again on next connection.',
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
**作用**:确保清除缓存后,下次打开 Chat UI 会正确地重新初始化和认证。
|
||||
|
||||
## 🔍 如何测试和诊断
|
||||
|
||||
### 步骤 1: 清除现有缓存
|
||||
|
||||
```bash
|
||||
# 在 VSCode 中执行命令
|
||||
Cmd+Shift+P (macOS) 或 Ctrl+Shift+P (Windows/Linux)
|
||||
输入: "Qwen Code: Clear Authentication Cache"
|
||||
```
|
||||
|
||||
### 步骤 2: 打开输出面板
|
||||
|
||||
```bash
|
||||
View → Output → 选择 "Qwen Code Companion"
|
||||
```
|
||||
|
||||
### 步骤 3: 打开 Chat UI 并观察日志
|
||||
|
||||
```bash
|
||||
Cmd+Shift+P → "Qwen Code: Open Chat"
|
||||
```
|
||||
|
||||
### 步骤 4: 分析日志
|
||||
|
||||
#### ✅ 正常情况(只认证一次)
|
||||
|
||||
```
|
||||
[WebViewProvider] Starting initialization, workingDir: /Users/xxx/workspace
|
||||
[WebViewProvider] Connecting to agent...
|
||||
[QwenAgentManager] Reading local session files...
|
||||
[QwenAgentManager] Creating new session...
|
||||
[QwenAgentManager] 🔐 AUTHENTICATION CALL STARTED at 2025-11-17T10:00:00.000Z
|
||||
[QwenAgentManager] Auth method: qwen-oauth, Max retries: 3
|
||||
[QwenAgentManager] Call stack:
|
||||
at QwenAgentManager.authenticateWithRetry (/path/to/QwenAgentManager.ts:206)
|
||||
at QwenAgentManager.connect (/path/to/QwenAgentManager.ts:162)
|
||||
...
|
||||
[QwenAgentManager] 📝 Authenticating (attempt 1/3)...
|
||||
[ACP] Sending authenticate request with methodId: qwen-oauth
|
||||
[ACP] Authenticate successful
|
||||
[QwenAgentManager] ✅ Authentication successful on attempt 1
|
||||
[QwenAgentManager] New session created successfully
|
||||
[AuthStateManager] Auth state saved
|
||||
[WebViewProvider] Agent connected successfully
|
||||
```
|
||||
|
||||
**关键点**:
|
||||
|
||||
- 只有 **一个** "🔐 AUTHENTICATION CALL STARTED"
|
||||
- 认证成功后立即创建 session
|
||||
- 整个流程顺利完成
|
||||
|
||||
#### ❌ 异常情况(认证多次)
|
||||
|
||||
```
|
||||
[QwenAgentManager] 🔐 AUTHENTICATION CALL STARTED at 2025-11-17T10:00:00.000Z
|
||||
[QwenAgentManager] Call stack:
|
||||
at QwenAgentManager.authenticateWithRetry (/path/to/QwenAgentManager.ts:206)
|
||||
at QwenAgentManager.connect (/path/to/QwenAgentManager.ts:162) ← 第一次调用
|
||||
[QwenAgentManager] 📝 Authenticating (attempt 1/3)...
|
||||
[QwenAgentManager] ✅ Authentication successful on attempt 1
|
||||
[QwenAgentManager] Session creation failed...
|
||||
[QwenAgentManager] 🔐 AUTHENTICATION CALL STARTED at 2025-11-17T10:00:05.000Z
|
||||
[QwenAgentManager] Call stack:
|
||||
at QwenAgentManager.authenticateWithRetry (/path/to/QwenAgentManager.ts:206)
|
||||
at QwenAgentManager.connect (/path/to/QwenAgentManager.ts:184) ← 第二次调用(缓存失效重试)
|
||||
[QwenAgentManager] 📝 Authenticating (attempt 1/3)...
|
||||
```
|
||||
|
||||
**关键点**:
|
||||
|
||||
- 有 **两个** "🔐 AUTHENTICATION CALL STARTED"
|
||||
- 第一次认证成功
|
||||
- Session 创建失败
|
||||
- 触发了缓存失效重试(第 184 行)
|
||||
|
||||
## 🤔 可能的原因分析
|
||||
|
||||
### 情况 1: 缓存有效但 Token 过期
|
||||
|
||||
**触发条件**:
|
||||
|
||||
- 本地缓存显示已认证
|
||||
- 跳过认证,直接创建 session
|
||||
- Session 创建失败(因为服务器端 token 已过期)
|
||||
- 触发缓存失效逻辑,清除缓存并重新认证
|
||||
|
||||
**代码位置**:
|
||||
`QwenAgentManager.ts:173-194`
|
||||
|
||||
```typescript
|
||||
try {
|
||||
await this.newSessionWithRetry(workingDir, 3);
|
||||
} catch (sessionError) {
|
||||
// 如果使用了缓存(needsAuth = false),但 session 创建失败
|
||||
if (!needsAuth && authStateManager) {
|
||||
console.log(
|
||||
'[QwenAgentManager] Session creation failed with cached auth...',
|
||||
);
|
||||
await authStateManager.clearAuthState();
|
||||
|
||||
// 第二次认证!
|
||||
await this.authenticateWithRetry(authMethod, 3);
|
||||
await authStateManager.saveAuthState(workingDir, authMethod);
|
||||
await this.newSessionWithRetry(workingDir, 3);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**是否正常**:
|
||||
|
||||
- ✅ **这是正常的设计**,用于处理缓存有效但服务器 token 过期的情况
|
||||
- ⚠️ 但如果 **每次** 都触发这个逻辑,说明有问题
|
||||
|
||||
### 情况 2: 认证重试(单次调用的多次尝试)
|
||||
|
||||
**触发条件**:
|
||||
|
||||
- 网络不稳定
|
||||
- 认证失败,自动重试
|
||||
|
||||
**日志特征**:
|
||||
|
||||
```
|
||||
[QwenAgentManager] 🔐 AUTHENTICATION CALL STARTED ← 只有一个
|
||||
[QwenAgentManager] 📝 Authenticating (attempt 1/3)...
|
||||
[QwenAgentManager] ❌ Authentication attempt 1 failed
|
||||
[QwenAgentManager] ⏳ Retrying in 1000ms...
|
||||
[QwenAgentManager] 📝 Authenticating (attempt 2/3)...
|
||||
[QwenAgentManager] ✅ Authentication successful on attempt 2
|
||||
```
|
||||
|
||||
**是否正常**:
|
||||
|
||||
- ✅ **这是正常的**,这是单次认证调用的重试机制
|
||||
- 用户可能看到多次浏览器弹窗,但这是预期行为
|
||||
|
||||
### 情况 3: OAuth 流程本身需要多次交互
|
||||
|
||||
**可能原因**:
|
||||
|
||||
- Qwen CLI 的 OAuth 实现可能需要:
|
||||
1. 第一步:获取授权码(authorization code)
|
||||
2. 第二步:交换访问令牌(access token)
|
||||
|
||||
**如何确认**:
|
||||
|
||||
- 如果日志只显示 **一个** "🔐 AUTHENTICATION CALL STARTED"
|
||||
- 但浏览器弹出了 **两次** 授权页面
|
||||
- 那么是 CLI 的 OAuth 流程设计,不是扩展的问题
|
||||
|
||||
### 情况 4: agentInitialized 标志失效
|
||||
|
||||
**触发条件**:
|
||||
|
||||
- 每次打开 Chat UI 都重新初始化
|
||||
- `agentInitialized` 没有正确保持为 `true`
|
||||
|
||||
**如何确认**:
|
||||
|
||||
```
|
||||
第1次打开:
|
||||
[WebViewProvider] Starting initialization... ← 正常
|
||||
|
||||
第2次打开(不关闭 WebView):
|
||||
[WebViewProvider] Starting initialization... ← 异常!应该是 "Agent already initialized"
|
||||
```
|
||||
|
||||
**修复状态**:
|
||||
|
||||
- ✅ 已修复(添加了 `resetAgentState` 方法)
|
||||
|
||||
## 📋 测试清单
|
||||
|
||||
请按照以下步骤测试,并记录日志:
|
||||
|
||||
### ✅ 测试 1: 首次登录
|
||||
|
||||
```bash
|
||||
1. 清除缓存: Cmd+Shift+P → "Clear Authentication Cache"
|
||||
2. 重启 VSCode Extension Host (F5 重新调试)
|
||||
3. 打开 Chat UI: Cmd+Shift+P → "Open Chat"
|
||||
4. 记录日志中 "🔐 AUTHENTICATION CALL STARTED" 出现的次数
|
||||
```
|
||||
|
||||
**期望结果**:
|
||||
|
||||
- "🔐 AUTHENTICATION CALL STARTED" 只出现 **1 次**
|
||||
- 浏览器弹窗次数:取决于 OAuth 流程(1-2 次都是正常的)
|
||||
|
||||
### ✅ 测试 2: 缓存有效时
|
||||
|
||||
```bash
|
||||
1. 首次登录成功(参考测试 1)
|
||||
2. 关闭 Chat UI WebView
|
||||
3. 重新打开 Chat UI
|
||||
4. 检查日志
|
||||
```
|
||||
|
||||
**期望结果**:
|
||||
|
||||
- 看到 "Using cached authentication"
|
||||
- **不应该** 出现 "🔐 AUTHENTICATION CALL STARTED"
|
||||
- 不需要重新登录
|
||||
|
||||
### ✅ 测试 3: 清除缓存后重新登录
|
||||
|
||||
```bash
|
||||
1. 打开 Chat UI(已登录状态)
|
||||
2. 执行: Cmd+Shift+P → "Clear Authentication Cache"
|
||||
3. 检查日志是否有 "Resetting agent state"
|
||||
4. 关闭 Chat UI
|
||||
5. 重新打开 Chat UI
|
||||
6. 检查是否需要重新登录
|
||||
```
|
||||
|
||||
**期望结果**:
|
||||
|
||||
- 清除缓存后看到 "Resetting agent state"
|
||||
- 重新打开时需要登录
|
||||
- "🔐 AUTHENTICATION CALL STARTED" 只出现 **1 次**
|
||||
|
||||
### ✅ 测试 4: agentInitialized 标志
|
||||
|
||||
```bash
|
||||
1. 打开 Chat UI(首次)
|
||||
2. 不要关闭 WebView
|
||||
3. 再次执行: Cmd+Shift+P → "Open Chat"
|
||||
4. 检查日志
|
||||
```
|
||||
|
||||
**期望结果**:
|
||||
|
||||
- 第二次打开时看到 "Agent already initialized, reusing existing connection"
|
||||
- **不应该** 重新初始化
|
||||
|
||||
## 🎯 下一步行动
|
||||
|
||||
### 如果测试失败(仍然两次登录)
|
||||
|
||||
1. **收集完整日志**:
|
||||
- 从 Extension Host 启动开始
|
||||
- 到第二次 "AUTHENTICATION CALL STARTED" 结束
|
||||
- 包括完整的调用栈信息
|
||||
|
||||
2. **检查调用栈**:
|
||||
- 确认两次调用是从哪里触发的
|
||||
- 第一次:应该是 line 162 (needsAuth 分支)
|
||||
- 第二次:应该是 line 184 (缓存失效重试)
|
||||
|
||||
3. **确认是否是"情况 1"**:
|
||||
- 如果确实是缓存失效导致的第二次认证
|
||||
- 需要调查为什么 session 创建会失败
|
||||
|
||||
4. **可能的解决方案**:
|
||||
- 如果是缓存时间太长,可以缩短 AUTH_CACHE_DURATION
|
||||
- 如果是 session 创建逻辑有问题,需要修复 newSessionWithRetry
|
||||
- 如果是 CLI 的问题,需要向 Qwen Code 团队反馈
|
||||
|
||||
### 如果是 OAuth 流程本身的问题
|
||||
|
||||
- 联系 Qwen Code 团队
|
||||
- 确认是否可以优化 OAuth 流程,减少用户交互次数
|
||||
- 或者在文档中说明这是正常行为
|
||||
|
||||
---
|
||||
|
||||
**创建日期**: 2025-11-17
|
||||
**最后更新**: 2025-11-17
|
||||
**负责人**: VSCode Extension Team
|
||||
Reference in New Issue
Block a user