From e54edbc0373a6389d6e76b8eeb5f949273d81e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Fri, 3 Jul 2026 13:55:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(agent):=20=E7=A7=BB=E9=99=A4=E6=9C=AA?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E5=AF=BC=E5=85=A5=E5=B9=B6=E7=AE=80?= =?UTF-8?q?=E5=8C=96=E6=9D=A1=E4=BB=B6=E8=A1=A8=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/agent/session.rs | 3 +-- src/llm/convert.rs | 5 ++--- src/llm/cycle.rs | 2 +- src/llm/provider/anthropic.rs | 6 +++--- src/llm/provider/openai.rs | 2 +- src/llm/stream.rs | 2 +- src/llm/types/request.rs | 8 ++------ src/memory/conversation.rs | 5 ++--- src/memory/knowledge.rs | 8 +++----- 9 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/agent/session.rs b/src/agent/session.rs index 975842f..7219c96 100644 --- a/src/agent/session.rs +++ b/src/agent/session.rs @@ -15,8 +15,7 @@ use crate::agent::runtime::RuntimeBundle; use crate::agent::session_memory::SessionMemory; use crate::llm::cycle::{CostTracker, CycleConfig, LlmCycle}; use crate::llm::hooks::{HookContext, HookEvent}; -use crate::llm::types::message::{ContentBlock, Message}; -use crate::llm::types::openai_message::OpenaiChatMessage; +use crate::llm::types::message::Message; use crate::llm::types::response_v2::MessageResponse; use crate::memory::store::InMemoryStore; diff --git a/src/llm/convert.rs b/src/llm/convert.rs index ef93a4d..adc4955 100644 --- a/src/llm/convert.rs +++ b/src/llm/convert.rs @@ -178,8 +178,8 @@ pub fn content_to_blocks(field: &ContentField) -> Vec { // ponytail: 简化处理 —— URL 直接通过,data URI 拆出 // data:;base64, → ImageSource { data: b64, mime, is_url: false }。 let url = &image_url.url; - if let Some(rest) = url.strip_prefix("data:") { - if let Some((mime, b64)) = rest.split_once(";base64,") { + if let Some(rest) = url.strip_prefix("data:") + && let Some((mime, b64)) = rest.split_once(";base64,") { return Some(ContentBlock::Image { source: crate::llm::types::message::ImageSource { data: b64.to_string(), @@ -188,7 +188,6 @@ pub fn content_to_blocks(field: &ContentField) -> Vec { }, }); } - } Some(ContentBlock::Image { source: crate::llm::types::message::ImageSource { data: url.clone(), diff --git a/src/llm/cycle.rs b/src/llm/cycle.rs index 9a2ad74..0ca5fe8 100644 --- a/src/llm/cycle.rs +++ b/src/llm/cycle.rs @@ -16,7 +16,7 @@ use crate::llm::compact::{should_compact, microcompact, CompactConfig, CompactSt use crate::llm::cycle::retry::should_retry; use crate::llm::error::LlmError; use crate::llm::hooks::{HookContext, HookExecutor}; -use crate::llm::provider::{LlmProvider, ProviderCapabilities, ProviderFeatures}; +use crate::llm::provider::LlmProvider; use crate::llm::stream::StreamEvent; use crate::llm::types::message::{ContentBlock, Message}; use crate::llm::types::request_v2::MessageRequest; diff --git a/src/llm/provider/anthropic.rs b/src/llm/provider/anthropic.rs index 7220636..bfc6955 100644 --- a/src/llm/provider/anthropic.rs +++ b/src/llm/provider/anthropic.rs @@ -21,7 +21,7 @@ use tracing::{debug, error, info, warn}; use super::{LlmProvider, ProviderCapabilities, ProviderFeatures}; use crate::llm::error::LlmError; use crate::llm::types::message::{ContentBlock, ContentBlockType, Message}; -use crate::llm::types::request_v2::{MessageRequest, ThinkingConfig}; +use crate::llm::types::request_v2::MessageRequest; use crate::llm::types::response_v2::{ MessageResponse, PartialMessageResponse, PartialUsage, StopReason, StreamEvent, }; @@ -193,7 +193,7 @@ impl AnthropicProvider { .json(&body) .send() .await - .map_err(|e| Self::map_reqwest_error(e))?; + .map_err(Self::map_reqwest_error)?; let status = response.status(); if !status.is_success() { @@ -229,7 +229,7 @@ impl AnthropicProvider { .json(&body) .send() .await - .map_err(|e| Self::map_reqwest_error(e))?; + .map_err(Self::map_reqwest_error)?; let status = response.status(); if !status.is_success() { diff --git a/src/llm/provider/openai.rs b/src/llm/provider/openai.rs index 1cd269c..824b9ef 100644 --- a/src/llm/provider/openai.rs +++ b/src/llm/provider/openai.rs @@ -22,7 +22,7 @@ use serde_json::Value; use tracing::{debug, error, info}; use super::{LlmProvider, ProviderCapabilities, ProviderFeatures}; -use crate::llm::convert::{blocks_to_content, content_to_blocks, from_openai, to_openai}; +use crate::llm::convert::{from_openai, to_openai}; use crate::llm::error::LlmError; use crate::llm::types::message::{ContentBlock, ContentBlockType, Message}; use crate::llm::types::openai_message::{ContentField, OpenaiChatMessage}; diff --git a/src/llm/stream.rs b/src/llm/stream.rs index 365692c..4531494 100644 --- a/src/llm/stream.rs +++ b/src/llm/stream.rs @@ -23,7 +23,7 @@ use crate::llm::types::old_stream::LegacyStreamEvent; use crate::llm::types::response_v2::MessageResponse; use crate::llm::types::response_v2::StopReason; use crate::llm::types::usage::Usage; -use crate::llm::types::{FinishReason, OpenaiChatChunk, OpenaiToolCall}; +use crate::llm::types::{OpenaiChatChunk, OpenaiToolCall}; // 唯一的对外 `StreamEvent` 定义(高精度 IR 事件,来自 `response_v2`)。 // diff --git a/src/llm/types/request.rs b/src/llm/types/request.rs index 3746eb8..f7363c2 100644 --- a/src/llm/types/request.rs +++ b/src/llm/types/request.rs @@ -12,7 +12,9 @@ pub struct StreamOptions { } #[derive(Debug, Clone)] +#[derive(Default)] pub enum ToolChoice { + #[default] None, Auto, Required, @@ -20,12 +22,6 @@ pub enum ToolChoice { AllowedTools { tool_names: Vec }, } -impl Default for ToolChoice { - fn default() -> Self { - // Default 行为由调用方显式选择;此处选择不暴露任何工具 —— 不暴露比错暴露安全。 - ToolChoice::None - } -} impl Serialize for ToolChoice { fn serialize(&self, serializer: S) -> Result diff --git a/src/memory/conversation.rs b/src/memory/conversation.rs index a2b1e3d..9405012 100644 --- a/src/memory/conversation.rs +++ b/src/memory/conversation.rs @@ -174,8 +174,8 @@ impl ConversationMemory { } } - if let Some(ref compact_config) = self.config.compact_config { - if should_compact(&self.messages, compact_config, &self.compact_state) { + if let Some(ref compact_config) = self.config.compact_config + && should_compact(&self.messages, compact_config, &self.compact_state) { let keep_recent = compact_config.keep_recent; let freed = microcompact(&mut self.messages, keep_recent); if freed > 0 { @@ -184,7 +184,6 @@ impl ConversationMemory { let _ = self.compact_state.record_failure(); } } - } } } diff --git a/src/memory/knowledge.rs b/src/memory/knowledge.rs index 79770ea..8fca0cd 100644 --- a/src/memory/knowledge.rs +++ b/src/memory/knowledge.rs @@ -123,14 +123,12 @@ impl KnowledgeStore { let mut results = Vec::new(); let index = self.index.lock().unwrap(); for entry in index.iter() { - if entry.title.to_lowercase().contains(&needle) + if (entry.title.to_lowercase().contains(&needle) || entry.summary.to_lowercase().contains(&needle) - || entry.tags.iter().any(|t| t.to_lowercase().contains(&needle)) - { - if let Some(page) = self.get_page(&entry.id).await? { + || entry.tags.iter().any(|t| t.to_lowercase().contains(&needle))) + && let Some(page) = self.get_page(&entry.id).await? { results.push(page); } - } } Ok(results) }