徐涛
|
34eec9f546
|
feat(engine): 实现 Agent 执行引擎(SessionManager + Checkpointer + SessionSnapshot)
Phase 17 主体交付:解决 v0.2 中 session 在变量里、无父子关系、无 checkpoint、
不可序列化的空白。
新增模块 src/engine/(5 文件,约 1300 行纯实现 + 21 个内联测试):
- error.rs(46 行)—— EngineError 枚举(6 变体)
- SessionNotFound / SessionAlreadyExists / CheckpointNotFound
- Memory(#[from] MemoryError) 透传(与 AgentError 风格一致)
- Serialization / Agent(#[from] AgentError)
- snapshot.rs(36 行)—— SessionSnapshot + SessionMemoryEntry
- 独立 struct 避开 Arc<dyn Agent> 不可序列化限制
- SessionMemoryEntry 保留 value/metadata/created_at 完整信息
- 所有字段 #[serde(default)] 宽松反序列化保证前向兼容
- checkpointer.rs(377 行)—— Time-travel 检查点管理器
- checkpoint() / rollback_load() / list_checkpoints() / delete_all() / latest_snapshot()
- 存储 key:ckpt:{session_id}:{ckpt_id}
- ckpt_id 纳秒+计数器(无外部依赖,ponytail)
- CkptMeta.created_at_nanos 字段确保同秒内精确降序
- 6 个内联测试覆盖 roundtrip / 不存在 ckpt / 降序排序 / delete_all 幂等 /
latest_snapshot / 跨 session 隔离
- session_manager.rs(906 行)—— SessionManager 会话树管理
- 内部 RwLock<HashMap> + Arc<tokio::sync::Mutex<AgentSession>> 双重锁
- create / create_child / get / recover / replace / children / parent /
destroy / submit_turn / submit_turn_stream / finalize_turn_stream 共 11 个公开方法
- SessionManagerConfig.auto_checkpoint 默认 true(同步写入 +
tracing::error! 失败不阻断主流程,不提供强持久化保证)
- 孤儿策略:destroy 不递归删除子 session;父被销毁后 parent() 返回 None
- create_child 限制:父 session 必须先 get/recover 到内存(bundle 不可序列化)
- 15 个内联测试覆盖 CRUD / recover / replace / 树形 / 孤儿 / auto_checkpoint 开关 /
序列化兼容性 / 幂等 / 10 并发创建
- mod.rs(20 行)—— 统一 pub use 重导出 EngineError / SessionManager /
SessionManagerConfig / Checkpointer / CkptMeta / SessionSnapshot /
SessionMemoryEntry
AgentSession 扩展(src/agent/session.rs,+152 行):
- to_snapshot() pub async —— 从 MemoryStore 拍平 session_memory 全量数据
- from_snapshot() pub fn Result —— 纯同步构造器(pending_memory_restore 暂存)
- restore_memory() pub async &mut self —— 写回持久层并清空 pending
- has_pending_memory_restore() —— 查询 pending 状态
- pub(crate) fn bundle() —— accessor 供 SessionManager::create_child 继承
SessionMemory 扩展(src/agent/session_memory.rs,+57 行):
- list_entries() —— 返回 Vec<(key, value, metadata, created_at_unix_secs)>
- set_with_meta() —— 保留 metadata/created_at 写入(供 restore_memory 完整恢复)
src/lib.rs —— pub mod engine 声明
examples/engine_demo.rs(+251 行):
端到端演示 create → submit_turn → checkpoint → list_checkpoints →
rollback_load → from_snapshot → restore_memory → replace → destroy 完整链路,
含 rollback 一致性 assert(turn_index 和 cost 恢复到 checkpoint 时刻)。
零新外部依赖(serde_json 已有)。全量 353 → 374(+21 新测试)。
clippy 0 警告,doc 0 warning,example exit 0。
Phase 17: Agent 执行引擎 — Step 2-7(合并提交)
|
2026-07-15 08:59:46 +08:00 |
|
徐涛
|
1d51dcdfe0
|
feat(core): 为 CostTracker/ContextSlot/MergeStrategy 加 Clone+Serialize+Deserialize
Phase 17 前置 derive 改动:
- CostTracker 加 Clone + Serialize + Deserialize(3 行)—— 用于 SessionSnapshot
序列化 cost_so_far 字段
- ContextSlot 加 Serialize + Deserialize(1 行)—— 用于 SessionSnapshot
序列化 slots HashMap
- MergeStrategy 加 Serialize + Deserialize(1 行)—— 与 ContextSlot 一致
零破坏性:派生仅为新增能力,不修改现有行为。ContextSlot 的 save()
路径独立序列化 messages/meta/config,不走整体 serde,两组路径可共存。
Phase 17: Agent 执行引擎 — Step 1
|
2026-07-15 08:58:43 +08:00 |
|
徐涛
|
cc1c68b69d
|
feat(agent): 实现摘要自动生成(SummaryConfig + 内联检查点)
SummaryConfig 6 字段配置(trigger_token_ratio / max_context_tokens /
summary_prompt / debounce_turns / summary_model / max_tool_result_chars),
AgentBuilder 链式 summary_config();AgentSession 在 submit_turn /
finalize_turn 的 OnTurnEnd 之后内联检查点:水位 + 防抖(首次不受
约束)→ 独立 LlmCycle 调 submit_messages 生成摘要 → 写入
FocusedConfig.summary_override + slot.save() + SessionMemory 全局快照。
should_summarize 接收 current_turn 参数避免流式路径 turn_index 偏差;
format_messages_as_text 简洁版格式化含 30K 整体截断保留最新;空消息
守卫直接返回空串。所有错误静默 tracing::error!,成功路径
tracing::info!。
src/agent/summary.rs 新增 ~240 行;agent/session.rs +428 行(双路径
检查点 + 关联函数 + 测试 + 公开 API)。零新外部依赖。全量 335 → 353
测试(+18 新测试),clippy 0 警告,doc 0 warning。两轮审查 PASS——
第一轮 PM/SA 修复 11 项,第二轮 Code Reviewer 修复 9 项(含 🔴
generate_summary 空消息 bug + 🟡 5 项 + 💭 2 项)。方案文档 docs/
22-phase16-summary-auto-generation.md(471 行);roadmap.md 标记
Phase 16 完成 + M12 里程碑达成。
|
2026-07-10 06:43:06 +08:00 |
|
徐涛
|
32d886f870
|
feat(memory): 新增 VectorStore 抽象与 RagPipeline 持久化管线
- 新增 src/memory/vector_store.rs(约 660 行):
- VectorStore trait:批量 add / search / remove + add_one 默认实现
- InMemoryVectorStore:Mutex<HashMap> + 余弦全量扫描(锁内克隆、锁外计算)
- PersistentVectorStore:MemoryStore 包装,JSON blob 持久化,先持久化后内存
- RagPipeline:split → embed → store 组合器(具体 struct,非 trait)
- 22 个内联测试覆盖 InMemory(10)/ Persistent(6)/ RagPipeline(4)/ 性能基准(2)
- 性能断言:search 10K 条 <100ms,PersistentVectorStore::new 加载 <500ms
- 标记 VectorRetriever / InMemoryVectorRetriever 为 #[deprecated(since="0.3.0")]
- memory.rs 追加 VectorStore 等 4 个类型的 re-export
- document_demo 从手动 VectorRetriever 循环迁移到 RagPipeline 两行调用
- 零新增外部依赖
|
2026-07-09 16:51:29 +08:00 |
|
徐涛
|
d4c4d8fa3c
|
feat(document): 实现 Document 类型与 RecursiveCharacterSplitter 分割器
新增 Phase 14 核心模块,为 RAG 管线提供 split → embed 阶段的底层支撑。
新增内容:
- Document 类型(id/content/metadata/mime_type 四字段 + new/from_raw 构造器)
- RecursiveCharacterSplitter(两阶段算法:按 separator 优先级递归分割 + 贪心合并 overlap 滑动窗口)
- Embedding trait(异步向量化抽象,复用 LlmError)+ MockEmbedding(sin-hash 零依赖伪随机实现)
- 19 个 Document 单元测试 + 6 个 Embedding 单元测试
- document_demo 示例(Document → Splitter → MockEmbedding → InMemoryVectorRetriever 端到端演示)
模块注册:
- src/lib.rs: pub mod document + pub use Document
- src/llm.rs: pub mod embedding
设计文档:docs/20-phase14-document-and-embedding.md(1417 行,含背景/调研/方案对比/实施计划)
零新外部依赖,所有长度比较以 Unicode 字符为单位(chars_len),CJK 文本行为正确。
|
2026-07-09 13:08:35 +08:00 |
|
徐涛
|
c36668071e
|
fix(agent): Phase 9 实施审查修复
- cycle.rs: run_tool_loop 实现 PreRequest hook(之前 `let _ = hook_executor.as_ref()` 是空操作,
导致 hook-based logging/monitoring 在流式工具循环中失效;现在与 submit_with_tools 行为对齐,
含 should_block 检查,阻断时通过 StreamEvent::Error 事件化)
- session.rs: 删除 submit_turn_stream 末尾的 `let _ = hook_executor;` 死代码(Arc 引用生命周期
由 Arc 自动管理)
- session.rs: 新增 2 个集成测试覆盖方案 §4 Step 5:
- submit_turn_stream_end_to_end:mock provider → 消费流 → finalize_turn 后 cost_so_far
正确更新(10/5 tokens)+ turn_index=1 + default slot 包含 user/assistant 消息
- submit_turn_stream_triggers_turn_hooks:OnTurnStart 在 submit_turn_stream 返回流前
触发(计数=1)+ OnTurnEnd 在 finalize_turn 前不触发(计数=0)+ finalize_turn 后触发(计数=1)
- docs/16-phase9-streaming-experience.md: 标注 finalize_turn Phase 10 签名变更(new_messages_from_cycle
+ Result 返回),Step 5 测试实现位置
- 测试 288 passed / 0 failed(基线 286 + 2 新增),clippy 0 警告,doc 0 warning
|
2026-07-08 23:19:24 +08:00 |
|
徐涛
|
d4f27b5865
|
refactor(types): 删除旧类型文件和 ChatResponse
- 删除 src/llm/types/old_stream.rs(45 行,LegacyStreamEvent 内部死代码)
- types/mod.rs 删除 pub mod old_stream; 与 ChatResponse 结构体定义
- 前置验证 A 通过:parse_chunk_stream / map_legacy_to_ir / LegacyToIrEventStream /
ChunkToLegacyEventStream / LegacyStreamEvent 零外部调用方
- 前置验证 B 通过:cargo doc --no-deps 中无 ChatResponse 引用
- cycle.rs:88 的 #[allow(deprecated)] 保留(LlmCycle impl 中无 ChatResponse 引用,
与 ChatResponse 无关;按方案文档"若不相关则无需改动"原则保留原状)
- stream.rs 已在 Step 13.2 commit 中同步简化为 module doc + pub use
- 同步更新 docs/roadmap.md:Phase 13 状态 ⏳→✅,M9 里程碑 + 完成日期,
Mermaid 依赖图 P13 pending→done,"下一步"指向 Phase 14
- Breaking Change:agcore::llm::types::ChatResponse 已删除
(v0.1.0 起标记 #[deprecated],请改用 MessageResponse)
|
2026-07-08 22:59:31 +08:00 |
|
徐涛
|
1c0e1e0ed1
|
refactor(types): response.rs 类型移入 provider/openai.rs
- 删除 types/response.rs(177 行)
- 所有 OpenAI wire-format 响应类型迁入 provider/openai.rs,可见性 pub(crate):
TokenLogprob / TopLogprob / Logprobs / URLCitation / Annotation / OpenaiAudio /
Choice / OpenaiChatResponse / Delta / ChunkChoice / OpenaiChatChunk
- From<OpenaiChatMessage> for Delta 与 From<OpenaiChatResponse> for OpenaiChatChunk
同步迁入 openai.rs
- types/mod.rs 删除 pub mod response; 与对应 re-export
- convert_response 同步降级为 pub(crate) 以匹配 OpenaiChatResponse 可见性
- stream.rs: OpenaiChatChunk import 路径改为 crate::llm::provider::openai
- stream.rs 同步简化为 module doc + pub use 重导出(合并 Step 13.3 的清理动作,
避免遗留 dead_code 警告来回)
- mod.rs: ChatResponse 的两个 From impl 同步删除(impl 内引用的 OpenaiChatResponse
/ OpenaiChatChunk / Delta / ChunkChoice 已不在 types 模块),结构体保留到 Step 13.3
- 公共 re-export 路径 agcore::llm::types::OpenaiChatResponse/Chunk 等已删除
(Breaking Change,见 CHANGELOG)
|
2026-07-08 22:58:18 +08:00 |
|
徐涛
|
760de46623
|
refactor(types): request.rs 类型移入 provider/openai.rs
- 删除 types/request.rs(187 行)
- 所有 OpenAI wire-format 类型迁入 provider/openai.rs,可见性 pub(crate):
StreamOptions / OpenaiTool / AudioParam / PredictionContent / UserLocation /
Approximate / WebSearchOptions / OpenaiChatRequest
- types/mod.rs 删除 pub mod request; 与对应 re-export
- convert_request 同步降级为 pub(crate) 以匹配 OpenaiChatRequest 可见性
- 公共 re-export 路径 agcore::llm::types::OpenaiChatRequest 等已删除(Breaking Change,见 CHANGELOG)
|
2026-07-08 22:55:17 +08:00 |
|
徐涛
|
f8df6a9421
|
refactor(types): ToolChoice 移入 tool.rs
- ToolChoice 枚举与 serde impl 从 types/request.rs 迁入 types/tool.rs
- mod.rs re-export 从 request::ToolChoice 改为 tool::ToolChoice(公共 agcore::llm::types::ToolChoice 路径保持不变)
- request_v2.rs import 路径更新为 crate::llm::types::tool::ToolChoice
- OpenaiChatRequest 字段类型引用更新为 super::tool::ToolChoice(Step 13.1 删除 request.rs 后此临时 import 同步消除)
|
2026-07-08 22:53:46 +08:00 |
|
徐涛
|
802518b5fe
|
feat(agent): 实现 ContextSlot fork/merge
- 新增 MergeStrategy 枚举(#[non_exhaustive],为 Phase 16 Summarize 预留)
- 新增 ContextSlot::fork() 从父 slot 派生独立子 slot(Full / Focused 策略)
- 新增 ContextSlot::merge() 将子 slot 消息合入父 slot(Append / Replace 策略)
- 防御性检查:禁止 self-merge、跨 session merge、合并到 Readonly slot
- 重构 AgentSession::derive_slot 复用 fork() 消除重复代码
- 新增 9 个内联测试覆盖 fork/merge happy path 与 error path
- agent.rs 追加 MergeStrategy re-export(agcore::agent::MergeStrategy 路径可用)
|
2026-07-08 22:52:38 +08:00 |
|
徐涛
|
71abe881ed
|
feat(core): 完成 Phase 11 测试与检索补强
- 新增 VectorRetriever trait 与 InMemoryVectorRetriever 引用实现
- 补充 Provider roundtrip wiremock 测试与 MemoryStore 并发测试共 23 个
- 修复 openai 429 retry-after header 解析(与 anthropic 对齐)
|
2026-07-06 14:52:49 +08:00 |
|
徐涛
|
635942248b
|
feat(core): 新增 Phase 10 ContextSlot 多上下文分区管理
- 新增 ContextSlot 类型(Full / Focused / Readonly 三种模式,
New / Derived / Static 三种来源),支持 JSON blob 批次持久化
- AgentSession 新增 slots 字段与 5 个管理方法
(create_slot / switch_slot / list_slots / derive_slot / delete_slot),
自动创建 "default" slot
- submit_turn / finalize_turn 改造为基于当前 slot 的增量追加写回,
确保 Focused 模式"读时过滤"语义不丢失数据
- finalize_turn 签名变更(新增 new_messages_from_cycle 参数,
返回 Result<(), AgentError>),向后兼容列于 docs/17
- 新增 3 个 AgentError 变体(SlotReadonly / SlotNotFound / SlotAlreadyExists)
- 新增分支对话示例 context_slot_demo(法律咨询→两个派生方向→切换→隔离验证)
- 新增 43 个测试覆盖持久化、Focused 过滤、Readonly 阻断、delete 保护、
派生逻辑、流式 finalize_turn、key 注入防护等场景
- 方案文档:docs/17-phase10-contextslot.md(含 §5 推荐方案、§6 实施建议、
§9 实施计划,经过 4 轮方案/计划/实施审查 + 1 轮非阻塞建议修复)
|
2026-07-06 09:46:04 +08:00 |
|
徐涛
|
212cfcc916
|
feat(core): 新增 Phase 9 流式体验增强 submit_turn_stream
- 新增 StreamEvent::ToolExecutionStarted/Completed 变体(apply_to 元事件)
- 新增 LlmCycle::submit_with_tools_stream + run_tool_loop(spawn + mpsc 状态机)
- 新增 AgentSession::submit_turn_stream + finalize_turn(手动同步状态)
- CycleConfig 加 Clone derive
- 新增 9 个单元测试 + 2 个集成测试(211 passed)
- clippy 0 警告,存量 0 回归
docs: 追加 Phase 9 实施方案(docs/16-phase9-streaming-experience.md)
|
2026-07-05 23:37:37 +08:00 |
|
徐涛
|
5b4343a051
|
refactor(agent): StepStatus::Completed 切换至 MessageResponse
StepStatus::Completed 字段类型从废弃的 ChatResponse 切换为 IR 层
MessageResponse,同时清理 task_agent_demo.rs 的 3 处废弃类型引用:
- ChatResponse → MessageResponse (字段映射见 §3.1.2)
- OpenaiChatMessage::assistant_text(t) → Message::assistant(t)
- FinishReason::Stop → StopReason::Stop (Option 包裹同步移除)
移除 src/agent/task.rs 的两处 #[allow(deprecated)] 与
examples/task_agent_demo.rs 顶部 #![allow(deprecated)],零
deprecated warning。
验收: cargo build + clippy -D warnings + test --all-targets 全绿;
cargo run --example task_agent_demo exit 0。
|
2026-07-05 19:48:59 +08:00 |
|
徐涛
|
6e1182e64c
|
feat(core): 14 个公开枚举标记 #[non_exhaustive]
为 v0.2.0-rc.1 API 稳定性收尾。覆盖:
- P0 核心 IR: Message / ContentBlock / ContentBlockType / StreamEvent / HookEvent
- P0 Error: AgentError / LlmError / ToolError / MemoryError / PromptError
- P1 其他: MemoryStrategy / StepStatus / ToolChoice / ResponseFormat
明确不加的: 内部 wire-format (OpenaiChatMessage 等) /
语义已收敛 (Role/ServiceTier 等) / 使用面窄 (Permission 等)。
示例侧的 3 处 Message exhaustive match (prompt_composer /
conversation_memory_demo) 补全 `_` 通配分支,零行为变化。
验收: cargo build + clippy -D warnings + test --all-targets 全绿 (200 passed)
|
2026-07-05 19:47:03 +08:00 |
|
徐涛
|
c82af60f81
|
feat(memory): 实现 SqliteStore 持久化
- 新增 src/memory/store/sqlite_store.rs(SqliteStore + 9 个内联测试)
- 基于 rusqlite 0.32(bundled),使用 Arc<Mutex<Connection>> + spawn_blocking
- WAL 模式 + synchronous=NORMAL + busy_timeout=5s + PRAGMA user_version
schema 版本管理
- created_at 归一化为 UTC 的 RFC 3339 TEXT,字典序等价时间序
- 错误精细映射:SqliteFailure/InvalidQuery → InvalidInput;
FromSqlConversionFailure → Serialization;其他 → Storage
- 9 个测试覆盖 CRUD、upsert、prefix/since/offset+limit 过滤、
10 写者 × 10 次并发、持久化 round-trip、trait-box 互换兼容性
依赖:
- rusqlite = { version = "0.32", features = ["bundled"] }
- time 增补 features: parsing, formatting, macros
- dev-dependencies: tempfile = "3"
测试:199 → 200 pass(191 原有 + 9 新增)
|
2026-07-05 17:13:28 +08:00 |
|
徐涛
|
c8a91f6eaf
|
refactor(memory): 将 store.rs 拆分为模块目录,仅结构搬移
- 将 src/memory/store.rs 单体文件拆分为模块根 + store/ 目录结构
- InMemoryStore(struct + impl + Default + 6 个内联测试)整体提取到
src/memory/store/in_memory.rs
- store.rs 保留 MemoryStore trait 与 EvictionPolicy/EvictionConfig
- 外部消费者导入路径 crate::memory::store::MemoryStore 不变
|
2026-07-05 17:09:45 +08:00 |
|
徐涛
|
4cf5918b9c
|
refactor(llm): 移除 ToolDefinition 别名与遗留 deprecation 抑制点
完成 ToolDef IR 切换的最后清理:移除 ToolDefinition 别名与
OpenaiToolDefinition 的公共 re-export;各调用点(cycle/registry/mcp/agent)
直接使用 ToolDef 并清理对应的 #[allow(deprecated)] 抑制点;新增
roundtrip 测试验证 ToolDef 序列化兼容性。
|
2026-07-05 10:32:35 +08:00 |
|
徐涛
|
9da9b83167
|
feat(llm): 切换至 ToolDef IR 并适配 OpenAI Provider
将 MessageRequest.tools 切换为 Provider 无关的 ToolDef IR;
ToolDefinition 别名切换指向 ToolDef,registry/mcp 构造去掉
strict 字段;OpenAI 适配层通过 From 转换将 ToolDef 转为
OpenaiToolDefinition wire format。Anthropic 适配层字段名一致
无需改动,openai_compat/ollama 委托 GenericOpenaiProvider 无影响。
|
2026-07-05 10:14:32 +08:00 |
|
徐涛
|
b1875192fd
|
feat(llm): 引入 ToolDef IR 类型
新增 Provider 无关的工具定义中间表示 ToolDef,配套实现双向 From 转换;
旧 OpenaiToolDefinition 标记 doc(hidden)。本次仅新增类型,不影响现有
代码路径。
|
2026-07-05 10:06:52 +08:00 |
|
徐涛
|
5648b1d217
|
style(tools, llm): 统一导入顺序与代码格式
|
2026-07-05 08:19:13 +08:00 |
|
徐涛
|
98dfe6c1ed
|
feat(llm): 完成 Phase 5 热身准备(Ollama / non_exhaustive / ProviderConfig)
Phase 5 三个 Step 全部落地:
Step 5.2 — Ollama Provider
- 新增 OllamaProvider newtype 包装(默认 localhost:11434/v1,零 API key)
- ProviderType 新增 Ollama 变体与 FromStr 解析
Step 5.3 — #[non_exhaustive] 前置标记
- ProviderType / StopReason / FinishReason / EvictionPolicy 加 #[non_exhaustive]
- 编译期兼容护栏,避免下游 silent break
Step 5.1 — ProviderConfig 扩展
- 加 timeout_secs / max_retries 字段、Default、from_env(prefix)
- create_provider 各分支通过 pub(crate) from_parts 一次性构造并注入 timeout
(同时避开 Anthropic 的 default_headers 与双重 client 构造)
- map_reqwest_error 改为方法读取 self.timeout_secs(移除硬编码 120s)
- AnthropicProvider::with_timeout 同值短路,with_client 标 #[deprecated]
- DeepSeek / Qwen 加公开 with_client,new_with_client 走代理
- 7 个新测试:5 个 from_env 单元测试 + 3 个 timeout 传导 wiremock
(OpenAI Chat / DeepSeek / Anthropic)
- Cargo.toml 加 temp-env dev-dep
|
2026-07-05 08:12:40 +08:00 |
|
徐涛
|
602bd43fce
|
fix(llm,docs): 修复 Phase C 审查发现的两个警告
- LlmError::Request 变体补可操作建议:请检查 Provider 端点地址(base_url)和网络连通性
- README.md Mermaid 依赖图删除 Agent --> Prompt 边(编译级不存在)
- README.md 依赖规则文本同步:明确 agent 实际编译依赖为 llm/tools/memory,与 prompt 无直接依赖(system prompt 以 &str 传入)
参考审查:PM Director + SA Director 对 Phase C 的联合审查结论
|
2026-07-04 06:35:21 +08:00 |
|
徐涛
|
4fdc62754c
|
feat(errors): 错误消息面向最终用户友好化
- memory::MemoryError 英文 → 中文 + 操作建议(namespace 拼写 / 后端存储 / 数据兼容性)
- llm::LlmError 各变体补充修复建议(API key / 超时 / 上下文压缩)
- tools::ToolError 各变体补充修复指引(注册工具 / 检查 Schema / 调权限 / MCP 握手)
- prompt::PromptError 各变体补充修复指引(注册子模板 / 检查语法 / 调深度限制)
- agent::AgentError::Config 中文化 + 提示需调用的 builder 方法名
|
2026-07-04 06:21:31 +08:00 |
|
徐涛
|
7b2d2db322
|
feat(llm): 公开 MockProvider 并修复测试与 API 一致性
- 新增 src/llm/mock.rs:公开 MockProvider,实现 chat 与 chat_stream
(chat_stream 从 MessageResponse 拆解为 StreamEvent 序列),含 5 个内联测试
- src/llm.rs 注册 pub mod mock,供示例与外部 crate 引用
- src/agent/session.rs 测试改用 crate::llm::mock::MockProvider,
删除内嵌私有副本,统一公开路径
- src/prompt.rs re-export validate_messages,与 PromptComposer 对齐公开路径
|
2026-07-03 15:50:39 +08:00 |
|
徐涛
|
c084c57e2c
|
refactor(core): 扫清 v0.1 Phase A 技术债
- 修复测试编译回归:补全 session.rs/cycle.rs 测试模块导入;
convert.rs 2 处 irrefutable if let 改为 let
- composer.rs 迁移至 IR:OpenaiChatMessage → Message,
ContentField/OpenaiContentPart → ContentBlock;删除 set_message_name
和 build_request;developer 消息映射为 Message::System
- knowledge.rs 锁修复:std::sync::Mutex → tokio::sync::Mutex;
search() 优化锁粒度(锁内仅 clone IDs,避免锁内异步 IO)
- 标记 ChatResponse / ToolDefinition 为废弃(#[deprecated(since = "0.1.0")]),
内部使用点加 #[allow(deprecated)] 抑制警告
- clippy 清零:合并冗余 if、手动 strip_prefix 改 strip_prefix、
多处 dead_code 抑制、测试代码清理
|
2026-07-03 15:19:37 +08:00 |
|
徐涛
|
e54edbc037
|
feat(agent): 移除未使用的导入并简化条件表达式
|
2026-07-03 13:55:24 +08:00 |
|
徐涛
|
9e4f50c955
|
feat(llm): LlmCycle 切换 IR 消息类型,移除 Phase 0 桥接层
核心改动:
- LlmCycle.messages 从 Vec<OpenaiChatMessage> 切换为 Vec<Message>,
移除 Phase 0 引入的 chat_message_to_message / message_to_chat_message
转换函数
- 移除 LlmCycle.system_prompt 字段(FIX-D),调用方通过
Message::system_text() + with_messages() 管理系统提示;
with_system_prompt() 标记 #[deprecated] 保留为过渡期 shim
- submit_stream 简化(FIX-E):Item = StreamEvent 不再带 Result 包装,
错误用 StreamEvent::Error 传出;self.messages 不再自动 push_message,
调用方在收到 MessageComplete 后手动调用 cycle.push_message()
- compact.rs 适配 Message 类型 + ContentBlock 估算;microcompact
跳过 is_error:true 的 ToolResult(FIX-F),保留 LLM 错误诊断
- ConversationMemory 持久化从 OpenaiChatMessage 切换为 Message
- ToolInvocation 增加 tool_call_id 字段(FIX-A),
invoke/invoke_all 签名增加 tool_call_id 参数
调用方迁移:
- AgentSession::submit_turn 用 Message::system_text() + with_messages()
- simple_visit example 同步迁移
测试 177 passed / 0 failed(compact 新增 5 个单元测试覆盖 FIX-F + 估计全变体)。
|
2026-07-02 22:48:00 +08:00 |
|
徐涛
|
a74c24b6fe
|
feat(llm): 重写 Provider 适配层,支持 OpenAI Chat / Anthropic / DeepSeek / Qwen
重写 OpenaiChatProvider:移除 Phase 0 临时桥接,实现真实流式状态机
(ContentBlockStart / *Delta / ContentBlockEnd / ToolCallEnd),
MessageComplete.full_response 由 PartialMessageResponse::finalize 产出。
新增 AnthropicProvider:实现 Messages API + SSE 事件序列
(message_start → content_block_start → content_block_delta →
content_block_stop → message_delta → message_stop),
529(overloaded)映射为 RateLimit;thinking signature 由
partial.set_thinking_signature 内部写入。
新增 DeepSeekProvider / QwenProvider:OpenAI-compatible 协议的
newtype 包装,共享 GenericOpenaiProvider 的 HTTP / SSE / 转换逻辑;
Qwen 通过 extra_headers 注入 X-DashScope-SSE: enable。
新增 convert.rs 公共转换模块:从 Phase 0 cycle.rs / Phase 0
OpenaiProvider 桥接层提取 from_openai / to_openai /
content_to_blocks / blocks_to_content,避免跨 Provider 重复逻辑。
新增 wiremock dev-dependency + 14 个集成测试:
- OpenaiChatProvider:基础文本 / 401 / 500 / 流式 MessageComplete
- AnthropicProvider:基础 / 401 / 529 / 流式 SSE 序列 / max_tokens 默认值
- DeepSeek / Qwen:基础文本响应
171 个测试全部通过(之前 157,新增 14)。
|
2026-07-02 22:24:30 +08:00 |
|
徐涛
|
7c299f1cfd
|
feat(llm): 新增 IR 类型层 + 切换 LlmProvider trait 签名
引入跨 Provider 统一的新类型系统:
- Message 扁平大枚举(System/User/UserImage/Assistant/ToolResult)
- MessageRequest + MessageResponse + StreamEvent(高精度 IR)
- PartialMessageResponse 含 apply_to/finalize 汇聚算法
- ProviderType enum 扩展 + ProviderCapabilities
切换 LlmProvider trait 签名为 chat(MessageRequest) → MessageResponse,
chat_stream 返回 Stream<Item = Result<StreamEvent, LlmError>>,新增 capabilities()。
StreamEvent 命名冲突处理:旧变体迁移至 old_stream::LegacyStreamEvent,
stream.rs 通过 pub use 重新导出新高精度事件。
OpenaiProvider 添加 Phase 0 临时桥接(MessageRequest ↔ OpenaiChatRequest 转换),
标注 ponytail: Phase 0 临时桥接 标记,Phase 1 重写时移除。
测试 147 passed / 0 failed(新增 31 个新类型测试)。
|
2026-07-02 21:58:07 +08:00 |
|
徐涛
|
ce1f1aaca0
|
feat(agent): 实现 Phase 4c 会话级记忆功能
- 新增 `SessionMemory` 结构体,基于 `MemoryStore` 按 namespace 隔离键值数据
- `AgentBuilder` 增加 `session_memory_backend` 配置入口
- `RuntimeBundle` 透传 `session_memory_backend` 字段
- `AgentSession` 将内联 `HashMap` 替换为完整的 `SessionMemory`,`set_session_data` 和 `get_session_data` 改为异步方法
- 新增 3 个内联测试,全量测试从 113 增至 116,clippy 0 警告
|
2026-06-11 22:14:15 +08:00 |
|
徐涛
|
4de7db0b2c
|
docs(roadmap): 更新 Phase 4b 状态为已完成
|
2026-06-11 21:57:10 +08:00 |
|
徐涛
|
2b189880a9
|
feat(agent): 实现 Agent Runtime 核心胶水层 (Phase 4a)
- 添加 Agent trait、AgentSession、RuntimeBundle、AgentBuilder
- 添加 Plan/Step/StepStatus 任务规划数据结构
- 添加 AgentError 统一错误类型(聚合 LlmError/ToolError/MemoryError)
- 实现 submit_turn 单轮对话流程(含 hook 触发与 cost 累计)
- 扩展 LlmCycle 支持 Arc<dyn LlmProvider>
- 扩展 HookEvent 添加 OnTurnStart/OnTurnEnd
- 更新 roadmap 状态
|
2026-06-11 21:45:28 +08:00 |
|
徐涛
|
2ecc0b4001
|
feat(memory): 添加记忆系统模块
|
2026-06-08 08:42:43 +08:00 |
|
徐涛
|
b6e7acfb0f
|
feat(tools): 添加工具系统框架与 MCP 协议客户端
|
2026-06-07 10:57:15 +08:00 |
|
徐涛
|
993ae0eb4b
|
feat(prompt): 添加提示词工程模块并扩展LLM周期接口
新增 `prompt` 模块,包含模板引擎、组合器和错误类型,同时在`LlmCycle`中增加直接操作消息历史的方法和`submit_messages`接口
|
2026-06-03 06:18:16 +08:00 |
|
徐涛
|
32f3edaf19
|
feat(llm): 实现 Phase 0 剩余四个模块
实现 ProviderRegistry、HookExecutor、StreamEvents 和 Auto-compaction 模块,并集成到 LlmCycle 中
|
2026-06-02 08:51:42 +08:00 |
|
徐涛
|
af5a580b5e
|
feat(llm): 添加 Provider 工厂方法和枚举类型
- 新增 `ProviderType` 枚举和 `FromStr` 解析,支持通过环境变量选择 Provider
- 新增 `ProviderConfig` 结构体和 `create_provider` 工厂方法,统一 Provider 创建
- 更新示例代码使用新的工厂模式,移除直接实例化 OpenaiProvider 的方式
- 移除 Assistant 消息中未使用的 `reasoning_content` 字段
|
2026-05-14 13:15:30 +08:00 |
|
徐涛
|
28635e28d5
|
feat(llm): 添加 tracing 日志与 ContentField 扩展
为 OpenAI 消息类型引入 ContentField 以支持 string 和 array 两种 content 格式,新增 reasoning_content 字段;添加 tracing 日志初始化函数及请求
/响应日志;修正多处文件末尾换行与 import 顺序。
|
2026-05-14 09:00:22 +08:00 |
|
徐涛
|
e22c176643
|
feat(llm): 替换 ToolChoice 的自动派生为手动序列化
处理自定义 JSON 序列化逻辑,支持字符串值(`none`/`auto`/`required`)和对象格式(`{"type":"function","function":{"name":"..."}}`)。反序列化时向前兼容两种格式。
|
2026-05-14 08:36:08 +08:00 |
|
徐涛
|
a4b7b3b9f9
|
feat(llm): 重构 types.rs 为完整的 OpenAI 兼容类型系统
将 `types.rs` 拆分为模块化目录,所有类型派生 `Serialize/Deserialize`,
并新增 `OpenaiChatChunk`、`Role` 扩展等 30+ 缺失类型
消除对 `cycle/usage.rs` 的反向依赖,`Usage`/`CostTracker` 移至 `types/usage.rs`
|
2026-05-13 20:51:05 +08:00 |
|
徐涛
|
91d32a6a82
|
feat(llm): 添加 LLM 调用周期核心模块
新增 LLM 调用生命周期引擎,包含 Provider 抽象、OpenAI 兼容实现、
可重试机制及 Token 用量追踪。移除原有的占位测试代码。
添加所需的 Rust 依赖(tokio、reqwest、serde 等)。
|
2026-05-12 06:06:24 +08:00 |
|
徐涛
|
4eb8d9511f
|
chore: 构建初始项目结构。
|
2026-05-07 09:27:04 +08:00 |
|