Commit Graph
135 Commits
Author SHA1 Message Date
Yichen Jiang 680ae53bb6 Merge remote-tracking branch 'origin/master' into codex/skill-system
# Conflicts:
#	docs/architecture.md
#	docs/config-catalog.md
#	docs/module-graph.md
#	docs/rfc/INDEX.md
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	packages/core/agent-core/src/index.ts
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
#	packages/support/acp-snapshot/src/suite.ts
#	packages/ui/acp-agent/src/index.ts
2026-07-10 14:43:33 +08:00
Yichen Jiang 6292d52236 feat(skill): move catalogs into session prefixes 2026-07-10 14:19:06 +08:00
pku-xht 3eea868a1b Merge branch 'master' into feat/subagent-process 2026-07-10 10:05:01 +08:00
Tianyi Cui 58a5088feb Merge remote-tracking branch 'origin/master' into workflow-vm-to-workerthread
# Conflicts:
#	docs/config-catalog.md
#	docs/event-producer-consumer.md
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
2026-07-09 23:48:17 +08:00
Yichen Jiang b9bf67d0a7 Merge remote-tracking branch 'origin/master' into codex/skill-system 2026-07-09 23:11:10 +08:00
Tianyi Cui 2da28e89eb Merge remote-tracking branch 'origin/master' into code-mode-tools
# Conflicts:
#	examples/AGENTS.md
#	examples/README.md
#	package.json
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
2026-07-09 22:58:58 +08:00
imccyu 2c812fb84a Merge remote-tracking branch 'origin/master' into workflow-vm-to-workerthread 2026-07-09 22:36:52 +08:00
Tianyi Cui 88ab5ce0bc Merge branch 'master' into feat/subagent-process 2026-07-09 22:19:30 +08:00
imccyu fda5784e16 Merge remote-tracking branch 'origin/master' into tool-cordis
# Conflicts:
#	docs/capability-seams.md
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
#	scripts/gen-doc-graphs.ts
2026-07-09 22:02:06 +08:00
imccyu 7f5b990aa1 Merge remote-tracking branch 'origin/master' into workflow-vm-to-workerthread 2026-07-09 21:34:52 +08:00
Tianyi Cui 19fc33f172 Merge remote-tracking branch 'origin/master' into code-mode-tools
# Conflicts:
#	docs/config-catalog.md
#	docs/module-graph.md
#	docs/tool-catalog.md
#	packages/core/tools/tests/gen-tool-catalog.spec.ts
#	packages/ui/acp-agent/package.json
#	pnpm-lock.yaml
#	scripts/gen-tool-catalog.ts
2026-07-09 21:10:40 +08:00
imccyu 0d11a3afc7 workflow: rename dsh-workflow-vm to dsh-workflow-workerthread
Pure mechanical rename now that the package's internals are the
worker-thread engine: directory, package name, spec/e2e filenames,
module tags and logger prefixes, tsconfig/knip/run-gates/AGENTS.md
references, example cordis.yml plugin ids, doc links; catalogs
regenerated and the lockfile refreshed.
2026-07-09 19:33:08 +08:00
imccyu b5f618bcfb workflow: swap the engine's internals to node:worker_threads
In-place port of dsh-workflow-vm from the in-process node:vm execution
to one worker thread per run (the workflow-workerthread engine of
PR #215, adopted as THE engine): the script's vm context moves inside
the worker, agent() bridges to ctx.subagents over the message port
(host.ts/protocol.ts/session.ts/worker.ts are new; runtime.ts loses the
abandon channel — the host's grace timer force-settles and TERMINATES
instead), start() pre-parses the body host-side to keep the seam's
synchronous SCRIPT_PARSE throw, and a ready→go handshake keeps a run
cancelled before start from ever executing the body. start() no longer
blocks the host, termination is real, and the value boundary is
serialization by construction. The package keeps its name until the
follow-up rename commit; scripts see the identical hook surface, and
the seam-contract tests hardened ahead of this swap pass unchanged.

The run and child-RPC surfaces are class-shaped rather than literal
bundles: WorkerRun IMPLEMENTS the seam's WorkflowRun (id/meta are its
own clone, separate from event payloads') and start() returns the
instance directly — interface parity with the seam is compiler-checked;
worker-side, ChildRpcBridge (implements ChildPort; callId allocation +
pending book-keeping settled by onChild* entry points) and
RpcChildHandle (every member an RPC keyed by its callId) carry names in
stacks. ChildPort's method is startAgent — it names what it starts,
matching the script-side agent() hook and the agentsStarted /
workflow/agent-* vocabulary; the Child* type names deliberately stay
(the worker side is cordis- and subagent-free; these are reduced JSON
projections, not the seam's types).

Review findings from the reference PR are folded in rather than
re-introduced:
- cancel() drives BOTH child-cancel channels host-side: the request
  signal aborts AND each registered child's explicit cancel() is
  called — a worker wedged in a synchronous spin cannot relay its own
  ChildCancel RPCs (regression: cancel-only provider + wedged worker).
- All host warn paths render through the total renderThrown; a child
  dispose() rejecting a value whose coercion throws still acks
  ChildDisposed instead of wedging the script's finally (regression).
- built-worker.e2e.ts is wired into builtBinSmokeGate and the AGENTS.md
  CI sequence — the built lib/worker.js resolution contract now runs in
  an automated gate.
- workflow/end payload pinned on the worker-death path (with the
  cancelled and grace-force-settle pins riding the ported spec).
- Real-Worker scripted timing budgets widened (50-300ms → 150-1000ms)
  for starved CI hosts.

Workspace plumbing: the "./worker" subpath export sanctions the second
runtime bundle (check-workspace-constraints), tsdown builds two
single-entry passes, tsx becomes a devDependency for the unbuilt worker
spawn.
2026-07-09 19:31:14 +08:00
Yichen Jiang 1e06fdbb86 refactor: colocate user interaction with ui packages 2026-07-09 17:59:02 +08:00
pku-xht 607b02a659 Merge branch 'master' into feat/subagent-process 2026-07-09 14:01:28 +08:00
imccyu ee1da1ce5b feat(cordis): @deepseek-ai/dsh-tool-cordis — inspect/mount/unmount over the live runtime
New top-level packages/cordis/ group with the self-referential toolset:
cordis_inspect (services / plugin tree / tools / dynamic mounts / api / events,
the api section intersecting the generated catalog with the live service store),
cordis_mount (model-written code evaluated in a node:vm sandbox, mounted under
one cordis-dynamic group fiber as dyn-<n>), cordis_unmount (awaited disposal to
quiescence). Boundary mechanisms: dual-realm instanceof, JSON realm
normalization of dynamic tool results, marker-guarded registration, SchemaSpec
teaching errors, parse failures surfaced with the offending line + caret and a
line-scoped TypeScript hint, and the unmount-first recipe on tool-name
collisions. Config: vmTimeoutMs (schemastery, default 5000). Design record:
docs/rfc/implemented/feature/2026-07-08-self-referential-cordis-toolset.md.

The tool-catalog boot manifest, its regenerated output, and the pinned
tool-name list land here rather than with the other repo registration: the
completeness guard globs packages/*/tool-* and fails the generator (and the
core/tools spec) the moment the package directory exists.
2026-07-09 13:57:03 +08:00
pku-xht c321819053 rename: @deepseek-ai/dsh-subagent-process -> @deepseek-ai/dsh-subagent-subprocess
The extracted library's name sat one edit away from @deepseek-ai/dsh-subagent-inprocess
(process/inprocess), inviting a typo'd import to silently resolve to the wrong
package. subagent-subprocess also reads as the deliberate counterpart to
subagent-inprocess (in-process vs. subprocess), matching how the two shared
drivers actually differ.

Package directory, npm name, module doc, JSDoc module tags, test-file name and
its temp-dir prefixes, the subagent-acp import and its Config/tsconfig/package.json
references, root tsconfig.json/tsconfig.build.json/knip.json entries, and the
packages/subagent group README all renamed together; regenerated
docs/module-graph.md and docs/config-catalog.md. Pure rename — no behavior,
export, or Config shape changed.
2026-07-09 13:42:03 +08:00
Yichen Jiang bdab8c6a61 Merge remote-tracking branch 'origin/master' into codex/ask-user-question
# Conflicts:
#	docs/config-catalog.md
2026-07-09 13:34:13 +08:00
Tianyi Cui a4553cc10d Merge remote-tracking branch 'origin/master' into code-mode-tools
# Conflicts:
#	docs/cordis-catalog/events.md
#	docs/cordis-catalog/services.md
#	docs/event-producer-consumer.md
#	docs/tool-execution-pipeline.md
#	packages/core/tools/README.md
#	scripts/gen-doc-graphs.ts
2026-07-09 13:30:26 +08:00
Dudu-0223 0a3ffe1b04 Merge remote-tracking branch 'origin/master' into timeout-design
# Conflicts:
#	docs/event-producer-consumer.md
#	packages/README.md
2026-07-09 11:52:18 +08:00
Yichen Jiang a5ba05121a Merge branch 'master' into codex/ask-user-question 2026-07-09 11:11:07 +08:00
Tianyi Cui 673f20c990 Merge remote-tracking branch 'origin/master' into code-mode-tools
# Conflicts:
#	docs/event-producer-consumer.md
#	packages/support/acp-snapshot/tests/suite.spec.ts
2026-07-09 11:06:50 +08:00
pku-xht 6660d2a83e Merge branch 'master' into feat/subagent-process 2026-07-09 11:03:48 +08:00
Tianyi Cui 43de115173 Merge branch 'master' into code-runtime-worker 2026-07-09 01:04:01 +08:00
Yichen Jiang 56091d5b5d fix review findings: keep ask-user opt-in for acp app 2026-07-09 00:42:36 +08:00
Yichen Jiang b31399bdc4 Merge remote-tracking branch 'origin/master' into codex/ask-user-question
# Conflicts:
#	docs/module-graph.md
2026-07-08 22:22:25 +08:00
pku-xht cdd1ce2ad4 feat(subagent): extract dsh-subagent-process shared out-of-process machinery
The credential env scrub (SENSITIVE_ENV_PATTERN/buildChildEnv), the
spawn-failure capture (spawnFailure), the child-exit waits
(waitForExit/exitsWithin), and the stdin-EOF -> SIGTERM -> SIGKILL dispose
ladder move out of subagent-acp into a new pure library package (the
subagent-inprocess shape), with the ladder taking its two grace periods as
parameters — defaults stay in the plugin Config. New isolated-config-dir
helpers (mkdtemp create, best-effort remove; a pinned dir is never removed)
land alongside for the CLAUDE_CONFIG_DIR / CODEX_HOME redirection the RFC
names.

The ACP backend migrates onto the library with no semantic change: its suite
passes with import-path edits only. bash-local keeps its sibling copy, per
the RFC's blast-radius call.

RFC: docs/rfc/proposed/feature/2026-07-07-claude-code-and-codex-subagent-backends.md
2026-07-08 17:09:53 +08:00
Tianyi Cui 35ef649716 Merge branch 'code-runtime-worker' into code-mode-tools
Brings in the refreshed base (master merged through the stack after #203
and #205 landed), including the acp-snapshot extraction (#204), and
re-ports this PR's snapshot-suite extensions onto the extracted package:

- dsh-acp-snapshot's Scenario gains headerClass and configPath; the suite
  factory pins the request header PER CLASS (construction rejects a
  missing or duplicated class pin), forwards a scenario's configPath to
  the harness (RunOptions.configPath overrides AgentUnderTest.configPath),
  and a new fixtures meta-test asserts every pinning fixture carries
  exactly one request/header and no deltas.
- The acp-agent example's thin scenario table re-registers code-mode-turn
  and both-mode-turn with their overlay configs and per-class pins; the
  committed fixtures replay unchanged.
- The package's synthetic suites cover the new surface (explicit
  headerClass on one suite, the default on the other, a configPath
  override through the fake bin, and the two construction throws).
2026-07-08 15:55:29 +08:00
Yichen Jiang f453ba77a2 refactor: split skill providers 2026-07-08 15:50:38 +08:00
Dudu-0223 ef2a150293 Merge remote-tracking branch 'origin/master' into timeout-design 2026-07-08 15:40:56 +08:00
Dudu-0223 a7c055270d chore(timeout-policy): drop now-unused schemastery dependency
The zero-config enforcer no longer imports schemastery (its Config was
removed); knip flags the stale dependency. Remove it from the manifest
and sync the lockfile.
2026-07-08 15:10:15 +08:00
kingwl 232c1957e2 Merge remote-tracking branch 'origin/master' into feat/repeat-tool-guard 2026-07-08 14:52:12 +08:00
Tianyi Cui 030eebb634 Merge remote-tracking branch 'origin/master' into code-runtime-worker 2026-07-08 14:44:23 +08:00
Tianyi Cui d0314736de Merge remote-tracking branch 'origin/master' into code-runtime-pkg 2026-07-08 14:38:54 +08:00
kingwl db26ef479d feat(guard): add the repeat-tool-guard plugin 2026-07-08 14:24:20 +08:00
Tianyi Cui b59d245c7c feat: Code Mode — the registry's mode config, the SDK codegen, and the run_code bridge
The dsh-tools half of the Code Mode RFC (its fourth, final change): the
registry gains its first config — mode: native | code | both — and OWNS how
its tools reach the model. 'code' contributes exactly one wire tool,
run_code, plus a lazy tools:sdk prompt section declaring every other tool
as a generated TypeScript API (jsonSchemaToTs: total over the defineTool
subset, unknown degradation, lexicographic byte-identical rendering);
'both' ships both representations; 'native' is byte-for-byte the old
behavior. Non-native modes fail every assembly loudly without a
typescript-language ctx.codeRuntime.

run_code's dispatch bridge: JSON-normalizes each binding argument before
dispatch (what dispatches is what the tool/code-dispatch event logs — the
append can never fail on payload shape; BigInt/circulars reject that one
call), serializes all program tool calls through a per-run queue (even
Promise.all — no concurrency-safety metadata yet), routes every sub-call
through tools/pre-execute → tools/post-execute (a deny rejects the
program-side promise), drops sub-call additionalContext (no safe outlet
mid-run; pinned), owns a run-scoped abort that follows the outer signal in
and fires on settlement (in-flight sub-dispatch aborted, queued abandoned,
queue drained before returning), and converts a failed run into
CodeRunFailedError → a structured isError carrying kind + captured logs.
tool/code-dispatch joins SessionEventMap by declaration merging (log-only;
deriveMessages ignores it).

The composed surface: the tools config forwards through agent-core and
both app packages; examples/code-agent + demo:code run the worker runtime
under mode code (keyless boot smoke + a with-key e2e proving the collapsed
[run_code] header, the dispatch events, and the file the program wrote);
two new snapshot scenarios (code-mode-turn, both-mode-turn) record the SDK
section, collapsed header, dispatch events, and result card — each its own
header-pinning class (the harness gains per-scenario config overlays and
per-class pins). Catalogs, graphs, cookbook, hooks-bridge notes, and the
RFC (moved to implemented/, restructured to decision-era headings) updated
in the same change.
2026-07-08 12:58:23 +08:00
Dudu-0223 a76285c4e6 Merge origin/master into timeout-design
Resolve conflicts from master's catalog/doc refactors landing alongside the
tool-call timeout work:
- knip.json: keep both new workspace entries (util/timeout + support/acp-snapshot).
- tool-web/src/fetch.ts: keep the timeout_ms removal, adopt master's richer
  JSDoc @param/@returns style on parseFetchArgs/presentFetchCall.
- tools/README.md: keep the tools/execute pipeline wording, adopt master's
  flattened docs/tool-catalog.md path.
- Regenerate every generated doc (cordis-catalog, tool-catalog, config-catalog,
  doc-graphs, module-graph) so they carry both master's changes and the
  tools/execute event + timeout-policy package.
- Add @param/@returns to toolTimeoutResult for master's new verify-export-jsdoc gate.
2026-07-08 11:18:27 +08:00
Yichen Jiang d3f86996f7 Merge remote-tracking branch 'origin/master' into codex/ask-user-question
# Conflicts:
#	docs/config-catalog.md
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
#	pnpm-lock.yaml
2026-07-08 11:09:20 +08:00
Tianyi Cui 583704ac1d feat: add the worker-thread code runtime (dsh-code-runtime-worker)
The shipped backend of the code-execution seam, per the Code Mode RFC's
worker-thread section: one fresh Node worker per run, executing the
model's TypeScript after a host-side type-strip (wrapped in an
async-function shell so top-level return/await parse, sliced back out
position-preserved), bindings bridged over the message port under
hostile-peer rules (own-property name lookup, at-most-once replies,
post-settlement drops, null-prototype namespaces), logs streamed eagerly
with an in-band truncation marker, and two independent budgets — measured
event-loop busy time (computeMs) plus a never-pausing wall ceiling
(maxWallMs) — funneling into worker.terminate(). env: {} and execArgv: []
keep the isolate hermetic; disposal aborts in-flight runs and awaits
worker exits.

The worker entry loads unbuilt via Node's native type stripping
(src/worker.ts, erasable-only) and ships built as a sibling tsdown bundle
(lib/worker.js); tests/built-lib.e2e.ts pins the built load path under
plain node and joins the built-artifact smoke gate. Unit suites cover the
bootstrap in-process (fake port) and the runtime over real workers,
per-file 100%.
2026-07-08 11:07:14 +08:00
Dudu-0223 8190016e2b feat(timeout): add tools/execute seam + tool-timeout policy plugin
Model-facing tool-call budgets were tangled into each capability's schema
(bash timeoutMs, web_fetch timeout_ms) with no shared home. Add a
tools/execute around-dispatch waterfall to dsh-tools whose base next() is
the dispatch-with-normalization thunk, and a new @deepseek-ai/dsh-timeout-policy
plugin (packages/timeout/) that arms a per-tool deadline on exec.signal and
returns a structured TOOL_TIMEOUT when it wins. Migrate web_fetch (drop the
model-facing timeout_ms) and web_search onto it; the fetch provider keeps its
timeout only as a resource backstop for direct callers. bash and hook command
execution keep BASH_TIMEOUT unchanged.

Named the plugin timeout-policy (not the RFC's tool-timeout) so it does not
trip the gen-tool-catalog packages/*/tool-* completeness guard, and replace
exec.signal by in-place mutation before next() since cordis waterfall next()
ignores passed arguments. RFC moved to implemented/ recording both deviations.
2026-07-08 10:10:37 +08:00
kingwl 556f847064 feat(acp-snapshot): extract the ACP snapshot suite into a support package
The snapshot tier's machinery leaves examples/acp-agent/tests for
packages/support/acp-snapshot (@deepseek-ai/dsh-acp-snapshot), where the
coverage gate measures it and a second example can consume it instead of
forking it: harness.ts (runScenario, parameterized by an AgentUnderTest
{binScript, configPath, tsconfigPath} instead of module constants),
normalize.ts (moved verbatim), and suite.ts (defineAcpSnapshotSuite — the
per-scenario golden/log compares, record write-back, per-suite header pin
with its uniformity guard, and the fixture guard block, lifted from
acp.snapshot.ts). The example file collapses to its scenario table plus
one factory call; env reading (DSH_SNAPSHOT) stays at that edge.

The exactly-one-pin meta-test generalizes from the hardcoded text-turn
name to "exactly one per suite" — which scenario pins is the scenario
table's reviewable choice (per-suite pinning per the proposal RFC).

Extraction parity: pnpm run test:snapshot is 36 passed + fs-policy-reject
failing BEFORE AND AFTER (BSD-sed environment failure, reproduced at the
base commit in a clean worktree — the recorded golden's sed -i syntax is
GNU-only), with zero byte changes under examples/acp-agent/tests/snapshots/.
Coverage for the new src files lands in the next commit.
2026-07-08 02:38:25 +08:00
Tianyi Cui 6da6f04016 feat: add the code-execution capability seam (ctx.codeRuntime)
New group packages/code-runtime/ with the interface package
@deepseek-ai/dsh-code-runtime, per the Code Mode RFC: abstract CodeRuntime
service (run() resolves program failures as an error field, rejects only
for seam misuse), the CodeRunRequest/CodeBindingNamespace/CodeRunResult/
CodeLogEntry/CodeRunFailure vocabulary, and readonly language/isolation
backend descriptors. Registered in the tsconfig maps, packages/README,
architecture service map, and the doc-graph service-role classification;
catalogs regenerated.

The RFC's one forward path token to the worker package becomes an npm-name
mention until PR3 creates that directory (verify-package-paths is
drift-scoped: the now-existing group made the token checkable).

docs/architecture.md ceiling 1630 -> 1640: the doc gained a genuinely new
capability-service row; the row itself is already minimal.
2026-07-08 02:17:24 +08:00
Tianyi Cui a706ec7966 Merge branch 'structured-output-subagent-seam' into worktree-dynamic-workflows
# Conflicts:
#	docs/rfc/INDEX.md
#	examples/acp-agent/tests/snapshots/text-turn/session.jsonl
2026-07-07 23:10:50 +08:00
imccyu 85308526c8 Merge branch 'master' into worktree-node-22-18-compat 2026-07-07 22:46:02 +08:00
Tianyi Cui 8db99d36e8 Merge branch 'structured-output-subagent-seam' into worktree-dynamic-workflows
# Conflicts:
#	examples/acp-agent/tests/snapshots/fs-policy-reject/session.jsonl
#	examples/acp-agent/tests/snapshots/fs-policy-reject/stdout.golden.jsonl
2026-07-07 22:21:44 +08:00
Tianyi Cui f8517654a8 Merge branch 'structured-output-subagent-seam' into worktree-dynamic-workflows 2026-07-07 21:23:20 +08:00
Tianyi Cui 0e0f3b2f19 review: acquire the structured runtime per run, not per backend
The Codex simplification concern plus the duplication comment on the spawn
apply, resolved by deletion: the backend-lifetime holds are gone, so the
runtime registers at the first structured run and disposes when the last
settles — a deployment that never passes outputSchema carries no always-on
global state, and there is no per-backend acquisition block left to extract.

The driver spec now drives an INLINE spawn-shaped provider over
startInProcessRun, which removes the spawn/fork devDependencies (the
test-only workspace cycle); plugin-level structured coverage moves to the
backends' own specs (capture through the shipped plugin, mid-run backend
unload, seeded fork capture). tools.md, the driver README, and both backend
READMEs describe the run-scoped lifetime; the module-graph regenerates
without the cycle edges.
2026-07-07 21:09:02 +08:00
imccyu 72933ec558 refactor(system-prompt): rename TOOL_ORDER_REST from '...' to '<unlisted-tools>'
A three-dot rest entry reads as elision in a cordis.yml; the spelled-out
sentinel says what lands there. The literal now appears once in code (the
constant) and once in the value-pinning test; every other reference — the
forwarding tests included — imports TOOL_ORDER_REST, which adds the
dsh-system-prompt devDependency to the two app packages.

Review follow-up on #196.
2026-07-07 20:49:35 +08:00
Yichen Jiang 7065b32e0b Merge branch 'master' into codex/ask-user-question 2026-07-07 19:42:25 +08:00
imccyu f33e14ff19 build: lower the Node engines floor to 22.18 2026-07-07 17:15:41 +08:00