refactor(process): split the process manager out of the bash executor

New process/ capability family: @deepseek-ai/dsh-process owns ctx.processes —
abstract ProcessManager.spawn(spec) over a fully-explicit ProcessSpawnSpec —
plus the shared DSH_* managed-environment and CollectedOutput vocabulary;
@deepseek-ai/dsh-process-local carries the former bash-local run.ts plumbing
(detached groups, tail-keep spill-backed output, credential scrub, kill
escalation, kill-and-join disposal) with no config of its own.

dsh-bash-local becomes a consumer: it keeps command defaulting, the fused
deadline timedOut/aborted classification, the model-friendly terminal env
(now merged through the ordinary env channel), and the [stderr]-marked
background read merge, and spawns through ctx.processes. Background-process
lifetime moves to the manager, so an executor reload no longer kills live
background work; a background spawn failure is injected once into the read
path instead of being buffered as fake stderr. dsh-bash re-exports the moved
vocabulary so bash consumers keep one import root; dsh-bash-sandbox only
redeclares the inherited inject.

Every composition loading a bash executor now loads dsh-process-local (CLI,
examples, python bundled runtime, create-sdk bash feature, inline test
configs).
This commit is contained in:
Tianyi Cui
2026-07-26 06:59:01 +08:00
parent 71c564d801
commit 0d6bfd8856
89 changed files with 1331 additions and 365 deletions

View File

@@ -7,5 +7,5 @@
"docs/testing.md": 1100,
"examples/AGENTS.md": 310,
"packages/AGENTS.md": 660,
"packages/README.md": 790
"packages/README.md": 810
}

View File

