Skip to main content

CHANGELOG.md

# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.3.0] - 2026-05-16

**Minor release** — 来自 **Hive 团队 RFC v2 实战反馈**的 13 条 API 升级 + A2A 协议
Task 端点 + Phase 11 多子库联动。所有改动**有 1 条公共 API breaking change**(#B21),
其余对 v0.2.x 完全向后兼容。

### Highlights(v0.2.x → v0.3.0)

- 🔍 **Tool 耗时监控开箱即用**`pending_tools[].started_at_ms` + 新事件
  `:tool_execution_metrics`,无需自己埋点
- 🪝 **新 Plugin hook `:after_turn`** — Agent 回 idle 前结构化 payload,长期记忆闭环
  延迟从"下一 session"降到"立刻可用"
- 🔄 **Provider 容灾平滑切换**`switch_model/3` + 4 元 Plugin action 同步切
  `provider_opts`,Anthropic ↔ OpenAI 自建网关零中断
- 📦 **批量原子工具管理**`attach_tools/2 / detach_tools/2 / replace_tools/2`,
  MCP Server 启停一键搞定
- 🛡️ **公共 API 不再 raise/exit** — 所有 facade 在 invalid session / dead pid 时返回
  `{:error, :invalid_session|:not_alive}`,集成方告别 `try/rescue/catch :exit`
- 📡 **A2A 协议 Task 端点**`POST /v1/a2a/tasks/send` 同步 + `/tasks/sendSubscribe`
  流式 SSE(cmdc_gateway 0.3.0)
- 🚧 **Gateway Guardrails** — Input/Output filter Plug,黑名单关键字 / 超长 prompt
  在 HTTP 边界拦截
- 📚 **完整 Plugin 13×8 矩阵文档** + 友好 Options 校验错误

### ⚠️ Breaking Changes(v0.2.x → v0.3.0)

#### #B21 公共 API 不再 raise/exit

所有 `CMDC.*` facade(含 `attach_tool / detach_tool / status / prompt / abort /
approve / reject / monitor / messages / agent_pid / steer / stop / switch_model /
attach_tools / detach_tools / replace_tools`)在传入 invalid session_id / 已死
pid / 非 pid 非 string 时,从 `raise ArgumentError` / `exit({:invalid_session, _})`
改为返回 `{:error, :invalid_session}``{:error, :not_alive}`
**成功路径返回值保持不变**`:ok` / map / `%CMDC.Message{}` 等)。

**Migration**
```elixir
# v0.2.x(继续工作,无需改动)
:ok = CMDC.attach_tool(session, MyTool)
%{state: :idle} = CMDC.status(session)

# v0.2.x 在 invalid session 时 raise / exit,下面这种 try/rescue 模式现在可以删
# 旧代码:
try do
  CMDC.monitor(session)
rescue
  _ -> :ignore
catch
  :exit, _ -> :ignore
end

# v0.3 新写法:直接拿 tuple,不再需要 catch
case CMDC.monitor(session) do
  {:error, _} = err -> :ignore
  ref when is_reference(ref) -> handle(ref)
end

# 旧 `:ok = CMDC.attach_tool(invalid_sid, T)` 模式在 invalid session 下会 MatchError,
# 但这本来就是程序错误(传错 session_id),新行为更可控、可观察。
```

### Added — Phase 11G · Hive RFC v2

