fix: 思考/工具明细完整展示,去掉省略号截断,过长加滚动条

This commit is contained in:
Rick Ye
2026-09-08 01:03:44 +08:00
parent d6e38f391a
commit 55fe7d1024
2 changed files with 24 additions and 18 deletions
@@ -114,7 +114,7 @@ export function Thinking({
<div <div
ref={scrollRef} ref={scrollRef}
onScroll={handleScroll} onScroll={handleScroll}
className={`mt-1 ml-[5px] pl-4 ${streaming ? 'max-h-[220px] overflow-y-auto' : ''}`} className={`mt-1 ml-[5px] overflow-y-auto pl-4 ${streaming ? 'max-h-[220px]' : 'max-h-[400px]'}`}
> >
<div className="relative"> <div className="relative">
<span aria-hidden className="absolute bottom-0 left-[3px] top-0 w-px bg-line" /> <span aria-hidden className="absolute bottom-0 left-[3px] top-0 w-px bg-line" />
@@ -143,11 +143,11 @@ export function Thinking({
) )
} }
/** 思考文本 → 行数组(空行剔除,超长行截断) */ /** 思考文本 → 行数组(空行剔除,内容不截断;过长由容器的滚动条承担) */
export function thinkingRows(text: string): { primary: string }[] { export function thinkingRows(text: string): { primary: string }[] {
return text return text
.split('\n') .split('\n')
.map((l) => l.trim()) .map((l) => l.trim())
.filter(Boolean) .filter(Boolean)
.map((line) => ({ primary: line.length > 300 ? `${line.slice(0, 300)}…` : line })) .map((line) => ({ primary: line }))
} }
@@ -198,9 +198,13 @@ function buildRow(view: ToolCallView, dupIndex: number): ToolRow {
) )
const resultText = extractResultText(tool.result) const resultText = extractResultText(tool.result)
if (resultText) { if (resultText) {
const lines = resultText.split('\n').slice(0, 10) // 完整输出,不逐行截断;过长由展开区的滚动条承担,仅在行数超限时兜底
for (const line of lines) detail.push({ text: line.slice(0, 160), tone: 'plain' }) const lines = resultText.split('\n')
if (resultText.split('\n').length > 10) detail.push({ text: '…(结果已截断)', tone: 'plain' }) const maxLines = 400
for (const line of lines.slice(0, maxLines)) detail.push({ text: line, tone: 'plain' })
if (lines.length > maxLines) {
detail.push({ text: `…(共 ${lines.length} 行,已截断)`, tone: 'plain' })
}
} }
} }
const args = tool?.args ?? view.pendingApproval?.args const args = tool?.args ?? view.pendingApproval?.args
@@ -237,7 +241,7 @@ function buildThinkingRows(texts: string[]): ToolRow[] {
file: '', file: '',
dir: '', dir: '',
chip: lines[0].length > 60 ? `${lines[0].slice(0, 60)}…` : lines[0], chip: lines[0].length > 60 ? `${lines[0].slice(0, 60)}…` : lines[0],
detail: lines.slice(0, 12).map((line) => ({ text: line.slice(0, 160), tone: 'plain' as const })), detail: lines.map((line) => ({ text: line, tone: 'plain' as const })),
tool: undefined, tool: undefined,
pending: false pending: false
}) })
@@ -336,22 +340,24 @@ export function ToolChips({ calls = [], thinking = [], className = '' }: {
{row.icon !== 'think' && <StatusMark tool={row.tool} pending={row.pending} />} {row.icon !== 'think' && <StatusMark tool={row.tool} pending={row.pending} />}
</button> </button>
{/* 展开明细 */} {/* 展开明细:完整内容不截断,过长时在滚动区里查看;收起时懒渲染不占 DOM */}
<div <div
className="grid transition-[grid-template-rows,opacity]" className="grid transition-[grid-template-rows,opacity]"
style={{ gridTemplateRows: rowOpen ? '1fr' : '0fr', opacity: rowOpen ? 1 : 0, transitionTimingFunction: 'ease' }} style={{ gridTemplateRows: rowOpen ? '1fr' : '0fr', opacity: rowOpen ? 1 : 0, transitionTimingFunction: 'ease' }}
> >
<div className="min-h-0 overflow-hidden"> <div className="min-h-0 overflow-hidden">
<div className="mt-0.5 mb-1 ml-2 flex flex-col gap-0.5 border-l border-line py-0.5 pl-3.5"> {rowOpen && (
{row.detail.map((line, lineIndex) => ( <div className="mt-0.5 mb-1 ml-2 flex max-h-[320px] flex-col gap-0.5 overflow-y-auto border-l border-line py-0.5 pl-3.5">
<span {row.detail.map((line, lineIndex) => (
key={`${lineIndex}-${line.text.slice(0, 12)}`} <span
className={`truncate text-[11.5px] leading-[1.6] ${row.icon === 'think' ? '' : 'font-mono'} ${DETONE_CLASS[line.tone ?? 'plain']}`} key={`${lineIndex}-${line.text.slice(0, 12)}`}
> className={`whitespace-pre-wrap break-words text-[11.5px] leading-[1.6] ${row.icon === 'think' ? '' : 'font-mono'} ${DETONE_CLASS[line.tone ?? 'plain']}`}
{line.text} >
</span> {line.text}
))} </span>
</div> ))}
</div>
)}
</div> </div>
</div> </div>
</div> </div>