feat:修改对话中的样式 + 欢迎宁德弹窗内容

This commit is contained in:
Roe-xin
2026-02-26 17:27:23 +08:00
parent 7ca2fa1bcc
commit c9e9df3825
3 changed files with 183 additions and 104 deletions

View File

@ -28,17 +28,17 @@ import { setBalanceUpdateCallback } from "../services/creditsService";
function getTierIconUri( function getTierIconUri(
webview: vscode.Webview, webview: vscode.Webview,
context: vscode.ExtensionContext, context: vscode.ExtensionContext,
tierCode?: string tierCode?: string,
): string | undefined { ): string | undefined {
if (!tierCode) { if (!tierCode) {
return undefined; return undefined;
} }
const tierIconMap: Record<string, string> = { const tierIconMap: Record<string, string> = {
'BASIC': 'free.png', BASIC: "free.png",
'TRIAL': 'PRO-Try.png', TRIAL: "PRO-Try.png",
'ADVANCED': 'PRO.png', ADVANCED: "PRO.png",
'PROFESSIONAL': 'PRO+.png' PROFESSIONAL: "PRO+.png",
}; };
const iconFile = tierIconMap[tierCode]; const iconFile = tierIconMap[tierCode];
@ -47,7 +47,13 @@ function getTierIconUri(
} }
const iconUri = webview.asWebviewUri( const iconUri = webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, 'src', 'assets', 'titleIcon', iconFile) vscode.Uri.joinPath(
context.extensionUri,
"src",
"assets",
"titleIcon",
iconFile,
),
); );
return iconUri.toString(); return iconUri.toString();
@ -58,27 +64,29 @@ function getTierIconUri(
*/ */
export async function showICHelperPanel( export async function showICHelperPanel(
context: vscode.ExtensionContext, context: vscode.ExtensionContext,
viewColumn?: vscode.ViewColumn viewColumn?: vscode.ViewColumn,
) { ) {
// 检查 token 是否过期 // 检查 token 是否过期
let token: string | undefined; let token: string | undefined;
try { try {
const session = await vscode.authentication.getSession("iccoder", [], { createIfNone: false }); const session = await vscode.authentication.getSession("iccoder", [], {
createIfNone: false,
});
token = session?.accessToken; token = session?.accessToken;
} catch (error) { } catch (error) {
console.warn('[ICHelperPanel] 获取 session 失败:', error); console.warn("[ICHelperPanel] 获取 session 失败:", error);
} }
if (token && isTokenExpired(token)) { if (token && isTokenExpired(token)) {
// 清除过期的 session // 清除过期的 session
await context.globalState.update('icCoderSessions', []); await context.globalState.update("icCoderSessions", []);
await context.globalState.update('icCoderUserInfo', undefined); await context.globalState.update("icCoderUserInfo", undefined);
const action = await vscode.window.showWarningMessage( const action = await vscode.window.showWarningMessage(
'登录已过期,请重新登录', "登录已过期,请重新登录",
'立即登录' "立即登录",
); );
if (action === '立即登录') { if (action === "立即登录") {
vscode.commands.executeCommand("ic-coder.login"); vscode.commands.executeCommand("ic-coder.login");
} }
return; return;
@ -120,9 +128,9 @@ export async function showICHelperPanel(
retainContextWhenHidden: true, retainContextWhenHidden: true,
localResourceRoots: [ localResourceRoots: [
vscode.Uri.joinPath(context.extensionUri, "media"), vscode.Uri.joinPath(context.extensionUri, "media"),
vscode.Uri.joinPath(context.extensionUri, "src", "assets") vscode.Uri.joinPath(context.extensionUri, "src", "assets"),
], ],
} },
); );
// 为面板生成唯一ID // 为面板生成唯一ID
@ -136,36 +144,66 @@ export async function showICHelperPanel(
panel.iconPath = vscode.Uri.joinPath( panel.iconPath = vscode.Uri.joinPath(
context.extensionUri, context.extensionUri,
"media", "media",
"icon.png" "icon.png",
); );
// 获取页面内图标URI // 获取页面内图标URI
const iconUri = panel.webview.asWebviewUri( const iconUri = panel.webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, "media", "icon.png") vscode.Uri.joinPath(context.extensionUri, "media", "icon.png"),
); );
// 获取模型图标URI // 获取模型图标URI
const autoIconUri = panel.webview.asWebviewUri( const autoIconUri = panel.webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, "src", "assets", "model", "Auto.png") vscode.Uri.joinPath(
context.extensionUri,
"src",
"assets",
"model",
"Auto.png",
),
); );
const liteIconUri = panel.webview.asWebviewUri( const liteIconUri = panel.webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, "src", "assets", "model", "lite.png") vscode.Uri.joinPath(
context.extensionUri,
"src",
"assets",
"model",
"lite.png",
),
); );
const syIconUri = panel.webview.asWebviewUri( const syIconUri = panel.webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, "src", "assets", "model", "Sy.png") vscode.Uri.joinPath(
context.extensionUri,
"src",
"assets",
"model",
"Sy.png",
),
); );
const maxIconUri = panel.webview.asWebviewUri( const maxIconUri = panel.webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, "src", "assets", "model", "Max.png") vscode.Uri.joinPath(
context.extensionUri,
"src",
"assets",
"model",
"Max.png",
),
); );
// 获取二维码图片URI // 获取二维码图片URI
const qrCodeUri = panel.webview.asWebviewUri( const qrCodeUri = panel.webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, "src", "assets", "QRCode", "wx.png") vscode.Uri.joinPath(
context.extensionUri,
"src",
"assets",
"QRCode",
"wx.png",
),
); );
// 获取Logo URI // 获取Logo URI
const logoUri = panel.webview.asWebviewUri( const logoUri = panel.webview.asWebviewUri(
vscode.Uri.joinPath(context.extensionUri, "media", "homepage-logo.png") vscode.Uri.joinPath(context.extensionUri, "media", "homepage-logo.png"),
); );
// 设置HTML内容 // 设置HTML内容
@ -176,7 +214,7 @@ export async function showICHelperPanel(
syIconUri.toString(), syIconUri.toString(),
maxIconUri.toString(), maxIconUri.toString(),
qrCodeUri.toString(), qrCodeUri.toString(),
logoUri.toString() logoUri.toString(),
); );
// 获取并发送用户信息到 webview // 获取并发送用户信息到 webview
@ -186,21 +224,25 @@ export async function showICHelperPanel(
if (userInfo) { if (userInfo) {
// 使用缓存的用户信息 // 使用缓存的用户信息
console.log('[ICHelperPanel] 使用缓存的用户信息:', userInfo); console.log("[ICHelperPanel] 使用缓存的用户信息:", userInfo);
console.log('[ICHelperPanel] Credits 余额:', userInfo.credits); console.log("[ICHelperPanel] Credits 余额:", userInfo.credits);
const tierIconUrl = getTierIconUri(panel.webview, context, userInfo.membership?.tierCode); const tierIconUrl = getTierIconUri(
panel.webview,
context,
userInfo.membership?.tierCode,
);
const messageData = { const messageData = {
command: 'updateUserInfo', command: "updateUserInfo",
userInfo: { userInfo: {
userId: userInfo.userId, userId: userInfo.userId,
nickname: userInfo.nickname, nickname: userInfo.nickname,
username: userInfo.username, username: userInfo.username,
credits: userInfo.credits, credits: userInfo.credits,
membership: userInfo.membership membership: userInfo.membership,
}, },
tierIconUrl: tierIconUrl tierIconUrl: tierIconUrl,
}; };
console.log('[ICHelperPanel] 发送用户信息到前端:', messageData); console.log("[ICHelperPanel] 发送用户信息到前端:", messageData);
panel.webview.postMessage(messageData); panel.webview.postMessage(messageData);
} else { } else {
// 如果没有缓存,从 session 中获取 // 如果没有缓存,从 session 中获取
@ -208,19 +250,22 @@ export async function showICHelperPanel(
createIfNone: false, createIfNone: false,
}); });
if (session) { if (session) {
console.log('[ICHelperPanel] 从 session 获取用户信息, account:', session.account); console.log(
"[ICHelperPanel] 从 session 获取用户信息, account:",
session.account,
);
panel.webview.postMessage({ panel.webview.postMessage({
command: 'updateUserInfo', command: "updateUserInfo",
userInfo: { userInfo: {
userId: session.account.id, userId: session.account.id,
nickname: session.account.label, nickname: session.account.label,
username: session.account.label username: session.account.label,
} },
}); });
} }
} }
} catch (error) { } catch (error) {
console.error('[ICHelperPanel] 获取用户信息失败:', error); console.error("[ICHelperPanel] 获取用户信息失败:", error);
} }
// 设置余额更新回调 // 设置余额更新回调
@ -228,36 +273,40 @@ export async function showICHelperPanel(
const userInfo = getCachedUserInfo(); const userInfo = getCachedUserInfo();
if (userInfo) { if (userInfo) {
userInfo.credits = balance; userInfo.credits = balance;
const tierIconUrl = getTierIconUri(panel.webview, context, userInfo.membership?.tierCode); const tierIconUrl = getTierIconUri(
panel.webview,
context,
userInfo.membership?.tierCode,
);
panel.webview.postMessage({ panel.webview.postMessage({
command: 'updateUserInfo', command: "updateUserInfo",
userInfo: { userInfo: {
userId: userInfo.userId, userId: userInfo.userId,
nickname: userInfo.nickname, nickname: userInfo.nickname,
username: userInfo.username, username: userInfo.username,
credits: balance, credits: balance,
membership: userInfo.membership membership: userInfo.membership,
}, },
tierIconUrl: tierIconUrl tierIconUrl: tierIconUrl,
}); });
} }
}); });
// 检查是否有待发送的消息 // 检查是否有待发送的消息
const pendingMessage = context.globalState.get('pendingMessage') as any; const pendingMessage = context.globalState.get("pendingMessage") as any;
if (pendingMessage) { if (pendingMessage) {
console.log('[ICHelperPanel] 检测到待发送消息,准备自动发送'); console.log("[ICHelperPanel] 检测到待发送消息,准备自动发送");
// 清除待发送消息 // 清除待发送消息
await context.globalState.update('pendingMessage', undefined); await context.globalState.update("pendingMessage", undefined);
// 延迟发送,确保面板已完全初始化 // 延迟发送,确保面板已完全初始化
setTimeout(() => { setTimeout(() => {
panel.webview.postMessage({ panel.webview.postMessage({
command: 'autoSendMessage', command: "autoSendMessage",
text: pendingMessage.text, text: pendingMessage.text,
mode: pendingMessage.mode, mode: pendingMessage.mode,
serviceTier: pendingMessage.serviceTier serviceTier: pendingMessage.serviceTier,
}); });
}, 500); }, 500);
} }
@ -279,12 +328,12 @@ export async function showICHelperPanel(
try { try {
const taskMeta = await historyManager.createTask( const taskMeta = await historyManager.createTask(
workspacePath, workspacePath,
"新对话" "新对话",
); );
historyManager.setPanelTask( historyManager.setPanelTask(
panelId, panelId,
taskMeta.taskId, taskMeta.taskId,
workspacePath workspacePath,
); );
} catch (error) { } catch (error) {
console.error("创建任务失败:", error); console.error("创建任务失败:", error);
@ -296,14 +345,15 @@ export async function showICHelperPanel(
historyManager.switchToPanelTask(panelId); historyManager.switchToPanelTask(panelId);
// 显示进度条 // 显示进度条
panel.webview.postMessage({ type: 'showProgress' }); panel.webview.postMessage({ type: "showProgress" });
handleUserMessage( handleUserMessage(
panel, panel,
message.text, message.text,
context.extensionPath, context.extensionPath,
message.mode, message.mode,
message.model // 传递服务等级 message.model, // 传递服务等级
message.contextItems, // 传递上下文项
); );
break; break;
case "readFile": case "readFile":
@ -320,7 +370,7 @@ export async function showICHelperPanel(
panel, panel,
message.filePath, message.filePath,
message.searchText, message.searchText,
message.replaceText message.replaceText,
); );
break; break;
case "insertCode": case "insertCode":
@ -332,7 +382,10 @@ export async function showICHelperPanel(
case "openWaveformViewer": case "openWaveformViewer":
// 在新列中打开波形查看器 // 在新列中打开波形查看器
if (message.vcdFilePath) { if (message.vcdFilePath) {
vscode.commands.executeCommand('ic-coder.openVCDViewer', message.vcdFilePath); vscode.commands.executeCommand(
"ic-coder.openVCDViewer",
message.vcdFilePath,
);
} }
break; break;
case "getVCDInfo": case "getVCDInfo":
@ -350,7 +403,7 @@ export async function showICHelperPanel(
loadConversationHistory( loadConversationHistory(
panel, panel,
message.offset || 0, message.offset || 0,
message.limit || 10 message.limit || 10,
); );
break; break;
case "selectConversation": case "selectConversation":
@ -359,7 +412,7 @@ export async function showICHelperPanel(
selectConversation( selectConversation(
panel, panel,
message.conversationId, message.conversationId,
context.extensionPath context.extensionPath,
); );
} }
break; break;
@ -368,7 +421,7 @@ export async function showICHelperPanel(
void handleUserAnswer( void handleUserAnswer(
message.askId, message.askId,
message.selected, message.selected,
message.customInput message.customInput,
); );
break; break;
// 新增:中止对话 // 新增:中止对话
@ -432,18 +485,20 @@ export async function showICHelperPanel(
if (userInfo?.isPluginTrial === true) { if (userInfo?.isPluginTrial === true) {
// 试用用户,跳过邀请码验证,直接返回已验证 // 试用用户,跳过邀请码验证,直接返回已验证
console.log('[ICHelperPanel] 试用用户,跳过邀请码验证'); console.log("[ICHelperPanel] 试用用户,跳过邀请码验证");
panel.webview.postMessage({ panel.webview.postMessage({
command: "invitationCodeStatus", command: "invitationCodeStatus",
verified: true verified: true,
}); });
} else { } else {
// 正式用户,检查邀请码 // 正式用户,检查邀请码
const { InvitationService } = require("../services/invitationService"); const {
InvitationService,
} = require("../services/invitationService");
const isVerified = await InvitationService.isVerified(context); const isVerified = await InvitationService.isVerified(context);
panel.webview.postMessage({ panel.webview.postMessage({
command: "invitationCodeStatus", command: "invitationCodeStatus",
verified: isVerified verified: isVerified,
}); });
} }
} }
@ -451,49 +506,63 @@ export async function showICHelperPanel(
case "checkWelcomeModal": case "checkWelcomeModal":
// 检查是否需要显示欢迎弹窗 // 检查是否需要显示欢迎弹窗
{ {
console.log('[ICHelperPanel] 收到 checkWelcomeModal 消息'); console.log("[ICHelperPanel] 收到 checkWelcomeModal 消息");
const showWelcome = context.globalState.get('showWelcomeModal'); const showWelcome = context.globalState.get("showWelcomeModal");
console.log('[ICHelperPanel] showWelcomeModal 标记值:', showWelcome); console.log(
"[ICHelperPanel] showWelcomeModal 标记值:",
showWelcome,
);
if (showWelcome) { if (showWelcome) {
// 清除标记并显示欢迎弹窗 // 清除标记并显示欢迎弹窗
await context.globalState.update('showWelcomeModal', undefined); await context.globalState.update("showWelcomeModal", undefined);
console.log('[ICHelperPanel] ✅ 发送 showWelcomeModal 命令到前端'); console.log(
"[ICHelperPanel] ✅ 发送 showWelcomeModal 命令到前端",
);
panel.webview.postMessage({ panel.webview.postMessage({
command: "showWelcomeModal" command: "showWelcomeModal",
}); });
} else { } else {
console.log('[ICHelperPanel] showWelcomeModal 标记为 false不显示弹窗'); console.log(
"[ICHelperPanel] showWelcomeModal 标记为 false不显示弹窗",
);
} }
} }
break; break;
case "checkTrialExpiration": case "checkTrialExpiration":
// 检查试用期是否过期 // 检查试用期是否过期
{ {
console.log('[ICHelperPanel] 收到 checkTrialExpiration 消息'); console.log("[ICHelperPanel] 收到 checkTrialExpiration 消息");
const { TrialExpirationService } = require("../services/trialExpirationService"); const {
TrialExpirationService,
} = require("../services/trialExpirationService");
const trialService = new TrialExpirationService(context, panel); const trialService = new TrialExpirationService(context, panel);
const isExpired = await trialService.checkExpiration(); const isExpired = await trialService.checkExpiration();
console.log('[ICHelperPanel] 试用期过期状态:', isExpired); console.log("[ICHelperPanel] 试用期过期状态:", isExpired);
} }
break; break;
case "verifyInvitationCode": case "verifyInvitationCode":
// 验证邀请码 // 验证邀请码
{ {
const { InvitationService } = require("../services/invitationService"); const {
InvitationService,
} = require("../services/invitationService");
const result = await InvitationService.verifyCode(message.code); const result = await InvitationService.verifyCode(message.code);
if (result.success) { if (result.success) {
// 验证成功,保存状态 // 验证成功,保存状态
await InvitationService.saveVerificationStatus(context, message.code); await InvitationService.saveVerificationStatus(
context,
message.code,
);
panel.webview.postMessage({ panel.webview.postMessage({
command: "invitationCodeVerified", command: "invitationCodeVerified",
success: true success: true,
}); });
// 延迟显示欢迎弹窗,确保邀请码弹窗已关闭 // 延迟显示欢迎弹窗,确保邀请码弹窗已关闭
setTimeout(() => { setTimeout(() => {
panel.webview.postMessage({ panel.webview.postMessage({
command: "showNdtWelcomeModal" command: "showNdtWelcomeModal",
}); });
}, 300); }, 300);
} else { } else {
@ -501,7 +570,7 @@ export async function showICHelperPanel(
panel.webview.postMessage({ panel.webview.postMessage({
command: "invitationCodeVerified", command: "invitationCodeVerified",
success: false, success: false,
message: result.message message: result.message,
}); });
} }
} }
@ -512,7 +581,11 @@ export async function showICHelperPanel(
break; break;
case "openTutorial": case "openTutorial":
// 打开使用教程 // 打开使用教程
vscode.env.openExternal(vscode.Uri.parse("https://www.iccoder.com/tutorial")); vscode.env.openExternal(
vscode.Uri.parse(
"https://www.iccoder.com/guides/quick-start/first-task-plugin",
),
);
break; break;
case "openUserManual": case "openUserManual":
// 打开用户手册 // 打开用户手册
@ -521,7 +594,7 @@ export async function showICHelperPanel(
case "openUserFeedback": case "openUserFeedback":
// 打开用户反馈二维码弹窗 // 打开用户反馈二维码弹窗
panel.webview.postMessage({ panel.webview.postMessage({
command: "showFeedbackQRCode" command: "showFeedbackQRCode",
}); });
break; break;
// 处理计划操作(只做模式切换,响应已通过 submitAnswer 发送) // 处理计划操作(只做模式切换,响应已通过 submitAnswer 发送)
@ -533,13 +606,16 @@ export async function showICHelperPanel(
mode: "agent", mode: "agent",
}); });
// 注意:不再设置待执行计划;后端 LLM 会在同一对话中自动执行计划 // 注意:不再设置待执行计划;后端 LLM 会在同一对话中自动执行计划
} else if (message.action === "modify" || message.action === "cancel") { } else if (
message.action === "modify" ||
message.action === "cancel"
) {
void handlePlanAction( void handlePlanAction(
panel, panel,
message.action, message.action,
message.planTitle || "", message.planTitle || "",
context.extensionPath, context.extensionPath,
message.model message.model,
); );
} }
break; break;
@ -555,7 +631,7 @@ export async function showICHelperPanel(
// 获取工作区所有文件 // 获取工作区所有文件
const files = await vscode.workspace.findFiles( const files = await vscode.workspace.findFiles(
"**/*", "**/*",
"**/node_modules/**" "**/node_modules/**",
); );
panel.webview.postMessage({ panel.webview.postMessage({
@ -585,7 +661,11 @@ export async function showICHelperPanel(
try { try {
const items = fs.readdirSync(dir, { withFileTypes: true }); const items = fs.readdirSync(dir, { withFileTypes: true });
for (const item of items) { for (const item of items) {
if (item.isDirectory() && item.name !== "node_modules" && !item.name.startsWith(".")) { if (
item.isDirectory() &&
item.name !== "node_modules" &&
!item.name.startsWith(".")
) {
const fullPath = path.join(dir, item.name); const fullPath = path.join(dir, item.name);
const relativePath = path.relative(baseDir, fullPath); const relativePath = path.relative(baseDir, fullPath);
folders.push({ path: fullPath, relativePath }); folders.push({ path: fullPath, relativePath });
@ -614,7 +694,7 @@ export async function showICHelperPanel(
canSelectMany: true, canSelectMany: true,
openLabel: "选择图片", openLabel: "选择图片",
filters: { filters: {
"图片文件": ["png", "jpg", "jpeg", "gif", "bmp", "svg", "webp"], : ["png", "jpg", "jpeg", "gif", "bmp", "svg", "webp"],
}, },
}); });
if (imageUris && imageUris.length > 0) { if (imageUris && imageUris.length > 0) {
@ -634,8 +714,8 @@ export async function showICHelperPanel(
canSelectMany: true, canSelectMany: true,
openLabel: "选择文档", openLabel: "选择文档",
filters: { filters: {
"文档文件": ["pdf", "doc", "docx", "txt", "md"], : ["pdf", "doc", "docx", "txt", "md"],
"所有文件": ["*"], : ["*"],
}, },
}); });
if (docUris && docUris.length > 0) { if (docUris && docUris.length > 0) {
@ -657,7 +737,7 @@ export async function showICHelperPanel(
vscode.window vscode.window
.showWarningMessage( .showWarningMessage(
"请先打开一个文件夹作为工作区,这样我就能更好地为您服务了 😊", "请先打开一个文件夹作为工作区,这样我就能更好地为您服务了 😊",
"打开文件夹" "打开文件夹",
) )
.then((selection) => { .then((selection) => {
if (selection === "打开文件夹") { if (selection === "打开文件夹") {
@ -679,16 +759,16 @@ export async function showICHelperPanel(
break; break;
case "openICCoder": case "openICCoder":
// 打开 IC Coder 官网 // 打开 IC Coder 官网
vscode.env.openExternal(vscode.Uri.parse('https://www.iccoder.com')); vscode.env.openExternal(vscode.Uri.parse("https://www.iccoder.com"));
break; break;
case "logout": case "logout":
// 退出登录(前端已有确认对话框) // 退出登录(前端已有确认对话框)
vscode.commands.executeCommand('ic-coder.logout'); vscode.commands.executeCommand("ic-coder.logout");
break; break;
} }
}, },
undefined, undefined,
context.subscriptions context.subscriptions,
); );
// 面板关闭时清理任务映射 // 面板关闭时清理任务映射
@ -699,7 +779,7 @@ export async function showICHelperPanel(
historyManager.removePanelTask(panelId); historyManager.removePanelTask(panelId);
}, },
undefined, undefined,
context.subscriptions context.subscriptions,
); );
} }
@ -709,7 +789,7 @@ export async function showICHelperPanel(
async function getVCDFileInfo( async function getVCDFileInfo(
panel: vscode.WebviewPanel, panel: vscode.WebviewPanel,
vcdFilePath: string, vcdFilePath: string,
containerId: string containerId: string,
) { ) {
try { try {
const fs = require("fs"); const fs = require("fs");
@ -847,7 +927,7 @@ function parseVCDSignals(content: string, maxSignals: number = 3) {
if (signalDef.width === 1) { if (signalDef.width === 1) {
// 单比特信号 // 单比特信号
const singleBitMatch = trimmedLine.match( const singleBitMatch = trimmedLine.match(
new RegExp(`^([01xz])${signalDef.identifier}$`) new RegExp(`^([01xz])${signalDef.identifier}$`),
); );
if (singleBitMatch) { if (singleBitMatch) {
values.push({ time: currentTime, value: singleBitMatch[1] }); values.push({ time: currentTime, value: singleBitMatch[1] });
@ -855,7 +935,7 @@ function parseVCDSignals(content: string, maxSignals: number = 3) {
} else { } else {
// 多比特信号 // 多比特信号
const multiBitMatch = trimmedLine.match( const multiBitMatch = trimmedLine.match(
new RegExp(`^b([01xz]+)\\s+${signalDef.identifier}$`) new RegExp(`^b([01xz]+)\\s+${signalDef.identifier}$`),
); );
if (multiBitMatch) { if (multiBitMatch) {
values.push({ time: currentTime, value: multiBitMatch[1] }); values.push({ time: currentTime, value: multiBitMatch[1] });
@ -888,7 +968,7 @@ function parseVCDSignals(content: string, maxSignals: number = 3) {
async function loadConversationHistory( async function loadConversationHistory(
panel: vscode.WebviewPanel, panel: vscode.WebviewPanel,
offset: number = 0, offset: number = 0,
limit: number = 10 limit: number = 10,
) { ) {
try { try {
const historyManager = ChatHistoryManager.getInstance(); const historyManager = ChatHistoryManager.getInstance();
@ -909,7 +989,7 @@ async function loadConversationHistory(
const result = await historyManager.getConversationHistoryList( const result = await historyManager.getConversationHistoryList(
workspacePath, workspacePath,
offset, offset,
limit limit,
); );
// 发送会话历史到前端 // 发送会话历史到前端
@ -937,7 +1017,7 @@ async function loadConversationHistory(
async function selectConversation( async function selectConversation(
panel: vscode.WebviewPanel, panel: vscode.WebviewPanel,
taskId: string, taskId: string,
extensionPath: string extensionPath: string,
) { ) {
try { try {
const historyManager = ChatHistoryManager.getInstance(); const historyManager = ChatHistoryManager.getInstance();
@ -951,12 +1031,12 @@ async function selectConversation(
// 加载任务会话 // 加载任务会话
const taskSession = await historyManager.loadTaskSession( const taskSession = await historyManager.loadTaskSession(
workspacePath, workspacePath,
taskId taskId,
); );
if (!taskSession) { if (!taskSession) {
vscode.window.showErrorMessage( vscode.window.showErrorMessage(
`加载任务 ${taskId} 失败: 任务不存在或数据损坏` `加载任务 ${taskId} 失败: 任务不存在或数据损坏`,
); );
return; return;
} }
@ -1117,7 +1197,7 @@ async function selectConversation(
} }
vscode.window.showInformationMessage( vscode.window.showInformationMessage(
`已加载会话: ${taskSession.meta.taskName}` `已加载会话: ${taskSession.meta.taskName}`,
); );
} catch (error) { } catch (error) {
console.error("选择会话失败:", error); console.error("选择会话失败:", error);

View File

@ -544,9 +544,9 @@ export function getMessageAreaStyles(): string {
max-height: 0; max-height: 0;
} }
.tool-segment-description { .tool-segment-description {
margin: 2px 0 0 0px; margin: 6px 0 0 0px;
font-size: 12px; font-size: 12px;
color: #fff; color: #ccc;
line-height: 1.4; line-height: 1.4;
} }
/* 低调显示的工具调用样式 */ /* 低调显示的工具调用样式 */

View File

@ -18,20 +18,19 @@ export function getNdtWelcomeModalContent(logoUri?: string): string {
<div class="ndt-welcome-modal-header"> <div class="ndt-welcome-modal-header">
<div class="ndt-welcome-icon">🎉</div> <div class="ndt-welcome-icon">🎉</div>
<h2>欢迎宁德时代新能源科技股份有限公司的各位专家使用 IC Coder</h2> <h2>欢迎宁德时代新能源科技股份有限公司<span style="white-space: nowrap;">的各位专家</span>使用 IC Coder</h2>
<p class="ndt-welcome-modal-subtitle">感谢您选择 IC Coder 作为您的芯片设计助手</p>
</div> </div>
<div class="ndt-welcome-modal-body"> <div class="ndt-welcome-modal-body">
<!-- 试用期提示 --> <!-- 试用期提示 -->
<div class="ndt-trial-banner"> <div class="ndt-trial-banner">
<span>您已获得 <strong>5 天试用期</strong>,试用期内可无限制使用所有功能</span> <span>您已获得 <strong>5 天企业版试用期</strong>企业版试用期内Credits用量无限可无限制使用所有功能</span>
</div> </div>
<!-- IC Coder 简介 --> <!-- IC Coder 简介 -->
<div class="ndt-intro-section"> <div class="ndt-intro-section">
<h3 class="ndt-section-title">关于 IC Coder</h3> <h3 class="ndt-section-title">关于 IC Coder</h3>
<p class="ndt-intro-text">IC Coder是一款The Agentic AI Verilog Coding Platform自主式人工智能 Verilog 编码平台)。我们采用全球顶尖的大语言模型,加上自研的针对芯片设计领域深度优化的微调模型为代码生成提供强大的AI能力支撑。</p> <p class="ndt-intro-text">IC Coder是一款The Agentic AI Verilog Coding Platform自主式人工智能 Verilog 编码平台)。我们采用全球顶尖的IC Coder自研芯片设计微调模型为代码生成提供强大的AI能力支撑。</p>
<div class="ndt-features"> <div class="ndt-features">
<div class="ndt-feature-item"> <div class="ndt-feature-item">
@ -41,7 +40,7 @@ export function getNdtWelcomeModalContent(logoUri?: string): string {
<span class="ndt-feature-text">增强上下文引擎:智能理解和管理大规模设计上下文,确保生成代码的一致性和准确性</span> <span class="ndt-feature-text">增强上下文引擎:智能理解和管理大规模设计上下文,确保生成代码的一致性和准确性</span>
</div> </div>
<div class="ndt-feature-item"> <div class="ndt-feature-item">
<span class="ndt-feature-text">自研EDA工具集完整的仿真、综合、时序分析工具链无缝集成到AI工作流中</span> <span class="ndt-feature-text">AI自主仿真IC Coder提供完全自动化的仿真验证流程无需手动编写测试代码</span>
</div> </div>
</div> </div>
</div> </div>