Skip to content

fix(chat): K-brain 会话的文件链接能打开,右键可打开所在目录或用默认应用打开,Image 结果能显示 - #1124

Merged
AlphaCatMeow merged 1 commit into
Stack-Cairn:mainfrom
AlphaCatMeow:fix-chat-file-link-kbrain
Nov 2, 2026
Merged

AlphaCatMeow merged 1 commit into
Stack-Cairn:mainfrom
AlphaCatMeow:fix-chat-file-link-kbrain

Conversation

@AlphaCatMeow

@AlphaCatMeow AlphaCatMeow commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

K-brain 模式下代理生成的产物(包括系统临时目录里的临时产物)在聊天里打不开:点文件链接报 The conversation is unavailable on this device.;文件链接没有右键菜单,Office 等没有内置预览的文件无法交给默认应用;成功的 Image 调用在聊天里什么都不显示。本 PR 修复链接打开、加上文件与网址的右键菜单,并让 K-brain 的 Image 结果在桌面与 WebUI 显示。

Closes #1123
Depends-On: none
Stack-Root: #1124

Image 工具本身的报错(空占位、url/base64 字段里的路径、临时目录图片被拒)在 K-brain 侧修复:Stack-Cairn/K-brain#79(Closes Stack-Cairn/K-brain#78)。它合入发版后再单独开锁版本 PR,本 PR 不依赖它。

改动

  • 文件链接按会话找工作目录(chat_file_links.rs):原来只查桌面本地历史库,K-brain 会话不在库里就报 unavailable。现在先问"当前拥有这段历史的一方",本地库作回退,两边都没有仍拒绝。
    • 桌面窗口:用窗口传来的当前会话工作目录(窗口本来就能用任意目录调 fs 命令,不扩大可访问范围)。
    • WebUI 经网关:不采信请求里的目录,由 GatewayController::kbrain_conversation_workdir 经 composer action 让桌面前端按自己的会话记录查询(K-brain 模式查 K-brain,否则查本地库)。迁移过来的旧会话也以当前历史为准,不再用本地库里过期的 cwd。
  • 文件链接右键菜单(ChatFileLinkContextMenu.tsx、chatFileLinkContextMenuStore.ts):打开文件、打开所在目录;桌面端另有"用默认应用打开"(html/htm/xhtml/svg 显示为"用默认浏览器打开")。每个对话区挂一个宿主,多窗格只由第一个渲染;菜单项再点击一次被右键的链接按钮,所以执行的是链接当前的回调(窗格切换会话后不会用旧会话打开),链接已卸载时不执行。WebUI 不显示默认应用一项(在桌面主机上启动应用对远端用户没有意义;网关路径固定传 false)。
  • 默认应用打开的安全边界(Rust):只放行文档、媒体、网页类白名单(Office、PDF、图片、音视频、html、md、txt、json 等);拒绝脚本、可执行文件、带宏的 OOXML(docm/xlsm/pptm…)、带 shebang 的文件和含逗号的路径;Windows 上 explorer.exe 打开时路径一律加引号(未加引号时逗号会把 run.bat,a.pdf 拆成 run.bat)。打开所在目录对所有类型可用,只定位不启动。
  • Office 无预览文件:pptx、odt、vsdx 等左键原来报"不能安全打开",现在在文件管理器中定位。
  • 网址链接右键菜单:第一行显示目标地址,可用默认浏览器打开或复制链接(左键原有的外链确认不变)。
  • K-brain Image 结果显示(toolImages.ts):K-brain 返回了图片,但前端没有为成功的 Image 生成 display_image 详情,转录区把这一行整个隐藏;图片 data 还保留着完整 data URL,渲染时会再拼一次前缀。现在实时(turn.ts)与历史(history.ts)结果都把 data URL 拆成纯 base64 + MIME,Image 结果生成 display_image 详情(远程 https 图走现有代理),WebUI 实时同步的 tool_result 事件带上该详情。computer 截图等其他工具图片也因此不再是双前缀。

契约地图

生产者 消费者 已更新 测试
ChatFileLink.openInFileManager(菜单) useChatFileLinkNavigation → openChatFileLink → 桌面 Tauri 命令 / WebUI shim → proto open_in_file_manager(字段 8,已有)→ Rust 是(文件也生效) open_in_file_manager_reveals_files_of_every_type_without_launching
ChatFileLink.openWithDefaultApp(菜单,仅桌面) openChatFileLink → Tauri 命令新可选参数 open_with_default_app 是;网关路径固定 false,proto 不变 default_app_*、chat-file-link-menu-intent
打开链接的会话工作目录 桌面命令 / 网关 ChatFileOpen 是 conversation_workdir_*、chat-file-links.test.mjs
K-brain tool.result 图片 桌面实时 turn.ts、历史 history.ts、WebUI 实时 tool_result 事件(details) 是 kbrain-image-tool-results、review-kbrain-image-webui-live、kbrain-turn
网关直连 K-brain(events.go) WebUI 否:该模式日常不用,按 LA-4b 暂不做 —

