# Changelog 本项目所有重要变更均记录于此文件。格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)。 ## [0.3.0] - 未发布 v0.3.0 首个增量 Phase。技术债清理 + ContextSlot fork/merge + Phase 9 审查修复。 ### Breaking Changes **类型路径变更(0.3.0):** - `agcore::llm::types::request::ToolChoice` → `agcore::llm::types::tool::ToolChoice`(公共 re-export 路径 `agcore::llm::types::ToolChoice` 保持不变) - `agcore::llm::types::request::StreamOptions` → `agcore::llm::provider::openai::StreamOptions` - `agcore::llm::types::request::OpenaiChatRequest` → `agcore::llm::provider::openai::OpenaiChatRequest` - `agcore::llm::types::response::OpenaiChatResponse` → `agcore::llm::provider::openai::OpenaiChatResponse` - `agcore::llm::types::response::OpenaiChatChunk` → `agcore::llm::provider::openai::OpenaiChatChunk` - 其余 `request.rs`/`response.rs` 中的 wire-format 类型(`OpenaiTool`、`AudioParam`、`Choice`、`Delta`、`ChunkChoice`、`Annotation`、`Logprobs`、`TokenLogprob`、`URLCitation` 等)同步移入 `agcore::llm::provider::openai` 模块,可见性 `pub(crate)` **类型删除:** - `agcore::llm::types::ChatResponse` 已删除(自 v0.1.0 标记 `#[deprecated]`,请改用 `MessageResponse`) - `agcore::llm::types::old_stream::LegacyStreamEvent` 已删除(内部死代码) **模块签名变化:** - `LlmCycle::convert_request` / `convert_response` 由 `pub` 降级为 `pub(crate)`(因依赖的 `OpenaiChatRequest` / `OpenaiChatResponse` 已 `pub(crate)`) ### Added **Phase 13 — ContextSlot fork/merge** - `ContextSlot::fork(child_id, strategy)` — 从父槽派生独立子槽(数据层操作,不持久化;调用方需自行 `save()`) - `ContextSlot::merge(child, strategy)` — 将子槽消息合并回父槽(`Append` 追加 / `Replace` 替换两种策略) - `MergeStrategy` 枚举(`#[non_exhaustive]`,Phase 16 可扩展 `Summarize`) - `MergeStrategy` 防御性检查:禁止 self-merge / 跨 session merge / 合并到 Readonly slot - `agcore::agent::MergeStrategy` 公共 re-export 路径可用 - `AgentSession::derive_slot` 重构复用 `fork()` 消除重复代码(行为不变) **Phase 9 实施审查修复(2026-07-08)** - 2 个集成测试覆盖方案 §4 Step 5:`submit_turn_stream_end_to_end` + `submit_turn_stream_triggers_turn_hooks` ### Changed **Phase 13 — 技术债清理** - 3 个旧 types 文件删除(`src/llm/types/request.rs` 187 行 + `response.rs` 177 行 + `old_stream.rs` 45 行) - 所有 OpenAI wire-format 类型迁入 `provider/openai.rs`,可见性 `pub(crate)` - `src/llm/stream.rs` 简化为 module doc + `pub use` 重导出(保持 `use crate::llm::stream::StreamEvent` 路径兼容,零下游破坏) - `ToolChoice` 从 `request.rs` 迁入 `tool.rs`(serde impl 原样搬入) **Phase 9 实施审查修复** - `LlmCycle::run_tool_loop` 实现 `PreRequest` hook(之前 `let _ = hook_executor.as_ref()` 是空操作,导致 hook-based logging/monitoring 在流式工具循环中失效;现在与 `submit_with_tools` 行为对齐,含 `should_block` 检查,阻断时通过 `StreamEvent::Error` 事件化) ### Fixed **Phase 9 实施审查修复** - `AgentSession::submit_turn_stream` 末尾 `let _ = hook_executor;` 死代码移除(Arc 引用生命周期由 Arc 自动管理) ### Migration Guide (v0.2.0-rc.1 → v0.3.0) ```rust // ❌ v0.2.0-rc.1 — 已删除 use agcore::llm::types::ChatResponse; use agcore::llm::types::request::OpenaiChatRequest; // ✅ v0.3.0 — 替代路径 use agcore::llm::types::MessageResponse; // ChatResponse → MessageResponse // OpenAI wire-format 类型为内部使用,不再公共 re-export // 如需自定义 Provider,请直接 import agcore::llm::provider::openai::*(当前 pub(crate)) ``` ## [0.2.0-rc.1] - 2026-07-05 v0.2.0 候选发布。Phase 5-7 三大 P0 全部交付完成,API 稳定性扫尾,新增 2 个面向新用户的集成示例。 ### Added **Phase 5 — 热身准备** - `ProviderConfig::from_env(prefix)`:从 `{prefix}_BASE_URL` / `{prefix}_API_KEY` / `{prefix}_MODEL` / `{prefix}_TIMEOUT_SECS` / `{prefix}_MAX_RETRIES` 环境变量构造配置 - `ProviderConfig::timeout_secs` / `max_retries` 字段(默认 30 / 3) - `OllamaProvider`:本地推理 Provider(OpenAI-compatible,`http://localhost:11434/v1` 默认端点) - `ProviderType::Ollama` 变体 + `FromStr` 解析 **Phase 6 — ToolDef IR 正式化** - `ToolDef` 结构体(name / description / parameters)替代已废弃的 `OpenaiToolDefinition` - `MessageRequest.tools` 切换为 `Vec` - `OpenaiToolDefinition` 降级为 `#[doc(hidden)]`,仅供 OpenAI 适配层内部消费 **Phase 7 — SqliteStore 持久化** - `SqliteStore`:`MemoryStore` 的 SQLite 后端实现,基于 `rusqlite 0.32` bundled - WAL 模式 + `synchronous=NORMAL` + `busy_timeout=5s` 兼顾崩溃安全与吞吐 - `Arc>` + `spawn_blocking` 卸载 IO;10×10 并发写入无 race - `MemoryStore::save / get / delete / list` CRUD + prefix / since / offset+limit 过滤 - 进程重启数据不丢的 round-trip 验证 **Phase 8 — MVP 集成出口** - `examples/quick_start`:30 行最小可运行示例(MockProvider + EchoTool + submit_turn) - `examples/end_to_end`:3 工具 + 3 轮对话 + SqliteStore 持久化跨连接验证 ### Changed - **API 稳定性护栏**:14 个公开枚举标记 `#[non_exhaustive]`,覆盖 P0 核心 IR(`Message` / `ContentBlock` / `ContentBlockType` / `StreamEvent` / `HookEvent`)、P0 Error(`AgentError` / `LlmError` / `ToolError` / `MemoryError` / `PromptError`)、P1 其他(`MemoryStrategy` / `StepStatus` / `ToolChoice` / `ResponseFormat`) - **`StepStatus::Completed` 字段类型**:从废弃的 `ChatResponse` 切换为 IR 层 `MessageResponse`(同时清理 `task_agent_demo.rs` 的 `ChatResponse` / `OpenaiChatMessage` / `FinishReason` 三处废弃类型引用) ### Non-exhaustive 清单 为防止未来新增变体时下游 exhaustive match 静默失效,14 个枚举追加 `#[non_exhaustive]`: | 优先级 | 枚举 | |--------|------| | P0 核心 IR | `Message`, `ContentBlock`, `ContentBlockType`, `StreamEvent`, `HookEvent` | | P0 Error | `AgentError`, `LlmError`, `ToolError`, `MemoryError`, `PromptError` | | P1 其他 | `MemoryStrategy`, `StepStatus`, `ToolChoice`, `ResponseFormat` | 明确不加:内部 wire-format(`OpenaiChatMessage` 等)/ 语义已收敛(`Role` / `ServiceTier` / `Modality` / `ImageDetail` / `AudioFormat` / `StopSequence`)/ 使用面窄(`Permission` / `McpTransport` 等)。 ### Deprecated (继承自 0.1.0,无新增)`ChatResponse` / `ToolDefinition` 保持 `#[deprecated]` 标记。 ### Fixed - 修复 `StepStatus::Completed(ChatResponse)` 字段类型与 IR 体系不一致问题(已完成迁移) ### Migration Guide (v0.1 → v0.2.0-rc.1) 1. **枚举 match**:14 个 `#[non_exhaustive]` 枚举在 crate 外必须使用 `_ =>` 通配分支 2. **`StepStatus::Completed`**:字段类型从 `ChatResponse` 切换为 `MessageResponse`,需做字段映射(参考 `docs/15-phase8-mvp-integration.md` §3.1.2) 3. **`ToolDefinition` → `ToolDef`**:Phase 6 已彻底替换 `#[deprecated]` 别名,需全局重命名 --- ## [0.1.0] - 2026-07-04 首个公开版本。涵盖 Phase 0-4c 的全部核心能力、Provider IR 重构、LlmCycle 简化,以及面向用户的 7 个离线示例。 ### Added **LLM 调用周期(Phase 0)** - 统一 IR 类型层:`Message`、`ContentBlock`、`MessageRequest`、`MessageResponse`、`ToolDefinition`、`StopReason` - `LlmProvider` trait + 4 个 Provider 实现:OpenAI Chat Completions、Anthropic Messages、DeepSeek(OpenAI 兼容)、Qwen(OpenAI 兼容) - `ProviderRegistry`:多 Provider 注册与发现 - `LlmCycle`:重试策略 + 用量追踪 + 自动 tool 循环 + Auto-compaction - `HookExecutor`:OnTurnStart / OnTurnEnd / OnPlanStepComplete 等生命周期钩子 - `StreamEvents`:AssistantTextDelta / ToolExecutionStarted / MessageComplete 等流式事件 **提示词工程(Phase 1)** - `PromptTemplate`:变量插值 + 条件渲染 - `PromptComposer`:system/user/assistant/tool_result 消息链组合 **工具系统(Phase 2)** - `ToolRegistry`:注册、发现、并行调用、超时控制 - `BaseTool` trait(含 `ToolContext` 执行上下文) - `McpClient`:stdio transport(StreamableHttp 已预留接口) - `PermissionChecker`:白名单 / 黑名单 / 自定义权限 **记忆系统(Phase 3)** - `MemoryStore` trait + `InMemoryStore` 默认实现 - `ConversationMemory`:sliding window / 全量模式,集成 `llm::compact` - `KnowledgeStore`:知识页面存储 - `MemoryRetriever`:TextOverlap Dice 系数评分 - `EvictionPolicy`:None / Ttl / Capacity 三种淘汰策略 **Agent 运行时(Phase 4a/b/c)** - `Agent` trait:name / system_prompt / tool_definitions - `AgentSession` + `RuntimeBundle` + `AgentBuilder`:链式构造 + 依赖注入 - `AgentError`:Llm / Tool / Memory / HookBlocked / LimitExceeded / Config / PlanParse / Other 8 个变体 - `TaskAgent` trait + `JsonPlanParser`:自主执行 + 外部驱动 - `Plan` / `Step` / `StepStatus`:纯数据结构 - `SessionMemory`:基于 `MemoryStore` 的会话级 key-value 桥接 **面向用户的资产** - `agcore::llm::mock::MockProvider`:公开的 Mock Provider,支持 `chat` + `chat_stream`,无需 API key 即可运行示例 - 7 个离线可运行示例(`cargo run --example ...`): - `prompt_composer` — 模板变量插值 + 消息链构建 - `custom_tool` — 工具注册 + 权限检查 - `agent_session_demo` — AgentBuilder → AgentSession → submit_turn 完整链路 - `task_agent_demo` — JsonPlanParser → Plan → Step 状态机 - `conversation_memory_demo` — SessionMemory 命名空间隔离 - `knowledge_search_demo` — KnowledgeStore + 停用词过滤 - `streaming_events_demo` — 流式事件消费 ### Changed - **`LlmCycle` 切换到 IR 消息类型**:内部消息从 `OpenaiChatMessage` 切到统一 `Message` 类型,移除 Phase 0 的桥接转换层(方案:`docs/10c-phase2-llm-cycle-simplify.md`) - **Provider IR 重构**:`LlmProvider` trait 签名同步切到 `MessageRequest` / `MessageResponse`;新增 Anthropic / DeepSeek / Qwen Provider(方案:`docs/10-llm-provider-refinement.md`、`docs/10b-phase1-provider-adaptation.md`) - **`AgentBuilder` 扩展 `session_memory_backend`**:Phase 4c 接入会话级记忆 - **错误消息面向最终用户友好化**:`AgentError` / `LlmError` / `ToolError` / `MemoryError` / `PromptError` 全部改写为带可操作建议的友好消息 - **`composer.rs` IR 迁移**:`PromptComposer` 内部从 `OpenaiChatMessage` 切到 `Message` / `ContentBlock`,与新类型系统保持一致 - **`knowledge.rs` 锁修复**:`std::sync::Mutex` → `tokio::sync::Mutex`,避免 MutexGuard 跨 `.await` 持有 ### Deprecated - `ChatResponse` — 自 0.1.0 起标记为 deprecated,请改用 `MessageResponse` - `ToolDefinition` — 自 0.1.0 起标记为 deprecated(仍直接对应 OpenAI wire-format);v0.2 将引入 IR 工具类型 ### Fixed - 修复 Provider IR 重构后 `session.rs` / `cycle.rs` 测试模块的导入缺失回归 - 修复 `knowledge.rs::search()` 中 MutexGuard 跨 `.await` 持有的潜在阻塞 - 清零全部 clippy 警告(`#[allow(dead_code)]` 已在最低必要范围使用) ### Removed - 移除 Phase 0 的 `OpenaiChatMessage ↔ Message` 桥接层(LlmCycle 简化后已无外部调用方) --- ## 版本基线 | 指标 | 数值 | |------|------| | `cargo build --all-targets` | ✅ 通过 | | `cargo test --all-targets` | ✅ 182 passed / 0 failed | | `cargo clippy --all-targets -- -D warnings` | ✅ 0 警告 | | 离线示例 | ✅ 7 个全部 `cargo run` 退出码 0 | | 许可证 | Apache-2.0 | [0.1.0]: https://git.archgrid.xyz/xt/agcore/releases/tag/v0.1.0