Merge origin/master into codex/fix-compact-agents-reinjection
This commit is contained in:
@@ -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/README.md
|
||||
README.md: 64e9804eb69367588e926791039c453b0a9aede9
|
||||
README.zh.md: f0a174a2d59a21ed89fa1a83fc80d3fb05764244
|
||||
README.md: 5d021d9d9c7abae90b5f96bccd6447f4e2c3dc57
|
||||
README.zh.md: 66b355a93c0a0e6b53d1353de4024b7f86e82f7c
|
||||
|
||||
@@ -2,32 +2,24 @@
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Runnable demos (not workspaces) that showcase how the harness is wired. Each example is a **thin leaf**: either a `cordis.yml` tree that picks swappable backends and loads one app package, or an **overlay** — a patch list `dsh --config` applies over the shipped composition ([`apps/cli/config/base.cordis.yml`](../apps/cli/config/base.cordis.yml) plus a surface overlay). Bundled compositions live in [`@deepseek-ai/dsh-cli-demo`](../packages/examples/cli-demo), [`@deepseek-ai/dsh-acp-demo`](../packages/examples/acp-demo), and their shared [`@deepseek-ai/dsh-agent-spine-demo`](../packages/examples/agent-spine-demo) bundle; the `dsh` surfaces use flat config trees instead. There is no `start.ts`; the terminal `demo:*` scripts boot through the [`dsh`](../apps/cli/README.md) CLI, and the headless/ACP scripts invoke the `cli-demo`/`acp-demo` bins.
|
||||
Runnable demonstrations of the main DeepSeek Harness interfaces and extension points. Each child directory owns its configuration, prerequisites, commands, and detailed behavior.
|
||||
|
||||
## mcp-memory
|
||||
|
||||
Three default-off reference overlays connect a memory MCP server through the generic MCP client. Pick one file and pass it to `dsh --config`; DSH does not install or configure the upstream memory system. See [mcp-memory/README.md](mcp-memory/README.md) for pinned prerequisites, identity mapping, the shared optional prompt, and the write → fresh-session recall → use verification recipe.
|
||||
Optional overlays that connect supported third-party memory servers through the generic MCP client. See the [memory example reference](mcp-memory/README.md).
|
||||
|
||||
## headless-agent
|
||||
|
||||
A non-interactive agent demo that accepts one positional task, runs one complete model/tool turn on the `@deepseek-ai/dsh-cli-demo` app, persists a fresh session, prints `text`, `json`, or `stream-json`, and exits.
|
||||
|
||||
Run with: `pnpm run demo:headless "task"` (needs `DEEPSEEK_API_KEY`). See [headless-agent/README.md](headless-agent/README.md) for the output contract, safety boundaries, and snapshot suite.
|
||||
A non-interactive agent that accepts one task, runs it, and emits a selected machine-readable or human-readable output format. See the [headless example reference](headless-agent/README.md).
|
||||
|
||||
## jsonrpc-agent
|
||||
|
||||
An unattended coding agent driven through the Python SDK: JSON-RPC stdio, foreground-only `bash`, `read` / `write` / `edit`, one foreground `subagent`, `todo_write`, JSONL persistence, and compaction. It excludes terminal UI, stdout logging, approvals, skills, and background task controls. See [jsonrpc-agent/README.md](jsonrpc-agent/README.md).
|
||||
An unattended coding agent driven through the Python SDK and JSON-RPC. See the [JSON-RPC example reference](jsonrpc-agent/README.md).
|
||||
|
||||
## web-cordis
|
||||
|
||||
The **self-referential** demo: the coding spine plus [`@deepseek-ai/dsh-tool-cordis`](../packages/cordis/tool-cordis), whose three tools (`cordis_inspect` / `cordis_mount` / `cordis_unmount`) let the agent inspect the current DSH process, mount model-written temporary Plugins (an event listener, a brand-new tool, or a service another temporary Plugin injects), and unmount them again. These Plugins exist only in memory and share one internal `cordis-dynamic` fiber subtree; `ctx.fs`/`ctx.web` ride along provider-only as capabilities they can use.
|
||||
|
||||
Run the browser UI at `http://127.0.0.1:3081` with `pnpm run demo:cordis`, or the ACP server with `pnpm run demo:cordis acp` (both need `DEEPSEEK_API_KEY`). See [the toolset Agent Note](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md) for the design and sandbox caveats.
|
||||
A self-referential agent that can inspect and change its in-memory Cordis plugin tree. See the [web-cordis example reference](web-cordis/README.md).
|
||||
|
||||
## acp-agent
|
||||
|
||||
An agent exposed as an **Agent Client Protocol (ACP)** automation server over JSON-RPC stdio, via [`@deepseek-ai/dsh-acp-demo`](../packages/examples/acp-demo). Programmatic clients create fresh sessions, send text prompts, consume committed assistant text, answer one-shot permission requests, and cancel work. It owns the ACP keyless snapshot suite.
|
||||
|
||||
Run with: `pnpm run demo:acp` (needs `DEEPSEEK_API_KEY`); `pnpm run demo:code-mode` boots the same server in Code Mode via the `code-mode.cordis.yml` overlay. See [acp-agent/README.md](acp-agent/README.md) for the protocol and snapshot-test contracts.
|
||||
|
||||
The default `cordis.yml` composes [`@deepseek-ai/dsh-sandbox-local`](../packages/sandbox/sandbox-local), [`@deepseek-ai/dsh-bash-sandbox`](../packages/bash/bash-sandbox), and [`@deepseek-ai/dsh-user-approval`](../packages/ui/user-approval). `workspace-write` confines bash and filesystem mutations to each session workspace; a wider retry becomes a one-shot machine permission request over ACP.
|
||||
An Agent Client Protocol automation server for programmatic clients, with session, permission, and cancellation support. See the [ACP example reference](acp-agent/README.md).
|
||||
|
||||
@@ -2,32 +2,24 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
展示 harness 如何接线的可运行演示(不是 workspace)。每个示例都是一个 **轻量叶节点**:要么是一份选择可替换后端、加载一个应用包的 `cordis.yml` 配置树,要么是一个 **overlay**——由 `dsh --config` 叠加到交付组合([`apps/cli/config/base.cordis.yml`](../apps/cli/config/base.cordis.yml) 加一份 surface overlay)之上的 patch 列表。成组的组合位于 [`@deepseek-ai/dsh-cli-demo`](../packages/examples/cli-demo)、[`@deepseek-ai/dsh-acp-demo`](../packages/examples/acp-demo) 及它们共享的 [`@deepseek-ai/dsh-agent-spine-demo`](../packages/examples/agent-spine-demo) 组合包中;`dsh` 的各 surface 则改用平铺 config tree。没有 `start.ts`;终端 `demo:*` 脚本通过 [`dsh`](../apps/cli/README.md) CLI(命令行界面)启动,无头/ACP(Agent Client Protocol)脚本则调用 `cli-demo`/`acp-demo` bin。
|
||||
展示 DeepSeek Harness 主要接口和扩展点的可运行演示。每个子目录负责自己的配置、前置条件、命令和详细行为。
|
||||
|
||||
## mcp-memory
|
||||
|
||||
三份默认关闭的参考 overlay 通过通用 MCP 客户端连接一个记忆 MCP 服务器。选择其中一份文件传给 `dsh --config`;DSH 不负责安装或配置上游记忆系统。版本固定的前置条件、身份映射、可选的共用提示词,以及「写入 → 新会话召回 → 使用」验证流程详见 [mcp-memory/README.md](mcp-memory/README.md)。
|
||||
通过通用 MCP 客户端连接受支持第三方记忆服务器的可选 overlay。详见[记忆示例参考](mcp-memory/README.md)。
|
||||
|
||||
## headless-agent
|
||||
|
||||
非交互式 agent(智能体)演示:接受一个位置任务,在 `@deepseek-ai/dsh-cli-demo` 应用上运行一个完整模型/工具轮次,持久化新会话,打印 `text`、`json` 或 `stream-json`,然后退出。
|
||||
|
||||
运行:`pnpm run demo:headless "task"`(需要 `DEEPSEEK_API_KEY`)。输出契约、安全边界和快照套件详见 [headless-agent/README.md](headless-agent/README.md)。
|
||||
非交互式 agent(智能体):接受一项任务并运行,然后以选定的机器可读或人类可读格式输出结果。详见[无头示例参考](headless-agent/README.md)。
|
||||
|
||||
## jsonrpc-agent
|
||||
|
||||
通过 Python SDK 驱动的无人值守编码 agent:JSON-RPC stdio、仅前台 `bash`、`read`/`write`/`edit`、一个前台 `subagent`、`todo_write`、JSONL 持久化和压缩。它不包含终端 UI、stdout 日志、批准、skill 和后台任务控制。详见 [jsonrpc-agent/README.md](jsonrpc-agent/README.md)。
|
||||
由 Python SDK 和 JSON-RPC 驱动的无人值守编码 agent。详见 [JSON-RPC 示例参考](jsonrpc-agent/README.md)。
|
||||
|
||||
## web-cordis
|
||||
|
||||
**自指** 演示:编码主干加 [`@deepseek-ai/dsh-tool-cordis`](../packages/cordis/tool-cordis),其三个工具(`cordis_inspect`/`cordis_mount`/`cordis_unmount`)使 agent 可以检查当前 DSH 进程、挂载模型编写的临时 Plugin(事件监听器、一个全新工具,或一个供另一临时 Plugin 注入的服务),并再次卸载它们。这些 Plugin 只存在于内存中,共享一个内部 `cordis-dynamic` fiber 子树;`ctx.fs`/`ctx.web` 仅作为它们可用的能力提供方。
|
||||
|
||||
使用 `pnpm run demo:cordis` 在 `http://127.0.0.1:3081` 启动浏览器 UI,或使用 `pnpm run demo:cordis acp` 启动 ACP 服务器(两者均需 `DEEPSEEK_API_KEY`)。设计与沙箱注意事项详见[工具集 Agent Note](../.agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md)。
|
||||
能够检查并更改内存中 Cordis 插件树的自指 agent。详见 [web-cordis 示例参考](web-cordis/README.md)。
|
||||
|
||||
## acp-agent
|
||||
|
||||
作为 **Agent Client Protocol (ACP)** 自动化服务器通过 JSON-RPC stdio 公开的 agent,由 [`@deepseek-ai/dsh-acp-demo`](../packages/examples/acp-demo) 提供。程序化客户端可以创建新会话、发送文本提示词、消费已提交的 assistant 文本、回答一次性权限请求并取消工作。它拥有 ACP 无密钥快照套件。
|
||||
|
||||
运行:`pnpm run demo:acp`(需要 `DEEPSEEK_API_KEY`);`pnpm run demo:code-mode` 通过 `code-mode.cordis.yml` 覆盖以 Code Mode 启动同一服务器。协议与快照测试契约详见 [acp-agent/README.md](acp-agent/README.md)。
|
||||
|
||||
默认 `cordis.yml` 组合 [`@deepseek-ai/dsh-sandbox-local`](../packages/sandbox/sandbox-local)、[`@deepseek-ai/dsh-bash-sandbox`](../packages/bash/bash-sandbox) 和 [`@deepseek-ai/dsh-user-approval`](../packages/ui/user-approval)。`workspace-write` 将 bash 和文件系统变更限制在每个会话 workspace 中;范围更广的重试会通过 ACP 成为一次性机器权限请求。
|
||||
面向程序化客户端的 ACP(Agent Client Protocol)自动化服务器,支持会话、权限和取消操作。详见 [ACP 示例参考](acp-agent/README.md)。
|
||||
|
||||
@@ -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: a37954d4d52900413a506f227759a0a7dd2a25d0
|
||||
README.zh.md: a38431ea2f01fe16ff39b5dd00ec23e881713f5d
|
||||
README.md: 61c6efafe9dde4f91385beebdfd426c57006187b
|
||||
README.zh.md: 343e55722a4dda7c5cc5e0de6b5fecf250b9ab13
|
||||
|
||||
@@ -9,7 +9,7 @@ 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. [`session-query.cordis.yml`](session-query.cordis.yml) explicitly opts into the workspace-authorized query tools and generic timeout/spill policies for their dedicated snapshot; [`fs.cordis.yml`](fs.cordis.yml) adds spill storage for filesystem scenarios, [`code-mode.cordis.yml`](code-mode.cordis.yml) adds `run_code` and its generated TypeScript SDK, and [`web.cordis.yml`](web.cordis.yml) adds the web seam, the local fetch provider, `web_fetch`, and a loopback HTML fixture server for the web-fetch snapshot.
|
||||
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.
|
||||
|
||||
## Protocol channel
|
||||
|
||||
@@ -19,12 +19,6 @@ The automation contract — supported methods, baseline prompt content, committe
|
||||
|
||||
## Session workspaces and permissions
|
||||
|
||||
Each `session/new` supplies an absolute `cwd`. Sandboxed bash and filesystem mutations resolve `workspace-write` against that session cwd, so concurrent sessions can use separate project roots; platform temporary roots remain shared writable scratch space ([sandbox contract](../../packages/sandbox/sandbox/README.md)). `DSH_PERMISSION_MODE` selects `workspace-write` or `danger-full-access` for deployment and tests.
|
||||
Each `session/new` supplies an absolute `cwd`. Sandboxed bash and filesystem mutations resolve `workspace-write` against that session cwd, so concurrent sessions can use separate project roots; platform temporary roots remain shared writable scratch space ([sandbox contract](../../packages/sandbox/sandbox/README.md)). `DSH_PERMISSION_MODE` selects `workspace-write` or `danger-full-access` for the deployment.
|
||||
|
||||
Under `workspace-write`, a model retry requesting wider sandbox access triggers `session/request_permission` with `allow_once` and `reject_once`. The client decides programmatically; dismissal or an unavailable answer fails closed. The selected outcome applies only to that retry and is recorded through the normal tool-result/audit path. The server never exposes a permission picker or persists client policy.
|
||||
|
||||
## Snapshot tests
|
||||
|
||||
This example owns the ACP snapshot suite. It boots the real automation server, replays committed model streams through `dsh-llm-replay`, and compares both normalized protocol output and re-persisted session logs. Recording uses the real model; refresh reuses committed replay input. Overrides cover throw/hang behavior, and optional `workspace/` fixtures seed world-state checks.
|
||||
|
||||
Most scenarios pin backend behavior rather than ACP-specific behavior; the [automation-only ACP decision](../../.agents/notes/implemented/simplification/2026-07-23-acp-automation-only-protocol.md#snapshot-boundary) owns why that coverage remains transport-coupled.
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
通过 JSON-RPC stdio 提供的面向自动化的 [Agent Client Protocol(ACP)](https://agentclientprotocol.com) 服务器。它面向 parent agent(父智能体)、subagent 提供方和其他程序化客户端,而非产品 UI。
|
||||
通过 JSON-RPC stdio 提供的面向自动化的 [ACP(Agent Client Protocol)](https://agentclientprotocol.com) 服务器。它面向 parent agent(父智能体)、subagent 提供方和其他程序化客户端,而非产品 UI。
|
||||
|
||||
```sh
|
||||
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 只含协议内容。[`session-query.cordis.yml`](session-query.cordis.yml) 为其专用快照显式选用 workspace 授权的查询工具和通用超时/溢出策略;[`fs.cordis.yml`](fs.cordis.yml) 为文件系统场景添加溢出存储,[`code-mode.cordis.yml`](code-mode.cordis.yml) 添加 `run_code` 及其生成的 TypeScript SDK,[`web.cordis.yml`](web.cordis.yml) 则为 web-fetch 快照添加 web seam、本地抓取提供方、`web_fetch` 与一个回环 HTML fixture(测试前置数据)服务器。
|
||||
该叶节点加载 ACP 应用、DeepSeek 适配器、受沙箱限制的 bash 与文件系统栈、一次性批准策略、压缩(compaction)、subagent、工作流、钩子、派生会话查询索引和重复守卫。应用为每次 `session/new` 创建一个新 agent,将会话持久化到 JSONL,并保持 stdout 只含协议内容。可选 overlay 可添加会话查询、文件系统溢出存储、Code Mode 或 Web 抓取。
|
||||
|
||||
## 协议通道
|
||||
|
||||
@@ -19,12 +19,6 @@ Stdout 只携带以换行分隔的 ACP JSON-RPC。`@deepseek-ai/dsh-acp-demo`
|
||||
|
||||
## 会话 workspace 与权限
|
||||
|
||||
每次 `session/new` 都提供一个绝对 `cwd`。受沙箱限制的 bash 和文件系统修改会以该会话 cwd 为基准应用 `workspace-write`,因此并发会话可以使用不同的项目根目录;平台临时根目录仍是共享可写暂存空间(参见[沙箱契约](../../packages/sandbox/sandbox/README.md))。`DSH_PERMISSION_MODE` 在部署和测试中选择 `workspace-write` 或 `danger-full-access`。
|
||||
每次 `session/new` 都提供一个绝对 `cwd`。受沙箱限制的 bash 和文件系统修改会以该会话 cwd 为基准应用 `workspace-write`,因此并发会话可以使用不同的项目根目录;平台临时根目录仍是共享可写暂存空间(参见[沙箱契约](../../packages/sandbox/sandbox/README.md))。`DSH_PERMISSION_MODE` 为部署选择 `workspace-write` 或 `danger-full-access`。
|
||||
|
||||
在 `workspace-write` 下,如果模型重试请求更广泛的沙箱访问权限,就会触发 `session/request_permission`,选项为 `allow_once` 和 `reject_once`。客户端以程序方式决策;客户端放弃选择或无法给出答复时,系统会按拒绝处理。选定结果仅适用于该次重试,并通过常规工具结果/审计路径记录。服务器绝不公开权限选择器,也不持久化客户端策略。
|
||||
|
||||
## 快照测试
|
||||
|
||||
此示例拥有 ACP 快照套件。它会启动真实自动化服务器,通过 `dsh-llm-replay` 回放已提交的模型流,并比较规范化后的协议输出与重新持久化的会话日志。录制使用真实模型;刷新会复用已提交的回放输入。覆盖配置涵盖抛错/挂起行为,可选的 `workspace/` fixture 则为环境状态检查预置状态。
|
||||
|
||||
大多数场景锁定后端行为,而非 ACP 专用行为;[仅面向自动化的 ACP 决策](../../.agents/notes/implemented/simplification/2026-07-23-acp-automation-only-protocol.md#snapshot-boundary)说明了为何该覆盖仍与传输层耦合。
|
||||
|
||||
38
examples/acp-agent/partial-landlock.cordis.snapshot.yml
Normal file
38
examples/acp-agent/partial-landlock.cordis.snapshot.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
# Keyless runner-classification composition: replay authored model turns and
|
||||
# replace the shipping provider with a deterministic process-launch stand-in.
|
||||
- id: base
|
||||
name: '@cordisjs/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.
|
||||
|
||||
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'
|
||||
13
examples/acp-agent/partial-landlock.cordis.yml
Normal file
13
examples/acp-agent/partial-landlock.cordis.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
# Live counterpart for the runner-classification snapshot overlay. It replaces
|
||||
# only the sandbox provider; authored scenarios are skipped in record mode.
|
||||
- id: base
|
||||
name: '@cordisjs/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'
|
||||
@@ -49,6 +49,7 @@ const SUBAGENT_DURABILITY_FAILURE_CONFIG = fileURLToPath(
|
||||
const LSP_CONFIG = fileURLToPath(new URL('./lsp.cordis.yml', import.meta.url))
|
||||
const WEB_CONFIG = fileURLToPath(new URL('../web.cordis.yml', import.meta.url))
|
||||
const FS_SEARCH_CONFIG = fileURLToPath(new URL('./fs-search.cordis.yml', import.meta.url))
|
||||
const PARTIAL_LANDLOCK_CONFIG = fileURLToPath(new URL('../partial-landlock.cordis.yml', import.meta.url))
|
||||
const PWSH_CONFIG = fileURLToPath(new URL('./pwsh.cordis.yml', import.meta.url))
|
||||
const SNAPSHOTS_DIR = join(dirname(fileURLToPath(import.meta.url)), 'snapshots')
|
||||
const PACKED_CHUNKS_SOURCE = 'hook-cc-pretool-deny'
|
||||
@@ -176,6 +177,32 @@ const SCENARIOS: Scenario[] = [
|
||||
// newline and one recording replays on every host.
|
||||
pwshOnly: true,
|
||||
},
|
||||
// Authored keyless replay through a test-only partial-Landlock provider:
|
||||
// the exact compatibility notice must stay ordinary stderr when the wrapped
|
||||
// `false` command exits 1, rather than becoming SANDBOX_UNAVAILABLE.
|
||||
{
|
||||
name: 'partial-landlock-child-failure',
|
||||
hasModelTurn: true,
|
||||
recorded: false,
|
||||
headerClass: 'sandbox',
|
||||
configPath: PARTIAL_LANDLOCK_CONFIG,
|
||||
env: { DSH_PERMISSION_MODE: 'read-only' },
|
||||
posixOnly: true,
|
||||
},
|
||||
// A valid cwd plus a missing provider executable exercises the assembled
|
||||
// foreground error and background task marker without a platform runner.
|
||||
{
|
||||
name: 'missing-sandbox-runner',
|
||||
hasModelTurn: true,
|
||||
recorded: false,
|
||||
headerClass: 'sandbox',
|
||||
configPath: PARTIAL_LANDLOCK_CONFIG,
|
||||
env: {
|
||||
DSH_PERMISSION_MODE: 'read-only',
|
||||
DSH_SNAPSHOT_MISSING_SANDBOX_RUNNER: '1',
|
||||
},
|
||||
posixOnly: true,
|
||||
},
|
||||
{ name: 'todo-write', hasModelTurn: true, recorded: true },
|
||||
{
|
||||
name: 'skill-load',
|
||||
|
||||
41
examples/acp-agent/tests/fixtures/partial-landlock-sandbox.ts
vendored
Normal file
41
examples/acp-agent/tests/fixtures/partial-landlock-sandbox.ts
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import { join } from 'node:path'
|
||||
import type { ConfinedArgv, SandboxPolicy } from '@deepseek-ai/dsh-sandbox'
|
||||
import { SandboxProvider } from '@deepseek-ai/dsh-sandbox'
|
||||
|
||||
const NOTICE = 'landlock-run: partial enforcement (older Landlock ABI)'
|
||||
const MISSING_RUNNER_ENV = 'DSH_SNAPSHOT_MISSING_SANDBOX_RUNNER'
|
||||
|
||||
/**
|
||||
* Snapshot-only provider for deterministic runner classification. Its default
|
||||
* launch reproduces older-ABI Landlock; an explicit scenario flag selects a
|
||||
* missing executable under the valid workspace cwd. Keep the Landlock tuple
|
||||
* aligned with `RUNNER_FAILURE_RULES` in `packages/sandbox/sandbox-local/src/index.ts`.
|
||||
*/
|
||||
export default class PartialLandlockSandboxProvider extends SandboxProvider {
|
||||
confine(argv: readonly string[], policy: SandboxPolicy): ConfinedArgv {
|
||||
if (process.env[MISSING_RUNNER_ENV] === '1') {
|
||||
return {
|
||||
argv: [join(policy.workspaceRoot, '.dsh-missing-sandbox-runner'), ...argv],
|
||||
enforcement: 'full',
|
||||
denialSignatures: ['permission denied'],
|
||||
runnerFailureRules: [{ fatalSignatures: ['snapshot-runner: '] }],
|
||||
}
|
||||
}
|
||||
return {
|
||||
argv: [
|
||||
'bash',
|
||||
'-c',
|
||||
`printf '%s\\n' '${NOTICE}' >&2; exec "$@"`,
|
||||
'partial-landlock-run',
|
||||
...argv,
|
||||
],
|
||||
enforcement: 'partial',
|
||||
denialSignatures: ['permission denied'],
|
||||
runnerFailureRules: [{
|
||||
allowedExitCodes: [125],
|
||||
fatalSignatures: ['landlock-run: '],
|
||||
informationalLines: [NOTICE],
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"steps": [
|
||||
{ "op": "initialize" },
|
||||
{ "op": "newSession" },
|
||||
{
|
||||
"op": "prompt",
|
||||
"text": "Run true once with bash in the foreground. After that fails, run true with bash in the background, read task bash-1 with task_output and wait=true, then reply with exactly RUNNER_FAILURES_SURFACED and stop."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{"type":"session","version":0,"id":"55555555-5555-4555-8555-555555555555","createdAt":1785304900000,"cwd":"{{cwd}}","delegationDepth":0}
|
||||
{"type":"turn/start","seq":0,"time":1785825343526,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1785825343527,"data":{"content":[{"type":"text","text":"Run true once with bash in the foreground. After that fails, run true with bash in the background, read task bash-1 with task_output and wait=true, then reply with exactly RUNNER_FAILURES_SURFACED and stop."}],"source":{"kind":"user"},"role":"user","id":"698c50b4-8e89-490a-910a-319466b322e8"},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":2,"time":1785825343527,"data":{"title":"Run true once with bash","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"user/message","seq":3,"time":1785825343547,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"role":"user","id":"0027efa5-7cd8-4c0c-b6d0-b483e99dd35a"},"surfaceOp":"append"}
|
||||
{"type":"step/start","seq":4,"time":1785825343547,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":5,"time":1785825343548,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"request/context","seq":6,"time":1785825343548,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
|
||||
{"type":"assistant/chunk","seq":7,"time":1785304900007,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","seq":8,"time":1785304900008,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"missing-runner-foreground","name":"bash","argumentsDelta":"{\"command\":\"true\",\"description\":\"Exercise missing sandbox runner\"}"}}}
|
||||
{"type":"assistant/chunk","seq":9,"time":1785304900009,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"missing-runner-foreground","name":"bash","arguments":"{\"command\":\"true\",\"description\":\"Exercise missing sandbox runner\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":10,"time":1785304900010,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":1,"outputTokens":1}}}}
|
||||
{"type":"assistant/chunk","seq":11,"time":1785304900011,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":12,"time":1785825343557,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"missing-runner-foreground","name":"bash","arguments":"{\"command\":\"true\",\"description\":\"Exercise missing sandbox runner\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"9e30fc63-1414-487c-aab9-ad114818118c"},"usage":{"inputTokens":1,"outputTokens":1}},"sourceEventSeqs":[7,8,9,10,11],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":13,"time":1785825343557,"data":{"turn":1,"step":1,"callId":"missing-runner-foreground","name":"bash","arguments":"{\"command\":\"true\",\"description\":\"Exercise missing sandbox runner\"}"}}
|
||||
{"type":"tool/result","seq":14,"time":1785825343574,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"missing-runner-foreground"},"content":[{"type":"tool-result","toolCallId":"missing-runner-foreground","content":[{"type":"text","text":"Error: sandbox mode \"read-only\" is requested but no sandbox backend is usable on this host; refusing to run the command unconfined. Install bubblewrap or run a Landlock-enforcing kernel (Linux), ensure sandbox-exec is usable (macOS) — Windows has no confinement backend yet — or switch the consumer to danger-full-access. Runner failure: Error: spawn {{cwd}}/.dsh-missing-sandbox-runner ENOENT"}],"isError":true}],"role":"user","id":"48c382bd-1b30-4af0-b3e4-2c7bb811ba71"},"error":{"name":"SandboxUnavailableError","code":"SANDBOX_UNAVAILABLE"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":15,"time":1785825343574,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":16,"time":1785825343581,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":17,"time":1785304900017,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","seq":18,"time":1785304900018,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"missing-runner-background","name":"bash","argumentsDelta":"{\"command\":\"true\",\"description\":\"Exercise missing sandbox runner in background\",\"run_in_background\":true}"}}}
|
||||
{"type":"assistant/chunk","seq":19,"time":1785304900019,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"missing-runner-background","name":"bash","arguments":"{\"command\":\"true\",\"description\":\"Exercise missing sandbox runner in background\",\"run_in_background\":true}"}}}}
|
||||
{"type":"assistant/chunk","seq":20,"time":1785304900020,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":1,"outputTokens":1}}}}
|
||||
{"type":"assistant/chunk","seq":21,"time":1785825343587,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":22,"time":1785825343587,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"missing-runner-background","name":"bash","arguments":"{\"command\":\"true\",\"description\":\"Exercise missing sandbox runner in background\",\"run_in_background\":true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"0888df6a-237b-4b8b-9a4a-bdd8b42e1b3a"},"usage":{"inputTokens":1,"outputTokens":1}},"sourceEventSeqs":[17,18,19,20,21],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":23,"time":1785825343587,"data":{"turn":1,"step":2,"callId":"missing-runner-background","name":"bash","arguments":"{\"command\":\"true\",\"description\":\"Exercise missing sandbox runner in background\",\"run_in_background\":true}"}}
|
||||
{"type":"tool/result","seq":24,"time":1785825343595,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"missing-runner-background"},"content":[{"type":"tool-result","toolCallId":"missing-runner-background","content":[{"type":"text","text":"started background task bash-1"}],"isError":false}],"role":"user","id":"59acf44c-7ad3-4778-a12f-997c76d657e3"}},"sourceEventSeqs":[23],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":25,"time":1785825343595,"data":{"turn":1,"step":2}}
|
||||
{"type":"user/message","seq":26,"time":1785825343603,"data":{"content":[{"type":"text","text":"background task bash-1 (bash: true) finished [status: killed, killed before exit]. Read its output with task_output."}],"source":{"kind":"plugin","plugin":"tool-tasks"},"role":"user","id":"4ca0c254-b6de-4c5a-8484-430ed6a69761"},"surfaceOp":"append"}
|
||||
{"type":"step/start","seq":27,"time":1785825343603,"data":{"turn":1,"step":3}}
|
||||
{"type":"assistant/chunk","seq":28,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","seq":29,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"tool-call-delta","index":0,"id":"missing-runner-output","name":"task_output","argumentsDelta":"{\"task_id\":\"bash-1\",\"wait\":true}"}}}
|
||||
{"type":"assistant/chunk","seq":30,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"missing-runner-output","name":"task_output","arguments":"{\"task_id\":\"bash-1\",\"wait\":true}"}}}}
|
||||
{"type":"assistant/chunk","seq":31,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"usage","usage":{"inputTokens":1,"outputTokens":1}}}}
|
||||
{"type":"assistant/chunk","seq":32,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":33,"time":1785825343608,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"missing-runner-output","name":"task_output","arguments":"{\"task_id\":\"bash-1\",\"wait\":true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"19d8d568-a056-45e0-a3b4-21e26e7cbc26"},"usage":{"inputTokens":1,"outputTokens":1}},"sourceEventSeqs":[28,29,30,31,32],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":34,"time":1785825343608,"data":{"turn":1,"step":3,"callId":"missing-runner-output","name":"task_output","arguments":"{\"task_id\":\"bash-1\",\"wait\":true}"}}
|
||||
{"type":"tool/result","seq":35,"time":1785825343615,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"missing-runner-output"},"content":[{"type":"tool-result","toolCallId":"missing-runner-output","content":[{"type":"text","text":"[stderr]\nspawn failed: Error: spawn {{cwd}}/.dsh-missing-sandbox-runner ENOENT\n[sandbox: the sandbox runner itself failed under read-only mode — the command did not run; this is a sandbox problem, not a command failure]\n[status: killed, killed before exit]"}],"isError":false}],"role":"user","id":"3a637de6-c9f5-4474-9bbc-ee8ec354e27b"}},"sourceEventSeqs":[34],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":36,"time":1785825343615,"data":{"turn":1,"step":3}}
|
||||
{"type":"step/start","seq":37,"time":1785825343622,"data":{"turn":1,"step":4}}
|
||||
{"type":"assistant/chunk","seq":38,"time":1785825343627,"data":{"turn":1,"step":4,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":39,"time":1785825343627,"data":{"turn":1,"step":4,"chunk":{"type":"text-delta","index":0,"text":"RUNNER_FAILURES_SURFACED"}}}
|
||||
{"type":"assistant/chunk","seq":40,"time":1785825343627,"data":{"turn":1,"step":4,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"RUNNER_FAILURES_SURFACED"}}}}
|
||||
{"type":"assistant/chunk","seq":41,"time":1785825343627,"data":{"turn":1,"step":4,"chunk":{"type":"usage","usage":{"inputTokens":1,"outputTokens":1}}}}
|
||||
{"type":"assistant/chunk","seq":42,"time":1785825343628,"data":{"turn":1,"step":4,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":43,"time":1785825343628,"data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"text","text":"RUNNER_FAILURES_SURFACED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"59317a54-459a-4383-bcd3-eea76ab8de2a"},"usage":{"inputTokens":1,"outputTokens":1}},"sourceEventSeqs":[38,39,40,41,42],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":44,"time":1785825343628,"data":{"turn":1,"step":4}}
|
||||
{"type":"turn/end","seq":45,"time":1785825343628,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
@@ -0,0 +1,4 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
|
||||
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}"}}
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_message_chunk","content":{"type":"text","text":"RUNNER_FAILURES_SURFACED"}}}}
|
||||
{"jsonrpc":"2.0","id":3,"result":{"stopReason":"end_turn"}}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"steps": [
|
||||
{ "op": "initialize" },
|
||||
{ "op": "newSession" },
|
||||
{ "op": "prompt", "text": "Use the bash tool to run exactly: false. Then reply with exactly CHILD_EXIT_PRESERVED and stop." }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{"type":"session","version":0,"id":"44444444-4444-4444-8444-444444444444","createdAt":1785218500000,"cwd":"{{cwd}}","delegationDepth":0}
|
||||
{"type":"turn/start","seq":0,"time":1785218500001,"data":{"turn":1,"trigger":{"kind":"message","source":{"kind":"user"}}}}
|
||||
{"type":"user/message","seq":1,"time":1785218500002,"data":{"content":[{"type":"text","text":"Use the bash tool to run exactly: false. Then reply with exactly CHILD_EXIT_PRESERVED and stop."}],"source":{"kind":"user"},"role":"user","id":"44444444-4444-4444-8444-444444444445"},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":2,"time":1785218500003,"data":{"title":"Use the bash tool to","messageSeqs":[1],"source":{"kind":"fallback"}}}
|
||||
{"type":"user/message","seq":3,"time":1785218500004,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt"},"role":"user","id":"44444444-4444-4444-8444-444444444446"},"surfaceOp":"append"}
|
||||
{"type":"step/start","seq":4,"time":1785218500005,"data":{"turn":1,"step":1}}
|
||||
{"type":"request/header","seq":5,"time":1785218500006,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"request/context","seq":6,"time":1785218500007,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
|
||||
{"type":"assistant/chunk","seq":7,"time":1785218500008,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
{"type":"assistant/chunk","seq":8,"time":1785218500009,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"partial-landlock-call","name":"bash","argumentsDelta":"{\"command\":\"false\",\"description\":\"Exit with status one\"}"}}}
|
||||
{"type":"assistant/chunk","seq":9,"time":1785218500010,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"partial-landlock-call","name":"bash","arguments":"{\"command\":\"false\",\"description\":\"Exit with status one\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":10,"time":1785218500011,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":1,"outputTokens":1}}}}
|
||||
{"type":"assistant/chunk","seq":11,"time":1785218500012,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":12,"time":1785218500013,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"partial-landlock-call","name":"bash","arguments":"{\"command\":\"false\",\"description\":\"Exit with status one\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"44444444-4444-4444-8444-444444444447"},"usage":{"inputTokens":1,"outputTokens":1}},"sourceEventSeqs":[7,8,9,10,11],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":13,"time":1785218500014,"data":{"turn":1,"step":1,"callId":"partial-landlock-call","name":"bash","arguments":"{\"command\":\"false\",\"description\":\"Exit with status one\"}"}}
|
||||
{"type":"tool/result","seq":14,"time":1785218500015,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"partial-landlock-call"},"content":[{"type":"tool-result","toolCallId":"partial-landlock-call","content":[{"type":"text","text":"[stderr]\nlandlock-run: partial enforcement (older Landlock ABI)\n[exit code: 1]"}],"isError":false}],"role":"user","id":"44444444-4444-4444-8444-444444444448"}},"sourceEventSeqs":[13],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":15,"time":1785218500016,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":16,"time":1785218500017,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":17,"time":1785218500018,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":18,"time":1785218500019,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"CHILD_EXIT_PRESERVED"}}}
|
||||
{"type":"assistant/chunk","seq":19,"time":1785218500020,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"CHILD_EXIT_PRESERVED"}}}}
|
||||
{"type":"assistant/chunk","seq":20,"time":1785218500021,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":1,"outputTokens":1}}}}
|
||||
{"type":"assistant/chunk","seq":21,"time":1785218500022,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":22,"time":1785218500023,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"text","text":"CHILD_EXIT_PRESERVED"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"44444444-4444-4444-8444-444444444449"},"usage":{"inputTokens":1,"outputTokens":1}},"sourceEventSeqs":[17,18,19,20,21],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":23,"time":1785218500024,"data":{"turn":1,"step":2}}
|
||||
{"type":"turn/end","seq":24,"time":1785218500025,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
@@ -0,0 +1,4 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
|
||||
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}"}}
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_message_chunk","content":{"type":"text","text":"CHILD_EXIT_PRESERVED"}}}}
|
||||
{"jsonrpc":"2.0","id":3,"result":{"stopReason":"end_turn"}}
|
||||
@@ -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/headless-agent/README.md
|
||||
README.md: 445804a2611e5e8093eadf345ad10a2a7984c012
|
||||
README.zh.md: f1cf1964bbe15bc2b15abcd78a12fc1ffe7ea767
|
||||
README.md: 670a91ab402cf98585f2ece70787beb3b4aaf4dc
|
||||
README.zh.md: 6c8b3b5694403c5e09f2904f5c3ca18fe569163e
|
||||
|
||||
@@ -19,8 +19,8 @@ Exactly one nonblank positional task is required; quote tasks containing spaces.
|
||||
|
||||
Each invocation creates and persists a fresh session, runs all model and tool steps in one turn, flushes, disposes, and exits. This is non-interactive automation: there is no prompt, approval, resume, second turn, or stdin context. The configured tools can mutate the launch workspace, run commands, spawn child agents, and consume provider tokens.
|
||||
|
||||
## Advanced and snapshot wiring
|
||||
## Advanced configuration
|
||||
|
||||
[`advanced.cordis.yml`](advanced.cordis.yml) adds Code Mode and the Cordis tools to the shipped leaf. [`advanced.cordis.snapshot.yml`](advanced.cordis.snapshot.yml) replaces only the live LLM with replay. The tests under [`tests/`](tests/) own the keyless real-Loader smoke, key-gated world-verified smoke, and the `stream-json` replay snapshot with its parent and child session fixtures.
|
||||
[`advanced.cordis.yml`](advanced.cordis.yml) adds Code Mode and the Cordis tools to the shipped leaf.
|
||||
|
||||
The package-level [CLI contract](../../packages/examples/cli-demo/README.md) documents output records, exit status, cancellation, persistence, and model/token effects.
|
||||
|
||||
@@ -19,8 +19,8 @@ pnpm run demo:headless --output-format stream-json -- "run the focused tests"
|
||||
|
||||
每次调用都会创建并持久化新会话,在一个轮次中运行所有模型和工具步骤,然后刷写持久化数据、执行 dispose(资源释放),再退出。这是非交互式自动化:没有提示符、批准、恢复、第二轮次或 stdin 上下文。已配置工具可以修改启动时所在的工作区、运行命令、spawn 子 agent,并消耗提供方 token。
|
||||
|
||||
## 高级与快照接线
|
||||
## 高级配置
|
||||
|
||||
[`advanced.cordis.yml`](advanced.cordis.yml) 在已交付叶节点上添加 Code Mode 和 Cordis 工具。[`advanced.cordis.snapshot.yml`](advanced.cordis.snapshot.yml) 只将实时 LLM(大语言模型)替换为回放。[`tests/`](tests/) 下涵盖无密钥真实 Loader 冒烟测试、密钥门控的外部状态验证冒烟测试,以及带父子会话 fixture(测试前置数据)的 `stream-json` 回放快照。
|
||||
[`advanced.cordis.yml`](advanced.cordis.yml) 在已交付叶节点上添加 Code Mode 和 Cordis 工具。
|
||||
|
||||
这份包级 [CLI(命令行界面)契约](../../packages/examples/cli-demo/README.md) 说明输出记录、退出状态、取消、持久化以及模型/token 影响。
|
||||
|
||||
@@ -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/jsonrpc-agent/README.md
|
||||
README.md: 5e7b7d79415a4af0b0d16c61b0a4590dce57e545
|
||||
README.zh.md: 00450838e7d10ae9e95624b5f89992dd747d5440
|
||||
README.md: bcc1027d2edb30ab374dfa2ed13ad8e6360d923b
|
||||
README.zh.md: 197c25d7b4f5645aeb7e92d8c36ef4a423beb2e8
|
||||
|
||||
@@ -33,8 +33,4 @@ Pass the config path through the Python SDK's `cordis` option or `DSH_CORDIS_CON
|
||||
- owner-scoped persistent `bash`
|
||||
- `str_replace_editor` with `view`, `create`, `str_replace`, and `insert`
|
||||
|
||||
It composes the real local PTY, filesystem intent policy, and session sandbox policy. The keyless SDK snapshot drives the shipped JSON-RPC runtime through both tools, proves that shell cwd/environment survive across calls, and pins the notification stream, turn result, and persisted JSONL:
|
||||
|
||||
```bash
|
||||
pnpm exec vitest run --config vitest.snapshot.config.ts -t persistent-tools
|
||||
```
|
||||
It composes the local PTY, filesystem intent policy, and session sandbox policy.
|
||||
|
||||
@@ -33,8 +33,4 @@
|
||||
- agent 独占、状态持久的 `bash`
|
||||
- 提供 `view`、`create`、`str_replace` 与 `insert` 的 `str_replace_editor`
|
||||
|
||||
它组合真实本地 PTY、文件系统 intent 策略与 session 沙箱策略。无密钥 SDK 快照会通过正式 JSON-RPC runtime 驱动这两个工具,验证 shell 的 cwd 与环境变量能跨调用保留,并锁定通知流、轮次结果与已持久化的 JSONL:
|
||||
|
||||
```bash
|
||||
pnpm exec vitest run --config vitest.snapshot.config.ts -t persistent-tools
|
||||
```
|
||||
它组合本地 PTY、文件系统 intent 策略与会话沙箱策略。
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"@deepseek-ai/dsh-pwsh-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-repeat-tool-guard": "workspace:*",
|
||||
"@deepseek-ai/dsh-repository-plugin": "workspace:*",
|
||||
"@deepseek-ai/dsh-sandbox": "workspace:*",
|
||||
"@deepseek-ai/dsh-sandbox-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-sandbox-policy": "workspace:^",
|
||||
"@deepseek-ai/dsh-scope": "workspace:*",
|
||||
|
||||
6
examples/web-cordis/README.i18n.yaml
Normal file
6
examples/web-cordis/README.i18n.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write examples/web-cordis/README.md
|
||||
README.md: 75c7610fecc20777607c7c8cbb6ed2fc7f590b73
|
||||
README.zh.md: 5c25347ee17037bbfc7d10a5507424ce52e3faff
|
||||
21
examples/web-cordis/README.md
Normal file
21
examples/web-cordis/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# web-cordis
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Self-referential demonstration of [`@deepseek-ai/dsh-tool-cordis`](../../packages/cordis/tool-cordis/README.md). The agent can inspect its current Cordis process and mount or unmount model-authored plugins in memory. Temporary plugins disappear when they are unmounted or the process exits and may affect other sessions in the same process.
|
||||
|
||||
## Run it
|
||||
|
||||
Start the browser interface:
|
||||
|
||||
```sh
|
||||
pnpm run demo:cordis
|
||||
```
|
||||
|
||||
Start the ACP automation server instead:
|
||||
|
||||
```sh
|
||||
pnpm run demo:cordis acp
|
||||
```
|
||||
|
||||
Both commands require `DEEPSEEK_API_KEY`. The [Cordis tool reference](../../packages/cordis/tool-cordis/README.md) owns the tool, lifecycle, and safety contracts.
|
||||
21
examples/web-cordis/README.zh.md
Normal file
21
examples/web-cordis/README.zh.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# web-cordis
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
[`@deepseek-ai/dsh-tool-cordis`](../../packages/cordis/tool-cordis/README.md) 的自指示例。agent(智能体)可以检查当前 Cordis 进程,并在内存中挂载或卸载模型编写的插件。临时插件会在卸载或进程退出时消失,并可能影响同一进程中的其他会话。
|
||||
|
||||
## 运行
|
||||
|
||||
启动浏览器界面:
|
||||
|
||||
```sh
|
||||
pnpm run demo:cordis
|
||||
```
|
||||
|
||||
改为启动 ACP(Agent Client Protocol)自动化服务器:
|
||||
|
||||
```sh
|
||||
pnpm run demo:cordis acp
|
||||
```
|
||||
|
||||
这两条命令都需要 `DEEPSEEK_API_KEY`。工具、生命周期和安全契约由 [Cordis 工具参考](../../packages/cordis/tool-cordis/README.md)定义。
|
||||
Reference in New Issue
Block a user