fix(rebase): restore consolidated documentation state

This commit is contained in:
Turtle
2026-07-29 21:16:31 +08:00
parent 9970f60969
commit d2c7aaddc7
18 changed files with 40 additions and 350 deletions

View File

@@ -2,10 +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/examples/README.md
<<<<<<< HEAD
README.md: c229cef22087ac290bf862d6b3e31fdb533858c4
README.zh.md: 208b9a138506785ea1dd2d83ddfbba29e4b7968e
=======
README.md: d3ad432e71036db0d21f059e52f5d32e58010c42
README.zh.md: 0218e60df2511974b8eb222e23331c5a70c9df60
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)

View File

@@ -2,25 +2,16 @@
[English](README.md) | 中文
预先组合的插件 bundle(组合包),供轻量叶节点 `cordis.yml` 加载,无需手工组装主干和前端入口。这些是 **演示/参考** 包(package);npm 名称的 `-demo` 后缀把每个包标为非产品表层,直接查看包名即可辨认。仓库根目录 [`examples/`](../../examples/AGENTS.md) 下的可运行叶节点与 [Python SDK 运行时](../../python/sdk-runtime/README.md) 是消费方;每个消费方都只包含可替换后端和一个组合包入口。
预先组合的插件 bundle(组合包),供轻量叶节点 `cordis.yml` 加载,无需手工组装主干和前端入口。这些是 **演示/参考** 包;npm 名称的 `-demo` 后缀把每个包标为非产品表层,直接查看包名即可辨认。仓库根目录 [`examples/`](../../examples/AGENTS.md) 下的可运行叶节点与 [Python SDK runtime](../../python/sdk-runtime/README.md) 是消费方;每个叶节点都只包含可替换后端和一个组合包入口。
| 包 | npm 名称 | 角色 |
|---|---|---|
<<<<<<< HEAD
| `agent-spine-demo/` | `@deepseek-ai/dsh-agent-spine-demo` | 不含执行器和 UI 的 agent(智能体)主干,打包为一个组合包插件,带后备会话标题和可选择启用的持久化目标栈 |
| `tui-demo/` | `@deepseek-ai/dsh-tui-demo` | 全屏终端应用组合包:主干 + 持久化目标 + `/goal` 命令 + JSONL 持久化 + `dsh-tui` + 预创建的 `main` agent;没有 bin,由 [`dsh`](../../apps/cli/README.md) CLI(命令行界面)启动 |
=======
| `agent-spine-demo/` | `@deepseek-ai/dsh-agent-spine-demo` | 不含执行器和 UI 的 agent 主干,打包为一个组合包插件,带后备会话标题和选用的持久目标栈 |
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)
| `cli-demo/` | `@deepseek-ai/dsh-cli-demo` | 无头单次应用:主干 + JSONL 持久化 + 预创建的 `main` agent,提供文本和 DSH 原生 JSON 输出 |
| `acp-demo/` | `@deepseek-ai/dsh-acp-demo` | ACP(Agent Client Protocol)自动化服务器应用:主干 + 持久化目标 + JSONL 持久化 + [`acp`](../acp/acp/README.md) 桥接层(无 stdout logger),带启动 `bin` |
| `jsonrpc-demo/` | `@deepseek-ai/dsh-jsonrpc-demo` | 只有 bin 的运行时,用于启动外部 `cordis.yml`,供 stdio JSON-RPC SDK 客户端使用 |
| `acp-demo/` | `@deepseek-ai/dsh-acp-demo` | ACP 自动化服务器应用:主干 + 持久目标 + JSONL 持久化 + [`acp`](../acp/acp/README.md) 桥接层(无 stdout logger),带启动 `bin` |
| `jsonrpc-demo/` | `@deepseek-ai/dsh-jsonrpc-demo` | 只有 bin 的 runtime,用于启动外部 `cordis.yml`,供 stdio JSON-RPC SDK 客户端使用 |
<<<<<<< HEAD
`agent-spine-demo` 是共享组合包;`tui-demo`、`cli-demo` 和 `acp-demo` 分别将它与全屏终端、无头单次和 ACP 自动化前端入口组合。`cli-demo` 与 `acp-demo` 拥有各自的启动 bin;`tui-demo` 只交付组合包插件,产品 [`dsh`](../../apps/cli/README.md) CLI 是它的终端前端入口。`jsonrpc-demo` 自身不挂载任何组合,而是启动部署的 `cordis.yml` 所指名的任意插件树;Python SDK 运行时会启动它。
=======
`agent-spine-demo` 是共享组合包;`cli-demo` 和 `acp-demo` 分别将它与无头单次和 ACP 自动化前端入口组合,并拥有各自的启动 bin。产品 [`dsh`](../../apps/cli/README.md) CLI 不使用组合包:其 TUI 与 web surface 都是一份共享的 `base.cordis.yml` 加各自一份 overlay。`jsonrpc-demo` 自身不挂载任何组合,而是启动部署的 `cordis.yml` 所指名的任意插件树;Python SDK runtime 会启动它。
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)
这些 **不是** 产品 API。它们打包的主干组件位于 [`core/`](../core/README.md),人类/SDK 通道和启动粘合代码位于 [`ui/`](../ui/README.md),自动化传输位于 [`acp/`](../acp/README.md),可替换后端位于各自能力组;演示组合包只选定其中一种具体组合。可以自由替换或 fork。
@@ -28,4 +19,4 @@
## jsonrpc bin/exe 名称是历史遗留
`jsonrpc-demo` 已像同级包一样重命名,但其 bin 仍为 `dsh-jsonrpc-agent`,单文件可执行程序仍为 `dsh-jsonrpc-agent-pkg`(在 [Python 分发](../../python/sdk-runtime/README.md)各处被引用)。这些名称属于 SDK 的运行时启动表层;只有 SDK 统一该启动流程时才会协调它们,而不会在此次移动中处理。
`jsonrpc-demo` 已像同级包一样重命名,但其 bin 仍为 `dsh-jsonrpc-agent`,单文件可执行程序仍为 `dsh-jsonrpc-agent-pkg`(在 [Python 分发](../../python/sdk-runtime/README.md)各处被引用)。这些名称属于 SDK 的 runtime 启动表层;只有 SDK 统一该启动流程时才会协调它们,而不会在此次移动中处理。