来自 Hive 团队 v0.2.1 实战反馈的 `cmdc-rfc-v2.md`**13 条全收**(A4 + B4 + C4 + D2;
#C25 ring buffer 动态扩容延 v0.4)。

#### A 级(必改 — Hive 有旁路代码可立刻清理)

- **`pending_tools[].started_at_ms` + `:tool_execution_metrics` 事件**(RFC #A15)
  - `CMDC.status/1` 返回的 `pending_tools[]` 每项新增 `:started_at_ms` 字段
  - 新事件 `{:tool_execution_metrics, name, call_id, meta}`,紧随
    `:tool_execution_start``:tool_execution_end` 各发一次:
    - start 时:`meta = %{started_at_ms: integer()}`
    - end 时:`meta = %{started_at_ms, ended_at_ms, duration_ms}`
  - 现有 `:tool_execution_start` / `:tool_execution_end` 4 元位置参数保持不变
  - 适合做 tool 耗时 P99 监控 / 慢工具告警 / 自动 fallback
- **`:after_turn` Plugin hook**(RFC #A16)
  - 新增 13 个 Plugin event 中的第 13 个,触发时机:Agent 即将回 idle 前
    (finish + 所有 abort 路径)
  - payload 含 `outcome / abort_reason / messages_diff / token_usage_diff /
    duration_ms / started_at_ms / ended_at_ms`
  -`:session_end` 区别清晰:`:session_end` 保持现状(无 payload,向后兼容
    EventLogger 等老 Plugin);`:after_turn` 带结构化 payload
- **`switch_model` 4 元组 + `:provider_opts`**(RFC #A17)
  - `CMDC.switch_model/3` 新增 `:provider_opts` 选项
  - Plugin Action 4 元组形态 `{:switch_model, model, state, provider_opts: [...]}`
  - `{:model_switched, %{from, to, provider_opts_changed?}}` 事件 payload 加新字段

#### B 级(强烈建议)

- **`:plugin_event` 自动注入 `user_data`**(RFC #B18)
  - `state.user_data` 非空时,emit 的 `{:plugin_event, name, payload}` 当 payload
    是 map 时自动 merge `:user_data` 字段
  - Plugin 可在 payload 加 `:_no_user_data` 键 opt-out(broadcast 前自动 pop)
- **`:agent_resumed` trigger 扩充**(RFC #B19)
  - trigger 新增 `:user_respond / :steering`(除了原有的 `:tool_approved /
    :tool_rejected / :tool_approval_timeout`  - `CMDC.user_respond/3` 紧随 `:user_responded` 后 emit
    `{:agent_resumed, %{trigger: :user_respond, ref}}`
  - `inject_steering` 完毕后 emit `{:agent_resumed, %{trigger: :steering, refs, count}}`
- **批量原子工具管理**(RFC #B20)
  - `CMDC.attach_tools/2` — 批量挂载,任何一个失败全回滚
  - `CMDC.detach_tools/2` — 批量卸载
  - `CMDC.replace_tools/2` — 替换整张工具表,自动 diff
  - 新事件 `{:tools_updated, %{attached, detached}}` 批量操作汇总
  - 单个事件 `:tool_attached` / `:tool_detached` 与 v0.2 一致
- **公共 API 返回 tuple**(RFC #B21)— **见上方 Breaking Changes**

#### C 级(锦上添花)

- **EventBus replay 按 type 过滤**(RFC #C22)
  - `CMDC.EventBus.subscribe(sid, since: idx, types: [:agent_end, :stream_chunk])`
  - 仅影响 replay 阶段,实时订阅不过滤(避免漏事件)
- **`status/1` 累计统计字段**(RFC #C23)
  - 新增 `:turns_count`(与 `:turns` 等同,向后兼容别名)
  - 新增 `:messages_count` — 当前 messages 列表长度
  - 新增 `:active_since_ms` — Agent 进程启动时间戳
- **`abort/2` reason 接受 string + 白名单归一化**(RFC #C24)
  - 6 个标准 reason:`:user_cancelled / :timeout / :shutdown / :budget_exceeded /
    :permission_denied / :provider_error`
  - 对应 string 自动转 atom;不在白名单的 string 归并为 `:unknown` + Logger.warning
    (防止前端 JSON 注入任意 atom)
  - Atom 入参原样透传(向后兼容)
- **MemoryFlush `:extract_fn` 3 元签名**(RFC #C26)
  - 新签名:`extract_fn.(messages, ctx, opts)`,让提取器拿到 `ctx.user_data`
  - 老 2 元签名 `extract_fn.(messages, opts)` 自动检测兼容
  - 典型场景:按 `user_data.tier` 路由不同 LLM 做事实提取

#### D 级(文档与 DX)

- **完整 Plugin Hook × Action 矩阵**(RFC #D27)
  - `CMDC.Plugin` moduledoc 含 13 hooks × 8 actions 完整 ✅/❌ 表
  - 每 action 的累积/覆盖/短路语义详解
  - 4 种 `:emit` 形态对照
  - 4 元 `:switch_model` action 说明
- **`Options.new!` 友好 model 校验错误**(RFC #D28)
  - `Options.new!(model: 42)` 报错 message 含 valid providers + 5 个 example

### Added — Phase 11C · cmdc_gateway 0.3 A2A 协议

> 详见 `cmdc_gateway/CHANGELOG.md` 0.3.0 段。

- `POST /v1/a2a/tasks/send` — JSON-RPC 2.0 Task 协议(同步)
- `POST /v1/a2a/tasks/sendSubscribe` — SSE 流式 Task 进度
- `CMDCGateway.Plugs.Guardrails` — Input filter Plug(denylist keywords + regex +
  max_prompt_length),默认空,应用层按需配置
- `cmdc_gateway/examples/a2a/` — Elixir + Node.js + curl 客户端示例(11.14)

### Added — Phase 11E · 工具链 / 文档

- `benchmark/` 目录骨架(11.18)— cmdc_skill_engine / cmdc_orchestrator /
  cmdc_gateway 各一份基线脚本(Benchee),开发期可跑:
  ```
  MIX_ENV=test mix run benchmark/<name>.exs
  ```
- `docs/dev/PLANNING.md` Phase 11 决策日志(11.19)— 含 Phase 11G ↔ ADP 章节
  追溯表(13 条 RFC 对应 ADP 4/5/7/8/10/14/15/18 多章)
- `docs/dev/rfc/` — RFC 模板 + README + EXAMPLE RFC(11.20),后续集成方按
  4 状态流程(DRAFT/IN REVIEW/ACCEPTED/REJECTED)提交

### Tests

- 1136 tests / 21 doctests / 0 failures / 5 skipped(主库)
- 11G 各条带专项集成测试(共 ~65 个新测试)
- cmdc_gateway 113 tests(含 6 个 A2A 端点 + Guardrails 测试)

### Migration Guide

- 大多数代码无需改动 — 成功路径完全向后兼容
- **唯一例外**:依赖 `try/rescue/catch :exit, _` 捕获 invalid session 的代码可以
  删掉了,改用 `case CMDC.api(s) do {:error, _} -> ... ; ok -> ... end`
- 如果想用新能力:
  - 监控 tool 耗时 → 订阅 `:tool_execution_metrics` 或读 `status.pending_tools[].started_at_ms`
  - 长期记忆闭环 → 在 `:after_turn` hook 中处理 `payload.messages_diff`
  - Provider 容灾 → 在 Plugin `:before_request` 返回 `{:switch_model, "openai:...", state, provider_opts: [base_url: ...]}`
  - MCP 批量挂载 → `CMDC.replace_tools(session, new_mcp_tools)`

### 致谢

- Hive 团队(@hive-platform)— 提交 RFC v2 14 条 issue,13 条全收,1 条延 v0.4

## [0.2.1] - 2026-04-25

**Patch release** — 修掉 v0.2.0 的 Reflection iteration-reset bug,并新增 Planning Pattern
与 Producer-Reviewer Reflection 两大 Agentic Design Patterns 能力。所有改动对 v0.2.0 完全
**向后兼容**;老 Plugin / 老 API 零改动即可升级。

### Fixed

- **`CMDC.Plugin.Builtin.Reflection` iteration reset 死循环** — v0.2.0 该插件在多轮评审时
  `iteration` 会被意外重置,导致在某些回合顺序下 Agent 永远不会真正 finish。引入 `phase ::
  :idle | :reviewing | :done` 状态机彻底修复,`:done` 之后 `:before_finish` 不再触发。
- **`CMDC.Plugin` behaviour `describe/0` callback 类型声明** — 放宽到 `String.t() | map()`  消除 `CMDC.Plugin.Builtin.ModelRouter.describe/0` 的 dialyzer callback_type_mismatch 警告。
  老插件返回 String 保持有效。

### Added — Phase 11D · Planning + Reflection(对齐 ADP Ch4+Ch6+Ch7+Ch11)

Agentic Design Patterns 对齐首批能力,基于 O'Reilly《Agentic Design Patterns》一书 Ch4 Reflection、
Ch6 Planning、Ch7 Multi-Agent Collaboration、Ch11 Goal Setting and Monitoring 四章设计。

- **`CMDC.Plan` / `CMDC.Plan.Step`(new)** — 显式 Plan 数据结构,含 `step_started/2``step_completed/3`  `step_failed/3``step_skipped/3``annotate_step/3``approve/1``progress/1``to_markdown/1`  `to_prompt_section/1`。每个 step 有 `:pending | :in_progress | :completed | :failed | :skipped` 状态。
- **`CMDC.Plan` replan API(ADP Ch6 适应性要求)**`replace_steps/2` 整体重规划、`add_step/3` 追加、
  `insert_step/4` 在指定锚点前/后插入、`remove_step/2` 删除。所有修改自动打 `last_replanned_at` 时戳。
- **`CMDC.Agent.State.dynamic_context_sections`(new)** — Agent 状态新增此字段,Plugin 可通过
  `{:emit, {:update_system_context, key, text}, state}` 事件把内容动态注入下一轮 system prompt。
  `SystemPrompt``:full / :task / :minimal` 三种模式都会合并这些动态段落。
- **`CMDC.Context.last_assistant_reply`(new)** — 只读 Context 新增此字段,Plugin / Tool 可直接拿到
  最后一条 AI 回复全文,无需自己翻 `messages`- **`CMDC.Plugin.Builtin.Planning`(new)** — plan-first 规划插件。对较长 prompt 先 `intervene` 要求
  LLM 产出 markdown checklist,`after_response` 解析为 `CMDC.Plan` 并通过 `dynamic_context_sections`
  把 plan 持续注入 system prompt。失败重试(`max_plan_attempts: 2`)兜底,放弃后不阻塞主流程。
  emit `{:plan_generated, %CMDC.Plan{}}`- **`CMDC.Plugin.Builtin.Reflection` 大重构(modified)** — 修掉 v0.2 的 iteration reset 死循环 bug:
  -`phase :: :idle | :reviewing | :done` 状态机,`:done` 之后 `:before_finish` 不再触发,杜绝无限循环。
  - `max_reviews`(原 `max_iterations` 作为兼容别名)。`pass_signal` 支持字符串或 `%Regex{}`  - **`reviewer_subagent: true`** — ADP Ch4+Ch7 推荐的 Producer-Reviewer 分离:启动独立 Reviewer
    SubAgent(`CMDC.Agent.start_link` 新进程),可用 `reviewer_model` 指定不同模型评审主 Agent 输出,
    显著降低同模型自评的认知偏差。SubAgent 失败自动降级为内联自评,永不阻塞主会话。
  - emit `{:reflection_approved, %{critique, iteration}}`- **Agent before_prompt intervene(modified)**`CMDC.Agent``idle` 状态处理 `{:prompt, text}`
  `do_steer/5` 中的 `:passthrough_to_prompt` 分支,现在正确处理 `{:intervene, prompt, state}`
  返回值:把 intervene prompt 作为 user 消息追加,并广播 `{:intervention, prompt}` 事件。

### Changed

- `CMDC.Agent.broadcast_emitted_events/2` 支持 3-tuple emit 事件(被包装成
  `{:plugin_event, name, {a, b}}`),用于 `{:update_system_context, key, text}` 等 Plugin→Agent
  状态同步。
- `CMDC.Agent.State.to_context/1` 自动填充 `last_assistant_reply`
### Tests

- `test/cmdc/plan_test.exs``CMDC.Plan` 全量单测(新加 47 tests, 16 doctests)。
- `test/cmdc/plugin/builtin/planning_test.exs` — Planning 插件 14 tests。
- `test/cmdc/plugin/builtin/reflection_test.exs` — Reflection 18 tests(完整多轮循环、`phase` 状态机、
  regex pass_signal、SubAgent 兜底降级)。
- `test/cmdc/agent/integration_test.exs` — 新增 Planning E2E 2 tests + Reflection SubAgent Reviewer
  E2E 3 tests,含多轮 Producer-Reviewer 循环。
- 全量 **21 doctests + 1063 tests, 0 failures, 5 skipped**(v0.2.0 基线 1060 → v0.2.1 共 1063,
  所有新模块单元测试累计 47 (Plan) + 14 (Planning) + 18 (Reflection) = 79,
  集成测试累计 Planning E2E ×2 + Reflection SubAgent E2E ×3 = 5 条新端到端)。
- `mix dialyzer` passed successfully(v0.2.0 遗留 `model_router.ex` callback 警告一并修复)。

## [0.2.0] - 2026-04-24

This is a major feature release aligning CMDC with the 13 RFC proposals from the
Hive enterprise-agent team (April 2026) **plus** the four Phase 10 items originally
planned for v0.2 (`Steering`, `PromptMode`, `MemoryFlush`, `ModelRouter`).

All additions are **additive and backward-compatible** unless otherwise noted under
"Breaking". Integration code written for v0.1 continues to work with zero changes.

**Stats**: `+17` new features • `991` total tests (0 failures, 5 skipped) • `82.5%`
line coverage (up from 79.2%; four built-in plugins lifted from 0% → 100%) • `0` deprecations.

### Added — Facade API (RFC A1–A4)

- **`CMDC.Options.user_data`** (RFC A1) — opaque business-context map, propagated verbatim
  into `CMDC.Context.user_data`. SubAgent and `Tool.Task` inherit automatically unless
  the subagent explicitly sets its own `user_data`.
- **`CMDC.create_agent(messages: [...])`** (RFC A2) — inject prior history at boot so
  resumed / cloned sessions continue the LLM turn sequence naturally; accepts
  `%CMDC.Message{}` structs or maps.
- **`CMDC.approve/3` and `CMDC.reject/3` with `:auto_resume`** (RFC A3) — approve now
  auto-resumes the turn by default (`auto_resume: true`); reject defaults to
  `auto_resume: false`. Both emit `:agent_resumed` event when they actually restart a
  turn, so UIs can follow without race conditions. Legacy `approve/2` / `reject/2`
  still work (`auto_resume: true / false` defaults).
- **`normalize_session/1` + session-as-string everywhere** (RFC A4) — every public API
  accepts `pid() | String.t()`; `subscribe/1` can target not-yet-started sessions
  (common for UI pre-mount subscribe); `user_respond/3` broadcasts by session id
  without SessionRegistry round-trip.

### Added — Protocol (RFC B5–B7)

- **`%CMDC.TokenUsage{}`** (RFC B5) — typed struct `{input, output, total, cache_read,
  cache_write}`; all token-bearing events (`:after_response`, `:turn_complete`,
  `:agent_finished`) now emit this struct. Legacy map format remains readable.
- **`CMDC.abort/2` options** (RFC B6) — `reason:` (defaults `:user_abort`, embedded in
  `:agent_abort` event), `kill_tools:` (`:running` default / `:all` / `:none`),
  `clear_queue:` (default `true`). Documented 4-state behavior matrix and the
  `100ms within` emit guarantee for `:agent_abort`.
- **Plugin Hook × Action matrix** (RFC B7) — `docs/guides/plugin-matrix.md` with full
  11×7 table plus 5 copy-paste Cookbook scenarios (block tool, rate-limit, audit
  log, cost guard, steering-on-loop).

### Added — Runtime Control (RFC C8–C12)

- **`CMDC.switch_model/2`** (RFC C8) — change the LLM model mid-session; emits
  `:model_switched` with `{from, to, reason, turn, ts}`. Also exposed as a Plugin
  action `{:switch_model, new_model, state}` (used by the upgraded `ModelRouter`).
- **`CMDC.attach_tool/2` / `CMDC.detach_tool/2`** (RFC C9) — runtime toolset mutation.
  Emits `:tool_attached` / `:tool_detached`. If the LLM later calls a detached tool,
  the kernel emits `:tool_call_unknown` (no crash, no hang) and returns a tool_result
  error so the next turn lets the LLM self-correct.
- **EventBus replay buffer + `subscribe(:since)`** (RFC C10) — every session keeps a
  bounded ring of past events (default 500); subscribers can recover missed events on
  reconnect via `CMDC.subscribe(session, since: ts | event_id)`.
- **`CMDC.status/1` extensions** (RFC C11) — now returns
  `pending_tools`, `pending_approvals`, `pending_user_inputs`, `queue_sizes`
  (pending prompts / steerings) so dashboards can reflect the true "what is the
  agent blocked on right now".
- **`CMDC.monitor/1` + structured reason** (RFC C12) — `Process.monitor`-style API
  that returns a structured reason map (`{:normal | :shutdown | :exception |
  :max_turns_exceeded | :provider_timeout | {:plugin_aborted, name, why}}`) instead
  of the raw OTP term. Use `CMDC.demonitor/2` to cancel.

### Added — Event Protocol (RFC D14)

- **Generic `:plugin_event` event** — unified envelope
  `{:plugin_event, %{kind: atom, v: integer, session_id, occurred_at, ...}}` that all
  built-in and third-party plugins use to publish business-level events to EventBus.
  Subscribing to a single event gives the integrator access to every plugin's
  structured output. First producer: `MemoryFlush` (`kind: :memory_flush`).

### Added — Phase 10 (original roadmap)

- **10A. Steering**`CMDC.steer(session, instruction)` injects a mid-run "soft
  interrupt" without aborting. Queued when busy (default `max=3`), applied at the
  next safe point, emits `:steering_applied`. Plugins can gate via new
  `:before_steering` hook.
- **10B. PromptMode** — new `CMDC.Options.prompt_mode` field with 4 values:
  - `:full` (default) — full BasePrompt + identity + tools + Skills + Memory
  - `:task` — compact base for focused subagents (saves ~50% tokens)
  - `:minimal` — tool-name list only, no descriptions (saves ~90%)
  - `:none` — completely delegated to user-provided `system_prompt`

  `SubAgent` defaults to `:task` (SDK-level token savings); `Tool.Task` propagates
  the mode to children; 8-layer SubAgent chain drops from ~7200 to ~2400 tokens.
- **10C. MemoryFlush plugin** — new `CMDC.Plugin.Builtin.MemoryFlush` subscribes
  to the new `:before_compact` event, extracts key facts via configurable
  `extract_fn` (heuristic default, LLM-pluggable), deduplicates with SHA256, and
  appends to `working_dir/MEMORY.md`. Closes the loop with `MemoryLoader` for
  true long-session memory across restarts. Emits both `:memory_flushed`
  (internal) and `:plugin_event` (kind `:memory_flush`, per RFC D14).
- **10D. ModelRouter v2**`Plugin.Builtin.ModelRouter` now uses
  `{:switch_model, ...}` action (no more `[系统]` message pollution) and adds five
  new business-friendly condition families on top of the original three runtime
  conditions:
  - `:token_budget_lt` — remaining budget from `user_data[:token_budget]`
  - `:task_complexity` / `:task_complexity_in``:simple` / `:normal` / `:complex`
  - `:time_of_day_in` — list of UTC-hour ranges (with injectable `now_fn`)
  - `:user_tier` / `:user_tier_in``:free` / `:pro` / `:enterprise` / custom
  - `:user_data, key, value` and `:user_data, key, op, value` (`:eq/:gt/:lt/:gte/:lte`)

  Robustness: all conditions run inside a `rescue` wrapper; `user_data = nil` and
  unknown condition tuples safely degrade to `false`.

### Changed

- `ModelRouter` no longer injects `[系统] 已切换到模型 X` assistant messages; uses
  `{:switch_model, ...}` Plugin action + `:model_switched` event instead. Conversation
  history remains clean.
- `HumanApproval` / HITL flow now emits `:agent_resumed` when `approve(auto_resume: true)`
  actually restarts the turn (was previously silent).
- `CMDC.Agent` emits `:before_compact` event (new plugin hook) before Compactor runs,
  giving plugins a chance to persist facts before summarization.

### Fixed

- `CMDC.subscribe("session-id")` on a not-yet-started session no longer raises
  `ArgumentError`; it now succeeds and delivers events as soon as the session starts
  (RFC A4).
- `Plugin.Pipeline` `{:emit, ...}` action can now emit multiple events in a single
  return (`{:emit, [{name1, payload1}, ...], state}`) and accepts a 3-tuple shortcut
  `{:emit, name, payload, state}`.

### Breaking

- `Plugin.Builtin.ModelRouter` behavior change: existing users who relied on the
  `[系统] 已切换到模型 X` message being injected into context must migrate to subscribe
  `:model_switched` events or consume the new `:switch_model` action's side effects.
  Most users will experience this as a cleaner UX.

### Documentation

- `docs/guides/plugin-matrix.md` — complete 11 hooks × 7 actions matrix + 5 Cookbook
  scenarios (RFC B7).
- `docs/dev/rfc/2026-04-hive-feedback-review.md` — official response to the Hive team,
  documenting every accepted RFC's design decisions and migration paths.
- `llm.txt` / `llms-full.txt` — updated with PromptMode, MemoryFlush, ModelRouter v2,
  `:plugin_event`, `switch_model/2`, `attach_tool/2`, `monitor/1`, `:since` replay,
  and `status/1` extensions.
- `docs/dev/KNOWLEDGE.md` — added sections 5.24 / 5.25 / 5.26 documenting pitfalls
  found during 10B / 10C / 10D implementation (SubAgent token explosion, memory
  flush robustness, ModelRouter current_model state chain).

[0.2.0]: https://github.com/tuplehq/cmdc/releases/tag/v0.2.0

## [0.1.1] - 2026-04-08

### Fixed

- 修复 ex_doc 文档 10 处引用 warning(隐藏函数引用、不存在函数引用、LICENSE 文件缺失)
- LICENSE 文件加入 HexDocs extras
- README 许可证描述和联系方式更正

## [0.1.0] - 2026-04-08

Initial release of CMDC — Elixir Agent Kernel.

### Added

#### Core Infrastructure (L0)
- `CMDC.Options` — typed struct with NimbleOptions schema for AI-friendly agent configuration; all fields with precise `doc:` annotations
- `CMDC.Config` — application-level configuration struct with provider routing (`resolve_provider/2`)
- `CMDC.Context` — runtime execution context passed to Tools and Plugins
- `CMDC.Message` — typed message struct supporting system/user/assistant/tool_result roles; `@derive Jason.Encoder`
- `CMDC.Event` — 22 structured event types covering full agent lifecycle
- `CMDC.EventBus` — Registry-based PubSub; `subscribe/1`, `broadcast/2`, `subscribe_all/0`
- `CMDC.SubAgent` — declarative sub-agent specification struct with `nil`-means-inherit semantics

#### Core Abstractions (L1)
- `CMDC.Plugin` — behaviour with 11 event hooks and 7 action types (continue/intervene/abort/skip/block_tool/replace_tool_args/emit)
- `CMDC.Plugin.Pipeline` — priority-ordered plugin execution with short-circuit support
- `CMDC.Plugin.Registry` — plugin registration with deduplication and priority sorting
- `CMDC.Tool` — behaviour with `name/0`, `description/0`, `parameters/0`, `execute/2`; result type `{:ok, text} | {:error, text} | {:effect, term}`
- `CMDC.Sandbox` — behaviour abstracting file/command execution (8 callbacks); `CMDC.Sandbox.Local` as default OS implementation
- `CMDC.Skill` — SKILL.md discovery, loading, and system prompt injection
- `CMDC.Blueprint` — behaviour for declarative reusable agent configurations; struct pipeline helpers (`add_tools/2`, `add_plugins/2`, etc.)
- `CMDC.Provider` — thin `req_llm` wrapper; `stream/4`, `convert_messages/2`, `convert_tools/1`
- `CMDC.Provider.StreamBridge` — converts `ReqLLM.StreamResponse` into gen_statem messages

#### Agent Kernel (L2)
- `CMDC.Agent``gen_statem` state machine with 4-state loop: `idle → running → streaming → executing_tools`
- `CMDC.Agent.State` — runtime state with token/cost tracking, loop detection hashes, sandbox/todos/memory fields
- `CMDC.Agent.Stream` — streaming delta accumulation with XML tag extraction (`<status>`, `<title>`)
- `CMDC.Agent.ToolRunner` — parallel tool execution with built-in loop detection (exact duplicate + pattern + consecutive failure) + tool retry with `on_tool_error` Plugin hook; configurable via `:tool_max_retries` (default 0) and `:tool_retry_delay_ms` (default 500ms)
- `CMDC.Agent.Emitter` — EventBus event broadcasting with ETS ring buffer for recent event retrieval
- `CMDC.Agent.BasePrompt` — default base prompt aligned with DeepAgents `BASE_AGENT_PROMPT`
- `CMDC.Agent.SystemPrompt` — system prompt assembly: BasePrompt + user prompt + blueprint identity + skills + memory
- `CMDC.Agent.Compactor` — automatic context compaction; token-based trigger with character estimation fallback; offload to file
- `CMDC.Agent.Compactor.ArgTruncator` — pre-truncation of large tool arguments (write_file/edit_file/execute)

#### Built-in Plugins (6)
- `CMDC.Plugin.Builtin.SecurityGuard` (priority 10) — path and command blacklist enforcement
- `CMDC.Plugin.Builtin.HumanApproval` (priority 15) — HITL approval flow via `approval_required` events
- `CMDC.Plugin.Builtin.EventLogger` (priority 50) — JSON Lines session audit log
- `CMDC.Plugin.Builtin.MemoryLoader` (priority 100) — AGENTS.md loading and `<agent_memory>` injection; auto-reload on write_file/edit_file
- `CMDC.Plugin.Builtin.PatchToolCalls` (priority 120) — synthetic tool result injection for dangling tool_calls
- `CMDC.Plugin.Builtin.PromptCache` (priority 130) — Anthropic prompt caching headers; auto-skip for other providers

#### Built-in Tools (11)
- `CMDC.Tool.ReadFile` — file reading with offset/limit pagination; Sandbox proxy
- `CMDC.Tool.WriteFile` — file writing with parent directory creation; Sandbox proxy
- `CMDC.Tool.EditFile` — exact string replacement (str_replace); Sandbox proxy
- `CMDC.Tool.Shell` — shell command execution; large output auto-saved to temp file; Sandbox proxy
- `CMDC.Tool.Grep` — regex file search with line numbers and glob filtering; Sandbox proxy
- `CMDC.Tool.ListDir` — directory listing with type and size; Sandbox proxy
- `CMDC.Tool.Glob` — glob pattern file matching; Sandbox proxy
- `CMDC.Tool.Task` — OTP-process-level sub-agent spawning under SubAgent.Supervisor; broadcasts `subagent_start`/`subagent_end`
- `CMDC.Tool.WriteTodos` — Context.todos update with `todo_change` event broadcast
- `CMDC.Tool.AskUser` — pause execution, wait for `user_responded` event
- `CMDC.Tool.CompactConversation` — manual context compaction trigger

#### Integration Layer (L3)
- `CMDC.SessionServer` — per-session Supervisor tree (Agent + SubAgent.Supervisor)
- `CMDC.SubAgent.Supervisor` — DynamicSupervisor for isolated child agent processes (`:temporary` restart)
- `CMDC.MCP.Bridge` — dynamic CMDC.Tool module generation from MCP server tool definitions
- `CMDC.MCP.Client``anubis_mcp`-based MCP client with Registry naming per server
- `CMDC.MCP.Supervisor` — DynamicSupervisor for MCP client processes
- `CMDC.MCP.Config` — mcp.json discovery with multiple path fallbacks
- `CMDC.Memory.ETS` — ETS-backed key-value memory store with keyword search
- `CMDC.Gateway` / `CMDC.Gateway.Local` — outbound event reporting contract and local EventBus implementation

#### Public API (L4)
- `CMDC` — facade with `create_agent/1`, `prompt/2`, `collect_reply/2`, `stop/2`, `abort/1`, `subscribe/1`, `unsubscribe/1`, `approve/2`, `reject/2`, `status/1`, `agent_pid/1`, `session_id/1`
- `CMDC.Blueprint.Base` — built-in base blueprint (SecurityGuard + EventLogger + PatchToolCalls)

#### Documentation
- `README.md` — Quick Start, feature comparison table (CMDC vs DeepAgents), architecture diagram, built-in tool/plugin tables
- `llm.txt` — AI quick reference (~230 lines): all public API signatures, parameter types, common patterns
- `llms-full.txt` — AI complete reference (~999 lines): event protocol, Tool/Plugin development guide, 14 known pitfalls

[0.1.0]: https://github.com/tuplehq/cmdc/releases/tag/v0.1.0