feat(web): compose a web session's agent from a named preset
`session.create` takes an optional `agentPreset`, and the host resolves it, mounts it during pre-publication setup, and records the resolved id on the session header so a later resume rebuilds the same agent. Resolution happens BEFORE the session exists, not inside setup: the session boundary snapshots `meta` before asynchronous setup begins, so an id discovered during setup could never reach the header. Mounting still happens in setup, where a failure rolls the whole creation back rather than publishing a session whose capabilities are half-installed. Resume ignores whatever the request names and rebuilds from the stored id. A resumed session's history was produced under that composition; restoring a different one would replay tool calls the model can no longer make. `dsh-agent-presets` now throws `UnknownPresetError` / `PresetMountError` so the host can tell a bad request from a broken preset — they become `agent-preset-not-found` and `agent-preset-invalid`. Ships the two built-in compositions (`standard`, `core-web`) and the persona row that lets them differ in identity. Nothing mounts them yet: no roster is configured, so `composeAgent` finds no service and every session keeps the host composition. Wiring the roster and moving base's agent-plane rows behind it is the next commit, so the switch happens atomically with a real-composition test.
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/core-data-structures/persistence.md
|
||||
persistence.md: 0968496201defa869d94925e8e5ae3c5da1bbd37
|
||||
persistence.zh.md: efb01427b4355e531fb9b86922223cf27d3b3db0
|
||||
persistence.md: 65b000516894c6dfb4c661f0b9112197317197e6
|
||||
persistence.zh.md: 214b631063ae5368b95e2fa9603941eb7b3bbe64
|
||||
|
||||
@@ -77,12 +77,19 @@ interface SessionHeader {
|
||||
* resume — a runtime-only depth would reset a resumed child to top-level.
|
||||
*/
|
||||
readonly delegationDepth?: number
|
||||
/**
|
||||
* Id of the agent preset this session's agent was composed from, when the
|
||||
* deployment composes per session. Durable because the preset decides the
|
||||
* session's tools and prompt: a resume that restored a different composition
|
||||
* would replay history the model can no longer act on.
|
||||
*/
|
||||
readonly agentPreset?: string
|
||||
}
|
||||
```
|
||||
|
||||
## `CreateSessionOptions` — seeding and metadata
|
||||
|
||||
Creating a `Session` through the store takes a `seed` (initial replay or fork history) and `meta` (the storage-level fields the store folds into a `SessionHeader`). The store fills in `version`/`id` and defaults `createdAt`; the caller may supply the validated absolute `cwd`, the `parentSession` lineage, the `seedLength` seed boundary, the optional coarse `origin`, the `delegationDepth`, and an existing `createdAt`. `origin: 'subagent'` lets product navigation hide duplicate child rows; it does not prove that a descriptor is valid or that the child can resume.
|
||||
Creating a `Session` through the store takes a `seed` (initial replay or fork history) and `meta` (the storage-level fields the store folds into a `SessionHeader`). The store fills in `version`/`id` and defaults `createdAt`; the caller may supply the validated absolute `cwd`, the `parentSession` lineage, the `seedLength` seed boundary, the optional coarse `origin`, the `delegationDepth`, the `agentPreset` the agent was composed from, and an existing `createdAt`. `origin: 'subagent'` lets product navigation hide duplicate child rows; it does not prove that a descriptor is valid or that the child can resume.
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
@@ -104,6 +111,7 @@ interface CreateSessionOptions {
|
||||
readonly seedLength?: number
|
||||
readonly origin?: 'subagent'
|
||||
readonly delegationDepth?: number
|
||||
readonly agentPreset?: string
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -77,12 +77,19 @@ interface SessionHeader {
|
||||
* resume — a runtime-only depth would reset a resumed child to top-level.
|
||||
*/
|
||||
readonly delegationDepth?: number
|
||||
/**
|
||||
* Id of the agent preset this session's agent was composed from, when the
|
||||
* deployment composes per session. Durable because the preset decides the
|
||||
* session's tools and prompt: a resume that restored a different composition
|
||||
* would replay history the model can no longer act on.
|
||||
*/
|
||||
readonly agentPreset?: string
|
||||
}
|
||||
```
|
||||
|
||||
## `CreateSessionOptions`:seed 与元数据
|
||||
|
||||
通过 store 创建 `Session` 时会接收 `seed`(初始回放或 fork 历史)与 `meta`(store 折叠进 `SessionHeader` 的存储层字段)。store 填充 `version`/`id` 并为 `createdAt` 提供默认值;调用方可以提供已校验的绝对 `cwd`、`parentSession` 谱系、`seedLength` 种子边界、可选的粗粒度 `origin`、`delegationDepth` 以及已有的 `createdAt`。`origin: 'subagent'` 让产品导航能够隐藏重复的 child 行;它不证明描述符有效,也不证明 child 可以恢复。
|
||||
通过 store 创建 `Session` 时会接收 `seed`(初始回放或 fork 历史)与 `meta`(store 折叠进 `SessionHeader` 的存储层字段)。store 填充 `version`/`id` 并为 `createdAt` 提供默认值;调用方可以提供已校验的绝对 `cwd`、`parentSession` 谱系、`seedLength` 种子边界、可选的粗粒度 `origin`、`delegationDepth`、该 agent 所依据组装的 `agentPreset` 以及已有的 `createdAt`。`origin: 'subagent'` 让产品导航能够隐藏重复的 child 行;它不证明描述符有效,也不证明 child 可以恢复。
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
@@ -104,6 +111,7 @@ interface CreateSessionOptions {
|
||||
readonly seedLength?: number
|
||||
readonly origin?: 'subagent'
|
||||
readonly delegationDepth?: number
|
||||
readonly agentPreset?: string
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user