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:
@@ -81,7 +81,7 @@ async resolve(id?: string): Promise<AgentPreset>
|
||||
async mount(agentCtx: Context, id?: string): Promise<AgentPreset>
|
||||
```
|
||||
|
||||
Source: [`packages/preset/agent-presets/src/index.ts:36`](../../packages/preset/agent-presets/src/index.ts)
|
||||
Source: [`packages/preset/agent-presets/src/index.ts:37`](../../packages/preset/agent-presets/src/index.ts)
|
||||
|
||||
## `ctx.agents` — `AgentRegistry`
|
||||
|
||||
@@ -253,7 +253,7 @@ roots(): Agent[]
|
||||
|
||||
Types: [Agent](../core-data-structures/core.md) · [SessionId](../core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/agent/src/index.ts:242`](../../packages/core/agent/src/index.ts)
|
||||
Source: [`packages/core/agent/src/index.ts:243`](../../packages/core/agent/src/index.ts)
|
||||
|
||||
## `ctx.approval` — `ApprovalService`
|
||||
|
||||
@@ -1785,7 +1785,7 @@ fork(source: SessionForkSource, boundary?: number, childSessionId?: SessionId):
|
||||
|
||||
Types: [CreateSessionOptions](../core-data-structures/persistence.md) · [PrepareSessionOptions](../core-data-structures/persistence.md) · [Session](../core-data-structures/session.md) · [SessionId](../core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/session/src/index.ts:800`](../../packages/core/session/src/index.ts)
|
||||
Source: [`packages/core/session/src/index.ts:803`](../../packages/core/session/src/index.ts)
|
||||
|
||||
## `ctx.sessionTitle` — `SessionTitleService`
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
+14
-14
@@ -77,7 +77,7 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
}[T]
|
||||
```
|
||||
|
||||
Sources: [`packages/core/session/src/types.ts:308`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:315`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:343`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:375`](../packages/core/session/src/types.ts)
|
||||
Sources: [`packages/core/session/src/types.ts:316`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:323`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:351`](../packages/core/session/src/types.ts) · [`packages/core/session/src/types.ts:383`](../packages/core/session/src/types.ts)
|
||||
|
||||
## Events
|
||||
|
||||
@@ -174,7 +174,7 @@ Source: [`packages/ui/user-approval/src/index.ts:67`](../packages/ui/user-approv
|
||||
|
||||
Types: [StreamChunk](core-data-structures/llm-streaming.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:238`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:246`](../packages/core/session/src/types.ts)
|
||||
|
||||
#### `assistant/message` — surface
|
||||
|
||||
@@ -190,7 +190,7 @@ Source: [`packages/core/session/src/types.ts:238`](../packages/core/session/src/
|
||||
|
||||
Types: [TokenUsage](core-data-structures/llm-streaming.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:245`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:253`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `command/*`
|
||||
|
||||
@@ -446,7 +446,7 @@ Source: [`packages/plan/plan-mode/src/index.ts:52`](../packages/plan/plan-mode/s
|
||||
'request/context': RequestContext
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:281`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:289`](../packages/core/session/src/types.ts)
|
||||
|
||||
#### `request/header` — log-only
|
||||
|
||||
@@ -458,7 +458,7 @@ Source: [`packages/core/session/src/types.ts:281`](../packages/core/session/src/
|
||||
'request/header': { header: EpochHeader; reason: RequestHeaderReason }
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:276`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:284`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `sandbox/*`
|
||||
|
||||
@@ -511,7 +511,7 @@ Source: [`packages/sandbox/sandbox-policy/src/session-mode.ts:33`](../packages/s
|
||||
'session/end-seed': Record<string, never>
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:304`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:312`](../packages/core/session/src/types.ts)
|
||||
|
||||
#### `session/title` — log-only
|
||||
|
||||
@@ -547,7 +547,7 @@ Source: [`packages/session-title/session-title-llm/src/index.ts:43`](../packages
|
||||
'step/end': { turn: number; step: number }
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:228`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:236`](../packages/core/session/src/types.ts)
|
||||
|
||||
#### `step/start` — log-only
|
||||
|
||||
@@ -556,7 +556,7 @@ Source: [`packages/core/session/src/types.ts:228`](../packages/core/session/src/
|
||||
'step/start': { turn: number; step: number }
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:226`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:234`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `subagent/*`
|
||||
|
||||
@@ -586,7 +586,7 @@ Source: [`packages/subagent/subagent/src/descriptor.ts:37`](../packages/subagent
|
||||
|
||||
Types: [TodoItem](core-data-structures/session.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:271`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:279`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `tool/*`
|
||||
|
||||
@@ -603,7 +603,7 @@ Source: [`packages/core/session/src/types.ts:271`](../packages/core/session/src/
|
||||
|
||||
Types: [CallId](core-data-structures/core.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:251`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:259`](../packages/core/session/src/types.ts)
|
||||
|
||||
#### `tool/code-dispatch` — log-only
|
||||
|
||||
@@ -676,7 +676,7 @@ Source: [`packages/core/tools/src/code-mode.ts:33`](../packages/core/tools/src/c
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:263`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:271`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `turn/*`
|
||||
|
||||
@@ -696,7 +696,7 @@ Source: [`packages/core/session/src/types.ts:263`](../packages/core/session/src/
|
||||
|
||||
Types: [TurnEndReason](core-data-structures/session.md)
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:224`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:232`](../packages/core/session/src/types.ts)
|
||||
|
||||
#### `turn/start` — log-only
|
||||
|
||||
@@ -710,7 +710,7 @@ Source: [`packages/core/session/src/types.ts:224`](../packages/core/session/src/
|
||||
'turn/start': { turn: number }
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:215`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:223`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `user/*`
|
||||
|
||||
@@ -727,7 +727,7 @@ Source: [`packages/core/session/src/types.ts:215`](../packages/core/session/src/
|
||||
'user/message': UserMessage
|
||||
```
|
||||
|
||||
Source: [`packages/core/session/src/types.ts:236`](../packages/core/session/src/types.ts)
|
||||
Source: [`packages/core/session/src/types.ts:244`](../packages/core/session/src/types.ts)
|
||||
|
||||
### `web/*`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user