4686063ca8
- CHANGELOG.md: 追加 v0.3.0 (unreleased) 条目
- Breaking Changes: 类型路径变更(request.rs/response.rs → provider/openai.rs,
公共 ToolChoice re-export 路径不变)+ ChatResponse / LegacyStreamEvent 删除
- Added: ContextSlot::fork / merge + MergeStrategy 枚举(#[non_exhaustive])
- Changed: 3 个旧 types 文件删除 + 所有 wire-format 类型迁入 openai.rs
- Fixed: Phase 9 实施审查修复(PreRequest hook + 死代码清理 + 2 个集成测试)
- Migration Guide: v0.2.0-rc.1 → v0.3.0 路径迁移示例
- 修复 M9 里程碑验收 #11(CHANGELOG 条目)和审查结论 CONDITIONAL PASS 条件清单 #1
- docs/roadmap.md:
- 顶部最后更新日期 → 2026-07-08(Phase 13 完成 + M9 里程碑达成)
- 末尾"v0.3.0 规划完成"状态行从"Phase 13-19 待逐步实施"更新为"Phase 13 完成,
Phase 14-19 待实施(Document → 向量存储 → 摘要 → 引擎 → 调度 → 知识图谱)"
215 lines
12 KiB
Markdown
215 lines
12 KiB
Markdown
# 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<ToolDef>`
|
||
- `OpenaiToolDefinition` 降级为 `#[doc(hidden)]`,仅供 OpenAI 适配层内部消费
|
||
|
||
**Phase 7 — SqliteStore 持久化**
|
||
- `SqliteStore`:`MemoryStore` 的 SQLite 后端实现,基于 `rusqlite 0.32` bundled
|
||
- WAL 模式 + `synchronous=NORMAL` + `busy_timeout=5s` 兼顾崩溃安全与吞吐
|
||
- `Arc<Mutex<Connection>>` + `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 |