refactor(acp): launch automation through the dsh acp profile

Replace the standalone @deepseek-ai/dsh-acp-demo application with dsh --profile acp plus ordered example patches. The shipped acp-app bundle owns only the protocol bridge; every example overlay now targets shared dsh-base rows instead of copying a complete application tree.

Move launcher responsibilities into the ACP snapshot harness: it materializes profile patches, links required packages, reserves stdout for JSON-RPC, observes spawn and drain failures, and escalates process teardown deterministically. The relocated control-surface fixture and the ACP/subagent integration tests now exercise the real CLI/profile path.

This commit contains authored runtime, configuration, and test changes only. Generated transcript and projection churn is deliberately left for the next commit so reviewers can inspect the migration logic without hundreds of expected-output edits.
This commit is contained in:
Tianyi Cui
2026-08-23 10:59:00 +08:00
parent 713b41a946
commit d8dbb8235c
118 changed files with 2685 additions and 3168 deletions
@@ -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/simplification/2026-07-20-remove-stdio-and-echo-agents.md
2026-07-20-remove-stdio-and-echo-agents.md: 8761c360e492d6d315e738ed93441929584d1e20
2026-07-20-remove-stdio-and-echo-agents.zh.md: e34672ce9739ab22e76e44c305c22efb30b6a0c4
2026-07-20-remove-stdio-and-echo-agents.md: 1d71b74fda229f7eaed502b3badba2ab39e5ea54
2026-07-20-remove-stdio-and-echo-agents.zh.md: 8445a82d7e366bf57ea4d3ad4595a596b67f1fa8
@@ -20,7 +20,7 @@ The remaining application roles are explicit:
- `@deepseek-ai/dsh-tui` owns terminal-interactive execution. It rejects non-TTY streams before Loader boot; `apps/cli/config/base.cordis.yml` plus the `tui.cordis.yml` overlay own the complete coding composition, with PTY plus terminal-snapshot coverage in `apps/cli/tests/`.
- [`dsh --profile headless`](../../../../apps/cli/README.md) owns non-interactive execution. Its `headless` profile is the product composition; `examples/headless-agent` owns replay snapshots, generic real-agent suites, and an unexported keyless Loader driver.
- [`@deepseek-ai/dsh-acp-demo`](../../../../packages/examples/acp-demo/README.md) and `@deepseek-ai/dsh-sdk-jsonrpc-server` own their framed protocol integrations.
- [`dsh --profile acp`](../../../../apps/cli/README.md) and `@deepseek-ai/dsh-sdk-jsonrpc-server` own their framed protocol integrations.
The SDK project model that carried the `stdio` run-interface option is deleted by the [SDK project toolchain removal](2026-08-11-remove-sdk-project-toolchain.md). Repository-facing demo documentation requires a DeepSeek API key and leads with a current runnable product.
@@ -20,7 +20,7 @@ DeepSeek Harness 在 TUI 和 Headless coding agent 之外,还提供了两个
- `@deepseek-ai/dsh-tui` 负责终端交互式执行。它会在 Loader 启动前拒绝非 TTY 流;`apps/cli/config/base.cordis.yml``tui.cordis.yml` overlay 拥有完整 coding 组装,PTY 与终端快照覆盖则位于 `apps/cli/tests/`
- [`dsh --profile headless`](../../../../apps/cli/README.zh.md) 负责非交互式执行。其 `headless` profile 是产品组装;`examples/headless-agent` 负责回放快照、通用真实 agent 测试套件和未导出的无密钥 Loader driver。
- [`@deepseek-ai/dsh-acp-demo`](../../../../packages/examples/acp-demo/README.zh.md) 和 `@deepseek-ai/dsh-sdk-jsonrpc-server` 负责各自的分帧协议集成。
- [`dsh --profile acp`](../../../../apps/cli/README.zh.md) 和 `@deepseek-ai/dsh-sdk-jsonrpc-server` 负责各自的分帧协议集成。
承载 `stdio` 运行接口选项的 SDK 项目模型已由 [SDK 项目工具链移除决策](2026-08-11-remove-sdk-project-toolchain.zh.md)删除。仓库中的演示文档要求 DeepSeek API key,并优先引导到当前可运行的产品。
+2 -2
View File
@@ -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/cookbook/extension-cookbook.md
extension-cookbook.md: 9618a3522c5566636fe3e49f7eca93d1e113d51a
extension-cookbook.zh.md: 665968f0a91c05d124b9985c61bdf89c4e10cefa
extension-cookbook.md: 1081166674cb946675d8864091c50def018f9f97
extension-cookbook.zh.md: defdda53e8f8ea849d2f236566bef48751f4ad96
+1 -1
View File
@@ -90,7 +90,7 @@ export function apply(ctx: Context) {
## Runnable wirings
Runnable leaves load their plugin trees from `examples/*/cordis.yml`; the root `demo:*` scripts and those leaf directories are the authoritative inventory. The product `dsh` launcher owns Web and one-shot headless execution, ACP leaves use [`@deepseek-ai/dsh-acp-demo`](../../packages/examples/acp-demo), and JSON-RPC leaves use [`@deepseek-ai/dsh-sdk-jsonrpc-demo`](../../packages/examples/jsonrpc-demo). The headless snapshot leaf mounts [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo) and JSONL persistence explicitly, then drives them through an example-owned test fixture rather than a shipped app package.
Runnable leaves contribute profile patches from `examples/*/cordis.yml`; the root `demo:*` scripts and those leaf directories are the authoritative inventory. The product `dsh` launcher owns Web, ACP, SDK, and one-shot headless execution through named profiles. The JSON-RPC leaf remains only for the temporarily held-back Python SDK runtime. The headless snapshot leaf mounts [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo) and JSONL persistence explicitly, then drives them through an example-owned test fixture rather than a shipped app package.
## The feature → mechanism map
+1 -1
View File
@@ -92,7 +92,7 @@ export function apply(ctx: Context) {
## 可运行的组装示例
可运行叶子 `examples/*/cordis.yml` 加载各自的插件树;根目录的 `demo:*` 脚本和这些叶子目录是权威清单。产品 `dsh` 启动器负责 Web 和一次性 headless 执行,ACP 叶子使用 [`@deepseek-ai/dsh-acp-demo`](../../packages/examples/acp-demo)JSON-RPC 叶子使用 [`@deepseek-ai/dsh-sdk-jsonrpc-demo`](../../packages/examples/jsonrpc-demo)。headless 快照叶节点显式挂载 [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo) 和 JSONL 持久化,再通过示例自有的测试 fixture(测试前置数据)驱动这些组件,而不是通过已交付的 app 包。
可运行叶子通过 `examples/*/cordis.yml` 贡献 profile patch;根目录的 `demo:*` 脚本和这些叶子目录是权威清单。产品 `dsh` 启动器通过具名 profile 负责 Web、ACP、SDK 与一次性 headless 执行。JSON-RPC 叶子只为暂缓迁移的 Python SDK runtime 保留。headless 快照叶节点显式挂载 [`@deepseek-ai/dsh-agent-spine-demo`](../../packages/examples/agent-spine-demo) 和 JSONL 持久化,再通过示例自有的测试 fixture(测试前置数据)驱动这些组件,而不是通过已交付的 app 包。
<a id="the-feature--mechanism-map"></a>
+2 -2
View File
@@ -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 examples/acp-agent/README.md
README.md: 61c6efafe9dde4f91385beebdfd426c57006187b
README.zh.md: c8cdd248e1e71626aac007a8a6923ae7382ea691
README.md: 81545a8b3a631653256c6f3c6688ba97136b5db1
README.zh.md: 12a40cde8c1e9f063b32da7080bafed68fed705c
+2 -2
View File
@@ -9,11 +9,11 @@ pnpm run demo:acp # needs DEEPSEEK_API_KEY (repo-root .env or env)
pnpm run demo:code-mode # same protocol with the Code Mode tool transport
```
The leaf loads the ACP app, DeepSeek adapter, sandboxed bash and filesystem stacks, one-shot approval policy, compaction, subagents, workflows, hooks, a derived session-query index, and repeat guard. The app creates one fresh agent per `session/new`, persists sessions to JSONL, and keeps stdout protocol-pure. Optional overlays add session queries, filesystem spill storage, Code Mode, or web fetching.
The `dsh` launcher applies the shipped `acp` profile (`dsh-base` plus [`dsh-acp-app`](../../packages/bundle/acp-app/README.md)), then this leaf's `cordis.yml` patch. The profile supplies the ACP bridge, DeepSeek adapter, sandboxed shell and filesystem stacks, approval policy, compaction, subagents, workflows, a session-query index, and repeat guard; the leaf pins demo and snapshot values and adds hook bridges. The bridge creates one fresh agent per `session/new`, persists sessions to JSONL, and keeps stdout protocol-pure. Optional patch overlays add session-query tools, spill settings, Code Mode, or web fetching.
## Protocol channel
Stdout carries only newline-delimited ACP JSON-RPC. `@deepseek-ai/dsh-acp-demo` installs no stdout logger; leaf additions must use stderr for diagnostics.
Stdout carries only newline-delimited ACP JSON-RPC. `@deepseek-ai/dsh-acp-app` and this patch install no stdout logger; added plugins must use stderr for diagnostics.
The automation contract — supported methods, baseline prompt content, committed-text output, and the intentionally absent UI surfaces — lives in [`@deepseek-ai/dsh-acp`](../../packages/acp/acp/README.md).
+2 -2
View File
@@ -9,11 +9,11 @@ pnpm run demo:acp # needs DEEPSEEK_API_KEY (repo-root .env or env)
pnpm run demo:code-mode # same protocol with the Code Mode tool transport
```
该叶节点加载 ACP 应用、DeepSeek 适配器、受沙箱限制的 bash 与文件系统栈、一次性批准策略、压缩(compaction)、subagent、工作流、钩子、派生会话查询索引和重复守卫。应用为每次 `session/new` 创建一个新 agent,将会话持久化到 JSONL,并保持 stdout 只含协议内容。可选 overlay 可添加会话查询、文件系统 spill 存储、Code Mode 或 Web 抓取。
`dsh` 启动器先应用随附 `acp` profile`dsh-base` 加 [`dsh-acp-app`](../../packages/bundle/acp-app/README.zh.md)),再应用本叶节点的 `cordis.yml` patch。profile 提供 ACP bridge、DeepSeek 适配器、受沙箱限制的 shell 与文件系统栈、批准策略、压缩(compaction)、subagent、工作流、会话查询索引和重复守卫;本叶节点固定 demo 与 snapshot 值并添加 hook bridge。bridge 为每次 `session/new` 创建一个新 agent,将会话持久化到 JSONL,并保持 stdout 只含协议内容。可选 patch overlay 可添加会话查询工具、spill 设置、Code Mode 或 Web 抓取。
## 协议通道
Stdout 只携带以换行分隔的 ACP JSON-RPC。`@deepseek-ai/dsh-acp-demo` 不安装 stdout logger该叶节点新增的组件必须使用 stderr 输出诊断信息。
Stdout 只携带以换行分隔的 ACP JSON-RPC。`@deepseek-ai/dsh-acp-app` 与本 patch 均不安装 stdout logger新增插件必须使用 stderr 输出诊断信息。
自动化约定(支持的方法、基线提示词内容、已提交文本输出,以及有意缺少的 UI 界面)位于 [`@deepseek-ai/dsh-acp`](../../packages/acp/acp/README.zh.md)。
+49 -38
View File
@@ -1,40 +1,51 @@
# Replay counterpart to advanced.cordis.yml; only the live model is replaced.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: 'none'
workspaceContext:
maxBytes: 65536
tools:
mode: both
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: cordis-host-runner
name: '@deepseek-ai/dsh-cordis-host-runner'
- id: tool-cordis
name: '@deepseek-ai/dsh-tool-cordis'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: tools
name: '@deepseek-ai/dsh-tools'
config:
mode: both
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: cordis-host-runner
name: '@deepseek-ai/dsh-cordis-host-runner'
- id: tool-cordis
name: '@deepseek-ai/dsh-tool-cordis'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
+35 -25
View File
@@ -1,29 +1,39 @@
# Add Code Mode and Cordis tools to the base spawn/workflow stack, exercising
# all four boundaries in one ACP snapshot.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ./cordis.yml
patches:
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext:
maxBytes: 65536
tools:
mode: both
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
provider: deepseek-official
model: deepseek-v4-pro
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: cordis-host-runner
name: '@deepseek-ai/dsh-cordis-host-runner'
- id: tool-cordis
name: '@deepseek-ai/dsh-tool-cordis'
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: tools
name: '@deepseek-ai/dsh-tools'
config:
mode: both
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: cordis-host-runner
name: '@deepseek-ai/dsh-cordis-host-runner'
- id: tool-cordis
name: '@deepseek-ai/dsh-tool-cordis'
@@ -1,39 +1,46 @@
# Keyless replay counterpart of agent-instructions.cordis.yml. Patches do not
# compose across includes, so this applies the scenario config and model swap
# directly to the live tree.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: 'none'
workspaceContext:
maxBytes: 65536
dshHome: !!js process.cwd() + '/.dsh'
projectRootMarkers:
- .dsh-project
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
# Keyless replay counterpart of agent-instructions.cordis.yml: apply the
# scenario values and model swap to the ACP profile.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: workspace-context-compaction
name: './tests/fixtures/workspace-context-compaction.ts'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
dshHome: !!js process.cwd() + '/.dsh'
projectRootMarkers:
- .dsh-project
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: workspace-context-compaction
name: './tests/fixtures/workspace-context-compaction.ts'
@@ -1,24 +1,29 @@
# Workspace-context snapshot overlay: keep project-root and user-global
# discovery inside the scenario's temporary cwd. The app config patch replaces
# the whole base config, so the base fields are restated verbatim.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
# Workspace-context snapshot patch: keep project-root and user-global
# discovery inside the scenario's temporary cwd.
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ./cordis.yml
patches:
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext:
maxBytes: 65536
dshHome: !!js process.cwd() + '/.dsh'
projectRootMarkers:
- .dsh-project
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
provider: deepseek-official
model: deepseek-v4-pro
Verify your work by running the code or tests. Keep answers brief and factual.
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
dshHome: !!js process.cwd() + '/.dsh'
projectRootMarkers:
- .dsh-project
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
@@ -1,36 +1,47 @@
# Keyless counterpart to background-job-admission.cordis.yml: replace the
# DeepSeek adapter with replay while preserving the app's one-task admission
# config and the recorded flash route.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
tasks:
maxConcurrentJobsPerOwner: 1
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: jobs
name: '@deepseek-ai/dsh-jobs-local'
config:
maxConcurrentJobsPerOwner: 1
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
@@ -2,23 +2,32 @@
# configuring its task provider to allow one active task per exact owner. The
# scenario starts a real background Bash process, observes the second producer
# rejection, and cleans up the first task by its returned id.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ./cordis.yml
patches:
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext:
maxBytes: 65536
tasks:
maxConcurrentJobsPerOwner: 1
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
provider: deepseek-official
model: deepseek-v4-flash
Verify your work by running the code or tests. Keep answers brief and factual.
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: jobs
name: '@deepseek-ai/dsh-jobs-local'
config:
maxConcurrentJobsPerOwner: 1
@@ -1,38 +1,48 @@
# Keyless both mode combines the runtime/registry patch with the DeepSeek-to-replay
# swap. Include patches cannot target entries behind a nested include, so this file
# applies both overlays directly to `cordis.yml`.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: 'none'
workspaceContext:
maxBytes: 65536
tools:
mode: both
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
# Keyless both mode combines the runtime/registry changes with the
# DeepSeek-to-replay swap in one profile patch.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: tools
name: '@deepseek-ai/dsh-tools'
config:
mode: both
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
+33 -24
View File
@@ -1,27 +1,36 @@
# Both mode adds `ctx.codeRuntime` while keeping native tools on the wire and
# adding `run_code` plus its generated TypeScript SDK prompt. The app bin selects
# this overlay for snapshot recording and the sibling overlay for replay. A config
# patch replaces the whole app config, so unchanged base fields are restated below.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
# adding `run_code` plus its generated TypeScript SDK prompt. Recording applies
# this profile patch; replay applies its sibling patch.
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ./cordis.yml
patches:
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext:
maxBytes: 65536
tools:
mode: both
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
provider: deepseek-official
model: deepseek-v4-pro
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: tools
name: '@deepseek-ai/dsh-tools'
config:
mode: both
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
@@ -1,50 +1,60 @@
# Keyless counterpart to child-question.cordis.yml: keep the real interaction
# seam, model-facing tool, and tripwire provider while replacing DeepSeek with
# per-session replay.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: user-questions
name: '@deepseek-ai/dsh-user-questions'
- id: tool-ask-user
name: '@deepseek-ai/dsh-tool-ask-user'
- id: child-question-tripwire
name: './tests/fixtures/child-question-tripwire.ts'
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: tool-ask-user
name: '@deepseek-ai/dsh-tool-ask-user'
- id: child-question-tripwire
name: './tests/fixtures/child-question-tripwire.ts'
- id: user-questions
name: '@deepseek-ai/dsh-user-questions'
+8 -12
View File
@@ -1,14 +1,10 @@
# Snapshot-only human-interaction composition. The provider is a tripwire: the
# runtime-owned child must be rejected by the seam before any UI wait begins.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- insert:
- id: user-questions
name: '@deepseek-ai/dsh-user-questions'
- id: tool-ask-user
name: '@deepseek-ai/dsh-tool-ask-user'
- id: child-question-tripwire
name: './tests/fixtures/child-question-tripwire.ts'
- insert:
- id: tool-ask-user
name: '@deepseek-ai/dsh-tool-ask-user'
- id: child-question-tripwire
name: './tests/fixtures/child-question-tripwire.ts'
- id: user-questions
name: '@deepseek-ai/dsh-user-questions'
@@ -1,44 +1,56 @@
# Keyless replay combines Code Mode with the durable image store and an exact
# image-capable replay route. The scenario generates its tiny PNG inside the
# run_code program, then exercises read_image as a nested dispatch.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash-vision-exp
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
tools:
mode: code
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
inputModalities: [text]
- id: deepseek-v4-pro
inputModalities: [text]
- id: deepseek-v4-flash-vision-exp
inputModalities: [text, image]
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash-vision-exp
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: tools
name: '@deepseek-ai/dsh-tools'
config:
mode: code
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
inputModalities: [text]
- id: deepseek-v4-pro
inputModalities: [text]
- id: deepseek-v4-flash-vision-exp
inputModalities: [text, image]
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
+34 -23
View File
@@ -1,28 +1,39 @@
# Code Mode image overlay: mounts the worker runtime and durable attachment
# store so a nested read_image result can cross the generic rich-result bridge.
# The live config selects the shipped vision route for manual use.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ./cordis.yml
patches:
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash-vision-exp
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext:
maxBytes: 65536
tools:
mode: code
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
provider: deepseek-official
model: deepseek-v4-flash-vision-exp
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: tools
name: '@deepseek-ai/dsh-tools'
config:
mode: code
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
@@ -1,37 +1,48 @@
# Keyless replay counterpart of code-mode-workspace-context.cordis.yml. It adds
# Code Mode to the default filesystem suite and swaps in replay.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: 'none'
workspaceContext:
maxBytes: 65536
tools:
mode: code
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: tools
name: '@deepseek-ai/dsh-tools'
config:
mode: code
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
@@ -1,25 +1,35 @@
# Code Mode agent-instructions snapshot recording overlay. The default filesystem
# tools trigger nested instruction discovery after a read.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ./cordis.yml
patches:
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext:
maxBytes: 65536
tools:
mode: code
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
provider: deepseek-official
model: deepseek-v4-pro
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: tools
name: '@deepseek-ai/dsh-tools'
config:
mode: code
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
@@ -1,38 +1,48 @@
# Keyless Code Mode combines the runtime/registry patch with the DeepSeek-to-replay
# swap. Include patches cannot target entries behind a nested include, so this file
# applies both overlays directly to `cordis.yml`.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: 'none'
workspaceContext:
maxBytes: 65536
tools:
mode: code
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
# Keyless Code Mode combines the runtime/registry changes with the
# DeepSeek-to-replay swap in one profile patch.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: tools
name: '@deepseek-ai/dsh-tools'
config:
mode: code
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
+33 -25
View File
@@ -1,28 +1,36 @@
# Code Mode adds `ctx.codeRuntime` and changes the registry to one wire tool,
# `run_code`, plus its generated TypeScript SDK prompt. The app bin selects this
# overlay for `demo:code-mode` and snapshot recording, and selects the sibling
# replay overlay for `DSH_SNAPSHOT=replay`. A config patch replaces the whole app
# config, so unchanged base fields are restated below.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
# `run_code`, plus its generated TypeScript SDK prompt. The demo and snapshot
# recorder apply this profile patch; replay applies its sibling patch.
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ./cordis.yml
patches:
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext:
maxBytes: 65536
tools:
mode: code
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
provider: deepseek-official
model: deepseek-v4-pro
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: tools
name: '@deepseek-ai/dsh-tools'
config:
mode: code
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
+5 -10
View File
@@ -1,12 +1,7 @@
# Add the self-referential Cordis tools without changing the base ACP tool
# presentation mode.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- insert:
- id: cordis-host-runner
name: '@deepseek-ai/dsh-cordis-host-runner'
- id: tool-cordis
name: '@deepseek-ai/dsh-tool-cordis'
- insert:
- id: cordis-host-runner
name: '@deepseek-ai/dsh-cordis-host-runner'
- id: tool-cordis
name: '@deepseek-ai/dsh-tool-cordis'
+43 -60
View File
@@ -1,61 +1,44 @@
# Keyless replay includes the live `cordis.yml`, disables the key-requiring
# DeepSeek adapter, and inserts `llm-replay` to serve recorded JSONL without a key
# or network; every other app entry remains shared. It also restates the acp-agent
# config to re-pin `deepseek-v4-flash`: `cordis.yml` ships `deepseek-v4-pro`, but the
# recorded corpus (request headers, provenance, system prompt) was captured on flash,
# so replay holds the recorded model to stay reproducible without a re-record. A config
# patch replaces the whole app config, so the base fields are restated verbatim.
# With `DSH_SNAPSHOT=replay`, the app bin reads `DSH_SNAPSHOT_FILE` and optional
# `DSH_SNAPSHOT_OVERRIDE` from the harness. The one-shot patch applies at include
# load time, and stdout remains reserved for ACP JSON-RPC.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
# `name` asserts the target: a mismatch skips the patch and warns only when
# a logger exists. A renamed id leaves a stale adapter entry, but replay still
# short-circuits through `llm-replay`.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
# Replay fixtures are raw JSONL; the whole-config patch must restate
# the compression choice or the default zstd frames hide the logs
# from the harness's harvest.
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
# Replay-only patch layered after `cordis.yml`: replace the network adapter
# with recorded JSONL, pin the recorded top-level model, and keep persistence
# raw for fixture harvesting.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
# Authored scenarios can fence a later parent action on the real
# child settlement edge without exposing a test-only model tool.
- id: subagent-settlement-marker
name: './tests/fixtures/subagent-settlement-marker.ts'
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? dshHomePath('sessions')
compression: none
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: subagent-settlement-marker
name: './tests/fixtures/subagent-settlement-marker.ts'
+27 -148
View File
@@ -1,20 +1,7 @@
# ACP automation server and backend snapshot-record composition. With
# `DSH_SNAPSHOT=record`, the app bin runs the real DeepSeek adapter and the
# harness harvests its persisted log. The bin loads the gitignored root `.env`
# before this config. This tree has no stdout logger or HMR because stdout
# carries ACP JSON-RPC.
# ACP demo and snapshot-record patch over the shipped `acp` profile. The dsh
# launcher owns environment loading, plugin resolution, and process shutdown;
# stdout remains reserved for ACP JSON-RPC.
- id: deepseek-llm-api-extensions
name: '@deepseek-ai/dsh-deepseek-llm-api-extensions'
- id: session-log-deepseek
name: '@deepseek-ai/dsh-session-log-deepseek'
- id: plugin-package-inventory-deepseek
name: '@deepseek-ai/dsh-plugin-package-inventory-deepseek'
# The DeepSeek adapter. Shipped default: full thinking at max effort on every
# request; exact-model resolution materializes request defaults before logging.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
config:
@@ -26,103 +13,41 @@
- id: deepseek-v4-flash-vision-exp
inputModalities: [text, image]
# The default composition confines bash AND the filesystem tools to the
# workspace and asks before a wider retry. Snapshot runs select
# danger-full-access so the established scenarios remain runner-independent;
# DSH_PERMISSION_MODE provides the same explicit deployment/test override
# outside the snapshot harness. The sandbox default + fallback root live on
# ctx.sandboxPolicy; agent calls resolve both families against the session cwd.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
- id: sandbox-policy
name: '@deepseek-ai/dsh-sandbox-policy'
config:
mode: !!js "process.env.DSH_PERMISSION_MODE ?? (process.env.DSH_SNAPSHOT === undefined ? 'workspace-write' : 'danger-full-access')"
workspaceRoot: !!js process.cwd()
# Managed child-process groups for the bash executor (spawn/kill/output plumbing).
- id: subprocess
name: '@deepseek-ai/dsh-subprocess-local'
- id: bash
name: '@deepseek-ai/dsh-bash-sandbox'
config:
timeoutMs: 60000
- id: approval
name: '@deepseek-ai/dsh-user-approval'
config:
policy: !!js "(process.env.DSH_PERMISSION_MODE ?? (process.env.DSH_SNAPSHOT === undefined ? 'workspace-write' : 'danger-full-access')) === 'danger-full-access' ? 'never' : 'ask'"
# The ACP automation app: agent spine + JSONL persistence + protocol bridge.
# Persistence root: $DSH_SNAPSHOT_SESSIONS_ROOT when the snapshot harness sets it
# (so it can harvest / isolate the log), else ./.sessions for the demo.
# Snapshot modes use raw JSONL fixtures; ordinary runs keep the compressed default.
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? dshHomePath('sessions')
compression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext:
maxBytes: 65536
# Keep the persona to identity and behavior; tool plugins own tool guidance.
# The loop resolves {{model}} and each ACP session's client-supplied {{cwd}}.
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
# Replay-aware request pressure; the routed adapter supplies model capacity.
- id: token-meter
name: '@deepseek-ai/dsh-token-meter'
# Summarize an older range after measured pressure or a canonical provider overflow.
# Ratios scale against the routed model's context window.
- id: compaction-basic
name: '@deepseek-ai/dsh-compaction-basic'
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
thresholdRatio: 0.8
retainRatio: 0.08
maxTokens: 8192
compactionRetries: 1
# Projection registry: subagent catalog identity (mode/label) folds through
# its registered units; the catalog surfaces (`list_agents`, subagent listing)
# fail loud without the capability.
- id: session-projection
name: '@deepseek-ai/dsh-session-projection'
# Expose fresh-child `spawn` and completed-prefix `fork` through separate tool
# names so multi-child scenarios exercise both transports. These leaves follow
# the app because it provides `ctx.agents` and `ctx.tools`.
- id: subagent
name: '@deepseek-ai/dsh-subagent'
- id: subagent-spawn-in-process
name: '@deepseek-ai/dsh-subagent-spawn-in-process'
config:
providerName: spawn
- id: subagent-fork-in-process
name: '@deepseek-ai/dsh-subagent-fork-in-process'
config:
providerName: fork
# Continuable background children are selected per delegation tool. The
# separately loaded control package registers the global `send_message`; its
# list plugin registers `list_agents`, served through the sessionProjections
# registry mounted above. `report` is installed only in continuable child scopes.
- id: tool-subagent-control
name: '@deepseek-ai/dsh-tool-subagent-control'
- id: tool-subagent-list-agents
name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
- id: tool-subagent-report
name: '@deepseek-ai/dsh-tool-subagent-report'
maxBytes: 65536
- id: tool-subagent
name: '@deepseek-ai/dsh-tool-subagent'
@@ -132,10 +57,6 @@
backgroundMode: continuable
maxDepth: 1
# Fork stays one-shot because a continuable child's `report` tool and prompt
# section precede the inherited history a fork reuses; `run_in_background` is off
# as an explicit foreground-only choice even though agent-spine-demo mounts the
# generic Job runtime. See .agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.md.
- id: tool-subagent-fork
name: '@deepseek-ai/dsh-tool-subagent'
config:
@@ -145,60 +66,18 @@
enableRunInBackground: false
maxDepth: 1
# The worker-thread workflow engine fans a model-written JavaScript script's
# `agent()` calls out through the spawn backend; the adjacent tool exposes it to the model.
- id: workflow-worker-thread
name: '@deepseek-ai/dsh-workflow-worker-thread'
config:
provider: spawn
- id: tool-workflow
name: '@deepseek-ai/dsh-tool-workflow'
- id: tool-ralph
name: '@deepseek-ai/dsh-tool-ralph'
# `todo_write` replaces the logged whole list for later model requests.
- id: tool-todo
name: '@deepseek-ai/dsh-tool-todo'
config:
allowParallelInProgress: true
# Identical repeat calls trigger advisory context, never a block, at the default
# thresholds [3, 5, 8]. Only the repeat-tool-reminder snapshot scenario reaches them.
- id: repeat-tool-reminder
name: '@deepseek-ai/dsh-repeat-tool-reminder'
# The filesystem stack rides the SAME sandbox policy as bash: dsh-fs-sandbox
# replaces dsh-fs-local behind ctx.fs and fences write/edit by the effective
# mode (read-only denies, workspace-write contains to the workspace + temp
# roots, danger-full-access passes through), so read/write/edit are available
# under every mode. fs-observation-policy (read-before-edit) composes orthogonally on top.
- id: fs-sandbox
name: '@deepseek-ai/dsh-fs-sandbox'
config:
cwd: !!js process.cwd()
- id: fs-observation-policy
name: '@deepseek-ai/dsh-fs-observation-policy'
- insert:
- id: hooks-claude-code
name: '@deepseek-ai/dsh-hooks-claude-code'
config:
configPath: ./hooks.json
- id: tool-fs
name: '@deepseek-ai/dsh-tool-fs'
# `configPath` is read once at load and resolves from the server launch cwd, not
# `session/new.cwd`; one `hooks.json` therefore applies to every session and a
# project-local file is not discovered. Missing config registers nothing. Hook
# commands still run in the session cwd. Warnings use `ctx.logger`, never stdout;
# see packages/hooks/hooks-claude-code/README.md for the deferred per-session design.
- id: hooks-claude-code
name: '@deepseek-ai/dsh-hooks-claude-code'
config:
configPath: ./hooks.json
# Codex uses its own `codex-hooks.json` and snake_case five-event dialect; it
# cannot share Claude's file. It has the same process-level, read-once, missing-is-no-op,
# logger-only contract. Shipping both bridges lets a scenario seed and exercise either dialect.
- id: hooks-codex
name: '@deepseek-ai/dsh-hooks-codex'
config:
configPath: ./codex-hooks.json
- id: hooks-codex
name: '@deepseek-ai/dsh-hooks-codex'
config:
configPath: ./codex-hooks.json
@@ -1,53 +1,60 @@
# Keyless counterpart to depth-two.cordis.yml: apply the depth patch and replace
# the live adapter with per-session replay.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- id: tool-subagent
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: spawn
toolName: subagent
backgroundMode: continuable
maxDepth: 2
# Re-pin the recorded model: cordis.yml ships deepseek-v4-pro, but this
# scenario's corpus was captured on flash. A config patch replaces the
# whole app config, so the base fields are restated verbatim.
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- id: tool-subagent
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: spawn
toolName: subagent
backgroundMode: continuable
maxDepth: 2
# Re-pin the recorded flash model for this scenario's corpus.
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
+6 -11
View File
@@ -1,14 +1,9 @@
# Depth-limit snapshot overlay: keep the default composition and allow two
# generations of spawn children before runtime enforcement rejects another.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: tool-subagent
name: '@deepseek-ai/dsh-tool-subagent'
config:
path: ./cordis.yml
patches:
- id: tool-subagent
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: spawn
toolName: subagent
backgroundMode: continuable
maxDepth: 2
provider: spawn
toolName: subagent
backgroundMode: continuable
maxDepth: 2
+51 -44
View File
@@ -1,45 +1,52 @@
# Keyless filesystem snapshots apply the spill and replay overlays directly
# because include patches cannot target entries behind a nested include. The
# sandboxed filesystem stack already lives in the base cordis.yml. This file also
# re-pins the acp-agent model to `deepseek-v4-flash`: `cordis.yml` ships
# `deepseek-v4-pro`, but the recorded corpus was captured on flash, and a config
# patch replaces the whole app config, so the base fields are restated verbatim.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
# Keyless filesystem snapshots combine spill settings with replay. The
# sandboxed filesystem stack already lives in `dsh-base`; the ACP row re-pins
# `deepseek-v4-flash` for the recorded corpus.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: spill-local
name: '@deepseek-ai/dsh-spill-local'
config:
root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill'
- id: spill-policy
name: '@deepseek-ai/dsh-spill-policy'
config:
maxInlineBytes: 800
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: spill-local
name: '@deepseek-ai/dsh-spill-local'
config:
root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill'
- id: spill-policy
name: '@deepseek-ai/dsh-spill-policy'
config:
maxInlineBytes: 800
+10 -14
View File
@@ -1,17 +1,13 @@
# Filesystem-scenario overlay: the sandboxed filesystem stack already lives in
# the base cordis.yml, so this overlay adds only the local tool-result spill
# `dsh-base`, so this patch changes only the local tool-result spill
# storage those scenarios exercise.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: spill-local
name: '@deepseek-ai/dsh-spill-local'
config:
path: ./cordis.yml
patches:
- insert:
- id: spill-local
name: '@deepseek-ai/dsh-spill-local'
config:
root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill'
- id: spill-policy
name: '@deepseek-ai/dsh-spill-policy'
config:
maxInlineBytes: !!js process.env.DSH_SNAPSHOT && 800 || 50000
root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill'
- id: spill-policy
name: '@deepseek-ai/dsh-spill-policy'
config:
maxInlineBytes: !!js process.env.DSH_SNAPSHOT && 800 || 50000
@@ -2,38 +2,47 @@
# image.cordis.snapshot.yml overlay except the replay catalog leaves flash
# text-only, so the strict read_image gate refuses and no image ever enters
# the durable log.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
inputModalities: [text]
- id: deepseek-v4-pro
inputModalities: [text]
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
inputModalities: [text]
- id: deepseek-v4-pro
inputModalities: [text]
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
+27 -23
View File
@@ -1,27 +1,31 @@
# Text-route image overlay: the attachment store registers read_image, but the
# strict execution gate refuses on a route that does not declare image input,
# so a text-only deployment keeps its durable history text-clean. The app
# config is restated to re-pin `deepseek-v4-flash` (base ships pro; the
# authored fixture and the pinned header class are flash), because a config
# patch replaces the whole app config.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
# so a text-only deployment keeps its durable history text-clean. The ACP row
# re-pins `deepseek-v4-flash` for the authored fixture and header class.
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ./cordis.yml
patches:
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
provider: deepseek-official
model: deepseek-v4-flash
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
+47 -40
View File
@@ -1,43 +1,50 @@
# Keyless replay for the read-image success scenario. Include patches cannot
# target entries behind a nested include, so this restates the replay overlay
# directly over the base cordis.yml (the fs.cordis.snapshot.yml pattern) and
# re-pins the recorded vision model. The replay catalog declares image input,
# Keyless replay for the read-image success scenario. This profile patch swaps
# the adapter and re-pins the recorded vision model. The replay catalog declares image input,
# so the strict read_image gate accepts the route and the tool result carries
# the durable image block.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash-vision-exp
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
inputModalities: [text]
- id: deepseek-v4-pro
inputModalities: [text]
- id: deepseek-v4-flash-vision-exp
inputModalities: [text, image]
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash-vision-exp
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
inputModalities: [text]
- id: deepseek-v4-pro
inputModalities: [text]
- id: deepseek-v4-flash-vision-exp
inputModalities: [text, image]
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
+27 -22
View File
@@ -1,26 +1,31 @@
# Image-scenario overlay: adds the durable attachment store the read_image tool
# commits through. The store resolves its root from $DSH_HOME, which the
# snapshot harness scopes per run, so the overlay itself carries no paths. The
# app config is restated to select the shipped vision model because a config
# patch replaces the whole app config.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
# snapshot harness scopes per run, so the patch itself carries no attachment
# path. The ACP row selects the shipped vision model.
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ./cordis.yml
patches:
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash-vision-exp
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
provider: deepseek-official
model: deepseek-v4-flash-vision-exp
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
@@ -1,38 +1,47 @@
# Keyless runner-classification composition: replay authored model turns and
# replace the shipping provider with a deterministic process-launch stand-in.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: partial-landlock-sandbox
name: './tests/fixtures/partial-landlock-sandbox.ts'
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
disabled: true
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: partial-landlock-sandbox
name: './tests/fixtures/partial-landlock-sandbox.ts'
+7 -11
View File
@@ -1,13 +1,9 @@
# Live counterpart for the runner-classification snapshot overlay. It replaces
# only the sandbox provider; authored scenarios are skipped in record mode.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
disabled: true
- insert:
- id: partial-landlock-sandbox
name: './tests/fixtures/partial-landlock-sandbox.ts'
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
disabled: true
- insert:
- id: partial-landlock-sandbox
name: './tests/fixtures/partial-landlock-sandbox.ts'
@@ -1,64 +1,60 @@
# Keyless twin of product-subagent-both.cordis.yml: preserve all four named
# product tools while replacing only the external model adapter.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: subagent-codex-primary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-primary
- id: subagent-codex-secondary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-secondary
- id: subagent-claude-primary
name: '@deepseek-ai/dsh-subagent-claude-code'
config:
providerName: claude-primary
- id: subagent-claude-secondary
name: '@deepseek-ai/dsh-subagent-claude-code'
config:
providerName: claude-secondary
- id: tool-subagent-codex-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-primary
toolName: subagent_codex_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-codex-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-secondary
toolName: subagent_codex_secondary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-claude-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-primary
toolName: subagent_claude_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-claude-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-secondary
toolName: subagent_claude_secondary
backgroundMode: one-shot
maxDepth: provider-managed
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: subagent-codex-primary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-primary
- id: subagent-codex-secondary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-secondary
- id: subagent-claude-primary
name: '@deepseek-ai/dsh-subagent-claude-code'
config:
providerName: claude-primary
- id: subagent-claude-secondary
name: '@deepseek-ai/dsh-subagent-claude-code'
config:
providerName: claude-secondary
- id: tool-subagent-codex-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-primary
toolName: subagent_codex_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-codex-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-secondary
toolName: subagent_codex_secondary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-claude-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-primary
toolName: subagent_claude_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-claude-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-secondary
toolName: subagent_claude_secondary
backgroundMode: one-shot
maxDepth: provider-managed
@@ -1,53 +1,48 @@
# Add two named Codex providers, two named Claude Code providers, and the
# independent one-shot tool rows an Agent Preset may contribute. Loading the
# composition starts neither product; the scenario pins all four schemas.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- insert:
- id: subagent-codex-primary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-primary
- id: subagent-codex-secondary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-secondary
- id: subagent-claude-primary
name: '@deepseek-ai/dsh-subagent-claude-code'
config:
providerName: claude-primary
- id: subagent-claude-secondary
name: '@deepseek-ai/dsh-subagent-claude-code'
config:
providerName: claude-secondary
- id: tool-subagent-codex-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-primary
toolName: subagent_codex_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-codex-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-secondary
toolName: subagent_codex_secondary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-claude-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-primary
toolName: subagent_claude_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-claude-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-secondary
toolName: subagent_claude_secondary
backgroundMode: one-shot
maxDepth: provider-managed
- insert:
- id: subagent-codex-primary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-primary
- id: subagent-codex-secondary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-secondary
- id: subagent-claude-primary
name: '@deepseek-ai/dsh-subagent-claude-code'
config:
providerName: claude-primary
- id: subagent-claude-secondary
name: '@deepseek-ai/dsh-subagent-claude-code'
config:
providerName: claude-secondary
- id: tool-subagent-codex-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-primary
toolName: subagent_codex_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-codex-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-secondary
toolName: subagent_codex_secondary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-claude-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-primary
toolName: subagent_claude_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-claude-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-secondary
toolName: subagent_claude_secondary
backgroundMode: one-shot
maxDepth: provider-managed
@@ -1,42 +1,38 @@
# Keyless twin of product-subagent-codex.cordis.yml: keep both named product
# providers and tools while replacing only the external model adapter.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: subagent-codex-primary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-primary
- id: subagent-codex-secondary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-secondary
- id: tool-subagent-codex-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-primary
toolName: subagent_codex_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-codex-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-secondary
toolName: subagent_codex_secondary
backgroundMode: one-shot
maxDepth: provider-managed
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: subagent-codex-primary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-primary
- id: subagent-codex-secondary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-secondary
- id: tool-subagent-codex-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-primary
toolName: subagent_codex_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-codex-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-secondary
toolName: subagent_codex_secondary
backgroundMode: one-shot
maxDepth: provider-managed
@@ -1,31 +1,26 @@
# Add two named Codex product providers and their preset-shaped one-shot tools
# to the real ACP composition. The model is told not to call them; the scenario
# pins both assembled request schemas without starting Codex.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- insert:
- id: subagent-codex-primary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-primary
- id: subagent-codex-secondary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-secondary
- id: tool-subagent-codex-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-primary
toolName: subagent_codex_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-codex-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-secondary
toolName: subagent_codex_secondary
backgroundMode: one-shot
maxDepth: provider-managed
- insert:
- id: subagent-codex-primary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-primary
- id: subagent-codex-secondary
name: '@deepseek-ai/dsh-subagent-codex'
config:
providerName: codex-secondary
- id: tool-subagent-codex-primary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-primary
toolName: subagent_codex_primary
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-codex-secondary
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex-secondary
toolName: subagent_codex_secondary
backgroundMode: one-shot
maxDepth: provider-managed
+22 -26
View File
@@ -1,27 +1,23 @@
# Keyless replay counterpart to pty.cordis.yml.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: pty
name: '@deepseek-ai/dsh-terminal'
- id: pty-snapshot-backend
name: './pty-snapshot-backend.mjs'
- id: tool-terminal
name: '@deepseek-ai/dsh-tool-terminal'
config:
maxResultBytes: 64
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: pty
name: '@deepseek-ai/dsh-terminal'
- id: pty-snapshot-backend
name: './pty-snapshot-backend.mjs'
- id: tool-terminal
name: '@deepseek-ai/dsh-tool-terminal'
config:
maxResultBytes: 64
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
+14 -19
View File
@@ -1,21 +1,16 @@
# Opt-in persistent PTY composition for the PTY snapshot scenario. The base
# deployment already owns the shared sandbox provider and policy.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- insert:
- id: pty
name: '@deepseek-ai/dsh-terminal'
- id: terminal-bash
name: '@deepseek-ai/dsh-terminal-bash'
config:
pollIntervalMs: 10
exactProbeAfterMs: 20
idleSilenceMs: 250
handoffGraceMs: 250
timeoutMs: 2000
disposeGraceMs: 500
- id: tool-terminal
name: '@deepseek-ai/dsh-tool-terminal'
- insert:
- id: pty
name: '@deepseek-ai/dsh-terminal'
- id: terminal-bash
name: '@deepseek-ai/dsh-terminal-bash'
config:
pollIntervalMs: 10
exactProbeAfterMs: 20
idleSilenceMs: 250
handoffGraceMs: 250
timeoutMs: 2000
disposeGraceMs: 500
- id: tool-terminal
name: '@deepseek-ai/dsh-tool-terminal'
+45 -37
View File
@@ -2,41 +2,49 @@
# adapter, insert `llm-replay`, and give its provider the same deterministic
# 1 ms zero-jitter retry policy as the live sibling. The app patch still
# restates its whole config for raw JSONL persistence and the recorded model.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
retryPolicy:
mode: normal
maxRetries: 2
backoff:
initialDelayMs: 1
maxDelayMs: 1
jitterRatio: 0
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
retryPolicy:
mode: normal
maxRetries: 2
backoff:
initialDelayMs: 1
maxDelayMs: 1
jitterRatio: 0
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
+38 -31
View File
@@ -5,36 +5,43 @@
# Config patches replace whole plugin configs: the provider patch restates its
# adapter fields around `retryPolicy`, while the app patch re-pins the recorded
# flash model and restates its base fields.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
config:
thinking: enabled
reasoningEffort: max
retryPolicy:
mode: normal
maxRetries: 2
backoff:
initialDelayMs: 1
maxDelayMs: 1
jitterRatio: 0
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
thinking: enabled
reasoningEffort: max
retryPolicy:
mode: normal
maxRetries: 2
backoff:
initialDelayMs: 1
maxDelayMs: 1
jitterRatio: 0
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
Verify your work by running the code or tests. Keep answers brief and factual.
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
@@ -1,12 +1,60 @@
# Keyless session-query snapshot patch: replay plus the filesystem spill
# settings inherited by this scenario. The ACP row re-pins the recorded flash model.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: spill-local
name: '@deepseek-ai/dsh-spill-local'
config:
root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill'
- id: spill-policy
name: '@deepseek-ai/dsh-spill-policy'
config:
maxInlineBytes: 800
# Keyless counterpart to session-query.cordis.yml: the nested snapshot overlay
# supplies replay plus deterministic private spill storage and its byte limit.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./fs.cordis.snapshot.yml
patches:
- insert:
- id: tool-session-query
name: '@deepseek-ai/dsh-tool-session-query'
- id: timeout-policy
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
- insert:
- id: tool-session-query
name: '@deepseek-ai/dsh-tool-session-query'
- id: timeout-policy
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
+20 -10
View File
@@ -1,12 +1,22 @@
# Filesystem-scenario overlay: the sandboxed filesystem stack already lives in
# the base cordis.yml, so this overlay adds only the local tool-result spill
# storage those scenarios exercise.
- id: spill-local
name: '@deepseek-ai/dsh-spill-local'
config:
root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill'
- id: spill-policy
name: '@deepseek-ai/dsh-spill-policy'
config:
maxInlineBytes: !!js process.env.DSH_SNAPSHOT && 800 || 50000
# Explicit session-query tool opt-in for the dedicated spill scenario. The
# nested filesystem overlay supplies private spill storage and its byte limit.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./fs.cordis.yml
patches:
- insert:
- id: tool-session-query
name: '@deepseek-ai/dsh-tool-session-query'
- id: timeout-policy
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
- insert:
- id: tool-session-query
name: '@deepseek-ai/dsh-tool-session-query'
- id: timeout-policy
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
@@ -1,50 +1,58 @@
# Keyless replay counterpart of session-sandbox-root.cordis.yml. Patches do not
# compose across nested includes, so the replay swap, the recorded model pin,
# and the deliberately distinct sandbox fallback are applied together to the
# live tree.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
# Keyless replay counterpart of session-sandbox-root.cordis.yml: the replay
# swap, recorded model pin, and distinct sandbox fallback form one profile patch.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- id: sandbox-policy
name: '@deepseek-ai/dsh-sandbox-policy'
config:
mode: workspace-write
workspaceRoot: /tmp
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- id: sandbox-policy
name: '@deepseek-ai/dsh-sandbox-policy'
config:
mode: workspace-write
workspaceRoot: /tmp
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
@@ -2,13 +2,8 @@
# under the user's home, while this deployment fallback deliberately points at
# /tmp. A workspace-write mutation can therefore succeed only when the calling
# session's cwd replaces the process-level fallback root.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: sandbox-policy
name: '@deepseek-ai/dsh-sandbox-policy'
config:
path: ./cordis.yml
patches:
- id: sandbox-policy
name: '@deepseek-ai/dsh-sandbox-policy'
config:
mode: !!js "process.env.DSH_PERMISSION_MODE ?? (process.env.DSH_SNAPSHOT === undefined ? 'workspace-write' : 'danger-full-access')"
workspaceRoot: /tmp
mode: !!js "process.env.DSH_PERMISSION_MODE ?? (process.env.DSH_SNAPSHOT === undefined ? 'workspace-write' : 'danger-full-access')"
workspaceRoot: /tmp
@@ -1,53 +1,61 @@
# Keyless session-title composition. Main-agent chunks derive from session.jsonl;
# the auxiliary route consumes replay.override.json with pacing so its accepted
# title commits only after the main turn has closed.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay-main
name: '@deepseek-ai/dsh-llm-replay'
config:
overrideFile: ./.missing-main-replay-override.json
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: llm-replay-title
name: '@deepseek-ai/dsh-llm-replay'
config:
paceMs: 10
providers:
- id: title-replay
name: Title replay
models:
- id: title-model
- id: session-title-provider
name: '@deepseek-ai/dsh-session-title-first-prompt-llm'
config:
targetWords: 5
targetCjkCharacters: 10
maxInputBytes: 4096
maxOutputTokens: 32
timeoutMs: 5000
provider: title-replay
model: title-model
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: llm-replay-main
name: '@deepseek-ai/dsh-llm-replay'
config:
overrideFile: ./.missing-main-replay-override.json
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: llm-replay-title
name: '@deepseek-ai/dsh-llm-replay'
config:
paceMs: 10
providers:
- id: title-replay
name: Title replay
models:
- id: title-model
- id: session-title-provider
name: '@deepseek-ai/dsh-session-title-first-prompt-llm'
config:
targetWords: 5
targetCjkCharacters: 10
maxInputBytes: 4096
maxOutputTokens: 32
timeoutMs: 5000
provider: title-replay
model: title-model
+11 -16
View File
@@ -1,19 +1,14 @@
# Session-title snapshot composition: the optional first-prompt provider uses
# the ordinary DeepSeek route while the ACP app and every other capability stay
# identical to the base example.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- insert:
- id: session-title-provider
name: '@deepseek-ai/dsh-session-title-first-prompt-llm'
config:
targetWords: 5
targetCjkCharacters: 10
maxInputBytes: 4096
maxOutputTokens: 32
timeoutMs: 5000
provider: deepseek-official
model: deepseek-v4-flash
- insert:
- id: session-title-provider
name: '@deepseek-ai/dsh-session-title-first-prompt-llm'
config:
targetWords: 5
targetCjkCharacters: 10
maxInputBytes: 4096
maxOutputTokens: 32
timeoutMs: 5000
provider: deepseek-official
model: deepseek-v4-flash
@@ -1,46 +1,55 @@
# Keyless counterpart to subagent-continuable-inheritance.cordis.yml: replace
# the live adapter with replay and switch the root session to read-only at
# creation.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: parent-sandbox-override
name: './tests/fixtures/parent-sandbox-override.ts'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: parent-sandbox-override
name: './tests/fixtures/parent-sandbox-override.ts'
@@ -1,11 +1,6 @@
# Policy-inheritance overlay: the root session is switched to read-only at
# creation (the UI Access switch equivalent), so a continuable background
# child must inherit that override instead of the deployment default.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- insert:
- id: parent-sandbox-override
name: './tests/fixtures/parent-sandbox-override.ts'
- insert:
- id: parent-sandbox-override
name: './tests/fixtures/parent-sandbox-override.ts'
@@ -1,45 +1,54 @@
# Keyless counterpart to subagent-durability-failure.cordis.yml: replace the
# live adapter with replay and fail the provider-owned final child checkpoint.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: subagent-durability-failure
name: './tests/fixtures/subagent-durability-failure.ts'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: subagent-durability-failure
name: './tests/fixtures/subagent-durability-failure.ts'
@@ -1,10 +1,5 @@
# Snapshot-only durability-failure overlay. The child turn's ordinary flush
# succeeds; the provider-owned final confirmation fails deterministically.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- insert:
- id: subagent-durability-failure
name: './tests/fixtures/subagent-durability-failure.ts'
- insert:
- id: subagent-durability-failure
name: './tests/fixtures/subagent-durability-failure.ts'
@@ -1,46 +1,56 @@
# Keyless counterpart to subagent-report.cordis.yml: replace the live adapter
# with replay and preserve its child and parent scheduling fence.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
provider: deepseek-official
model: deepseek-v4-flash
Verify your work by running the code or tests. Keep answers brief and factual.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: report-fence
name: './tests/fixtures/subagent-report-fence.ts'
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: sandbox
name: '@deepseek-ai/dsh-sandbox-local'
config:
runnerCommand:
- bash
- -c
- while [ "$1" != "--" ]; do shift; done; shift; exec "$@"
- passthrough-runner
runnerFailureSignatures:
- 'passthrough-runner: profile rejected'
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- insert:
- id: report-fence
name: './tests/fixtures/subagent-report-fence.ts'
@@ -1,10 +1,6 @@
# Snapshot-only overlay fencing the child behind its parent's spawn turn and
# holding the parent in maintenance until settlement follows the default
# next-step report. The resumed parent claims both notices in causal order.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
- id: report-fence
name: './tests/fixtures/subagent-report-fence.ts'
- insert:
- id: report-fence
name: './tests/fixtures/subagent-report-fence.ts'
@@ -1,29 +1,25 @@
# Keyless twin of subagent-result-diagnostic.cordis.yml: keep the same test
# provider/tool and replace only the external model adapter.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: subagent-result-diagnostic
name: './tests/fixtures/subagent-result-diagnostic.ts'
- id: tool-subagent-codex
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: snapshot-diagnostic
toolName: subagent_codex
backgroundMode: one-shot
maxDepth: provider-managed
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: subagent-result-diagnostic
name: './tests/fixtures/subagent-result-diagnostic.ts'
- id: tool-subagent-codex
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: snapshot-diagnostic
toolName: subagent_codex
backgroundMode: one-shot
maxDepth: provider-managed
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
@@ -1,17 +1,12 @@
# Test-only product-shaped composition: mount a deterministic provider behind
# the same one-shot tool schema as the public Codex example.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ./cordis.yml
patches:
- insert:
- id: subagent-result-diagnostic
name: './tests/fixtures/subagent-result-diagnostic.ts'
- id: tool-subagent-codex
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: snapshot-diagnostic
toolName: subagent_codex
backgroundMode: one-shot
maxDepth: provider-managed
- insert:
- id: subagent-result-diagnostic
name: './tests/fixtures/subagent-result-diagnostic.ts'
- id: tool-subagent-codex
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: snapshot-diagnostic
toolName: subagent_codex
backgroundMode: one-shot
maxDepth: provider-managed
+2 -1
View File
@@ -22,8 +22,9 @@ import { cleanupAcpExampleTest } from './cleanup.ts'
*/
const AGENT: AgentUnderTest = {
binScript: fileURLToPath(new URL('../../../packages/examples/acp-demo/src/bin.ts', import.meta.url)),
binScript: fileURLToPath(new URL('../../../apps/cli/src/bin.ts', import.meta.url)),
configPath: fileURLToPath(new URL('../cordis.yml', import.meta.url)),
profile: 'acp',
tsconfigPath: fileURLToPath(new URL('../../../tsconfig.json', import.meta.url)),
}
const DANGER_FULL_ACCESS_ENV = { DSH_PERMISSION_MODE: 'danger-full-access' }
+7 -5
View File
@@ -29,12 +29,13 @@ import { OFFLOADED_IMAGE_TEXT } from '@deepseek-ai/dsh-llm'
* .agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.md.
*/
// The dsh-acp-demo bin (the demo:acp entry), this example's cordis.yml, and
// The dsh CLI, this example's profile patch, and
// the repo-root tsconfig (four levels up from examples/acp-agent/tests) — all
// ABSOLUTE: the subprocess cwd is a temp dir outside the repo.
const AGENT = {
binScript: fileURLToPath(new URL('../../../packages/examples/acp-demo/src/bin.ts', import.meta.url)),
binScript: fileURLToPath(new URL('../../../apps/cli/src/bin.ts', import.meta.url)),
configPath: fileURLToPath(new URL('../cordis.yml', import.meta.url)),
profile: 'acp',
tsconfigPath: fileURLToPath(new URL('../../../tsconfig.json', import.meta.url)),
}
const EDITING_CORDIS_SKILL = fileURLToPath(new URL(
@@ -42,8 +43,8 @@ const EDITING_CORDIS_SKILL = fileURLToPath(new URL(
import.meta.url,
))
// The Code Mode overlay configs (include-patched variants of cordis.yml; the
// replay swap resolves each one's sibling `*cordis.snapshot.yml`).
// The Code Mode profile patches; replay selects each one's sibling
// `*cordis.snapshot.yml`.
const CODE_MODE_CONFIG = fileURLToPath(new URL('../code-mode.cordis.yml', import.meta.url))
const CODE_MODE_IMAGE_CONFIG = fileURLToPath(new URL('../code-mode-image.cordis.yml', import.meta.url))
const CODE_MODE_WORKSPACE_CONTEXT_CONFIG = fileURLToPath(new URL('../code-mode-workspace-context.cordis.yml', import.meta.url))
@@ -238,6 +239,7 @@ const SCENARIOS: Scenario[] = [
recorded: false,
pinsHeader: true,
headerClass: 'image',
toolSchemasSource: 'text-turn',
configPath: IMAGE_CONFIG,
},
{
@@ -247,7 +249,7 @@ const SCENARIOS: Scenario[] = [
pinsHeader: true,
headerClass: 'image-text-route',
systemPromptSource: 'text-turn',
toolSchemasSource: 'read-image',
toolSchemasSource: 'text-turn',
configPath: IMAGE_TEXT_ROUTE_CONFIG,
},
// Authored keyless replay of wide-image admission: the 2001x1 fixture sits
@@ -1,4 +1,4 @@
/** Generic keyless ACP v1 automation-control conformance over the real demo process. */
/** Generic keyless ACP v1 automation-control conformance over the real dsh profile. */
import { mkdtemp, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
@@ -12,13 +12,15 @@ import {
} from '@deepseek-ai/dsh-acp-snapshot'
import { describe, expect, it } from 'vitest'
const repoRoot = fileURLToPath(new URL('../../../../', import.meta.url))
const repoRoot = fileURLToPath(new URL('../../../', import.meta.url))
const agent: AgentUnderTest = {
binScript: join(repoRoot, 'packages/examples/acp-demo/src/bin.ts'),
configPath: fileURLToPath(new URL('./control-surface.cordis.yml', import.meta.url)),
binScript: join(repoRoot, 'apps/cli/src/bin.ts'),
libBinScript: join(repoRoot, 'apps/cli/lib/bin.js'),
configPath: fileURLToPath(new URL('./fixtures/control-surface/cordis.yml', import.meta.url)),
profile: 'acp',
tsconfigPath: join(repoRoot, 'tsconfig.json'),
}
const mcpServer = fileURLToPath(new URL('../../../mcp/mcp-client/tests/fixture-server.ts', import.meta.url))
const mcpServer = fileURLToPath(new URL('../../../packages/mcp/mcp-client/tests/fixture-server.ts', import.meta.url))
/** Find one named select value in grouped or ungrouped standard options. */
function selectValue(
@@ -38,7 +40,7 @@ describe('standard ACP v1 control surface', () => {
it('selects, mounts MCP, closes, restarts, resumes, and cancels through the SDK only', async () => {
const cwd = await mkdtemp(join(tmpdir(), 'dsh-acp-control-'))
const persistenceRoot = join(cwd, '.sessions')
const env = { DSH_CONFORMANCE_PERSISTENCE_ROOT: persistenceRoot }
const env = { DSH_CONFORMANCE_PERSISTENCE_ROOT: persistenceRoot, DSH_TELEMETRY_DISABLED: '1' }
const mcpServers = [{ name: 'fixture', command: process.execPath, args: [mcpServer], env: [] }]
let first: LaunchedAcpTestAgent | undefined
let second: LaunchedAcpTestAgent | undefined
+3 -2
View File
@@ -19,7 +19,7 @@ import { cleanupAcpExampleTest } from './cleanup.ts'
/**
* The default ACP composition (`cordis.yml`) end to end.
*
* Keyless smoke: boot the REAL `cordis.yml` through the `dsh-acp-agent` bin as
* Keyless smoke: boot the real profile patch through `dsh --profile acp` as
* an ACP subprocess and drive initialize + session/new — the real-Loader-path
* guard (postmortem 0001) for THIS tree's exports, including the
* sandbox executor AND the approval service. No prompt is sent, so neither the
@@ -34,8 +34,9 @@ import { cleanupAcpExampleTest } from './cleanup.ts'
*/
const AGENT: AgentUnderTest = {
binScript: fileURLToPath(new URL('../../../packages/examples/acp-demo/src/bin.ts', import.meta.url)),
binScript: fileURLToPath(new URL('../../../apps/cli/src/bin.ts', import.meta.url)),
configPath: fileURLToPath(new URL('../cordis.yml', import.meta.url)),
profile: 'acp',
tsconfigPath: fileURLToPath(new URL('../../../tsconfig.json', import.meta.url)),
}
+16 -10
View File
@@ -1,15 +1,21 @@
# Keyless generic ACP v1 control-surface conformance composition.
- id: control-surface-llm
name: './control-surface-llm.ts'
# Keyless generic ACP v1 control-surface patch over `dsh --profile acp`.
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: control-fixture
model: alpha
persistenceRoot: !!js process.env.DSH_CONFORMANCE_PERSISTENCE_ROOT
persistenceCompression: none
workspaceContext: false
- id: token-meter
name: '../../../llm/token-meter/src/index.ts'
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_CONFORMANCE_PERSISTENCE_ROOT
compression: none
- insert:
- id: control-surface-llm
name: './control-surface-llm.ts'
+39 -32
View File
@@ -1,37 +1,44 @@
# Keyless assembled-request snapshot for native DeepSeek image offload. The
# local provider endpoint is supplied by the snapshot test; the real attachment
# store and ACP bridge carry two uploaded images into one model request.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
config:
path: ../../cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
config:
apiKeyEnv: DSH_SNAPSHOT_API_KEY
baseURL: !!js process.env.DSH_SNAPSHOT_BASE_URL
thinking: disabled
maxRequestFilesBytes: 92
imageOffloadByteQuantum: 1
models:
- id: deepseek-v4-flash-vision-exp
contextWindow: 32768
maxTokens: 1024
inputModalities: [text, image]
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash-vision-exp
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
apiKeyEnv: DSH_SNAPSHOT_API_KEY
baseURL: !!js process.env.DSH_SNAPSHOT_BASE_URL
thinking: disabled
maxRequestFilesBytes: 92
imageOffloadByteQuantum: 1
models:
- id: deepseek-v4-flash-vision-exp
contextWindow: 32768
maxTokens: 1024
inputModalities: [text, image]
Keep answers brief and factual.
- insert:
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash-vision-exp
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}.
Keep answers brief and factual.
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
@@ -1,46 +1,53 @@
# Keyless replay counterpart to fs-diff-bound.cordis.yml. Replay patches apply
# directly against the live cordis.yml because include patches cannot target
# entries behind a nested include; the acp-agent restatement keeps the recorded
# deepseek-v4-flash model and raw JSONL persistence for the harness's harvest.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ../cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
# Keyless replay counterpart to fs-diff-bound.cordis.yml. The ACP and
# persistence rows keep the recorded flash model and raw JSONL harvest.
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
Verify your work by running the code or tests. Keep answers brief and factual.
- id: fs-sandbox
name: '@deepseek-ai/dsh-fs-sandbox'
config:
cwd: !!js process.cwd()
diffBasisMaxBytes: 64
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
# Capability parity with the live adapter so replay
# reconstructs the freshly recorded request header.
- id: deepseek-v4-flash
contextWindow: 1000000
defaultMaxTokens: 256000
reasoningEfforts: ['off', 'low', 'high', 'max']
defaultReasoningEffort: max
- id: deepseek-v4-pro
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-flash
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: fs-sandbox
name: '@deepseek-ai/dsh-fs-sandbox'
config:
cwd: !!js process.cwd()
diffBasisMaxBytes: 64
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
# Capability parity with the live adapter so replay
# reconstructs the freshly recorded request header.
- id: deepseek-v4-flash
contextWindow: 1000000
defaultMaxTokens: 256000
reasoningEfforts: ['off', 'low', 'high', 'max']
defaultReasoningEffort: max
- id: deepseek-v4-pro
@@ -4,26 +4,33 @@
# diff. A config patch replaces the row's whole config, so `cwd` is restated
# verbatim, and the acp-agent restatement re-pins `deepseek-v4-flash` to match
# the recorded corpus and its pinned request headers.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
path: ../cordis.yml
patches:
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext:
maxBytes: 65536
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
provider: deepseek-official
model: deepseek-v4-flash
Verify your work by running the code or tests. Keep answers brief and factual.
- id: fs-sandbox
name: '@deepseek-ai/dsh-fs-sandbox'
config:
cwd: !!js process.cwd()
diffBasisMaxBytes: 64
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
config:
maxBytes: 65536
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: |
You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug.
Verify your work by running the code or tests. Keep answers brief and factual.
- id: fs-sandbox
name: '@deepseek-ai/dsh-fs-sandbox'
config:
cwd: !!js process.cwd()
diffBasisMaxBytes: 64
@@ -1,35 +1,81 @@
# Minimal keyless composition: real app, bash, and search tool; replayed model.
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-pro
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-pro
- id: subprocess
name: '@deepseek-ai/dsh-subprocess-local'
- id: bash
name: '@deepseek-ai/dsh-bash-local'
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext: false
skills:
enabled: false
toolJobs: false
goals: false
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
disabled: true
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: You are a concise snapshot agent working in {{cwd}}.
- id: tool-jobs
name: '@deepseek-ai/dsh-tool-jobs'
disabled: true
- id: goal
name: '@deepseek-ai/dsh-goal'
disabled: true
- id: goal-round-driver
name: '@deepseek-ai/dsh-goal-round-driver'
disabled: true
- id: command-goal
name: '@deepseek-ai/dsh-command-goal'
disabled: true
- id: tool-goal
name: '@deepseek-ai/dsh-tool-goal'
disabled: true
- id: skill
name: '@deepseek-ai/dsh-skill'
disabled: true
- id: skill-filesystem
name: '@deepseek-ai/dsh-skill-filesystem'
disabled: true
- id: tool-skill
name: '@deepseek-ai/dsh-tool-skill'
disabled: true
- id: tool-fs-search
name: '@deepseek-ai/dsh-tool-fs-search'
config:
sampleOverCapGlobResults: true
globMaxResults: 4
- id: spill-local
name: '@deepseek-ai/dsh-spill-local'
config:
root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill'
+53 -12
View File
@@ -8,25 +8,66 @@
- id: subprocess
name: '@deepseek-ai/dsh-subprocess-local'
- id: bash
name: '@deepseek-ai/dsh-bash-local'
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext: false
skills:
enabled: false
toolJobs: false
goals: false
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
disabled: true
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: You are a concise snapshot agent working in {{cwd}}.
- id: tool-jobs
name: '@deepseek-ai/dsh-tool-jobs'
disabled: true
- id: goal
name: '@deepseek-ai/dsh-goal'
disabled: true
- id: goal-round-driver
name: '@deepseek-ai/dsh-goal-round-driver'
disabled: true
- id: command-goal
name: '@deepseek-ai/dsh-command-goal'
disabled: true
- id: tool-goal
name: '@deepseek-ai/dsh-tool-goal'
disabled: true
- id: skill
name: '@deepseek-ai/dsh-skill'
disabled: true
- id: skill-filesystem
name: '@deepseek-ai/dsh-skill-filesystem'
disabled: true
- id: tool-skill
name: '@deepseek-ai/dsh-tool-skill'
disabled: true
- id: tool-fs-search
name: '@deepseek-ai/dsh-tool-fs-search'
config:
sampleOverCapGlobResults: true
globMaxResults: 4
- id: spill-local
name: '@deepseek-ai/dsh-spill-local'
config:
root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill'
+2 -1
View File
@@ -24,8 +24,9 @@ const wrapupDir = join(dirname(fileURLToPath(import.meta.url)), 'goal-snapshots/
const refreshing = process.env.DSH_SNAPSHOT === 'refresh'
const agent: AgentUnderTest = {
binScript: fileURLToPath(new URL('../../../packages/examples/acp-demo/src/bin.ts', import.meta.url)),
binScript: fileURLToPath(new URL('../../../apps/cli/src/bin.ts', import.meta.url)),
configPath: fileURLToPath(new URL('../cordis.yml', import.meta.url)),
profile: 'acp',
tsconfigPath: fileURLToPath(new URL('../../../tsconfig.json', import.meta.url)),
}
+2 -1
View File
@@ -19,8 +19,9 @@ import { cleanupAcpExampleTest } from './cleanup.ts'
*/
const AGENT: AgentUnderTest = {
binScript: fileURLToPath(new URL('../../../packages/examples/acp-demo/src/bin.ts', import.meta.url)),
binScript: fileURLToPath(new URL('../../../apps/cli/src/bin.ts', import.meta.url)),
configPath: fileURLToPath(new URL('../cordis.yml', import.meta.url)),
profile: 'acp',
tsconfigPath: fileURLToPath(new URL('../../../tsconfig.json', import.meta.url)),
}
@@ -1,36 +1,33 @@
# Keyless replay keeps the LSP composition intact and replaces only the model adapter.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ../cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: lsp
name: '@deepseek-ai/dsh-lsp'
- id: lsp-stdio
name: '@deepseek-ai/dsh-lsp-stdio'
config:
servers:
fixture:
command: !!js process.execPath
args: ['./lsp-server.mjs']
extensionToLanguage:
'.ts': typescript
- id: timeout-policy
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
- id: tool-lsp
name: '@deepseek-ai/dsh-tool-lsp'
config:
maxLocations: 1
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: lsp
name: '@deepseek-ai/dsh-lsp'
- id: lsp-stdio
name: '@deepseek-ai/dsh-lsp-stdio'
config:
servers:
fixture:
command: !!js process.execPath
args: ['./lsp-server.mjs']
extensionToLanguage:
'.ts': typescript
- id: tool-lsp
name: '@deepseek-ai/dsh-tool-lsp'
config:
maxLocations: 1
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: timeout-policy
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
+19 -23
View File
@@ -1,25 +1,21 @@
# Exercise the model-facing LSP tool through the shipped ACP app and Loader entry path.
# The scenario workspace supplies the deterministic stdio server used by this test composition.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
config:
path: ../cordis.yml
patches:
- insert:
- id: lsp
name: '@deepseek-ai/dsh-lsp'
- id: lsp-stdio
name: '@deepseek-ai/dsh-lsp-stdio'
config:
servers:
fixture:
command: !!js process.execPath
args: ['./lsp-server.mjs']
extensionToLanguage:
'.ts': typescript
- id: timeout-policy
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
- id: tool-lsp
name: '@deepseek-ai/dsh-tool-lsp'
config:
maxLocations: 1
- insert:
- id: lsp
name: '@deepseek-ai/dsh-lsp'
- id: lsp-stdio
name: '@deepseek-ai/dsh-lsp-stdio'
config:
servers:
fixture:
command: !!js process.execPath
args: ['./lsp-server.mjs']
extensionToLanguage:
'.ts': typescript
- id: tool-lsp
name: '@deepseek-ai/dsh-tool-lsp'
config:
maxLocations: 1
- id: timeout-policy
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
@@ -1,15 +1,21 @@
# Keyless replay counterpart to persistent-pwsh.cordis.yml.
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-pro
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- id: terminal
name: '@deepseek-ai/dsh-terminal'
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-pro
- insert:
- id: terminal
name: '@deepseek-ai/dsh-terminal'
- id: sandbox-policy
name: '@deepseek-ai/dsh-sandbox-policy'
@@ -20,26 +26,70 @@
- id: subprocess
name: '@deepseek-ai/dsh-subprocess-local'
- id: terminal-pwsh
name: '@deepseek-ai/dsh-terminal-bash'
config:
shellDialect: pwsh
timeoutMs: 30000
- insert:
- id: terminal-pwsh
name: '@deepseek-ai/dsh-terminal-bash'
config:
shellDialect: pwsh
timeoutMs: 30000
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext: false
skills:
enabled: false
toolBash: false
toolJobs: false
goals: false
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
disabled: true
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: You are a concise snapshot agent working in {{cwd}}.
- id: tool-pwsh-persistent
name: '@deepseek-ai/dsh-tool-pwsh-persistent'
- id: tool-jobs
name: '@deepseek-ai/dsh-tool-jobs'
disabled: true
- id: goal
name: '@deepseek-ai/dsh-goal'
disabled: true
- id: goal-round-driver
name: '@deepseek-ai/dsh-goal-round-driver'
disabled: true
- id: command-goal
name: '@deepseek-ai/dsh-command-goal'
disabled: true
- id: tool-goal
name: '@deepseek-ai/dsh-tool-goal'
disabled: true
- id: skill
name: '@deepseek-ai/dsh-skill'
disabled: true
- id: skill-filesystem
name: '@deepseek-ai/dsh-skill-filesystem'
disabled: true
- id: tool-skill
name: '@deepseek-ai/dsh-tool-skill'
disabled: true
- id: tool-bash
name: '@deepseek-ai/dsh-tool-bash'
disabled: true
- insert:
- id: tool-pwsh-persistent
name: '@deepseek-ai/dsh-tool-pwsh-persistent'
@@ -14,29 +14,74 @@
- id: subprocess
name: '@deepseek-ai/dsh-subprocess-local'
- id: terminal
name: '@deepseek-ai/dsh-terminal'
- insert:
- id: terminal
name: '@deepseek-ai/dsh-terminal'
- id: terminal-pwsh
name: '@deepseek-ai/dsh-terminal-bash'
config:
shellDialect: pwsh
timeoutMs: 30000
- insert:
- id: terminal-pwsh
name: '@deepseek-ai/dsh-terminal-bash'
config:
shellDialect: pwsh
timeoutMs: 30000
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext: false
skills:
enabled: false
toolBash: false
toolJobs: false
goals: false
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
disabled: true
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: You are a concise snapshot agent working in {{cwd}}.
- id: tool-pwsh-persistent
name: '@deepseek-ai/dsh-tool-pwsh-persistent'
- id: tool-jobs
name: '@deepseek-ai/dsh-tool-jobs'
disabled: true
- id: goal
name: '@deepseek-ai/dsh-goal'
disabled: true
- id: goal-round-driver
name: '@deepseek-ai/dsh-goal-round-driver'
disabled: true
- id: command-goal
name: '@deepseek-ai/dsh-command-goal'
disabled: true
- id: tool-goal
name: '@deepseek-ai/dsh-tool-goal'
disabled: true
- id: skill
name: '@deepseek-ai/dsh-skill'
disabled: true
- id: skill-filesystem
name: '@deepseek-ai/dsh-skill-filesystem'
disabled: true
- id: tool-skill
name: '@deepseek-ai/dsh-tool-skill'
disabled: true
- id: tool-bash
name: '@deepseek-ai/dsh-tool-bash'
disabled: true
- insert:
- id: tool-pwsh-persistent
name: '@deepseek-ai/dsh-tool-pwsh-persistent'
@@ -1,38 +1,85 @@
# Minimal keyless composition: real app, pwsh executor, and pwsh tool; replayed model.
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-pro
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-pro
- id: subprocess
name: '@deepseek-ai/dsh-subprocess-local'
- id: bash
name: '@deepseek-ai/dsh-pwsh-local'
- id: bash-sandbox
name: '@deepseek-ai/dsh-bash-sandbox'
disabled: true
- id: pwsh-sandbox
name: '@deepseek-ai/dsh-pwsh-sandbox'
disabled: false
- id: shell-env
name: '@deepseek-ai/dsh-shell-env'
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: none
workspaceContext: false
skills:
enabled: false
# job_output/job_kill stay mounted (the bundle's toolJobs default) so
# background pwsh runs are readable and killable.
goals: false
# The pwsh tool replaces the bundle's bash tool in this composition.
toolBash: false
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: none
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
disabled: true
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: You are a concise snapshot agent working in {{cwd}}.
- id: goal
name: '@deepseek-ai/dsh-goal'
disabled: true
- id: goal-round-driver
name: '@deepseek-ai/dsh-goal-round-driver'
disabled: true
- id: command-goal
name: '@deepseek-ai/dsh-command-goal'
disabled: true
- id: tool-goal
name: '@deepseek-ai/dsh-tool-goal'
disabled: true
- id: skill
name: '@deepseek-ai/dsh-skill'
disabled: true
- id: skill-filesystem
name: '@deepseek-ai/dsh-skill-filesystem'
disabled: true
- id: tool-skill
name: '@deepseek-ai/dsh-tool-skill'
disabled: true
- id: tool-bash
name: '@deepseek-ai/dsh-tool-bash'
disabled: true
- id: tool-pwsh
name: '@deepseek-ai/dsh-tool-pwsh'
disabled: false
+56 -14
View File
@@ -8,28 +8,70 @@
- id: subprocess
name: '@deepseek-ai/dsh-subprocess-local'
- id: bash
name: '@deepseek-ai/dsh-pwsh-local'
- id: bash-sandbox
name: '@deepseek-ai/dsh-bash-sandbox'
disabled: true
- id: pwsh-sandbox
name: '@deepseek-ai/dsh-pwsh-sandbox'
disabled: false
- id: shell-env
name: '@deepseek-ai/dsh-shell-env'
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
- id: acp
name: '@deepseek-ai/dsh-acp'
config:
provider: deepseek-official
model: deepseek-v4-pro
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
workspaceContext: false
skills:
enabled: false
# job_output/job_kill stay mounted (the bundle's toolJobs default) so
# background pwsh runs are readable and killable.
goals: false
# The pwsh tool replaces the bundle's bash tool in this composition.
toolBash: false
- id: session-persistence-jsonl
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
root: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
compression: !!js 'process.env.DSH_SNAPSHOT === undefined ? ''zstd'' : ''none'''
- id: agent-instructions
name: '@deepseek-ai/dsh-agent-instructions'
disabled: true
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
persona: You are a concise snapshot agent working in {{cwd}}.
- id: goal
name: '@deepseek-ai/dsh-goal'
disabled: true
- id: goal-round-driver
name: '@deepseek-ai/dsh-goal-round-driver'
disabled: true
- id: command-goal
name: '@deepseek-ai/dsh-command-goal'
disabled: true
- id: tool-goal
name: '@deepseek-ai/dsh-tool-goal'
disabled: true
- id: skill
name: '@deepseek-ai/dsh-skill'
disabled: true
- id: skill-filesystem
name: '@deepseek-ai/dsh-skill-filesystem'
disabled: true
- id: tool-skill
name: '@deepseek-ai/dsh-tool-skill'
disabled: true
- id: tool-bash
name: '@deepseek-ai/dsh-tool-bash'
disabled: true
- id: tool-pwsh
name: '@deepseek-ai/dsh-tool-pwsh'
disabled: false
+25 -27
View File
@@ -1,31 +1,29 @@
# Keyless replay counterpart to web.cordis.yml: the web stack and loopback
# fixture server stay real (the tool call re-executes the actual HTTP fetch and
# markdown rendering); only the model adapter is replaced by replay.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: web-fetch-http
name: '@deepseek-ai/dsh-web-fetch-http'
- id: web-fetch-fixture
name: './web-fetch-fixture-server.mjs'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: web
name: '@deepseek-ai/dsh-web'
- id: tool-web
name: '@deepseek-ai/dsh-tool-web'
config:
path: ./cordis.yml
patches:
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
disabled: true
- insert:
- id: web
name: '@deepseek-ai/dsh-web'
- id: web-fetch-http
name: '@deepseek-ai/dsh-web-fetch-http'
- id: web-fetch-fixture
name: './web-fetch-fixture-server.mjs'
- id: tool-web
name: '@deepseek-ai/dsh-tool-web'
config:
search: false
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:
providers:
- id: deepseek-official
name: DeepSeek
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
search: false
+12 -15
View File
@@ -3,19 +3,16 @@
# the pinned header carries exactly the surface under test), and the loopback
# fixture server the scenario prompt fetches — deterministic content, no
# external network, in recording and replay alike.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
- insert:
- id: web-fetch-http
name: '@deepseek-ai/dsh-web-fetch-http'
- id: web-fetch-fixture
name: './web-fetch-fixture-server.mjs'
- id: web
name: '@deepseek-ai/dsh-web'
- id: tool-web
name: '@deepseek-ai/dsh-tool-web'
config:
path: ./cordis.yml
patches:
- insert:
- id: web
name: '@deepseek-ai/dsh-web'
- id: web-fetch-http
name: '@deepseek-ai/dsh-web-fetch-http'
- id: web-fetch-fixture
name: './web-fetch-fixture-server.mjs'
- id: tool-web
name: '@deepseek-ai/dsh-tool-web'
config:
search: false
search: false
+2 -2
View File
@@ -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/boot/app-boot/README.md
README.md: 791a0c31e0582b5494221397fbd8171508d5c12f
README.zh.md: 5cb6dcde7722c2c63f36873b6f402ec957dcb91a
README.md: 9965d6d57f4ec6cd9a93650bbd0096b059fb010b
README.zh.md: 436b19e4b2a05f4462f7636fccd3911b8ed41548
+1 -1
View File
@@ -2,7 +2,7 @@
English | [中文](README.zh.md)
Shared boot glue for the app bins ([`dsh`](../../../apps/cli/README.md) and [`dsh-acp-demo`](../../examples/acp-demo/README.md)): each bin is a thin self-executing composition over these helpers, parameterized by its diagnostic prefix, so loader-failure behavior has one owner instead of drifting between published artifacts.
Shared Loader boot glue for [`dsh`](../../../apps/cli/README.md) profiles and the [temporarily packaged Python SDK runtime](../../../python/README.md). The product launcher owns profile composition and process lifecycle; the direct-config helpers remain only for that held-back runtime until its later migration.
| Export | Role |
|---|---|
+1 -1
View File
@@ -2,7 +2,7 @@
[English](README.md) | 中文
app bin[`dsh`](../../../apps/cli/README.zh.md) 与 [`dsh-acp-demo`](../../examples/acp-demo/README.zh.md)共用的启动粘合层:每个 bin 都是在这些辅助函数之上构建的精简自执行组合,并以自身诊断前缀参数化。这样,Loader 故障行为只由一处负责,不会在已发布产物之间逐渐分化
供 [`dsh`](../../../apps/cli/README.zh.md) profile 与[暂时打包的 Python SDK runtime](../../../python/README.zh.md) 共用的 Loader 启动粘合层。产品启动器负责 profile 组合与进程生命周期;直接配置 helper 只为暂缓迁移的 runtime 保留,直至后续迁移
| 导出 | 职责 |
|---|---|
+1 -1
View File
@@ -1,5 +1,5 @@
/**
* Shared boot glue for the app bins (`dsh`, `dsh-acp-demo`): load the gitignored
* Shared boot glue for `dsh` profiles and the temporarily packaged Python SDK runtime: load the gitignored
* `.env`, install the fail-loud Loader guards, resolve the config path (snapshot-aware), load the
* optional user patch layers from the Harness home (`~/.dsh`), expose its path resolver to
* config expressions, and drive the Cordis Loader against a leaf `cordis.yml` until the tree settles.
+2 -2
View File
@@ -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/bundle/acp-app/README.md
README.md: 5c0910dcdef2ddffe67aef29e14db371272238ee
README.zh.md: 7a70a1b34b1355095884a024b8192f6b10453143
README.md: 15890b8d13446613bbddc1b764290470abf28d1a
README.zh.md: 5bf85d224ee07d8fa013f7cd0dd67a67a8d70dbf
+7 -1
View File
@@ -4,10 +4,16 @@ English | [中文](README.zh.md)
The automation-only ACP stdio application as a `dsh` profile bundle over [`dsh-base`](../base/README.md). Its patch sets the coding-agent persona and default model route, disables module HMR, mounts an app-owned zero-option command provider, and starts [`dsh-acp`](../../acp/acp/README.md) only after that provider accepts the invocation. `dsh --profile acp --help` therefore writes help and exits without claiming stdin or stdout.
The startup provider binds stdin EOF to the launcher's bounded successful shutdown. ACP connection close, SIGINT, and SIGTERM drain the bridge-owned agents and the root profile tree before exit. Stdout is reserved for newline-delimited ACP JSON-RPC frames. A deployment selects a different complete composition through profile bundles and patch files, not another app bin.
The startup provider binds stdin EOF to the launcher's bounded successful shutdown. ACP connection close, SIGINT, and SIGTERM drain the bridge-owned agents and the root profile tree before exit. Stdout is reserved for newline-delimited ACP JSON-RPC frames. The bundle disables model-generated session titles because ACP exposes no title surface; deterministic fallback titles remain durable without an auxiliary model request. A deployment selects a different complete composition through profile bundles and patch files, not another app bin.
The shipped row creates sessions with `deepseek-official` and `deepseek-v4-flash`; a later patch can replace that row's complete config. The base profile owns adapters, tools, persistence, policy, settings, credentials, and the per-session workspace supplied by the ACP client.
## Standard automation workflow
An ACP v1 SDK client initializes `dsh --profile acp`, creates a session with an absolute `cwd` and optional standard stdio/HTTP MCP declarations, chooses an advertised `model` or `reasoning_effort`, prompts while observing standard semantic updates, then calls `session/close`. Another process can use `session/list` and `session/resume` against the same profile persistence root; resume reconnects the MCP declarations supplied by that request and does not replay history.
The complete supported method matrix, MCP trust model, update mapping, and stop reasons live in the [`dsh-acp` protocol contract](../../acp/acp/README.md#standard-acp-v1-surface). This profile adds no private method, capability, `_meta`, environment variable, or transport field. The keyless control-surface conformance test drives the real profile through the public ACP SDK.
## Model Experience
### ACP coding-agent persona
+7 -1
View File
@@ -4,10 +4,16 @@
以 [`dsh-base`](../base/README.zh.md) 为基础的 automation-only ACP stdio 应用 `dsh` profile 组合包。其 patch 设置 coding agent(编程智能体)persona 与默认模型路由、禁用模块 HMR(热模块替换)、挂载应用自有的零选项命令提供方,并且只在该提供方接受调用后启动 [`dsh-acp`](../../acp/acp/README.zh.md)。因此,`dsh --profile acp --help` 会写出 help 并退出,不会占用 stdin 或 stdout。
启动提供方把 stdin EOF 绑定到启动器的有界成功关闭。ACP 连接关闭、SIGINT 与 SIGTERM 会在退出前排空 bridge 自有 agent 以及根 profile 树。Stdout 仅保留给换行分隔的 ACP JSON-RPC frame。部署方通过 profile 组合包与 patch 文件选择另一套完整组合,而不是使用另一个 app bin。
启动提供方把 stdin EOF 绑定到启动器的有界成功关闭。ACP 连接关闭、SIGINT 与 SIGTERM 会在退出前排空 bridge 自有 agent 以及根 profile 树。Stdout 仅保留给换行分隔的 ACP JSON-RPC frame。ACP 不提供 title 表层,因此本组合包禁用模型生成的 session title;确定性的 fallback title 仍会持久化,但不发起辅助模型请求。部署方通过 profile 组合包与 patch 文件选择另一套完整组合,而不是使用另一个 app bin。
随附配置项使用 `deepseek-official``deepseek-v4-flash` 创建 session;后续 patch 可以替换该配置项的完整 config。base profile 负责适配器、工具、持久化、策略、settings 与 credentialsACP client 为每个 session 提供工作区。
## 标准自动化工作流
ACP v1 SDK 客户端先初始化 `dsh --profile acp`,再用绝对 `cwd` 与可选的标准 stdioHTTP MCP 声明创建 session,选择公开的 `model``reasoning_effort`,在观察标准语义更新的同时提交提示词,最后调用 `session/close`。另一个进程可以针对同一个 profile 持久化根目录使用 `session/list``session/resume`;resume 会重新连接该请求提供的 MCP 声明,但不会重放历史。
完整的受支持方法矩阵、MCP 信任模型、更新映射与停止原因见 [`dsh-acp` 协议约定](../../acp/acp/README.zh.md#standard-acp-v1-surface)。该 profile 不增加私有方法、能力、`_meta`、环境变量或传输字段。免密钥控制面一致性测试通过公开 ACP SDK 驱动真实 profile。
## 模型体验
### ACP coding-agent persona
+3
View File
@@ -8,6 +8,9 @@
- id: hmr
disabled: true
- id: session-title-llm
disabled: true
- insert:
- id: acp-app-startup
name: '@deepseek-ai/dsh-acp-app'
@@ -25,6 +25,7 @@ describe('dsh-acp-app bundle', () => {
insert?: Array<{ config?: { model?: string; provider?: string }; id?: string; inject?: string[]; name?: string }>
}>
expect(patches.find(patch => patch.id === 'hmr')).toMatchObject({ disabled: true })
expect(patches.find(patch => patch.id === 'session-title-llm')).toMatchObject({ disabled: true })
const rows = patches.flatMap(patch => patch.insert ?? [])
expect(rows.find(row => row.id === 'acp-app-startup')?.name).toBe('@deepseek-ai/dsh-acp-app')
expect(rows.find(row => row.id === 'acp')).toMatchObject({
@@ -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/acp-demo/README.md
README.md: dea2831d372e0075cee7e948ee7abd185e27cf6c
README.zh.md: a1493ec1ded67cd8f936e76c4db0bfde9a0a7d42
-65
View File
@@ -1,65 +0,0 @@
# @deepseek-ai/dsh-acp-demo
English | [中文](README.zh.md)
ACP automation server app: the default agent spine, client-created agents through [`@deepseek-ai/dsh-acp`](../../acp/acp/README.md), JSONL persistence, and semantic checkpointing behind one JSON-RPC stdio bin. Programmatic clients create, list, close, and resume sessions; this package mounts no human UI.
## Composition
| Plugin | Role |
|---|---|
| `@deepseek-ai/dsh-agent-spine-demo` | Providerless agent spine with no pre-created agents; `session/new` creates each agent. |
| `@deepseek-ai/dsh-session-persistence-jsonl` | Durable session logs used by checkpointing, observability, and snapshot replay. |
| `@deepseek-ai/dsh-session-checkpoint-policy` | Durability barriers before model calls and top-level tool effects, plus completed-step checkpoints. |
| `@deepseek-ai/dsh-session-query-sqlite` | Derived exact/FTS session-query service, opened before the ACP transport so leaf consumers are ready for the first model request. |
| `@deepseek-ai/dsh-acp` | Automation-only ACP transport over stdin/stdout. |
The app does not install commands, user interaction, session navigation, configuration pickers, or a stdout logger. It owns these plugins through one ordered effect so the query service is ready before ACP accepts work and ACP sessions quiesce before checkpointing and persistence detach. Leaf configurations supply LLM, executor, sandbox, approval, filesystem, and model-facing tool plugins.
## Config
| Key | Default | Routed to |
|---|---|---|
| `provider` | required | Provider route for each ACP-created agent. |
| `model` | required | Model for each ACP-created agent. |
| `maxParallelToolCalls` | agent-loop default | Positive-integer tool-call concurrency cap; `1` is serial. |
| `persona` | — | Deployment persona template for `dsh-system-prompt`. |
| `toolOrder` | lexicographic | Explicit model-facing tool order for `dsh-system-prompt`. |
| `tools` | `{ mode: 'native' }` | Native, Code Mode, or combined model tool transport. |
| `dshHome` | `$DSH_HOME` or `~/.dsh` | Harness home shared by bash and local skill discovery. |
| `sessionTitle` | spine example limits | Durable fallback-title limits; titles remain off the ACP wire. |
| `persistenceRoot` | `./.sessions` | JSONL backend root and parent directory of the derived `session-query.db` index. |
| `packChunks` | `true` | Pack consecutive delta-chunk events in storage. |
| `persistenceCompression` | `zstd` | Checksummed Zstandard frames or raw `none`. |
| `workspaceContext` | required | Workspace-instruction byte budget/config, or `false`. |
| `skills` | owner defaults | Skill registry, local provider, and model-facing skill tool. |
| `toolBash` | owner defaults | Model-facing bash tool config. |
| `jobs` | `{ maxConcurrentJobsPerOwner: 10 }` | Process-local per-owner active-task admission. |
| `toolJobs` | owner defaults | Generic background-job control config, or `false`. |
| `goals` | owner defaults | Persisted same-session goal domain and model tools, or `false`. |
The shipped [`examples/acp-agent/cordis.yml`](../../../examples/acp-agent/cordis.yml) adds the DeepSeek adapter, sandboxed bash and filesystem providers, one-shot approval policy, compaction, subagents, workflows, hooks, and model-facing tools. The app supplies the derived session-query index, while the model-facing query consumer remains an explicit leaf opt-in. Snapshot overlays replace only nondeterministic providers or policy values.
## Bin
`dsh-acp-demo [--config path-to-cordis.yml]` (short form `-c`; default `./cordis.yml`) loads the gitignored `.env`, except in replay mode; `DSH_SNAPSHOT=replay` selects the sibling `cordis.snapshot.yml`; stdin EOF disposes the context and flushes sessions before exit. Loader's installed optional `node-addon-require-builtin` peer resolves bare plugin specifiers for the built bin under plain Node. Diagnostics use stderr because stdout is the ACP wire.
## Standard automation workflow
An ACP v1 SDK client initializes the bin, creates a session with an absolute `cwd` and optional standard stdio/HTTP MCP declarations, chooses an advertised `model` or `reasoning_effort`, prompts and observes semantic standard updates, then calls `session/close`. A later process can use `session/list` and `session/resume` against the same `persistenceRoot`; resume reconnects the MCP declarations supplied by that request and does not replay history.
The complete supported/unsupported method matrix, MCP trust model, update mapping, and stop reasons live in the [`dsh-acp` protocol contract](../../acp/acp/README.md#standard-acp-v1-surface). The demo adds no private method, capability, `_meta`, environment variable, or transport field. The keyless control-surface conformance test drives this exact bin through the public ACP SDK.
## Model Experience
Indirectly, through `dsh-agent-spine-demo` and the leaf's model-facing plugins. ACP prompt text becomes the ordinary logged user message; protocol metadata and permission choices do not enter the model request.
#### KV Cache effect
Append-only per session; the app adds no request-prefix content itself.
## Known Limitations and Deferred Work
- **JSONL persistence is fixed** — a different backend requires another composition.
- **Sibling plugins can corrupt stdout** — the app cannot prevent another entry from writing non-protocol bytes.
- **Automation only** — session controls and semantic execution updates are protocol data, not a human UI; human interaction remains in other entry points.
-65
View File
@@ -1,65 +0,0 @@
# @deepseek-ai/dsh-acp-demo
[English](README.md) | 中文
ACPAgent Client Protocol)自动化服务器应用:默认 agent(智能体)主干、客户端通过 [`@deepseek-ai/dsh-acp`](../../acp/acp/README.zh.md) 创建的 agent、JSONL 持久化,以及语义检查点机制,并通过一个 JSON-RPC stdio bin 对外提供服务。程序化客户端可以创建、列出、关闭和恢复会话;此包不挂载人工交互 UI。
## 组合
| 插件 | 角色 |
|---|---|
| `@deepseek-ai/dsh-agent-spine-demo` | 不含提供方且不预创建 agent 的 agent 主干;`session/new` 创建每个 agent。 |
| `@deepseek-ai/dsh-session-persistence-jsonl` | 检查点、可观测性和快照回放所使用的持久会话日志。 |
| `@deepseek-ai/dsh-session-checkpoint-policy` | 在模型调用和顶层工具 effect 前建立持久性屏障,并为已完成步骤建立检查点。 |
| `@deepseek-ai/dsh-session-query-sqlite` | 派生的精确/FTS 会话查询服务;先于 ACP 传输打开,使叶节点消费方在首次模型请求前就绪。 |
| `@deepseek-ai/dsh-acp` | 通过 stdinstdout 提供的纯自动化 ACP 传输。 |
应用不安装命令、用户交互、会话导航、配置选择器或 stdout logger。它通过一个有序 effect 拥有这些插件,因此查询服务会在 ACP 接受工作前就绪,而 ACP 会话会在检查点与持久化插件卸载前完全停稳。叶节点配置负责提供 LLM(大语言模型)、执行器、沙箱、审批、文件系统和面向模型的工具插件。
## 配置
| 键 | 默认值 | 路由目标 |
|---|---|---|
| `provider` | 必填 | 每个由 ACP 创建的 agent 所用的提供方路由。 |
| `model` | 必填 | 每个由 ACP 创建的 agent 所用的模型。 |
| `maxParallelToolCalls` | agent loop(智能体循环)默认值 | 正整数工具调用并发上限;`1` 表示串行。 |
| `persona` | 无 | 供 `dsh-system-prompt` 使用的部署 persona 模板。 |
| `toolOrder` | 字典序 | 供 `dsh-system-prompt` 使用的显式面向模型工具顺序。 |
| `tools` | `{ mode: 'native' }` | Native、Code Mode 或组合式模型工具传输。 |
| `dshHome` | `$DSH_HOME``~/.dsh` | bash 与本地 skill(技能)发现共享的 harness 主目录。 |
| `sessionTitle` | 主干示例限制 | 持久后备标题限制;标题仍不会进入 ACP wire。 |
| `persistenceRoot` | `./.sessions` | JSONL 后端根目录,以及派生 `session-query.db` 索引的父目录。 |
| `packChunks` | `true` | 在存储中打包连续的增量分片事件。 |
| `persistenceCompression` | `zstd` | 带校验和的 Zstandard 帧,或原始 `none`。 |
| `workspaceContext` | 必填 | 工作区指令字节预算/配置,或 `false`。 |
| `skills` | 拥有者默认值 | skill 注册表、本地提供方和面向模型的 skill 工具。 |
| `toolBash` | 拥有者默认值 | 面向模型的 bash 工具配置。 |
| `jobs` | `{ maxConcurrentJobsPerOwner: 10 }` | 进程内按 owner 限制活动任务的准入配置。 |
| `toolJobs` | 拥有者默认值 | 通用后台任务控制配置,或 `false`。 |
| `goals` | 拥有者默认值 | 持久化的同会话目标领域与模型工具,或 `false`。 |
已交付的 [`examples/acp-agent/cordis.yml`](../../../examples/acp-agent/cordis.yml) 添加 DeepSeek 适配器、沙箱化 bash 与文件系统提供方、一次性审批策略、压缩(compaction)、subagent、工作流、钩子,以及面向模型的工具。应用提供派生会话查询索引,而面向模型的查询消费方仍由叶节点显式选用。快照 overlay 只替换非确定性提供方或策略值。
## Bin
`dsh-acp-demo [--config path-to-cordis.yml]`(短形式 `-c`;默认为 `./cordis.yml`)会加载 gitignore 排除的 `.env`,回放模式除外;`DSH_SNAPSHOT=replay` 选择同级 `cordis.snapshot.yml`stdin EOF 会在退出前 dispose(资源释放)上下文并刷新会话。Loader 已安装的可选对等依赖(peer dependency`node-addon-require-builtin` 使纯 Node 下构建后的 bin 可以解析裸插件说明符。诊断使用 stderr,因为 stdout 是 ACP wire。
## 标准自动化工作流
ACP v1 SDK 客户端先初始化 bin,再使用绝对 `cwd` 和可选标准 stdio/HTTP MCP 声明创建会话,选择已公布的 `model``reasoning_effort`,发送提示词并观察标准语义更新,最后调用 `session/close`。后续进程可以针对同一个 `persistenceRoot` 使用 `session/list``session/resume`;恢复会重新连接该请求提供的 MCP 声明,并且不会重放历史。
完整的支持/不支持方法矩阵、MCP 信任模型、更新映射和 stop reason 位于 [`dsh-acp` 协议约定](../../acp/acp/README.zh.md#standard-acp-v1-surface)。Demo 不增加私有方法、能力、`_meta`、环境变量或传输字段。Keyless control-surface conformance 测试只通过公开 ACP SDK 驱动这个确切 bin。
## 模型体验
模型体验由 `dsh-agent-spine-demo` 和叶节点的面向模型插件间接提供。ACP 提示词文本会成为普通的已记录用户消息;协议元数据与权限选择不会进入模型请求。
#### KV Cache 影响
每个会话仅追加;应用本身不添加请求前缀内容。
## 已知限制与暂缓事项
- **JSONL 持久化固定不变**:使用其他后端需要另一种组合。
- **同级插件可能破坏 stdout**:应用无法阻止另一个 Cordis 配置项写入非协议字节。
- **仅面向自动化**:会话控制和语义执行更新是协议数据,不是人工 UI;人工交互仍属于其他运行入口。
-79
View File
@@ -1,79 +0,0 @@
{
"name": "@deepseek-ai/dsh-acp-demo",
"description": "ACP automation server app: agent spine + JSONL persistence + ACP transport, with a JSON-RPC stdio bin",
"version": "0.1.1-rc.2",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
"directory": "packages/examples/acp-demo"
},
"type": "module",
"main": "lib/index.js",
"types": "lib/types/index.d.ts",
"bin": {
"dsh-acp-demo": "lib/bin.js"
},
"exports": {
".": {
"types": "./lib/types/index.d.ts",
"default": "./lib/index.js"
},
"./invariant": {
"types": "./lib/types/invariant.d.ts",
"default": "./lib/invariant.js"
},
"./bin": {
"types": "./lib/types/bin.d.ts",
"default": "./lib/bin.js"
},
"./src/*": "./src/*",
"./package.json": "./package.json"
},
"files": [
"lib/index.js",
"lib/invariant.js",
"lib/bin.js",
"lib/types/**/*.d.ts"
],
"license": "MIT",
"peerDependencies": {
"@deepseek-ai/cordis-plugin-include": "workspace:^",
"@deepseek-ai/cordis-plugin-loader": "workspace:^",
"@deepseek-ai/dsh-acp": "workspace:^",
"@deepseek-ai/dsh-agent-spine-demo": "workspace:^",
"@deepseek-ai/dsh-app-boot": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-session-checkpoint-policy": "workspace:^",
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^",
"@deepseek-ai/dsh-session-query": "workspace:^",
"@deepseek-ai/dsh-session-query-sqlite": "workspace:^",
"@deepseek-ai/dsh-tools": "workspace:^",
"@deepseek-ai/dsh-agent-instructions": "workspace:^",
"@deepseek-ai/cordis": "workspace:^",
"@deepseek-ai/schemastery": "workspace:^"
},
"devDependencies": {
"@agentclientprotocol/sdk": "1.4.0",
"@deepseek-ai/cordis-plugin-include": "workspace:^",
"@deepseek-ai/cordis-plugin-loader": "workspace:^",
"@deepseek-ai/dsh-acp": "workspace:^",
"@deepseek-ai/dsh-acp-snapshot": "workspace:^",
"@deepseek-ai/dsh-agent": "workspace:^",
"@deepseek-ai/dsh-agent-spine-demo": "workspace:^",
"@deepseek-ai/dsh-app-boot": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-llm": "workspace:^",
"@deepseek-ai/dsh-session-checkpoint-policy": "workspace:^",
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:^",
"@deepseek-ai/dsh-session-query": "workspace:^",
"@deepseek-ai/dsh-session-query-sqlite": "workspace:^",
"@deepseek-ai/dsh-system-prompt": "workspace:^",
"@deepseek-ai/dsh-tools": "workspace:^",
"@deepseek-ai/dsh-agent-instructions": "workspace:^",
"@deepseek-ai/cordis": "workspace:^",
"@deepseek-ai/schemastery": "workspace:^"
}
}
-35
View File
@@ -1,35 +0,0 @@
#!/usr/bin/env node
/**
* Boot an ACP stdio server from `cordis.yml`; usage is
* `dsh-acp-demo [--config path]`, defaulting to `./cordis.yml`. Shared env
* loading, Loader guards, snapshot config selection, and settled-tree boot live
* in dsh-app-boot. Replay skips `.env` and selects sibling
* `cordis.snapshot.yml` so a stray key cannot trigger a model call. EOF disposes
* and flushes snapshot runs; the calling automation owns process lifetime. Stdout is
* reserved for JSON-RPC, so diagnostics go only to stderr.
* @module @deepseek-ai/dsh-acp-demo/bin
*/
import { parseArgs } from 'node:util'
import { boot, installFailLoud, loadEnv, resolveConfigPath } from '@deepseek-ai/dsh-app-boot'
const NAME = 'dsh-acp-demo'
/* v8 ignore start -- thin self-executing composition over the unit-tested
dsh-app-boot helpers; exercised end-to-end by the snapshot suite and the
built-bin smoke */
installFailLoud(NAME)
const snapshotMode = process.env['DSH_SNAPSHOT']
if (snapshotMode !== 'replay') loadEnv(NAME)
const { values } = parseArgs({
args: process.argv.slice(2),
options: { config: { type: 'string', short: 'c' } },
strict: true,
})
const ctx = await boot(NAME, resolveConfigPath(values.config ?? './cordis.yml', snapshotMode))
if (snapshotMode !== undefined) {
process.stdin.on('end', () => {
void ctx.fiber.dispose().then(() => { process.exit(0) })
})
}
/* v8 ignore stop */
-141
View File
@@ -1,141 +0,0 @@
/**
* The ACP automation server app: the default agent spine
* ({@link @deepseek-ai/dsh-agent-spine-demo}), JSONL session persistence, and
* the {@link @deepseek-ai/dsh-acp} bridge. The app owns those plugins through one
* ordered lifecycle so ACP sessions quiesce before persistence detaches. It
* writes nothing to stdout.
* It pre-creates no agents and leaves adapters, executors, and optional tools to
* the leaf, which must likewise avoid stdout loggers. Named exports are
* required so Loader retains this plugin's `Config` schema (see
* docs/postmortem/0001).
* @module @deepseek-ai/dsh-acp-demo
*/
import type { Context } from '@deepseek-ai/cordis'
import { join } from 'node:path'
import z from '@deepseek-ai/schemastery'
import * as acp from '@deepseek-ai/dsh-acp'
import * as agentCore from '@deepseek-ai/dsh-agent-spine-demo'
import * as workspaceContext from '@deepseek-ai/dsh-agent-instructions'
import ToolRuntime, { type Config as ToolsConfig } from '@deepseek-ai/dsh-tools'
import JsonlSessionPersistence, {
JsonlCompressionSchema,
type JsonlCompression,
} from '@deepseek-ai/dsh-session-persistence-jsonl'
import * as sessionCheckpointPolicy from '@deepseek-ai/dsh-session-checkpoint-policy'
import SqliteSessionQueryEngine from '@deepseek-ai/dsh-session-query-sqlite'
export const name = 'acp-demo'
const DEFAULT_PERSISTENCE_ROOT = './.sessions'
/**
* App config: the swappable per-deployment values. `provider` and `model` configure
* each agent the ACP bridge creates at `session/new`; `persona` is the
* deployment persona (forwarded to the system-prompt plugin); `toolOrder` is
* the explicit model-facing tool order (forwarded to the system-prompt plugin);
* `tools` is the tool registry's config (its presentation `mode`, forwarded
* through agent-spine-demo); `persistenceRoot` is the JSONL backend's directory.
*/
export interface Config {
/** Provider route for ACP-created agents. */
provider: string
/** Model name for ACP-created agents (must have a registered adapter). */
model: string
/** Bundled agent-loop concurrency cap; `1` is serial and omission uses its default. */
maxParallelToolCalls?: number
/** Deployment persona (the system-prompt plugin's `persona` config). */
persona?: string
/** Explicit model-facing tool order (the system-prompt plugin's `toolOrder` config; see dsh-system-prompt). */
toolOrder?: string[]
/** Tool-registry config — its presentation `mode` (forwarded through agent-spine-demo; see dsh-tools). */
tools?: ToolsConfig
/** DeepSeek Harness home directory exposed to bash and used for local skill discovery. */
dshHome?: string
/** Fallback session-title limits forwarded through agent-spine-demo. */
sessionTitle?: NonNullable<agentCore.Config['sessionTitle']>
/** Directory for JSONL sessions and the derived query index. Defaults to `./.sessions`. */
persistenceRoot?: string
/** Write delta-chunk runs as packed storage rows (the JSONL backend's `packChunks`). Defaults to `true`. */
packChunks?: boolean
/** JSONL artifact encoding; defaults to checksummed Zstandard frames. */
persistenceCompression?: JsonlCompression
/** Controls automatic AGENTS.md/CLAUDE.md loading; configure a byte budget or set `false`. */
workspaceContext: agentCore.Config['workspaceContext']
/** Skill registry, local-provider, and model-facing consumer config forwarded to agent-spine-demo. */
skills?: agentCore.SkillConfig
/** Model-facing bash tool config forwarded through agent-core. */
toolBash?: NonNullable<agentCore.Config['toolBash']>
/** Process-local background-job admission config forwarded through agent-core. */
jobs?: NonNullable<agentCore.Config['jobs']>
/** Generic background-job controls forwarded through agent-core; set false to omit their tools. */
toolJobs?: NonNullable<agentCore.Config['toolJobs']>
/** Persisted same-session goals; owner defaults enable them, or false disables the stack and tools. */
goals?: agentCore.GoalConfig | false
}
// Each entry point owns a complete, directly readable config schema; extracting
// the common fields would make two small app contracts depend on a new facade.
/* jscpd:ignore-start */
export const Config: z<Config> = z.object({
provider: z.string().required(),
model: z.string().required(),
maxParallelToolCalls: z.number().step(1).min(1),
persona: z.string(),
// The array default is forced to undefined: ABSENT means "lexicographic
// order" (the owning dsh-system-prompt schema does the same), while
// schemastery's native [] default would read as an invalid configured list.
toolOrder: z.array(z.string()).default(undefined as unknown as string[]),
tools: ToolRuntime.Config,
dshHome: z.string(),
sessionTitle: agentCore.SessionTitleConfigSchema,
persistenceRoot: z.string().default(DEFAULT_PERSISTENCE_ROOT),
packChunks: z.boolean().default(true),
persistenceCompression: JsonlCompressionSchema,
workspaceContext: z.union([z.const(false), workspaceContext.Config]).required(),
skills: agentCore.SkillConfigSchema,
toolBash: agentCore.ToolBashConfigSchema,
jobs: agentCore.JobsConfigSchema,
toolJobs: z.union([z.const(false), agentCore.ToolJobsConfigSchema]),
goals: z.union([z.const(false), agentCore.GoalConfigSchema]),
})
/* jscpd:ignore-end */
/**
* Compose the spine with the ACP automation transport. The agent-spine-demo bundle pre-creates
* NO agents (its `agents` list defaults to `[]`) and carries the deployment
* `persona`; the JSONL backend and derived query index persist under
* `persistenceRoot`; the ACP bridge owns stdout for JSON-RPC and creates one
* agent per `session/new` from the provider/model pair. The composite effect
* unloads in reverse order, keeping checkpoint and persistence listeners
* attached until ACP agents have flushed their closing events. No logger, no
* `hmr` — stdout stays pure.
*/
export async function apply(ctx: Context, config: Config): Promise<void> {
const goals = config.goals ?? {}
const persistenceRoot = config.persistenceRoot ?? DEFAULT_PERSISTENCE_ROOT
await ctx.effect(async function* () {
const spine = ctx.plugin(agentCore, { ...agentCore.pickSpineConfig(config), goals })
await spine
yield spine.dispose
// Same rationale as the Config schema above: each entry point forwards its own
// persistence passthroughs rather than sharing a facade with stdio-demo.
/* jscpd:ignore-start */
const persistence = ctx.plugin(JsonlSessionPersistence, {
root: persistenceRoot,
...config.packChunks !== undefined ? { packChunks: config.packChunks } : {},
...(config.persistenceCompression === undefined ? {} : { compression: config.persistenceCompression }),
})
await persistence
yield persistence.dispose
/* jscpd:ignore-end */
const checkpoint = ctx.plugin(sessionCheckpointPolicy)
await checkpoint
yield checkpoint.dispose
const query = ctx.plugin(SqliteSessionQueryEngine, { path: join(persistenceRoot, 'session-query.db') })
await query
yield query.dispose
const transport = ctx.plugin(acp, { provider: config.provider, model: config.model })
await transport
yield transport.dispose
}, 'acp-demo.composition')
}
@@ -1,30 +0,0 @@
/**
* Package-owned invariant companion for `@deepseek-ai/dsh-acp-demo`.
* @module @deepseek-ai/dsh-acp-demo/invariant
*/
/* jscpd:ignore-start */
import type { Context } from '@deepseek-ai/cordis'
import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants'
const PACKAGE_NAME = '@deepseek-ai/dsh-acp-demo'
/** Cordis companion plugin name. */
export const name = 'acp-demo-invariant'
/** Service required before the companion can reserve package ownership. */
export const inject = ['invariants']
/**
* No runtime invariant: this composition package owns no independent event stream or mutable data;
* Loader and built-entry tests cover its wiring.
*/
const install: InvariantInstaller = () => {}
/**
* Register this package's invariant companion.
* @param ctx - Cordis context carrying the invariant service.
* @returns the installed registration's disposer after setup succeeds.
*/
export const apply = (ctx: Context): Promise<() => void> =>
Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install))
/* jscpd:ignore-end */
@@ -1,277 +0,0 @@
import { describe, expect, it } from 'vitest'
import { randomUUID } from 'node:crypto'
import { mkdtemp } from 'node:fs/promises'
import { join } from 'node:path'
import { tmpdir } from 'node:os'
import { Context } from '@deepseek-ai/cordis'
import Loader from '@deepseek-ai/cordis-plugin-loader'
import { agentEvents } from '@deepseek-ai/dsh-agent'
import { TOOL_ORDER_REST } from '@deepseek-ai/dsh-system-prompt'
import type { Message } from '@deepseek-ai/dsh-llm'
import { SessionId } from '@deepseek-ai/dsh-session'
import * as acpAgent from '../src/index.ts'
/**
* In-process unit coverage for the @deepseek-ai/dsh-acp-demo composition:
* mounting it brings up the agent-spine-demo spine + JSONL persistence + the ACP
* bridge in one `ctx.plugin`. It loads no Loader-only plugin (no hmr), so it
* mounts in a plain Context.
*
* The REAL Loader-path guard (export shape via `unwrapExports`, the headline
* ACP operations end-to-end) is the keyless bin smoke in `load-path.e2e.ts`;
* this spec asserts the composition and the persistenceRoot default branch.
*/
async function mount(config: acpAgent.Config, withBash = false): Promise<Context> {
const ctx = new Context()
if (withBash) {
ctx.provide('shell', {
sandboxMode: undefined,
resolve() { throw new Error('composition test does not execute bash') },
run() { throw new Error('composition test does not execute bash') },
start() { throw new Error('composition test does not execute bash') },
})
}
config.persistenceRoot ??= await mkdtemp(join(tmpdir(), 'dsh-acp-demo-persistence-'))
await ctx.plugin(acpAgent, config)
return ctx
}
async function isolatedSkillsConfig(catalogDescriptionMaxLength?: number): Promise<NonNullable<acpAgent.Config['skills']>> {
const home = await mkdtemp(join(tmpdir(), 'dsh-acp-demo-skills-'))
return {
filesystem: { dshHome: join(home, '.dsh'), agentsHome: join(home, '.agents') },
...catalogDescriptionMaxLength !== undefined ? { tool: { catalogDescriptionMaxLength } } : {},
}
}
async function composePrefix(ctx: Context): Promise<Message[]> {
const agent = ctx.agentLoop.create(SessionId(`acp-demo-prefix-${randomUUID()}`), {}, { cwd: '/tmp' })
const signal = new AbortController().signal
const decision = await agentEvents(ctx, agent).waterfall(
'agent/pre-step', { messages: [], turn: 1, step: 1, signal },
() => Promise.resolve({ kind: 'enter', messages: [] }),
)
if (decision.kind === 'enter') {
for (const message of decision.messages) {
agent.session.append('user/message', message, { surfaceOp: 'append' })
}
}
return agent.session.deriveMessages()
}
async function withIsolatedSkillHomes<T>(run: () => Promise<T>): Promise<T> {
const oldDshHome = process.env.DSH_HOME
const oldAgentsHome = process.env.DSH_AGENTS_HOME
const home = await mkdtemp(join(tmpdir(), 'dsh-acp-demo-default-skills-'))
process.env.DSH_HOME = join(home, '.dsh')
process.env.DSH_AGENTS_HOME = join(home, '.agents')
try {
return await run()
} finally {
if (oldDshHome === undefined) {
delete process.env.DSH_HOME
} else {
process.env.DSH_HOME = oldDshHome
}
if (oldAgentsHome === undefined) {
delete process.env.DSH_AGENTS_HOME
} else {
process.env.DSH_AGENTS_HOME = oldAgentsHome
}
}
}
describe('dsh-acp-demo composition', () => {
it('brings up the spine + persistence + the ACP bridge', async () => {
const ctx = await mount({
provider: 'mock',
model: 'mock',
persona: 'hi',
persistenceRoot: await mkdtemp(join(tmpdir(), 'dsh-acp-demo-test-')),
persistenceCompression: 'none',
skills: await isolatedSkillsConfig(),
workspaceContext: false,
})
expect(ctx.get('agents')).toBeDefined()
expect(ctx.get('sessions')).toBeDefined()
expect(ctx.get('sessionPersistence')).toBeDefined()
expect(ctx.get('sessionQuery')).toBeDefined()
expect(ctx.get('sessionReferenceResolver')).toBeUndefined()
expect((ctx.get('sessionPersistence') as unknown as { config: { compression?: string } }).config.compression).toBe('none')
expect(ctx.get('agentLoop')).toBeDefined()
expect(ctx.get('userQuestions')).toBeUndefined()
expect(ctx.get('commands')).toBeUndefined()
expect(ctx.get('tools')?.get('ask_user_question')).toBeUndefined()
expect(ctx.get('goals')).toBeDefined()
expect(ctx.get('tools')?.get('get_goal')).toBeDefined()
// No pre-created agents — ACP session/new creates them on demand.
expect(ctx.get('agents')!.list()).toHaveLength(0)
await ctx.fiber.dispose()
})
it('can explicitly omit the persisted-goal stack', async () => {
const ctx = await mount({
provider: 'mock',
model: 'mock',
goals: false,
workspaceContext: false,
})
expect(ctx.get('goals')).toBeUndefined()
expect(ctx.get('tools')?.get('get_goal')).toBeUndefined()
await ctx.fiber.dispose()
})
it('defaults the persistence root when omitted', async () => {
// Exercises the `DEFAULT_PERSISTENCE_ROOT` fallback for a direct-apply caller that
// bypasses the schema's `.default(...)`: call `apply` directly (not via
// `ctx.plugin`, which validates+defaults the config first) with no
// persistenceRoot, so the runtime fallback is the one that fires.
const ctx = new Context()
// No persona: covers the omitted-persona forwarding branch too.
await acpAgent.apply(ctx, {
provider: 'mock',
model: 'mock',
skills: await isolatedSkillsConfig(),
workspaceContext: false,
})
expect(ctx.get('sessionPersistence')).toBeDefined()
await ctx.fiber.dispose()
})
it('forwards explicit project-instruction controls to the bundled spine', async () => {
const ctx = await mount({
provider: 'mock',
model: 'mock',
persona: 'hi',
persistenceRoot: await mkdtemp(join(tmpdir(), 'dsh-acp-demo-workspace-context-')),
workspaceContext: false,
})
expect(ctx.get('agents')).toBeDefined()
expect(ctx.get('agentLoop')).toBeDefined()
await ctx.fiber.dispose()
})
it('uses default skill config when apply is called directly without skills', async () => {
await withIsolatedSkillHomes(async () => {
const ctx = new Context()
await acpAgent.apply(ctx, { provider: 'mock', model: 'mock', workspaceContext: false })
expect(ctx.skills).toBeDefined()
expect(await ctx.skills.list()).toEqual([])
await ctx.fiber.dispose()
})
})
it('forwards skill config and dshHome into agent-spine-demo', async () => {
const skills = await isolatedSkillsConfig(6)
const ctx = await mount({ provider: 'mock', model: 'mock', persona: 'hi', dshHome: skills.filesystem!.dshHome!, skills, workspaceContext: false })
ctx.skills.register({ name: 'acp-skill', description: 'ACP skill', source: 'runtime', content: 'body' })
expect(JSON.stringify(await composePrefix(ctx))).toContain('- `acp-skill`: ACP...')
await ctx.fiber.dispose()
})
it('forwards maxParallelToolCalls to the bundled agent loop', async () => {
const ctx = await mount({
provider: 'mock',
model: 'mock',
maxParallelToolCalls: 3,
persistenceRoot: await mkdtemp(join(tmpdir(), 'dsh-acp-demo-test-parallel-')),
skills: await isolatedSkillsConfig(),
workspaceContext: false,
})
expect(ctx.get('agentLoop')?.config.maxParallelToolCalls).toBe(3)
await ctx.fiber.dispose()
})
it('forwards task admission config to the bundled task provider', async () => {
const ctx = await mount({
provider: 'mock',
model: 'mock',
jobs: { maxConcurrentJobsPerOwner: 1 },
skills: await isolatedSkillsConfig(),
workspaceContext: false,
})
let settle!: (outcome: { status: 'killed' }) => void
ctx.jobs.start({
kind: 'bash',
label: 'hold configured slot',
run: () => ({
cancel: () => { settle({ status: 'killed' }) },
done: new Promise((resolve) => { settle = resolve }),
}),
})
expect(() => ctx.jobs.start({
kind: 'bash',
label: 'blocked configured task',
run: () => ({ cancel: () => {}, done: Promise.resolve({ status: 'completed' }) }),
})).toThrow('(limit: 1)')
await ctx.fiber.dispose()
})
it('forwards bundled tool config into agent-core', async () => {
const ctx = await mount({
provider: 'mock',
model: 'mock',
workspaceContext: false,
toolBash: { enableRunInBackground: false },
toolJobs: { waitTimeoutMs: 7, maxWaitTimeoutMs: 11 },
skills: await isolatedSkillsConfig(),
}, true)
const bash = ctx.tools.schemas().find(tool => tool.name === 'bash')
expect(Object.keys((bash!.parameters as { properties: Record<string, unknown> }).properties))
.not.toContain('run_in_background')
await ctx.fiber.dispose()
})
it('exposes its plugin shape', () => {
expect(acpAgent.name).toBe('acp-demo')
expect(acpAgent.Config).toBeDefined()
})
it('forwards toolOrder through agent-spine-demo to the system-prompt assembly', async () => {
const ctx = await mount({
provider: 'mock',
model: 'mock',
toolOrder: ['zulu', TOOL_ORDER_REST],
persistenceRoot: await mkdtemp(join(tmpdir(), 'dsh-acp-demo-test-tool-order-')),
workspaceContext: false,
})
// The bundle's own bash tools pend on the absent `ctx.shell` executor in
// this providerless mount, so register two plain tools to order.
for (const name of ['alpha', 'zulu']) {
ctx.get('tools')!.register({
name,
description: name,
parameters: {},
output: { schema: { type: 'null' }, render: () => [] },
execute: async () => null,
})
}
const assembly = await ctx.get('systemPrompt')!.assemble()
expect(assembly.tools.map(tool => tool.name)).toEqual([
'zulu',
'alpha',
'create_goal',
'get_goal',
'job_kill',
'job_list',
'job_output',
'skill',
'update_goal',
])
await ctx.fiber.dispose()
})
it('has the namespace-plugin export shape (no stray default) so the Loader keeps name/Config/apply', () => {
// A default export would make `unwrapExports` collapse this inject-less namespace and silently
// drop `name`/`Config` while the app still boots. Guard the postmortem-0001 shape directly.
expect('default' in acpAgent).toBe(false)
expect(typeof acpAgent.apply).toBe('function')
const loader = Object.create(Loader.prototype) as Loader
const unwrapped = loader.unwrapExports(acpAgent) as Record<string, unknown>
expect(unwrapped).toBe(acpAgent)
expect(unwrapped.name).toBe('acp-demo')
expect(unwrapped.Config).toBeDefined()
expect(typeof unwrapped.apply).toBe('function')
})
})
@@ -1,242 +0,0 @@
import { spawn } from 'node:child_process'
import { mkdtemp, mkdir, readdir, rm, symlink, writeFile, readFile } from 'node:fs/promises'
import { existsSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
import { fileURLToPath, pathToFileURL } from 'node:url'
import {
client as createAcpClientApp,
methods,
ndJsonStream,
PROTOCOL_VERSION,
type SessionNotification,
} from '@agentclientprotocol/sdk'
import { Readable, Writable } from 'node:stream'
import { promisify } from 'node:util'
import { zstdDecompress } from 'node:zlib'
import { execa } from 'execa'
import { afterEach, describe, expect, it } from 'vitest'
/**
* Published-entry smoke: run `lib/bin.js` under plain Node in a symlinked external consumer and
* complete a mock-backed turn. This catches built-only settle races, stdout protocol leaks, and
* published persistence behavior that the tsx source-path smoke cannot. It skips before build.
*/
const repoRoot = fileURLToPath(new URL('../../../../', import.meta.url))
const acpBin = join(repoRoot, 'packages/examples/acp-demo/lib/bin.js')
const decompress = promisify(zstdDecompress)
const dshPackages = [
'examples/agent-spine-demo', 'core/agent', 'core/scope', 'core/session', 'core/system-prompt',
'core/tools', 'core/agent-loop', 'llm/llm', 'shell/shell',
'shell/bash-local', 'shell/tool-bash', 'subprocess/subprocess', 'subprocess/subprocess-local', 'context/agent-instructions', 'runtime-diagnostics/invariants', 'boot/app-boot',
'session/session-persistence',
'session/session-checkpoint-policy', 'session/session-persistence-jsonl',
'acp/acp', 'mcp/mcp-client', 'examples/acp-demo', 'util/home-paths', 'util/timeout',
]
const vendorPackages = [
'cordis', 'loader', 'include', 'timer', 'hmr', 'logger-console',
'schemastery', 'cosmokit',
]
// Resolve ACP's declared third-party dependencies from that package, not this test: pnpm's strict
// layout need not hoist them. Symlink those exact paths into the plain-Node consumer.
const npmDeps = ['@agentclientprotocol/sdk']
const acpPkgDir = join(repoRoot, 'packages/acp/acp')
async function pkgName(absDir: string): Promise<string> {
const json = JSON.parse(await readFile(join(absDir, 'package.json'), 'utf8')) as { name: string }
return json.name
}
async function link(target: string, name: string, nm: string): Promise<void> {
const dest = join(nm, name)
await mkdir(dirname(dest), { recursive: true })
await symlink(target, dest)
}
/** Build a temp consumer dir + a minimal acp `cordis.yml`. Returns the dir. */
async function makeConsumer(): Promise<string> {
const dir = await mkdtemp(join(tmpdir(), 'acp-built-bin-'))
const nm = join(dir, 'node_modules')
for (const rel of dshPackages) {
const abs = join(repoRoot, 'packages', rel)
await link(abs, await pkgName(abs), nm)
}
for (const v of vendorPackages) {
const abs = join(repoRoot, 'vendor', v)
await link(abs, await pkgName(abs), nm)
}
for (const dep of npmDeps) {
// Resolve from ACP's package.json URL (the package that declares the
// dep), not this test file's location — `acp-agent` does not depend on these.
// ACP SDK 1.4 intentionally does not export package.json; its stable entry
// is `<package>/dist/acp.js`, so the package root is two directories up.
const fromAcp = pathToFileURL(join(acpPkgDir, 'package.json')).href
const resolved = fileURLToPath(import.meta.resolve(dep, fromAcp))
await link(dirname(dirname(resolved)), dep, nm)
}
await writeFile(join(dir, 'mock-llm.mjs'), [
"import { LlmAdapter } from '@deepseek-ai/dsh-llm'",
'class Mock extends LlmAdapter {',
' async * stream() {',
" yield { type: 'block-start', index: 0, blockType: 'text' }",
" yield { type: 'text-delta', index: 0, text: 'ACP BUILT OK' }",
" yield { type: 'block-end', index: 0, block: { type: 'text', text: 'ACP BUILT OK' } }",
" yield { type: 'finish', reason: { kind: 'stop' } }",
' }',
'}',
"export const name = 'built-acp-mock'",
"export const inject = ['llm']",
"export function apply(ctx) { ctx.llm.registerAdapter(['built-acp-mock'], new Mock()) }",
'',
].join('\n'))
await writeFile(join(dir, 'cordis.yml'), [
'- id: mock-llm',
' name: \'./mock-llm.mjs\'',
'- id: subprocess',
' name: \'@deepseek-ai/dsh-subprocess-local\'',
'- id: bash',
' name: \'@deepseek-ai/dsh-bash-local\'',
'- id: acp-agent',
' name: \'@deepseek-ai/dsh-acp-demo\'',
' config:',
' provider: built-acp-mock',
' model: built-acp-mock',
' persona: \'test agent\'',
' workspaceContext: false',
'',
].join('\n'))
return dir
}
let consumer: string | undefined
let child: ReturnType<typeof spawn> | undefined
afterEach(async () => {
if (child !== undefined) {
const proc = child
child = undefined
// Windows retains the child's cwd and session-log handles until process
// teardown completes, so await exit before removing the temp directory.
if (proc.exitCode === null && proc.signalCode === null) {
const exited = new Promise<void>((resolve) => { proc.once('exit', () => { resolve() }) })
proc.kill('SIGKILL')
await exited
}
}
// Windows can briefly retain released handles after exit; retry removal.
if (consumer !== undefined) await rm(consumer, { recursive: true, force: true, maxRetries: 10, retryDelay: 100 })
consumer = undefined
})
describe.skipIf(!existsSync(acpBin))('dsh-acp-demo BUILT bin (node lib/bin.js, no tsx)', () => {
it('boots the published bin, completes a turn, and writes default Zstandard persistence', async () => {
consumer = await makeConsumer()
child = spawn(process.execPath, [acpBin, '--config', './cordis.yml'], {
cwd: consumer,
env: {
...process.env,
DSH_HOME: join(consumer, '.dsh'),
DSH_AGENTS_HOME: join(consumer, '.agents'),
},
stdio: ['pipe', 'pipe', 'pipe'],
})
const stderr: string[] = []
child.stderr!.setEncoding('utf8')
child.stderr!.on('data', (c: string) => stderr.push(c))
// Tee raw stdout for a protocol-purity check, and feed it to the SDK client.
const rawOut: string[] = []
const passthrough = new Readable({ read() {} })
child.stdout!.on('data', (buf: Buffer) => { rawOut.push(buf.toString('utf8')); passthrough.push(buf) })
child.stdout!.on('end', () => passthrough.push(null))
const stream = ndJsonStream(
Writable.toWeb(child.stdin!) as WritableStream<Uint8Array>,
Readable.toWeb(passthrough) as ReadableStream<Uint8Array>,
)
const updates: SessionNotification['update'][] = []
const clientApp = createAcpClientApp({ name: 'dsh-acp-built-smoke' })
.onNotification(methods.client.session.update, ({ params }) => {
updates.push(params.update)
return Promise.resolve()
})
.onRequest(methods.client.session.requestPermission, () => {
return Promise.resolve({ outcome: { outcome: 'cancelled' } })
})
const client = clientApp.connect(stream).agent
const init = await client.request(methods.agent.initialize, {
protocolVersion: PROTOCOL_VERSION,
clientCapabilities: {},
})
.catch((error: unknown): never => {
throw new Error(`built ACP initialize failed\n${stderr.join('')}`, { cause: error })
})
expect(init.agentCapabilities).toEqual({
mcpCapabilities: { http: true },
promptCapabilities: { image: false, audio: false, embeddedContext: false },
sessionCapabilities: { close: {}, list: {}, resume: {} },
})
const sessionCwd = consumer
const { sessionId } = await client.request(methods.agent.session.new, { cwd: sessionCwd, mcpServers: [] })
const result = await client.request(methods.agent.session.prompt, {
sessionId,
prompt: [{ type: 'text', text: 'reply' }],
})
expect(result.stopReason).toBe('end_turn')
await expect.poll(() => updates).toHaveLength(1)
expect(updates[0]).toMatchObject({
sessionUpdate: 'agent_message_chunk',
content: { type: 'text', text: 'ACP BUILT OK' },
})
expect(updates[0] !== undefined && 'messageId' in updates[0] && typeof updates[0].messageId === 'string').toBe(true)
const sessionsRoot = join(sessionCwd, '.sessions')
let log: string | undefined
await expect.poll(async () => {
log = (await readdir(sessionsRoot, { recursive: true })).find(file => file.endsWith('.jsonl.zstd'))
return log
}).toBeTypeOf('string')
const compressed = await readFile(join(sessionsRoot, log!))
expect(compressed.subarray(0, 4).toString('hex')).toBe('28b52ffd')
expect(JSON.parse((await decompress(compressed)).toString())).toMatchObject({ type: 'session', id: sessionId })
expect(stderr.join('')).not.toContain('without inject')
// stdout purity: every emitted line is a JSON-RPC frame, no logger leak.
for (const line of rawOut.join('').split('\n').filter(l => l.trim().length > 0)) {
expect(() => JSON.parse(line) as unknown).not.toThrow()
}
}, 30_000)
it('fails LOUD (non-zero exit + stderr) on a config whose directory does not exist', async () => {
// boot() pre-resolves the bootstrap include to an absolute URL, so a nonexistent config
// directory cannot break its import; the include plugin's own read must fail loud instead.
const { code, stderr } = await runBinExpectingExit('/nonexistent/dir/cordis.yml')
expect(code).not.toBe(0)
expect(stderr).toContain('config file not found')
}, 30_000)
it('fails LOUD (non-zero exit + stderr) on a missing config file in a real directory', async () => {
// Existing directory plus missing config exercises the include plugin's fail-loud path.
consumer = await makeConsumer()
const { code, stderr } = await runBinExpectingExit('./does-not-exist.yml', consumer)
expect(code).not.toBe(0)
expect(stderr).toContain('config file not found')
}, 30_000)
})
/** Spawn the built acp bin against `configArg` (stdin closed at EOF) and resolve with its exit code + stderr. */
async function runBinExpectingExit(configArg: string, cwd: string = tmpdir()): Promise<{ code: number; stderr: string }> {
const result = await execa(process.execPath, [acpBin, '--config', configArg], {
cwd,
env: {
DSH_HOME: join(cwd, '.dsh'),
DSH_AGENTS_HOME: join(cwd, '.agents'),
},
input: '',
timeout: 25_000,
killSignal: 'SIGKILL',
reject: false,
})
if (result.timedOut) throw new Error(`bin did not exit within 25s. stderr:\n${result.stderr}`)
return { code: result.exitCode ?? -1, stderr: result.stderr }
}
@@ -1,133 +0,0 @@
import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process'
import { Readable, Writable } from 'node:stream'
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { afterEach, describe, expect, it } from 'vitest'
import {
client as createAcpClientApp,
methods,
ndJsonStream,
PROTOCOL_VERSION,
type ClientContext,
} from '@agentclientprotocol/sdk'
/**
* Source-path Loader smoke through the package's own bin, covering the
* automation server's initialize and fresh-session path across the
* `unwrapExports` shape implicated by postmortem 0001. Session creation reaches
* the factory but not the model, so a dummy key is sufficient.
*/
const binScript = fileURLToPath(new URL('../src/bin.ts', import.meta.url))
const tsxLoader = fileURLToPath(import.meta.resolve('tsx'))
// Repo root is four levels up from packages/examples/acp-demo/tests.
const repoTsconfig = fileURLToPath(new URL('../../../../tsconfig.json', import.meta.url))
// A minimal opt-in leaf that loads this app + the two backends and the optional
// session-query consumer/policies, inlined so the package test owns its fixture.
const CORDIS_YML = `
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
- id: subprocess
name: '@deepseek-ai/dsh-subprocess-local'
- id: bash
name: '@deepseek-ai/dsh-bash-local'
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
config:
provider: deepseek-official
model: deepseek-v4-flash
persona: 'You are a test agent.'
workspaceContext: false
- id: tool-session-query
name: '@deepseek-ai/dsh-tool-session-query'
- id: timeout-policy
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
- id: spill-local
name: '@deepseek-ai/dsh-spill-local'
- id: spill-policy
name: '@deepseek-ai/dsh-spill-policy'
config:
maxInlineBytes: 50000
`
interface Spawned {
child: ChildProcessWithoutNullStreams
client: ClientContext
stderr: string[]
}
let spawned: Spawned | undefined
let workdir: string | undefined
afterEach(async () => {
if (spawned !== undefined) {
spawned.child.kill('SIGKILL')
spawned = undefined
}
if (workdir !== undefined) await rm(workdir, { recursive: true, force: true })
workdir = undefined
})
async function boot(): Promise<Spawned & { cwd: string }> {
workdir = await mkdtemp(join(tmpdir(), 'acp-agent-pkg-'))
const cwd = workdir
const configPath = join(cwd, 'cordis.yml')
await writeFile(configPath, CORDIS_YML)
const child = spawn(
process.execPath,
['--import', tsxLoader, binScript, '--config', configPath],
{
cwd,
env: {
...process.env,
TSX_TSCONFIG_PATH: repoTsconfig,
// Key-present check only; no prompt is sent, so the model is never called.
DEEPSEEK_API_KEY: process.env.DEEPSEEK_API_KEY ?? 'keyless-acp-agent-smoke',
DSH_HOME: join(cwd, '.dsh'),
DSH_AGENTS_HOME: join(cwd, '.agents'),
},
stdio: ['pipe', 'pipe', 'pipe'],
},
)
const stderr: string[] = []
child.stderr.setEncoding('utf8')
child.stderr.on('data', (chunk: string) => stderr.push(chunk))
const stream = ndJsonStream(
Writable.toWeb(child.stdin) as WritableStream<Uint8Array>,
Readable.toWeb(child.stdout) as ReadableStream<Uint8Array>,
)
const client = createAcpClientApp({ name: 'dsh-acp-load-smoke' })
.onNotification(methods.client.session.update, () => Promise.resolve())
.onRequest(methods.client.session.requestPermission, () => (
Promise.resolve({ outcome: { outcome: 'cancelled' } })
))
.connect(stream).agent
spawned = { child, client, stderr }
return { ...spawned, cwd }
}
describe('dsh-acp-demo real-load-path smoke (bin + Loader, keyless)', () => {
it('boots via its bin and exposes the standard automation controls', async () => {
const { client, cwd, stderr } = await boot()
// initialize: a broken export shape (collapsed bridge plugin, dropped inject)
// crashes the tree on the first service read here — see postmortem 0001.
const init = await client.request(methods.agent.initialize, {
protocolVersion: PROTOCOL_VERSION,
clientCapabilities: {},
})
expect(init.agentCapabilities).toEqual({
mcpCapabilities: { http: true },
promptCapabilities: { image: false, audio: false, embeddedContext: false },
sessionCapabilities: { close: {}, list: {}, resume: {} },
})
// session/new reaches the agent FACTORY (create) without the model.
const { sessionId } = await client.request(methods.agent.session.new, { cwd, mcpServers: [] })
expect(sessionId).toBeTruthy()
expect(stderr.join('')).not.toContain('without inject')
}, 30_000)
})
-51
View File
@@ -1,51 +0,0 @@
{
"extends": "../../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "lib/types"
},
"include": [
"src"
],
"references": [
{
"path": "../../../vendor/cordis"
},
{
"path": "../../../vendor/schemastery"
},
{
"path": "../../../vendor/loader"
},
{
"path": "../../boot/app-boot"
},
{
"path": "../../acp/acp"
},
{
"path": "../../core/agent"
},
{
"path": "../../session-query/session-query"
},
{
"path": "../../session-query/session-query-sqlite"
},
{
"path": "../agent-spine-demo"
},
{
"path": "../../context/agent-instructions"
},
{
"path": "../../session/session-checkpoint-policy"
},
{
"path": "../../session/session-persistence-jsonl"
},
{
"path": "../../runtime-diagnostics/invariants"
}
]
}

Some files were not shown because too many files have changed in this diff Show More