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 抑制、测试代码清理
This commit is contained in:
徐涛
2026-07-03 15:19:37 +08:00
parent c2c0d498ee
commit c084c57e2c
16 changed files with 138 additions and 181 deletions
+13 -18
View File
@@ -40,15 +40,14 @@ pub fn from_openai(msg: &OpenaiChatMessage) -> Message {
let mut blocks = content_to_blocks(content);
if let Some(calls) = tool_calls {
for call in calls {
if let OpenaiToolCall::Function { id, function } = call {
let input: Value =
serde_json::from_str(&function.arguments).unwrap_or(Value::Null);
blocks.push(ContentBlock::ToolUse {
id: id.clone(),
name: function.name.clone(),
input,
});
}
let OpenaiToolCall::Function { id, function } = call;
let input: Value =
serde_json::from_str(&function.arguments).unwrap_or(Value::Null);
blocks.push(ContentBlock::ToolUse {
id: id.clone(),
name: function.name.clone(),
input,
});
}
}
Message::Assistant { content: blocks }
@@ -254,8 +253,7 @@ pub fn blocks_to_content(blocks: &[ContentBlock]) -> ContentField {
#[cfg(test)]
mod tests {
use super::*;
use crate::llm::types::message::ImageSource;
use crate::llm::types::shared::{AudioFormat, ImageDetail};
use crate::llm::types::shared::ImageDetail;
use serde_json::json;
#[test]
@@ -364,13 +362,10 @@ mod tests {
assert!(matches!(content, ContentField::String(_)));
let calls = tool_calls.expect("tool_calls");
assert_eq!(calls.len(), 1);
if let OpenaiToolCall::Function { id, function } = &calls[0] {
assert_eq!(id, "call_1");
assert_eq!(function.name, "search");
assert!(function.arguments.contains("rust"));
} else {
panic!("expected Function variant");
}
let OpenaiToolCall::Function { id, function } = &calls[0];
assert_eq!(id, "call_1");
assert_eq!(function.name, "search");
assert!(function.arguments.contains("rust"));
}
_ => panic!("expected Assistant"),
}
+9 -7
View File
@@ -21,6 +21,7 @@ use crate::llm::stream::StreamEvent;
use crate::llm::types::message::{ContentBlock, Message};
use crate::llm::types::request_v2::MessageRequest;
use crate::llm::types::response_v2::{MessageResponse, StopReason};
#[allow(deprecated)]
use crate::llm::types::{ToolChoice, ToolDefinition};
/// LLM 调用周期配置。
@@ -79,6 +80,7 @@ pub struct LlmCycle {
compact_state: CompactState,
}
#[allow(deprecated)]
impl LlmCycle {
/// 创建一个新的 LlmCycle(持有 `Box<dyn LlmProvider>` 的独占所有权)。
///
@@ -175,13 +177,10 @@ impl LlmCycle {
messages: Vec<Message>,
tools: Vec<ToolDefinition>,
) -> Result<MessageResponse, LlmError> {
let ir_messages: Vec<Message> = messages;
let ir_tools: Vec<ToolDefinition> = tools.clone();
let request = MessageRequest {
model: self.config.model.clone(),
messages: ir_messages,
tools: ir_tools,
messages,
tools,
tool_choice: ToolChoice::Auto,
max_tokens: self.config.max_tokens,
temperature: self.config.temperature,
@@ -672,6 +671,7 @@ fn truncate_tool_result(s: &str, max_bytes: usize) -> String {
#[cfg(test)]
mod tests {
use super::*;
use crate::llm::provider::{ProviderCapabilities, ProviderFeatures};
use crate::tools::{BaseTool, ToolRegistry};
use async_trait::async_trait;
use futures_core::Stream;
@@ -858,8 +858,10 @@ mod tests {
#[tokio::test]
async fn test_submit_with_tools_max_turns_exceeded() {
let mut config = CycleConfig::default();
config.max_tool_turns = Some(2);
let config = CycleConfig {
max_tool_turns: Some(2),
..Default::default()
};
let responses = vec![
assistant_tool_call_response(vec![("c1", "add", r#"{"a":1,"b":1}"#)]),
assistant_tool_call_response(vec![("c2", "add", r#"{"a":1,"b":1}"#)]),
+1
View File
@@ -75,6 +75,7 @@ impl<'a> HookContext<'a> {
}
/// 设置 plan step 序号(仅 OnPlanStepComplete 使用,Phase 4b 新增)。
#[allow(dead_code)]
pub(crate) fn with_plan_step_index(mut self, plan_step_index: usize) -> Self {
self.plan_step_index = Some(plan_step_index);
self
+3
View File
@@ -36,6 +36,7 @@ const DEFAULT_MAX_TOKENS: u32 = 4096;
pub struct AnthropicProvider {
http_client: Client,
base_url: String,
#[allow(dead_code)]
api_key: String,
model: String,
}
@@ -586,6 +587,7 @@ enum AnthropicDelta {
struct AnthropicMessageDeltaInner {
stop_reason: Option<String>,
#[serde(default)]
#[allow(dead_code)]
stop_sequence: Option<String>,
}
@@ -599,6 +601,7 @@ pub struct AnthropicSseStream {
chunks: Pin<Box<dyn Stream<Item = Result<Bytes, LlmError>> + Send>>,
buffer: String,
partial: PartialMessageResponse,
#[allow(dead_code)]
next_block_index: u32,
saw_terminal: bool,
}
+2 -2
View File
@@ -720,8 +720,8 @@ impl Stream for ChunkToEventStream {
}
let data = if let Some(p) = trimmed.strip_prefix("data: ") {
p
} else if trimmed.starts_with("data:") {
&trimmed[5..]
} else if let Some(p) = trimmed.strip_prefix("data:") {
p
} else {
continue;
};
+4
View File
@@ -40,6 +40,7 @@ pub use usage::{CompletionTokensDetails, CostTracker, PromptTokensDetails, Usage
// Phase 1 起移除 `ChatRequest` 别名 —— 新代码统一使用 `MessageRequest`v2 IR)。
// `ChatResponse` 结构体仍存在,作为 OpenAI `chat_inner()` 内部 wire-format 转换目标。
/// 旧 wire-format 响应结构(保留用于 OpenAI 内部转换层)。
#[deprecated(since = "0.1.0", note = "请改用 MessageResponse")]
#[derive(Debug, Clone)]
pub struct ChatResponse {
pub message: OpenaiChatMessage,
@@ -47,6 +48,7 @@ pub struct ChatResponse {
pub stop_reason: Option<FinishReason>,
}
#[allow(deprecated)]
impl From<OpenaiChatResponse> for ChatResponse {
fn from(response: OpenaiChatResponse) -> Self {
let message = response
@@ -63,6 +65,7 @@ impl From<OpenaiChatResponse> for ChatResponse {
}
}
#[allow(deprecated)]
impl From<ChatResponse> for OpenaiChatChunk {
fn from(response: ChatResponse) -> Self {
let delta = Delta::from(response.message.clone());
@@ -95,4 +98,5 @@ impl From<ChatResponse> for OpenaiChatChunk {
}
/// 工具定义别名(无新类型冲突,保留)。
#[deprecated(since = "0.1.0", note = "ToolDefinition 仍直接对应 OpenAI wire-format;未来 v0.2 引入 IR 工具类型后会再次更新")]
pub type ToolDefinition = OpenaiToolDefinition;