验证

  • 基线:upstream/main 643f581(已包含 v2-kbrian)。
  • 静态:typecheck:ui / typecheck:gui / typecheck:webui 通过;改动文件 LF 后 biome check --line-ending=lf 通过;node scripts/check-mirror.mjs 通过;git diff --check 通过;改动的 Rust 文件 rustfmt 通过(envelope_handler.rs 1502/1510 行为基线原有格式差异,未动)。
  • Rust:cargo test --lib -- chat_file_links windows_open windows_reveal gateway 144 通过 0 失败(独立 CARGO_TARGET_DIR,避开运行中的调试版)。
  • 全量(la-full-tests.mjs,8 个批次全部跑完):4488 条,通过 4479,失败 8,跳过 1。失败均与本 PR 无关:
    • 已知环境失败(known-failures.json):Tauri cargo 套件首次编译超时、两条按 CWD 读源码的用例。
    • permission-modes-backend、kbrain-trajectory ×2:真实 K-brain 进程里 bash 未实际执行("child must really execute bash"),这两个测试及其加载的模块都不在本 diff 内。
  • 新增/更新测试:chat-file-link-context-menu、chat-file-link-menu-intent、chat-file-link-menu-pane-switch、kbrain-image-tool-results、review-chat-file-link-default-app-comma、review-chat-url-menu-confirmation、review-kbrain-image-webui-live、chat-file-links、markdown-image-policy、kbrain-turn;Rust 新增 conversation_workdir_*、default_app_*、office_documents_without_a_preview_reveal_on_a_plain_click、open_in_file_manager_reveals_*、windows_open_quotes_paths_so_commas_cannot_split_them 等。
  • 对抗复审 6 轮:第 1 轮 2 P2(多窗格点菜单抢焦点;迁移会话用过期 cwd),第 2 轮 1 P2(菜单冻结右键时的回调,后台窗格切会话后打开错会话),第 4 轮 1 P1 / 1 P2(逗号让 explorer 打开另一个文件;网址菜单绕过外链确认且不显示地址),第 5 轮 1 P2(WebUI 实时不显示 Image),全部修复并保留回归;第 3、6 轮"未发现阻止合并的问题"。
  • 真机(Windows,当前分支 tauri dev 调试版 + MCP bridge;WebUI gateway-webui-dev 连调试版托管的网关):
场景 桌面 WebUI
K-brain 会话里点 %TEMP% 下的 report.md / chart.png 编辑器 / 预览打开,不再报 unavailable 编辑器打开(经网关)
编辑并保存临时目录里的 report.md 写入成功 编辑器里输入并保存,磁盘文件更新
右键文件链接 → 打开所在目录 资源管理器打开到产物目录 菜单项存在(在桌面主机执行)
右键 page.html → 用默认浏览器打开 Edge 打开该页(加引号后复验) 不显示该项
左键 deck.pptx 资源管理器定位,无报错 —
右键网址 显示 https://example.com/、打开 / 复制 真实点击"复制链接",系统剪贴板为该网址
模型用 Image 显示 %TEMP% 图片(配合 K-brain#79 本地编译的 sidecar) 实时与刷新后历史均显示 从 WebUI 发起的会话实时显示
390 宽度菜单 无横向溢出、文字未截断 同左

截图

桌面:临时目录 report.md 在编辑器打开 / chart.png 预览 / 文件链接右键菜单 / 网页文件"用默认浏览器打开" / 网址菜单显示目标地址 / 390 宽度 / Image 结果显示






WebUI:编辑保存 / 文件链接菜单(无默认应用项)/ 网址菜单 / 390 宽度 / Image 实时显示




未覆盖

  • macOS / Linux 的打开与定位只在 CI 与代码层面确认;macOS bundle 一类目录仍由 is_active_directory 拒绝。
  • WebUI 下"打开所在目录"在桌面主机执行,远端用户看不到结果(沿用原有 reveal 语义)。
  • 有选中文本时右键链接,显示链接菜单而不是"复制选中文本"。
  • 网关直连 K-brain 模式(events.go)的 Image 显示未改。
  • legacy doc/xls/ppt 允许用默认应用打开(Office 运行宏前会询问)。

🤖 Generated with Claude Code

- 打开聊天文件链接时按会话查工作目录:K-brain 会话不在本地历史库,原来报
  "The conversation is unavailable on this device."。桌面窗口用当前会话的工作
  目录;WebUI 经网关由桌面前端按 K-brain 会话记录查询,不采信请求里的目录;
  迁移来的旧会话也以当前历史为准,本地库只作回退
- 文件链接右键:打开文件、打开所在目录;桌面端另有"用默认应用打开"(网页文件
  为"用默认浏览器打开"),仅放行文档/媒体/网页类,拒绝脚本、可执行、带宏
  Office 与含逗号的路径;Windows 打开时路径一律加引号
- 网址链接右键:显示目标地址,用默认浏览器打开或复制链接
- 没有内置预览的 Office 文件(pptx、odt 等)左键改为在文件管理器中定位
- K-brain 模式下成功的 Image 调用原来什么都不显示:实时与历史结果都转换成
  display_image,data URL 只保留一次前缀,远程图片走代理

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@AlphaCatMeow
AlphaCatMeow merged commit fc4c41f into Stack-Cairn:main Nov 2, 2026
15 checks passed
@AlphaCatMeow
AlphaCatMeow deleted the fix-chat-file-link-kbrain branch November 2, 2026 09:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant