会话快照标准 payload。
统一 CMDC.Checkpoint.save/3 的输出与 load/2 的输入。
含 @schema_version 便于未来 schema 演进时向前兼容。
不可序列化字段策略
Agent.State 中以下字段在 save/2 时会被自动剥离,
并在 resume_session!/2 时由 plugin :session_start hook 重建:
这一策略避免序列化死引用、同时保证 plugin 状态可以靠
:session_start 重新初始化。Snapshot 会保留这些字段名加 :_stripped 标记
以便恢复时知道哪些 plugin 需要重置。
Provider Registry 协议兼容(v0.5.1+)
state.model 字段可能含 "registry:profile_name:provider:model_id" 前缀
(CMDC.Provider.Registry 命名 Provider Profile 协议)。
- Snapshot 序列化时原样保留
"registry:..."字符串(不解析) CMDC.resume_session!/2会重新触发CMDC.Provider.Registry.lookup/1- 若 profile 已被 unregister 或迁移到其它节点,resume 返
{:error, {:registry_profile_missing, name}}—— 集成方可 re-register 后重试
典型用例:Studio 多租户重启后,集成方 init 时灌入持久层所有 profile, 即可平滑 resume 历史会话;若集成方误删 profile,resume 失败给出明确恢复路径。
Examples
iex> snap = Snapshot.new(session_id: "sess-1", state: %{messages: []})
iex> snap.schema_version
1
Summary
Functions
构建新的 Snapshot,自动生成 checkpoint_id + saved_at,
并剥离不可序列化字段。
对 snapshot 的 :state 字段应用一个 redact 函数,返回新的 Snapshot。
返回 schema 版本号常量。
Types
可被序列化为 snapshot 的负载(通常是 Agent.State 或 map)。
@type t() :: %CMDC.Checkpoint.Snapshot{ checkpoint_id: String.t(), label: String.t() | nil, metadata: map(), saved_at: DateTime.t(), schema_version: pos_integer(), session_id: String.t(), state: serializable(), stripped_fields: [atom()] }
Functions
构建新的 Snapshot,自动生成 checkpoint_id + saved_at,
并剥离不可序列化字段。
选项
:session_id— 必填:state— 必填(Agent.State 或任意 map):label— 可选标签:metadata— 用户附加 map(默认%{})
@spec redact(t(), (serializable() -> serializable())) :: t()
对 snapshot 的 :state 字段应用一个 redact 函数,返回新的 Snapshot。
常见用途:backend 在 save/3 前去除敏感字段(API key / token / PII),
让 CMDC 不强制 encryption_at_rest,但给集成方留官方 hook 接 Cloak / KMS。
行为
redact_fn接受当前snapshot.state(map 或 struct)返回处理后的 map / struct- 其他字段(checkpoint_id / session_id / saved_at / stripped_fields / metadata / label)保持不变
- 不变更
schema_version
示例
# 去掉所有以 :api_ / :token 开头的 key
Snapshot.redact(snap, fn state ->
Enum.reject(state, fn {k, _v} ->
ks = to_string(k)
String.starts_with?(ks, "api_") or String.contains?(ks, "token")
end)
|> Map.new()
end)
# 接 Cloak 加密敏感字段
Snapshot.redact(snap, &MyApp.Vault.encrypt_sensitive/1)
@spec schema_version() :: pos_integer()
返回 schema 版本号常量。