diff --git a/examples/README.i18n.yaml b/examples/README.i18n.yaml index a05f495338..6ac301268c 100644 --- a/examples/README.i18n.yaml +++ b/examples/README.i18n.yaml @@ -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 examples/README.md -<<<<<<< HEAD -README.md: 7f12178d1b67f1ebfac6f4f0e31403c54106e98f -README.zh.md: c7c1bf76593661616464558e554d57340d7c03b1 -======= README.md: eb425ad152579ee10bbd54e99c667606fc8a649a README.zh.md: 5f00b4471b516bb78679f09b41dcb1bdbc3ebdbc ->>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays) diff --git a/examples/README.zh.md b/examples/README.zh.md index de91e30217..5f00b4471b 100644 --- a/examples/README.zh.md +++ b/examples/README.zh.md @@ -2,15 +2,11 @@ [English](README.md) | 中文 -<<<<<<< HEAD -展示 harness 如何组装的可运行演示(不是 workspace)。每个示例都是一个 **轻量叶节点**:一份选择可替换后端、加载一个应用包(package)并可添加可选产品工具的 `cordis.yml`。组合和启动粘合代码位于 [`@deepseek-ai/dsh-tui-demo`](../packages/examples/tui-demo)、[`@deepseek-ai/dsh-cli-demo`](../packages/examples/cli-demo)、[`@deepseek-ai/dsh-acp-demo`](../packages/examples/acp-demo) 及它们共享的 [`@deepseek-ai/dsh-agent-spine-demo`](../packages/examples/agent-spine-demo) 组合包中。没有 `start.ts`;终端 `demo:*` 脚本通过 [`dsh`](../apps/cli/README.md) CLI(命令行界面)启动(该 CLI 挂载 `tui-demo` 组合包),无头/ACP(Agent Client Protocol)脚本则调用 `cli-demo`/`acp-demo` bin。 -======= 展示 harness 如何接线的可运行演示(不是 workspace)。每个示例都是一个 **轻量叶节点**:要么是一份选择可替换后端、加载一个应用包(package)的 `cordis.yml` 配置树,要么是一个 **overlay**——由 `dsh --config` 叠加到交付组合([`apps/cli/base.cordis.yml`](../apps/cli/base.cordis.yml) 加一份 surface overlay)之上的 patch 列表。成组的组合位于 [`@deepseek-ai/dsh-cli-demo`](../packages/examples/cli-demo)、[`@deepseek-ai/dsh-acp-demo`](../packages/examples/acp-demo) 及它们共享的 [`@deepseek-ai/dsh-agent-spine-demo`](../packages/examples/agent-spine-demo) 组合包中;`dsh` 的各 surface 则改用平铺 config tree。没有 `start.ts`;终端 `demo:*` 脚本通过 [`dsh`](../apps/cli/README.md) CLI(命令行界面)启动,无头/ACP(Agent Client Protocol)脚本则调用 `cli-demo`/`acp-demo` bin。 ->>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays) ## headless-agent -非交互式 agent(智能体)演示:接受一个位置参数形式的任务,在 `@deepseek-ai/dsh-cli-demo` 应用上运行一个完整模型/工具轮次,持久化新会话,打印 `text`、`json` 或 `stream-json`,然后退出。 +非交互式 agent(智能体)演示:接受一个位置任务,在 `@deepseek-ai/dsh-cli-demo` 应用上运行一个完整模型/工具轮次,持久化新会话,打印 `text`、`json` 或 `stream-json`,然后退出。 运行:`pnpm run demo:headless "task"`(需要 `DEEPSEEK_API_KEY`)。输出契约、安全边界和快照套件详见 [headless-agent/README.md](headless-agent/README.md)。 @@ -22,22 +18,18 @@ ## jsonrpc-agent -通过 Python SDK 驱动的无人值守编码 agent:JSON-RPC stdio、仅前台 `bash`、`read`/`write`/`edit`、一个前台 `subagent`、`todo_write`、JSONL 持久化和压缩。它不包含终端 UI、stdout 日志、批准、skill(技能)和后台任务控制。详见 [jsonrpc-agent/README.md](jsonrpc-agent/README.md)。 +通过 Python SDK 驱动的无人值守编码 agent:JSON-RPC stdio、仅前台 `bash`、`read`/`write`/`edit`、一个前台 `subagent`、`todo_write`、JSONL 持久化和压缩。它不包含终端 UI、stdout 日志、批准、skill 和后台任务控制。详见 [jsonrpc-agent/README.md](jsonrpc-agent/README.md)。 ## web-cordis -**自指** 演示:编码主干加 [`@deepseek-ai/dsh-tool-cordis`](../packages/cordis/tool-cordis),其三个工具(`cordis_inspect`/`cordis_mount`/`cordis_unmount`)使 agent 可以检查当前 DSH 进程、挂载模型编写的临时插件(事件监听器、一个全新工具,或一个供另一个临时插件注入的服务),并再次卸载它们。这些插件只存在于内存中,共享一个内部 `cordis-dynamic` fiber 子树;`ctx.fs`/`ctx.web` 仅作为它们可用的能力提供方。 +**自指** 演示:编码主干加 [`@deepseek-ai/dsh-tool-cordis`](../packages/cordis/tool-cordis),其三个工具(`cordis_inspect`/`cordis_mount`/`cordis_unmount`)使 agent 可以检查当前 DSH 进程、挂载模型编写的临时 Plugin(事件监听器、一个全新工具,或一个供另一临时 Plugin 注入的服务),并再次卸载它们。这些 Plugin 只存在于内存中,共享一个内部 `cordis-dynamic` fiber 子树;`ctx.fs`/`ctx.web` 仅作为它们可用的能力提供方。 -<<<<<<< HEAD -使用 `pnpm run demo:cordis` 运行 TUI,使用 `pnpm run demo:cordis web` 在 `http://127.0.0.1:3081` 启动浏览器 UI,或使用 `pnpm run demo:cordis acp` 启动 ACP 服务器(三者均需 `DEEPSEEK_API_KEY`)。分阶段演示脚本详见 [cordis-agent/README.md](cordis-agent/README.md),设计与沙箱注意事项详见[工具集 Agent Note(agent 决策记录)](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。 -======= 使用 `pnpm run demo:cordis` 在 `http://127.0.0.1:3081` 启动浏览器 UI,或使用 `pnpm run demo:cordis acp` 启动 ACP 服务器(两者均需 `DEEPSEEK_API_KEY`)。设计与沙箱注意事项详见[工具集 Agent Note](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。 ->>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays) ## acp-agent -一个通过 JSON-RPC stdio 公开、作为 **Agent Client Protocol (ACP)** 自动化服务器运行的 agent,由 [`@deepseek-ai/dsh-acp-demo`](../packages/examples/acp-demo) 提供。程序化客户端可以创建新会话、发送文本提示词、消费已提交的 assistant 文本、回答一次性权限请求并取消工作。它拥有 ACP 无密钥快照套件。 +作为 **Agent Client Protocol (ACP)** 自动化服务器通过 JSON-RPC stdio 公开的 agent,由 [`@deepseek-ai/dsh-acp-demo`](../packages/examples/acp-demo) 提供。程序化客户端可以创建新会话、发送文本提示词、消费已提交的 assistant 文本、回答一次性权限请求并取消工作。它拥有 ACP 无密钥快照套件。 运行:`pnpm run demo:acp`(需要 `DEEPSEEK_API_KEY`);`pnpm run demo:code-mode acp` 通过 `code-mode.cordis.yml` 覆盖以 Code Mode 启动同一服务器。协议与快照测试契约详见 [acp-agent/README.md](acp-agent/README.md)。 -默认 `cordis.yml` 组合 [`@deepseek-ai/dsh-sandbox-local`](../packages/sandbox/sandbox-local)、[`@deepseek-ai/dsh-bash-sandbox`](../packages/bash/bash-sandbox) 和 [`@deepseek-ai/dsh-user-approval`](../packages/ui/user-approval)。`workspace-write` 将 bash 和文件系统变更限制在每个会话 workspace 中;请求更广泛沙箱权限的重试会通过 ACP 触发一次性的机器权限请求。 +默认 `cordis.yml` 组合 [`@deepseek-ai/dsh-sandbox-local`](../packages/sandbox/sandbox-local)、[`@deepseek-ai/dsh-bash-sandbox`](../packages/bash/bash-sandbox) 和 [`@deepseek-ai/dsh-user-approval`](../packages/ui/user-approval)。`workspace-write` 将 bash 和文件系统变更限制在每个会话 workspace 中;范围更广的重试会通过 ACP 成为一次性机器权限请求。 diff --git a/examples/code-mode/README.i18n.yaml b/examples/code-mode/README.i18n.yaml index 2b1171f393..03d2c40a85 100644 --- a/examples/code-mode/README.i18n.yaml +++ b/examples/code-mode/README.i18n.yaml @@ -1,12 +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: -<<<<<<< HEAD:examples/tui-agent/README.i18n.yaml -# pnpm run verify-translation-pairing --write examples/tui-agent/README.md -README.md: ea8695d37ea247a38644392a4572c1ea9855fd44 -README.zh.md: c6acd39d8713816d870c00fa8597754d0d09880a -======= # pnpm run verify-translation-pairing --write examples/code-mode/README.md README.md: 1557483ee98fab60aa63f8c5ec40f7e592c275ba README.zh.md: c20a9a7dde80eb0e03f17b62b5dc21189ef65f06 ->>>>>>> a1c6a2c3f (refactor(cli)!: one shared base config with per-surface overlays):examples/code-mode/README.i18n.yaml diff --git a/examples/cordis-agent/README.i18n.yaml b/examples/cordis-agent/README.i18n.yaml deleted file mode 100644 index 4cbfbb67cb..0000000000 --- a/examples/cordis-agent/README.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 examples/cordis-agent/README.md -README.md: 55970e932bc16d8361932daa9ea55af83ef73d33 -README.zh.md: a8ec332d8b3673d6656663eb3bfd7d37a4e328f6 diff --git a/examples/cordis-agent/README.zh.md b/examples/cordis-agent/README.zh.md deleted file mode 100644 index a8ec332d8b..0000000000 --- a/examples/cordis-agent/README.zh.md +++ /dev/null @@ -1,37 +0,0 @@ -# cordis-agent - -[English](README.md) | 中文 - -自指 harness 演示:在全屏 TUI 上运行 DeepSeek V4 编码主干,并加载 [`@deepseek-ai/dsh-tool-cordis`](../../packages/cordis/tool-cordis/README.md)。后者让模型检查当前 DSH 进程、挂载仅存于内存的临时插件,并卸载它们。临时插件可跨轮次保持活跃,但会在卸载、工具集卸载或 DSH 重启后消失;它们不创建文件或配置,也可能影响同一进程中的其他会话。`ctx.fs` 和 `ctx.web` 仅以能力提供方形式加载,供这些插件使用。设计详见[工具集 Agent Note(agent 决策记录)](../../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。 - -## 运行 - -```sh -# repo root .env (gitignored) or exported env: -# DEEPSEEK_API_KEY=sk-… -# DEEPSEEK_BASE_URL=https://… # optional; defaults to the public API -pnpm run demo:cordis # TUI (default) -pnpm run demo:cordis web # browser UI at http://127.0.0.1:3081 -pnpm run demo:cordis acp # ACP server -``` - -预期演示分阶段进行:先验证监听器链路,再让 agent(智能体)扩展自身: - -``` -> Mount a temporary Plugin that listens to the 'agent/status' event and logs every status change, then run `echo hi` with bash. - [tool call] cordis_mount({"code": "return { name: 'status-logger', apply(ctx) { ctx.on('agent/status', (agent, status) => console.log('status →', status)) } }"}) - [tool result] Temporary Plugin dyn-1 is running (plugin "status-logger"; available until unmounted or DSH restarts). - [tool call] bash({"command": "echo hi"}) -[cordis:dyn-1] status → … ← the temporary listener firing, live -> Now give yourself a reverse_text tool and use it on "harness". - [tool call] cordis_mount({"code": "return { name: 'reverse-text', inject: ['tools'], apply(ctx) { ctx.tools.register(harness.defineTool({ name: 'reverse_text', … })) } }"}) - [tool call] reverse_text({"text": "harness"}) ← a tool the agent built for itself, one step earlier -> Unmount both temporary Plugins. - [tool call] cordis_unmount({"id": "dyn-1"}) -``` - -请求 `cordis_inspect` 并使用 `what: "api"` 或 `what: "events"`,即可查看编写插件代码所用的生成服务/事件资料。还可挂载两个协作临时插件(一个中调用 `ctx.provide`,另一个中使用 `inject`),观察 Cordis 如何暂停并恢复消费方。 - -## 端到端测试 - -`tests/keyless-smoke.e2e.ts` 使用虚拟密钥通过 Loader 启动真实 `cordis.yml`,并断言横幅、包名解析,以及收到 EOF 后正常退出。`tests/cordis-tools.e2e.ts` 是带密钥的冒烟测试:真实模型挂载一个临时状态监听器,测试验证其带标记的控制台输出行;然后创建并使用 `reverse_text` 工具,再通过 provide/inject 组合两个临时插件。[`packages/cordis/tool-cordis`](../../packages/cordis/tool-cordis) 包含相关单元测试,并受逐文件 100% 覆盖率门禁约束。 diff --git a/examples/tui-agent/README.zh.md b/examples/tui-agent/README.zh.md deleted file mode 100644 index c6acd39d87..0000000000 --- a/examples/tui-agent/README.zh.md +++ /dev/null @@ -1,80 +0,0 @@ -# tui-agent - -[English](README.md) | 中文 - -全屏交互式编码 agent(智能体):DeepSeek V4、本地 bash 与文件系统工具、压缩(compaction)、subagent、工作流与全新 agent Ralph 迭代、plan mode(`/plan` 进入,`exit_plan_mode` 评审退出)、超时/溢出策略,以及通过 [`@deepseek-ai/dsh-tui-demo`](../../packages/examples/tui-demo) 提供的 JSONL 持久化;该应用从 `cordis.yml` 加载。同级 [`headless-agent`](../headless-agent/README.md) 以适合管道调用的单次任务形式运行同一能力类,[`acp-agent`](../acp-agent/README.md) 则通过 JSON-RPC 提供该能力。 - -## 运行 - -```sh -# repo root .env (gitignored) or exported env: -# DEEPSEEK_API_KEY=sk-… -# DEEPSEEK_BASE_URL=https://… # optional; defaults to the public API -pnpm run demo:tui -``` - -演示脚本和可安装的 `dsh` CLI(命令行界面,见 [`apps/cli`](../../apps/cli/README.md))都会以此示例的 `cordis.yml` 作为已交付的默认配置启动;`dsh` 还会应用 `~/.dsh` 中的个人覆盖,并将调用目录作为工作区。 - -输入一项编码任务。agent 使用 `read`/`write`/`edit` 文件系统工具处理常规文件操作,使用 `bash`(加上面向后台任务的通用 `task_output`/`task_list`/`task_kill`)执行 shell 命令、搜索和测试。每次 bash 调用都在新的 `bash -c` 中运行(系统提示词要求模型传递 `workdir`,而不是使用 `cd`)。文件系统工具和 bash 都会相对于会话工作区解析相对路径。agent 还可以通过 `subagent`/`subagent_fork` 委托。 - -`todo_write` 任务跟踪器是选用的,不在已交付配置中:请将 `@deepseek-ai/dsh-tool-todo` 添加到 `cordis.yml`(或在 `~/.dsh` 下使用个人配置覆盖)以公开该工具。加载后,模型会把整表计划记录到会话日志,TUI 则渲染它。 - -TUI 渲染 Markdown 历史、推理(reasoning)、工具自有的终端/diff/通用卡片、token 总量,以及加载 `todo_write` 时的最新计划。较长的工具正文保留首尾预览;Ctrl+O 展开或折叠所有卡片。Enter 用于提交,或在 agent 运行时进行 steering(中途引导);Ctrl+R 切换推理,Escape 取消,`/help` 列出命令。`/plan` 为下一步骤选择 plan mode;`/plan ` 还会将消息提交到该步骤,`/plan off` 则在没有模型输入的情况下选择默认 mode。`/status` 会展开当前会话的标识、活动计数、精确 token/缓存 bucket、上下文用量和时间戳,而不中断正在运行的轮次。`/model` 打开当前提供方目录的键盘选择器;使用 Up/Down 聚焦模型,使用 Shift+Tab 循环切换为该模型公布的推理强度,再用 Enter 选择;也可以使用 `/model ` 和 `/model /` 直接选择。`ask_user_question` 会打开一个位于左下方的宽键盘面板,包含批次进度和编号选项。 - -### 恢复早先的会话 - -每次运行默认都会启动新会话(其事件日志落在 `./.sessions/` 下)。如需 **继续** 先前对话,请将其 id 传给已安装的 `dsh` CLI:此时 `main` agent 会重新水化持久日志,而不会从头开始,因此模型会将早先轮次视为历史: - -```sh -dsh --resume -``` - -`/resume` 打开可搜索键盘选择器,显示标题、活动、上一轮结果、模型路由、持久化目标阶段和实时/已持久化状态。已安装的 `dsh` 宿主会等待刷写完成,对当前应用执行 dispose(资源释放),然后以 `dsh --resume ` 替换进程。TUI 仍会在退出时打印该命令,并在自定义宿主无法移交时显示它。`dsh --resume ` 在启动上下文中提供 id,`cordis.yml` 会读取它(`resumeSessionId: !!js "typeof resumeSessionId === 'string' ? resumeSessionId : undefined"`);没有标志时,agent 会开始新会话。缺失或无法读取的 id 不会启动 agent,而会发出 `agent-loop/config-start-failed`:TUI 打印失败并以非零状态退出。选择器没有跨进程会话锁,因此拥有并发宿主的部署必须自行协调会话所有权。 - -## Code Mode - -[`code-mode.cordis.yml`](code-mode.cordis.yml) 在同一树上覆盖 worker 线程运行时和 `tools: { mode: code }`。模型会收到一个 `run_code` 传输工具,加上一份为可见工具生成的 TypeScript SDK;只有程序输出会返回模型上下文。使用 `mode: both` 可在 `run_code` 旁同时公开原生调用。执行契约详见 [Code Mode Agent Note(agent 决策记录)](../../.agents/notes/implemented/feature/2026-06-15-code-mode.md)。 - -```sh -pnpm run demo:code-mode # this overlay under the TUI (default UI) -pnpm run demo:code-mode acp # the acp-agent example's same-shaped overlay -``` - -尝试一项横跨多个工具调用的任务,例如: - -> 统计 docs/ 下每个 `*.md` 文件的行数,并将最大的三个写入 summary.txt。 - -然后观察 transcript(文本记录):一次 `run_code` 调用、一个循环调用工具的程序,以及模型筛选后的结果,而不是五次原始工具输出往返。 - -## 每个叶节点配置项所演示的内容 - -此示例是轻量叶节点 `cordis.yml`:它选择可替换后端、加载一个应用包(package),并添加有意放在共享主干外的产品工具。主干(会话、系统提示词、工具、agent、不变式、`agent-loop`)和入口集群(JSONL 持久化、pi-tui 通道、预创建的 `main` agent)位于 [`@deepseek-ai/dsh-tui-demo`](../../packages/examples/tui-demo) 应用及其加载的 [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo) 组合包中;叶节点负责接线后端与面向模型的可选工具: - -| 配置项 | 演示内容 | -|---|---| -| `hmr` (`@cordisjs/plugin-hmr`) | 开发/演示的编辑-重载循环:它是 **叶节点** 配置项(不内置到应用),因为它依赖 Loader 的内部模块访问 | -| `llm-deepseek` | 默认原生适配器 | -| `bash` (`dsh-bash-local`) | 执行器实现:bash seam 中可替换的实现侧。面向模型的 `bash` schema(`tool-bash`)和通用 `task_*` 控制(`tool-tasks`)由 `dsh-agent-spine-demo` 提供,因此叶节点只选择执行器 | -| `tui-agent` (`@deepseek-ai/dsh-tui-demo`) | 应用组合包:agent-spine 演示 + JSONL 持久化 + pi-tui 通道 + 预创建的 `main` agent | -| `subagent`, `subagent-spawn`, `subagent-fork` | subagent 提供方注册表加两个进程内后端:新子 agent,以及用父 agent 已完成轮次前缀播种的子 agent | -| `tool-subagent`, `tool-subagent-fork` | 两次面向模型的 `dsh-tool-subagent` 加载,每次绑定不同提供方,并以不同工具名(`subagent`、`subagent_fork`)公开 | -| `workflow-workerthread`, `tool-workflow` | worker 线程工作流引擎及其面向模型的 `workflow` 工具,子调用通过 spawn 后端路由 | -| `plan-mode` | 插件拥有的 `/plan [message]` 进入命令和 `/plan off` 退出命令、plan-mode 提示词策略、工具限制,以及经评审的 `exit_plan_mode` 转换 | -| `fs-local`, `fs-policy`, `tool-fs` | 文件系统栈:本地 `ctx.fs` 提供方、先读后写/编辑策略门禁(位于 `fs/*` 事件门禁),以及面向模型的 `read`/`write`/`edit` 工具。相对路径相对于会话工作区解析 | - -## 端到端测试(`pnpm run test:e2e`) - -与 UI 无关的带密钥套件通过 `tests/harness.ts` 以程序方式组装完整栈(无 PTY、无 Loader): - -- `tests/full-loop.e2e.ts`:canary 测试:真实模型通过真实 bash 工具运行 `echo e2e-ok`;断言 `tool/call`/`tool/result` 会话事件和最终答案。 -- `tests/coding-task.e2e.ts`:类 swebench 冒烟测试:临时目录包含 `add.js`(其中 `a - b` 写在本应是 `a + b` 的位置)和失败的 `add.test.js`;agent 必须修复错误并验证。测试会自行重新运行 `node add.test.js` 并检查文件,不信任 agent 的说法。 -- `tests/resume.e2e.ts`:跨进程持久连续性:第一次运行告诉真实模型一个密码并将轮次持久化到临时 JSONL 根目录,然后 dispose 整个上下文;第二次运行在同一根目录上创建新上下文,恢复会话 id 并要求模型回忆密码。只有重新水化的日志能够提供该回忆。 -- `tests/compaction.e2e.ts`:压缩冒烟测试:一项真实多步 bash 任务在故意设得很小的上下文窗口中运行,使自动压缩监听器在会话中途触发。测试验证外部状态:真实日志中出现 `compact/start…end` 对,模型可见内容缩减(一个替换节点遮蔽了较旧节点),且 agent 在压缩后仍给出正确最终答案。 -- `tests/todo-write.e2e.ts`:加载选用的 `todo_write` 工具,由真实模型驱动,测试验证产生的 `todo/write` 会话事件。 -- `tests/code-mode.e2e.ts`:带密钥 Code Mode 证明:使用真实模型和双工具任务,断言协议层工具列表精确为 `[run_code]`,`tool/code-dispatch` 事件位于父调用下,且筛选后的答案已返回。 - -这些测试在没有 `DEEPSEEK_API_KEY` 时自行跳过。无密钥 `tests/tui-keyless-smoke.e2e.ts` 通过 PTY 启动真实 Loader 树(唯一获准的 PTY 界面):基础启动 + `/plan` + `/exit`,一次带问题对话框和工具往返的脚本 LLM(大语言模型)对话,Code Mode 覆盖配置的欢迎行,以及恢复失败退出路径。 - -## 快照测试 - -`tests/snapshots//session.jsonl` 提供已录制的用户提示词和模型分片;同级子日志驱动 subagent 和工作流。无密钥套件通过真实循环和工具实现执行这些脚本,然后比较可读的预期终端单元格/样式输出。对于仅涉及展示的变更,使用 `pnpm run test:snapshot:refresh`;已录制的模型流程改变时,使用 DeepSeek 密钥运行 `pnpm run test:snapshot:record`。已实现的 [TUI 快照 Agent Note](../../.agents/notes/implemented/testing/2026-07-18-tui-terminal-state-snapshots.md) 规定了场景矩阵,以及已录制旅程、包级瞬态快照与 PTY 覆盖之间的分工。 diff --git a/packages/examples/README.i18n.yaml b/packages/examples/README.i18n.yaml index ddf815f1b1..0b0ee3db7c 100644 --- a/packages/examples/README.i18n.yaml +++ b/packages/examples/README.i18n.yaml @@ -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) diff --git a/packages/examples/README.zh.md b/packages/examples/README.zh.md index 7ec12eb1c6..0218e60df2 100644 --- a/packages/examples/README.zh.md +++ b/packages/examples/README.zh.md @@ -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 统一该启动流程时才会协调它们,而不会在此次移动中处理。 diff --git a/packages/examples/agent-spine-demo/README.i18n.yaml b/packages/examples/agent-spine-demo/README.i18n.yaml index 48d17b5391..59caccb8a1 100644 --- a/packages/examples/agent-spine-demo/README.i18n.yaml +++ b/packages/examples/agent-spine-demo/README.i18n.yaml @@ -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) diff --git a/packages/examples/agent-spine-demo/README.zh.md b/packages/examples/agent-spine-demo/README.zh.md index 96a4354b03..d5b0e2b507 100644 --- a/packages/examples/agent-spine-demo/README.zh.md +++ b/packages/examples/agent-spine-demo/README.zh.md @@ -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 始终启用的校验与冻结是另一套机制。 diff --git a/packages/examples/tui-demo/README.i18n.yaml b/packages/examples/tui-demo/README.i18n.yaml deleted file mode 100644 index a9815be3a3..0000000000 --- a/packages/examples/tui-demo/README.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 packages/examples/tui-demo/README.md -README.md: 058ebe87af5f041bd19fbfb205a97753ccacf6b9 -README.zh.md: 43681e9c77cbd77459ec0539b69e0ab73274d2c1 diff --git a/packages/examples/tui-demo/README.zh.md b/packages/examples/tui-demo/README.zh.md deleted file mode 100644 index 43681e9c77..0000000000 --- a/packages/examples/tui-demo/README.zh.md +++ /dev/null @@ -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-` 会话 id,并将它同时传给 TUI 与已配置的 agent。恢复运行会将两个组件都绑定到 `resumeSessionId`。TUI 先于主干挂载,因此它可以渲染匹配的配置启动失败,而不会留下空白终端。应用为 `/resume` 组合持久化和会话查询;嵌入宿主还可以提供 `tuiResumeHost`,用于原地移交进程。 - -## 入口 - -此包(package)不交付 bin。[`dsh`](../../../apps/cli/README.md) CLI 是终端入口:裸 `dsh` 启动已交付的 `examples/tui-agent/cordis.yml`(它挂载此组合包),而 `dsh --config ` 启动另一个挂载此组合包的叶节点配置。它加载 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`;权限提示需要批准服务和回答方。 diff --git a/packages/todo/README.i18n.yaml b/packages/todo/README.i18n.yaml index e726755dcf..12b2ce442d 100644 --- a/packages/todo/README.i18n.yaml +++ b/packages/todo/README.i18n.yaml @@ -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) diff --git a/packages/todo/README.zh.md b/packages/todo/README.zh.md index d8d8ffc4db..abdac592a3 100644 --- a/packages/todo/README.zh.md +++ b/packages/todo/README.zh.md @@ -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) diff --git a/packages/todo/tool-todo/README.i18n.yaml b/packages/todo/tool-todo/README.i18n.yaml index 8b1ac9bcc1..eb152a048e 100644 --- a/packages/todo/tool-todo/README.i18n.yaml +++ b/packages/todo/tool-todo/README.i18n.yaml @@ -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) diff --git a/packages/todo/tool-todo/README.zh.md b/packages/todo/tool-todo/README.zh.md index 26328dde33..778c920198 100644 --- a/packages/todo/tool-todo/README.zh.md +++ b/packages/todo/tool-todo/README.zh.md @@ -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, in progress, completed.`。稳定失败文本为 ``Error: invalid todo: `content` must be a non-empty string``、`Error: invalid todos: duplicate content ""`、`Error: invalid todos: at most one task may be in_progress, got ` 和 `Error: todo_write requires an owning agent session`。完整 `todo/write` 会话事件是 UI 与回放状态,而非第二条模型消息。 +每个 assistant 工具调用都会在参数中保留整个替换列表。成功时精确返回 `Updated todo list: pending, in progress, completed.`。稳定失败文本为 ``Error: invalid todo: `content` must be a non-empty string``、`Error: invalid todos: duplicate content ""`、`Error: invalid todos: at most one task may be in_progress, got ` 和 `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 字段。 - **整表替换是唯一操作**:没有部分更新,也没有回读工具;模型每次调用都必须重新发送完整列表。 diff --git a/packages/ui/README.i18n.yaml b/packages/ui/README.i18n.yaml index 06460978a8..0c9f3488d6 100644 --- a/packages/ui/README.i18n.yaml +++ b/packages/ui/README.i18n.yaml @@ -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) diff --git a/packages/ui/README.zh.md b/packages/ui/README.zh.md index 9ef39eee8d..f02f9d902d 100644 --- a/packages/ui/README.zh.md +++ b/packages/ui/README.zh.md @@ -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)