fix: remove reason in message bottom
parent
67585d17ce
commit
f1553be178
|
|
@ -139,12 +139,15 @@ export default function MessageItem(props: {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 展示 RAG 和 工具调用 */}
|
{/* 底部 Meta 信息展示 (RAG / Tool) */}
|
||||||
{!isMobile && message.meta && !isUser && (
|
{!isMobile && message.meta && !isUser && (
|
||||||
<div style={{ marginTop: 8 }}>
|
<div className="message-meta-section">
|
||||||
{!!message.meta.reasoning && <ReasoningView reasoning={message.meta.reasoning} />}
|
{message.meta.retrieved && message.meta.retrieved.length > 0 && (
|
||||||
{!!message.meta.retrieved?.length && <RetrievedView retrieved={message.meta.retrieved} />}
|
<RetrievedView retrieved={message.meta.retrieved} />
|
||||||
{!!message.meta.toolCalls?.length && <ToolCallView calls={message.meta.toolCalls} />}
|
)}
|
||||||
|
{message.meta.toolCalls && message.meta.toolCalls.length > 0 && (
|
||||||
|
<ToolCallView calls={message.meta.toolCalls} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
.reasoning-container {
|
||||||
|
margin: 4px 0;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
padding: 4px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-header:hover {
|
||||||
|
background-color: var(--color-surface-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--color-text-tertiary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-toggle-icon {
|
||||||
|
font-size: 10px;
|
||||||
|
color: var(--color-text-tertiary);
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-container.is-expanded .reasoning-toggle-icon {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-content {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
line-height: 1.6;
|
||||||
|
overflow: auto;
|
||||||
|
border-left: 2px solid var(--color-border-light);
|
||||||
|
padding-left: 12px;
|
||||||
|
margin-left: 4px;
|
||||||
|
margin-top: 8px;
|
||||||
|
animation: reasoningFadeIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes reasoningFadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-4px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RAG View Styles */
|
||||||
|
.retrieved-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #6366f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retrieved-list {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retrieved-item {
|
||||||
|
padding: 8px;
|
||||||
|
background: #f6f8ff;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
border-left: 3px solid #6366f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retrieved-item-header {
|
||||||
|
color: #6366f1;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.retrieved-item-preview {
|
||||||
|
color: #374151;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tool Call View Styles */
|
||||||
|
.tool-call-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #f97316;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-call-list {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-call-item {
|
||||||
|
padding: 8px;
|
||||||
|
background: #fff7ed;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
border-left: 3px solid #f97316;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-call-item-header {
|
||||||
|
color: #c2410c;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-call-item-args {
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-call-item-result {
|
||||||
|
color: #374151;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tool-call-item-result code {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ import { Collapse, Tag } from 'antd';
|
||||||
import { RightOutlined } from '@ant-design/icons';
|
import { RightOutlined } from '@ant-design/icons';
|
||||||
import type { RetrievedSnippet, ToolCallTrace } from '../../../../api';
|
import type { RetrievedSnippet, ToolCallTrace } from '../../../../api';
|
||||||
import Markdown from '../../../../components/Markdown';
|
import Markdown from '../../../../components/Markdown';
|
||||||
|
import './MetaViews.css';
|
||||||
|
|
||||||
export function ReasoningView({
|
export function ReasoningView({
|
||||||
reasoning,
|
reasoning,
|
||||||
|
|
@ -14,35 +15,12 @@ export function ReasoningView({
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className={`reasoning-container ${expanded ? 'is-expanded' : ''}`}>
|
<div className={`reasoning-container ${expanded ? 'is-expanded' : ''}`}>
|
||||||
<div className="reasoning-header" onClick={onToggle} style={{
|
<div className="reasoning-header" onClick={onToggle}>
|
||||||
display: 'flex',
|
<span className="reasoning-label">已深度思考</span>
|
||||||
alignItems: 'center',
|
<RightOutlined className="reasoning-toggle-icon" />
|
||||||
gap: 6,
|
|
||||||
cursor: 'pointer',
|
|
||||||
userSelect: 'none',
|
|
||||||
marginBottom: expanded ? 8 : 0
|
|
||||||
}}>
|
|
||||||
<span style={{ fontSize: 12, color: 'var(--color-text-tertiary)', fontWeight: 500 }}>
|
|
||||||
已深度思考
|
|
||||||
</span>
|
|
||||||
<RightOutlined style={{
|
|
||||||
fontSize: 10,
|
|
||||||
color: 'var(--color-text-tertiary)',
|
|
||||||
transition: 'transform 0.2s',
|
|
||||||
transform: expanded ? 'rotate(90deg)' : 'rotate(0deg)'
|
|
||||||
}} />
|
|
||||||
</div>
|
</div>
|
||||||
{expanded && (
|
{expanded && (
|
||||||
<div className="reasoning-content" style={{
|
<div className="reasoning-content">
|
||||||
fontSize: 13,
|
|
||||||
color: 'var(--color-text-secondary)',
|
|
||||||
lineHeight: 1.6,
|
|
||||||
maxHeight: 300,
|
|
||||||
overflow: 'auto',
|
|
||||||
borderLeft: '2px solid var(--color-border-light)',
|
|
||||||
paddingLeft: 12,
|
|
||||||
marginLeft: 4
|
|
||||||
}}>
|
|
||||||
<Markdown>{reasoning}</Markdown>
|
<Markdown>{reasoning}</Markdown>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -58,24 +36,15 @@ export function RetrievedView({ retrieved }: { retrieved: RetrievedSnippet[] })
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
key: 'rag',
|
key: 'rag',
|
||||||
label: <span style={{ fontSize: 12, color: '#6366f1' }}>🔍 RAG 命中片段 ({retrieved.length})</span>,
|
label: <span className="retrieved-label">RAG 命中片段 ({retrieved.length})</span>,
|
||||||
children: (
|
children: (
|
||||||
<div style={{ fontSize: 12 }}>
|
<div className="retrieved-list">
|
||||||
{retrieved.map((r, i) => (
|
{retrieved.map((r, i) => (
|
||||||
<div
|
<div key={i} className="retrieved-item">
|
||||||
key={i}
|
<div className="retrieved-item-header">
|
||||||
style={{
|
|
||||||
padding: 8,
|
|
||||||
background: '#f6f8ff',
|
|
||||||
borderRadius: 6,
|
|
||||||
marginBottom: 6,
|
|
||||||
borderLeft: '3px solid #6366f1'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ color: '#6366f1', fontWeight: 600, marginBottom: 4 }}>
|
|
||||||
📄 {r.fileName} · 切片#{r.chunkIndex} · score {r.score.toFixed(3)}
|
📄 {r.fileName} · 切片#{r.chunkIndex} · score {r.score.toFixed(3)}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ color: '#374151', whiteSpace: 'pre-wrap' }}>
|
<div className="retrieved-item-preview">
|
||||||
{r.preview}
|
{r.preview}
|
||||||
{r.preview.length >= 200 ? '…' : ''}
|
{r.preview.length >= 200 ? '…' : ''}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -98,35 +67,26 @@ export function ToolCallView({ calls, liveStyle }: { calls: ToolCallTrace[]; liv
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
key: 'tc',
|
key: 'tc',
|
||||||
label: <span style={{ fontSize: 12, color: '#f97316' }}>🛠 工具调用 ({calls.length})</span>,
|
label: <span className="tool-call-label">🛠 工具调用 ({calls.length})<RightOutlined /></span>,
|
||||||
children: (
|
children: (
|
||||||
<div style={{ fontSize: 12 }}>
|
<div className="tool-call-list">
|
||||||
{calls.map((t, i) => {
|
{calls.map((t, i) => {
|
||||||
const isPending = (t.result as any)?.pending;
|
const isPending = (t.result as any)?.pending;
|
||||||
const isFailed = t.result?.ok === false;
|
const isFailed = t.result?.ok === false;
|
||||||
return (
|
return (
|
||||||
<div
|
<div key={i} className="tool-call-item">
|
||||||
key={i}
|
<div className="tool-call-item-header">
|
||||||
style={{
|
|
||||||
padding: 8,
|
|
||||||
background: '#fff7ed',
|
|
||||||
borderRadius: 6,
|
|
||||||
marginBottom: 6,
|
|
||||||
borderLeft: '3px solid #f97316'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div style={{ color: '#c2410c', fontWeight: 600, marginBottom: 4 }}>
|
|
||||||
⚙️ {t.name} {isPending && <Tag color="processing">运行中…</Tag>}
|
⚙️ {t.name} {isPending && <Tag color="processing">运行中…</Tag>}
|
||||||
{!isPending && t.result?.durationMs != null && <Tag>{t.result.durationMs}ms</Tag>}
|
{!isPending && t.result?.durationMs != null && <Tag>{t.result.durationMs}ms</Tag>}
|
||||||
{isFailed && <Tag color="error">失败</Tag>}
|
{isFailed && <Tag color="error">失败</Tag>}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ color: '#6b7280' }}>
|
<div className="tool-call-item-args">
|
||||||
<b>args:</b> {JSON.stringify(t.args)}
|
<b>args:</b> {JSON.stringify(t.args)}
|
||||||
</div>
|
</div>
|
||||||
{!isPending && (
|
{!isPending && (
|
||||||
<div style={{ color: '#374151', marginTop: 4 }}>
|
<div className="tool-call-item-result">
|
||||||
<b>result:</b>{' '}
|
<b>result:</b>{' '}
|
||||||
<code style={{ wordBreak: 'break-all' }}>
|
<code>
|
||||||
{JSON.stringify(t.result?.result ?? t.result?.error ?? t.result).slice(0, 500)}
|
{JSON.stringify(t.result?.result ?? t.result?.error ?? t.result).slice(0, 500)}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue