refactor(profiles): select PTC execution through overlays

This commit is contained in:
_Kerman committed 2026-10-19 17:34:49 +08:00
1 parent fa8e928e4f
commit 78b577faa4
28 files changed
+81 -71

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
- id: tool-executor-native
disabled: true
- id: tool-executor-ptc
disabled: false
+2 -2
View File
@@ -21,8 +21,8 @@
en: 8d2cfff9bab7327f
zh: 21515ab6e6798504
/dsh-cli-behavior-reference/web-profile:
en: 850434e8ca162221
zh: 4893613f97a21eb8
en: 179aa84fb1f628c0
zh: 01da19b1a5d6aaf3
/dsh-cli-behavior-reference/shared-deployment-behavior:
en: 6a7abc9339e8f37f
zh: 133adb834c8e195d
+1 -1
View File
@@ -130,7 +130,7 @@ The base-backed modes treat the invoking directory as the default workspace root
New sessions in base-backed profiles default to the `workspace-write` permission preset. Bash and filesystem mutations are restricted to the session workspace and platform temporary roots; reads and network access are not confined, while process visibility depends on the selected sandbox backend — bwrap runs commands in a private PID namespace that hides host processes, and Landlock and Seatbelt leave host process visibility unchanged. `DSH_PERMISSION_MODE` changes the process fallback. Stored General-settings permissions affect later Web sessions, not an already-open one. The standalone `sdk-minimal` tree instead pins `danger-full-access` and mounts no approval or permission-settings service.
`DSH_TOOLS_MODE` selects `native` or `ptc` for the process; another value fails at boot. The shipped `minimal` agent preset keeps that deployment presentation, fixes the complete system prompt to `You are a helpful software engineer assistant.`, and provides the platform-selected persistent shell, `read_image`, and `working_directory`. It supports automatic context compaction and the human `/compact` command. Select 极简模式 when creating a Web session; the shared browser, workspace, persistence, sandbox, and permission host remains in place.
Web and headless inherit native tool execution from the base bundle; use a [PTC overlay](../config/examples/ptc.yml) to select PTC. The shipped `minimal` agent preset keeps that deployment presentation, fixes the complete system prompt to `You are a helpful software engineer assistant.`, and provides the platform-selected persistent shell, `read_image`, and `working_directory`. It supports automatic context compaction and the human `/compact` command. Select 极简模式 when creating a Web session; the shared browser, workspace, persistence, sandbox, and permission host remains in place.
## Shared deployment behavior
+1 -1
View File
@@ -132,7 +132,7 @@ dsh web --help
基于 base 的 profile 中,新会话默认使用 `workspace-write` 权限预设。Bash 和文件系统修改仅限于会话 workspace 与平台临时根目录;读取和网络访问不受限制,进程可见性则取决于所选沙箱后端——bwrap 在私有 PID 命名空间中运行命令并隐藏宿主进程,Landlock 与 Seatbelt 保持宿主进程可见性不变。`DSH_PERMISSION_MODE` 更改进程后备值。General settings 中存储的权限影响后续 Web 会话,不改变已打开的会话。独立的 `sdk-minimal` 配置树则固定为 `danger-full-access`,且不挂载 approval 或权限 settings 服务。
`DSH_TOOLS_MODE` 为进程选择 `native` 或 `ptc`;其他值会导致启动失败。随附的 `minimal` agent preset 会保留该部署的呈现方式,将完整系统提示词固定为 `You are a helpful software engineer assistant.`,并提供按平台选择的持久 shell、`read_image` 和 `working_directory`。它支持自动上下文压缩和用户 `/compact` 命令。创建 Web 会话时请选择极简模式;共享的浏览器、workspace、持久化、沙箱与权限宿主保持不变。
Web 与 headless 继承 base bundle 的原生工具执行;使用 [PTC overlay](../config/examples/ptc.yml) 可选择 PTC。随附的 `minimal` agent preset 会保留该部署的呈现方式,将完整系统提示词固定为 `You are a helpful software engineer assistant.`,并提供按平台选择的持久 shell、`read_image` 和 `working_directory`。它支持自动上下文压缩和用户 `/compact` 命令。创建 Web 会话时请选择极简模式;共享的浏览器、workspace、持久化、沙箱与权限宿主保持不变。
## 共享部署行为
@@ -555,7 +555,7 @@ describe('headless stream-json snapshots', () => {
'--permission-mode', 'auto', '--approval-policy', 'never', '--json', 'Run the CLI probe.',
],
tsconfigPath,
env: { DSH_AUTO_REVIEW_TEST_MODE: mode, DSH_TOOLS_MODE: 'native', DSH_TELEMETRY_DISABLED: '1' },
env: { DSH_AUTO_REVIEW_TEST_MODE: mode, DSH_TELEMETRY_DISABLED: '1' },
inspect: async (cwd) => {
const logs = await persistedLogs(cwd, join(cwd, '.dsh', 'sessions'))
expect(logs).toHaveLength(1)
@@ -605,7 +605,7 @@ describe('headless stream-json snapshots', () => {
const first = await runLoaderSmoke({
label: 'headless Auto denied wake', cwd, binScript: dshBinScript, configPath: autoReviewOverlayPath,
binArgs: [...args, '--permission-mode', 'auto', '--approval-policy', 'never', 'Run the CLI probe.'], tsconfigPath,
env: { DSH_AUTO_REVIEW_TEST_MODE: 'deny', DSH_TOOLS_MODE: 'native', DSH_TELEMETRY_DISABLED: '1' },
env: { DSH_AUTO_REVIEW_TEST_MODE: 'deny', DSH_TELEMETRY_DISABLED: '1' },
})
const sessionId = parseJsonl(first.stdout)[0]?.sessionId
if (typeof sessionId !== 'string') throw new Error('missing Auto Session identity')
@@ -615,7 +615,7 @@ describe('headless stream-json snapshots', () => {
const second = await runLoaderSmoke({
label: 'headless Auto authorized wake', cwd, binScript: dshBinScript, configPath: autoReviewOverlayPath,
binArgs: [...args, '--session-id', sessionId, 'I authorize the exact CLI probe. Retry it.'], tsconfigPath,
env: { DSH_AUTO_REVIEW_TEST_MODE: 'allow', DSH_TOOLS_MODE: 'native', DSH_TELEMETRY_DISABLED: '1' },
env: { DSH_AUTO_REVIEW_TEST_MODE: 'allow', DSH_TELEMETRY_DISABLED: '1' },
inspect: async (directory) => {
const logs = await persistedLogs(directory, join(directory, '.dsh', 'sessions'))
expect(logs).toHaveLength(1)
@@ -58,7 +58,6 @@ describe.skipIf(!existsSync(join(repoRoot, 'apps/cli/lib/bin.js')))('dsh SOURCE
DSH_HOME: join(root, 'home'),
DSH_AGENTS_HOME: join(root, 'agents'),
DSH_TELEMETRY_DISABLED: '1',
DSH_TOOLS_MODE: 'native',
DSH_CLI_MOCK_FAILURE: '0',
},
input: '',
@@ -58,7 +58,7 @@ it.skipIf(!process.env.DEEPSEEK_API_KEY || process.platform === 'win32')(`agent
], {
cwd: root, env: {
PATH: path, DSH_HOME: join(root, 'home'), DSH_AGENTS_HOME: join(root, 'agents'),
DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1', DSH_TOOLS_MODE: 'native',
DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1',
DSH_PRIMARY_RUNTIME: carrier === 'sdk' ? undefined : '',
},
timeout: 110_000, killSignal: 'SIGKILL', reject: false,
-8
View File
@@ -384,13 +384,6 @@ export interface LaunchOptions {
paceMs?: number
/** Synthetic model capacity for UI scenarios whose seeded history must remain uncompacted. */
replayContextWindow?: number
/**
* Tool presentation mode patched onto the shipped `tools` row (`code`
* collapses the wire to run_code + the SDK prompt section). Omit for the
* yml default. The PTC runtime row is always in the tree, so no extra
* insertion is needed.
*/
toolsMode?: 'native' | 'ptc'
/**
* Keep the shipped DeepSeek adapter mounted while masking the process
* environment's DEEPSEEK_API_KEY for this scaffold lifetime. This is the
@@ -689,7 +682,6 @@ export async function launchWebScaffold(options: LaunchOptions = {}): Promise<We
{ id: 'agent-preset-registry', config: { default: options.agentPresets.default } },
{ insert: (options.agentPresets.definitions ?? []).map(config => ({ id: `preset-${config.id}`, name: '@deepseek-ai/dsh-agent-preset', config })) },
],
...options.toolsMode === undefined ? [] : [{ id: 'tools', config: { mode: options.toolsMode } }],
...options.deepSeekSearch === undefined
? []
: [{
+15 -6
View File
@@ -603,7 +603,7 @@ describe('dsh web keyless CLI smoke', () => {
}
}, 120_000)
it('DSH_TOOLS_MODE=ptc collapses the provider wire tools to run_code with the SDK prompt section', async () => {
it.each(['native', 'ptc'] as const)('selects the %s executor through profile overlays and ignores the retired environment selector', async (mode) => {
requireDist()
const workspace = mkdtempSync(join(tmpdir(), 'dsh-web-ptc-'))
@@ -632,14 +632,17 @@ describe('dsh web keyless CLI smoke', () => {
const tsxLoader = pathToFileURL(createRequire(join(REPO_ROOT, 'package.json')).resolve('tsx')).href
const child = spawn(
process.execPath,
['--import', tsxLoader, join(REPO_ROOT, 'apps/cli/src/bin.ts'), 'web', '--no-open', '--port', '0'],
['--import', tsxLoader, join(REPO_ROOT, 'apps/cli/src/bin.ts'), 'web',
...mode === 'ptc' ? ['--patch', join(REPO_ROOT, 'apps/cli/config/examples/ptc.yml')] : [],
'--no-open', '--port', '0',
],
{
cwd: workspace,
env: {
...process.env,
DEEPSEEK_API_KEY: 'keyless-web-ptc',
DEEPSEEK_BASE_URL: `http://127.0.0.1:${address.port}`,
DSH_TOOLS_MODE: 'ptc',
DSH_TOOLS_MODE: mode === 'native' ? 'ptc' : 'native',
DSH_HOME: join(workspace, '.dsh'),
DSH_AGENTS_HOME: join(workspace, '.agents'),
TSX_TSCONFIG_PATH: join(REPO_ROOT, 'tsconfig.json'),
@@ -662,9 +665,15 @@ describe('dsh web keyless CLI smoke', () => {
setTimeout(() => { reject(new Error('provider request not received in 10s')) }, 10_000).unref()
}),
])
expect(captured.tools?.map(tool => tool.name)).toEqual(['run_code'])
expect(captured.system).toContain('## Writing code for run_code')
expect(captured.system).toContain('declare const tools')
if (mode === 'ptc') {
expect(captured.tools?.map(tool => tool.name)).toEqual(['run_code'])
expect(captured.system).toContain('## Writing code for run_code')
expect(captured.system).toContain('declare const tools')
} else {
expect(captured.tools?.map(tool => tool.name)).not.toContain('run_code')
expect(captured.tools?.length).toBeGreaterThan(0)
expect(captured.system).not.toContain('## Writing code for run_code')
}
} finally {
const closed = child.exitCode === null
? new Promise<void>((resolveClose) => { child.once('close', () => { resolveClose() }) })
@@ -9,8 +9,8 @@
en: 73002a2963b9ea27
zh: a67ea382d7c70c61
/mount-a-tool-executor/change:
en: f732d85027bf0236
zh: d6597cde7ba31e47
en: 6d9c056c4ec74661
zh: 340be0eddcd30049
/mount-a-tool-executor/migration:
en: 79369b132e00d7be
zh: e93523fa3369ae1c
en: 60ea8b9dd1128dfc
zh: 7c648e9e5d75c49b
@@ -9,7 +9,7 @@ English | [中文](guide.zh.md)
## Change
`@deepseek-ai/dsh-tools` keeps tool registration and executor selection, but rejects the removed `mode` and `maxParallelSubCalls` configuration fields at load time. Native and PTC execution require `@deepseek-ai/dsh-tool-executor-native` or `@deepseek-ai/dsh-tool-executor-ptc`. Shipped profiles mount an executor; custom compositions must add one. The existing `dsh-agent-tool-presentation` selector remains supported but is deprecated. Enabled `tool-executor-native` and `tool-executor-ptc` rows are required at startup; invalid executor configuration now stops startup.
`@deepseek-ai/dsh-tools` keeps tool registration and executor selection, but rejects the removed `mode` and `maxParallelSubCalls` configuration fields at load time. Native and PTC execution require `@deepseek-ai/dsh-tool-executor-native` or `@deepseek-ai/dsh-tool-executor-ptc`. Shipped profiles mount an executor; custom compositions must add one. The existing `dsh-agent-tool-presentation` selector remains supported but is deprecated. Enabled `tool-executor-native` and `tool-executor-ptc` rows are required at startup; invalid executor configuration now stops startup. Web and headless no longer read `DSH_TOOLS_MODE`; both inherit native execution from base.
## Migration
@@ -19,3 +19,17 @@ English | [中文](guide.zh.md)
4. Import PTC SDK renderers and `CodeRunFailedError` from `@deepseek-ai/dsh-tool-executor-ptc`. Run a task with the selected interaction mode and confirm its tool results appear in the Session.
5. Import `ToolExecutionPipeline` and `executeToolBatch` from `@deepseek-ai/dsh-tools/pipeline`. Complete calls, including single calls, use batches; custom schedulers call `prepare`, `dispatch`, and `complete` directly. Add `@deepseek-ai/dsh-tool-testkit` as a development dependency for tool fixtures and import them from that package. Neither is exported by the tool registry entry.
6. Import `PtcDispatchLog` from the PTC executor package using `import type`. Detached Session readers use `@deepseek-ai/dsh-tool-executor-ptc/types` for durable dispatch events. Live PTC policy and message-source declarations remain on the executor package entry.
7. Remove `DSH_TOOLS_MODE` from launch environments. For PTC, save the following as `ptc.yml` and pass it with `--patch`; native execution needs no overlay. The same patch works with `--profile web`. Confirm that the model receives only `run_code` in PTC mode.
```yaml
- id: tool-executor-native
disabled: true
- id: tool-executor-ptc
disabled: false
```
```bash
dsh --profile headless --patch ./ptc.yml "task"
```
@@ -9,7 +9,7 @@ description: "工具执行模式从 dsh-tools 配置移至显式执行器插件
## 变更
`@deepseek-ai/dsh-tools` 保留工具注册和执行器选择,但加载时会拒绝已移除的 `mode` 和 `maxParallelSubCalls` 配置字段。原生和 PTC 执行分别要求 `@deepseek-ai/dsh-tool-executor-native` 或 `@deepseek-ai/dsh-tool-executor-ptc`。内置 profile 已挂载执行器,自定义组合必须添加一个。现有 `dsh-agent-tool-presentation` 选择器仍受支持,但已弃用。启用的 `tool-executor-native` 和 `tool-executor-ptc` 条目属于启动必需项;无效的执行器配置会终止启动。
`@deepseek-ai/dsh-tools` 保留工具注册和执行器选择,但加载时会拒绝已移除的 `mode` 和 `maxParallelSubCalls` 配置字段。原生和 PTC 执行分别要求 `@deepseek-ai/dsh-tool-executor-native` 或 `@deepseek-ai/dsh-tool-executor-ptc`。内置 profile 已挂载执行器,自定义组合必须添加一个。现有 `dsh-agent-tool-presentation` 选择器仍受支持,但已弃用。启用的 `tool-executor-native` 和 `tool-executor-ptc` 条目属于启动必需项;无效的执行器配置会终止启动。Web 与 headless 不再读取 `DSH_TOOLS_MODE`,均继承 base 的原生执行。
## 迁移
@@ -19,3 +19,17 @@ description: "工具执行模式从 dsh-tools 配置移至显式执行器插件
4. 从 `@deepseek-ai/dsh-tool-executor-ptc` 导入 PTC SDK 渲染器和 `CodeRunFailedError`。用所选交互模式运行任务,确认工具结果出现在 Session 中。
5. 从 `@deepseek-ai/dsh-tools/pipeline` 导入 `ToolExecutionPipeline` 和 `executeToolBatch`。完整执行(包括单次调用)使用批次;自定义调度器直接调用 `prepare`、`dispatch` 和 `complete`。把 `@deepseek-ai/dsh-tool-testkit` 添加为开发依赖,并从该包导入工具 fixture。工具注册表主入口不再导出这些成员。
6. 使用 `import type` 从 PTC 执行器包导入 `PtcDispatchLog`。独立 Session 读取者通过 `@deepseek-ai/dsh-tool-executor-ptc/types` 获取持久化分派事件;PTC 实时策略与消息来源声明由执行器包主入口提供。
7. 从启动环境中移除 `DSH_TOOLS_MODE`。需要 PTC 时,将以下内容保存为 `ptc.yml` 并通过 `--patch` 加载;原生执行无需 overlay。同一补丁也适用于 `--profile web`。确认 PTC 模式下模型只收到 `run_code`。
```yaml
- id: tool-executor-native
disabled: true
- id: tool-executor-ptc
disabled: false
```
```bash
dsh --profile headless --patch ./ptc.yml "task"
```
+2 -2
View File
@@ -48,8 +48,8 @@
en: fdef19c52550fdf8
zh: c4bab4fb6972cf10
/deepseek-ai-dsh-headless/understand-the-implementation/patch-surface-over-base:
en: 290f49af13bb0ae1
zh: 5b599df1df8e6b7b
en: e192267973792ad1
zh: ef78428a68dff9e4
/deepseek-ai-dsh-headless/understand-the-implementation/exit-mapping:
en: c2466d3d8a26177a
zh: b75743bfa2e7723a
+1 -1
View File
@@ -125,7 +125,7 @@ The runner awaits the complete application (`ctx.get('loader')?.await()`) so the
### Patch surface over base
The patch rides over `dsh-base`: it inherits the projection cache and shared PTC runtime, sets the coding persona prefix and separate cwd suffix on the base `system-prompt` row, keeps the same temporary process-wide PTC mode opt-in (`DSH_TOOLS_MODE`) as the Web surface, disables the shared HMR row, and mounts the startup provider and the runner. The cache checkpoints each persisted one-shot session for later consumers; its durability barrier flushes each covered log prefix before publishing the cache row and may split otherwise coalesced JSONL runs. The startup provider ([`src/startup.ts`](src/startup.ts)) injects `ctx.cmdlineArgs` ([`dsh-cmdline`](../../boot/cmdline/README.md)), reads the task and invocation options, prints the app's `--help`, and provides `headlessStartup`; the runner reads its task, Session identity, and output mode from lazy config. It reads the explicit CLI permission preset and approval policy directly from `headlessStartup`, with runner config as the default. The sandbox-policy row also waits for this service, retaining the base mode and workspace defaults while receiving the explicit directory grants.
The patch rides over `dsh-base`: it inherits the projection cache and shared PTC runtime, sets the coding persona prefix and separate cwd suffix on the base `system-prompt` row, inherits native tool execution and accepts a [PTC overlay](../../../apps/cli/config/examples/ptc.yml), disables the shared HMR row, and mounts the startup provider and the runner. The cache checkpoints each persisted one-shot session for later consumers; its durability barrier flushes each covered log prefix before publishing the cache row and may split otherwise coalesced JSONL runs. The startup provider ([`src/startup.ts`](src/startup.ts)) injects `ctx.cmdlineArgs` ([`dsh-cmdline`](../../boot/cmdline/README.md)), reads the task and invocation options, prints the app's `--help`, and provides `headlessStartup`; the runner reads its task, Session identity, and output mode from lazy config. It reads the explicit CLI permission preset and approval policy directly from `headlessStartup`, with runner config as the default. The sandbox-policy row also waits for this service, retaining the base mode and workspace defaults while receiving the explicit directory grants.
### Exit mapping
+1 -1
View File
@@ -125,7 +125,7 @@ runner 等待整个应用结算(`ctx.get('loader')?.await()`),确保已组
### 基于 base 的 patch 内容
patch 叠加在 `dsh-base` 之上:继承投影缓存与共享 PTC 运行时,在基础 `system-prompt` 行上设置编码 persona 前缀与独立的 cwd 后缀,保留与 Web 表层相同的临时进程级 PTC mode 开关(`DSH_TOOLS_MODE`),禁用共享的 HMR(热模块替换)行,并挂载启动提供方与 runner。缓存为每个已持久化的一次性会话写入检查点,供后续消费方使用;其持久性屏障会在发布缓存行前 flush 所覆盖的日志前缀,因此可能拆分原本会合并的 JSONL 连续段。启动提供方([`src/startup.ts`](src/startup.ts))注入 `ctx.cmdlineArgs`([`dsh-cmdline`](../../boot/cmdline/README.zh.md)),读取任务和调用选项、打印应用自己的 `--help`,并提供 `headlessStartup`;runner 从延迟配置读取任务、Session 标识与输出模式。它直接从 `headlessStartup` 读取显式 CLI 权限预设与审批策略,以 runner 配置作为默认值。sandbox-policy 行也等待此服务,在保留基础模式和工作区默认值的同时接收显式目录授权。
patch 叠加在 `dsh-base` 之上:继承投影缓存与共享 PTC 运行时,在基础 `system-prompt` 行上设置编码 persona 前缀与独立的 cwd 后缀,继承原生工具执行,并支持 [PTC overlay](../../../apps/cli/config/examples/ptc.yml),禁用共享的 HMR(热模块替换)行,并挂载启动提供方与 runner。缓存为每个已持久化的一次性会话写入检查点,供后续消费方使用;其持久性屏障会在发布缓存行前 flush 所覆盖的日志前缀,因此可能拆分原本会合并的 JSONL 连续段。启动提供方([`src/startup.ts`](src/startup.ts))注入 `ctx.cmdlineArgs`([`dsh-cmdline`](../../boot/cmdline/README.zh.md)),读取任务和调用选项、打印应用自己的 `--help`,并提供 `headlessStartup`;runner 从延迟配置读取任务、Session 标识与输出模式。它直接从 `headlessStartup` 读取显式 CLI 权限预设与审批策略,以 runner 配置作为默认值。sandbox-policy 行也等待此服务,在保留基础模式和工作区默认值的同时接收显式目录授权。
### 退出映射
-12
View File
@@ -11,18 +11,6 @@
personaPrefix: >-
You are a coding agent powered by the {{model}} model.
- id: tool-executor-native
name: '@deepseek-ai/dsh-tool-executor-native'
disabled: !!js |
(() => {
const mode = process.env.DSH_TOOLS_MODE ?? 'native'
if (mode !== 'native' && mode !== 'ptc') throw new Error('DSH_TOOLS_MODE must be native or ptc')
return mode === 'ptc'
})()
- id: tool-executor-ptc
disabled: !!js process.env.DSH_TOOLS_MODE !== 'ptc'
- insert:
- id: headless-startup
name: '@deepseek-ai/dsh-headless/startup'
+2 -2
View File
@@ -36,8 +36,8 @@
en: 323742a00cfe67b2
zh: eff5245a82fc16e7
/deepseek-ai-dsh-web-app/understand-the-implementation/patch-semantics:
en: 8a2554b3d17daa1f
zh: 66f18946791cabb6
en: a6d126f30b1594d7
zh: 7f0ccc8a55d6f743
/deepseek-ai-dsh-web-app/understand-the-implementation/advertised-application-url:
en: 0b22e03e28d41420
zh: fd45a97dd4336c25
+1 -1
View File
@@ -102,7 +102,7 @@ The bundle is one patch layer of five files plus one runtime glue plugin: `cordi
### Patch semantics
A patch replaces the targeted row's whole `config`, so each web row restates every key it owns: the persona prefix template, the `DSH_TOOLS_MODE` PTC mode opt-in, and the `session-query-sqlite` values on the base rows, then `insert` adds the web host rows, transport, and browser roster. The `webserver`, `web-runtime`, and `connection` rows inject the `webStartup` provider and read their invocation values directly; Connection composes its accepted authorities from `ctx.webStartup.trustedHosts`, and the Host/Origin fence accepts the listener's bind IP independently of that list. The per-agent tool rows the base mounts process-wide are disabled here and the preset roster takes over; the reasoning for each host-plane versus preset-plane decision is inline in the patch.
A patch replaces the targeted row's whole `config`, so each web row restates every key it owns: the persona prefix template and the `session-query-sqlite` values on the base rows, then `insert` adds the web host rows, transport, and browser roster. The `webserver`, `web-runtime`, and `connection` rows inject the `webStartup` provider and read their invocation values directly; Connection composes its accepted authorities from `ctx.webStartup.trustedHosts`, and the Host/Origin fence accepts the listener's bind IP independently of that list. The bundle inherits native tool execution; a [PTC overlay](../../../apps/cli/config/examples/ptc.yml) changes the deployment executor. The per-agent tool rows the base mounts process-wide are disabled here and the preset roster takes over; the reasoning for each host-plane versus preset-plane decision is inline in the patch.
### Advertised application URL
+1 -1
View File
@@ -102,7 +102,7 @@ dsh --profile web --no-open --host "$(hostname -i | awk '{print $1}')" --public-
### patch 语义
patch 会替换目标行的整个 `config`,因此每个 Web 行都重述自己拥有的每个键:基础行上的 persona 前缀模板、`DSH_TOOLS_MODE` PTC mode 开关与 `session-query-sqlite` 值,随后 `insert` 添加 Web 宿主行、传输层与浏览器名录。`webserver`、`web-runtime` 与 `connection` 行都注入 `webStartup` 提供方并直接读取本次调用的取值;Connection 的被接受 authority 全部来自 `ctx.webStartup.trustedHosts`,Host/Origin 栅栏则独立于该列表接受监听器的绑定 IP。base 以进程级挂载的按 agent 工具行在这里被禁用,由 preset 名录接管;每项宿主层与 preset 层归属决策的理由以行内注释写在 patch 里。
patch 会替换目标行的整个 `config`,因此每个 Web 行都重述自己拥有的每个键:基础行上的 persona 前缀模板与 `session-query-sqlite` 值,随后 `insert` 添加 Web 宿主行、传输层与浏览器名录。`webserver`、`web-runtime` 与 `connection` 行都注入 `webStartup` 提供方并直接读取本次调用的取值;Connection 的被接受 authority 全部来自 `ctx.webStartup.trustedHosts`,Host/Origin 栅栏则独立于该列表接受监听器的绑定 IP。bundle 继承原生工具执行;[PTC overlay](../../../apps/cli/config/examples/ptc.yml) 可切换部署执行器。base 以进程级挂载的按 agent 工具行在这里被禁用,由 preset 名录接管;每项宿主层与 preset 层归属决策的理由以行内注释写在 patch 里。
### 公告应用 URL
-12
View File
@@ -29,18 +29,6 @@
path: ':memory:'
openAt: never
- id: tool-executor-native
name: '@deepseek-ai/dsh-tool-executor-native'
disabled: !!js |
(() => {
const mode = process.env.DSH_TOOLS_MODE ?? 'native'
if (mode !== 'native' && mode !== 'ptc') throw new Error('DSH_TOOLS_MODE must be native or ptc')
return mode === 'ptc'
})()
- id: tool-executor-ptc
disabled: !!js process.env.DSH_TOOLS_MODE !== 'ptc'
# ── web-only host rows, the transport layer, and the browser roster ─────────
# `dsh.client` rows are the browser roster the modules node half scans into
+1 -1
View File
@@ -50,7 +50,7 @@ Enable the experimental layer explicitly for the headless profile:
```sh
dsh plugin --profile headless add @deepseek-ai/dsh-experimental-auto-review
DSH_TOOLS_MODE=native dsh headless --permission-mode auto --approval-policy never --json - < task.txt > run.jsonl
dsh headless --permission-mode auto --approval-policy never --json - < task.txt > run.jsonl
```
For a one-off run from this checkout, pass `--patch /absolute/path/to/packages/experimental/auto-review/cordis.patch.yml` instead of installing a profile layer. An unavailable Auto integration fails preset selection before reading stdin or starting model work. Auto uses full host access; `--add-dir` is unnecessary in this mode. Native tools keep every tool body on the review path; direct Node effects in PTC remain outside it.
@@ -50,7 +50,7 @@ pnpm dsh plugin --profile web remove @deepseek-ai/dsh-experimental-auto-review
```sh
dsh plugin --profile headless add @deepseek-ai/dsh-experimental-auto-review
DSH_TOOLS_MODE=native dsh headless --permission-mode auto --approval-policy never --json - < task.txt > run.jsonl
dsh headless --permission-mode auto --approval-policy never --json - < task.txt > run.jsonl
```
如需从此 checkout 单次运行,可传入 `--patch /absolute/path/to/packages/experimental/auto-review/cordis.patch.yml`,无需安装 profile 层。Auto integration 不可用时,权限预设选择会在读取 stdin 或开始模型工作前失败。Auto 使用完全主机访问权限;此模式不需要 `--add-dir`。原生工具让每个工具 body 都经过审查;PTC 的直接 Node 效果仍不在审查范围内。
@@ -19,8 +19,9 @@ it.skipIf(!process.env.DEEPSEEK_API_KEY || !runtime).each(['native', 'ptc'])('ch
binScript: join(repo, 'apps/cli/src/bin.ts'), sourceImport: 'tsx/esm', tsconfigPath: join(repo, 'tsconfig.base.json'),
configPath: 'office.patch.json', processTimeoutMs: 110_000,
binArgs: ['--profile', 'headless', '--patch', 'office.patch.json',
...mode === 'ptc' ? ['--patch', join(repo, 'apps/cli/config/examples/ptc.yml')] : [],
'In input.docx, change the title paragraph text to Quarterly results without changing its formatting; save result.docx. Do not render or visually inspect the finished file. Respond briefly in English.'],
env: { DSH_PRIMARY_RUNTIME: runtime, DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1', DSH_TOOLS_MODE: mode,
env: { DSH_PRIMARY_RUNTIME: runtime, DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1',
HTTP_PROXY: process.env.DSH_OFFICE_TEST_PROXY, HTTPS_PROXY: process.env.DSH_OFFICE_TEST_PROXY },
async prepare(cwd) {
await execa(python!, ['-c', `
@@ -15,7 +15,7 @@ const python = runtime && join(runtime, 'dependencies/python', process.platform
const launch = {
binScript: join(repo, 'apps/cli/src/bin.ts'), sourceImport: 'tsx/esm' as const, tsconfigPath: join(repo, 'tsconfig.base.json'),
configPath: 'office.patch.json', processTimeoutMs: 110_000,
env: { DSH_PRIMARY_RUNTIME: runtime, DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1', DSH_TOOLS_MODE: 'native',
env: { DSH_PRIMARY_RUNTIME: runtime, DSH_PERMISSION_MODE: 'danger-full-access', DSH_TELEMETRY_DISABLED: '1',
HTTP_PROXY: process.env.DSH_OFFICE_TEST_PROXY, HTTPS_PROXY: process.env.DSH_OFFICE_TEST_PROXY },
}
@@ -39,8 +39,9 @@ async function sessionEvents(cwd: string) {
it.skipIf(!process.env.DEEPSEEK_API_KEY || !runtime).each([{ format: 'docx', mode: 'native' }, { format: 'pdf', mode: 'native' }, { format: 'docx', mode: 'ptc' }])('loads the operation skill and renders $format through the shell in $mode mode', async ({ format, mode }) => {
await runLoaderSmoke({
label: 'Office CLI rendering', tempDirPrefix: 'dsh-office-render-',
...launch, env: { ...launch.env, DSH_TOOLS_MODE: mode },
...launch,
binArgs: ['--profile', 'headless', '--patch', 'office.patch.json',
...mode === 'ptc' ? ['--patch', join(repo, 'apps/cli/config/examples/ptc.yml')] : [],
`Export page 1 of input.${format} as PNG into preview and check that the exported image is readable. Report briefly in English.`],
async prepare(cwd) {
await execa(python!, ['-c', "from docx import Document\nd=Document()\nd.add_heading('Quarterly revenue',0)\nd.add_paragraph('Q1: 12; Q2: 18; Total: 30')\nd.save('input.docx')"], { cwd })
@@ -76,7 +76,7 @@ it.skipIf(!process.env.DEEPSEEK_API_KEY || !runtime).each(cases)('$format $kind
// The CLI fixture and its log live outside the workspace; bwrap's private /tmp hides both.
env: { DSH_PRIMARY_RUNTIME: runtime, DSH_PERMISSION_MODE: 'danger-full-access',
DSH_HOME: join(controlRoot, 'home'), DSH_AGENTS_HOME: join(controlRoot, 'agents'),
DSH_TELEMETRY_DISABLED: '1', DSH_TOOLS_MODE: 'native',
DSH_TELEMETRY_DISABLED: '1',
TMPDIR: previewRoot, TMP: previewRoot, TEMP: previewRoot,
HTTP_PROXY: process.env.DSH_OFFICE_TEST_PROXY, HTTPS_PROXY: process.env.DSH_OFFICE_TEST_PROXY },
async prepare(cwd) {
@@ -80,6 +80,7 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY || !runtime).each(['native', 'ptc'
tsconfigPath: join(repo, 'tsconfig.base.json'),
configPath,
binArgs: ['--profile', 'headless', '--patch', configPath,
...mode === 'ptc' ? ['--patch', join(repo, 'apps/cli/config/examples/ptc.yml')] : [],
`${task} Use input.xlsx and save the finished workbook as result.xlsx. Preserve the Notes sheet and leave input.xlsx unchanged. Respond briefly in English.`,
],
processTimeoutMs: 110_000,
@@ -89,7 +90,6 @@ describe.skipIf(!process.env.DEEPSEEK_API_KEY || !runtime).each(['native', 'ptc'
DSH_HOME: join(controlRoot, 'home'),
DSH_AGENTS_HOME: join(controlRoot, 'agents'),
DSH_TELEMETRY_DISABLED: '1',
DSH_TOOLS_MODE: mode,
HTTP_PROXY: process.env.DSH_OFFICE_TEST_PROXY,
HTTPS_PROXY: process.env.DSH_OFFICE_TEST_PROXY,
},
+2 -1
View File
@@ -10,9 +10,10 @@ const child = spawn(process.execPath, [
'apps/cli/src/bin.ts',
'--profile',
'headless',
'--patch',
'apps/cli/config/examples/ptc.yml',
task,
], {
stdio: 'inherit',
env: { ...process.env, DSH_TOOLS_MODE: 'ptc' },
})
child.on('exit', (code, signal) => { process.exit(signal !== null ? 1 : code ?? 1) })
@@ -10,5 +10,3 @@ header:
toolSchemasSource: text-turn
workspace:
final: true
environment:
DSH_TOOLS_MODE: native