Files
HologramAgent-DSH-Memory-Port/cordis.patch.yml
jianf f1b74a35ef feat(memory): ship the profile overlay that mounts the replacement loop
6d9ad62 added `lib/loop.js` — a subclass of the harness `AgentLoop` that moves
per-turn recall out of conversation history and into the system prompt. That
class was never instantiated by anything: the commit proved the pure
`promoteSnapshotSections` function, not that a replacement loop can actually be
mounted. This commit adds the two pieces the mount needs.

`cordis.patch.yml` is the overlay that does it, and it is the only artefact that
proves the swap is possible:

- `- id: agent-loop / disabled: true` is mandatory and is addressed by ID, not
  by name. `AgentLoop`'s constructor ends with
  `ctx.effect(() => ctx.agents.setFactory(this))`
  (dsh-agent-loop/lib/index.js:1590) and `setFactory` throws when a factory is
  already registered (dsh-agent/lib/index.js:429-437). Leaving the base row
  enabled fails startup with "an agent factory is already registered".
- The inserted row reuses the package itself under the `dsh-memory/loop`
  subpath, with no `config` block: `HologramAgentLoop` declares no `static
  Config`, so it inherits the parent schema and the profile's own `agent-loop`
  config rows keep working through the inherited constructor.

`package.json` gains that subpath export plus `lib/loop.js` in `files`. Without
the export the overlay resolves to nothing and the profile cannot boot — the
two changes only work together, which is why they land in one commit.

Measured on this machine with the overlay applied to a headless profile
(`~/.dsh/profiles/headless/cordis.patch.yml`), dsh 0.2.1-rc.2:

- `dsh --profile headless "回答两个字:收到了"` -> exit 0, stdout `收到了`;
  `--dump-config` shows `- id: agent-loop` with `disabled: true` alongside
  `- id: hologram-agent-loop, name: dsh-memory/loop`.
- A tool round trip returns the tool's output: asking for
  `echo TOOL_OK_42` via bash yields `TOOL_OK_42`.
- SIGINT during a long task exits in 1s with code 130, stdout empty.
- The web profile's patch layer is still `[]` — untouched.

npm test: 247 pass, 0 fail.
2026-11-04 17:07:48 +08:00

30 lines
1.4 KiB
YAML

# Ship-ready overlay that swaps the harness loop for `dsh-memory/loop`.
#
# This is the ONLY artefact that proves the replacement loop is mounted: without
# it `lib/loop.js` is a subclass nobody instantiates (its unit tests exercise the
# pure `promoteSnapshotSections` function and nothing else).
#
# Apply it to a profile (a `--patch` overlay, or copied into the profile's own
# `cordis.patch.yml`); `dsh` composes it over `@deepseek-ai/dsh-base`, where the
# `agent-loop` row already exists:
#
# dsh --profile headless --patch <this file> "<task>"
#
# ★ The disable is not optional, and it is by ID, not by name. `AgentLoop`'s
# constructor ends with `ctx.effect(() => ctx.agents.setFactory(this))`
# (dsh-agent-loop/lib/index.js:1590), and `dsh-agent`'s `setFactory` throws when a
# factory is already registered (dsh-agent/lib/index.js:429-437). Leaving the base
# row enabled makes startup fail with "an agent factory is already registered";
# `HologramAgentLoop` inherits that constructor, so it registers exactly once —
# but only if the base row is gone.
- id: agent-loop
disabled: true
# The replacement. No `config` block on purpose: `HologramAgentLoop` defines no
# `static Config`, so it inherits the parent schema (`maxParallelToolCalls`,
# `agents`) and the profile's own `agent-loop` config rows keep working through
# the inherited constructor.
- insert:
- id: hologram-agent-loop
name: dsh-memory/loop