View File

@@ -2,10 +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/examples/agent-spine-demo/README.md
<<<<<<< HEAD
README.md: 359e7153be2f480ba3fea4b06782acdc9f89ebb9
README.zh.md: acd8c06940b03e90e368314cd725846a2b92b656
=======
README.md: 6fde5c64052e369541787f90c12c33a7b0b8f9eb
README.zh.md: d5b0e2b50707750132bdeae9d7e56d513b0f40a7
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)

View File

@@ -2,7 +2,7 @@
[English](README.md) | 中文
将 **默认的不含执行器、不含 UI 的 agent(智能体)主干** 作为一个 Cordis 组合包插件。它加载每个 harness agent 所需的固定服务集合,包括本地 skill(技能)提供方,并将循环的 `agents` 列表作为自身配置转发。因此,应用包(package)只需添加前端入口和可替换后端,就能组合出可工作的 agent。
将 **默认的不含执行器、不含 UI 的 agent 主干** 作为一个 Cordis 组合包插件。它加载每个 harness agent 所需的固定服务集合,包括本地 skill 提供方,并将循环的 `agents` 列表作为自身配置转发。因此,应用包只需添加前端入口和可替换后端,就能组合出可工作的 agent。
阅读此包可了解完整插件树及其组合顺序。
@@ -43,15 +43,11 @@
主干包含每个前端入口都共有的全部组件。可替换组件和与前端入口耦合的组件留在外部,由加载组合包的一方选择:
- **LLM(大语言模型)适配器**:组合包交付抽象 `llm` 服务;叶节点在 `ctx.llm` 上注册具体适配器(`llm-deepseek`、`llm-pi-ai`、`llm-replay`)。
- **基于模型的会话标题提供方**:组合包挂载带可覆盖示例限制的后备服务(5 个词、40 个后备字节、80 个可接受标题字节);叶节点可以恰好选用一个首消息或全消息 LLM 提供方。
- **LLM 适配器**:组合包交付抽象 `llm` 服务;叶节点在 `ctx.llm` 上注册具体适配器(`llm-deepseek`、`llm-pi-ai`、`llm-replay`)。
- **模型支持的会话标题提供方**:组合包挂载带可覆盖示例限制的后备服务(5 个词、40 个后备字节、80 个可接受标题字节);叶节点可以恰好选用一个首消息或全消息 LLM 提供方。
- **bash 执行器**:组合包交付 `tool-bash`(消费方 schema);叶节点提供 `ctx.bash`(`bash-local` 或沙箱化实现)。
- **非本地 skill 提供方**:组合包交付 skill 注册表、本地文件系统提供方和 `skill` 工具;部署可以把嵌入式目录或远程目录等其他提供方作为同级插件添加。
<<<<<<< HEAD
- **前端入口与各应用基础设施**:终端 TUI 或 ACP(Agent Client Protocol)自动化传输,以及 `hmr`。应用包([`dsh-tui-demo`](../tui-demo/README.md)、[`dsh-acp-demo`](../acp-demo/README.md))拥有这些选择。`timer` 位于主干中,因为它是共有组件且不写 stdout;前端入口拥有 stdout,因此留在组合包外。
=======
- **前端入口与各应用基础设施**:终端 TUI 或 ACP 自动化传输,以及 `hmr`。应用包([`dsh-cli-demo`](../cli-demo/README.md)、[`dsh-acp-demo`](../acp-demo/README.md))拥有这些选择。`timer` 位于主干中,因为它是共有组件且不写 stdout;前端入口拥有 stdout,因此留在组合包外。
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)
这把[接口/实现/消费方 seam](../../../.agents/notes/implemented/architecture/2026-06-13-capability-seams.md) 提升到组合层:组合包拥有共享主干,叶节点拥有后端,应用包拥有前端入口。
@@ -63,25 +59,25 @@ import type { Config } from '@deepseek-ai/dsh-agent-spine-demo'
// workspaceContext requires { maxBytes } or false; the other owner schemas supply defaults.
```
组合包将每个字段转发给拥有它的子节点:`agents` 与 `maxParallelToolCalls` 交给 `agent-loop`(`agents` 默认为 `[]`,上限在该处默认),因此每个应用提供自己的预创建 agent;TUI 和无头应用预创建 `main`,ACP 应用则在 `session/new` 按需创建 agent;`persona` 与 `toolOrder` 交给 `dsh-system-prompt`;`tools` 交给工具注册表以配置呈现模式;`sessionTitle` 交给后备标题服务;`skills.registry`、`skills.local` 与 `skills.tool` 分别交给 skill 注册表、本地提供方和面向模型的消费方;必填的 `workspaceContext` 选择交给 `dsh-workspace-context`(`{ maxBytes }` 启用加载,`false` 禁用);`invariants` 交给不变式服务;`toolBash`/`toolTasks` 交给组合包拥有的两个面向模型工具插件。组合包始终挂载 `dsh-llm-retry`,而每个叶节点适配器拥有自己的嵌套 `retryPolicy`。省略 `sessionTitle` 时采用显式示例策略:5 个词、40 个后备字节、80 个可接受标题字节。`goals` 对象会选用持久化领域、模型工具和同会话 Goal Round 驱动器,并将 `goals.domain` 与 `goals.tool` 转发给各自拥有者;省略或设为 `false` 会让整个栈缺席,使无头调用方继续以单轮次结算。设置 `skills.enabled: false` 会同时省略本地提供方和面向模型的 skill 工具;设置 `toolTasks: false` 会保留供前台生产方使用的任务服务,但不公开 `task_output`/`task_list`/`task_kill`。它对 `dshHome` 只解析一次,解析通过 [`@deepseek-ai/dsh-paths`](../../util/paths/README.md) 完成,并将所得绝对值转发给 tool-bash 的托管环境和已启用的本地 skill 发现。顶层 `dshHome` 缺席时采用 `skills.local.dshHome`;两者同时提供但解析后的路径不同会明确失败。`toolBash.enableRunInBackground` 只控制 bash 生产方;独立加载的生产方保留各自配置。工作区指令先于 skill 目录注册,因此其会话前缀消息先渲染。应用包使用 `pickSpineConfig()`,只复制这些由组合包拥有的字段。
组合包将每个字段转发给拥有它的子节点:`agents` 与 `maxParallelToolCalls` 交给 `agent-loop`(`agents` 默认为 `[]`,上限在该处默认),因此每个应用提供自己的预创建 agent;TUI 和无头应用预创建 `main`,ACP 应用则在 `session/new` 按需创建 agent;`persona` 与 `toolOrder` 交给 `dsh-system-prompt`;`tools` 交给工具注册表以配置呈现 mode;`sessionTitle` 交给后备标题服务;`skills.registry`、`skills.local` 与 `skills.tool` 分别交给 skill 注册表、本地提供方和面向模型的消费方;必填的 `workspaceContext` 选择交给 `dsh-workspace-context`(`{ maxBytes }` 启用加载,`false` 禁用);`invariants` 交给不变式服务;`toolBash`/`toolTasks` 交给组合包拥有的两个面向模型工具插件。组合包始终挂载 `dsh-llm-retry`,而每个叶节点适配器拥有自己的嵌套 `retryPolicy`。省略 `sessionTitle` 时采用显式示例策略:5 个词、40 个后备字节、80 个可接受标题字节。`goals` 对象会选用持久领域、模型工具和同会话驱动器,并将 `goals.domain` 与 `goals.tool` 转发给各自拥有者;省略或设为 `false` 会让整个栈缺席,使无头调用方继续以一轮结算。设置 `skills.enabled: false` 会同时省略本地提供方和面向模型的 skill 工具;设置 `toolTasks: false` 会保留供前台生产方使用的任务服务,但不公开 `task_output`/`task_list`/`task_kill`。它对 `dshHome` 只解析一次,解析通过 [`@deepseek-ai/dsh-paths`](../../util/paths/README.md) 完成,并将所得绝对值转发给 tool-bash 的托管环境和已启用的本地 skill 发现。顶层 `dshHome` 缺席时采用 `skills.local.dshHome`;两者同时提供但解析后的路径不同会明确失败。`toolBash.enableRunInBackground` 只控制 bash 生产方;独立加载的生产方保留各自配置。Workspace 指令先于 skill 目录注册,因此其会话前缀消息先渲染。应用包使用 `pickSpineConfig()`,只复制这些由组合包拥有的字段。
例如,`{ invariants: { enabled: true, package_allowlist: ['^@deepseek-ai/dsh-'], package_blocklist: ['agent-loop$'] } }` 会让包拥有的配套插件保持挂载,但抑制被阻止的拥有者。Blocklist 匹配优先于 allowlist 匹配;正则表达式与生命周期规则见 [`dsh-invariants`](../../support/invariants/README.md)。
## 为何使用代码组合包,而非共享 YAML include
YAML include 可以去重配置,却无法拥有 bin 或提供前端入口默认值。ACP 应用包默认接出协议纯净的 stdout,但叶节点仍可添加不安全的 logger。组合包子节点把服务注册到根 isolate-keyed store,因此叶节点的同级插件无需依赖加载顺序即可通过注入看到它们。
YAML include 可以去重配置,却无法拥有 bin 或提供前端入口默认值。ACP 应用包默认接出协议纯净的 stdout,但叶节点仍可添加不安全的 logger。组合包子节点把服务注册到根 isolate-keyed store,因此注入这些服务的叶节点同级插件无需依赖加载顺序即可看到它们。
重试策略可能在新的编号步骤中重复失败的请求。重试状态、提供方错误和失败的部分分片不进入模型历史;每次提供方尝试仍可能产生计费;always 模式没有尝试次数上限;前端入口从所有已记录步骤推导用量;重建的请求保留先前前缀,以便复用提供方缓存。
重试策略可能在新的编号步骤中重复失败的请求。重试状态、提供方错误和失败的部分 chunk 不进入模型历史;每次提供方尝试仍可能产生计费;always mode 没有尝试次数上限;前端入口从所有已记录步骤推导用量;重建的请求保留先前前缀,以便复用提供方 cache。
## 模型体验
模型通过 `dsh-system-prompt`、`dsh-tool-skill`、`dsh-tool-bash`、`dsh-tools` 和 `dsh-llm-retry` 间接获得体验;还会通过 `dsh-tool-goal` 与 Goal Round 提示词获得体验,前提是启用 `goals`。组合包自身不添加面向模型的包装内容。
模型通过 `dsh-system-prompt`、`dsh-tool-skill`、`dsh-tool-bash`、`dsh-tools` 和 `dsh-llm-retry` 间接获得体验;还会通过 `dsh-tool-goal` 与目标轮次提示词获得体验,前提是启用 `goals`。组合包自身不添加面向模型的包装内容。
#### KV Cache 影响
不会直接失效;上述消费方负责请求前缀的任何变更。
不会直接失效;具名消费方拥有请求前缀的任何变更。
## 已知限制与暂缓事项
## 已知限制与延后工作
- **大部分主干集合固定在代码中**:`apply()` 始终挂载核心服务与 `tool-bash`;配置可以省略组合包内的目标、skill 与任务控制工具,但要替换循环或删除其他主干成员,就必须组合另一个组合包。
- **大部分主干集合固定在代码中**:`apply()` 始终挂载核心服务与 `tool-bash`;配置可以省略组合包内的目标、skill 与任务控制工具,但要替换循环或删除其他主干成员,就必须组合另一个 bundle。
- **不变式 seam 与配套插件仍是固定成员**:`invariants.enabled: false` 或包筛选器会抑制检查,但不会移除服务或配套插件注册;Session 始终启用的校验与冻结是另一套机制。

View File

@@ -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 packages/examples/tui-demo/README.md
README.md: 058ebe87af5f041bd19fbfb205a97753ccacf6b9
README.zh.md: 43681e9c77cbd77459ec0539b69e0ab73274d2c1

View File

@@ -1,112 +0,0 @@
# @deepseek-ai/dsh-tui-demo
[English](README.md) | 中文
全屏终端应用组合包:一个 Cordis 插件,组合 [`@deepseek-ai/dsh-agent-spine-demo`](../agent-spine-demo/README.md)、持久化的同会话目标、人类命令注册表与 `/goal` 生产方、JSONL 持久化、键盘支持的用户交互、预创建的 `main` agent(智能体),以及 [`@deepseek-ai/dsh-tui`](../../ui/tui/README.md)。一份 `cordis.yml` 将它作为一个 Cordis 配置项挂载;[`dsh`](../../../apps/cli/README.md) CLI(命令行界面)是启动此类配置的入口。
管道、脚本和其他非交互式运行应使用 [`@deepseek-ai/dsh-cli-demo`](../cli-demo/README.md)。此组合包需要一对 TTY,不提供面向行的回退。
## 内置组件
| 插件 | 设置在此处的原因 |
|---|---|
| `@deepseek-ai/dsh-agent-spine-demo` | 共享服务、面向模型的工具,以及一个已配置的 `main` agent |
| `@deepseek-ai/dsh-commands` | 供 TUI 和命令插件消费、仅面向人类的命令发现与分发 |
| `@deepseek-ai/dsh-command-goal` | 直接在主干的持久化目标栈上提供 `/goal` 状态与变更 |
| `@deepseek-ai/dsh-session-persistence-jsonl` | 位于 `persistenceRoot` 下的持久会话日志 |
| `@deepseek-ai/dsh-session-checkpoint-policy` | 模型请求和顶层工具 effect 前的语义持久性屏障,以及已完成步骤的检查点 |
| `@deepseek-ai/dsh-session-query-sqlite` + `@deepseek-ai/dsh-session-reference` | TUI 消费的组合式精确/FTS 会话查询与有界 `@session` 快照;面向模型的查询工具仍由叶节点选用 |
| `@deepseek-ai/dsh-user-interaction` | 与提供方无关的人类问题服务 |
| `@deepseek-ai/dsh-tui` | 全屏 transcript(文本记录)、编辑器、工具卡片、计划与问题 overlay |
| `@deepseek-ai/dsh-tool-ask-user` | 面向模型的 `ask_user_question` 工具 |
可替换的 LLM(大语言模型)、bash、文件系统和其他能力提供方仍留在叶节点配置中。`@cordisjs/plugin-hmr` 也仍是仅叶节点使用的开发条目,因为它需要 Loader 内部实现。
## 配置
| 键 | 默认值 | 路由目标 |
|---|---|---|
| `provider` | 必填 | 已配置 `main` agent 的提供方 |
| `model` | 必填 | 已配置 `main` agent 的模型 |
| `maxParallelToolCalls` | agent-loop 默认值 | 组合包内循环的并发上限 |
| `persona` | 无 | 系统提示词 persona 模板 |
| `toolOrder` | 字典序 | 显式的面向模型工具顺序 |
| `tools` | 拥有者默认值 | 工具呈现模式 |
| `dshHome` | 拥有者默认值 | bash 与 skill(技能)使用的 harness 主目录 |
| `sessionTitle` | 主干示例限制 | 后备标题词数/字节限制 |
| `skills` | 拥有者默认值 | skill 注册表、本地提供方和工具配置 |
| `toolBash` | 拥有者默认值 | 面向模型的 bash 工具配置 |
| `toolTasks` | 拥有者默认值 | 后台任务控制工具配置,或 `false` |
| `goals` | 拥有者默认值 | 持久目标领域与模型工具配置;`false` 会移除目标栈与 `/goal` 生产方 |
| `workspaceContext` | 必填 | Workspace 指令配置,或 `false` |
| `persistenceRoot` | `./.sessions` | JSONL 持久化根目录,以及派生 `session-query.db` 索引的父目录 |
| `persistenceCompression` | `'zstd'` | JSONL 产物编码(`'zstd'` 或原始 `'none'`) |
| `sessionReferences` | 服务默认值 | 路由到 `dsh-session-reference` 的跨会话候选项与快照限制 |
| `welcome` | `ready.` | TUI 副标题 |
| `resumeCommand` | 无 | 退出和无宿主回退的命令模板;选择器本身使用会话查询与宿主移交 |
| `ui` | 拥有者默认值 | 推理(reasoning)、颜色、卡片高度等 TUI 呈现设置 |
| `resumeSessionId` | 无 | 要恢复的确切持久化会话 |
新运行会创建 `main-session-<uuid>` 会话 id,并将它同时传给 TUI 与已配置的 agent。恢复运行会将两个组件都绑定到 `resumeSessionId`。TUI 先于主干挂载,因此它可以渲染匹配的配置启动失败,而不会留下空白终端。应用为 `/resume` 组合持久化和会话查询;嵌入宿主还可以提供 `tuiResumeHost`,用于原地移交进程。
## 入口
此包(package)不交付 bin。[`dsh`](../../../apps/cli/README.md) CLI 是终端入口:裸 `dsh` 启动已交付的 `examples/tui-agent/cordis.yml`(它挂载此组合包),而 `dsh --config <path-to-cordis.yml>` 启动另一个挂载此组合包的叶节点配置。它加载 cwd 下可选的 `.env`,驱动 Cordis Loader,并等待完整插件树。仓库安装了 Loader 的可选原生辅助程序,因此裸包说明符可以在纯 Node 下解析。
## 叶节点示例
```yaml
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
config:
apiKey: !!js process.env.DEEPSEEK_API_KEY
- id: bash
name: '@deepseek-ai/dsh-bash-local'
- id: tui-agent
name: '@deepseek-ai/dsh-tui-demo'
config:
provider: deepseek
model: deepseek-v4-flash
workspaceContext:
maxBytes: 65536
welcome: 'Coding agent ready.'
ui:
showReasoning: true
```
## 模型体验
### 交互式终端轮次
#### 模型看到的内容
每次非空、非命令的编辑器提交都会成为用户消息;运行中轮次内的提交成为 steering(中途引导)。斜杠命令输入和输出仍只面向人类,而已接受的 `/goal` 变更会追加领域拥有的模型可见状态。共享主干提供已配置的 persona、workspace 指令、skill 目录、目标控制和可见工具 schema。TUI 渲染本身对模型不可见。
#### Token 影响
用户、assistant 与工具历史按常规会话和压缩(compaction)规则增长。Header、卡片、计划、Markdown 样式和快捷键不增加 token。
#### KV Cache 影响
只要组合后的提示词、schema、路由和保留历史前缀保持稳定,就保持仅追加。组合方式变更与 compaction 可能从第一个变化的 token 起使复用失效。
### 人类问题答案
#### 模型看到的内容
`ask_user_question` 会保留工具调用,以及 `dsh-tool-ask-user` 定义的精简答案或稳定中断错误。问题 overlay 只在终端显示。
#### Token 影响
只有已完成或失败的工具结果会增加保留 token。
#### KV Cache 影响
仅追加;答案跟在可复用请求前缀之后。
## 已知限制与暂缓事项
- **只支持 TTY**:stdin 与 stdout 都必须是终端;自动化使用 `dsh-cli-demo`。
- **一个已配置的终端会话**:transcript 与编辑器绑定到一个确切会话 id。
- **应用集群固定不变**:JSONL 持久化与 ask-user 工具内置;不同策略需要另一种组合。
- **批准机制独立存在**:此应用回答 `ctx.userInteraction`,而不是 `ctx.approval`;权限提示需要批准服务和回答方。

View File

@@ -2,10 +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/todo/README.md
<<<<<<< HEAD
README.md: 1e5ae9a1583b9e9d3913fcd1dca7ef11a5f391fe
README.zh.md: a77f788a41353ea547059864dc7cf73ac5025219
=======
README.md: 495851a13f70bc8e3cb2dc99da47ab305ca205fa
README.zh.md: abdac592a312cb36d145e7d16e01821561090dcb
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)

View File

@@ -1,15 +1,11 @@
# todo/:todo/规划能力家族
# todo/:todo/规划能力系列
[English](README.md) | 中文
面向模型的 todo 工具。它是单一 **产品**包(package):这里没有接口/实现 seam,因为该列表是由单一所有者管理的会话状态(每个 agent(智能体)会话拥有自己的列表),而非可替换能力。
面向模型的 todo 工具。它是单一 **产品** 包(package):这里没有接口/实现 seam,因为该列表是由单一所有者管理的会话状态(每个 agent(智能体)会话拥有自己的列表),而非可替换能力。
| 包 | 职责 | ctx 键 |
|---|---|---|
| `tool-todo/` | 面向模型的 `todo_write` 工具;将完整列表写入会话日志(`todo/write`) | (注册到 `ctx.tools`) |
<<<<<<< HEAD
列表存在于事件溯源会话日志中(`SessionEventMap['todo/write']`,由 [`dsh-session`](../core/session) 拥有);本包是追加快照的轻量消费方。[TUI 应用](../examples/tui-demo)等 UI 以及宿主/客户端运行时会根据会话事件渲染该持久化列表。
=======
列表存在于事件溯源会话日志中(`SessionEventMap['todo/write']`,由 [`dsh-session`](../core/session) 拥有);本包是追加快照的轻量消费方。[TUI 前端入口](../ui/tui)等 UI 以及宿主/客户端运行时会根据会话事件渲染该持久列表。
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)

View File

@@ -2,10 +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/todo/tool-todo/README.md
<<<<<<< HEAD
README.md: b05ef43e7137dcf5678b1f1ad6d8c00b8a43baef
README.zh.md: 88a9f5d69ff52dcedbd8f27a4ace5fde3e0dc5a2
=======
README.md: f86a0d7331cc822a6568eeb14b89a64abaa23378
README.zh.md: 778c920198599546890c90d21badf2d7bb0f2551
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)

View File

@@ -6,66 +6,62 @@
## 功能
注册一个工具 `todo_write(todos: [{ content, status }])` 到 `ctx.tools`。模型每次调用都会发送完整列表,不存在部分更新或单项编辑。每次调用都会向调用 agent 的会话日志追加 `todo/write` 事件(完整列表快照),具体调用 `agent.session.append('todo/write', { todos })`;当前列表是最新的该类事件(回放时后写覆盖先写)。
注册一个工具 `todo_write(todos: [{ content, status }])` 到 `ctx.tools`。模型每次调用都会发送完整列表,不存在部分更新或单项编辑。每次调用都会向调用 agent 的会话日志追加 `todo/write` 事件(完整列表快照),具体调用 `agent.session.append('todo/write', { todos })`;当前列表是最新的该类事件(回放时后写者胜)。
`status` 是 `pending`、`in_progress` 或 `completed` 之一。
## 单一所有者
该列表属于调用工具的唯一 agent 会话。不存在 subagent/共享/swarm scope:非 agent 调用方(没有 `exec.agent`)无处写入列表,因此会被拒绝。这是有意设置的 scope 限制,详见 Agent Note(agent 决策记录)。
该列表属于调用工具的唯一 agent 会话。不存在 subagent/共享/swarm scope:非 agent 调用方(没有 `exec.agent`)无处写入列表,因此会被拒绝。这是有意设置的 scope 限制,详见 Agent Note。
## 验证
除 schema 的类型/必填/枚举检查外,`execute` 还会拒绝空或重复的 `content`、同时存在多个 `in_progress` 任务的情况(连贯计划最多只有一个活跃任务),以及 `content`/`status` 之外的任何条目键——扩展条目形状(id、嵌套)会明确报错而不是被静默压平,保证落日志的快照与模型自认为写入的内容一致。列表的顺序及及时更新由模型依照工具描述负责。
除 schema 的类型/必填/枚举检查外,`execute` 还会拒绝空或重复的 `content`、同时存在多个 `in_progress` 任务的情况(连贯计划最多只有一个活跃任务),以及 `content`/`status` 之外的任何条目键——扩展条目形状(id、嵌套)会响亮失败而不是被静默压平,保证落日志的快照与模型自认为写入的内容一致。顺序与保持列表最新的纪律由模型根据工具描述负责。
## 渲染
<<<<<<< HEAD
规范结果为 `{ todos, counts: { pending, inProgress, completed } }`;其 Native 渲染器返回精简的更新确认。工具还会写入完整 `todo/write` 会话事件。UI 订阅事件流,并自行渲染该持久化列表:[TUI 应用](../../examples/tui-demo)与 [web 客户端](../../client/ui-conversation)基于当前有效计划(其后没有更晚 `turn/start` 的最近一次 `todo/write`)显示计划条(web 另有专属工具行)([展示](../../../.agents/notes/implemented/feature/2026-07-23-web-todo-display.md)、[生命周期](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md))。
=======
规范结果为 `{ todos, counts: { pending, inProgress, completed } }`;其 Native 渲染器返回精简的更新确认。工具还会写入完整 `todo/write` 会话事件。UI 订阅事件流,并自行渲染该持久列表:[TUI 前端入口](../../ui/tui)与 [web 客户端](../../client/ui-conversation)基于站立计划(其后没有更晚 `turn/start` 的最近一次 `todo/write`)显示计划条(web 另有专属工具行)([展示](../../../.agents/notes/implemented/feature/2026-07-23-web-todo-display.md)、[生命周期](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md))。
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)
## 会话投影
当组合挂载了 `ctx.sessionProjections`([`@deepseek-ai/dsh-session-projection`](../../session-projection/session-projection/README.md))时,本包在一个注入的子插件中注册 `todos` 投影单元:`init` = `null`(尚无写入)、`apply` = 从每个 `todo/write` 取整表,并在每个 `turn/start` 清为 `null`(当前有效计划;`turn/end` 保留刚完成的清单;其余事件都返回同一个状态引用)、`view` = 恒等、`stateVersion` = 2。该键在本包中合并进 `SessionProjectionMap`(经接口包的 `/types` 出口);框架驱动该单元,载体通过历史尾页与 `session/projection` 推送帧提供该值。未挂载注册表的组合不受影响。生命周期理由见 [在下一轮次清空 todo 计划](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md)。
当组合挂载了 `ctx.sessionProjections`([`@deepseek-ai/dsh-session-projection`](../../session-projection/session-projection/README.md))时,本包在一个注入式子插件下注册 `todos` 投影单元:`init` = `null`(尚无写入)、`apply` = 从每个 `todo/write` 取整表,并在每个 `turn/start` 清为 `null`(站立计划;`turn/end` 保留刚完成的清单;其余事件都返回同一个状态引用)、`view` = 恒等、`stateVersion` = 2。key 在本包合并进 `SessionProjectionMap`(经接口包的 `/types` 出口);框架驱动该单元,载体在历史尾页与 `session/projection` 推送帧上供给该值。未装注册表的组合不受影响。生命周期理由见 [下一轮清空 todo 计划条](../../../.agents/notes/implemented/feature/2026-07-28-todo-plan-clears-on-next-turn.md)。
## 导出形状
函数/命名空间插件:导出 `name`/`inject`/`apply`,不提供默认导出。意外的 `export default` 会被 Loader 的 `unwrapExports` 折叠为默认导出,并导致 `inject` 丢失(参见 [docs/postmortem/0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.md))。
函数/命名空间插件:导出 `name`/`inject`/`apply`,不提供默认导出。意外的 `export default` 会通过 Loader 的 `unwrapExports` 折叠模块并丢弃 `inject`(参见 [docs/postmortem/0001](../../../docs/postmortem/0001-acp-default-export-drops-inject.md))。
## 模型体验
### 工具 schema
#### 模型看到的内容
#### 模型所见内容
模型会看到生成的 [`todo_write` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-todo)。
#### Token 影响
工具可见的每个请求都有固定的 schema token 开销。
工具可见的每个请求都有固定 schema 成本。
#### KV Cache 影响
只要定义和可见性不变,前缀就保持稳定。插件生命周期或 scope 限制可能会使从此 schema 起的缓存复用失效。
只要定义和可见性不变,前缀就保持稳定。插件生命周期或 scope 限制可能会使此 schema 之后的复用失效。
### 工具调用历史与结果
#### 模型看到的内容
#### 模型所见内容
每个 assistant 工具调用都会在参数中保留整个替换列表。成功时原样返回 `Updated todo list: <pending> pending, <inProgress> in progress, <completed> completed.`。稳定失败文本为 ``Error: invalid todo: `content` must be a non-empty string``、`Error: invalid todos: duplicate content "<content>"`、`Error: invalid todos: at most one task may be in_progress, got <count>` 和 `Error: todo_write requires an owning agent session`。完整 `todo/write` 会话事件是 UI 与回放状态,而非第二条模型消息。
每个 assistant 工具调用都会在参数中保留整个替换列表。成功时精确返回 `Updated todo list: <pending> pending, <inProgress> in progress, <completed> completed.`。稳定失败文本为 ``Error: invalid todo: `content` must be a non-empty string``、`Error: invalid todos: duplicate content "<content>"`、`Error: invalid todos: at most one task may be in_progress, got <count>` 和 `Error: todo_write requires an owning agent session`。完整 `todo/write` 会话事件是 UI 与回放状态,而非第二条模型消息。
#### Token 影响
token 用量会随模型每次提交的完整列表增长,且这些调用参数会保留到压缩(compaction)。结果本身很小,且形状固定。
Token 增长与模型每次提交的完整列表成比例,且这些调用参数会保留到压缩(compaction)。结果本身很小,且形状固定。
#### KV Cache 影响
仅追加;新可见内容位于可复用请求前缀之后,不会使现有 KV-cache 条目失效。
## 已知限制与暂缓事项
## 已知限制与延后工作
- **仅单一所有者 scope**:列表属于唯一调用 agent 会话;subagent/共享/swarm scope 是有意设置的限制(参见「单一所有者」一节),非 agent 调用方会被拒绝。
- **条目形状有意保持最小**:`content` 加三态 `status`;整表替换不需要稳定 id、优先级或 active-form 字段。
- **仅单一所有者 scope**:列表属于唯一调用 agent 会话;subagent/共享/swarm scope 是有意裁减(参见「单一所有者」一节),非 agent 调用方会被拒绝。
- **项目形状有意保持最小**:`content` 加三态 `status`;整表替换不需要稳定 id、优先级或 active-form 字段。
- **整表替换是唯一操作**:没有部分更新,也没有回读工具;模型每次调用都必须重新发送完整列表。

View File

@@ -2,10 +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/ui/README.md
<<<<<<< HEAD
README.md: f08157d411a018141cdc21c487f81ae198f4de56
README.zh.md: ed4fbf576224a61e680fca337ac5e60829f8a90e
=======
README.md: 307ae14709b59e5c233aa930f20e30c87cdbab69
README.zh.md: f02f9d902d0b61ad0299fb3fb24b97cf99c56b21
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)

View File

@@ -2,25 +2,21 @@
[English](README.md) | 中文
面向用户的交互通道和进程外 SDK 服务器。这些是**产品**包(package):由用户或 SDK 客户端直接操作的真实接口。
面向用户的交互通道和进程外 SDK 服务器。这些是**产品** 包(package):由用户或 SDK 客户端直接操作的真实接口。
| 包 | 职责 | ctx 键 |
|---|---|---|
| `commands/` | 用户命令注册表:共享发现元数据、作用域遮蔽、取消以及 UI 直接分派 | `ctx.commands` |
| `user-approval/` | 一次性用户审批机制、封闭的结果词汇、审计事件和逐会话审批策略 | `ctx.approval` |
| `permission/` | 面向用户的权限预设(`workspace-write`/`danger-full-access`):通过一项产品级选择组合沙箱模式与审批策略两个可调参数,并写入各自的会话事件 | `ctx.permission` |
| `permission/` | 面向用户的权限预设(`workspace-write`/`danger-full-access`):用一个产品级选择器组合沙箱模式与审批策略两个调节项,并写入各自的会话事件 | `ctx.permission` |
| `user-interaction/` | UI 支持的确认工具所使用的抽象用户问答 seam | `ctx.userInteraction` |
| `tool-ask-user/` | 模型侧 `ask_user_question` 工具,基于 `ctx.userInteraction` 实现 | (注册到 `ctx.tools`) |
| `tui/` | 交互式 pi-tui 终端通道:渲染会话标题、事件和工具意图,响应 `ctx.userInteraction`,并托管由 effect 持有的插件浮层 | `ctx.tui`(驱动 `ctx.agents`) |
| `jsonrpc/` | 面向进程外 SDK 客户端的 stdio JSON-RPC 服务器 | (驱动 `ctx.agents`) |
| `app-boot/` | app bin 的共享启动粘合层:加载 `.env`、会明确报错的 Loader 保护机制、感知快照的配置解析,以及等待整棵树停稳的启动序列 | (供各 bin 使用的库) |
| `app-boot/` | app bin 的共享启动粘合层:加载 `.env`、Loader 快速失败保护、感知快照的配置解析,以及等待整棵树停稳的启动序列 | (供各 bin 使用的库) |
UI 集成属于由客户端驱动的插件,而非对循环的修改:它使用现有的 `agent/*` 事件分类和 `dsh-agent` 工厂。[`tui`](tui/README.md) 是交互式终端入口,并提供终端本地的 `ctx.tui` 扩展服务;[`jsonrpc`](jsonrpc/README.md) 为进程外 SDK 客户端提供服务,非交互式的一次性任务则使用 `cli-demo`。[`commands`](commands/README.md) 是 TUI 使用的仅面向用户的发现与分派通道;命令输入和输出不会成为模型消息。
UI 集成属于客户端驱动插件,而非对循环的修改:它使用现有的 `agent/*` 事件分类和 `dsh-agent` 工厂。[`tui`](tui/README.md) 是交互式终端入口,并提供终端本地的 `ctx.tui` 扩展服务;[`jsonrpc`](jsonrpc/README.md) 为进程外 SDK 客户端提供服务,而非交互式单次任务使用 `cli-demo`。[`commands`](commands/README.md) 是 TUI 使用的纯用户发现与分派通道;命令输入和输出不会成为模型消息。
`user-approval`、`user-interaction` 和 `tool-ask-user` 位于此处,因为向用户提问是由 UI 支持的产品功能,并不属于无提供方的核心主干。`user-approval` 负责一次性的 `ctx.approval` 决策机制及其策略层级;应答逻辑仍由负责 agent(智能体)的通道或自动化传输层提供。`user-interaction` 保持提供方无关(`ctx.userInteraction`),`tool-ask-user` 是其模型侧消费方,而交互式 app 包提供具体的提供方。
`user-approval`、`user-interaction` 和 `tool-ask-user` 位于此处,因为向用户提问是由 UI 支持的产品功能,并不属于提供方无关的核心主干。`user-approval` 持有一次性的 `ctx.approval` 决策机制及其策略层级;应答方仍归拥有 agent(智能体)的通道或自动化传输层所有。`user-interaction` 保持提供方无关(`ctx.userInteraction`),`tool-ask-user` 是其模型侧消费方,而交互式 app 包提供具体实现。
<<<<<<< HEAD
基于 [`agent-spine-demo`](../examples/agent-spine-demo/README.md) 组合的可运行 app bundle 位于 [`examples/`](../examples/README.md)(`tui-demo`、`acp-demo`、`jsonrpc-demo`)。`acp-demo` 和 `jsonrpc-demo` 各自提供启动 bin;`tui-demo` bundle 则由产品 [`dsh`](../../apps/cli/README.md) CLI(命令行界面)启动。`ui/` 保留可复用的用户/SDK 通道插件和共享 `app-boot` 粘合层;仅供自动化使用的 ACP(Agent Client Protocol)传输层位于 [`acp/`](../acp/README.md)。每个入口都负责自己的 stdout 策略,叶子 `cordis.yml` 则提供后端与可选工具。
=======
基于 [`agent-spine-demo`](../examples/agent-spine-demo/README.md) 组合的可运行 app bundle 位于 [`examples/`](../examples/README.md)(`cli-demo`、`acp-demo`、`jsonrpc-demo`)。`acp-demo` 和 `jsonrpc-demo` 持有启动 bin;产品 [`dsh`](../../apps/cli/README.md) CLI 不使用 bundle:它启动 `apps/cli` 中的平铺 config tree。`ui/` 保留可复用的用户/SDK 通道插件和共享 `app-boot` 粘合层;仅供自动化使用的 ACP 传输层位于 [`acp/`](../acp/README.md)。每个入口都持有自己的 stdout 策略,叶子 `cordis.yml` 则提供后端与可选工具。
>>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays)