style:对话界面的样式优化

- 代码高亮
- 间距调整
- 工具调用的样式调整
This commit is contained in:
Roe-xin
2026-01-08 16:10:41 +08:00
parent 5577fe17bb
commit 0bcdc615e3
4 changed files with 301 additions and 72 deletions

View File

@ -172,15 +172,8 @@ export function getAgentCardScript(): string {
const icon = step.status === 'completed' ? '✅' : step.status === 'error' ? '❌' : '🔄';
const displayName = getAgentToolDisplayName(step.toolName);
const result = step.toolResult ? \`: \${step.toolResult.substring(0, 50)}\${step.toolResult.length > 50 ? '...' : ''}\` : '';
// 为技术性工具调用添加低调样式(用户看不懂的)
const lowProfileTools = [
'knowledge_save', 'knowledge_load',
'queryKnowledgeSummary', 'queryRules', 'querySignals',
'setModule', 'addSignal', 'addSignalExample',
'validateKnowledgeGraph', 'addPlan', 'addEdge',
'showPlan', 'spawnExplorer'
];
const stepClass = lowProfileTools.includes(step.toolName) ? 'agent-step low-profile' : 'agent-step';
// 所有工具调用都使用低调样式
const stepClass = 'agent-step low-profile';
return \`<div class="\${stepClass}"><span class="step-icon">\${icon}</span><span class="step-name">\${displayName}</span><span class="step-result">\${result}</span></div>\`;
}).join('');

View File

@ -30,6 +30,10 @@ import {
} from "./waveformPreviewContent";
import { getAgentCardStyles, getAgentCardScript } from "./agentCard";
import { getPlanCardStyles, getPlanCardScript } from "./planCard";
import {
getCodeHighlightStyles,
getCodeHighlightScript,
} from "../components/codeHighlight";
/**
* 获取消息区域的 HTML 内容
@ -294,7 +298,7 @@ export function getMessageAreaStyles(): string {
padding: 0;
}
.message-segment {
padding: 10px 22px;
padding: 10px 20px;
}
.segment-text {
line-height: 1.6;
@ -319,37 +323,14 @@ export function getMessageAreaStyles(): string {
.segment-text h3 {
font-size: 1.1em;
}
.segment-text pre {
background: var(--vscode-textCodeBlock-background);
border: 1px solid var(--vscode-panel-border);
border-radius: 6px;
padding: 12px;
overflow-x: auto;
margin: 12px 0;
}
.segment-text code {
font-family: 'Courier New', Consolas, monospace;
font-size: 0.9em;
}
.segment-text pre code {
background: transparent;
padding: 0;
border: none;
}
.segment-text code:not(pre code) {
background: var(--vscode-textCodeBlock-background);
padding: 2px 6px;
border-radius: 3px;
color: var(--vscode-textPreformat-foreground);
}
.segment-text ul,
.segment-text ol {
margin: 8px 0;
padding-left: 24px;
}
.segment-text li {
margin: 4px 0;
line-height: 1.6;
margin: 0;
line-height: 0.4;
}
.segment-text strong {
font-weight: 600;
@ -375,7 +356,7 @@ export function getMessageAreaStyles(): string {
}
/* 低调显示的工具调用 - 移除边距和背景 */
.segment-tool.low-profile {
margin: 2px 0;
margin: 2px 20px;
padding: 0;
background: none;
}
@ -541,7 +522,7 @@ export function getMessageAreaStyles(): string {
/* 低调显示的工具调用样式 */
.segment-tool.low-profile .tool-segment-header {
opacity: 0.65;
font-size: 11px;
font-size: 12px;
}
.segment-tool.low-profile .tool-segment-icon {
opacity: 0.55;
@ -642,6 +623,8 @@ export function getMessageAreaStyles(): string {
${getPlanCardStyles()}
${getCodeHighlightStyles()}
${getWaveformPreviewContent()}
`;
}
@ -1008,17 +991,8 @@ export function getMessageAreaScript(): string {
return;
}
// 为技术性工具调用添加低调样式
const lowProfileTools = [
'knowledge_save', 'knowledge_load',
'queryKnowledgeSummary', 'queryRules', 'querySignals',
'setModule', 'addSignal', 'addSignalExample',
'validateKnowledgeGraph', 'addPlan', 'addEdge',
'showPlan', 'addRule', 'updateNode', 'addStateTransition'
];
if (lowProfileTools.includes(segment.toolName)) {
segmentDiv.className += ' low-profile';
}
// 所有工具调用都使用低调样式
segmentDiv.className += ' low-profile';
const statusIcon = segment.toolStatus === 'error' ? '❌' : '🔧';
const toolResult = segment.toolResult || '';
@ -1270,17 +1244,8 @@ export function getMessageAreaScript(): string {
return;
}
// 为技术性工具调用添加低调样式
const lowProfileTools = [
'knowledge_save', 'knowledge_load',
'queryKnowledgeSummary', 'queryRules', 'querySignals',
'setModule', 'addSignal', 'addSignalExample',
'validateKnowledgeGraph', 'addPlan', 'addEdge',
'showPlan', 'addRule', 'updateNode', 'addStateTransition'
];
if (lowProfileTools.includes(segment.toolName)) {
segmentDiv.className += ' low-profile';
}
// 所有工具调用都使用低调样式
segmentDiv.className += ' low-profile';
const statusIcon = segment.toolStatus === 'error' ? '❌' : '🔧';
const toolResult = segment.toolResult || '';
@ -1406,21 +1371,41 @@ export function getMessageAreaScript(): string {
function formatText(text) {
if (!text) return '';
// 先转义 HTML 特殊字符
let html = text
let html = text;
// 先提取并处理代码块(避免被转义)
const codeBlocks = [];
html = html.replace(/\`\`\`(\\w+)?\\n([\\s\\S]*?)\`\`\`/g, function(match, lang, code) {
const language = lang || 'plaintext';
// 转义代码内容
const escapedCode = code.trim()
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
// 不再手动高亮,让 highlight.js 处理
const placeholder = \`___CODE_BLOCK_\${codeBlocks.length}___\`;
codeBlocks.push('<pre><code class="language-' + language + '">' + escapedCode + '</code></pre>');
return placeholder;
});
// 提取行内代码(避免被转义)
const inlineCodes = [];
html = html.replace(/\`([^\`]+)\`/g, function(match, code) {
const escapedCode = code
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
const placeholder = \`___INLINE_CODE_\${inlineCodes.length}___\`;
inlineCodes.push('<code>' + escapedCode + '</code>');
return placeholder;
});
// 转义其他 HTML 特殊字符
html = html
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
// 处理代码块(三个反引号包裹的代码)
html = html.replace(/\`\`\`(\\w+)?\\n([\\s\\S]*?)\`\`\`/g, function(match, lang, code) {
const language = lang || 'plaintext';
return '<pre><code class="language-' + language + '">' + code.trim() + '</code></pre>';
});
// 处理行内代码(单个反引号包裹)
html = html.replace(/\`([^\`]+)\`/g, '<code>$1</code>');
// 处理标题 ### Title
html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>');
html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>');
@ -1442,9 +1427,19 @@ export function getMessageAreaScript(): string {
// 处理链接 [text](url)
html = html.replace(/\\[([^\\]]+)\\]\\(([^\\)]+)\\)/g, '<a href="$2" target="_blank">$1</a>');
// 处理换行
// 处理换行(在恢复代码块之前)
html = html.replace(/\\n/g, '<br>');
// 恢复代码块(在最后恢复,避免被其他处理影响)
codeBlocks.forEach((block, index) => {
html = html.replace(\`___CODE_BLOCK_\${index}___\`, block);
});
// 恢复行内代码
inlineCodes.forEach((code, index) => {
html = html.replace(\`___INLINE_CODE_\${index}___\`, code);
});
return html;
}
@ -1594,5 +1589,7 @@ export function getMessageAreaScript(): string {
}
${getWaveformPreviewScript()}
${getCodeHighlightScript()}
`;
}

View File

@ -23,6 +23,7 @@ import {
getProgressBarStyles,
getProgressBarScript,
} from "./progressBar";
import { getHighlightJsLinks } from "../components/codeHighlight";
import { getCurrentEnv } from "../config/settings";
/**
* 获取 WebView 面板的 HTML 内容
@ -44,6 +45,7 @@ export function getWebviewContent(
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IC Coder</title>
${getHighlightJsLinks()}
<style>
body {
font-family: var(--vscode-font-family);
@ -269,7 +271,7 @@ export function getWebviewContent(
padding: 0;
}
.message-segment {
padding: 10px 22px;
padding: 10px 20px;
}
.segment-text {
line-height: 1.6;