feat(agent-presets): compose each session's agent from a preset cordis.yml
A preset is a directory holding one `agent.cordis.yml`. Mounting it under an agent's scope context during `setup(agentCtx)` gives that one session its own tools and prompt sections while every other live session keeps its own. No registry gains a tier. `dsh-tools` and `dsh-system-prompt` already file registrations into the calling context's scope layer, and entry contexts chain to the context a subtree was plugged into, so a composition mounted under `agent.ctx` is that agent's alone and unwinds with it. The mount audits itself because a directly-plugged subtree is absent from `ctx.loader.entries()` and no boot audit covers it. It rejects an unscoped target, a row that never became usable, and a row that published a service into the root service realm — that last one is process-global rather than per-session, and its collision with the next session surfaces as an unhandled rejection `setup` never observes, leaving a half-composed agent that looks healthy. The package invariant re-checks that rule on every service notification, since a row publishing from a timer would escape a one-shot audit. Raises the `packages/README.md` word ceiling from 920 to 980: the group table must enumerate every group, and the new `preset/` row is necessary content. Design: .agents/notes/implemented/architecture/2026-08-03-per-session-agent-presets.md
This commit is contained in:
@@ -110,6 +110,37 @@ Depends on: [`AgentOptions`](core-data-structures/core.md) · [`SessionId`](core
|
||||
|
||||
Source: [`packages/core/agent-loop/src/index.ts:236`](../packages/core/agent-loop/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-agent-presets`
|
||||
|
||||
Requires: `loader`
|
||||
|
||||
```ts config-catalog
|
||||
/** Plugin config: which profile is the default, and where profiles live. */
|
||||
export interface Config {
|
||||
/** Profile id mounted when a caller names none. Missing at mount time fails loud. */
|
||||
default: string
|
||||
/** Scanned roots in precedence order; an earlier root wins a duplicate id. */
|
||||
roots: PresetRoot[]
|
||||
}
|
||||
|
||||
/** One directory scanned for profile subdirectories. */
|
||||
export interface PresetRoot {
|
||||
/** Directory holding one subdirectory per profile; a leading `~` expands. */
|
||||
path: string
|
||||
/** Trust recorded on every profile discovered under this root. */
|
||||
trust: PresetTrust
|
||||
}
|
||||
|
||||
/**
|
||||
* Where a profile's composition came from. A `system` profile ships with the
|
||||
* deployment; a `user` profile was authored locally, by a person or by an
|
||||
* agent, and therefore carries the same trust as shell access.
|
||||
*/
|
||||
export type PresetTrust = 'system' | 'user'
|
||||
```
|
||||
|
||||
Source: [`packages/preset/agent-presets/src/types.ts:29`](../packages/preset/agent-presets/src/types.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-agent-spine-demo`
|
||||
|
||||
```ts config-catalog
|
||||
|
||||
Reference in New Issue
Block a user