背景
当前 TUI 中 @ 文件引用只提供自动补全功能(file-mention-provider.ts),用户提交消息后 @path/to/file 作为原始文本发给 LLM。LLM 要获取文件内容,仍需自行调用 Read tool,多一轮工具调用的开销。
提议
在 turn 启动时(applyUserPromptHook 之后、step loop 之前),解析用户输入中的 @ 文件引用,调用 ReadTool 预读文件内容,将合成的 assistant + tool result 消息注入 context。LLM 看到的效果等同于自己已经调用过 Read tool,可直接基于文件内容回答。
动机
- 减少一轮 tool call 往返,加快首次响应
- 用户显式
@ 了文件,说明意图明确——预读符合直觉
- 与 Claude Code 等竞品的
@ 行为对齐(引用即注入)
设计要点
- 复用 ReadTool — 预读走
ReadTool.resolveExecution().execute(),继承二进制检测、NUL 字节校验、MAX_BYTES/MAX_LINES 限制、CRLF 处理等全部逻辑,无重复代码
- 路径过滤 — 只匹配看起来像文件路径的 token(含
/ 或扩展名 .,加常见无扩展名文件 allowlist),避免误匹配 email、version pin、commit hash
- Workspace 对齐 — 使用 ToolManager 持有的 workspace(含 skill roots + additionalDirs),与 builtin Read tool 路径访问策略一致
- 事件发射 — 发射
tool.call.started / tool.result 事件,TUI 正常渲染 "Read xxx" 卡片
- 并行读取 —
Promise.all 并行读取,接受 turn 的 AbortSignal,支持用户取消
- 上限 — 单条消息最多预读 5 个文件
- 时机 — 在
UserPromptSubmit hook 之后注入,hook block 时不会污染 history
开放问题
- 是否需要对预读失败(文件不存在、超出 workspace)向用户显示提示?当前静默跳过。
pendingToolResultIds 同步:合成消息直接 appendMessage 不走 loop event 路径,是否需要额外处理以兼容 compaction?
参考实现
我在 fork 上有一份初步实现:feat/preread-file-mentions,涉及文件:
packages/agent-core/src/agent/turn/file-mention.ts(提取 + 读取)
packages/agent-core/src/agent/turn/index.ts(集成到 turn)
packages/agent-core/src/agent/tool/index.ts(暴露 workspace)
- 23 个单元测试通过
背景
当前 TUI 中
@文件引用只提供自动补全功能(file-mention-provider.ts),用户提交消息后@path/to/file作为原始文本发给 LLM。LLM 要获取文件内容,仍需自行调用 Read tool,多一轮工具调用的开销。提议
在 turn 启动时(
applyUserPromptHook之后、step loop 之前),解析用户输入中的@文件引用,调用 ReadTool 预读文件内容,将合成的 assistant + tool result 消息注入 context。LLM 看到的效果等同于自己已经调用过 Read tool,可直接基于文件内容回答。动机
@了文件,说明意图明确——预读符合直觉@行为对齐(引用即注入)设计要点
ReadTool.resolveExecution().execute(),继承二进制检测、NUL 字节校验、MAX_BYTES/MAX_LINES 限制、CRLF 处理等全部逻辑,无重复代码/或扩展名.,加常见无扩展名文件 allowlist),避免误匹配 email、version pin、commit hashtool.call.started/tool.result事件,TUI 正常渲染 "Read xxx" 卡片Promise.all并行读取,接受 turn 的AbortSignal,支持用户取消UserPromptSubmithook 之后注入,hook block 时不会污染 history开放问题
pendingToolResultIds同步:合成消息直接 appendMessage 不走 loop event 路径,是否需要额外处理以兼容 compaction?参考实现
我在 fork 上有一份初步实现:
feat/preread-file-mentions,涉及文件:packages/agent-core/src/agent/turn/file-mention.ts(提取 + 读取)packages/agent-core/src/agent/turn/index.ts(集成到 turn)packages/agent-core/src/agent/tool/index.ts(暴露 workspace)