重构: 巨函数拆分 + 清理历史标记注释 + custom_prompt/停止按钮/tunnel 改进

This commit is contained in:
lxy
2026-07-31 21:36:12 +08:00
parent 365af554da
commit bd9031d35d
73 changed files with 1421 additions and 1064 deletions
+5 -5
View File
@@ -1,4 +1,4 @@
//! 模型能力数据模型 — F-01 阶段1
//! 模型能力数据模型
//!
//! 单模型的完整描述(4 维度 + 路由控制)。纯数据结构,零 IO / 零 DB 依赖。
//! df-storage 反序列化 DB 行时直接消费本模块类型;df-ai 探测器/路由器阶段 2-4 再用。
@@ -45,9 +45,9 @@ pub enum Capability {
///
/// 序列化为 snake_case。原设计文档 §2.2 列 Free/Low/Medium/High,但 Free 变体形同虚设:
/// 预设表(presets/models.json)0 条 free + 启发式从不赋 Free(只 Low/Medium/High),
/// B-260618-05 删除 Free 死档变体。
/// Free 死档变体已删除
///
/// 路由已解耦(2026-06-18 B-260618-03):provider /v1/models API 不返回 cost_tier,
/// 路由已解耦:provider /v1/models API 不返回 cost_tier,
/// 此维度 100% 靠预设表写死 + 模型名启发式猜,数据无客观依据不可信,不再参与硬路由
/// (原 §6.1 `cost_tier <= max_cost` 过滤已删除)。枚举保留供未来出现真实判别源时再接回。
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
@@ -63,7 +63,7 @@ pub enum CostTier {
/// 设计文档 §2.2:Lite/Standard/Plus/Ultra。序列化为 snake_case。
/// 派生 Ord:Lite < Standard < Plus < Ultra。
///
/// 路由已解耦(2026-06-18 B-260618-03):provider /v1/models API 不返回 intelligence,
/// 路由已解耦:provider /v1/models API 不返回 intelligence,
/// 此维度 100% 靠预设表写死 + 模型名启发式猜,数据无客观依据不可信,不再参与硬路由
/// (原 §6.1 `intelligence >= min_intelligence` 过滤已删除)。枚举保留供未来出现真实判别源时再接回。
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
@@ -302,7 +302,7 @@ mod tests {
assert_eq!(serde_json::from_str::<CostTier>(expected).unwrap(), variant);
}
// Ord:Low < Medium < High(枚举序,路由已解耦不再用于过滤,保留供未来判别源)。
// Free 变体已删除(B-260618-05:预设/启发式从不赋 Free,死档)。
// Free 变体已删除(预设/启发式从不赋 Free,死档)。
assert!(CostTier::Low < CostTier::Medium);
assert!(CostTier::Medium < CostTier::High);
}
+8 -9
View File
@@ -90,8 +90,8 @@ impl ChatMessage {
/// 是否处于 active 态(status 为 None 或 "active")。其余状态一律 false。
///
/// 正面白名单F-15 §3.2:仅认 None / "active",新状态
/// (如阶段2 引入的 "archived_segment" / "compressed")自动落入不 active 分支,
/// 正面白名单:仅认 None / "active",新状态
/// (如"archived_segment" / "compressed")自动落入不 active 分支,
/// 无需每加一个状态就来这里改。当前取值 None/Some("active")/Some("truncated")
/// 行为与旧反面排除完全等价(None=true / "active"=true / "truncated"=false)。
pub fn is_active(&self) -> bool {
@@ -155,10 +155,9 @@ mod tests {
#[test]
fn is_active_whitelist() {
// F-15 §3.2 正面白名单:仅 None / "active" 为 true,其余一律 false。
// 正面白名单:仅 None / "active" 为 true,其余一律 false。
// 零行为变化:None / "active" / "truncated" 与旧反面排除完全等价;
// "archived_segment" / "compressed"(阶段2 引入,当前代码未赋值)由白名单
// matches! 只认 None/active 自动落入 false,面向未来验证。
// "archived_segment" / "compressed" 由白名单 matches! 只认 None/active 自动落入 false。
// None(构造默认值,向前兼容老 JSON)
let m = ChatMessage::user("hi");
@@ -174,18 +173,18 @@ mod tests {
m.status = Some(MessageStatus::Truncated);
assert!(!m.is_active(), "truncated 应不 active");
// "archived_segment" — 阶段2 待引入,白名单自动隔离
// "archived_segment" — 白名单自动隔离
let mut m = ChatMessage::user("hi");
m.status = Some(MessageStatus::ArchivedSegment);
assert!(!m.is_active(), "archived_segment 应不 active(白名单隔离)");
// "compressed" — 阶段2 待引入,白名单自动隔离
// "compressed" — 白名单自动隔离
let mut m = ChatMessage::user("hi");
m.status = Some(MessageStatus::Compressed);
assert!(!m.is_active(), "compressed 应不 active(白名单隔离)");
}
// ---------- F-260614-05 Phase 2a ContentPart ----------
// ---------- ContentPart ----------
/// 老 JSON(无 parts 字段)反序列化时 parts 应为 None(向前兼容)
#[test]
@@ -333,7 +332,7 @@ mod tests {
assert_eq!(deserialized.reasoning_content, Some("thinking process".to_string()));
}
// ---------- F-260619-04 消息级溯源:id 字段 ----------
// ---------- 消息级溯源:id 字段 ----------
/// 所有便捷构造函数默认生成非 None 的 id(ULID 风格)
#[test]
+3 -3
View File
@@ -43,7 +43,7 @@ pub struct CompletionRequest {
/// 多模态消息内容片。Text 片为字符串;Image 片可走 url 或 base64(二选一,base64 非空时 url 忽略)。
///
/// F-260614-05 Phase 2a 后端:ContentPart 作为 `ChatMessage.parts` 的元素类型。
/// ContentPart 作为 `ChatMessage.parts` 的元素类型。
/// 设计上 `content: String`(纯文本主载荷)保持不变,多模态片挂在 `parts`:
/// 这样未接入多模态的调用方(audit/title/commands/knowledge_inject 等读 content 当字符串)
/// 零回归,避免一次性改全仓。provider 转换层在 `has_image()` 为真时把 parts 透传给
@@ -79,13 +79,13 @@ pub enum ContentPart {
pub struct ChatMessage {
/// 消息全局唯一 ID。用于消息级溯源(source_ref / audit message_id / idea source)。
/// 构造时由 `new_message_id()` 生成;老 JSON 反序列化为 None(向前兼容)。
/// 消息拆分存储(F-260619-03)后,此 ID 即 `ai_messages.id` 列主键。
/// 消息拆分存储后,此 ID 即 `ai_messages.id` 列主键。
/// 临时/派生消息(如 title 摘要)可显式赋 None(不溯源不落库)。
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub role: MessageRole,
pub content: String,
/// 多模态内容片F-260614-05 Phase 2a
/// 多模态内容片。
///
/// `None`/空 → 纯文本消息(绝大多数场景,content 即全部载荷)。
/// `Some(含 Image 片)` → 多模态消息,provider 在 `has_image()` 为真时把 parts