本章只列用户实际会被坑的兼容边界——不是新增的可选字段,是写错代码会报错或行为变化的位置。 新增字段、新增可选参数、文档改写等"无影响"的变化请看 Changelog


v0.4.x → v0.5.0(当前版本)

全加性升级,零代码 / 零行为破坏。所有 v0.4.x 代码不动即可跑通。

新增公共 API(向后兼容,按需采用)

  • CMDC.Options.hibernate_after_ms — 进程空闲超时自动 hibernate,单进程 heap 8KB → 1.5KB
  • CMDC.checkpoint!/2 + CMDC.resume_session!/2 — facade API 把运行中 session 抓快照 + 跨进程恢复
  • CMDC.Checkpoint.Snapshot.redact/2 — backend 写前预处理 hook(接 Cloak / KMS)
  • CMDC.Plugin.Builtin.AutoCheckpoint — 内置 Plugin,按 turn / on_tools / on_events 自动存档 + 自动 GC
  • CMDC.AsyncTaskSupervisor — application supervision tree 新增,供 plugin 异步任务用
  • CMDC.Telemetry 从 6 事件扩到 16 事件(10 个新事件覆盖 Plugin Pipeline / Compactor / Checkpoint / SubAgent / Hibernate)

长会话场景推荐配置

如果你的 Agent 是常驻多租户场景(>100 idle 会话同节点):

{:ok, session} = CMDC.create_agent(
  model: "anthropic:claude-sonnet-4-5",
  hibernate_after_ms: 60_000,                              # 新增
  plugins: [
    {CMDC.Plugin.Builtin.AutoCheckpoint,                    # 新增
     backend: CMDCMemoryPg.CheckpointBackend,
     every_n_turns: 10,
     on_events: [:approval_required, :session_end]}
  ]
)

持久化场景新增子库 cmdc_memory_pg 0.1.0

defp deps do
  [
    {:cmdc, "~> 0.5"},
    {:cmdc_memory_pg, "~> 0.1"}        # 可选 PG backend
  ]
end

# config/runtime.exs
config :cmdc, :checkpoint_backend, CMDCMemoryPg.CheckpointBackend

提供 Checkpoint + EpisodicMemory 持久化 PG 后端,与主库 CMDC.Checkpoint.Backend / CMDC.Memory behaviour 完全对接。

测试场景新增子库 cmdc_test 0.1.0

defp deps do
  [
    {:cmdc, "~> 0.5"},
    {:cmdc_test, "~> 0.1", only: :test}
  ]
end

提供 4 大测试 helpers:

  • MockProvider Builder API
  • Plugin.run_hook/3 单元测 + Plugin.Spy 集成路径 inject anonymous handler
  • EventCapture + Assertions.{assert_event_emitted, refute_event_emitted, assert_event_count}

无升级动作。直接改 mix.exs 依赖到 ~> 0.5 即可。


v0.4.0 → v0.4.1

纯文档 patch,零代码 / 零行为变更。

  • 主库 mix.exs extras 重组、内核模块加 @moduledoc false、清理 hex doc 内部字眼
  • 1219 tests + 21 doctests 不变

无升级动作


v0.3.x → v0.4.0

新增公共模块(向后兼容,纯增量)

  • CMDC.Backend behaviour + Backend.{State, Filesystem, Composite} 三个内置实现
  • CMDC.Checkpoint + Checkpoint.Backend behaviour + ETS / DETS 两个内置 backend
  • CMDC.Telemetry 标准 :telemetry 事件契约
  • 4 个新内置 Plugin:LargeResultOffload / ContentPolicy / EpisodicMemory / MemoryFlush

旧代码不需要改任何东西就能拿到这些能力——按需挂载即可。

Plugin Pipeline 新 action :replace_tool_result

:after_tool hook 接受。让 plugin 在 raw_result 写进 message history 之前替换它(LargeResultOffload 用这个 action 把 200KB 结果换成 preview)。

无破坏性影响——旧 plugin 完全不受影响。

HumanApproval:approve_always 第三态

# v0.3:approve(session, id) 只放当次
CMDC.approve(session, id)

# v0.4:可加 :kind 走 session-scoped 永久白名单
CMDC.approve(session, id, kind: :approve_always)

旧代码 CMDC.approve(session, id) 默认 :approve_once,行为不变。

Sandbox virtual_mode(推荐生产开启)

Backend.Filesystem.new/1 支持 :virtual_mode 选项:

# v0.3 行为(默认 false,0 安全保护)
backend = CMDC.Backend.Filesystem.new(root_dir: "/tmp/work")

# v0.4 推荐生产配置
backend = CMDC.Backend.Filesystem.new(
  root_dir: "/tmp/work",
  virtual_mode: true     # 拦 .. / ~ traversal + O_NOFOLLOW symlink 防护
)

virtual_mode: true 会拒绝路径逃逸 root_dir有可能让原本依赖 绝对路径的代码失败。如果你的 Agent 之前依赖访问 root_dir 外的文件 (不推荐),开启前要先改造业务代码。

