28ca43ccb2
将 note、pdd、prd、roadmap 四类文档分别归入 `design/` 下对应子目录中,并新增 `.gitkeep` 占位文件
477 lines
24 KiB
Markdown
477 lines
24 KiB
Markdown
# AG Core Roadmap — v0.3.2
|
||
|
||
**状态**:✅ Phase 20-27 全部交付(v0.3.2 交付完毕)
|
||
|
||
> 本文件聚焦 **v0.3.2 版本** 的规划与交付(Phase 20–27)。
|
||
> 返回总入口:[`roadmap.md`](./roadmap.md)
|
||
|
||
> **进度更新(2026-07-19)**:v0.3.2 全部交付。Step 1 完成 Phase 20-25(Cargo features 定义 + 依赖 optional 化 + 全模块 cfg 门控);Step 3 完成 Phase 26-27(CI 测试矩阵固化 + LlmProvider trait 归属修正 + examples required-features + 文档更新)。验证矩阵 6 种组合全部通过(427/416/363/369/401/407 passed),clippy 0 警告,18 个 example 单独编译通过。
|
||
>
|
||
> **Step 3 实施中的关键调整**(超出原方案的发现):
|
||
> - `LlmProvider` trait + `ProviderCapabilities` + `ProviderFeatures` 从 `provider.rs` 移至新建的 `provider_trait.rs`,归属 `#[cfg(feature = "llm")]`(ADR-1,纯 Mock 场景不再需要 provider feature)
|
||
> - `llm` feature 补充 imply `futures-util`(修复 `cycle.rs` 隐式依赖)
|
||
> - `bundle()` 方法加 `#[cfg(feature = "engine")]` 门控修复 dead_code 警告
|
||
> - `prompt_composer` / `custom_tool` 的 required-features 需额外 `llm`(`response_v2.rs` 依赖 `LlmError`,预存耦合)
|
||
> - cargo fmt 全量格式化(修复预存格式问题,CI format job 可通过)
|
||
>
|
||
> 实施方案见 [`docs/26-step1-phase20-cargo-features-implementation.md`](./26-step1-phase20-cargo-features-implementation.md) 和 [`docs/27-step3-phase26-ci-verification.md`](./27-step3-phase26-ci-verification.md)。
|
||
|
||
## v0.3.2 愿景
|
||
|
||
通过 Cargo features 拆分,让下游按需选择模块,跳过不需要的编译单元和重型依赖。
|
||
|
||
## v0.3.2 总体范围
|
||
|
||
**版本等级**:patch(v0.3.2),`default = ["full"]` 保持向后兼容,非破坏性变更。
|
||
|
||
**改造基线**:v0.3.0 已交付 23,718 行 Rust 代码,66 个源文件。当前所有依赖全量编译——引用 agcore 就意味着拉入 rusqlite bundled、reqwest、tokio full 等全部重型依赖。
|
||
|
||
**改造目标**:16 个 features(10 模块级 + 5 provider + 1 工具)+ 4 个快捷组合。下游可只选 `chat` 组合跳过 SQLite 和 MCP 的编译,或只选 `document` 实现纯文档分割零外部依赖。
|
||
|
||
**工作性质**:纯 cfg 门控 + Cargo.toml 配置变更,不新增功能代码。
|
||
|
||
**总体规模**:8 个增量 Phase(Phase 20–27),预计新增/修改约 330 行配置与条件编译代码。
|
||
|
||
---
|
||
|
||
## 功能清单
|
||
|
||
### 模块级 features(10 个)
|
||
|
||
| Feature | 覆盖内容 | imply | 外部依赖成本 |
|
||
|---------|---------|-------|-------------|
|
||
| `document` | Document + RecursiveCharacterSplitter | — | 无 |
|
||
| `llm-types` | Message, ToolDef, Usage, ToolChoice 等 IR 类型 | — | 无(只 serde + thiserror) |
|
||
| `prompt` | PromptTemplate + PromptComposer | `llm-types` | 无 |
|
||
| `llm` | Provider trait + LlmCycle + hooks + compact + embedding + mock | `llm-types` | tokio, async-stream, futures-core, futures-util, tokio-stream |
|
||
| `tools` | BaseTool + ToolRegistry | `llm-types` | futures, tokio-util, tokio |
|
||
| `tools-mcp` | McpClient(Stdio/StreamableHttp) | `tools` | reqwest |
|
||
| `memory` | MemoryStore(InMemory) + Conversation + VectorStore(InMemory) + KnowledgeGraph + Retriever | `document` + `llm` | tokio, time(继承 llm 的依赖) |
|
||
| `memory-sqlite` | SqliteStore | `memory` | rusqlite (bundled), time |
|
||
| `agent` | Agent + Builder + Session + ContextSlot + Summary | `llm` + `tools` + `memory` | 继承下层 |
|
||
| `engine` | SessionManager + Checkpointer + SubAgent + Switch | `agent` | 继承下层 |
|
||
|
||
### Provider features(5 个,各自独立)
|
||
|
||
| Feature | imply | 外部依赖 |
|
||
|---------|-------|---------|
|
||
| `provider-openai` | `llm` | reqwest + bytes + futures-util |
|
||
| `provider-anthropic` | `llm` | reqwest + bytes + futures-util |
|
||
| `provider-deepseek` | `llm` | reqwest |
|
||
| `provider-qwen` | `llm` | reqwest |
|
||
| `provider-ollama` | `llm` | reqwest |
|
||
|
||
### 工具 features(1 个)
|
||
|
||
| Feature | 控制 | 依赖 |
|
||
|---------|------|------|
|
||
| `tracing-init` | `init_tracing()` 函数 | tracing-subscriber |
|
||
|
||
### 快捷组合(4 个)
|
||
|
||
| 组合 | 定义 | 场景 |
|
||
|------|------|------|
|
||
| `full`(default) | 全部 16 个 feature | 全栈(兼容 v0.3) |
|
||
| `light` | llm + provider-openai + tools + tools-mcp + memory + agent + engine + prompt + document | 生产常用 |
|
||
| `chat` | agent + provider-openai | 纯对话(context+session+轻量记忆,跳过 SQLite;MCP 按需加 `tools-mcp`) |
|
||
| `multi` | engine + provider-openai | 多 Agent 复合(chat + subagent + switch + checkpointer;MCP 按需加 `tools-mcp`) |
|
||
|
||
---
|
||
|
||
## 实施计划 — 8 个增量 Phase
|
||
|
||
> **编号说明**:Phase 20-27 接续 v0.3.0 的 Phase 13-19。
|
||
|
||
### 实施节奏:4 个 Step
|
||
|
||
将 8 个 Phase 合并为 4 个实施步骤,平衡变更风险与执行效率。
|
||
|
||
| Step | Phase | 内容 | 验证方式 | 预估行数 |
|
||
|------|-------|------|---------|---------|
|
||
| **Step 1** ✅ | Phase 20-25 | Cargo.toml features 定义 + 依赖 optional 化 + 全模块 cfg 门控(合并实施) | 14 条编译验证全通过 + `cargo test -F full` 427 passed | ~100 |
|
||
| **Step 2** | (已合并至 Step 1) | — | — | — |
|
||
| **Step 3** ✅ | Phase 26 | 测试矩阵验证 + 修复 cfg 遗漏 + LlmProvider trait 归属修正 + examples required-features | 6 种组合全部测试通过 + clippy 0 警告 + 18 个 example 单独编译通过 | ~80 |
|
||
| **Step 4** ✅ | Phase 27 | README + 示例标注 + 总入口同步 | review 通过 | ~100 |
|
||
|
||
**Step 1 单独成步**:Cargo.toml 是基础设施变更,编译通过后打 checkpoint,后续都是纯源文件变更。
|
||
|
||
**Step 2 合并 Phase 21–25**:全是 `#[cfg(feature = "...")]` 公式化插门控,按依赖顺序(底层模块 → LLM/Provider → Tools/MCP → Memory → Agent/Engine)实施,每插一个 feature 门控就验证。按子模块分批 commit 控制粒度。
|
||
|
||
---
|
||
|
||
### Phase 20: Cargo.toml 基础设施改造
|
||
|
||
**目标**:定义完整的 [features] 表,重型依赖改为 optional,建立 imply 链。
|
||
|
||
| Step | 内容 | 文件范围 | 验证标准 |
|
||
|------|------|---------|---------|
|
||
| **20.1** | 定义 16 个 features + 4 个快捷组合,`default = ["full"]` | `Cargo.toml` | `cargo build --features "full"` 编译通过,行为与原版一致 |
|
||
| **20.2** | tokio / reqwest / rusqlite / tracing-subscriber 改为 optional | `Cargo.toml` | `cargo build --no-default-features` 成功(空 crate) |
|
||
| **20.3** | tokio-stream / futures / futures-util / futures-core / bytes / async-stream / tokio-util / time 改为 optional | `Cargo.toml` | `cargo build --features "full"` 全量依赖正确拉取 |
|
||
| **20.4** | tokio features 拆细:从 `["full"]` 改为 `["rt", "sync", "time", "macros", "process", "io-util"]`,仅保留实际使用的子模块 | `Cargo.toml` | `cargo build --features "llm,provider-openai"` 不拉入 tokio net/http 等无关子模块 |
|
||
| **20.5** | feature imply 链配置:`prompt → llm-types`,`llm → llm-types`,`tools → llm-types`,`memory → document`,`agent → llm + tools + memory`(不含 tools-mcp),`engine → agent` | `Cargo.toml` | `cargo build --features "agent,provider-openai"` transitive 依赖自动拉取 |
|
||
|
||
**依赖**:无(Cargo.toml 独立改造)
|
||
**优先级**:P0
|
||
**预估规模**:约 40 行
|
||
**状态**:✅ 已交付(2026-07-19)— features 定义 + 依赖 optional 化 + tokio features 拆细(含 `rt-multi-thread` 修正)
|
||
|
||
---
|
||
|
||
### Phase 21: 底层模块 cfg 门控注入
|
||
|
||
**目标**:为 llm-types、document、prompt 三个零/低外部依赖模块添加条件编译门控。
|
||
|
||
| Step | 内容 | 文件范围 | 验证标准 |
|
||
|------|------|---------|---------|
|
||
| **21.1** | `src/lib.rs` 中所有 `pub mod` 声明加 `#[cfg(feature = "...")]` | `src/lib.rs` | `cargo build --no-default-features` 无模块引入 |
|
||
| **21.2** | llm-types 模块条件编译 + 公共类型条件导出 | `src/llm/types/` | `cargo build --no-default-features --features "llm-types"` 编译通过 |
|
||
| **21.3** | document 模块条件编译 + `pub use Document` 条件导出 | `src/document.rs` | `cargo build --no-default-features --features "document"` 编译通过 |
|
||
| **21.4** | prompt 模块条件编译 | `src/prompt.rs` | `cargo build --no-default-features --features "prompt"` 编译通过 |
|
||
|
||
**依赖**:Phase 20(需 feature 定义就绪)
|
||
**优先级**:P0
|
||
**预估规模**:约 30 行
|
||
**状态**:✅ 已交付(2026-07-19,Step 1 合并)— `src/lib.rs` 全部 `pub mod` + `pub use Document` 门控完成
|
||
|
||
---
|
||
|
||
### Phase 22: LLM + Provider 门控注入
|
||
|
||
**目标**:llm 模块整体门控 + 5 个 Provider 独立条件编译 + cycle.rs 中 ToolRegistry 引用的 `#[cfg]` 隔离。
|
||
|
||
| Step | 内容 | 文件范围 | 验证标准 |
|
||
|------|------|---------|---------|
|
||
| **22.1** | llm 模块 cfg + embedding 子模块条件导出 + MockProvider 条件编译 | `src/llm.rs` | `cargo build --no-default-features --features "llm"` 编译通过 |
|
||
| **22.2** | `create_provider()` + `build_client_*` 条件编译,按 feature 分别暴露 | `src/llm/provider.rs` | 各 provider feature 单独启用 |
|
||
| **22.3** | OpenAI provider `#[cfg(feature = "provider-openai")]` | `src/llm/provider/openai.rs` | `--features "llm,provider-openai"` 编译通过;不含时不编译 |
|
||
| **22.4** | Anthropic provider 条件编译 | `src/llm/provider/anthropic.rs` | `--features "llm,provider-anthropic"` 编译通过 |
|
||
| **22.5** | DeepSeek + Qwen 共享 `openai_compat.rs` 用 `any(feature = "provider-deepseek", feature = "provider-qwen")` 条件 | `src/llm/provider/openai_compat.rs` | 各自单独编译通过 |
|
||
| **22.6** | Ollama provider 条件编译 | `src/llm/provider/ollama.rs` | `--features "llm,provider-ollama"` 编译通过 |
|
||
| **22.7** | `cycle.rs` 中 ToolRegistry 引用 + `submit_with_tools` 系列方法 `#[cfg(feature = "tools")]` | `src/llm/cycle.rs` | `--features "llm,provider-openai"` 不含 tools 编译通过 |
|
||
|
||
**依赖**:Phase 20 + Phase 21
|
||
**优先级**:P0
|
||
**预估规模**:约 80 行(中复杂度,cycle.rs 门控需精确隔离)
|
||
**状态**:✅ 已交付(2026-07-19,Step 1 合并)— `src/llm.rs` 子模块按 llm-types/llm/provider 三类门控;`cycle.rs` 中 `ToolRegistry` import + `submit_with_tools` / `submit_with_tools_stream` / `run_tool_loop` 加 `#[cfg(feature = "tools")]`(Phase 22.7 提前)
|
||
|
||
---
|
||
|
||
### Phase 23: Tools + MCP 门控注入
|
||
|
||
**目标**:tools 模块整体门控 + mcp 子模块条件编译。
|
||
|
||
| Step | 内容 | 文件范围 | 验证标准 |
|
||
|------|------|---------|---------|
|
||
| **23.1** | tools 模块 cfg + pub use 条件导出 | `src/tools.rs` | `--features "tools"` 编译通过;不含时不编译 |
|
||
| **23.2** | `mcp.rs` 整个文件 `#[cfg(feature = "tools-mcp")]` | `src/tools/mcp.rs` | `--features "tools"` 不含 mcp 时编译通过;加 `tools-mcp` 时引入 |
|
||
| **23.3** | ToolRegistry 中 McpClient 引用的条件导出 | `src/tools/registry.rs` | `--features "tools"` 不含 mcp 编译通过 |
|
||
|
||
**依赖**:Phase 20 + Phase 21
|
||
**优先级**:P0
|
||
**预估规模**:约 20 行
|
||
**状态**:✅ 已交付(2026-07-19,Step 1 合并)— `src/tools.rs` 中 `pub mod mcp` + `pub use mcp::*` 加 `#[cfg(feature = "tools-mcp")]`
|
||
|
||
---
|
||
|
||
### Phase 24: Memory 门控注入
|
||
|
||
**目标**:memory 模块门控 + vector_store 中 Embedding 引用隔离 + SqliteStore 可选化。
|
||
|
||
| Step | 内容 | 文件范围 | 验证标准 |
|
||
|------|------|---------|---------|
|
||
| **24.1** | memory 模块 cfg + pub use 条件导出 | `src/memory.rs` | `--features "memory"` imply document 编译通过 |
|
||
| **24.2** | vector_store 中 Embedding trait 引用 `#[cfg(feature = "llm")]` | `src/memory/vector_store.rs` | `--features "memory"` 不含 `llm` 编译通过 |
|
||
| **24.3** | `sqlite_store.rs` 整个文件 `#[cfg(feature = "memory-sqlite")]` | `src/memory/store/sqlite_store.rs` | `--features "memory"` 不含 sqlite 编译通过 |
|
||
| **24.4** | `memory.rs` 中 `pub use SqliteStore` 条件导出 | `src/memory.rs` | `--features "memory-sqlite"` 正确导出 SqliteStore |
|
||
|
||
**依赖**:Phase 20 + Phase 21
|
||
**优先级**:P0
|
||
**预估规模**:约 30 行
|
||
**状态**:✅ 已交付(2026-07-19,Step 1 合并)— Phase 24.3(`sqlite_store` 模块门控)+ Phase 24.4(`pub use SqliteStore` 门控)已完成;Phase 24.1(memory 模块 pub use)由 `src/lib.rs` 的 `#[cfg(feature = "memory")]` 覆盖;Phase 24.2(vector_store 中 Embedding 引用隔离)经 Phase 26 验证无需补充——`memory` feature imply `llm`,`Embedding` trait 在 `memory` 启用时一定可用
|
||
|
||
---
|
||
|
||
### Phase 25: Agent + Engine 门控注入
|
||
|
||
**目标**:agent 和 engine 两个高层模块的条件编译门控。注意 agent 不再 imply tools-mcp——MCP 作为可选工具层由用户显式启用。
|
||
|
||
| Step | 内容 | 文件范围 | 验证标准 |
|
||
|------|------|---------|---------|
|
||
| **25.1** | agent 模块 cfg + pub use 条件导出 | `src/agent.rs` | `--features "agent,provider-openai"` 编译通过 |
|
||
| **25.2** | engine 模块 cfg + 子模块条件导出(switch / sub_agent / checkpointer) | `src/engine/` | `--features "engine,provider-openai"` 编译通过 |
|
||
| **25.3** | `lib.rs` 中 agent / engine 模块声明 cfg + 条件重导出 | `src/lib.rs` | 验证 `engine` imply `agent` 链正确,transitive 依赖完整 |
|
||
|
||
**依赖**:Phase 20-24(全链路依赖就绪后操作)
|
||
**优先级**:P0
|
||
**预估规模**:约 20 行
|
||
**状态**:✅ 已交付(2026-07-19,Step 1 合并)— Phase 25.3(`src/lib.rs` 中 agent/engine 模块声明 cfg)已完成;Phase 25.1/25.2(agent/engine 内部子模块条件导出)由 `src/lib.rs` 顶层门控覆盖;`src/agent/session.rs` 中 engine 相关 import + `to_snapshot` / `from_snapshot` / `restore_memory` / `has_pending_memory_restore` + `pending_memory_restore` 字段加 `#[cfg(feature = "engine")]`;Phase 26 验证 `bundle()` 方法加 `#[cfg(feature = "engine")]` 门控修复 dead_code 警告
|
||
|
||
---
|
||
|
||
### Phase 26: 快捷组合验证 + 测试矩阵
|
||
|
||
**目标**:验证 4 个快捷组合 + clippy 完整性检查。
|
||
|
||
| Step | 内容 | 文件范围 | 验证标准 |
|
||
|------|------|---------|---------|
|
||
| **26.1** | `default = ["full"]` 回归验证 | CI | `cargo test --features "full"` 全绿(427 passed) |
|
||
| **26.2** | light 组合编译 + 单元测试 | CI | `cargo test --no-default-features --features "light"` 通过 |
|
||
| **26.3** | chat 组合(无 MCP)编译 + 单元测试 | CI | `cargo test --no-default-features --features "chat,provider-openai"` 通过 |
|
||
| **26.4** | chat + MCP 组合编译 + 单元测试 | CI | `cargo test --no-default-features --features "chat,provider-openai,tools-mcp"` 通过 |
|
||
| **26.5** | multi 组合(无 MCP)编译 + 单元测试 | CI | `cargo test --no-default-features --features "multi,provider-openai"` 通过 |
|
||
| **26.6** | multi + MCP 组合编译 + 单元测试 | CI | `cargo test --no-default-features --features "multi,provider-openai,tools-mcp"` 通过 |
|
||
| **26.7** | clippy `--all-features` 无警告 | CI | `cargo clippy --all-features -- -D warnings` 0 警告 |
|
||
| **26.8** | 修复各组合编译中发现的 cfg 遗漏 | 全量 | 7 种组合全部编译 + 测试通过 |
|
||
|
||
**依赖**:Phase 20-25(所有门控就绪)
|
||
**优先级**:P0
|
||
**预估规模**:约 10 行(CI 配置)
|
||
**状态**:✅ 已交付(2026-07-19)— 6 种 feature 组合测试矩阵 + clippy + format + examples 验证 job 全部通过;`RUSTFLAGS=-D warnings` 强制零警告;LlmProvider trait 归属修正 + bundle() 门控 + llm feature 补充 imply futures-util
|
||
|
||
---
|
||
|
||
### Phase 27: 文档更新 + 示例标注 + README feature 表
|
||
|
||
**目标**:让下游使用者能快速理解 feature 体系并选择合适组合。
|
||
|
||
| Step | 内容 | 文件范围 | 验证标准 |
|
||
|------|------|---------|---------|
|
||
| **27.1** | README.md 添加 feature 表格 + `Cargo.toml` 使用示例 + 各组合推荐场景 | `README.md` | review 通过 |
|
||
| **27.2** | 各示例文件顶部添加所需的 feature 组合标注注释 | `examples/*.rs` | review 通过 |
|
||
| **27.3** | 更新 `docs/roadmap.md` 总入口添加 v0.3.2 链接和简要状态 | `docs/roadmap.md` | review 通过 |
|
||
|
||
**依赖**:Phase 20-26
|
||
**优先级**:P0
|
||
**预估规模**:约 100 行
|
||
**状态**:✅ 已交付(2026-07-19)— README 添加 feature 表格 + 快捷组合 + 模块级 features 清单 + 升级指南(LlmProvider 路径迁移);18 个 example 顶部添加 Required features 注释;roadmap 总入口同步
|
||
|
||
---
|
||
|
||
## Feature 依赖关系图
|
||
|
||
```mermaid
|
||
graph TD
|
||
subgraph "快捷组合"
|
||
FULL["full (default)"]
|
||
LIGHT["light"]
|
||
CHAT["chat"]
|
||
MULTI["multi"]
|
||
end
|
||
|
||
subgraph "模块级"
|
||
ENGINE["engine"]
|
||
AGENT["agent"]
|
||
LLM["llm"]
|
||
TOOLS["tools"]
|
||
TOOLS_MCP["tools-mcp"]
|
||
MEMORY["memory"]
|
||
MEMORY_SQLITE["memory-sqlite"]
|
||
PROMPT["prompt"]
|
||
LLM_TYPES["llm-types"]
|
||
DOCUMENT["document"]
|
||
end
|
||
|
||
subgraph "Provider"
|
||
P_OPENAI["provider-openai"]
|
||
P_ANTHROPIC["provider-anthropic"]
|
||
P_DEEPSEEK["provider-deepseek"]
|
||
P_QWEN["provider-qwen"]
|
||
P_OLLAMA["provider-ollama"]
|
||
end
|
||
|
||
FULL --> LIGHT & CHAT & MULTI
|
||
ENGINE --> AGENT
|
||
AGENT --> LLM & TOOLS & MEMORY
|
||
CHAT -.-> TOOLS_MCP
|
||
MULTI -.-> TOOLS_MCP
|
||
MEMORY_SQLITE --> MEMORY
|
||
TOOLS_MCP --> TOOLS
|
||
MEMORY --> DOCUMENT
|
||
LLM --> LLM_TYPES
|
||
TOOLS --> LLM_TYPES
|
||
PROMPT --> LLM_TYPES
|
||
P_OPENAI --> LLM
|
||
P_ANTHROPIC --> LLM
|
||
P_DEEPSEEK --> LLM
|
||
P_QWEN --> LLM
|
||
P_OLLAMA --> LLM
|
||
|
||
classDef done fill:#4ade80,stroke:#16a34a,color:#1a1a1a
|
||
classDef pending fill:#fbbf24,stroke:#d97706,color:#1a1a1a
|
||
classDef provider fill:#93c5fd,stroke:#2563eb,color:#1a1a1a
|
||
class P_OPENAI,P_ANTHROPIC,P_DEEPSEEK,P_QWEN,P_OLLAMA provider
|
||
class FULL,ENGINE,AGENT,LLM,TOOLS,TOOLS_MCP,MEMORY,MEMORY_SQLITE,PROMPT,LLM_TYPES,DOCUMENT,LIGHT,CHAT,MULTI done
|
||
```
|
||
|
||
## 关键里程碑
|
||
|
||
| 里程碑 | Phase 完成条件 | 可验证指标 | 状态 |
|
||
|--------|---------------|-----------|------|
|
||
| **M16** | Phase 20 | `cargo build --no-default-features` 成功;`cargo build --features "full"` 与原行为一致 | ✅ 2026-07-19 |
|
||
| **M17** | Phase 21 | 三种零依赖模块各自独立编译通过 | ✅ 2026-07-19(Step 1 合并) |
|
||
| **M18** | Phase 22 | 5 个 provider 各自单独编译;cycle.rs 无 tools 时编译通过 | ✅ 2026-07-19(Step 1 合并) |
|
||
| **M19** | Phase 23 | tools 不含 mcp 编译通过;加 tools-mcp 引入 McpClient | ✅ 2026-07-19(Step 1 合并) |
|
||
| **M20** | Phase 24 | memory imply document+llm 编译通过;不含 sqlite 编译通过;加 memory-sqlite 引入 SqliteStore | ✅ 2026-07-19(Step 1 合并) |
|
||
| **M21** | Phase 25 | agent + engine 全链路门控编译通过 | ✅ 2026-07-19(Step 1 合并) |
|
||
| **M22** | Phase 26 | 7 种 CI 组合全部编译 + 测试通过;clippy --all-features 0 警告 | ✅ 2026-07-19 |
|
||
| **M23** | Phase 27 | 文档 review 通过 | ✅ 2026-07-19 |
|
||
|
||
## Cargo.toml [features] 草案
|
||
|
||
```toml
|
||
[dependencies]
|
||
# 轻量核心依赖(始终编译)
|
||
serde = { version = "1", features = ["derive"] }
|
||
serde_json = "1"
|
||
thiserror = "2"
|
||
async-trait = "0.1"
|
||
tracing = "0.1"
|
||
|
||
# 按 feature 可选的重依赖
|
||
tokio = { version = "1", features = ["rt", "sync", "time", "macros", "process", "io-util"], optional = true }
|
||
reqwest = { version = "0.12", features = ["json", "stream"], optional = true }
|
||
rusqlite = { version = "0.32", features = ["bundled"], optional = true }
|
||
tracing-subscriber = { version = "0.3", features = ["env-filter"], optional = true }
|
||
tokio-stream = { version = "0.1", optional = true }
|
||
futures = { version = "0.3", optional = true }
|
||
futures-util = { version = "0.3", optional = true }
|
||
futures-core = { version = "0.3", optional = true }
|
||
bytes = { version = "1", optional = true }
|
||
async-stream = { version = "0.3", optional = true }
|
||
tokio-util = { version = "0.7", features = ["rt"], optional = true }
|
||
time = { version = "0.3", features = ["serde", "parsing", "formatting", "macros"], optional = true }
|
||
```
|
||
|
||
```toml
|
||
[features]
|
||
default = ["full"]
|
||
|
||
# === 模块级 features ===
|
||
document = []
|
||
llm-types = []
|
||
prompt = ["llm-types"]
|
||
llm = ["llm-types", "tokio", "async-stream", "futures-core", "futures-util", "tokio-stream"]
|
||
tools = ["llm-types", "futures", "tokio-util", "tokio"]
|
||
tools-mcp = ["tools", "reqwest"]
|
||
memory = ["document", "llm", "tokio", "time"]
|
||
memory-sqlite = ["memory", "rusqlite", "time"]
|
||
agent = ["llm", "tools", "memory", "futures-util"]
|
||
engine = ["agent"]
|
||
|
||
# === Provider features ===
|
||
provider-openai = ["llm", "reqwest", "bytes", "futures-util"]
|
||
provider-anthropic = ["llm", "reqwest", "bytes", "futures-util"]
|
||
provider-deepseek = ["llm", "reqwest"]
|
||
provider-qwen = ["llm", "reqwest"]
|
||
provider-ollama = ["llm", "reqwest"]
|
||
|
||
# === 工具 features ===
|
||
tracing-init = ["tracing-subscriber"]
|
||
|
||
# === 快捷组合 ===
|
||
full = [
|
||
"document", "llm-types", "prompt", "llm",
|
||
"tools", "tools-mcp",
|
||
"memory", "memory-sqlite",
|
||
"agent", "engine",
|
||
"provider-openai", "provider-anthropic", "provider-deepseek",
|
||
"provider-qwen", "provider-ollama",
|
||
"tracing-init",
|
||
]
|
||
light = [
|
||
"llm", "provider-openai", "tools", "tools-mcp",
|
||
"memory", "agent", "engine",
|
||
"prompt", "document",
|
||
]
|
||
chat = ["agent", "provider-openai"]
|
||
multi = ["engine", "provider-openai"]
|
||
```
|
||
|
||
### 依赖 optional 化对照
|
||
|
||
| 依赖 | 启用者 | 当前声明 |
|
||
|------|--------|---------|
|
||
| `tokio`(features = `rt, rt-multi-thread, sync, time, macros, process, io-util`) | llm, tools, memory | `optional = true` |
|
||
| `reqwest`(features = ["json", "stream"]) | provider-*, tools-mcp | `optional = true` |
|
||
| `rusqlite`(features = ["bundled"]) | memory-sqlite | `optional = true` |
|
||
| `tracing-subscriber`(features = ["env-filter"]) | tracing-init | `optional = true` |
|
||
| `tokio-stream` | llm | `optional = true` |
|
||
| `futures` | tools | `optional = true` |
|
||
| `futures-util` | llm, provider-*, agent | `optional = true` |
|
||
| `futures-core` | llm | `optional = true` |
|
||
| `bytes` | provider-openai, provider-anthropic | `optional = true` |
|
||
| `async-stream` | llm | `optional = true` |
|
||
| `tokio-util`(features = ["rt"]) | tools | `optional = true` |
|
||
| `time`(features = ["serde","parsing","formatting","macros"]) | memory, memory-sqlite | `optional = true` |
|
||
|
||
**始终编译**(轻量依赖,不参与 feature 门控):`serde`、`serde_json`、`thiserror`、`async-trait`、`tracing`
|
||
|
||
### CI 测试矩阵(已实施)
|
||
|
||
```yaml
|
||
# .github/workflows/ci.yml
|
||
name: CI
|
||
on: [push, pull_request]
|
||
env:
|
||
RUSTFLAGS: "-D warnings"
|
||
jobs:
|
||
test-matrix:
|
||
strategy:
|
||
fail-fast: false
|
||
matrix:
|
||
features:
|
||
- "full"
|
||
- "light"
|
||
- "chat,provider-openai"
|
||
- "chat,provider-openai,tools-mcp"
|
||
- "multi,provider-openai"
|
||
- "multi,provider-openai,tools-mcp"
|
||
runs-on: ubuntu-latest
|
||
timeout-minutes: 15
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||
with:
|
||
toolchain: nightly
|
||
- run: cargo test --no-default-features --features "${{ matrix.features }}" --lib
|
||
clippy:
|
||
runs-on: ubuntu-latest
|
||
timeout-minutes: 15
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||
with:
|
||
toolchain: nightly
|
||
- run: cargo clippy --all-features --lib -- -D warnings
|
||
format:
|
||
runs-on: ubuntu-latest
|
||
timeout-minutes: 10
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||
with:
|
||
toolchain: stable
|
||
- run: cargo fmt --check
|
||
examples:
|
||
runs-on: ubuntu-latest
|
||
timeout-minutes: 15
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||
with:
|
||
toolchain: nightly
|
||
- run: cargo test --features "full"
|
||
```
|
||
|
||
**关键设计决策**:
|
||
- 矩阵使用 `--lib` 避免 examples 编译干扰模块测试验证
|
||
- `RUSTFLAGS=-D warnings` 强制零警告
|
||
- format job 使用 stable toolchain(`cargo fmt --check` 无需 nightly)
|
||
- 独立 `examples` job 验证所有 example 在完整 features 下编译
|
||
- 每个 job 设置 `timeout-minutes` 兜底
|
||
|
||
---
|
||
|
||
返回总入口:[`roadmap.md`](./roadmap.md)
|