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:
+13
-18
@@ -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
@@ -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}"#)]),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user