deepseek-harness/examples/coding-agent/cordis.yml

141 lines
5.6 KiB
YAML
Raw Normal View History

2026-07-04 01:07:26 +08:00
# The coding-agent plugin tree: the REPL agent demo. The two swappable
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
# backends — the DeepSeek adapter and the local bash executor — plus `hmr` for
# the dev/demo reload loop, then the stdio chat app (@deepseek-ai/dsh-stdio-
# agent), which bundles the whole agent-core spine (timer, llm, sessions,
# system-prompt, tools, agents, invariants, tool-bash, agent-loop), the console
# logger, JSONL persistence, the readline UI, and a pre-created `main` agent.
#
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
# `hmr` is a leaf entry (not baked into dsh-stdio-agent): it is a Loader-only
2026-07-04 01:07:26 +08:00
# dev plugin that needs `--expose-internals` — the `demo:repl` script passes
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
# it. Requires DEEPSEEK_API_KEY (and optionally DEEPSEEK_BASE_URL) in the
# environment — the dsh-stdio-agent bin loads the gitignored repo-root .env
# first. cordis.yml reads them via the `!!js` tag.
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
# Hot-module reload for the dev/demo loop (needs `node --expose-internals`).
- id: hmr
name: '@cordisjs/plugin-hmr'
config:
root: ['.']
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
# The DeepSeek adapter. Swap to '@deepseek-ai/dsh-llm-pi-ai' for the pi-ai-backed
# twin (same config shape; `reasoning: high` replaces thinking/reasoningEffort).
- id: llm-deepseek
name: '@deepseek-ai/dsh-llm-deepseek'
config:
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
apiKey: !!js process.env.DEEPSEEK_API_KEY
baseURL: !!js process.env.DEEPSEEK_BASE_URL
models:
- deepseek-v4-pro
- deepseek-v4-flash
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
# Local bash executor for agent-core's tool-bash schema.
# FIXME(config-comments): keep this executor note from implying bash is the
# whole tool set; filesystem, subagent, and todo_write are loaded below.
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
- id: bash
name: '@deepseek-ai/dsh-bash-local'
config:
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
timeoutMs: 60000
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
# The stdio chat app: the whole spine + front-door cluster, configured for a
2026-07-04 01:07:26 +08:00
# REPL agent demo driving a pre-created `main` agent.
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
- id: stdio-agent
name: '@deepseek-ai/dsh-stdio-agent'
refactor(examples): extract reusable logic into tested packages Logic that lived under examples/ was outside the per-file 100% coverage gate (examples/ are not workspaces) and, in the stdio-UI case, duplicated across two examples. Move it into packages/ so it is gated and de-duped. - packages/ui-stdio (new): unify the two diverged stdio-chat.ts copies into one @deepseek-ai/dsh-ui-stdio plugin (welcome/agent Config). A test-only I/O seam (createStdioChat(ctx, config, runtime)) keeps process streams out of the serializable config and makes every render/EOF/disposal branch unit-testable. Per-file 100%. echo/coding cordis.yml now load the package; both src/stdio-chat.ts deleted. - packages/llm-replay (new): move examples/acp-agent/src/llm-replay.ts (+ its spec) here so its derive/parse/replay branches fall under the coverage gate. cordis.snapshot.yml + README rewired to the package name; added apply/env /assertNever/abort tests to reach per-file 100%. - examples/{echo,coding}-agent: keyless Loader-path e2e smokes that boot the real cordis.yml (no key) — the guard a hand-mounted unit test cannot be for the unwrapExports/export-shape class (postmortem 0001). examples/AGENTS.md codifies the keyless+with-key smoke convention (keyless-by-nature exception for echo-agent). - AGENTS.md: a scoped, removal-triggered pre-release stance (foundation over blast radius). packages/README.md: new rows + a FIXME to later regroup ALL packages into a hierarchy. Wiring: tsconfig paths/refs, publint, knip, module-graph. Verified: typecheck, lint, test:coverage (887 tests, 100%), build, hygiene, doc-sync, test:snapshot (10), test:e2e (6 keyless pass, with-key self-skip).
2026-06-19 12:42:28 +08:00
config:
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
model: deepseek-v4-flash
# Set RESUME_SESSION_ID to continue a prior persisted session (the ids live
# under ./.sessions); unset starts a fresh session each run.
resumeSessionId: !!js process.env.RESUME_SESSION_ID
persistenceRoot: './.sessions'
2026-07-04 01:07:26 +08:00
welcome: 'agent REPL ready. Give it a coding task (its tools are read, write, edit, bash, subagent, and todo_write).'
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
systemPrompt: |
You are coding-agent, a CLI coding assistant.
Your tools are read/write/edit for file operations, bash (plus
bash_output/bash_kill for background tasks), and subagent. Use read to
inspect UTF-8 text files, write to create or replace files, and edit for
targeted literal replacements. Use bash for shell commands, tests,
searches, and operations that are not ordinary file reads or edits. Each
bash call runs in a fresh shell — pass workdir instead of cd, and never
rely on shell state between calls.
Add in-process subagent backends: spawn (fresh) and fork (seeded) The second PR of the subagent seam: the two in-process backends that run a child agent on the same cordis context, reusing the agent factory's quiescent AgentHandle teardown. Both register on ctx.subagents (PR1's named-provider registry) and share one run driver. - dsh-subagent-spawn: a FRESH child via ctx.agents.create — own session, the parent's model by default (overridable), zero inherited conversation. Also exports the shared in-process run driver (startInProcessRun): mint ids, stamp cwd/parentSession-lineage/depth, drive the one-shot (send → whenIdle), read the last assistant/message + turn/end reason, dispose to quiescence. - dsh-subagent-fork: a child SEEDED with the parent's balanced completed-turn prefix (the log up to and including its last turn/end), so the child inherits context. The in-flight unbalanced turn is excluded — a raw seed would fail the invariants replay. Proven: a regression test goes red if the boundary seeds the open turn. - Seam extension: CreateAgentOptions.seed, threaded through AgentLoop.createAgent → ctx.sessions.prepare({ seed }) (the primitive resume already used). This is the fork-lineage path the TODO(sub-agents) markers anticipated. - Depth: a merge-extensible AgentOptions.subagentDepth (0 top-level, parent+1 for a child); the depthLimit capability refuses a spawn past request.maxDepth. Tests: real-loop unit tests for both backends (mock MODEL only, real loop + invariants), a multi-subagent test (one parent drives a fork AND a spawn child then keeps working), and a with-key e2e (a real parent delegates via the `subagent` tool to a real child that writes a file on disk — world-verified). 100% per-file coverage. The coding-agent demo wires the spawn backend + tool. Snapshot coverage of nested agents is deferred to a stacked follow-up (TODO(subagent-snapshots)): dsh-llm-replay is a single global positional cursor that cannot route calls to a parent vs. a child on one context. Recorded in the RFC's deferrals and a new AGENTS.md rule: designing a subsystem must design its test infrastructure END TO END up front, verifying the snapshot/e2e harness can express the new shape — a gap this plan hit.
2026-06-22 05:58:40 +08:00
Use the subagent tool to delegate a focused, self-contained subtask
to a fresh child agent (it works in its own context and returns only
its final result) — give it a complete, standalone instruction. Use
subagent_fork instead when the subtask needs THIS conversation's
context: the child inherits the log so far.
refactor(examples): extract the app spine into dsh-agent-core + app packages Implements docs/rfc/.../2026-06-20-extract-example-app-packages.md. Each example was thick — a hand-rolled start.ts, an infra preamble, nested base.yml/base-core.yml/acp-tail.yml includes, and a coupled front-door cluster enforced only by prose. This moves the composition into packages so each example is a thin leaf cordis.yml: pick the swappable backends, load one app package. New packages: - @deepseek-ai/dsh-agent-core (packages/core/agent-core): one bundle plugin that loads the providerless/executor-less/UI-less spine (timer + llm + sessions + system-prompt + tools + agents + invariants + tool-bash + agent-loop) via ctx.plugin(...) inside apply(), and forwards agent-loop's `agents` list as its own Config (export const Config = AgentLoop.Config, default []). - @deepseek-ai/dsh-stdio-agent (packages/ui/stdio-agent): terminal chat APP — agent-core + console logger + readline UI + a pre-created `main` agent, with a bin. The demo:echo/coding front door. - @deepseek-ai/dsh-acp-agent (packages/ui/acp-agent): ACP server APP — agent-core + JSONL persistence + the acp bridge, NO stdout logger, with a bin. The stdout-purity footgun is structurally unreachable from the leaf. Amendment to the RFC: hmr stays a LEAF cordis.yml entry, not baked into dsh-stdio-agent. hmr is a Loader-only dev plugin (throws without --expose-internals; the in-process test tier can't even import its decorator form), so a package statically importing it could never carry the per-file coverage gate. Unlike the console logger, a stray hmr is not a stdout-purity footgun, so leaving it at the leaf costs no safety. With hmr out, all three new packages carry in-process unit specs at 100%. Boot glue (Loader tail, .env load, snapshot-mode selection, stdin-dispose lifecycle) moves into each app's bin; start.ts and base.yml/base-core.yml/ acp-tail.yml are deleted. Each app package gets a keyless real-load-path test that boots through its bin + the cordis Loader (guarding the unwrapExports export-shape bug class, postmortem 0001). ACP snapshot replay stays green against the existing committed goldens (pure boot restructuring). RFC moved proposed->implemented with the amendment recorded; package/example/architecture docs and the module graph updated.
2026-06-21 12:03:44 +08:00
Check the [exit code: N] marker on every command; investigate
failures before moving on. Verify your work by running the code or
tests. Keep answers brief and factual.
Add in-process subagent backends: spawn (fresh) and fork (seeded) The second PR of the subagent seam: the two in-process backends that run a child agent on the same cordis context, reusing the agent factory's quiescent AgentHandle teardown. Both register on ctx.subagents (PR1's named-provider registry) and share one run driver. - dsh-subagent-spawn: a FRESH child via ctx.agents.create — own session, the parent's model by default (overridable), zero inherited conversation. Also exports the shared in-process run driver (startInProcessRun): mint ids, stamp cwd/parentSession-lineage/depth, drive the one-shot (send → whenIdle), read the last assistant/message + turn/end reason, dispose to quiescence. - dsh-subagent-fork: a child SEEDED with the parent's balanced completed-turn prefix (the log up to and including its last turn/end), so the child inherits context. The in-flight unbalanced turn is excluded — a raw seed would fail the invariants replay. Proven: a regression test goes red if the boundary seeds the open turn. - Seam extension: CreateAgentOptions.seed, threaded through AgentLoop.createAgent → ctx.sessions.prepare({ seed }) (the primitive resume already used). This is the fork-lineage path the TODO(sub-agents) markers anticipated. - Depth: a merge-extensible AgentOptions.subagentDepth (0 top-level, parent+1 for a child); the depthLimit capability refuses a spawn past request.maxDepth. Tests: real-loop unit tests for both backends (mock MODEL only, real loop + invariants), a multi-subagent test (one parent drives a fork AND a spawn child then keeps working), and a with-key e2e (a real parent delegates via the `subagent` tool to a real child that writes a file on disk — world-verified). 100% per-file coverage. The coding-agent demo wires the spawn backend + tool. Snapshot coverage of nested agents is deferred to a stacked follow-up (TODO(subagent-snapshots)): dsh-llm-replay is a single global positional cursor that cannot route calls to a parent vs. a child on one context. Recorded in the RFC's deferrals and a new AGENTS.md rule: designing a subsystem must design its test infrastructure END TO END up front, verifying the snapshot/e2e harness can express the new shape — a gap this plan hit.
2026-06-22 05:58:40 +08:00
For multi-step work, use the todo_write tool to track a task list:
send the WHOLE list each call (it replaces the previous one), keep at
most one task in_progress (exactly one while work remains), and mark a
task completed as soon as it is done. Skip it for trivial single-step
tasks.
refactor(compact): turn-agnostic retention + dedicated agent/pre-request seam Reform the compaction blueprint so a runaway turn survives and the design stops drifting across review rounds: - Drop in-flight-turn protection ("layer 2"). Retention is a uniform tail→head whole-unit walk; the only structural guard is step-alignment. A single turn that alone exceeds the window now compacts its own early closed steps instead of being retained verbatim (the failure mode that motivated this). - Move auto-compaction off the agent/request waterfall onto a new awaited agent/pre-request loop seam, fired before history derivation. Compaction mutates the surface; the loop derives once from the result — no double-derive, and a listener structurally cannot act on not-yet-derived messages. - Tighten compactIfNeeded to required (session, system, model, signal). - Enforce a single-pass convergence invariant in resolveConfig: reject configs where summarizationMaxTokens + retainTokens exceeds the threshold, so a compaction can never immediately re-trigger. - Document the crash vs recoverable failure taxonomy; core session repair stays compaction-agnostic (a log-only orphaned compact/start is inert). - Wire dsh-compact-basic into examples/coding-agent and add a with-key compaction e2e (compaction's first real-world exercise + runaway net). - Rewrite the RFC to encode the blueprint and move it to implemented/. The runaway-turn snapshot is a named deferred follow-up: dsh-llm-replay cannot yet serve the interleaved summarization model call.
2026-06-26 08:59:33 +08:00
# Automatic context compaction: when the derived history approaches the model's
# context window, summarize an older range into a checkpoint so a long-running
# or tool-heavy session keeps fitting. A leaf entry (needs ctx.llm + the
# agent-loop's `agent/pre-step` seam from the app above).
refactor(compact): turn-agnostic retention + dedicated agent/pre-request seam Reform the compaction blueprint so a runaway turn survives and the design stops drifting across review rounds: - Drop in-flight-turn protection ("layer 2"). Retention is a uniform tail→head whole-unit walk; the only structural guard is step-alignment. A single turn that alone exceeds the window now compacts its own early closed steps instead of being retained verbatim (the failure mode that motivated this). - Move auto-compaction off the agent/request waterfall onto a new awaited agent/pre-request loop seam, fired before history derivation. Compaction mutates the surface; the loop derives once from the result — no double-derive, and a listener structurally cannot act on not-yet-derived messages. - Tighten compactIfNeeded to required (session, system, model, signal). - Enforce a single-pass convergence invariant in resolveConfig: reject configs where summarizationMaxTokens + retainTokens exceeds the threshold, so a compaction can never immediately re-trigger. - Document the crash vs recoverable failure taxonomy; core session repair stays compaction-agnostic (a log-only orphaned compact/start is inert). - Wire dsh-compact-basic into examples/coding-agent and add a with-key compaction e2e (compaction's first real-world exercise + runaway net). - Rewrite the RFC to encode the blueprint and move it to implemented/. The runaway-turn snapshot is a named deferred follow-up: dsh-llm-replay cannot yet serve the interleaved summarization model call.
2026-06-26 08:59:33 +08:00
- id: compact-basic
name: '@deepseek-ai/dsh-compact-basic'
config:
contextWindow: 128000
thresholdRatio: 0.8
refactor(compact): turn-agnostic retention + dedicated agent/pre-request seam Reform the compaction blueprint so a runaway turn survives and the design stops drifting across review rounds: - Drop in-flight-turn protection ("layer 2"). Retention is a uniform tail→head whole-unit walk; the only structural guard is step-alignment. A single turn that alone exceeds the window now compacts its own early closed steps instead of being retained verbatim (the failure mode that motivated this). - Move auto-compaction off the agent/request waterfall onto a new awaited agent/pre-request loop seam, fired before history derivation. Compaction mutates the surface; the loop derives once from the result — no double-derive, and a listener structurally cannot act on not-yet-derived messages. - Tighten compactIfNeeded to required (session, system, model, signal). - Enforce a single-pass convergence invariant in resolveConfig: reject configs where summarizationMaxTokens + retainTokens exceeds the threshold, so a compaction can never immediately re-trigger. - Document the crash vs recoverable failure taxonomy; core session repair stays compaction-agnostic (a log-only orphaned compact/start is inert). - Wire dsh-compact-basic into examples/coding-agent and add a with-key compaction e2e (compaction's first real-world exercise + runaway net). - Rewrite the RFC to encode the blueprint and move it to implemented/. The runaway-turn snapshot is a named deferred follow-up: dsh-llm-replay cannot yet serve the interleaved summarization model call.
2026-06-26 08:59:33 +08:00
retainTokens: 20480
summarizationModel: ''
maxTokens: 8192
compactionRetries: 1
refactor(compact): turn-agnostic retention + dedicated agent/pre-request seam Reform the compaction blueprint so a runaway turn survives and the design stops drifting across review rounds: - Drop in-flight-turn protection ("layer 2"). Retention is a uniform tail→head whole-unit walk; the only structural guard is step-alignment. A single turn that alone exceeds the window now compacts its own early closed steps instead of being retained verbatim (the failure mode that motivated this). - Move auto-compaction off the agent/request waterfall onto a new awaited agent/pre-request loop seam, fired before history derivation. Compaction mutates the surface; the loop derives once from the result — no double-derive, and a listener structurally cannot act on not-yet-derived messages. - Tighten compactIfNeeded to required (session, system, model, signal). - Enforce a single-pass convergence invariant in resolveConfig: reject configs where summarizationMaxTokens + retainTokens exceeds the threshold, so a compaction can never immediately re-trigger. - Document the crash vs recoverable failure taxonomy; core session repair stays compaction-agnostic (a log-only orphaned compact/start is inert). - Wire dsh-compact-basic into examples/coding-agent and add a with-key compaction e2e (compaction's first real-world exercise + runaway net). - Rewrite the RFC to encode the blueprint and move it to implemented/. The runaway-turn snapshot is a named deferred follow-up: dsh-llm-replay cannot yet serve the interleaved summarization model call.
2026-06-26 08:59:33 +08:00
# The subagent seam + BOTH in-process backends + two model-facing tools, as leaf
# entries after the app (which provides ctx.agents/ctx.tools). spawn (a fresh
# child) and fork (a child seeded with the parent's completed-turn prefix) are
# independent backends over the shared dsh-subagent-inprocess driver. Exposing
# both transports is pure config: load each backend, then load dsh-tool-subagent
# once per backend with a distinct toolName (the tool registry rejects a
# duplicate name) — no code change.
Add in-process subagent backends: spawn (fresh) and fork (seeded) The second PR of the subagent seam: the two in-process backends that run a child agent on the same cordis context, reusing the agent factory's quiescent AgentHandle teardown. Both register on ctx.subagents (PR1's named-provider registry) and share one run driver. - dsh-subagent-spawn: a FRESH child via ctx.agents.create — own session, the parent's model by default (overridable), zero inherited conversation. Also exports the shared in-process run driver (startInProcessRun): mint ids, stamp cwd/parentSession-lineage/depth, drive the one-shot (send → whenIdle), read the last assistant/message + turn/end reason, dispose to quiescence. - dsh-subagent-fork: a child SEEDED with the parent's balanced completed-turn prefix (the log up to and including its last turn/end), so the child inherits context. The in-flight unbalanced turn is excluded — a raw seed would fail the invariants replay. Proven: a regression test goes red if the boundary seeds the open turn. - Seam extension: CreateAgentOptions.seed, threaded through AgentLoop.createAgent → ctx.sessions.prepare({ seed }) (the primitive resume already used). This is the fork-lineage path the TODO(sub-agents) markers anticipated. - Depth: a merge-extensible AgentOptions.subagentDepth (0 top-level, parent+1 for a child); the depthLimit capability refuses a spawn past request.maxDepth. Tests: real-loop unit tests for both backends (mock MODEL only, real loop + invariants), a multi-subagent test (one parent drives a fork AND a spawn child then keeps working), and a with-key e2e (a real parent delegates via the `subagent` tool to a real child that writes a file on disk — world-verified). 100% per-file coverage. The coding-agent demo wires the spawn backend + tool. Snapshot coverage of nested agents is deferred to a stacked follow-up (TODO(subagent-snapshots)): dsh-llm-replay is a single global positional cursor that cannot route calls to a parent vs. a child on one context. Recorded in the RFC's deferrals and a new AGENTS.md rule: designing a subsystem must design its test infrastructure END TO END up front, verifying the snapshot/e2e harness can express the new shape — a gap this plan hit.
2026-06-22 05:58:40 +08:00
- id: subagent
name: '@deepseek-ai/dsh-subagent'
- id: subagent-spawn
name: '@deepseek-ai/dsh-subagent-spawn'
config:
providerName: spawn
- id: subagent-fork
name: '@deepseek-ai/dsh-subagent-fork'
config:
providerName: fork
Add in-process subagent backends: spawn (fresh) and fork (seeded) The second PR of the subagent seam: the two in-process backends that run a child agent on the same cordis context, reusing the agent factory's quiescent AgentHandle teardown. Both register on ctx.subagents (PR1's named-provider registry) and share one run driver. - dsh-subagent-spawn: a FRESH child via ctx.agents.create — own session, the parent's model by default (overridable), zero inherited conversation. Also exports the shared in-process run driver (startInProcessRun): mint ids, stamp cwd/parentSession-lineage/depth, drive the one-shot (send → whenIdle), read the last assistant/message + turn/end reason, dispose to quiescence. - dsh-subagent-fork: a child SEEDED with the parent's balanced completed-turn prefix (the log up to and including its last turn/end), so the child inherits context. The in-flight unbalanced turn is excluded — a raw seed would fail the invariants replay. Proven: a regression test goes red if the boundary seeds the open turn. - Seam extension: CreateAgentOptions.seed, threaded through AgentLoop.createAgent → ctx.sessions.prepare({ seed }) (the primitive resume already used). This is the fork-lineage path the TODO(sub-agents) markers anticipated. - Depth: a merge-extensible AgentOptions.subagentDepth (0 top-level, parent+1 for a child); the depthLimit capability refuses a spawn past request.maxDepth. Tests: real-loop unit tests for both backends (mock MODEL only, real loop + invariants), a multi-subagent test (one parent drives a fork AND a spawn child then keeps working), and a with-key e2e (a real parent delegates via the `subagent` tool to a real child that writes a file on disk — world-verified). 100% per-file coverage. The coding-agent demo wires the spawn backend + tool. Snapshot coverage of nested agents is deferred to a stacked follow-up (TODO(subagent-snapshots)): dsh-llm-replay is a single global positional cursor that cannot route calls to a parent vs. a child on one context. Recorded in the RFC's deferrals and a new AGENTS.md rule: designing a subsystem must design its test infrastructure END TO END up front, verifying the snapshot/e2e harness can express the new shape — a gap this plan hit.
2026-06-22 05:58:40 +08:00
- id: tool-subagent
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: spawn
toolName: subagent
- id: tool-subagent-fork
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: fork
toolName: subagent_fork
# The model-facing todo_write tool: whole-list task tracking written to the
# session log (todo/write), rendered as a stdio checklist / ACP plan.
- id: tool-todo
name: '@deepseek-ai/dsh-tool-todo'
# Filesystem capability stack: local provider, read-before-write/edit policy
# gate, then the model-facing read/write/edit tools. stdio-agent is a single
# session, so relative paths resolve from the process cwd (the workspace).
- id: fs-local
name: '@deepseek-ai/dsh-fs-local'
config:
cwd: !!js process.cwd()
- id: fs-policy
name: '@deepseek-ai/dsh-fs-policy'
- id: tool-fs
name: '@deepseek-ai/dsh-tool-fs'