From f92f984d3dad43ae138a4c2b0b5ef2733d97fb11 Mon Sep 17 00:00:00 2001 From: creatixchu Date: Wed, 16 Sep 2026 19:48:48 +0800 Subject: [PATCH 1/7] docs(notes): propose one card per delivered changed file --- ...09-16-delivered-file-single-card.i18n.yaml | 6 +++ .../2026-09-16-delivered-file-single-card.md | 41 +++++++++++++++++++ ...026-09-16-delivered-file-single-card.zh.md | 41 +++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 .agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.i18n.yaml create mode 100644 .agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.md create mode 100644 .agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.zh.md diff --git a/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.i18n.yaml b/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.i18n.yaml new file mode 100644 index 0000000000..cc205c7391 --- /dev/null +++ b/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.i18n.yaml @@ -0,0 +1,6 @@ +# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each +# side as of the last confirmed-consistent state. Both languages carry equal authority; +# after editing either side, bring the other along and re-record with: +# pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.md +2026-09-16-delivered-file-single-card.md: 65edb58a97a3c67550df37a4172863faa9d2eae4 +2026-09-16-delivered-file-single-card.zh.md: c21857071184fc3a5f4d97eb524606f465c82ae1 diff --git a/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.md b/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.md new file mode 100644 index 0000000000..65edb58a97 --- /dev/null +++ b/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.md @@ -0,0 +1,41 @@ +# Agent Note: One card per delivered changed file + +Status: proposed + +English | [中文](2026-09-16-delivered-file-single-card.zh.md) + +## Problem + +A finished turn ends with two file surfaces: the [changed-files card](../../implemented/feature/2026-09-11-turn-changed-files-card.md) lists every file the turn changed with its line counts and opens the [review tab](../../implemented/feature/2026-09-15-changed-file-diff-preview.md) on that file, and a delivery card for every file the model declared through [present](../../implemented/feature/2026-09-08-present-workspace-source-files.md) previews it in the Sidebar and opens it natively. A file the turn both changed and delivered appears in both, and the second appearance tells the user nothing new; the recorded `changed-files-turn` scenario shows four files as four rows and four cards. + +The two surfaces differ in what they offer and how long they live. The row carries counts and the comparison; the card carries the model's description, the preview, and the native actions. The card's content lives only in the Host process, so a conversation reopened after a Host restart has no changed-files card, while `deliverables/presented` events persist in the Session log and their cards come back. + +## Proposal + +Render a file the turn both changed and delivered once, on its delivery card. The changed-files card drops that file's row and keeps its header, which still names the turn's complete file count and summed counts and still opens the review on the turn; when every changed file was delivered only the header remains. The delivery card gains the file's added and deleted lines, or its binary or oversized label, beside the file name, and that label opens the review tab on the file, so the comparison, the preview, the native actions, and the description stay available from one place. Files only changed or only delivered render as before, and turns never share data. + +Matching is lexical, on the Client, at render time: separators normalized to `/`, `.` segments dropped, `..` folded, and an absolute path under the Session working directory stated relative to it. Repeated deliveries of one file in a turn merge under the same key, keeping the latest description. Two spellings that meet only through a symbolic link stay distinct. + +Nothing durable changes: no Session event, no Host route, and no recorder change; the merge lives in `packages/client/ui-deliverables` beside the card derivation. After a Host restart the changed-files card is absent and the delivery cards render as today, without a special case. + +## Alternatives considered + +**Keeping the row and dropping the card** costs less code, but turns a deliverable's default entry from the preview into the comparison: a report or SVG becomes one diff row, and a binary deliverable becomes a `binary` label with no preview at all. + +**Asking the model not to `present` files the changed-files card will list** cannot work: the `workspace/changes` event is never model-visible and its coverage depends on git, ignore rules, the file cap, and temporary-directory exclusion; `present` is shared by the `standard`, `ptc`, and `cordis` presets whose headless and SDK consumers have no changed-files card; and after a Host restart an undelivered file has no entry at all. The tool description also requires delivering every requested output, which the [delivery decision](../../implemented/feature/2026-09-08-present-workspace-source-files.md) settled. + +**One combined card** that lists every changed file with delivery actions on the delivered rows would merge two surfaces with different lifetimes into one and reopen the card design; the proposal keeps both surfaces and moves only the duplicate. + +## Acceptance criteria + +- A file both changed and delivered in one turn renders one delivery card and no changed-files row; the header count and totals still cover it. +- The delivery card shows the file's counts, and that label opens the turn's review tab on the file; preview, native actions, and the description remain. +- Repeated deliveries of one file in a turn render one card; files with the same basename in different directories render separately. +- Reloading the page renders the same result as the first render; after a Host restart the delivery cards render without the changed-files card. +- The `changed-files-turn` and `present-svg` recorded scenarios and the package unit tests cover the merge. + +## Risks + +- A delivery spelled through a symbolic link, or with an absolute path outside the working directory that the recorder spelled differently, is not matched and renders twice; the README lists this as a known limitation. +- A changed-files card reduced to its header may read as incomplete; the header keeps the complete count so the review still lists every file. +- The counts label on a 60px delivery card competes for space with long file names; the design of that label is open until a design is agreed. diff --git a/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.zh.md b/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.zh.md new file mode 100644 index 0000000000..c218570711 --- /dev/null +++ b/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.zh.md @@ -0,0 +1,41 @@ +# Agent Note: 交付的改动文件只显示一张卡片 + +Status: proposed + +[English](2026-09-16-delivered-file-single-card.md) | 中文 + +## 问题 + +一轮结束时有两个文件区块:[改动文件卡片](../../implemented/feature/2026-09-11-turn-changed-files-card.zh.md)列出本轮改动的每个文件及其增删行数,并在该文件上打开 [review tab](../../implemented/feature/2026-09-15-changed-file-diff-preview.zh.md);模型通过 [present](../../implemented/feature/2026-09-08-present-workspace-source-files.zh.md) 声明的每个文件有一张交付卡片,在 Sidebar 中预览并用原生应用打开。本轮既改动又交付的文件在两处都出现,第二次出现没有给用户任何新信息;录制的 `changed-files-turn` 场景里四个文件显示为四行加四张卡片。 + +两个区块提供的东西和寿命都不同。行有行数和对比;卡片有模型写的说明、预览和原生操作。卡片的内容只活在 Host 进程里,Host 重启后重新打开的会话没有改动文件卡片,而 `deliverables/presented` 事件持久化在 Session log 里,它们的卡片会回来。 + +## 提议 + +本轮既改动又交付的文件只显示一次,显示在交付卡片上。改动文件卡片去掉该文件的行,保留头部;头部仍写本轮完整的文件数和汇总行数,仍在本轮上打开 review;所有改动文件都被交付时只剩头部。交付卡片在文件名旁补上该文件的增删行数,或二进制、过大标签,点击该标签在该文件上打开 review tab,这样对比、预览、原生操作和说明都从同一处可达。只改动或只交付的文件照旧显示,不同轮次之间不共享数据。 + +匹配在 Client 渲染时按词法进行:分隔符统一为 `/`,去掉 `.` 段,折叠 `..`,落在 Session 工作目录下的绝对路径改写为相对路径。同一轮内重复交付同一文件按同一个键合并,保留最新的说明。只经软链才相同的两种拼写保持不同。 + +持久化的东西都不变:没有新的 Session 事件、没有 Host 路由、recorder 不改;合并逻辑放在 `packages/client/ui-deliverables` 里卡片推导的旁边。Host 重启后改动文件卡片不存在,交付卡片按现在的方式渲染,不需要特殊处理。 + +## 考虑过的替代方案 + +**保留行、去掉卡片**代码更少,但交付物的默认入口从预览变成对比:一份报告或 SVG 变成一行 diff,二进制交付物变成一个「二进制」标签,完全没有预览。 + +**让模型不要 `present` 改动文件卡片会列出的文件**行不通:`workspace/changes` 事件从不进模型上下文,它的覆盖范围取决于 git、ignore 规则、文件数上限和临时目录排除;`present` 由 `standard`、`ptc`、`cordis` 三个 preset 共用,它们的 headless 和 SDK 消费者没有改动文件卡片;Host 重启后没交付的文件就没有任何入口。工具描述也要求交付用户要的每个产出,这是[交付决定](../../implemented/feature/2026-09-08-present-workspace-source-files.zh.md)定下的。 + +**一张合并卡片**,列出每个改动文件并在被交付的行上放交付操作,会把两个寿命不同的区块并成一个,并重开卡片设计;本提议保留两个区块,只挪走重复的那份。 + +## 验收标准 + +- 同一轮既改动又交付的文件只显示一张交付卡片,没有改动文件行;头部的数量和汇总仍包含它。 +- 交付卡片显示该文件的行数,点击该标签在该文件上打开本轮的 review tab;预览、原生操作和说明都保留。 +- 同一轮重复交付同一文件只显示一张卡片;不同目录下同名的文件分别显示。 +- 重新加载页面后的渲染结果与首次一致;Host 重启后交付卡片照常渲染,没有改动文件卡片。 +- `changed-files-turn` 和 `present-svg` 录制场景以及本包单测覆盖这次合并。 + +## 风险 + +- 经软链拼写的交付,或 recorder 拼法不同的工作目录外绝对路径,不会被匹配到,仍显示两次;README 把它列为已知限制。 +- 只剩头部的改动文件卡片可能显得不完整;头部保留完整数量,review 仍列出每个文件。 +- 60px 高的交付卡片上,行数标签会和长文件名争空间;该标签的样式在设计定下之前保持开放。 From 28fbe7433da43d8fb72f66258ad67f1324fc4ac6 Mon Sep 17 00:00:00 2001 From: creatixchu Date: Fri, 18 Sep 2026 16:31:13 +0800 Subject: [PATCH 2/7] fix: guide selective file presentation through prompts --- ...8-present-workspace-source-files.i18n.yaml | 4 +- ...26-09-08-present-workspace-source-files.md | 2 +- ...09-08-present-workspace-source-files.zh.md | 2 +- ...09-16-delivered-file-single-card.i18n.yaml | 6 --- .../2026-09-16-delivered-file-single-card.md | 41 ------------------- ...026-09-16-delivered-file-single-card.zh.md | 41 ------------------- docs/tool-catalog.i18n.yaml | 4 +- docs/tool-catalog.md | 2 +- docs/tool-catalog.zh.md | 2 +- .../client/ui-deliverables/README.i18n.yaml | 4 +- packages/client/ui-deliverables/README.md | 6 +-- packages/client/ui-deliverables/README.zh.md | 6 +-- packages/client/ui-deliverables/src/index.ts | 6 ++- .../tool-present/README.i18n.yaml | 4 +- packages/deliverables/tool-present/README.md | 2 +- .../deliverables/tool-present/README.zh.md | 2 +- .../deliverables/tool-present/src/index.ts | 9 ++-- 17 files changed, 30 insertions(+), 113 deletions(-) delete mode 100644 .agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.i18n.yaml delete mode 100644 .agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.md delete mode 100644 .agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.zh.md diff --git a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml index 0458b32e17..5e0dc05743 100644 --- a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md -2026-09-08-present-workspace-source-files.md: e1bc2bbc56d423741ca53550af2879fed3f01ecf -2026-09-08-present-workspace-source-files.zh.md: e4f21172b36a5fef50e44a79adca71011ee90a3b +2026-09-08-present-workspace-source-files.md: 1ab40bdf8b88c73ddb40b071281842ef7b2e3ac1 +2026-09-08-present-workspace-source-files.zh.md: 8f389b97f3a388affc3b49cbb532f69c127336fc diff --git a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md index e1bc2bbc56..1ab40bdf8b 100644 --- a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md +++ b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md @@ -12,7 +12,7 @@ Users need to open and edit the files produced in their workspace, including she The [present tool](../../../../packages/deliverables/tool-present/README.md) declares existing regular source files under the [Session filesystem access policy](2026-09-09-present-filesystem-access.md). It records paths and optional descriptions without reading or copying contents. The [deliverables plugin](../../../../packages/client/ui-deliverables/README.md) opens current workspace sources in the Host's default application. Edits are visible on the next open; deletion or movement makes the declaration unavailable. File-content preservation and copy-on-write storage are deferred until a persistence design owns them. -The tool description requires `present` after writing a file the user asked to receive and before the final response, including files created through Bash or code execution. A prose path reference does not replace the call. The recorded [SVG delivery scenario](../../../../snapshots/web/present-svg/snapshot.yml) uses a user request that does not name `present`, and checks the resulting file, delivery event, and card. Its UI snapshot covers the expanded Chat transcript; navigation and composer controls belong to their own scenarios, so unrelated chrome changes cannot invalidate file-delivery expectations. +The [tool description](../../../../packages/deliverables/tool-present/README.md#model-experience) guides the model’s choice of files for explicit delivery. A declaration remains distinct from a prose file reference. The recorded [SVG delivery scenario](../../../../snapshots/web/present-svg/snapshot.yml) uses a user request that does not name `present`, and checks the resulting file, delivery event, and card. Its UI snapshot covers the expanded Chat transcript; navigation and composer controls belong to their own scenarios, so unrelated chrome changes cannot invalidate file-delivery expectations. The tool remains an ordinary package with shared filesystem and tool error classes. Its pure type entry owns the delivery event without importing Host code into the browser. The `standard`, `ptc`, and `cordis` presets mount it; `minimal` retains its two tools. Each plugin instance correlates its executions with successful final `tools/result` notifications before appending `deliverables/presented`. Native and nested calls share this rule. A later enclosing program failure does not revoke a completed nested declaration; blocked results publish none, and same-name scoped replacements cannot publish another instance's results. diff --git a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.zh.md b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.zh.md index e4f21172b3..8f389b97f3 100644 --- a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.zh.md +++ b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.zh.md @@ -12,7 +12,7 @@ Status: implemented [present 工具](../../../../packages/deliverables/tool-present/README.zh.md)声明交付[Session 文件系统访问策略](2026-09-09-present-filesystem-access.zh.md)允许的已有普通源文件。它记录路径和可选说明,不读取或复制内容。[交付插件](../../../../packages/client/ui-deliverables/README.zh.md)使用 Host 默认应用打开当前工作区源文件。下次打开会看到编辑后的内容;删除或移动文件会使声明不可用。文件内容保留与写时复制存储延期到有持久化设计负责时实现。 -工具说明要求在写好用户要求接收的文件后、最终回复前调用 `present`,包括通过 Bash 或代码执行创建的文件。正文中的路径引用不能替代调用。录制的 [SVG 交付场景](../../../../snapshots/web/present-svg/snapshot.yml)使用未提及 `present` 的用户请求,检查生成文件、交付事件和卡片。其 UI 快照覆盖展开后的 Chat 对话内容;导航和输入框控件由各自场景负责,避免无关界面改动使文件交付预期失效。 +[工具说明](../../../../packages/deliverables/tool-present/README.zh.md#model-experience)指导模型选择需要显式交付的文件。交付声明与正文中的文件引用各自独立。录制的 [SVG 交付场景](../../../../snapshots/web/present-svg/snapshot.yml)使用未提及 `present` 的用户请求,检查生成文件、交付事件和卡片。其 UI 快照覆盖展开后的 Chat 对话内容;导航和输入框控件由各自场景负责,避免无关界面改动使文件交付预期失效。 工具保持为普通包,共享文件系统和工具错误类型。其纯类型入口拥有交付事件,不向浏览器导入 Host 代码。`standard`、`ptc` 与 `cordis` preset 挂载工具;`minimal` 保持两个工具。每个插件实例将其执行与成功的最终 `tools/result` 通知关联,再追加 `deliverables/presented`。原生与嵌套调用遵循同一规则。外层程序随后失败不会撤销已完成的嵌套声明;被阻止的结果不发布声明,同名作用域替换也不能发布其他实例的结果。 diff --git a/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.i18n.yaml b/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.i18n.yaml deleted file mode 100644 index cc205c7391..0000000000 --- a/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.i18n.yaml +++ /dev/null @@ -1,6 +0,0 @@ -# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each -# side as of the last confirmed-consistent state. Both languages carry equal authority; -# after editing either side, bring the other along and re-record with: -# pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.md -2026-09-16-delivered-file-single-card.md: 65edb58a97a3c67550df37a4172863faa9d2eae4 -2026-09-16-delivered-file-single-card.zh.md: c21857071184fc3a5f4d97eb524606f465c82ae1 diff --git a/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.md b/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.md deleted file mode 100644 index 65edb58a97..0000000000 --- a/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.md +++ /dev/null @@ -1,41 +0,0 @@ -# Agent Note: One card per delivered changed file - -Status: proposed - -English | [中文](2026-09-16-delivered-file-single-card.zh.md) - -## Problem - -A finished turn ends with two file surfaces: the [changed-files card](../../implemented/feature/2026-09-11-turn-changed-files-card.md) lists every file the turn changed with its line counts and opens the [review tab](../../implemented/feature/2026-09-15-changed-file-diff-preview.md) on that file, and a delivery card for every file the model declared through [present](../../implemented/feature/2026-09-08-present-workspace-source-files.md) previews it in the Sidebar and opens it natively. A file the turn both changed and delivered appears in both, and the second appearance tells the user nothing new; the recorded `changed-files-turn` scenario shows four files as four rows and four cards. - -The two surfaces differ in what they offer and how long they live. The row carries counts and the comparison; the card carries the model's description, the preview, and the native actions. The card's content lives only in the Host process, so a conversation reopened after a Host restart has no changed-files card, while `deliverables/presented` events persist in the Session log and their cards come back. - -## Proposal - -Render a file the turn both changed and delivered once, on its delivery card. The changed-files card drops that file's row and keeps its header, which still names the turn's complete file count and summed counts and still opens the review on the turn; when every changed file was delivered only the header remains. The delivery card gains the file's added and deleted lines, or its binary or oversized label, beside the file name, and that label opens the review tab on the file, so the comparison, the preview, the native actions, and the description stay available from one place. Files only changed or only delivered render as before, and turns never share data. - -Matching is lexical, on the Client, at render time: separators normalized to `/`, `.` segments dropped, `..` folded, and an absolute path under the Session working directory stated relative to it. Repeated deliveries of one file in a turn merge under the same key, keeping the latest description. Two spellings that meet only through a symbolic link stay distinct. - -Nothing durable changes: no Session event, no Host route, and no recorder change; the merge lives in `packages/client/ui-deliverables` beside the card derivation. After a Host restart the changed-files card is absent and the delivery cards render as today, without a special case. - -## Alternatives considered - -**Keeping the row and dropping the card** costs less code, but turns a deliverable's default entry from the preview into the comparison: a report or SVG becomes one diff row, and a binary deliverable becomes a `binary` label with no preview at all. - -**Asking the model not to `present` files the changed-files card will list** cannot work: the `workspace/changes` event is never model-visible and its coverage depends on git, ignore rules, the file cap, and temporary-directory exclusion; `present` is shared by the `standard`, `ptc`, and `cordis` presets whose headless and SDK consumers have no changed-files card; and after a Host restart an undelivered file has no entry at all. The tool description also requires delivering every requested output, which the [delivery decision](../../implemented/feature/2026-09-08-present-workspace-source-files.md) settled. - -**One combined card** that lists every changed file with delivery actions on the delivered rows would merge two surfaces with different lifetimes into one and reopen the card design; the proposal keeps both surfaces and moves only the duplicate. - -## Acceptance criteria - -- A file both changed and delivered in one turn renders one delivery card and no changed-files row; the header count and totals still cover it. -- The delivery card shows the file's counts, and that label opens the turn's review tab on the file; preview, native actions, and the description remain. -- Repeated deliveries of one file in a turn render one card; files with the same basename in different directories render separately. -- Reloading the page renders the same result as the first render; after a Host restart the delivery cards render without the changed-files card. -- The `changed-files-turn` and `present-svg` recorded scenarios and the package unit tests cover the merge. - -## Risks - -- A delivery spelled through a symbolic link, or with an absolute path outside the working directory that the recorder spelled differently, is not matched and renders twice; the README lists this as a known limitation. -- A changed-files card reduced to its header may read as incomplete; the header keeps the complete count so the review still lists every file. -- The counts label on a 60px delivery card competes for space with long file names; the design of that label is open until a design is agreed. diff --git a/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.zh.md b/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.zh.md deleted file mode 100644 index c218570711..0000000000 --- a/.agents/notes/proposed/feature/2026-09-16-delivered-file-single-card.zh.md +++ /dev/null @@ -1,41 +0,0 @@ -# Agent Note: 交付的改动文件只显示一张卡片 - -Status: proposed - -[English](2026-09-16-delivered-file-single-card.md) | 中文 - -## 问题 - -一轮结束时有两个文件区块:[改动文件卡片](../../implemented/feature/2026-09-11-turn-changed-files-card.zh.md)列出本轮改动的每个文件及其增删行数,并在该文件上打开 [review tab](../../implemented/feature/2026-09-15-changed-file-diff-preview.zh.md);模型通过 [present](../../implemented/feature/2026-09-08-present-workspace-source-files.zh.md) 声明的每个文件有一张交付卡片,在 Sidebar 中预览并用原生应用打开。本轮既改动又交付的文件在两处都出现,第二次出现没有给用户任何新信息;录制的 `changed-files-turn` 场景里四个文件显示为四行加四张卡片。 - -两个区块提供的东西和寿命都不同。行有行数和对比;卡片有模型写的说明、预览和原生操作。卡片的内容只活在 Host 进程里,Host 重启后重新打开的会话没有改动文件卡片,而 `deliverables/presented` 事件持久化在 Session log 里,它们的卡片会回来。 - -## 提议 - -本轮既改动又交付的文件只显示一次,显示在交付卡片上。改动文件卡片去掉该文件的行,保留头部;头部仍写本轮完整的文件数和汇总行数,仍在本轮上打开 review;所有改动文件都被交付时只剩头部。交付卡片在文件名旁补上该文件的增删行数,或二进制、过大标签,点击该标签在该文件上打开 review tab,这样对比、预览、原生操作和说明都从同一处可达。只改动或只交付的文件照旧显示,不同轮次之间不共享数据。 - -匹配在 Client 渲染时按词法进行:分隔符统一为 `/`,去掉 `.` 段,折叠 `..`,落在 Session 工作目录下的绝对路径改写为相对路径。同一轮内重复交付同一文件按同一个键合并,保留最新的说明。只经软链才相同的两种拼写保持不同。 - -持久化的东西都不变:没有新的 Session 事件、没有 Host 路由、recorder 不改;合并逻辑放在 `packages/client/ui-deliverables` 里卡片推导的旁边。Host 重启后改动文件卡片不存在,交付卡片按现在的方式渲染,不需要特殊处理。 - -## 考虑过的替代方案 - -**保留行、去掉卡片**代码更少,但交付物的默认入口从预览变成对比:一份报告或 SVG 变成一行 diff,二进制交付物变成一个「二进制」标签,完全没有预览。 - -**让模型不要 `present` 改动文件卡片会列出的文件**行不通:`workspace/changes` 事件从不进模型上下文,它的覆盖范围取决于 git、ignore 规则、文件数上限和临时目录排除;`present` 由 `standard`、`ptc`、`cordis` 三个 preset 共用,它们的 headless 和 SDK 消费者没有改动文件卡片;Host 重启后没交付的文件就没有任何入口。工具描述也要求交付用户要的每个产出,这是[交付决定](../../implemented/feature/2026-09-08-present-workspace-source-files.zh.md)定下的。 - -**一张合并卡片**,列出每个改动文件并在被交付的行上放交付操作,会把两个寿命不同的区块并成一个,并重开卡片设计;本提议保留两个区块,只挪走重复的那份。 - -## 验收标准 - -- 同一轮既改动又交付的文件只显示一张交付卡片,没有改动文件行;头部的数量和汇总仍包含它。 -- 交付卡片显示该文件的行数,点击该标签在该文件上打开本轮的 review tab;预览、原生操作和说明都保留。 -- 同一轮重复交付同一文件只显示一张卡片;不同目录下同名的文件分别显示。 -- 重新加载页面后的渲染结果与首次一致;Host 重启后交付卡片照常渲染,没有改动文件卡片。 -- `changed-files-turn` 和 `present-svg` 录制场景以及本包单测覆盖这次合并。 - -## 风险 - -- 经软链拼写的交付,或 recorder 拼法不同的工作目录外绝对路径,不会被匹配到,仍显示两次;README 把它列为已知限制。 -- 只剩头部的改动文件卡片可能显得不完整;头部保留完整数量,review 仍列出每个文件。 -- 60px 高的交付卡片上,行数标签会和长文件名争空间;该标签的样式在设计定下之前保持开放。 diff --git a/docs/tool-catalog.i18n.yaml b/docs/tool-catalog.i18n.yaml index ecd7976970..edf1570667 100644 --- a/docs/tool-catalog.i18n.yaml +++ b/docs/tool-catalog.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/tool-catalog.md -tool-catalog.md: b133f9ba94276878b380999b3023210a5d627c6a -tool-catalog.zh.md: 3f63676e4eb379163352a6c6a590f868e53f6efb +tool-catalog.md: 232b0ea958bc5797ba2f7d0ec88437928dca89df +tool-catalog.zh.md: 264fc1ed397ff4293afec73d9a4fd17b3c98dd5c diff --git a/docs/tool-catalog.md b/docs/tool-catalog.md index b133f9ba94..232b0ea958 100644 --- a/docs/tool-catalog.md +++ b/docs/tool-catalog.md @@ -627,7 +627,7 @@ The bash tool is the model-facing consumer of the bash executor seam. A `run_in_ ### `present` -Declare existing files accessible through the Session filesystem as final deliverables. When a file you create or update is an output the user asked to receive, you must call present after writing it and before your final response, including files created through Bash or code execution. Mentioning its path in your reply does not replace this call. The files must already exist. The user opens the current source files; their contents are not copied or preserved. +Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables per call; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved. ```json { diff --git a/docs/tool-catalog.zh.md b/docs/tool-catalog.zh.md index 3f63676e4e..264fc1ed39 100644 --- a/docs/tool-catalog.zh.md +++ b/docs/tool-catalog.zh.md @@ -631,7 +631,7 @@ bash 工具是 bash 执行器 seam 面向模型的消费方。使用 `run_in_bac ### `present` -声明交付 Session 文件系统可访问的已有文件。如果你创建或更新的文件是用户要求接收的成果,则必须在写入完成后、最终回复前调用 present,包括通过 Bash 或代码执行创建的文件。在回复中提到文件路径不能替代这次调用。文件必须已存在。用户打开当前源文件;不复制或保存其内容。 +选择 Session 文件系统可访问的已有文件,声明为最终交付物。当用户需要独立的文件交付物时使用 present,尤其是 Office 文档、电子表格和演示文稿。如果最终回复已经足够展示结果,优先在回复中展示;创建或编辑文件本身不要求调用 present。每次调用通常选择最重要的 1 至 2 项交付物,任务需要时可以更多。文件必须已存在。用户打开当前源文件;不复制或保存其内容。 ```json { diff --git a/packages/client/ui-deliverables/README.i18n.yaml b/packages/client/ui-deliverables/README.i18n.yaml index 457551a057..ce4332c413 100644 --- a/packages/client/ui-deliverables/README.i18n.yaml +++ b/packages/client/ui-deliverables/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-deliverables/README.md -README.md: a5d333353bd9c342be0549c70773ed38123e0ba8 -README.zh.md: 9704b73e5377491d6379bf8cf3424b4f30b2fda0 +README.md: ff6031af2a585dc13222a2aae3de78b455db4688 +README.zh.md: 7bd20c472da8d6571518490bff73babdb1d611e7 diff --git a/packages/client/ui-deliverables/README.md b/packages/client/ui-deliverables/README.md index a5d333353b..ff6031af2a 100644 --- a/packages/client/ui-deliverables/README.md +++ b/packages/client/ui-deliverables/README.md @@ -38,7 +38,7 @@ The `present` tool row retains the delivery-document glyph while showing running Developer tools must be enabled to show this card or request its summary. Turning the preference off removes the card immediately while explicit delivery cards, inline file links, and recorded workspace changes remain available. -The card renders the summary the Host serves for the turn's latest `workspace/changes` announcement, read once per announcement through the authenticated summary route; while the read is pending, once the Host answers that the summary is gone, or when it lists no file, there is no card. Its header names the complete changed-file count with the summed added and deleted lines, and each row shows one file's display path with its own counts, “binary” for a binary file, or “too large” for a file the Host did not capture. Rows appear in the recorded display order, so repository files above the working directory and files outside it sort first. Three rows show before a fold; a control below reveals every recorded file and, once expanded, collapses the list again from the bottom. Each row opens the turn's review in the right Sidebar on that file, and the header opens it on the first file. The first file section starts 20px below the closing prose, a following explicit-delivery section starts 16px below the card, and the action footer starts 20px below the last file section. Final file deliveries still require `present`. +The card renders the summary the Host serves for the turn's latest `workspace/changes` announcement, read once per announcement through the authenticated summary route; while the read is pending, once the Host answers that the summary is gone, or when it lists no file, there is no card. Its header names the complete changed-file count with the summed added and deleted lines, and each row shows one file's display path with its own counts, “binary” for a binary file, or “too large” for a file the Host did not capture. Rows appear in the recorded display order, so repository files above the working directory and files outside it sort first. Three rows show before a fold; a control below reveals every recorded file and, once expanded, collapses the list again from the bottom. Each row opens the turn's review in the right Sidebar on that file, and the header opens it on the first file. The first file section starts 20px below the closing prose, a following explicit-delivery section starts 16px below the card, and the action footer starts 20px below the last file section. ### The review tab @@ -87,11 +87,11 @@ Read these pages when the deliverables surface is not enough. They move from the #### What the model sees -The guidance asks the model to name primary outputs after successful creation or modification and link every existing-file mention outside commands, configuration expressions, and code blocks, including repeats and tables. Labels default to filenames or clear aliases, with only enough parent directories to distinguish files. Precise references display `filename:24` or `filename:24–30`; their destinations retain full relative or absolute paths with `#L24` or `#L24-L30` anchors. The display suffix contains neither `#` nor `L`. +The guidance prefers primary results in the final reply: Markdown images display inline, and file links open Sidebar previews. It recommends separate `present` cards for complete file deliverables, especially Office files, usually selecting the most important one or two while allowing more when needed. It treats code changes as already having a diff view and discourages extra commands to inspect its visibility. It asks the model to link every existing-file mention outside commands, configuration expressions, and code blocks, including repeats and tables. Labels default to filenames or clear aliases, with only enough parent directories to distinguish files. Precise references display `filename:24` or `filename:24–30`; their destinations retain full relative or absolute paths with `#L24` or `#L24-L30` anchors. The display suffix contains neither `#` nor `L`. #### Token effect -One fixed paragraph containing an output reminder and file-reference guidance whenever this package is loaded. The [present tool](../../deliverables/tool-present/README.md#model-experience) owns the delivery schema and result text. +One fixed paragraph containing output-selection, rendering, and file-reference guidance whenever this package is loaded. The [present tool](../../deliverables/tool-present/README.md#model-experience) owns the delivery schema and result text. #### KV Cache effect diff --git a/packages/client/ui-deliverables/README.zh.md b/packages/client/ui-deliverables/README.zh.md index 9704b73e53..7bd20c472d 100644 --- a/packages/client/ui-deliverables/README.zh.md +++ b/packages/client/ui-deliverables/README.zh.md @@ -38,7 +38,7 @@ Web 的 `standard`、`ptc` 与 `cordis` preset 提供 `present` 用于声明交 只有开启开发者工具才展示此卡片并请求其摘要。关闭该偏好会立即隐藏卡片,同时保留显式交付卡片、行内文件链接和已记录的工作区改动。 -卡片渲染 Host 为本轮最新一条 `workspace/changes` 宣告提供的摘要,每条宣告通过经过认证的摘要路由读取一次;读取尚未完成、Host 答复摘要已不存在,或摘要没有列出任何文件时,没有卡片。标题给出改动文件总数与增删行数合计,每一行显示一个文件的展示路径及其增删行数,二进制文件显示“二进制”,Host 没有捕获的文件显示“过大”。行按记录的展示顺序排列,因此仓库内位于工作目录之上的文件与工作区外的文件排在最前。折叠前显示三行;下方的控件展开全部记录文件,展开后同一位置的控件从底部收起列表。每一行在右侧 Sidebar 中打开本轮的 review 并选中该文件,标题则在第一个文件上打开它。首个文件区块位于收尾正文下方 20px,后续显式交付区块位于卡片下方 16px,操作页脚位于最后一个文件区块下方 20px。最终文件交付仍需调用 `present`。 +卡片渲染 Host 为本轮最新一条 `workspace/changes` 宣告提供的摘要,每条宣告通过经过认证的摘要路由读取一次;读取尚未完成、Host 答复摘要已不存在,或摘要没有列出任何文件时,没有卡片。标题给出改动文件总数与增删行数合计,每一行显示一个文件的展示路径及其增删行数,二进制文件显示“二进制”,Host 没有捕获的文件显示“过大”。行按记录的展示顺序排列,因此仓库内位于工作目录之上的文件与工作区外的文件排在最前。折叠前显示三行;下方的控件展开全部记录文件,展开后同一位置的控件从底部收起列表。每一行在右侧 Sidebar 中打开本轮的 review 并选中该文件,标题则在第一个文件上打开它。首个文件区块位于收尾正文下方 20px,后续显式交付区块位于卡片下方 16px,操作页脚位于最后一个文件区块下方 20px。 ### review tab @@ -87,11 +87,11 @@ Node 半部注册[模型体验](#model-experience)所述的静态 `ui:deliverabl #### 模型看到的内容 -提示词要求模型在成功创建或修改文件后点名主要产出,并链接命令、配置表达式和代码块以外的每次现有文件提及,包括重复提及和表格。标签默认使用文件名或清楚的别名,仅添加足以区分文件的父目录。精确引用显示为 `filename:24` 或 `filename:24–30`;目标保留完整相对路径或绝对路径,以及 `#L24` 或 `#L24-L30` 锚点。显示后缀不含 `#` 或 `L`。 +提示词建议在最终回复中展示主要结果:Markdown 图片直接显示在正文中,文件链接打开 Sidebar 预览。对于需要完整文件的交付,尤其是 Office 文件,建议使用独立的 `present` 卡片,通常选最重要的一两项,需要时可以更多。提示词按代码改动已有 diff 视图提供建议,并要求避免为确认其显示情况额外运行命令。文件引用要求链接命令、配置表达式和代码块以外的每次现有文件提及,包括重复提及和表格。标签默认使用文件名或清楚的别名,仅添加足以区分文件的父目录。精确引用显示为 `filename:24` 或 `filename:24–30`;目标保留完整相对路径或绝对路径,以及 `#L24` 或 `#L24-L30` 锚点。显示后缀不含 `#` 或 `L`。 #### Token 影响 -加载本包时增加一段包含产出提醒和文件引用指导的固定提示词。[present 工具](../../deliverables/tool-present/README.zh.md#model-experience)拥有交付 schema 和结果文本。 +加载本包时增加一段包含产出选择、渲染效果和文件引用指导的固定提示词。[present 工具](../../deliverables/tool-present/README.zh.md#model-experience)拥有交付 schema 和结果文本。 #### KV Cache 影响 diff --git a/packages/client/ui-deliverables/src/index.ts b/packages/client/ui-deliverables/src/index.ts index d6fd183ac5..7066c25324 100644 --- a/packages/client/ui-deliverables/src/index.ts +++ b/packages/client/ui-deliverables/src/index.ts @@ -14,7 +14,11 @@ import { registerPresentOpen } from './present-open.ts' export const inject = ['systemPrompt', 'connection', 'sessionQuery', 'sessionController', 'workspaceFiles', 'fs', 'sandboxPolicy', 'workspaceChanges'] /** Static Web guidance for primary outputs and existing-file references. */ -const FILE_REFERENCE_PROMPT = 'When you successfully create or modify files, mention the primary outputs in your final response. ' +const FILE_REFERENCE_PROMPT = 'Prefer showing the primary results within your final response alongside a brief explanation. ' + + 'Markdown images such as ![Preview](path/to/image.png) display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. ' + + 'Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. ' + + 'Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. ' + + 'Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. ' + 'Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. ' + 'Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix.' diff --git a/packages/deliverables/tool-present/README.i18n.yaml b/packages/deliverables/tool-present/README.i18n.yaml index a40c948a43..6df145b497 100644 --- a/packages/deliverables/tool-present/README.i18n.yaml +++ b/packages/deliverables/tool-present/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/deliverables/tool-present/README.md -README.md: 93003711545f678336a02c9bf8589176f844af65 -README.zh.md: 161efcc3931fbf57175064ccf1179b195320d4b9 +README.md: a1b4d7d3a7cc2fa7449589667667eb322df9b3cc +README.zh.md: 71529c5aa1b6ae4e66040fc3f2d76b3633b51262 diff --git a/packages/deliverables/tool-present/README.md b/packages/deliverables/tool-present/README.md index 9300371154..a1b4d7d3a7 100644 --- a/packages/deliverables/tool-present/README.md +++ b/packages/deliverables/tool-present/README.md @@ -73,7 +73,7 @@ The pure `./types` entry declares `PresentedFile` and the Session event without #### What the model sees -The [present schema](../../../docs/tool-catalog.md#present) asks for existing accessible files: “Declare existing files accessible through the Session filesystem as final deliverables. When a file you create or update is an output the user asked to receive, you must call present after writing it and before your final response, including files created through Bash or code execution. Mentioning its path in your reply does not replace this call. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” Results report `Presented ` for each file; the program result and durable event contain paths and optional descriptions. +The [present schema](../../../docs/tool-catalog.md#present) asks for existing accessible files: “Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables per call; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” Results report `Presented ` for each file; the program result and durable event contain paths and optional descriptions. #### Token effect diff --git a/packages/deliverables/tool-present/README.zh.md b/packages/deliverables/tool-present/README.zh.md index 161efcc393..71529c5aa1 100644 --- a/packages/deliverables/tool-present/README.zh.md +++ b/packages/deliverables/tool-present/README.zh.md @@ -73,7 +73,7 @@ kind: "package-reference" #### 模型看到的内容 -[present schema](../../../docs/tool-catalog.zh.md#present)要求已有且可访问的文件:“Declare existing files accessible through the Session filesystem as final deliverables. When a file you create or update is an output the user asked to receive, you must call present after writing it and before your final response, including files created through Bash or code execution. Mentioning its path in your reply does not replace this call. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” 每个文件的结果为 `Presented `;程序结果和持久事件包含路径及可选说明。 +[present schema](../../../docs/tool-catalog.zh.md#present)要求已有且可访问的文件:“Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables per call; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” 每个文件的结果为 `Presented `;程序结果和持久事件包含路径及可选说明。 #### Token 影响 diff --git a/packages/deliverables/tool-present/src/index.ts b/packages/deliverables/tool-present/src/index.ts index 626006e17b..925d2a59b3 100644 --- a/packages/deliverables/tool-present/src/index.ts +++ b/packages/deliverables/tool-present/src/index.ts @@ -37,10 +37,11 @@ export function apply(ctx: Context, config: Config): void { const pending = new WeakMap() ctx.tools.register(defineTool({ name: 'present', - description: 'Declare existing files accessible through the Session filesystem as final deliverables. ' - + 'When a file you create or update is an output the user asked to receive, you must call present after writing it and before your final response, including files created through Bash or code execution. ' - + 'Mentioning its path in your reply does not replace this call. The files must already exist. ' - + 'The user opens the current source files; their contents are not copied or preserved.', + description: 'Declare selected existing files accessible through the Session filesystem as final deliverables. ' + + 'Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. ' + + 'Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. ' + + 'Usually select the 1-2 most important deliverables per call; include more when the task calls for them. ' + + 'The files must already exist. The user opens the current source files; their contents are not copied or preserved.', parameters: { files: { type: 'array', required: true, From 2e55564e0295fe72efa2cab09c4e3343b27122b2 Mon Sep 17 00:00:00 2001 From: creatixchu Date: Fri, 18 Sep 2026 16:32:56 +0800 Subject: [PATCH 3/7] fix: specify absolute paths for inline image rendering --- packages/client/ui-deliverables/README.i18n.yaml | 4 ++-- packages/client/ui-deliverables/README.md | 2 +- packages/client/ui-deliverables/README.zh.md | 2 +- packages/client/ui-deliverables/src/index.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/client/ui-deliverables/README.i18n.yaml b/packages/client/ui-deliverables/README.i18n.yaml index ce4332c413..cd0b594d94 100644 --- a/packages/client/ui-deliverables/README.i18n.yaml +++ b/packages/client/ui-deliverables/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-deliverables/README.md -README.md: ff6031af2a585dc13222a2aae3de78b455db4688 -README.zh.md: 7bd20c472da8d6571518490bff73babdb1d611e7 +README.md: 6ddabc5638a4e6d99b6b4d4413992e492ed5a1b6 +README.zh.md: cf9569e5fb7bc7153a879e6bf92cbaae547a3fb4 diff --git a/packages/client/ui-deliverables/README.md b/packages/client/ui-deliverables/README.md index ff6031af2a..6ddabc5638 100644 --- a/packages/client/ui-deliverables/README.md +++ b/packages/client/ui-deliverables/README.md @@ -87,7 +87,7 @@ Read these pages when the deliverables surface is not enough. They move from the #### What the model sees -The guidance prefers primary results in the final reply: Markdown images display inline, and file links open Sidebar previews. It recommends separate `present` cards for complete file deliverables, especially Office files, usually selecting the most important one or two while allowing more when needed. It treats code changes as already having a diff view and discourages extra commands to inspect its visibility. It asks the model to link every existing-file mention outside commands, configuration expressions, and code blocks, including repeats and tables. Labels default to filenames or clear aliases, with only enough parent directories to distinguish files. Precise references display `filename:24` or `filename:24–30`; their destinations retain full relative or absolute paths with `#L24` or `#L24-L30` anchors. The display suffix contains neither `#` nor `L`. +The guidance prefers primary results in the final reply: Markdown images with absolute file paths display inline, and file links open Sidebar previews. It recommends separate `present` cards for complete file deliverables, especially Office files, usually selecting the most important one or two while allowing more when needed. It treats code changes as already having a diff view and discourages extra commands to inspect its visibility. It asks the model to link every existing-file mention outside commands, configuration expressions, and code blocks, including repeats and tables. Labels default to filenames or clear aliases, with only enough parent directories to distinguish files. Precise references display `filename:24` or `filename:24–30`; their destinations retain full relative or absolute paths with `#L24` or `#L24-L30` anchors. The display suffix contains neither `#` nor `L`. #### Token effect diff --git a/packages/client/ui-deliverables/README.zh.md b/packages/client/ui-deliverables/README.zh.md index 7bd20c472d..cf9569e5fb 100644 --- a/packages/client/ui-deliverables/README.zh.md +++ b/packages/client/ui-deliverables/README.zh.md @@ -87,7 +87,7 @@ Node 半部注册[模型体验](#model-experience)所述的静态 `ui:deliverabl #### 模型看到的内容 -提示词建议在最终回复中展示主要结果:Markdown 图片直接显示在正文中,文件链接打开 Sidebar 预览。对于需要完整文件的交付,尤其是 Office 文件,建议使用独立的 `present` 卡片,通常选最重要的一两项,需要时可以更多。提示词按代码改动已有 diff 视图提供建议,并要求避免为确认其显示情况额外运行命令。文件引用要求链接命令、配置表达式和代码块以外的每次现有文件提及,包括重复提及和表格。标签默认使用文件名或清楚的别名,仅添加足以区分文件的父目录。精确引用显示为 `filename:24` 或 `filename:24–30`;目标保留完整相对路径或绝对路径,以及 `#L24` 或 `#L24-L30` 锚点。显示后缀不含 `#` 或 `L`。 +提示词建议在最终回复中展示主要结果:使用绝对文件路径的 Markdown 图片直接显示在正文中,文件链接打开 Sidebar 预览。对于需要完整文件的交付,尤其是 Office 文件,建议使用独立的 `present` 卡片,通常选最重要的一两项,需要时可以更多。提示词按代码改动已有 diff 视图提供建议,并要求避免为确认其显示情况额外运行命令。文件引用要求链接命令、配置表达式和代码块以外的每次现有文件提及,包括重复提及和表格。标签默认使用文件名或清楚的别名,仅添加足以区分文件的父目录。精确引用显示为 `filename:24` 或 `filename:24–30`;目标保留完整相对路径或绝对路径,以及 `#L24` 或 `#L24-L30` 锚点。显示后缀不含 `#` 或 `L`。 #### Token 影响 diff --git a/packages/client/ui-deliverables/src/index.ts b/packages/client/ui-deliverables/src/index.ts index 7066c25324..a5a353d8f8 100644 --- a/packages/client/ui-deliverables/src/index.ts +++ b/packages/client/ui-deliverables/src/index.ts @@ -15,7 +15,7 @@ export const inject = ['systemPrompt', 'connection', 'sessionQuery', 'sessionCon /** Static Web guidance for primary outputs and existing-file references. */ const FILE_REFERENCE_PROMPT = 'Prefer showing the primary results within your final response alongside a brief explanation. ' - + 'Markdown images such as ![Preview](path/to/image.png) display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. ' + + 'Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. ' + 'Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. ' + 'Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. ' + 'Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. ' From 13692e91793d33f359637fccf610b55cf8f377c0 Mon Sep 17 00:00:00 2001 From: creatixchu Date: Fri, 18 Sep 2026 16:35:51 +0800 Subject: [PATCH 4/7] test: refresh selective presentation prompt snapshots --- .../web-runtime-context/file-reference-prompt.expected.md | 2 +- packages/client/ui-deliverables/tests/prompt.host.spec.ts | 5 +++-- snapshots/web/fresh-round-trip/system-prompt.expected.md | 2 +- snapshots/web/fresh-round-trip/tool-schemas.expected.json | 2 +- snapshots/web/ptc-round/system-prompt.expected.md | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/apps/web/tests/expected/web-runtime-context/file-reference-prompt.expected.md b/apps/web/tests/expected/web-runtime-context/file-reference-prompt.expected.md index fbfa9b1cab..894efdb261 100644 --- a/apps/web/tests/expected/web-runtime-context/file-reference-prompt.expected.md +++ b/apps/web/tests/expected/web-runtime-context/file-reference-prompt.expected.md @@ -1 +1 @@ -When you successfully create or modify files, mention the primary outputs in your final response. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. +Prefer showing the primary results within your final response alongside a brief explanation. Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. diff --git a/packages/client/ui-deliverables/tests/prompt.host.spec.ts b/packages/client/ui-deliverables/tests/prompt.host.spec.ts index 0b7e989104..0632ed2f82 100644 --- a/packages/client/ui-deliverables/tests/prompt.host.spec.ts +++ b/packages/client/ui-deliverables/tests/prompt.host.spec.ts @@ -29,9 +29,10 @@ describe('ui-deliverables node plugin', () => { const section = (await ctx.systemPrompt.assemble()).sections .find(entry => entry.name === 'ui:deliverable-file-references') - expect(section?.text).toMatchInlineSnapshot('"When you successfully create or modify files, mention the primary outputs in your final response. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix."') + expect(section?.text).toMatchInlineSnapshot('"Prefer showing the primary results within your final response alongside a brief explanation. Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix."') - for (const scenario of ['cordis-tool-round', 'fresh-round-trip', 'ptc-round', 'schedule-catalog']) { + // Seeded historical sessions retain the prompt recorded with their original tools. + for (const scenario of ['fresh-round-trip', 'ptc-round']) { const sidecar = await readFile(new URL(`../../../../snapshots/web/${scenario}/system-prompt.expected.md`, import.meta.url), 'utf8') expect(sidecar, scenario).toContain(section!.text) } diff --git a/snapshots/web/fresh-round-trip/system-prompt.expected.md b/snapshots/web/fresh-round-trip/system-prompt.expected.md index a320dcb8b8..f065d79923 100644 --- a/snapshots/web/fresh-round-trip/system-prompt.expected.md +++ b/snapshots/web/fresh-round-trip/system-prompt.expected.md @@ -30,7 +30,7 @@ Use subagent in the background by default. Start independent delegations togethe Use subagent_fork in the background by default. Start independent delegations together in one assistant message and continue useful work while they run. Set `run_in_background: false` only when your next action depends on that subagent's result. When a background run settles, the runtime sends you a notice containing its outcome and any final assistant message. -When you successfully create or modify files, mention the primary outputs in your final response. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. +Prefer showing the primary results within your final response alongside a brief explanation. Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. The DeepSeek Harness implementation checkout is at {{sourceRoot}}. The checkout location and current working directory are separate values and may differ; never infer the working directory from this path. Use pwd to determine the current working directory. Use this checkout only to inspect or extend DSH itself. diff --git a/snapshots/web/fresh-round-trip/tool-schemas.expected.json b/snapshots/web/fresh-round-trip/tool-schemas.expected.json index c7c71cc5d6..6bd16a39f4 100644 --- a/snapshots/web/fresh-round-trip/tool-schemas.expected.json +++ b/snapshots/web/fresh-round-trip/tool-schemas.expected.json @@ -325,7 +325,7 @@ }, { "name": "present", - "description": "Declare existing files accessible through the Session filesystem as final deliverables. When a file you create or update is an output the user asked to receive, you must call present after writing it and before your final response, including files created through Bash or code execution. Mentioning its path in your reply does not replace this call. The files must already exist. The user opens the current source files; their contents are not copied or preserved.", + "description": "Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables per call; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved.", "parameters": { "type": "object", "properties": { diff --git a/snapshots/web/ptc-round/system-prompt.expected.md b/snapshots/web/ptc-round/system-prompt.expected.md index 6dfe22aed8..4531081ba9 100644 --- a/snapshots/web/ptc-round/system-prompt.expected.md +++ b/snapshots/web/ptc-round/system-prompt.expected.md @@ -160,7 +160,7 @@ interface ToolArgsMap { /** children (default) lists direct children only; descendants walks the complete tree below you. */ scope?: "children" | "descendants"; } & Record; - /** Declare existing files accessible through the Session filesystem as final deliverables. When a file you create or update is an output the user asked to receive, you must call present after writing it and before your final response, including files created through Bash or code execution. Mentioning its path in your reply does not replace this call. The files must already exist. The user opens the current source files; their contents are not copied or preserved. */ + /** Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables per call; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved. */ present: { files: { /** Path of an existing regular file. Relative paths use the Session working directory. */ @@ -540,7 +540,7 @@ declare const tools: { } ``` -When you successfully create or modify files, mention the primary outputs in your final response. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. +Prefer showing the primary results within your final response alongside a brief explanation. Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. The DeepSeek Harness implementation checkout is at {{sourceRoot}}. The checkout location and current working directory are separate values and may differ; never infer the working directory from this path. Use pwd to determine the current working directory. Use this checkout only to inspect or extend DSH itself. From 63c1e04b931dfa65fb7fbf1f08e2f59f0900231c Mon Sep 17 00:00:00 2001 From: creatixchu Date: Fri, 18 Sep 2026 17:09:02 +0800 Subject: [PATCH 5/7] fix: keep file access available across presentation clients --- ...09-08-present-workspace-source-files.i18n.yaml | 4 ++-- .../2026-09-08-present-workspace-source-files.md | 2 +- ...026-09-08-present-workspace-source-files.zh.md | 2 +- apps/web/tests/present-svg.e2e.ts | 13 +++++++------ docs/tool-catalog.i18n.yaml | 4 ++-- docs/tool-catalog.md | 2 +- docs/tool-catalog.zh.md | 2 +- ...assistant-markdown-path-images.client.spec.tsx | 1 + packages/client/ui-deliverables/README.i18n.yaml | 4 ++-- packages/client/ui-deliverables/README.md | 3 ++- packages/client/ui-deliverables/README.zh.md | 3 ++- packages/client/ui-deliverables/src/index.ts | 4 ++-- .../ui-deliverables/tests/prompt.host.spec.ts | 2 +- .../tests/markdown-file-links.client.spec.tsx | 15 +++++++++++++++ .../deliverables/tool-present/README.i18n.yaml | 4 ++-- packages/deliverables/tool-present/README.md | 2 +- packages/deliverables/tool-present/README.zh.md | 2 +- packages/deliverables/tool-present/src/index.ts | 2 +- 18 files changed, 45 insertions(+), 26 deletions(-) diff --git a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml index 5e0dc05743..057e138853 100644 --- a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md -2026-09-08-present-workspace-source-files.md: 1ab40bdf8b88c73ddb40b071281842ef7b2e3ac1 -2026-09-08-present-workspace-source-files.zh.md: 8f389b97f3a388affc3b49cbb532f69c127336fc +2026-09-08-present-workspace-source-files.md: 52cc3e9cdbcd30d378117a327b86062523a2cb3e +2026-09-08-present-workspace-source-files.zh.md: 99b7b9df1d9ca2da2175df1ae7e9d8acbb5c5fdd diff --git a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md index 1ab40bdf8b..52cc3e9cdb 100644 --- a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md +++ b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.md @@ -12,7 +12,7 @@ Users need to open and edit the files produced in their workspace, including she The [present tool](../../../../packages/deliverables/tool-present/README.md) declares existing regular source files under the [Session filesystem access policy](2026-09-09-present-filesystem-access.md). It records paths and optional descriptions without reading or copying contents. The [deliverables plugin](../../../../packages/client/ui-deliverables/README.md) opens current workspace sources in the Host's default application. Edits are visible on the next open; deletion or movement makes the declaration unavailable. File-content preservation and copy-on-write storage are deferred until a persistence design owns them. -The [tool description](../../../../packages/deliverables/tool-present/README.md#model-experience) guides the model’s choice of files for explicit delivery. A declaration remains distinct from a prose file reference. The recorded [SVG delivery scenario](../../../../snapshots/web/present-svg/snapshot.yml) uses a user request that does not name `present`, and checks the resulting file, delivery event, and card. Its UI snapshot covers the expanded Chat transcript; navigation and composer controls belong to their own scenarios, so unrelated chrome changes cannot invalidate file-delivery expectations. +The [tool description](../../../../packages/deliverables/tool-present/README.md#model-experience) guides the model's choice of files for explicit delivery. A declaration remains distinct from a prose file reference. The recorded [SVG delivery scenario](../../../../snapshots/web/present-svg/snapshot.yml) covers the resulting file, delivery event, and card. New recordings explicitly request a separate file card; replay preserves the recorded request. This scenario verifies explicit delivery, not a requirement to call `present` for every SVG. Its UI snapshot covers the expanded Chat transcript; navigation and composer controls belong to their own scenarios, so unrelated chrome changes cannot invalidate file-delivery expectations. The tool remains an ordinary package with shared filesystem and tool error classes. Its pure type entry owns the delivery event without importing Host code into the browser. The `standard`, `ptc`, and `cordis` presets mount it; `minimal` retains its two tools. Each plugin instance correlates its executions with successful final `tools/result` notifications before appending `deliverables/presented`. Native and nested calls share this rule. A later enclosing program failure does not revoke a completed nested declaration; blocked results publish none, and same-name scoped replacements cannot publish another instance's results. diff --git a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.zh.md b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.zh.md index 8f389b97f3..99b7b9df1d 100644 --- a/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.zh.md +++ b/.agents/notes/implemented/feature/2026-09-08-present-workspace-source-files.zh.md @@ -12,7 +12,7 @@ Status: implemented [present 工具](../../../../packages/deliverables/tool-present/README.zh.md)声明交付[Session 文件系统访问策略](2026-09-09-present-filesystem-access.zh.md)允许的已有普通源文件。它记录路径和可选说明,不读取或复制内容。[交付插件](../../../../packages/client/ui-deliverables/README.zh.md)使用 Host 默认应用打开当前工作区源文件。下次打开会看到编辑后的内容;删除或移动文件会使声明不可用。文件内容保留与写时复制存储延期到有持久化设计负责时实现。 -[工具说明](../../../../packages/deliverables/tool-present/README.zh.md#model-experience)指导模型选择需要显式交付的文件。交付声明与正文中的文件引用各自独立。录制的 [SVG 交付场景](../../../../snapshots/web/present-svg/snapshot.yml)使用未提及 `present` 的用户请求,检查生成文件、交付事件和卡片。其 UI 快照覆盖展开后的 Chat 对话内容;导航和输入框控件由各自场景负责,避免无关界面改动使文件交付预期失效。 +[工具说明](../../../../packages/deliverables/tool-present/README.zh.md#model-experience)指导模型选择需要显式交付的文件。交付声明与正文中的文件引用各自独立。录制的 [SVG 交付场景](../../../../snapshots/web/present-svg/snapshot.yml)覆盖生成文件、交付事件和卡片。新录制明确请求独立文件卡片,回放保留录制时的请求。该场景验证显式交付,不要求所有 SVG 都调用 `present`。其 UI 快照覆盖展开后的 Chat 对话内容;导航和输入框控件由各自场景负责,避免无关界面改动使文件交付预期失效。 工具保持为普通包,共享文件系统和工具错误类型。其纯类型入口拥有交付事件,不向浏览器导入 Host 代码。`standard`、`ptc` 与 `cordis` preset 挂载工具;`minimal` 保持两个工具。每个插件实例将其执行与成功的最终 `tools/result` 通知关联,再追加 `deliverables/presented`。原生与嵌套调用遵循同一规则。外层程序随后失败不会撤销已完成的嵌套声明;被阻止的结果不发布声明,同名作用域替换也不能发布其他实例的结果。 diff --git a/apps/web/tests/present-svg.e2e.ts b/apps/web/tests/present-svg.e2e.ts index 8273a72d02..5c21f9aab8 100644 --- a/apps/web/tests/present-svg.e2e.ts +++ b/apps/web/tests/present-svg.e2e.ts @@ -1,4 +1,4 @@ -/** A file request elicits explicit SVG delivery without naming the present tool. */ +/** An explicit file-card request exercises SVG delivery without naming the present tool. */ import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join, resolve } from 'node:path' @@ -17,7 +17,7 @@ import { connectFreshWorkspaceZh, ZH_BROWSER_LOCALE } from './support.ts' const DIR = fileURLToPath(new URL('../../../snapshots/web/present-svg', import.meta.url)) const FIXTURE = join(DIR, 'session.v3.jsonl') const MODE = webSnapshotMode() -const PROMPT = '简单画一个 SVG 表示冯诺依曼架构, 保存为 von-neumann.svg' +const RECORD_PROMPT = '简单画一个 SVG 表示冯诺依曼架构,保存为 von-neumann.svg,并提供独立文件卡片,方便打开。' const FILE = 'von-neumann.svg' describe('web e2e: requested SVG is explicitly delivered', () => { @@ -65,11 +65,12 @@ describe('web e2e: requested SVG is explicitly delivered', () => { } }) - it('writes valid SVG and calls present before the final reply', async () => { - if (MODE !== 'record') expect(fixtureUserPrompts(await readFile(FIXTURE, 'utf8'))).toEqual([PROMPT]) + it('writes valid SVG and provides the requested file card before the final reply', async () => { + const prompts = MODE === 'record' ? [RECORD_PROMPT] : fixtureUserPrompts(await readFile(FIXTURE, 'utf8')) + expect(prompts).toHaveLength(1) const settled = scaffold.whenTurnSettled() const input = page.locator('[data-composer-input]').first() - await input.fill(PROMPT) + await input.fill(prompts[0]!) await input.press('Enter') const sessionId = await settled const session = scaffold.ctx.agents.get(sessionId)?.session @@ -91,7 +92,7 @@ describe('web e2e: requested SVG is explicitly delivered', () => { const events = session.snapshotEvents() const declarations = events.filter(event => event.type === 'deliverables/presented') const delivery = declarations.find(event => event.data.files.some(file => resolve(cwd, file.path) === join(cwd, FILE))) - expect(delivery, 'the file request must produce a successful present declaration').toBeDefined() + expect(delivery, 'explicit file-card delivery requires a successful present declaration').toBeDefined() if (delivery === undefined) throw new Error('SVG was written but not delivered') expect(events.some(event => ( event.type === 'tool/call' && event.data.name === 'present' && event.data.callId === delivery.data.callId diff --git a/docs/tool-catalog.i18n.yaml b/docs/tool-catalog.i18n.yaml index edf1570667..2652212da5 100644 --- a/docs/tool-catalog.i18n.yaml +++ b/docs/tool-catalog.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/tool-catalog.md -tool-catalog.md: 232b0ea958bc5797ba2f7d0ec88437928dca89df -tool-catalog.zh.md: 264fc1ed397ff4293afec73d9a4fd17b3c98dd5c +tool-catalog.md: 4f435b91fefd9fe694eaa153251dae35ab3dd543 +tool-catalog.zh.md: a7514000f9a37b3984193383a9beecd7a62ebee0 diff --git a/docs/tool-catalog.md b/docs/tool-catalog.md index 232b0ea958..4f435b91fe 100644 --- a/docs/tool-catalog.md +++ b/docs/tool-catalog.md @@ -627,7 +627,7 @@ The bash tool is the model-facing consumer of the bash executor seam. A `run_in_ ### `present` -Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables per call; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved. +Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved. ```json { diff --git a/docs/tool-catalog.zh.md b/docs/tool-catalog.zh.md index 264fc1ed39..a7514000f9 100644 --- a/docs/tool-catalog.zh.md +++ b/docs/tool-catalog.zh.md @@ -631,7 +631,7 @@ bash 工具是 bash 执行器 seam 面向模型的消费方。使用 `run_in_bac ### `present` -选择 Session 文件系统可访问的已有文件,声明为最终交付物。当用户需要独立的文件交付物时使用 present,尤其是 Office 文档、电子表格和演示文稿。如果最终回复已经足够展示结果,优先在回复中展示;创建或编辑文件本身不要求调用 present。每次调用通常选择最重要的 1 至 2 项交付物,任务需要时可以更多。文件必须已存在。用户打开当前源文件;不复制或保存其内容。 +选择 Session 文件系统可访问的已有文件,声明为最终交付物。当用户需要独立的文件交付物时使用 present,尤其是 Office 文档、电子表格和演示文稿。如果最终回复已经足够展示结果,优先在回复中展示;创建或编辑文件本身不要求调用 present。通常选择最重要的 1 至 2 项交付物,任务需要时可以更多。文件必须已存在。用户打开当前源文件;不复制或保存其内容。 ```json { diff --git a/packages/client/ui-chat/tests/assistant-markdown-path-images.client.spec.tsx b/packages/client/ui-chat/tests/assistant-markdown-path-images.client.spec.tsx index 564f5a6a41..704b53396f 100644 --- a/packages/client/ui-chat/tests/assistant-markdown-path-images.client.spec.tsx +++ b/packages/client/ui-chat/tests/assistant-markdown-path-images.client.spec.tsx @@ -25,6 +25,7 @@ describe('localPathMediaUrl', () => { }) it('keeps non-HTTP transports inert', () => { + expect(localPathMediaUrl('dsh-app:', 'dsh-app://app', '/tmp/graph.png')).toBeUndefined() expect(localPathMediaUrl('file:', 'file:///app', '/tmp/graph.png')).toBeUndefined() expect(localPathMediaUrl('ws:', ORIGIN, '/tmp/graph.png')).toBeUndefined() }) diff --git a/packages/client/ui-deliverables/README.i18n.yaml b/packages/client/ui-deliverables/README.i18n.yaml index cd0b594d94..096955008a 100644 --- a/packages/client/ui-deliverables/README.i18n.yaml +++ b/packages/client/ui-deliverables/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-deliverables/README.md -README.md: 6ddabc5638a4e6d99b6b4d4413992e492ed5a1b6 -README.zh.md: cf9569e5fb7bc7153a879e6bf92cbaae547a3fb4 +README.md: 133d3c2dd6a1d360d8be7ce90e4f9578d5ab2075 +README.zh.md: 46540cc6c9ff7832b439ae25e091c1fd98b7e349 diff --git a/packages/client/ui-deliverables/README.md b/packages/client/ui-deliverables/README.md index 6ddabc5638..133d3c2dd6 100644 --- a/packages/client/ui-deliverables/README.md +++ b/packages/client/ui-deliverables/README.md @@ -87,7 +87,7 @@ Read these pages when the deliverables surface is not enough. They move from the #### What the model sees -The guidance prefers primary results in the final reply: Markdown images with absolute file paths display inline, and file links open Sidebar previews. It recommends separate `present` cards for complete file deliverables, especially Office files, usually selecting the most important one or two while allowing more when needed. It treats code changes as already having a diff view and discourages extra commands to inspect its visibility. It asks the model to link every existing-file mention outside commands, configuration expressions, and code blocks, including repeats and tables. Labels default to filenames or clear aliases, with only enough parent directories to distinguish files. Precise references display `filename:24` or `filename:24–30`; their destinations retain full relative or absolute paths with `#L24` or `#L24-L30` anchors. The display suffix contains neither `#` nor `L`. +The guidance prefers primary results in the final reply: file links open Sidebar previews, and image previews include a file link for clients without inline-image support. It recommends separate `present` cards for complete file deliverables, especially Office files, usually selecting the most important one or two while allowing more when needed. It discourages cards solely for code edits and extra commands to inspect diff visibility. This guidance applies even with developer tools disabled: it accepts fewer file surfaces to avoid duplicate presentation and unnecessary tool calls. It asks the model to link every existing-file mention outside commands, configuration expressions, and code blocks, including repeats and tables. Labels default to filenames or clear aliases, with only enough parent directories to distinguish files. Precise references display `filename:24` or `filename:24–30`; their destinations retain full relative or absolute paths with `#L24` or `#L24-L30` anchors. The display suffix contains neither `#` nor `L`. #### Token effect @@ -104,6 +104,7 @@ The section is static at first-party order 9000 for the lifetime of the package These limits define the current deliverables vocabulary. They are current package constraints, not a general file-linking comparison or a task backlog. +- **Inline local images require HTTP(S) and POSIX absolute paths**: Desktop’s `dsh-app:` pages and Windows drive-letter paths do not support inline local images. The guidance retains a Markdown file link so users can open the Sidebar preview. - **Mention matching is exact path or unique basename only** — a suffix mention stays inert; widening the matcher is deferred until a real closing-message shape needs it. - **Terminal-created files require explicit delivery** — the card lists them once git records the change, but delivery cards and inline-code references require `present`; explicit Markdown links can reference existing files directly. - **Declarations do not preserve file contents** — reopening or transferring a Session requires source files accessible through the viewed Session’s filesystem. Missing files, directories, and final symbolic links return 404. diff --git a/packages/client/ui-deliverables/README.zh.md b/packages/client/ui-deliverables/README.zh.md index cf9569e5fb..46540cc6c9 100644 --- a/packages/client/ui-deliverables/README.zh.md +++ b/packages/client/ui-deliverables/README.zh.md @@ -87,7 +87,7 @@ Node 半部注册[模型体验](#model-experience)所述的静态 `ui:deliverabl #### 模型看到的内容 -提示词建议在最终回复中展示主要结果:使用绝对文件路径的 Markdown 图片直接显示在正文中,文件链接打开 Sidebar 预览。对于需要完整文件的交付,尤其是 Office 文件,建议使用独立的 `present` 卡片,通常选最重要的一两项,需要时可以更多。提示词按代码改动已有 diff 视图提供建议,并要求避免为确认其显示情况额外运行命令。文件引用要求链接命令、配置表达式和代码块以外的每次现有文件提及,包括重复提及和表格。标签默认使用文件名或清楚的别名,仅添加足以区分文件的父目录。精确引用显示为 `filename:24` 或 `filename:24–30`;目标保留完整相对路径或绝对路径,以及 `#L24` 或 `#L24-L30` 锚点。显示后缀不含 `#` 或 `L`。 +提示词建议在最终回复中展示主要结果:文件链接打开 Sidebar 预览,图片预览同时保留文件链接,供不支持行内图片的客户端使用。对于需要完整文件的交付,尤其是 Office 文件,建议使用独立的 `present` 卡片,通常选最重要的一两项,需要时可以更多。提示词建议避免仅为列出代码改动生成卡片,也不为确认 diff 是否显示额外运行命令。开发者工具关闭时仍采用这条建议,接受较少的文件展示入口,以减少重复展示和不必要的工具调用。文件引用要求链接命令、配置表达式和代码块以外的每次现有文件提及,包括重复提及和表格。标签默认使用文件名或清楚的别名,仅添加足以区分文件的父目录。精确引用显示为 `filename:24` 或 `filename:24–30`;目标保留完整相对路径或绝对路径,以及 `#L24` 或 `#L24-L30` 锚点。显示后缀不含 `#` 或 `L`。 #### Token 影响 @@ -104,6 +104,7 @@ Node 半部注册[模型体验](#model-experience)所述的静态 `ui:deliverabl 这些限制界定了当前产出物词表。它们是当前包约束,不是通用文件链接对比或任务积压。 +- **本地行内图片要求 HTTP(S) 页面和 POSIX 绝对路径**:Desktop 的 `dsh-app:` 页面和 Windows 盘符路径不支持本地行内图片。提示词要求保留 Markdown 文件链接,让用户仍可打开 Sidebar 预览。 - **提及匹配只认精确路径或唯一 basename**——后缀式提及保持惰性;等真实的收尾消息形态产生需求后再放宽匹配规则。 - **终端创建的文件需要显式交付**——git 记录到改动后卡片会列出它们,但交付卡片和行内代码引用需要调用 `present`;显式 Markdown 链接可以直接引用现有文件。 - **声明不保存文件内容**:重新打开或转移 Session 后,源文件仍需能被当前查看的 Session 文件系统访问。文件缺失、为目录或最终路径为符号链接时返回 404。 diff --git a/packages/client/ui-deliverables/src/index.ts b/packages/client/ui-deliverables/src/index.ts index a5a353d8f8..9ea08752c3 100644 --- a/packages/client/ui-deliverables/src/index.ts +++ b/packages/client/ui-deliverables/src/index.ts @@ -15,8 +15,8 @@ export const inject = ['systemPrompt', 'connection', 'sessionQuery', 'sessionCon /** Static Web guidance for primary outputs and existing-file references. */ const FILE_REFERENCE_PROMPT = 'Prefer showing the primary results within your final response alongside a brief explanation. ' - + 'Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. ' - + 'Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. ' + + 'Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. For images, you can add an inline preview such as ![Preview](/absolute/path/image.png); include a file link as well so the image remains accessible in clients that cannot display it inline. ' + + 'Do not call present just to list edited source files, or run commands to check whether a diff view will appear. ' + 'Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. ' + 'Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. ' + 'Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. ' diff --git a/packages/client/ui-deliverables/tests/prompt.host.spec.ts b/packages/client/ui-deliverables/tests/prompt.host.spec.ts index 0632ed2f82..92e117a337 100644 --- a/packages/client/ui-deliverables/tests/prompt.host.spec.ts +++ b/packages/client/ui-deliverables/tests/prompt.host.spec.ts @@ -31,7 +31,7 @@ describe('ui-deliverables node plugin', () => { .find(entry => entry.name === 'ui:deliverable-file-references') expect(section?.text).toMatchInlineSnapshot('"Prefer showing the primary results within your final response alongside a brief explanation. Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix."') - // Seeded historical sessions retain the prompt recorded with their original tools. + // Only live request pins track current guidance; seeded sessions retain their recorded prompt. for (const scenario of ['fresh-round-trip', 'ptc-round']) { const sidecar = await readFile(new URL(`../../../../snapshots/web/${scenario}/system-prompt.expected.md`, import.meta.url), 'utf8') expect(sidecar, scenario).toContain(section!.text) diff --git a/packages/client/ui-primitives/tests/markdown-file-links.client.spec.tsx b/packages/client/ui-primitives/tests/markdown-file-links.client.spec.tsx index bff4bcac36..a4c0536885 100644 --- a/packages/client/ui-primitives/tests/markdown-file-links.client.spec.tsx +++ b/packages/client/ui-primitives/tests/markdown-file-links.client.spec.tsx @@ -29,6 +29,21 @@ describe('Markdown file links', () => { expect(view.container.querySelector('a')).toBeNull() }) + it.each(['/workspace/chart.png', 'C:/work/chart.png'])('keeps %s accessible when inline images are unavailable', (path) => { + const openFile = vi.fn() + const view = render( + + undefined }} + /> + , + ) + expect(view.container.querySelector('img')).toBeNull() + fireEvent.click(view.getByRole('button', { name: 'Open image' })) + expect(openFile).toHaveBeenCalledExactlyOnceWith(path, undefined) + }) + it.each(['', '![](https://example.com/image.png)'])('names an empty label %s with the decoded path', (label) => { const view = render( diff --git a/packages/deliverables/tool-present/README.i18n.yaml b/packages/deliverables/tool-present/README.i18n.yaml index 6df145b497..03415d69c8 100644 --- a/packages/deliverables/tool-present/README.i18n.yaml +++ b/packages/deliverables/tool-present/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/deliverables/tool-present/README.md -README.md: a1b4d7d3a7cc2fa7449589667667eb322df9b3cc -README.zh.md: 71529c5aa1b6ae4e66040fc3f2d76b3633b51262 +README.md: c24a9a0b274f7fecfff27d9d1a910cd4c516ac4d +README.zh.md: 3e77361f2572f28c00f4feddff01d0ce9a868bc1 diff --git a/packages/deliverables/tool-present/README.md b/packages/deliverables/tool-present/README.md index a1b4d7d3a7..c24a9a0b27 100644 --- a/packages/deliverables/tool-present/README.md +++ b/packages/deliverables/tool-present/README.md @@ -73,7 +73,7 @@ The pure `./types` entry declares `PresentedFile` and the Session event without #### What the model sees -The [present schema](../../../docs/tool-catalog.md#present) asks for existing accessible files: “Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables per call; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” Results report `Presented ` for each file; the program result and durable event contain paths and optional descriptions. +The [present schema](../../../docs/tool-catalog.md#present) asks for existing accessible files: “Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” Results report `Presented ` for each file; the program result and durable event contain paths and optional descriptions. #### Token effect diff --git a/packages/deliverables/tool-present/README.zh.md b/packages/deliverables/tool-present/README.zh.md index 71529c5aa1..3e77361f25 100644 --- a/packages/deliverables/tool-present/README.zh.md +++ b/packages/deliverables/tool-present/README.zh.md @@ -73,7 +73,7 @@ kind: "package-reference" #### 模型看到的内容 -[present schema](../../../docs/tool-catalog.zh.md#present)要求已有且可访问的文件:“Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables per call; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” 每个文件的结果为 `Presented `;程序结果和持久事件包含路径及可选说明。 +[present schema](../../../docs/tool-catalog.zh.md#present)要求已有且可访问的文件:“Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” 每个文件的结果为 `Presented `;程序结果和持久事件包含路径及可选说明。 #### Token 影响 diff --git a/packages/deliverables/tool-present/src/index.ts b/packages/deliverables/tool-present/src/index.ts index 925d2a59b3..11805f8e53 100644 --- a/packages/deliverables/tool-present/src/index.ts +++ b/packages/deliverables/tool-present/src/index.ts @@ -40,7 +40,7 @@ export function apply(ctx: Context, config: Config): void { description: 'Declare selected existing files accessible through the Session filesystem as final deliverables. ' + 'Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. ' + 'Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. ' - + 'Usually select the 1-2 most important deliverables per call; include more when the task calls for them. ' + + 'Usually select the 1-2 most important deliverables; include more when the task calls for them. ' + 'The files must already exist. The user opens the current source files; their contents are not copied or preserved.', parameters: { files: { From 223385954d79b4cd593cf4bc1ee8748b4e57b3bb Mon Sep 17 00:00:00 2001 From: creatixchu Date: Fri, 18 Sep 2026 17:10:38 +0800 Subject: [PATCH 6/7] fix: recommend at most four files per presentation --- docs/tool-catalog.i18n.yaml | 4 ++-- docs/tool-catalog.md | 2 +- docs/tool-catalog.zh.md | 2 +- packages/client/ui-deliverables/README.i18n.yaml | 4 ++-- packages/client/ui-deliverables/README.md | 2 +- packages/client/ui-deliverables/README.zh.md | 2 +- packages/client/ui-deliverables/src/index.ts | 2 +- packages/deliverables/tool-present/README.i18n.yaml | 4 ++-- packages/deliverables/tool-present/README.md | 2 +- packages/deliverables/tool-present/README.zh.md | 2 +- packages/deliverables/tool-present/src/index.ts | 2 +- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/tool-catalog.i18n.yaml b/docs/tool-catalog.i18n.yaml index 2652212da5..ea95dc73fa 100644 --- a/docs/tool-catalog.i18n.yaml +++ b/docs/tool-catalog.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write docs/tool-catalog.md -tool-catalog.md: 4f435b91fefd9fe694eaa153251dae35ab3dd543 -tool-catalog.zh.md: a7514000f9a37b3984193383a9beecd7a62ebee0 +tool-catalog.md: e737834ff79c78e514370be6548450401b5bd4ab +tool-catalog.zh.md: f15db56f7edfaa08ffdb794d57de5c4e3179a626 diff --git a/docs/tool-catalog.md b/docs/tool-catalog.md index 4f435b91fe..e737834ff7 100644 --- a/docs/tool-catalog.md +++ b/docs/tool-catalog.md @@ -627,7 +627,7 @@ The bash tool is the model-facing consumer of the bash executor seam. A `run_in_ ### `present` -Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved. +Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. The files must already exist. The user opens the current source files; their contents are not copied or preserved. ```json { diff --git a/docs/tool-catalog.zh.md b/docs/tool-catalog.zh.md index a7514000f9..f15db56f7e 100644 --- a/docs/tool-catalog.zh.md +++ b/docs/tool-catalog.zh.md @@ -631,7 +631,7 @@ bash 工具是 bash 执行器 seam 面向模型的消费方。使用 `run_in_bac ### `present` -选择 Session 文件系统可访问的已有文件,声明为最终交付物。当用户需要独立的文件交付物时使用 present,尤其是 Office 文档、电子表格和演示文稿。如果最终回复已经足够展示结果,优先在回复中展示;创建或编辑文件本身不要求调用 present。通常选择最重要的 1 至 2 项交付物,任务需要时可以更多。文件必须已存在。用户打开当前源文件;不复制或保存其内容。 +选择 Session 文件系统可访问的已有文件,声明为最终交付物。当用户需要独立的文件交付物时使用 present,尤其是 Office 文档、电子表格和演示文稿。如果最终回复已经足够展示结果,优先在回复中展示;创建或编辑文件本身不要求调用 present。通常选择最重要的 1 至 2 项交付物,任务需要时可以更多,但一次 present 调用最多 4 个文件。文件必须已存在。用户打开当前源文件;不复制或保存其内容。 ```json { diff --git a/packages/client/ui-deliverables/README.i18n.yaml b/packages/client/ui-deliverables/README.i18n.yaml index 096955008a..dcc64704fe 100644 --- a/packages/client/ui-deliverables/README.i18n.yaml +++ b/packages/client/ui-deliverables/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/client/ui-deliverables/README.md -README.md: 133d3c2dd6a1d360d8be7ce90e4f9578d5ab2075 -README.zh.md: 46540cc6c9ff7832b439ae25e091c1fd98b7e349 +README.md: a4e09925bb6833e20dfefc508052907a1be6a6e8 +README.zh.md: a8c4a74e455206d5b7ab73870bacaca7c1b4d2ed diff --git a/packages/client/ui-deliverables/README.md b/packages/client/ui-deliverables/README.md index 133d3c2dd6..a4e09925bb 100644 --- a/packages/client/ui-deliverables/README.md +++ b/packages/client/ui-deliverables/README.md @@ -87,7 +87,7 @@ Read these pages when the deliverables surface is not enough. They move from the #### What the model sees -The guidance prefers primary results in the final reply: file links open Sidebar previews, and image previews include a file link for clients without inline-image support. It recommends separate `present` cards for complete file deliverables, especially Office files, usually selecting the most important one or two while allowing more when needed. It discourages cards solely for code edits and extra commands to inspect diff visibility. This guidance applies even with developer tools disabled: it accepts fewer file surfaces to avoid duplicate presentation and unnecessary tool calls. It asks the model to link every existing-file mention outside commands, configuration expressions, and code blocks, including repeats and tables. Labels default to filenames or clear aliases, with only enough parent directories to distinguish files. Precise references display `filename:24` or `filename:24–30`; their destinations retain full relative or absolute paths with `#L24` or `#L24-L30` anchors. The display suffix contains neither `#` nor `L`. +The guidance prefers primary results in the final reply: file links open Sidebar previews, and image previews include a file link for clients without inline-image support. It recommends separate `present` cards for complete file deliverables, especially Office files, usually selecting the most important one or two, with at most four files per call when more are needed. It discourages cards solely for code edits and extra commands to inspect diff visibility. This guidance applies even with developer tools disabled: it accepts fewer file surfaces to avoid duplicate presentation and unnecessary tool calls. It asks the model to link every existing-file mention outside commands, configuration expressions, and code blocks, including repeats and tables. Labels default to filenames or clear aliases, with only enough parent directories to distinguish files. Precise references display `filename:24` or `filename:24–30`; their destinations retain full relative or absolute paths with `#L24` or `#L24-L30` anchors. The display suffix contains neither `#` nor `L`. #### Token effect diff --git a/packages/client/ui-deliverables/README.zh.md b/packages/client/ui-deliverables/README.zh.md index 46540cc6c9..a8c4a74e45 100644 --- a/packages/client/ui-deliverables/README.zh.md +++ b/packages/client/ui-deliverables/README.zh.md @@ -87,7 +87,7 @@ Node 半部注册[模型体验](#model-experience)所述的静态 `ui:deliverabl #### 模型看到的内容 -提示词建议在最终回复中展示主要结果:文件链接打开 Sidebar 预览,图片预览同时保留文件链接,供不支持行内图片的客户端使用。对于需要完整文件的交付,尤其是 Office 文件,建议使用独立的 `present` 卡片,通常选最重要的一两项,需要时可以更多。提示词建议避免仅为列出代码改动生成卡片,也不为确认 diff 是否显示额外运行命令。开发者工具关闭时仍采用这条建议,接受较少的文件展示入口,以减少重复展示和不必要的工具调用。文件引用要求链接命令、配置表达式和代码块以外的每次现有文件提及,包括重复提及和表格。标签默认使用文件名或清楚的别名,仅添加足以区分文件的父目录。精确引用显示为 `filename:24` 或 `filename:24–30`;目标保留完整相对路径或绝对路径,以及 `#L24` 或 `#L24-L30` 锚点。显示后缀不含 `#` 或 `L`。 +提示词建议在最终回复中展示主要结果:文件链接打开 Sidebar 预览,图片预览同时保留文件链接,供不支持行内图片的客户端使用。对于需要完整文件的交付,尤其是 Office 文件,建议使用独立的 `present` 卡片,通常选最重要的一两项,需要时可以更多,但每次调用最多四项。提示词建议避免仅为列出代码改动生成卡片,也不为确认 diff 是否显示额外运行命令。开发者工具关闭时仍采用这条建议,接受较少的文件展示入口,以减少重复展示和不必要的工具调用。文件引用要求链接命令、配置表达式和代码块以外的每次现有文件提及,包括重复提及和表格。标签默认使用文件名或清楚的别名,仅添加足以区分文件的父目录。精确引用显示为 `filename:24` 或 `filename:24–30`;目标保留完整相对路径或绝对路径,以及 `#L24` 或 `#L24-L30` 锚点。显示后缀不含 `#` 或 `L`。 #### Token 影响 diff --git a/packages/client/ui-deliverables/src/index.ts b/packages/client/ui-deliverables/src/index.ts index 9ea08752c3..33ede599ca 100644 --- a/packages/client/ui-deliverables/src/index.ts +++ b/packages/client/ui-deliverables/src/index.ts @@ -18,7 +18,7 @@ const FILE_REFERENCE_PROMPT = 'Prefer showing the primary results within your fi + 'Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. For images, you can add an inline preview such as ![Preview](/absolute/path/image.png); include a file link as well so the image remains accessible in clients that cannot display it inline. ' + 'Do not call present just to list edited source files, or run commands to check whether a diff view will appear. ' + 'Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. ' - + 'Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. ' + + 'Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. Avoid repeating results already shown inline unless the separate card adds useful access. ' + 'Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. ' + 'Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix.' diff --git a/packages/deliverables/tool-present/README.i18n.yaml b/packages/deliverables/tool-present/README.i18n.yaml index 03415d69c8..90a7c23e7a 100644 --- a/packages/deliverables/tool-present/README.i18n.yaml +++ b/packages/deliverables/tool-present/README.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write packages/deliverables/tool-present/README.md -README.md: c24a9a0b274f7fecfff27d9d1a910cd4c516ac4d -README.zh.md: 3e77361f2572f28c00f4feddff01d0ce9a868bc1 +README.md: a7eb9e7cf9060472258666de186a7ecefe7aa407 +README.zh.md: 5ba4ab5f100517708d80e4860d9e5eed0f43a801 diff --git a/packages/deliverables/tool-present/README.md b/packages/deliverables/tool-present/README.md index c24a9a0b27..a7eb9e7cf9 100644 --- a/packages/deliverables/tool-present/README.md +++ b/packages/deliverables/tool-present/README.md @@ -73,7 +73,7 @@ The pure `./types` entry declares `PresentedFile` and the Session event without #### What the model sees -The [present schema](../../../docs/tool-catalog.md#present) asks for existing accessible files: “Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” Results report `Presented ` for each file; the program result and durable event contain paths and optional descriptions. +The [present schema](../../../docs/tool-catalog.md#present) asks for existing accessible files: “Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” Results report `Presented ` for each file; the program result and durable event contain paths and optional descriptions. #### Token effect diff --git a/packages/deliverables/tool-present/README.zh.md b/packages/deliverables/tool-present/README.zh.md index 3e77361f25..5ba4ab5f10 100644 --- a/packages/deliverables/tool-present/README.zh.md +++ b/packages/deliverables/tool-present/README.zh.md @@ -73,7 +73,7 @@ kind: "package-reference" #### 模型看到的内容 -[present schema](../../../docs/tool-catalog.zh.md#present)要求已有且可访问的文件:“Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” 每个文件的结果为 `Presented `;程序结果和持久事件包含路径及可选说明。 +[present schema](../../../docs/tool-catalog.zh.md#present)要求已有且可访问的文件:“Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. The files must already exist. The user opens the current source files; their contents are not copied or preserved.” 每个文件的结果为 `Presented `;程序结果和持久事件包含路径及可选说明。 #### Token 影响 diff --git a/packages/deliverables/tool-present/src/index.ts b/packages/deliverables/tool-present/src/index.ts index 11805f8e53..d355fc1a6b 100644 --- a/packages/deliverables/tool-present/src/index.ts +++ b/packages/deliverables/tool-present/src/index.ts @@ -40,7 +40,7 @@ export function apply(ctx: Context, config: Config): void { description: 'Declare selected existing files accessible through the Session filesystem as final deliverables. ' + 'Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. ' + 'Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. ' - + 'Usually select the 1-2 most important deliverables; include more when the task calls for them. ' + + 'Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. ' + 'The files must already exist. The user opens the current source files; their contents are not copied or preserved.', parameters: { files: { From ba98bcbf0824eded9c0012a611599bcd220edbc9 Mon Sep 17 00:00:00 2001 From: creatixchu Date: Fri, 18 Sep 2026 17:12:03 +0800 Subject: [PATCH 7/7] test: refresh presentation guidance after review --- .../web-runtime-context/file-reference-prompt.expected.md | 2 +- packages/client/ui-deliverables/tests/prompt.host.spec.ts | 2 +- snapshots/web/fresh-round-trip/system-prompt.expected.md | 2 +- snapshots/web/fresh-round-trip/tool-schemas.expected.json | 2 +- snapshots/web/ptc-round/system-prompt.expected.md | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/web/tests/expected/web-runtime-context/file-reference-prompt.expected.md b/apps/web/tests/expected/web-runtime-context/file-reference-prompt.expected.md index 894efdb261..f4bdf601f8 100644 --- a/apps/web/tests/expected/web-runtime-context/file-reference-prompt.expected.md +++ b/apps/web/tests/expected/web-runtime-context/file-reference-prompt.expected.md @@ -1 +1 @@ -Prefer showing the primary results within your final response alongside a brief explanation. Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. +Prefer showing the primary results within your final response alongside a brief explanation. Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. For images, you can add an inline preview such as ![Preview](/absolute/path/image.png); include a file link as well so the image remains accessible in clients that cannot display it inline. Do not call present just to list edited source files, or run commands to check whether a diff view will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. diff --git a/packages/client/ui-deliverables/tests/prompt.host.spec.ts b/packages/client/ui-deliverables/tests/prompt.host.spec.ts index 92e117a337..9758dba3c5 100644 --- a/packages/client/ui-deliverables/tests/prompt.host.spec.ts +++ b/packages/client/ui-deliverables/tests/prompt.host.spec.ts @@ -29,7 +29,7 @@ describe('ui-deliverables node plugin', () => { const section = (await ctx.systemPrompt.assemble()).sections .find(entry => entry.name === 'ui:deliverable-file-references') - expect(section?.text).toMatchInlineSnapshot('"Prefer showing the primary results within your final response alongside a brief explanation. Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix."') + expect(section?.text).toMatchInlineSnapshot('"Prefer showing the primary results within your final response alongside a brief explanation. Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. For images, you can add an inline preview such as ![Preview](/absolute/path/image.png); include a file link as well so the image remains accessible in clients that cannot display it inline. Do not call present just to list edited source files, or run commands to check whether a diff view will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix."') // Only live request pins track current guidance; seeded sessions retain their recorded prompt. for (const scenario of ['fresh-round-trip', 'ptc-round']) { diff --git a/snapshots/web/fresh-round-trip/system-prompt.expected.md b/snapshots/web/fresh-round-trip/system-prompt.expected.md index f065d79923..cc5a4013c4 100644 --- a/snapshots/web/fresh-round-trip/system-prompt.expected.md +++ b/snapshots/web/fresh-round-trip/system-prompt.expected.md @@ -30,7 +30,7 @@ Use subagent in the background by default. Start independent delegations togethe Use subagent_fork in the background by default. Start independent delegations together in one assistant message and continue useful work while they run. Set `run_in_background: false` only when your next action depends on that subagent's result. When a background run settles, the runtime sends you a notice containing its outcome and any final assistant message. -Prefer showing the primary results within your final response alongside a brief explanation. Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. +Prefer showing the primary results within your final response alongside a brief explanation. Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. For images, you can add an inline preview such as ![Preview](/absolute/path/image.png); include a file link as well so the image remains accessible in clients that cannot display it inline. Do not call present just to list edited source files, or run commands to check whether a diff view will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. The DeepSeek Harness implementation checkout is at {{sourceRoot}}. The checkout location and current working directory are separate values and may differ; never infer the working directory from this path. Use pwd to determine the current working directory. Use this checkout only to inspect or extend DSH itself. diff --git a/snapshots/web/fresh-round-trip/tool-schemas.expected.json b/snapshots/web/fresh-round-trip/tool-schemas.expected.json index 6bd16a39f4..c146ce23c2 100644 --- a/snapshots/web/fresh-round-trip/tool-schemas.expected.json +++ b/snapshots/web/fresh-round-trip/tool-schemas.expected.json @@ -325,7 +325,7 @@ }, { "name": "present", - "description": "Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables per call; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved.", + "description": "Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. The files must already exist. The user opens the current source files; their contents are not copied or preserved.", "parameters": { "type": "object", "properties": { diff --git a/snapshots/web/ptc-round/system-prompt.expected.md b/snapshots/web/ptc-round/system-prompt.expected.md index 4531081ba9..914b51d1bd 100644 --- a/snapshots/web/ptc-round/system-prompt.expected.md +++ b/snapshots/web/ptc-round/system-prompt.expected.md @@ -160,7 +160,7 @@ interface ToolArgsMap { /** children (default) lists direct children only; descendants walks the complete tree below you. */ scope?: "children" | "descendants"; } & Record; - /** Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables per call; include more when the task calls for them. The files must already exist. The user opens the current source files; their contents are not copied or preserved. */ + /** Declare selected existing files accessible through the Session filesystem as final deliverables. Use present when the user needs a separate file deliverable, especially Office documents, spreadsheets, and slide decks. Prefer showing results in your final response when that is sufficient; creating or editing a file does not by itself require present. Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. The files must already exist. The user opens the current source files; their contents are not copied or preserved. */ present: { files: { /** Path of an existing regular file. Relative paths use the Session working directory. */ @@ -540,7 +540,7 @@ declare const tools: { } ``` -Prefer showing the primary results within your final response alongside a brief explanation. Markdown images using absolute file paths, such as ![Preview](/absolute/path/image.png), display the image in the reply; Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. Code changes have a separate diff view; do not call present just to list edited source files, or run commands to check whether the diff will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when the task calls for them. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. +Prefer showing the primary results within your final response alongside a brief explanation. Markdown file links such as [Report](path/to/report.html) open the file in the sidebar preview. For images, you can add an inline preview such as ![Preview](/absolute/path/image.png); include a file link as well so the image remains accessible in clients that cannot display it inline. Do not call present just to list edited source files, or run commands to check whether a diff view will appear. Use present when a separate file card helps the user open the complete deliverable, especially Office documents, spreadsheets, and slide decks. Each presented file adds a card below the reply, with preview and native-open actions. Usually select the 1-2 most important deliverables; include more when needed, but at most 4 files in a single present call. Avoid repeating results already shown inline unless the separate card adds useful access. Outside commands, configuration expressions, and code blocks, link every mention of an existing file, including repeats and tables, to its full path relative to the working directory or absolute; append #L24 or #L24-L30 to the target for known lines. Use the filename or a clear alias as the label, adding only enough parent directories to distinguish files; keep full paths out of labels. Default to the name alone; when precise locations matter, append :24 or :24–30, with no # or L in the line suffix. The DeepSeek Harness implementation checkout is at {{sourceRoot}}. The checkout location and current working directory are separate values and may differ; never infer the working directory from this path. Use pwd to determine the current working directory. Use this checkout only to inspect or extend DSH itself.