feat(session): bound persistence write batching

This commit is contained in:
Tianyi Cui
2026-08-08 15:43:52 +08:00
parent 7ab20890e6
commit 924c954469
52 changed files with 763 additions and 126 deletions

View File

@@ -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 packages/session-persistence/session-checkpoint-policy/README.md
README.md: 57be9e78236775c39971c925f4972398c0b20a97
README.zh.md: 66508382783c36c41be65afc758398d406c3a58f
README.md: 01ed3c694967b1a86245d01b9d9f7eecd1193348
README.zh.md: e2c197c0cc1d942a045c1ea22c1fb257f6e4059d

View File

@@ -16,7 +16,7 @@ This zero-config function plugin consumes `ctx.sessions`, `ctx.llm`, `ctx.tools`
name: '@deepseek-ai/dsh-session-checkpoint-policy'
```
Persistence and checkpoint scheduling are intentionally separate Cordis plugins. A persistence backend eagerly writes `session/event` appends and makes each requested `session/flush` an observation barrier; this policy chooses the request, tool-dispatch, and next-step barriers. Loading a backend without this policy is valid, but a crash may lose the latest eagerly buffered events. First-party persisted apps and runtimes mount both plugins explicitly; a specialized deployment may deliberately omit or replace the policy.
Persistence and checkpoint scheduling are intentionally separate Cordis plugins. A persistence backend starts bounded background batches for `session/event` appends and makes each requested `session/flush` an immediate quiescence barrier; this policy chooses the request, tool-dispatch, and next-step barriers. Loading a backend without this policy is valid, but a crash may lose events still inside the configured batching window or an outstanding write. First-party persisted apps and runtimes mount both plugins explicitly; a specialized deployment may deliberately omit or replace the policy.
The policy wraps `llm/stream` lazily, so the downstream stream is not constructed until the live session's buffered request events are durable. It wraps `tools/execute` after pre-execute policy and guards; a top-level tool body runs only after its recorded call is durable. If cancellation lands while that flush is pending, the wrapper returns the canonical `ABORTED_BEFORE_DISPATCH` result without entering the tool body. Nested tool dispatches reuse the outer model-visible call's checkpoint. `agent/pre-step` persists the preceding response/result batch before request derivation.
@@ -41,5 +41,5 @@ The repair result is appended after the reusable prefix, so it does not invalida
## Known Limitations and Deferred Work
- The policy durably records execution intent, not generic exactly-once effects. Side-effecting tools should forward `exec.callId` as an idempotency key when their provider supports one.
- Streaming `assistant/chunk` events have no per-chunk checkpoint. They reach storage with the next semantic checkpoint, so a hard crash may lose the current partial response.
- Streaming `assistant/chunk` events have no per-chunk checkpoint. Bounded background batches normally persist them before the next semantic checkpoint, but a hard crash may lose the current in-memory batch or outstanding write.
- A persisted call without a result cannot prove whether its external effect completed. Recovery therefore records an unknown outcome instead of retrying automatically.

View File

@@ -16,7 +16,7 @@
name: '@deepseek-ai/dsh-session-checkpoint-policy'
```
持久化与检查点调度刻意拆分为独立 Cordis 插件。持久化后端会主动写入追加的 `session/event`,并把每个已请求 `session/flush` 变成观测屏障;该策略选择请求、工具分派和下一步骤屏障。不带此策略加载后端是有效的,但崩溃可能丢失最新的已缓冲事件。第一方持久化应用和运行时显式挂载两个插件;专用部署可以刻意省略或替换策略。
持久化与检查点调度刻意拆分为独立 Cordis 插件。持久化后端会为追加的 `session/event` 启动有界后台批次,并把每个已请求的 `session/flush` 变成即时完全停稳屏障;该策略选择请求、工具分派和下一步骤屏障。不带此策略加载后端是有效的,但崩溃可能丢失仍位于已配置批处理窗口内的事件,或尚未完成的写入。第一方持久化应用和运行时显式挂载两个插件;专用部署可以刻意省略或替换策略。
策略延迟包装 `llm/stream`,因此下游流只会在活动会话中缓冲的请求事件已持久化后构造。它在预执行策略和防护机制之后包装 `tools/execute`;只有在已记录调用已持久化后,顶层工具正文才会运行。如果取消在 flush 等待期间到达,包装层会返回规范的 `ABORTED_BEFORE_DISPATCH` 结果,不进入工具正文。嵌套工具分派重用外层模型可见调用的检查点。`agent/pre-step` 在派生请求前持久化前一响应/结果批次。
@@ -41,5 +41,5 @@
## 已知限制与暂缓事项
- 该策略以持久方式记录执行意图,而非为通用副作用提供恰好一次保证。当提供方支持时,有副作用的工具应将 `exec.callId` 作为幂等键转发。
- 流式 `assistant/chunk` 事件没有每分片检查点。它们在下一个语义检查点到达存储,因此硬崩溃可能丢失当前部分响应。
- 流式 `assistant/chunk` 事件没有逐分片检查点。有界后台批次通常会在下一个语义检查点之前将其持久化,但硬崩溃可能丢失当前内存批次或尚未完成的写入。
- 已持久化的调用没有结果时,无法证明其外部副作用是否完成。因此,恢复会记录未知结果,而不是自动重试。