Files
agcore/CHANGELOG.md
徐涛 4686063ca8 docs: 标记 Phase 13 完成 + 追加 v0.3.0 CHANGELOG 条目
- 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 → 向量存储 → 摘要 → 引擎 → 调度 → 知识图谱)"
2026-07-09 06:19:43 +08:00

215 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`:本地推理 ProviderOpenAI-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` 卸载 IO10×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、DeepSeekOpenAI 兼容)、QwenOpenAI 兼容)
- `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 transportStreamableHttp 已预留接口)
- `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` traitname / 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