未来 v0.5 默认值会切换为 true,到时是 breaking change。


v0.2.x → v0.3.0(1 条 breaking change

#1 公共 API 全部改 {:ok, _} | {:error, _} 返回(breaking

v0.2 的 CMDC.monitor / abort / attach_tool / detach_tool / status / messages / agent_pid / steer / stop / switch_model / replace_tools / attach_tools / detach_tools 在传非法 session 时会 raise

v0.3 起改为返回 {:error, :invalid_session | :not_alive}

迁移:把所有 CMDC.xxx(session, ...) 改为 with 链或 case 匹配:

# v0.2 写法(v0.3 仍能跑,但只在 session 合法时工作)
CMDC.attach_tool(session, MyTool)

# v0.3 推荐写法
case CMDC.attach_tool(session, MyTool) do
  {:ok, _name} -> :ok
  {:error, :invalid_session} -> handle_dead_session()
  {:error, {:validation_failed, failures}} -> handle_invalid_tool(failures)
end

成功路径的返回值(:ok / map / Message struct 等)保持不变,所以多数业务 代码只需要在最外层套个 case 即可。

abort/2 :reason 接受 string

v0.2 只接受 atom,v0.3 起接受下列 6 个标准 string 自动归一为 atom,防止 前端通过 JSON 反序列化注入任意 atom 进 BEAM atom table:

"user_cancelled" / "timeout" / "shutdown" /
"budget_exceeded" / "permission_denied" / "provider_error"

其他 string 一律归并为 :unknownLogger.warning。Atom 入参保持原样 透传。

pending_toolsstarted_at_ms 字段

CMDC.status/1 返回的 pending_tools 列表每项新增 started_at_ms 字段 (System.system_time(:millisecond))。如果你之前对 pendingtools 做了 strict map match `%{name: , callid: , args: _}`,会失败:

# v0.2 strict match
%{name: name, call_id: id, args: args} = tool

# v0.3 兼容写法
%{name: name, call_id: id, args: args, started_at_ms: _} = tool
# 或更稳妥:
name = tool.name

Plugin emit 自动注入 user_data

emit 出来的 {:plugin_event, name, payload} 当 payload 是 map 时,Pipeline 会自动 merge state.user_data:user_data 字段。如果你的订阅方做了 strict map match 不期待 :user_data,要么改 match,要么在 plugin 给 payload 加 :_no_user_data opt out。

:after_turn 新 hook

新增 {:after_turn, payload} Plugin hook,每 turn 回 idle 前触发(finish

  • abort 双路径)。比 :session_end 触发更频繁,新 plugin 推荐用它写 审计 / 长期记忆 / 计费等。

旧 plugin 不受影响。

attach_tools / detach_tools / replace_tools 批量原子 API

新增三个批量 API。dry-run + 全回滚语义:任一失败全部不动。单次的 attach_tool/2 / detach_tool/2 行为完全不变,可继续用。

EventBus replay 加 :types 白名单

subscribe/2:types 选项:

# v0.3 起:只 replay stream / agent_end 类事件
{:ok, _} = CMDC.subscribe(session, since: 100, types: [:message_delta, :agent_end])

:since 一直存在;:types 是新增可选项。


v0.1.x → v0.2.0

{:agent_end, messages, token_usage} 第三参数改 struct

v0.1.x 的 token_usage 是 plain map(%{prompt_tokens, completion_tokens, ...}), v0.2 起统一为 %CMDC.TokenUsage{} struct:

# v0.1.x 兼容写法
%{total_tokens: tt} = usage

# v0.2 推荐写法(也兼容 v0.1 字段名)
%CMDC.TokenUsage{total_tokens: tt, cost_usd: cost} = usage

字段名保留 prompt_tokens / completion_tokens / total_tokens(OpenAI 行业 事实标准),同时归一化 Anthropic 风格的 input_tokens / output_tokens

Steering 软中断(新功能)

新增 CMDC.steer/2 公开 API + 3 个新事件 :steering_received / :steering_applied / :tool_skipped_for_steering

SubAgent prompt_mode 默认改 :task

v0.1 子代理用完整 BasePrompt(同主 Agent)。v0.2 起 SubAgent 默认 prompt_mode: :task(精简),节省 30-50% system prompt token。

如果你的子代理依赖完整 BasePrompt 行为:

%CMDC.SubAgent{
  name: "...",
  prompt_mode: :full  # 显式指定回 v0.1 行为
}

MemoryFlush Plugin(新功能)

新增 CMDC.Plugin.Builtin.MemoryFlush,在压缩前把关键事实持久化到 MEMORY.md,下次会话由 MemoryLoader 自动加载回 system prompt——解决 长会话失忆问题。

Ring Buffer + replay(新功能)

Options.event_buffer_size > 0 启用 per-session 事件 ring buffer, subscribe(session, since: idx) 重连补帧。默认 0 = 关闭,零内存开销。


完整变更摘要

各版本完整 changelog 见仓库 CHANGELOG.md