refactor(subprocess): rename the process seam to subprocess and address review

Review feedback (tianyicui): 'process' is a poor service name. The family is
now packages/subprocess/ — @deepseek-ai/dsh-subprocess (ctx.subprocess,
abstract SubprocessService, Subprocess* vocabulary) and
@deepseek-ai/dsh-subprocess-local (LocalSubprocessService) — renamed
throughout code, compositions, docs (en+zh, pairs re-recorded), catalogs,
and gates. 'subprocess' is the precise term for managed OS children (the
Python-stdlib sense), avoids colliding with Node's global process object,
and reads as one system beside dsh-subagent-subprocess.

ds-review-bot findings addressed:
- kill() on a settled handle is now a no-op (no signal to a possibly-reused
  pgid, no referenced grace timer delaying exit); pinned by a spy test.
- The moved DshEnvironmentKey/DshEnvironment/CollectedOutput types get
  drift-checked type-equiv blocks on the new subprocess.md page, restoring
  their manifest registration.
- subprocess.md is registered in the core.md sub-page index (en+zh).
This commit is contained in:
Tianyi Cui
2026-07-26 12:43:14 +08:00
parent 8f75565f03
commit fc566119a7
108 changed files with 587 additions and 557 deletions

View File

@@ -52,7 +52,7 @@
"@deepseek-ai/dsh-bash-local": "workspace:^",
"@deepseek-ai/dsh-invariants": "workspace:^",
"@deepseek-ai/dsh-llm": "workspace:^",
"@deepseek-ai/dsh-process-local": "workspace:^",
"@deepseek-ai/dsh-subprocess-local": "workspace:^",
"@deepseek-ai/dsh-paths": "workspace:^",
"@deepseek-ai/dsh-sandbox": "workspace:^",
"@deepseek-ai/dsh-sandbox-policy": "workspace:^",

View File

@@ -11,7 +11,7 @@ import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-test
import LocalTaskService from '@deepseek-ai/dsh-tasks-local'
import * as ToolTasks from '@deepseek-ai/dsh-tool-tasks'
import { LocalBashExecutor } from '@deepseek-ai/dsh-bash-local'
import LocalProcessManager from '@deepseek-ai/dsh-process-local'
import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local'
import * as ToolBash from '@deepseek-ai/dsh-tool-bash'
import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts'
@@ -30,7 +30,7 @@ async function harness(adapter: MockAdapter, sessionRoot?: string, dshHome?: str
await ctx.plugin(AgentLoop, { agents: [] })
await ctx.plugin(LocalTaskService)
await ctx.plugin(ToolTasks)
await ctx.plugin(LocalProcessManager)
await ctx.plugin(LocalSubprocessService)
await ctx.plugin(LocalBashExecutor, { timeoutMs: 10_000 })
await ctx.plugin(ToolBash, dshHome === undefined ? {} : { dshHome })
ctx.llm.registerAdapter(['mock'], adapter)

View File

@@ -17,7 +17,7 @@ import * as ToolTasks from '@deepseek-ai/dsh-tool-tasks'
import ApprovalService from '@deepseek-ai/dsh-user-approval'
import type { ApprovalOutcome } from '@deepseek-ai/dsh-user-approval'
import { LocalBashExecutor } from '@deepseek-ai/dsh-bash-local'
import LocalProcessManager from '@deepseek-ai/dsh-process-local'
import LocalSubprocessService from '@deepseek-ai/dsh-subprocess-local'
import SandboxPolicyService from '@deepseek-ai/dsh-sandbox-policy'
import * as ToolBash from '@deepseek-ai/dsh-tool-bash'
import { processOutcome } from '../src/background.ts'
@@ -33,8 +33,8 @@ async function setup() {
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRegistry)
await ctx.plugin(AgentRegistry)
await ctx.plugin(LocalProcessManager)
;(ctx.processes as LocalProcessManager).internals = { spillDir }
await ctx.plugin(LocalSubprocessService)
;(ctx.subprocess as LocalSubprocessService).internals = { spillDir }
await ctx.plugin(LocalBashExecutor, { timeoutMs: 10_000, graceMs: 200 })
await ctx.plugin(ToolBash)
return ctx
@@ -48,8 +48,8 @@ async function setupWithTasks() {
await ctx.plugin(AgentRegistry)
await ctx.plugin(LocalTaskService)
await ctx.plugin(ToolTasks)
await ctx.plugin(LocalProcessManager)
;(ctx.processes as LocalProcessManager).internals = { spillDir }
await ctx.plugin(LocalSubprocessService)
;(ctx.subprocess as LocalSubprocessService).internals = { spillDir }
await ctx.plugin(LocalBashExecutor, { timeoutMs: 10_000, graceMs: 200 })
await ctx.plugin(ToolBash)
return ctx
@@ -278,8 +278,8 @@ describe('bash tool', () => {
const ctx = new Context()
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRegistry)
await ctx.plugin(LocalProcessManager)
;(ctx.processes as LocalProcessManager).internals = { spillDir }
await ctx.plugin(LocalSubprocessService)
;(ctx.subprocess as LocalSubprocessService).internals = { spillDir }
await ctx.plugin(LocalBashExecutor, { maxOutputBytes: 100, graceMs: 200 })
await ctx.plugin(ToolBash)
const result = await call(ctx, 'bash', { command: 'for i in $(seq 1 100); do printf "line-%04d\\n" $i; done', description: 'test command' })
@@ -387,7 +387,7 @@ describe('bash tool', () => {
const ctx = new Context()
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRegistry)
await ctx.plugin(LocalProcessManager)
await ctx.plugin(LocalSubprocessService)
await ctx.plugin(LocalBashExecutor, {})
const fiber = await ctx.plugin(ToolBash)
expect(ctx.tools.schemas()).toHaveLength(1)
@@ -405,7 +405,7 @@ describe('bash tool', () => {
// inject: ['tools', 'bash'] keeps the plugin pending until bash exists.
await ctx.plugin(ToolBash)
expect(ctx.tools.schemas()).toHaveLength(0)
await ctx.plugin(LocalProcessManager)
await ctx.plugin(LocalSubprocessService)
await ctx.plugin(LocalBashExecutor, {})
await new Promise(resolve => setTimeout(resolve, 0))
expect(ctx.tools.schemas()).toHaveLength(1)
@@ -417,7 +417,7 @@ describe('bash tool', () => {
const ctx = new Context()
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRegistry)
await ctx.plugin(LocalProcessManager)
await ctx.plugin(LocalSubprocessService)
await ctx.plugin(LocalBashExecutor, {})
ToolBash.apply(ctx, {})
const schema = ctx.tools.schemas()[0]!
@@ -533,7 +533,7 @@ describe('background execution through the task runtime', () => {
const ctx = new Context()
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRegistry)
await ctx.plugin(LocalProcessManager)
await ctx.plugin(LocalSubprocessService)
await ctx.plugin(LocalBashExecutor, {})
await ctx.plugin(ToolBash, { enableRunInBackground: false })