docs(upgrade): fold registration compatibility into the projection handles guide
Move the session projection handles guide from the released v0.2.1-alpha.3 directory to the current v0.2.1-rc.2 directory and fold in the callable registration and deprecated keyed-read notes, replacing the separate session-projection-registration guide.
This commit is contained in:
1 parent
b3b82021d5
commit
87ca056c0d
10 files changed
+59
-109
No files matched your search
@@ -1,21 +0,0 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "Session projection registration is asynchronous and returns a retained reader instead of a disposer."
|
||||
---
|
||||
# Session projection registration handles
|
||||
|
||||
English | [中文](guide.zh.md)
|
||||
|
||||
## Change
|
||||
|
||||
`@deepseek-ai/dsh-session-projection` changes `SessionProjectionRegistry.register(definition)` from a synchronous disposer to `Promise<ProjectionHandle<S>>`. Registry-level `stateOf(session, key)` and `SessionProjectionStateMap` are removed. Host state types stay local to `ProjectionDefinition<K, S>` and are inferred from `stateSchema` during registration. Registration errors now reject the returned promise. After the last registration is disposed, the unit leaves snapshots, checkpoints, and live notifications, but retained handles can still fold Session events on demand.
|
||||
|
||||
`@deepseek-ai/dsh-agent` and `@deepseek-ai/dsh-subagent` require `sessionProjections`. AgentRegistry owns turn and step state; consumers use `ctx.agents.turnBoundaryOf(session)` instead of importing `turnBoundaryProjectionDefinition`. Turn-state consumers, including the Claude Code mods bridge, require `agents`. Preset and context-pressure reads use `ctx.agentPresets.presetForSession(session)` and `ctx.tokenMeter.contextPressure(session)`. The API controller and mods bridge no longer register those definitions independently; their optional-service behavior applies when the owning service is absent. `@deepseek-ai/dsh-api-session-controller` also removes `installModelSelectionProjection`.
|
||||
|
||||
## Migration
|
||||
|
||||
1. Mount `SessionProjectionRegistry` before `AgentRegistry`, `SubagentRuntime`, and other projection owners in custom compositions. Include `@deepseek-ai/dsh-agent` wherever a plugin requires `agents`. Consumers of domain data inject the owning service.
|
||||
2. Remove host-state map augmentations and imports; pass the local state type as the second `ProjectionDefinition<K, S>` argument. Keep client-value declarations in `SessionProjectionMap`. For a plugin's own definitions, await `ctx.sessionProjections.register(definition)` in asynchronous `apply()` or `[Service.init]()` and retain the handle privately before publishing dependent operations. Keep existing function-plugin namespace exports.
|
||||
3. Replace `registry.stateOf(session, key)` with a business service method for another domain, or `handle.stateOf(session)` inside the owner. Replace stored unregister callbacks with `handle.dispose`, which always returns `Promise<void>`, and await explicit disposal; fiber disposal still releases registrations automatically. Await registration when handling initialization failures.
|
||||
4. Replace `installModelSelectionProjection(ctx)` with `await ctx.sessionProjections.register(modelSelectionProjection)`, importing the definition from `@deepseek-ai/dsh-api-session-controller/src/model-selection-projection.ts`.
|
||||
5. Typecheck custom plugins, then verify activation, a Session state read, and owner disposal. A released reader remains usable, while the released unit disappears from new snapshots once its final registration is gone.
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "Session 投影注册改为异步,并返回保留读取能力的句柄而不是释放函数。"
|
||||
---
|
||||
# Session 投影注册句柄
|
||||
|
||||
[English](guide.md) | 中文
|
||||
|
||||
## 变更
|
||||
|
||||
`@deepseek-ai/dsh-session-projection` 的 `SessionProjectionRegistry.register(definition)` 从同步释放函数改为返回 `Promise<ProjectionHandle<S>>`。注册表级 `stateOf(session, key)` 与 `SessionProjectionStateMap` 已移除。宿主状态类型保留在各自的 `ProjectionDefinition<K, S>` 中,注册时从 `stateSchema` 推导。注册错误现在使返回的 Promise 拒绝。最后一次注册释放后,该投影单元不再参与快照、检查点和实时通知,但保留的句柄仍可按需折叠 Session 事件。
|
||||
|
||||
`@deepseek-ai/dsh-agent` 与 `@deepseek-ai/dsh-subagent` 依赖 `sessionProjections`。AgentRegistry 持有轮次和步骤状态;消费方使用 `ctx.agents.turnBoundaryOf(session)`,不再导入 `turnBoundaryProjectionDefinition`。包括 Claude Code mods 桥接在内的轮次状态消费方依赖 `agents`。预设与上下文压力分别通过 `ctx.agentPresets.presetForSession(session)` 和 `ctx.tokenMeter.contextPressure(session)` 读取。API 控制器与 mods 桥接不再独立注册这些定义;所属服务缺席时采用各自的可选服务行为。`@deepseek-ai/dsh-api-session-controller` 同时移除了 `installModelSelectionProjection`。
|
||||
|
||||
## 迁移
|
||||
|
||||
1. 在自定义组合中,先挂载 `SessionProjectionRegistry`,再挂载 `AgentRegistry`、`SubagentRuntime` 及其他投影所有者。组合中的插件依赖 `agents` 时,加入 `@deepseek-ai/dsh-agent`。领域数据的消费方注入所属服务。
|
||||
2. 删除宿主状态映射的声明合并与导入,将局部状态类型作为 `ProjectionDefinition<K, S>` 的第二个类型参数。保留 `SessionProjectionMap` 中的客户端值声明。对插件自己的定义,在异步 `apply()` 或 `[Service.init]()` 中等待 `ctx.sessionProjections.register(definition)`,并在提供依赖操作前于内部保存句柄。保留现有函数插件命名空间导出。
|
||||
3. 将 `registry.stateOf(session, key)` 替换为其他领域的业务服务方法,或所有者内部的 `handle.stateOf(session)`。将保存的取消注册回调替换为始终返回 `Promise<void>` 的 `handle.dispose`,并等待显式释放完成;fiber 释放仍会自动释放注册。处理初始化失败时须等待注册。
|
||||
4. 将 `installModelSelectionProjection(ctx)` 替换为 `await ctx.sessionProjections.register(modelSelectionProjection)`,从 `@deepseek-ai/dsh-api-session-controller/src/model-selection-projection.ts` 导入该定义。
|
||||
5. 对自定义插件执行类型检查,再验证激活、Session 状态读取与 owner 释放。已释放的读取句柄仍可使用,而投影单元在最后一次注册解除后会从新快照中消失。
|
||||
+9
-9
@@ -1,16 +1,16 @@
|
||||
# Bilingual-pair consistency record for guide.md (docs/i18n/README.md): per heading
|
||||
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
||||
# After editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/upgrade-guide/v0.2.1-alpha.3/session-projection-handles/guide.md
|
||||
# pnpm run verify-translation-pairing --write docs/upgrade-guide/v0.2.1-rc.2/session-projection-handles/guide.md
|
||||
/:
|
||||
en: b3f54a7eadb3398a
|
||||
zh: 6815b996b2cebc6f
|
||||
en: a7c158942ce2a575
|
||||
zh: 7103da2fa7ca494a
|
||||
/session-projection-registration-handles:
|
||||
en: 5cf8cb0051860df5
|
||||
zh: 2578c6c3e77bc1c7
|
||||
en: 08af78abac6d3bcd
|
||||
zh: 85ede5596cac9d5e
|
||||
/session-projection-registration-handles/change:
|
||||
en: 64c2492c43c7a263
|
||||
zh: ba5a15b959df496c
|
||||
en: 8e49d770c3621cfb
|
||||
zh: 3d8266cae467bc05
|
||||
/session-projection-registration-handles/migration:
|
||||
en: bd4310bb946b6f08
|
||||
zh: 2086e6e9c11bc4ed
|
||||
en: 9c7d73f9f50c4bdd
|
||||
zh: b1c597c63d52b444
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "Session projection registration resolves asynchronously to a retained reader; the callable result and registry-level state reads are deprecated."
|
||||
---
|
||||
# Session projection registration handles
|
||||
|
||||
English | [中文](guide.zh.md)
|
||||
|
||||
## Change
|
||||
|
||||
`@deepseek-ai/dsh-session-projection` changes `SessionProjectionRegistry.register(definition)` from a synchronous disposer to `Promise<ProjectionHandle<S>>`. The definition installs synchronously; awaiting the result yields a handle with `stateOf(session)` and `dispose()`, and registration errors reject it. The runtime value is a callable thenable, not a native Promise: calling it still releases the registration, but that call is deprecated. `typeof registration` is `"function"` and `registration instanceof Promise` is false, so code that branches on those checks or treats functions as callbacks is affected; Vitest's `.rejects` calls it instead of observing the rejection.
|
||||
|
||||
Registry-level `stateOf(session, key): unknown` is deprecated. It returns `undefined` whenever no plugin currently registers the key: its owner is not composed, has not reached registration, or has released its last registration. `SessionProjectionStateMap` is removed; host state types stay local to `ProjectionDefinition<K, S>` and are inferred from `stateSchema`. After the last registration is disposed, the unit leaves snapshots, checkpoints, and live notifications, but retained handles still fold Session events on demand. [Runtime compatibility](../../../../packages/session/session-projection/README.md#deprecated-plugin-compatibility) details the deprecated calls.
|
||||
|
||||
`@deepseek-ai/dsh-agent` and `@deepseek-ai/dsh-subagent` require `sessionProjections`. AgentRegistry owns turn and step state and provides `ctx.agents.turnBoundaryOf(session)`; `@deepseek-ai/dsh-agent-loop` no longer exports `turnBoundaryProjectionDefinition`. Turn-state consumers, including the Claude Code mods bridge, require `agents`. Preset and context-pressure reads use `ctx.agentPresets.presetForSession(session)` and `ctx.tokenMeter.contextPressure(session)`. `@deepseek-ai/dsh-api-session-controller` removes `installModelSelectionProjection`.
|
||||
|
||||
## Migration
|
||||
|
||||
1. Mount `SessionProjectionRegistry` before `AgentRegistry`, `SubagentRuntime`, and other projection owners in custom compositions. Include `@deepseek-ai/dsh-agent` wherever a plugin requires `agents`.
|
||||
2. For a plugin's own definitions, await `ctx.sessionProjections.register(definition)` in asynchronous `apply()` or `[Service.init]()` and retain the handle before publishing dependent operations. Remove `SessionProjectionStateMap` augmentations and pass the state type as the second `ProjectionDefinition<K, S>` argument. Keep client-value declarations in `SessionProjectionMap`.
|
||||
3. Replace `registry.stateOf(session, key)` with the owning service's method, such as `ctx.agents.turnBoundaryOf(session)`, or `handle.stateOf(session)` inside the owner; until then, handle its `undefined` result. Replace calls to the registration result with an awaited `handle.dispose()`; fiber disposal still releases registrations automatically.
|
||||
4. Where a native Promise is required, pass `Promise.resolve(registration)`, including `await expect(Promise.resolve(registration)).rejects.toThrow(...)` in Vitest. Replace `typeof` or `instanceof Promise` checks on the result with awaiting.
|
||||
5. Replace `installModelSelectionProjection(ctx)` with `await ctx.sessionProjections.register(modelSelectionProjection)`, importing the definition from `@deepseek-ai/dsh-api-session-controller/src/model-selection-projection.ts`.
|
||||
6. Typecheck custom plugins, then verify activation, a Session state read, a rejected registration, and owner disposal.
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "Session 投影注册异步解析为保留读取能力的句柄;可调用的注册结果与注册表级状态读取已弃用。"
|
||||
---
|
||||
# Session 投影注册句柄
|
||||
|
||||
[English](guide.md) | 中文
|
||||
|
||||
## 变更
|
||||
|
||||
`@deepseek-ai/dsh-session-projection` 的 `SessionProjectionRegistry.register(definition)` 从同步释放函数改为 `Promise<ProjectionHandle<S>>`。定义同步安装;等待结果得到带 `stateOf(session)` 与 `dispose()` 的句柄,注册错误使结果拒绝。运行时返回值是可调用的 thenable,而非原生 Promise:调用它仍会释放注册,但该调用已弃用。`typeof registration` 为 `"function"`,`registration instanceof Promise` 为 false,因此按这些检查分支或把函数视为回调的代码会受影响;Vitest 的 `.rejects` 会调用它,而不是观察拒绝。
|
||||
|
||||
注册表级 `stateOf(session, key): unknown` 已弃用。当前没有任何插件注册该 key 时它返回 `undefined`:所属插件未组合、尚未执行到注册,或已释放最后一次注册。`SessionProjectionStateMap` 已移除;宿主状态类型保留在各自的 `ProjectionDefinition<K, S>` 中,并从 `stateSchema` 推导。最后一次注册释放后,该投影单元不再参与快照、检查点和实时通知,但保留的句柄仍可按需折叠 Session 事件。[运行时兼容说明](../../../../packages/session/session-projection/README.zh.md#deprecated-plugin-compatibility)详述这些已弃用调用。
|
||||
|
||||
`@deepseek-ai/dsh-agent` 与 `@deepseek-ai/dsh-subagent` 依赖 `sessionProjections`。AgentRegistry 持有轮次和步骤状态,并提供 `ctx.agents.turnBoundaryOf(session)`;`@deepseek-ai/dsh-agent-loop` 不再导出 `turnBoundaryProjectionDefinition`。包括 Claude Code mods 桥接在内的轮次状态消费方依赖 `agents`。预设与上下文压力分别通过 `ctx.agentPresets.presetForSession(session)` 和 `ctx.tokenMeter.contextPressure(session)` 读取。`@deepseek-ai/dsh-api-session-controller` 移除了 `installModelSelectionProjection`。
|
||||
|
||||
## 迁移
|
||||
|
||||
1. 在自定义组合中,先挂载 `SessionProjectionRegistry`,再挂载 `AgentRegistry`、`SubagentRuntime` 及其他投影所有者。组合中的插件依赖 `agents` 时,加入 `@deepseek-ai/dsh-agent`。
|
||||
2. 对插件自己的定义,在异步 `apply()` 或 `[Service.init]()` 中等待 `ctx.sessionProjections.register(definition)`,并在提供依赖操作前保存句柄。删除 `SessionProjectionStateMap` 的声明合并,将状态类型作为 `ProjectionDefinition<K, S>` 的第二个类型参数。保留 `SessionProjectionMap` 中的客户端值声明。
|
||||
3. 将 `registry.stateOf(session, key)` 替换为所属服务的方法(例如 `ctx.agents.turnBoundaryOf(session)`),或所有者内部的 `handle.stateOf(session)`;替换之前须处理其 `undefined` 结果。将对注册结果的调用替换为等待 `handle.dispose()`;fiber 释放仍会自动释放注册。
|
||||
4. 需要原生 Promise 时传入 `Promise.resolve(registration)`,包括在 Vitest 中写 `await expect(Promise.resolve(registration)).rejects.toThrow(...)`。将对结果的 `typeof` 或 `instanceof Promise` 检查改为直接等待。
|
||||
5. 将 `installModelSelectionProjection(ctx)` 替换为 `await ctx.sessionProjections.register(modelSelectionProjection)`,从 `@deepseek-ai/dsh-api-session-controller/src/model-selection-projection.ts` 导入该定义。
|
||||
6. 对自定义插件执行类型检查,再验证激活、Session 状态读取、注册被拒绝以及 owner 释放。
|
||||
@@ -1,16 +0,0 @@
|
||||
# Bilingual-pair consistency record for guide.md (docs/i18n/README.md): per heading
|
||||
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
||||
# After editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/upgrade-guide/v0.2.1-rc.2/session-projection-registration/guide.md
|
||||
/:
|
||||
en: 1a25bfb7e416f46a
|
||||
zh: ef6c593731b3060d
|
||||
/session-projection-registration-returns-a-callable-thenable:
|
||||
en: b6dc85dc2b48b22d
|
||||
zh: e35f32e364693189
|
||||
/session-projection-registration-returns-a-callable-thenable/change:
|
||||
en: e577472dc17a0152
|
||||
zh: 167312dd4ab3b2b2
|
||||
/session-projection-registration-returns-a-callable-thenable/migration:
|
||||
en: 324f8178180519c8
|
||||
zh: e38782e76b4dc244
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "Session projection registration returns a callable thenable instead of a native Promise."
|
||||
---
|
||||
|
||||
# Session projection registration returns a callable thenable
|
||||
|
||||
English | [中文](guide.zh.md)
|
||||
|
||||
## Change
|
||||
|
||||
`@deepseek-ai/dsh-session-projection` keeps the declared `register(definition): Promise<ProjectionHandle<S>>` API, but its runtime return value changes from a native Promise to a callable thenable. `await`, `.then()`, `.catch()`, and `.finally()` still deliver the same retained handle. `typeof registration` is now `"function"`, and `registration instanceof Promise` is false. Code that branches on those checks or treats functions as callbacks is affected; Vitest's `.rejects` can call the disposer instead of observing the registration error.
|
||||
|
||||
The callable value supports deprecated synchronous disposer usage by compiled plugins. Registry-level `stateOf(session, key): unknown` is also available again as a deprecated runtime API; new code reads through retained handles. Async return/yield assimilates it into the handle, which is not a valid Cordis effect. See [runtime compatibility](../../../../packages/session/session-projection/README.md#deprecated-plugin-compatibility) for warning timing and ignored-error handling.
|
||||
|
||||
## Migration
|
||||
|
||||
1. Keep awaiting `ctx.sessionProjections.register(definition)` and use the returned handle's `stateOf(session)` and `dispose()` methods. In async plugins or effects, await registration and return `void`; the owning fiber releases the registration automatically.
|
||||
2. Where a native Promise is required, pass `Promise.resolve(registration)`. Replace checks on the registration's `typeof` or `instanceof Promise` with ordinary awaiting. In Vitest, write `await expect(Promise.resolve(registration)).rejects.toThrow(...)`.
|
||||
3. Run plugin initialization and disposal tests, including a rejected registration. Confirm that the expected registration error is observed and released registrations no longer participate in snapshots.
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "Session 投影注册返回可调用的 thenable,取代原生 Promise。"
|
||||
---
|
||||
|
||||
# Session 投影注册返回可调用的 thenable
|
||||
|
||||
[English](guide.md) | 中文
|
||||
|
||||
## 变更
|
||||
|
||||
`@deepseek-ai/dsh-session-projection` 保持声明的 `register(definition): Promise<ProjectionHandle<S>>` API,但运行时返回值从原生 Promise 变为可调用的 thenable。`await`、`.then()`、`.catch()` 和 `.finally()` 仍交付相同的保留句柄。`typeof registration` 现在为 `"function"`,`registration instanceof Promise` 为 false。按这些检查分支或把函数视为回调的代码会受影响;Vitest 的 `.rejects` 可能调用 disposer,而不是观察注册错误。
|
||||
|
||||
可调用值支持已编译插件中已弃用的同步 disposer 用法。registry 级 `stateOf(session, key): unknown` 也恢复为已弃用的运行时 API;新代码通过保留句柄读取。异步 return/yield 会将其吸收为句柄,而句柄不是有效的 Cordis effect。警告时机和忽略错误的处理方式见[运行时兼容说明](../../../../packages/session/session-projection/README.zh.md#deprecated-plugin-compatibility)。
|
||||
|
||||
## 迁移
|
||||
|
||||
1. 继续等待 `ctx.sessionProjections.register(definition)`,并使用返回句柄的 `stateOf(session)` 和 `dispose()` 方法。在异步插件或 effect 中等待注册并返回 `void`;所属 fiber 会自动释放注册。
|
||||
2. 需要原生 Promise 时传入 `Promise.resolve(registration)`。将对注册值的 `typeof` 或 `instanceof Promise` 检查改为正常等待。在 Vitest 中使用 `await expect(Promise.resolve(registration)).rejects.toThrow(...)`。
|
||||
3. 运行插件初始化和释放测试,包括注册拒绝用例。确认能观察到预期注册错误,且已释放的注册不再参与快照。
|
||||
@@ -68,7 +68,7 @@ A domain that owns projected state declares `sessionProjections` as a Cordis ser
|
||||
<a id="deprecated-plugin-compatibility"></a>
|
||||
### Deprecated plugin compatibility
|
||||
|
||||
`register(definition)` keeps its public return type `Promise<ProjectionHandle<S>>`, but the runtime value is a callable thenable, not a native `Promise` (`typeof` is `"function"`; `instanceof Promise` is false). Awaiting it delivers the retained handle; calling it releases the registration through the original Cordis effect disposer. Calling the return value is deprecated; use `handle.dispose()` in new code. Use `Promise.resolve(registration)` when an API requires a native Promise or treats functions as callbacks, including Vitest Promise assertions. See the [upgrade guide](../../../docs/upgrade-guide/v0.2.1-rc.2/session-projection-registration/guide.md).
|
||||
`register(definition)` keeps its public return type `Promise<ProjectionHandle<S>>`, but the runtime value is a callable thenable, not a native `Promise` (`typeof` is `"function"`; `instanceof Promise` is false). Awaiting it delivers the retained handle; calling it releases the registration through the original Cordis effect disposer. Calling the return value is deprecated; use `handle.dispose()` in new code. Use `Promise.resolve(registration)` when an API requires a native Promise or treats functions as callbacks, including Vitest Promise assertions. See the [upgrade guide](../../../docs/upgrade-guide/v0.2.1-rc.2/session-projection-handles/guide.md).
|
||||
|
||||
Legacy synchronous `return register(...)`, `ctx.effect(() => register(...))`, and synchronous generator yields retain cleanup ownership. Returning or yielding the registration through an async function or async generator assimilates the thenable into a handle, which Cordis rejects as `Invalid effect`. Async plugins and effects await registration and return `void`; the owning fiber releases the registration automatically.
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ const { asOfSeq, values } = ctx.sessionProjections.snapshot(session)
|
||||
<a id="deprecated-plugin-compatibility"></a>
|
||||
### 已弃用的插件兼容接口
|
||||
|
||||
`register(definition)` 的公开返回类型保持为 `Promise<ProjectionHandle<S>>`,但运行时值是可调用的 thenable,并非原生 `Promise`(`typeof` 为 `"function"`,`instanceof Promise` 为 false)。等待它会得到保留的句柄,调用它则通过原有 Cordis effect disposer 释放注册。调用返回值的用法已弃用;新代码使用 `handle.dispose()`。API 要求原生 Promise 或把函数视为回调时,包括 Vitest 的 Promise 断言,使用 `Promise.resolve(registration)`。参见[升级指南](../../../docs/upgrade-guide/v0.2.1-rc.2/session-projection-registration/guide.zh.md)。
|
||||
`register(definition)` 的公开返回类型保持为 `Promise<ProjectionHandle<S>>`,但运行时值是可调用的 thenable,并非原生 `Promise`(`typeof` 为 `"function"`,`instanceof Promise` 为 false)。等待它会得到保留的句柄,调用它则通过原有 Cordis effect disposer 释放注册。调用返回值的用法已弃用;新代码使用 `handle.dispose()`。API 要求原生 Promise 或把函数视为回调时,包括 Vitest 的 Promise 断言,使用 `Promise.resolve(registration)`。参见[升级指南](../../../docs/upgrade-guide/v0.2.1-rc.2/session-projection-handles/guide.zh.md)。
|
||||
|
||||
旧的同步 `return register(...)`、`ctx.effect(() => register(...))` 和同步生成器 yield 保留原有清理所有权。通过异步函数返回或异步生成器 yield 注册值时,thenable 会被吸收为句柄,Cordis 会以 `Invalid effect` 拒绝它。异步插件和 effect 等待注册完成后返回 `void`;所属 fiber 会自动释放注册。
|
||||
|
||||
|
||||
Reference in new issue
Block a user