重构: 巨函数拆分 + 清理历史标记注释 + custom_prompt/停止按钮/tunnel 改进
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user