Merge branch 'feat/back-to-front' into feat/front-end

This commit is contained in:
Roe-xin
2026-01-13 11:07:53 +08:00
10 changed files with 312 additions and 103 deletions

View File

@ -29,7 +29,7 @@ import type {
} from "../types/api";
import { submitToolConfirm, submitAnswer, stopDialog } from "./apiClient";
import { ChatHistoryManager } from "../utils/chatHistoryManager";
import { getUserIdFromToken } from "../utils/jwtUtils";
import { getUserIdFromToken, isTokenExpired } from "../utils/jwtUtils";
import { updateCachedBalance } from "./creditsService";
/**
@ -418,8 +418,9 @@ export class DialogSession {
const config = getConfig();
// 从登录 session 获取真实 userId
// 从登录 session 获取真实 userId 和 token
let userId = config.userId; // 默认值
let token: string | undefined;
try {
console.log("[DialogSession] 尝试获取登录 session...");
const session = await vscode.authentication.getSession("iccoder", [], {
@ -434,6 +435,22 @@ export class DialogSession {
"[DialogSession] accessToken 长度:",
session.accessToken.length
);
// 检测 token 是否过期
const expired = isTokenExpired(session.accessToken);
if (expired === true) {
console.error("[DialogSession] token 已过期,需要重新登录");
vscode.window
.showErrorMessage("登录已过期,请重新登录", "重新登录")
.then((selection) => {
if (selection === "重新登录") {
vscode.commands.executeCommand("iccoder.login");
}
});
throw new Error("登录已过期,请重新登录");
}
token = session.accessToken; // 保存 token 用于扣费
const parsedUserId = getUserIdFromToken(session.accessToken);
console.log("[DialogSession] 解析的 userId:", parsedUserId);
if (parsedUserId) {
@ -475,6 +492,7 @@ export class DialogSession {
userId,
mode: mode || "agent",
serviceTier: serviceTier || config.serviceTier, // 优先使用传入的参数
token, // JWT token 用于扣费
compactedData: compactedData || undefined,
newMessages: newMessages.length > 0 ? newMessages : undefined,
knowledgeData: knowledgeData || undefined,
@ -861,6 +879,23 @@ export class DialogSession {
onError: (data) => {
this.isActive = false;
// 检测登录状态过期(只弹一次窗,不再传递错误)
if (
data.message.includes("LOGIN_EXPIRED") ||
data.message.includes("登录状态已过期")
) {
vscode.window
.showErrorMessage("登录状态已过期,请重新登录", "重新登录")
.then((selection) => {
if (selection === "重新登录") {
vscode.commands.executeCommand("ic-coder.login");
}
});
// 登录过期错误已处理,不再传递给外部
return;
}
callbacks.onError?.(data.message);
},
@ -1068,7 +1103,15 @@ export class DialogSession {
selected?: string[],
customInput?: string
): Promise<void> {
await userInteractionManager.receiveAnswer(askId, selected, customInput);
// 直接调用 receiveAnswer传递 taskId 作为 fallbackTaskId
// 如果 pendingQuestions 中有问题,走正常流程
// 如果没有receiveAnswer 会使用 fallbackTaskId 直接发送到后端
await userInteractionManager.receiveAnswer(
askId,
selected,
customInput,
this.taskId
);
}
}