@@ -64,7 +64,12 @@ export const LINK_MAP: Record<string, string> = {
BashExecSpec: 'bash.md',
BashProcess: 'bash.md',
BashRunResult: 'bash.md',
DshEnvironment: 'bash.md',
DshEnvironment: 'process.md',
ProcessHandle: 'process.md',
ProcessOutcome: 'process.md',
ProcessOutputRead: 'process.md',
ProcessOutputReader: 'process.md',
ProcessSpawnSpec: 'process.md',
CodeRunRequest: 'code-runtime.md',
CodeRunResult: 'code-runtime.md',
CompactionResult: 'compaction.md',

View File

@@ -59,6 +59,7 @@ const GROUP_ORDER = [
'llm',
'core',
'goal',
'process',
'bash',
'pty',
'sandbox',
@@ -264,6 +265,15 @@ const SERVICE_ROLES: ServiceRole[] = [
mode: 'core',
note: 'Folds revisioned objective state from the session log and keeps live continuation activation process-local.',
},
{
key: 'processes',
pkg: 'process',
title: 'Process manager seam',
mode: 'seam',
implementations: ['process-local'],
consumers: ['bash-local', 'bash-sandbox'],
note: 'The bash executors spawn their process groups through ctx.processes; the manager owns group lifetime, bounded spill-backed output, and kill escalation.',
},
{
key: 'bash',
pkg: 'bash',

View File

@@ -19,6 +19,7 @@ import ToolRegistry, { type Config as ToolsConfig } from '@deepseek-ai/dsh-tools
import { BashExecutor } from '@deepseek-ai/dsh-bash'
import type { BashExecRequest, BashExecSpec, BashProcess, BashRunResult } from '@deepseek-ai/dsh-bash'
import LocalBashExecutor from '@deepseek-ai/dsh-bash-local'
import LocalProcessManager from '@deepseek-ai/dsh-process-local'
import LocalFileSystem from '@deepseek-ai/dsh-fs-local'
import UserInteractionService from '@deepseek-ai/dsh-user-interaction'
import PlanModeService from '@deepseek-ai/dsh-plan-mode'
@@ -197,6 +198,7 @@ const TOOL_PACKAGES: ToolPackage[] = [
requires: ['ctx.tools', 'ctx.bash', 'ctx.tasks at call time for run_in_background'],
writes: ['tool/call', 'tool/result'],
async mount(ctx) {
await ctx.plugin(LocalProcessManager)
await ctx.plugin(LocalBashExecutor)
await ctx.plugin(ToolBash)
},

View File

@@ -729,16 +729,6 @@
"symbol": "ApprovalRequest",
"source": "packages/ui/user-approval/src/index.ts"
},
{
"doc": "docs/core-data-structures/bash.md",
"symbol": "DshEnvironmentKey",
"source": "packages/bash/bash/src/types.ts"
},
{
"doc": "docs/core-data-structures/bash.md",
"symbol": "DshEnvironment",
"source": "packages/bash/bash/src/types.ts"
},
{
"doc": "docs/core-data-structures/bash.md",
"symbol": "BashExecRequest",
@@ -759,11 +749,6 @@
"symbol": "BashSandboxInfo",
"source": "packages/bash/bash/src/types.ts"
},
{
"doc": "docs/core-data-structures/bash.md",
"symbol": "CollectedOutput",
"source": "packages/bash/bash/src/types.ts"
},
{
"doc": "docs/core-data-structures/bash.md",
"symbol": "BashProcess",
@@ -1867,16 +1852,6 @@
"symbol": "ApprovalRequest",
"source": "packages/ui/user-approval/src/index.ts"
},
{
"doc": "docs/core-data-structures/bash.zh.md",
"symbol": "DshEnvironmentKey",
"source": "packages/bash/bash/src/types.ts"
},
{
"doc": "docs/core-data-structures/bash.zh.md",
"symbol": "DshEnvironment",
"source": "packages/bash/bash/src/types.ts"
},
{
"doc": "docs/core-data-structures/bash.zh.md",
"symbol": "BashExecRequest",
@@ -1897,11 +1872,6 @@
"symbol": "BashSandboxInfo",
"source": "packages/bash/bash/src/types.ts"
},
{
"doc": "docs/core-data-structures/bash.zh.md",
"symbol": "CollectedOutput",
"source": "packages/bash/bash/src/types.ts"
},
{
"doc": "docs/core-data-structures/bash.zh.md",
"symbol": "BashProcess",
@@ -2191,6 +2161,31 @@
"doc": "docs/core-data-structures/workflow.zh.md",
"symbol": "WorkflowRun",
"source": "packages/workflow/workflow/src/types.ts"
},
{
"doc": "docs/core-data-structures/process.md",
"symbol": "ProcessSpawnSpec",
"source": "packages/process/process/src/types.ts"
},
{
"doc": "docs/core-data-structures/process.md",
"symbol": "ProcessHandle",
"source": "packages/process/process/src/types.ts"
},
{
"doc": "docs/core-data-structures/process.md",
"symbol": "ProcessOutputReader",
"source": "packages/process/process/src/types.ts"
},
{
"doc": "docs/core-data-structures/process.md",
"symbol": "ProcessOutputRead",
"source": "packages/process/process/src/types.ts"
},
{
"doc": "docs/core-data-structures/process.md",
"symbol": "ProcessOutcome",
"source": "packages/process/process/src/types.ts"
}
]
}

View File

@@ -72,6 +72,8 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly<Record<string, SentenceContract>> = {
'packages/llm/token-meter': { kind: 'indirect', reason: 'The measurement service leaves model-visible changes to its consumers.' },
'packages/lsp/lsp': { kind: 'indirect', reason: 'The provider registry delegates model rendering to dsh-tool-lsp.' },
'packages/lsp/lsp-local': { kind: 'indirect', reason: 'The provider backend delegates model rendering to dsh-tool-lsp.' },
'packages/process/process': { kind: 'indirect', reason: 'The seam delegates all model rendering to consumer seams such as the bash executor family.' },
'packages/process/process-local': { kind: 'indirect', reason: 'The manager backend delegates model rendering to consumer seams such as the bash executor family.' },
'packages/sandbox/sandbox-local': { kind: 'indirect', reason: 'The provider backend delegates model rendering to dsh-bash-sandbox and dsh-tool-bash.' },
'packages/sandbox/sandbox-policy': { kind: 'indirect', reason: 'The policy service holds the mode dsh-tool-bash and dsh-tool-fs render in their denial markers.' },
'packages/sdk/create-sdk': { kind: 'indirect', reason: 'The initializer only writes project files; selected runtime plugins provide the generated project model surface.' },