fix(session-title): harden async provider lifecycle

This commit is contained in:
Tianyi Cui
2026-07-21 12:08:00 +08:00
parent bb7db52941
commit a9d518a38e
25 changed files with 491 additions and 102 deletions

View File

@@ -881,7 +881,7 @@ Source: [`packages/session-title/session-title/src/index.ts:63`](../packages/ses
## `@deepseek-ai/dsh-session-title-all-messages-llm`
Requires: `sessionTitle` · `llm`
Requires: `sessionTitle` · `llm` · `sessions`
```ts config-catalog
/** Required LLM policy; this plugin adds no defaults. */
@@ -894,7 +894,7 @@ Source: [`packages/session-title/session-title-all-messages-llm/src/index.ts:15`
## `@deepseek-ai/dsh-session-title-first-message-llm`
Requires: `sessionTitle` · `llm`
Requires: `sessionTitle` · `llm` · `sessions`
```ts config-catalog
/** Required LLM policy; this plugin adds no defaults. */

View File

@@ -1016,14 +1016,14 @@ async refresh(session: Session, signal?: AbortSignal): Promise<SessionTitleSnaps
* Register the sole optional title provider. Disposal aborts its pending and
* active work before another provider may register.
* @param provider - provider identity, cadence, and generation function.
* @returns exact Cordis effect disposer for HMR-safe unregistration.
* @returns exact Cordis effect disposer, which settles after active calls quiesce.
*/
register(provider: SessionTitleProvider): () => void
register(provider: SessionTitleProvider): () => Promise<void>
```
Types: [Session](../core-data-structures/session.md) · [SessionTitleProvider](../core-data-structures/session-title.md) · [SessionTitleSnapshot](../core-data-structures/session-title.md)
Source: [`packages/session-title/session-title/src/index.ts:233`](../../packages/session-title/session-title/src/index.ts)
Source: [`packages/session-title/session-title/src/index.ts:235`](../../packages/session-title/session-title/src/index.ts)
## `ctx.skills` — `SkillService`

View File

@@ -1,8 +1,8 @@
# Session Titles
Durable latest-wins title state and the optional asynchronous provider vocabulary owned by [`@deepseek-ai/dsh-session-title`](../../packages/session-title/session-title). The package README owns timing, fallback, failure, and fork behavior; the generated [persistence catalog](../persistence-catalog.md) owns the complete `session/title` event declaration.
Durable latest-wins title state and the optional asynchronous provider vocabulary owned by [`@deepseek-ai/dsh-session-title`](../../packages/session-title/session-title). The shared LLM helper owns the exact auxiliary request record. Package READMEs own timing, fallback, failure, and fork behavior; the generated [persistence catalog](../persistence-catalog.md) owns the complete event declarations.
Source: [`packages/session-title/session-title/src/index.ts`](../../packages/session-title/session-title/src/index.ts)
Sources: [`packages/session-title/session-title/src/index.ts`](../../packages/session-title/session-title/src/index.ts), [`packages/session-title/session-title-llm/src/index.ts`](../../packages/session-title/session-title-llm/src/index.ts)
## Durable title state
@@ -56,6 +56,28 @@ interface SessionTitleSnapshot extends SessionTitleEventData {
}
```
## Auxiliary request record
The shared LLM helper records each validated, dispatchable title request before calling the model. The payload reproduces the model-visible system and message input, routing, output limit, provider ownership, and source-message attribution even when generation later fails.
```ts type-equiv
/** Exact model-visible request recorded before one auxiliary title dispatch. */
interface SessionTitleLlmRequestEventData {
/** Registered title-provider identity responsible for the request. */
readonly titleProvider: SessionTitleProviderId
/** Exact human `user/message` seqs represented in `messages`. */
readonly messageSeqs: number[]
/** Exact auxiliary LLM route. */
readonly route: SessionTitleModelProvenance
/** Exact auxiliary system prompt. */
readonly system: string
/** Exact auxiliary message list. */
readonly messages: Message[]
/** Exact auxiliary output-token cap. */
readonly maxTokens: number
}
```
## Provider input and output
The service snapshots eligible messages through one revision. A provider returns only seqs from that request; service-owned acceptance verifies ordering, normalizes the title, enforces the byte limit, and appends provenance.

View File

@@ -251,6 +251,7 @@ flowchart TD
pkg_session_query --> pkg_session_persistence
pkg_session_query --> pkg_session_title
pkg_session_title_llm --> pkg_llm
pkg_session_title_llm --> pkg_session
pkg_session_title_llm --> pkg_session_title
pkg_session_title_llm --> pkg_timeout
pkg_invariants --> pkg_agent
@@ -298,9 +299,11 @@ flowchart TD
pkg_fs_sandbox --> pkg_sandbox
pkg_fs_sandbox --> pkg_sandbox_policy
pkg_session_title_all_messages_llm --> pkg_llm
pkg_session_title_all_messages_llm --> pkg_session
pkg_session_title_all_messages_llm --> pkg_session_title
pkg_session_title_all_messages_llm --> pkg_session_title_llm
pkg_session_title_first_message_llm --> pkg_llm
pkg_session_title_first_message_llm --> pkg_session
pkg_session_title_first_message_llm --> pkg_session_title
pkg_session_title_first_message_llm --> pkg_session_title_llm
pkg_permission --> pkg_bash
@@ -585,7 +588,7 @@ flowchart TD
| [`session-persistence-jsonl`](../packages/session-persistence/session-persistence-jsonl) | `session-persistence` | [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence) |
| [`session-persistence-sqlite`](../packages/session-persistence/session-persistence-sqlite) | `session-persistence` | [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence) |
| [`session-query`](../packages/session-query/session-query) | `session-query` | [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`session-title`](../packages/session-title/session-title) |
| [`session-title-llm`](../packages/session-title/session-title-llm) | `session-title` | [`llm`](../packages/llm/llm), [`session-title`](../packages/session-title/session-title), [`timeout`](../packages/util/timeout) |
| [`session-title-llm`](../packages/session-title/session-title-llm) | `session-title` | [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-title`](../packages/session-title/session-title), [`timeout`](../packages/util/timeout) |
| [`invariants`](../packages/support/invariants) | `support` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session) |
| [`commands`](../packages/ui/commands) | `ui` | [`agent`](../packages/core/agent), [`scope`](../packages/core/scope) |
| [`user-approval`](../packages/ui/user-approval) | `ui` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt) |
@@ -598,8 +601,8 @@ flowchart TD
| [`goal-session`](../packages/goal/goal-session) | `goal` | [`agent`](../packages/core/agent), [`goal`](../packages/goal/goal), [`llm`](../packages/llm/llm), [`session`](../packages/core/session) |
| [`bash-sandbox`](../packages/bash/bash-sandbox) | `bash` | [`bash`](../packages/bash/bash), [`bash-local`](../packages/bash/bash-local), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
| [`fs-sandbox`](../packages/fs/fs-sandbox) | `fs` | [`fs`](../packages/fs/fs), [`fs-local`](../packages/fs/fs-local), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy) |
| [`session-title-all-messages-llm`](../packages/session-title/session-title-all-messages-llm) | `session-title` | [`llm`](../packages/llm/llm), [`session-title`](../packages/session-title/session-title), [`session-title-llm`](../packages/session-title/session-title-llm) |
| [`session-title-first-message-llm`](../packages/session-title/session-title-first-message-llm) | `session-title` | [`llm`](../packages/llm/llm), [`session-title`](../packages/session-title/session-title), [`session-title-llm`](../packages/session-title/session-title-llm) |
| [`session-title-all-messages-llm`](../packages/session-title/session-title-all-messages-llm) | `session-title` | [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-title`](../packages/session-title/session-title), [`session-title-llm`](../packages/session-title/session-title-llm) |
| [`session-title-first-message-llm`](../packages/session-title/session-title-first-message-llm) | `session-title` | [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-title`](../packages/session-title/session-title), [`session-title-llm`](../packages/session-title/session-title-llm) |
| [`permission`](../packages/ui/permission) | `ui` | [`bash`](../packages/bash/bash), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`user-approval`](../packages/ui/user-approval) |
| [`agent-loop`](../packages/core/agent-loop) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session-persistence/session-persistence), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`tool-goal`](../packages/goal/tool-goal) | `goal` | [`agent`](../packages/core/agent), [`goal`](../packages/goal/goal), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |

View File

@@ -392,6 +392,17 @@ Types: [SessionTitleEventData](core-data-structures/session-title.md)
Source: [`packages/session-title/session-title/src/index.ts:89`](../packages/session-title/session-title/src/index.ts)
#### `session/title-llm-request` — log-only
```ts persistence-catalog
/** Log-only pre-dispatch record of one session-title model request. */
'session/title-llm-request': SessionTitleLlmRequestEventData
```
Types: [SessionTitleLlmRequestEventData](core-data-structures/session-title.md)
Source: [`packages/session-title/session-title-llm/src/index.ts:40`](../packages/session-title/session-title-llm/src/index.ts)
### `steering/*`
#### `steering/message` — surface