修复: read_file/grep 工具结果处理

BUG-260625-01 grep 单文件路径走 grep_one_file(旧 read_dir 报 os error 267 目录无效);BUG-260625-02 read_file search 模式渲染命中行 matches(旧取 content 显 0 行误判读取失败)。
This commit is contained in:
2026-06-25 00:27:02 +08:00
parent 24c3fa08f1
commit 047b3b91fa
3 changed files with 156 additions and 103 deletions

View File

@@ -2,19 +2,33 @@
<!-- 结果展示区( ToolCard.vue 抽离,纯渲染,逻辑等价)
分支顺序/条件/文案与原 ToolCard.vue 一字不变,仅搬运行内联模板 -->
<!-- read_file 结果:代码预览 -->
<!-- read_file 结果:全文预览(默认)/ 命中行(search 模式) -->
<div v-if="tc.name === 'read_file' && tc.result && tc.status === 'completed' && parsed" class="ai-tool-file-content">
<div class="ai-tool-file-bar">
<span class="ai-tool-file-icon" v-html="fileIcon"></span>
<span class="ai-tool-file-path">{{ parsed?.path }}</span>
<span class="ai-tool-file-meta">{{ parsed?.has_more
<!-- BUG-260625-02: search 模式返回 matches(命中行) content,
旧模板取 lines/returned_lines 0 + content ,用户误以为读取失败
search 模式显搜索词 + 命中数(复用 grepHitsN 文案);默认模式显行数/大小 + 展开 -->
<span v-if="parsed?.search" class="ai-tool-file-meta">{{ parsed?.search }} {{ $t('aiTool.grepHitsN', { n: typeof parsed?.total === 'number' ? parsed.total : (parsed?.matches?.length || 0) }) }}</span>
<span v-else class="ai-tool-file-meta">{{ parsed?.has_more
? $t('aiTool.linesTruncated', { shown: parsed?.returned_lines ?? 0, total: parsed?.lines ?? 0 })
: `${parsed?.lines || 0} ${$t('aiTool.lines')}` }} · {{ formatBytes(parsed?.size) }}</span>
<button class="ai-tool-expand-btn" @click="emit('expand-content', tc.id)">
<button v-if="!parsed?.search" class="ai-tool-expand-btn" @click="emit('expand-content', tc.id)">
{{ isContentExpanded ? $t('aiTool.collapse') : $t('aiTool.expand') }}
</button>
</div>
<pre class="ai-tool-file-pre" :class="{ 'ai-tool-file-pre--collapsed': !isContentExpanded }"><code>{{ parsed?.content }}</code></pre>
<!-- search 模式:命中行渲染(复用 grep content 样式;read_file matches {line,content} file) -->
<div v-if="parsed?.search && parsed?.matches?.length" class="ai-tool-grep-matches">
<div v-for="(m, i) in parsed?.matches" :key="i" class="ai-tool-grep-match">
<div v-if="m.line !== null && m.line !== undefined" class="ai-tool-grep-match-head">
<span class="ai-tool-grep-line">:{{ m.line }}</span>
</div>
<code class="ai-tool-grep-content">{{ m.content }}</code>
</div>
</div>
<!-- 默认模式:全文预览 -->
<pre v-else class="ai-tool-file-pre" :class="{ 'ai-tool-file-pre--collapsed': !isContentExpanded }"><code>{{ parsed?.content }}</code></pre>
</div>
<!-- list_directory 结果:文件树 -->

View File

@@ -85,6 +85,8 @@ export interface ToolResult {
body?: string
body_bytes?: number
elapsed_ms?: number
// read_file search 模式(BUG-260625-02):传 search 参数返命中行 matches[{line,content}] 非全文 content
search?: string
// grep 跨文件内容搜索结果字段(F-260621):
// - output_mode: content(默认)/ files_with_matches / count
// - matches: content 模式命中行 [{file,line,content,context?}]