Files

1 line
43 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "blueokanna/talk2u", "files": {"rust/src/api/data_models.rs": {"1d6fd7f3c63e04a567cdcaa1381564cc5681e743": {"t": 1785746246.1623309, "n": 8575, "h": "a11370422ad144c6", "c": "use flutter_rust_bridge::frb;\nuse serde::{Deserialize, Serialize};\n\n#[frb]\n#[derive(Debug, Clone)]\npub enum ChatStreamEvent {\n ContentDelta(String),\n ThinkingDelta(String),\n Done,\n Error(String),\n}\n\n#[derive(Default)]\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageType {\n #[default]\n Say,\n Do,\n Mixed,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Message {\n pub id: String,\n pub role: MessageRole,\n pub content: String,\n pub thinking_content: Option<String>,\n pub model: String,\n pub timestamp: i64,\n #[serde(default)]\n pub message_type: MessageType,\n}\n\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageRole {\n User,\n Assistant,\n System,\n}\n\n#[derive(Default)]\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum DialogueStyle {\n Free,\n SayOnly,\n DoOnly,\n #[default]\n Mixed,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Conversation {\n pub id: String,\n pub title: String,\n pub messages: Vec<Message>,\n pub model: String,\n pub created_at: i64,\n pub updated_at: i64,\n #[serde(default)]\n pub dialogue_style: DialogueStyle,\n #[serde(default)]\n pub turn_count: u32,\n #[serde(default)]\n pub memory_summaries: Vec<MemorySummary>,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemorySummary {\n pub id: String,\n pub summary: String,\n pub core_facts: Vec<String>,\n pub turn_range_start: u32,\n pub turn_range_end: u32,\n pub created_at: i64,\n pub keywords: Vec<String>,\n #[serde(default)]\n pub compression_generation: u32,\n #[serde(default)]\n pub context_card: Option<MemoryContextCard>,\n #[serde(default)]\n pub fact_tiers: Vec<MemoryTier>,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub enum CompressionImpactLevel {\n Lossless,\n StyleDrift,\n PersonalityFade,\n DetailLoss,\n IdentityErosion,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct ConversationSummary {\n pub id: String,\n pub title: String,\n pub last_message_preview: String,\n pub model: String,\n pub updated_at: i64,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct AppSettings {\n pub api_key: Option<String>,\n pub default_model: String,\n pub enable_thinking_by_default: bool,\n #[serde(default = \"default_chat_model\")]\n pub chat_model: String,\n #[serde(default = \"default_thinking_model\")]\n pub thinking_model: String,\n #[serde(default = \"default_selected_provider\")]\n pub selected_provider: String,\n #[serde(default = \"default_providers_json\")]\n pub providers_json: String,\n}\n\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct ProviderConfig {\n pub id: String,\n pub name: String,\n pub api_key: Option<String>,\n pub api_url: String,\n pub chat_model: String,\n pub thinking_model: Option<String>,\n pub protocol: String,\n #[serde(default = \"default_provider_max_output_tokens\")]\n pub max_output_tokens: u32,\n}\n\nimpl ProviderConfig {\n pub fn is_configured(&self) -> bool {\n !self.api_url.trim().is_empty()\n && !self.chat_model.trim().is_empty()\n && (!self.requires_api_key()\n || self\n .api_key\n .as_deref()\n .map(str::trim)\n .is_some_and(|key| !key.is_empty()))\n && self.max_output_tokens > 0\n }\n\n pub fn requires_api_key(&self) -> bool {\n self.id != \"custom\" || self.protocol.eq_ignore_ascii_case(\"anthropic\")\n }\n}\n\nfn default_provider_max_output_tokens() -> u32 {\n 4096\n}\n\nfn default_selected_provider() -> String {\n \"zhipu\".to_string()\n}\n\npub fn default_provider_configs() -> Vec<ProviderConfig> {\n vec![\n ProviderConfig {\n id: \"zhipu\".to_string(),\n name: \"智谱清言\".to_string(),\n api_key: None,\n api_url: \"https://open.bigmodel.cn/api/paas/v4/chat/completions\".to_string(),\n chat_model: \"glm-4.7\".to_string(),\n thinking_model: Some(\"glm-4-air\".to_string()),\n protocol: \"openai\".to_string(),\n max_output_tokens: 16_384,\n },\n ProviderConfig {\n id: \"deepseek\".to_string(),\n name: \"DeepSeek\".to_string(),\n api_key: None,\n api_url: \"https://api.deepseek.com/chat/completions\".to_string(),\n chat_model: \"deepseek-chat\".to_string(),\n thinking_model: Some(\"deepseek-reasoner\".to_string()),\n protocol: \"openai\".to_string(),\n max_output_tokens: 8_192,\n },\n ProviderConfig {\n id: \"openai\".to_string(),\n name: \"OpenAI\".to_string(),\n api_key: None,\n api_url: \"https://api.openai.com/v1/chat/completions\".to_string(),\n chat_model: \"gpt-4.1-mini\".to_string(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 16_384,\n },\n ProviderConfig {\n id: \"anthropic\".to_string(),\n name: \"Anthropic\".to_string(),\n api_key: None,\n api_url: \"https://api.anthropic.com/v1/messages\".to_string(),\n chat_model: \"claude-sonnet-4-5\".to_string(),\n thinking_model: None,\n protocol: \"anthropic\".to_string(),\n max_output_tokens: 8_192,\n },\n ProviderConfig {\n id: \"kimi\".to_string(),\n name: \"Kimi\".to_string(),\n api_key: None,\n api_url: \"https://api.moonshot.cn/v1/chat/completions\".to_string(),\n chat_model: \"moonshot-v1-8k\".to_string(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 4_096,\n },\n ProviderConfig {\n id: \"qwen\".to_string(),\n name: \"Qwen(通义千问)\".to_string(),\n api_key: None,\n api_url: \"https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions\"\n .to_string(),\n chat_model: \"qwen-plus\".to_string(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 8_192,\n },\n ProviderConfig {\n id: \"custom\".to_string(),\n name: \"自定义 OpenAI 兼容接口\".to_string(),\n api_key: None,\n api_url: String::new(),\n chat_model: String::new(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 4_096,\n },\n ]\n}\n\nfn default_providers_json() -> String {\n serde_json::to_string(&default_provider_configs()).unwrap_or_else(|_| \"[]\".to_string())\n}\n\nfn default_chat_model() -> String {\n \"glm-4.7\".to_string()\n}\n\nfn default_thinking_model() -> String {\n \"glm-4-air\".to_string()\n}\n\nimpl Default for AppSettings {\n fn default() -> Self {\n Self {\n api_key: None,\n default_model: \"glm-4.7\".to_string(),\n enable_thinking_by_default: true,\n chat_model: \"glm-4.7\".to_string(),\n thinking_model: \"glm-4-air\".to_string(),\n selected_provider: default_selected_provider(),\n providers_json: default_providers_json(),\n }\n }\n}\n\n#[frb]\n#[derive(Debug, Clone)]\npub struct ModelInfo {\n pub id: String,\n pub name: String,\n pub context_tokens: usize,\n pub max_output_tokens: usize,\n pub supports_thinking: bool,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemoryContextCard {\n pub source_range: String,\n pub topic_tags: Vec<String>,\n pub key_entities: Vec<String>,\n pub emotional_tone: String,\n pub causal_links: Vec<String>,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub enum MemoryTier {\n Identity,\n CriticalEvent,\n RelationshipDynamic,\n CurrentState,\n SceneDetail,\n}\n\n#[frb]\n#[derive(Debug, Clone)]\npub struct MemorySearchResult {\n pub summary: String,\n pub core_facts: Vec<String>,\n pub relevance_score: f64,\n}\n\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct DistilledSystemState {\n pub core_prompt: String,\n pub last_memory_count: usize,\n pub last_max_compression_gen: u32,\n pub character_prompt_hash: u64,\n pub last_turn_count: u32,\n pub distilled_at: i64,\n pub core_facts_snapshot: Vec<String>,\n}\n"}, "232e5b6f47b8f0a3c24a636771565d359c6bb48d": {"t": 1785761053.5187578, "n": 8575, "h": "a11370422ad144c6", "c": "use flutter_rust_bridge::frb;\nuse serde::{Deserialize, Serialize};\n\n#[frb]\n#[derive(Debug, Clone)]\npub enum ChatStreamEvent {\n ContentDelta(String),\n ThinkingDelta(String),\n Done,\n Error(String),\n}\n\n#[derive(Default)]\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageType {\n #[default]\n Say,\n Do,\n Mixed,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Message {\n pub id: String,\n pub role: MessageRole,\n pub content: String,\n pub thinking_content: Option<String>,\n pub model: String,\n pub timestamp: i64,\n #[serde(default)]\n pub message_type: MessageType,\n}\n\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageRole {\n User,\n Assistant,\n System,\n}\n\n#[derive(Default)]\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum DialogueStyle {\n Free,\n SayOnly,\n DoOnly,\n #[default]\n Mixed,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Conversation {\n pub id: String,\n pub title: String,\n pub messages: Vec<Message>,\n pub model: String,\n pub created_at: i64,\n pub updated_at: i64,\n #[serde(default)]\n pub dialogue_style: DialogueStyle,\n #[serde(default)]\n pub turn_count: u32,\n #[serde(default)]\n pub memory_summaries: Vec<MemorySummary>,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemorySummary {\n pub id: String,\n pub summary: String,\n pub core_facts: Vec<String>,\n pub turn_range_start: u32,\n pub turn_range_end: u32,\n pub created_at: i64,\n pub keywords: Vec<String>,\n #[serde(default)]\n pub compression_generation: u32,\n #[serde(default)]\n pub context_card: Option<MemoryContextCard>,\n #[serde(default)]\n pub fact_tiers: Vec<MemoryTier>,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub enum CompressionImpactLevel {\n Lossless,\n StyleDrift,\n PersonalityFade,\n DetailLoss,\n IdentityErosion,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct ConversationSummary {\n pub id: String,\n pub title: String,\n pub last_message_preview: String,\n pub model: String,\n pub updated_at: i64,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct AppSettings {\n pub api_key: Option<String>,\n pub default_model: String,\n pub enable_thinking_by_default: bool,\n #[serde(default = \"default_chat_model\")]\n pub chat_model: String,\n #[serde(default = \"default_thinking_model\")]\n pub thinking_model: String,\n #[serde(default = \"default_selected_provider\")]\n pub selected_provider: String,\n #[serde(default = \"default_providers_json\")]\n pub providers_json: String,\n}\n\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct ProviderConfig {\n pub id: String,\n pub name: String,\n pub api_key: Option<String>,\n pub api_url: String,\n pub chat_model: String,\n pub thinking_model: Option<String>,\n pub protocol: String,\n #[serde(default = \"default_provider_max_output_tokens\")]\n pub max_output_tokens: u32,\n}\n\nimpl ProviderConfig {\n pub fn is_configured(&self) -> bool {\n !self.api_url.trim().is_empty()\n && !self.chat_model.trim().is_empty()\n && (!self.requires_api_key()\n || self\n .api_key\n .as_deref()\n .map(str::trim)\n .is_some_and(|key| !key.is_empty()))\n && self.max_output_tokens > 0\n }\n\n pub fn requires_api_key(&self) -> bool {\n self.id != \"custom\" || self.protocol.eq_ignore_ascii_case(\"anthropic\")\n }\n}\n\nfn default_provider_max_output_tokens() -> u32 {\n 4096\n}\n\nfn default_selected_provider() -> String {\n \"zhipu\".to_string()\n}\n\npub fn default_provider_configs() -> Vec<ProviderConfig> {\n vec![\n ProviderConfig {\n id: \"zhipu\".to_string(),\n name: \"智谱清言\".to_string(),\n api_key: None,\n api_url: \"https://open.bigmodel.cn/api/paas/v4/chat/completions\".to_string(),\n chat_model: \"glm-4.7\".to_string(),\n thinking_model: Some(\"glm-4-air\".to_string()),\n protocol: \"openai\".to_string(),\n max_output_tokens: 16_384,\n },\n ProviderConfig {\n id: \"deepseek\".to_string(),\n name: \"DeepSeek\".to_string(),\n api_key: None,\n api_url: \"https://api.deepseek.com/chat/completions\".to_string(),\n chat_model: \"deepseek-chat\".to_string(),\n thinking_model: Some(\"deepseek-reasoner\".to_string()),\n protocol: \"openai\".to_string(),\n max_output_tokens: 8_192,\n },\n ProviderConfig {\n id: \"openai\".to_string(),\n name: \"OpenAI\".to_string(),\n api_key: None,\n api_url: \"https://api.openai.com/v1/chat/completions\".to_string(),\n chat_model: \"gpt-4.1-mini\".to_string(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 16_384,\n },\n ProviderConfig {\n id: \"anthropic\".to_string(),\n name: \"Anthropic\".to_string(),\n api_key: None,\n api_url: \"https://api.anthropic.com/v1/messages\".to_string(),\n chat_model: \"claude-sonnet-4-5\".to_string(),\n thinking_model: None,\n protocol: \"anthropic\".to_string(),\n max_output_tokens: 8_192,\n },\n ProviderConfig {\n id: \"kimi\".to_string(),\n name: \"Kimi\".to_string(),\n api_key: None,\n api_url: \"https://api.moonshot.cn/v1/chat/completions\".to_string(),\n chat_model: \"moonshot-v1-8k\".to_string(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 4_096,\n },\n ProviderConfig {\n id: \"qwen\".to_string(),\n name: \"Qwen(通义千问)\".to_string(),\n api_key: None,\n api_url: \"https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions\"\n .to_string(),\n chat_model: \"qwen-plus\".to_string(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 8_192,\n },\n ProviderConfig {\n id: \"custom\".to_string(),\n name: \"自定义 OpenAI 兼容接口\".to_string(),\n api_key: None,\n api_url: String::new(),\n chat_model: String::new(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 4_096,\n },\n ]\n}\n\nfn default_providers_json() -> String {\n serde_json::to_string(&default_provider_configs()).unwrap_or_else(|_| \"[]\".to_string())\n}\n\nfn default_chat_model() -> String {\n \"glm-4.7\".to_string()\n}\n\nfn default_thinking_model() -> String {\n \"glm-4-air\".to_string()\n}\n\nimpl Default for AppSettings {\n fn default() -> Self {\n Self {\n api_key: None,\n default_model: \"glm-4.7\".to_string(),\n enable_thinking_by_default: true,\n chat_model: \"glm-4.7\".to_string(),\n thinking_model: \"glm-4-air\".to_string(),\n selected_provider: default_selected_provider(),\n providers_json: default_providers_json(),\n }\n }\n}\n\n#[frb]\n#[derive(Debug, Clone)]\npub struct ModelInfo {\n pub id: String,\n pub name: String,\n pub context_tokens: usize,\n pub max_output_tokens: usize,\n pub supports_thinking: bool,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemoryContextCard {\n pub source_range: String,\n pub topic_tags: Vec<String>,\n pub key_entities: Vec<String>,\n pub emotional_tone: String,\n pub causal_links: Vec<String>,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub enum MemoryTier {\n Identity,\n CriticalEvent,\n RelationshipDynamic,\n CurrentState,\n SceneDetail,\n}\n\n#[frb]\n#[derive(Debug, Clone)]\npub struct MemorySearchResult {\n pub summary: String,\n pub core_facts: Vec<String>,\n pub relevance_score: f64,\n}\n\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct DistilledSystemState {\n pub core_prompt: String,\n pub last_memory_count: usize,\n pub last_max_compression_gen: u32,\n pub character_prompt_hash: u64,\n pub last_turn_count: u32,\n pub distilled_at: i64,\n pub core_facts_snapshot: Vec<String>,\n}\n"}, "660c3ded72b3a5dd25e8402af3e8d3a7463a66be": {"t": 1785761054.9851255, "n": 8926, "h": "7fcc1e49a4d6f6bf", "c": "use flutter_rust_bridge::frb;\nuse serde::{Deserialize, Serialize};\n\n#[frb]\n#[derive(Debug, Clone)]\npub enum ChatStreamEvent {\n ContentDelta(String),\n ThinkingDelta(String),\n Done,\n Error(String),\n}\n\n#[derive(Default)]\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageType {\n #[default]\n Say,\n Do,\n Mixed,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Message {\n pub id: String,\n pub role: MessageRole,\n pub content: String,\n pub thinking_content: Option<String>,\n pub model: String,\n pub timestamp: i64,\n #[serde(default)]\n pub message_type: MessageType,\n}\n\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageRole {\n User,\n Assistant,\n System,\n}\n\n#[derive(Default)]\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum DialogueStyle {\n Free,\n SayOnly,\n DoOnly,\n #[default]\n Mixed,\n}\n\n/// 对话\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Conversation {\n pub id: String,\n pub title: String,\n pub messages: Vec<Message>,\n pub model: String,\n pub created_at: i64,\n pub updated_at: i64,\n #[serde(default)]\n pub dialogue_style: DialogueStyle,\n #[serde(default)]\n pub turn_count: u32,\n #[serde(default)]\n pub memory_summaries: Vec<MemorySummary>,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemorySummary {\n pub id: String,\n pub summary: String,\n pub core_facts: Vec<String>,\n pub turn_range_start: u32,\n pub turn_range_end: u32,\n pub created_at: i64,\n pub keywords: Vec<String>,\n #[serde(default)]\n pub compression_generation: u32,\n #[serde(default)]\n pub context_card: Option<MemoryContextCard>,\n #[serde(default)]\n pub fact_tiers: Vec<MemoryTier>,\n}\n\n/// 压缩影响等级 — 随压缩代数递增,逐步影响不同维度\n/// Gen 0-1: 无损(完整保留所有信息)\n/// Gen 2-3: 语气/表达风格可能轻微偏移\n/// Gen 4-5: 性格细节可能模糊(如口癖频率降低)\n/// Gen 6-7: 次要关系/金钱等数值细节可能丢失\n/// Gen 8+: 身份设定的边缘属性可能受影响(核心身份仍保留)\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub enum CompressionImpactLevel {\n Lossless,\n StyleDrift,\n PersonalityFade,\n DetailLoss,\n IdentityErosion,\n}\n\n/// 对话摘要(用于列表展示)\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct ConversationSummary {\n pub id: String,\n pub title: String,\n pub last_message_preview: String,\n pub model: String,\n pub updated_at: i64,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct AppSettings {\n pub api_key: Option<String>,\n pub default_model: String,\n pub enable_thinking_by_default: bool,\n #[serde(default = \"default_chat_model\")]\n pub chat_model: String,\n #[serde(default = \"default_thinking_model\")]\n pub thinking_model: String,\n #[serde(default = \"default_selected_provider\")]\n pub selected_provider: String,\n #[serde(default = \"default_providers_json\")]\n pub providers_json: String,\n}\n\n/// A saved LLM endpoint. `protocol` is either `openai` or `anthropic`.\n/// Custom endpoints intentionally use the OpenAI-compatible wire format.\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct ProviderConfig {\n pub id: String,\n pub name: String,\n pub api_key: Option<String>,\n pub api_url: String,\n pub chat_model: String,\n pub thinking_model: Option<String>,\n pub protocol: String,\n #[serde(default = \"default_provider_max_output_tokens\")]\n pub max_output_tokens: u32,\n}\n\nimpl ProviderConfig {\n pub fn is_configured(&self) -> bool {\n !self.api_url.trim().is_empty()\n && !self.chat_model.trim().is_empty()\n && (!self.requires_api_key()\n || self\n .api_key\n .as_deref()\n .map(str::trim)\n .is_some_and(|key| !key.is_empty()))\n && self.max_output_tokens > 0\n }\n\n pub fn requires_api_key(&self) -> bool {\n self.id != \"custom\" || self.protocol.eq_ignore_ascii_case(\"anthropic\")\n }\n}\n\nfn default_provider_max_output_tokens() -> u32 {\n 4096\n}\n\nfn default_selected_provider() -> String {\n \"zhipu\".to_string()\n}\n\npub fn default_provider_configs() -> Vec<ProviderConfig> {\n vec![\n ProviderConfig {\n id: \"zhipu\".to_string(),\n name: \"智谱清言\".to_string(),\n api_key: None,\n api_url: \"https://open.bigmodel.cn/api/paas/v4/chat/completions\".to_string(),\n chat_model: \"glm-4.7\".to_string(),\n thinking_model: Some(\"glm-4-air\".to_string()),\n protocol: \"openai\".to_string(),\n max_output_tokens: 16_384,\n },\n ProviderConfig {\n id: \"deepseek\".to_string(),\n name: \"DeepSeek\".to_string(),\n api_key: None,\n api_url: \"https://api.deepseek.com/chat/completions\".to_string(),\n chat_model: \"deepseek-chat\".to_string(),\n thinking_model: Some(\"deepseek-reasoner\".to_string()),\n protocol: \"openai\".to_string(),\n max_output_tokens: 8_192,\n },\n ProviderConfig {\n id: \"openai\".to_string(),\n name: \"OpenAI\".to_string(),\n api_key: None,\n api_url: \"https://api.openai.com/v1/chat/completions\".to_string(),\n chat_model: \"gpt-4.1-mini\".to_string(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 16_384,\n },\n ProviderConfig {\n id: \"anthropic\".to_string(),\n name: \"Anthropic\".to_string(),\n api_key: None,\n api_url: \"https://api.anthropic.com/v1/messages\".to_string(),\n chat_model: \"claude-sonnet-4-5\".to_string(),\n thinking_model: None,\n protocol: \"anthropic\".to_string(),\n max_output_tokens: 8_192,\n },\n ProviderConfig {\n id: \"kimi\".to_string(),\n name: \"Kimi\".to_string(),\n api_key: None,\n api_url: \"https://api.moonshot.cn/v1/chat/completions\".to_string(),\n chat_model: \"moonshot-v1-8k\".to_string(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 4_096,\n },\n ProviderConfig {\n id: \"qwen\".to_string(),\n name: \"Qwen(通义千问)\".to_string(),\n api_key: None,\n api_url: \"https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions\"\n .to_string(),\n chat_model: \"qwen-plus\".to_string(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 8_192,\n },\n ProviderConfig {\n id: \"custom\".to_string(),\n name: \"自定义 OpenAI 兼容接口\".to_string(),\n api_key: None,\n api_url: String::new(),\n chat_model: String::new(),\n thinking_model: None,\n protocol: \"openai\".to_string(),\n max_output_tokens: 4_096,\n },\n ]\n}\n\nfn default_providers_json() -> String {\n serde_json::to_string(&default_provider_configs()).unwrap_or_else(|_| \"[]\".to_string())\n}\n\nfn default_chat_model() -> String {\n \"glm-4.7\".to_string()\n}\n\nfn default_thinking_model() -> String {\n \"glm-4-air\".to_string()\n}\n\nimpl Default for AppSettings {\n fn default() -> Self {\n Self {\n api_key: None,\n default_model: \"glm-4.7\".to_string(),\n enable_thinking_by_default: true,\n chat_model: \"glm-4.7\".to_string(),\n thinking_model: \"glm-4-air\".to_string(),\n selected_provider: default_selected_provider(),\n providers_json: default_providers_json(),\n }\n }\n}\n\n#[frb]\n#[derive(Debug, Clone)]\npub struct ModelInfo {\n pub id: String,\n pub name: String,\n pub context_tokens: usize,\n pub max_output_tokens: usize,\n pub supports_thinking: bool,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemoryContextCard {\n pub source_range: String,\n pub topic_tags: Vec<String>,\n pub key_entities: Vec<String>,\n pub emotional_tone: String,\n pub causal_links: Vec<String>,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub enum MemoryTier {\n Identity,\n CriticalEvent,\n RelationshipDynamic,\n CurrentState,\n SceneDetail,\n}\n\n#[frb]\n#[derive(Debug, Clone)]\npub struct MemorySearchResult {\n pub summary: String,\n pub core_facts: Vec<String>,\n pub relevance_score: f64,\n}\n\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct DistilledSystemState {\n pub core_prompt: String,\n pub last_memory_count: usize,\n pub last_max_compression_gen: u32,\n pub character_prompt_hash: u64,\n pub last_turn_count: u32,\n pub distilled_at: i64,\n pub core_facts_snapshot: Vec<String>,\n}\n"}, "885b8827332b60371ee5474bb0f7aa38d4e0238a": {"t": 1785761056.3127632, "n": 4440, "h": "0003bcaf4783ba69", "c": "use flutter_rust_bridge::frb;\nuse serde::{Deserialize, Serialize};\n\n#[frb]\n#[derive(Debug, Clone)]\npub enum ChatStreamEvent {\n ContentDelta(String),\n ThinkingDelta(String),\n Done,\n Error(String),\n}\n\n#[derive(Default)]\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageType {\n #[default]\n Say,\n Do,\n Mixed,\n}\n\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Message {\n pub id: String,\n pub role: MessageRole,\n pub content: String,\n pub thinking_content: Option<String>,\n pub model: String,\n pub timestamp: i64,\n #[serde(default)]\n pub message_type: MessageType,\n}\n\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageRole {\n User,\n Assistant,\n System,\n}\n\n#[derive(Default)]\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum DialogueStyle {\n Free,\n SayOnly,\n DoOnly,\n #[default]\n Mixed,\n}\n\n\n/// 对话\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Conversation {\n pub id: String,\n pub title: String,\n pub messages: Vec<Message>,\n pub model: String,\n pub created_at: i64,\n pub updated_at: i64,\n #[serde(default)]\n pub dialogue_style: DialogueStyle,\n #[serde(default)]\n pub turn_count: u32,\n #[serde(default)]\n pub memory_summaries: Vec<MemorySummary>,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemorySummary {\n pub id: String,\n pub summary: String,\n pub core_facts: Vec<String>,\n pub turn_range_start: u32,\n pub turn_range_end: u32,\n pub created_at: i64,\n pub keywords: Vec<String>,\n #[serde(default)]\n pub compression_generation: u32,\n #[serde(default)]\n pub context_card: Option<MemoryContextCard>,\n #[serde(default)]\n pub fact_tiers: Vec<MemoryTier>,\n}\n\n/// 压缩影响等级 — 随压缩代数递增,逐步影响不同维度\n/// Gen 0-1: 无损(完整保留所有信息)\n/// Gen 2-3: 语气/表达风格可能轻微偏移\n/// Gen 4-5: 性格细节可能模糊(如口癖频率降低)\n/// Gen 6-7: 次要关系/金钱等数值细节可能丢失\n/// Gen 8+: 身份设定的边缘属性可能受影响(核心身份仍保留)\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub enum CompressionImpactLevel {\n Lossless,\n StyleDrift,\n PersonalityFade,\n DetailLoss,\n IdentityErosion,\n}\n\n/// 对话摘要(用于列表展示)\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct ConversationSummary {\n pub id: String,\n pub title: String,\n pub last_message_preview: String,\n pub model: String,\n pub updated_at: i64,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct AppSettings {\n pub api_key: Option<String>,\n pub default_model: String,\n pub enable_thinking_by_default: bool,\n #[serde(default = \"default_chat_model\")]\n pub chat_model: String,\n #[serde(default = \"default_thinking_model\")]\n pub thinking_model: String,\n}\n\nfn default_chat_model() -> String {\n \"glm-4.7\".to_string()\n}\n\nfn default_thinking_model() -> String {\n \"glm-4-air\".to_string()\n}\n\nimpl Default for AppSettings {\n fn default() -> Self {\n Self {\n api_key: None,\n default_model: \"glm-4.7\".to_string(),\n enable_thinking_by_default: true,\n chat_model: \"glm-4.7\".to_string(),\n thinking_model: \"glm-4-air\".to_string(),\n }\n }\n}\n\n#[frb]\n#[derive(Debug, Clone)]\npub struct ModelInfo {\n pub id: String,\n pub name: String,\n pub context_tokens: usize,\n pub max_output_tokens: usize,\n pub supports_thinking: bool,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemoryContextCard {\n pub source_range: String,\n pub topic_tags: Vec<String>,\n pub key_entities: Vec<String>,\n pub emotional_tone: String,\n pub causal_links: Vec<String>,\n}\n\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub enum MemoryTier {\n Identity,\n CriticalEvent,\n RelationshipDynamic,\n CurrentState,\n SceneDetail,\n}\n\n#[frb]\n#[derive(Debug, Clone)]\npub struct MemorySearchResult {\n pub summary: String,\n pub core_facts: Vec<String>,\n pub relevance_score: f64,\n}\n\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct DistilledSystemState {\n pub core_prompt: String,\n pub last_memory_count: usize,\n pub last_max_compression_gen: u32,\n pub character_prompt_hash: u64,\n pub last_turn_count: u32,\n pub distilled_at: i64,\n pub core_facts_snapshot: Vec<String>,\n}\n"}, "b0ac5f3b2f6ba8ce84beaa85f5995beda092f8b1": {"t": 1785761057.8129475, "n": 5334, "h": "38ef73965cd9e0d5", "c": "use flutter_rust_bridge::frb;\nuse serde::{Deserialize, Serialize};\n\n/// 聊天流事件 - 通过 flutter_rust_bridge Stream 传递给 Flutter\n#[frb]\n#[derive(Debug, Clone)]\npub enum ChatStreamEvent {\n /// 正常内容增量\n ContentDelta(String),\n /// 思考内容增量\n ThinkingDelta(String),\n /// 流结束\n Done,\n /// 错误\n Error(String),\n}\n\n/// 消息类型标记:say(对话)或 do(动作/旁白)\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageType {\n Say,\n Do,\n Mixed, // 同时包含 say 和 do\n}\n\nimpl Default for MessageType {\n fn default() -> Self {\n MessageType::Say\n }\n}\n\n/// 单条消息\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Message {\n pub id: String,\n pub role: MessageRole,\n pub content: String,\n pub thinking_content: Option<String>,\n pub model: String,\n pub timestamp: i64,\n #[serde(default)]\n pub message_type: MessageType,\n}\n\n/// 消息角色\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageRole {\n User,\n Assistant,\n System,\n}\n\n/// 对话风格\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum DialogueStyle {\n /// 默认自由对话\n Free,\n /// 纯对话模式(say only)\n SayOnly,\n /// 纯动作/旁白模式(do only)\n DoOnly,\n /// 混合模式(say + do 自动识别)\n Mixed,\n}\n\nimpl Default for DialogueStyle {\n fn default() -> Self {\n DialogueStyle::Mixed\n }\n}\n\n/// 对话\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Conversation {\n pub id: String,\n pub title: String,\n pub messages: Vec<Message>,\n pub model: String,\n pub created_at: i64,\n pub updated_at: i64,\n #[serde(default)]\n pub dialogue_style: DialogueStyle,\n #[serde(default)]\n pub turn_count: u32,\n #[serde(default)]\n pub memory_summaries: Vec<MemorySummary>,\n}\n\n/// 记忆摘要条目\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemorySummary {\n pub id: String,\n pub summary: String,\n /// 核心身份/事件等不可变信息\n pub core_facts: Vec<String>,\n /// 涵盖的消息范围 [start_turn, end_turn]\n pub turn_range_start: u32,\n pub turn_range_end: u32,\n pub created_at: i64,\n /// BM25 关键词索引\n pub keywords: Vec<String>,\n /// 压缩代数:每次被合并/压缩时 +1,代数越高信息损耗风险越大\n #[serde(default)]\n pub compression_generation: u32,\n /// 上下文增强卡片 — 结构化元信息,提升检索精度\n #[serde(default)]\n pub context_card: Option<MemoryContextCard>,\n /// 每条核心事实的排级分类,与 core_facts 一一对应\n #[serde(default)]\n pub fact_tiers: Vec<MemoryTier>,\n}\n\n/// 压缩影响等级 — 随压缩代数递增,逐步影响不同维度\n/// Gen 0-1: 无损(完整保留所有信息)\n/// Gen 2-3: 语气/表达风格可能轻微偏移\n/// Gen 4-5: 性格细节可能模糊(如口癖频率降低)\n/// Gen 6-7: 次要关系/金钱等数值细节可能丢失\n/// Gen 8+: 身份设定的边缘属性可能受影响(核心身份仍保留)\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub enum CompressionImpactLevel {\n /// 无损:所有信息完整保留\n Lossless,\n /// 风格微调:语气、表达习惯可能轻微变化\n StyleDrift,\n /// 性格模糊:性格细节开始模糊\n PersonalityFade,\n /// 细节丢失:金钱数值、次要关系等可能不精确\n DetailLoss,\n /// 深度退化:身份边缘属性可能受影响\n IdentityErosion,\n}\n\n/// 对话摘要(用于列表展示)\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct ConversationSummary {\n pub id: String,\n pub title: String,\n pub last_message_preview: String,\n pub model: String,\n pub updated_at: i64,\n}\n\n/// 应用设置\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct AppSettings {\n pub api_key: Option<String>,\n pub default_model: String,\n pub enable_thinking_by_default: bool,\n #[serde(default = \"default_chat_model\")]\n pub chat_model: String,\n #[serde(default = \"default_thinking_model\")]\n pub thinking_model: String,\n}\n\nfn default_chat_model() -> String {\n \"glm-4.7\".to_string()\n}\n\nfn default_thinking_model() -> String {\n \"glm-4-air\".to_string()\n}\n\nimpl Default for AppSettings {\n fn default() -> Self {\n Self {\n api_key: None,\n default_model: \"glm-4.7\".to_string(),\n enable_thinking_by_default: true,\n chat_model: \"glm-4.7\".to_string(),\n thinking_model: \"glm-4-air\".to_string(),\n }\n }\n}\n\n/// 模型信息\n#[frb]\n#[derive(Debug, Clone)]\npub struct ModelInfo {\n pub id: String,\n pub name: String,\n /// 最大输入上下文 token 数\n pub context_tokens: usize,\n /// 最大输出 token 数\n pub max_output_tokens: usize,\n pub supports_thinking: bool,\n}\n\n/// 记忆上下文增强卡片 — 为每条记忆附加结构化元信息\n/// 参考智谱上下文增强技术:为知识切片\"恢复记忆\"\n/// 包含来源信息、主题概括、关键实体、歧义消除\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemoryContextCard {\n /// 来源:涵盖的轮次范围描述\n pub source_range: String,\n /// 主题标签(1-3个关键词)\n pub topic_tags: Vec<String>,\n /// 关键实体(人物、地点、物品等)\n pub key_entities: Vec<String>,\n /// 情感基调(正/负/中性 + 强度)\n pub emotional_tone: String,\n /// 因果关联:与其他记忆的关联描述\n pub causal_links: Vec<String>,\n}\n\n/// 分级压缩排级 — 类似军队排级的信息优先级\n/// 当记忆条目过多需要二次压缩时,按排级决定保留优先级\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub enum MemoryTier {\n /// 最高级:身份锚点(姓名、核心设定、与用户关系)— 永不丢弃\n Identity,\n /// 高级:不可逆事件(关键转折、承诺、约定)— 极少丢弃\n CriticalEvent,\n /// 中级:关系动态(亲密度变化、信任变化)— 可合并但不丢弃\n RelationshipDynamic,\n /// 普通:状态信息(当前情绪、物理状态)— 可被最新状态覆盖\n CurrentState,\n /// 低级:场景细节(氛围、环境描写)— 可安全丢弃\n SceneDetail,\n}\n\n/// 记忆检索结果\n#[frb]\n#[derive(Debug, Clone)]\npub struct MemorySearchResult {\n pub summary: String,\n pub core_facts: Vec<String>,\n pub relevance_score: f64,\n}\n"}, "11bb6170fb0c9acfaac81a9fe1fa48fe1b46d0af": {"t": 1785761058.974718, "n": 3577, "h": "b54005c239242003", "c": "use flutter_rust_bridge::frb;\nuse serde::{Deserialize, Serialize};\n\n/// 聊天流事件 - 通过 flutter_rust_bridge Stream 传递给 Flutter\n#[frb]\n#[derive(Debug, Clone)]\npub enum ChatStreamEvent {\n /// 正常内容增量\n ContentDelta(String),\n /// 思考内容增量\n ThinkingDelta(String),\n /// 流结束\n Done,\n /// 错误\n Error(String),\n}\n\n/// 消息类型标记:say(对话)或 do(动作/旁白)\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageType {\n Say,\n Do,\n Mixed, // 同时包含 say 和 do\n}\n\nimpl Default for MessageType {\n fn default() -> Self {\n MessageType::Say\n }\n}\n\n/// 单条消息\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Message {\n pub id: String,\n pub role: MessageRole,\n pub content: String,\n pub thinking_content: Option<String>,\n pub model: String,\n pub timestamp: i64,\n #[serde(default)]\n pub message_type: MessageType,\n}\n\n/// 消息角色\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum MessageRole {\n User,\n Assistant,\n System,\n}\n\n/// 对话风格\n#[frb]\n#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]\npub enum DialogueStyle {\n /// 默认自由对话\n Free,\n /// 纯对话模式(say only)\n SayOnly,\n /// 纯动作/旁白模式(do only)\n DoOnly,\n /// 混合模式(say + do 自动识别)\n Mixed,\n}\n\nimpl Default for DialogueStyle {\n fn default() -> Self {\n DialogueStyle::Mixed\n }\n}\n\n/// 对话\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct Conversation {\n pub id: String,\n pub title: String,\n pub messages: Vec<Message>,\n pub model: String,\n pub created_at: i64,\n pub updated_at: i64,\n #[serde(default)]\n pub dialogue_style: DialogueStyle,\n #[serde(default)]\n pub turn_count: u32,\n #[serde(default)]\n pub memory_summaries: Vec<MemorySummary>,\n}\n\n/// 记忆摘要条目\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct MemorySummary {\n pub id: String,\n pub summary: String,\n /// 核心身份/事件等不可变信息\n pub core_facts: Vec<String>,\n /// 涵盖的消息范围 [start_turn, end_turn]\n pub turn_range_start: u32,\n pub turn_range_end: u32,\n pub created_at: i64,\n /// BM25 关键词索引\n pub keywords: Vec<String>,\n}\n\n/// 对话摘要(用于列表展示)\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct ConversationSummary {\n pub id: String,\n pub title: String,\n pub last_message_preview: String,\n pub model: String,\n pub updated_at: i64,\n}\n\n/// 应用设置\n#[frb]\n#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]\npub struct AppSettings {\n pub api_key: Option<String>,\n pub default_model: String,\n pub enable_thinking_by_default: bool,\n #[serde(default = \"default_chat_model\")]\n pub chat_model: String,\n #[serde(default = \"default_thinking_model\")]\n pub thinking_model: String,\n}\n\nfn default_chat_model() -> String {\n \"glm-4.7\".to_string()\n}\n\nfn default_thinking_model() -> String {\n \"glm-4-air\".to_string()\n}\n\nimpl Default for AppSettings {\n fn default() -> Self {\n Self {\n api_key: None,\n default_model: \"glm-4.7\".to_string(),\n enable_thinking_by_default: true,\n chat_model: \"glm-4.7\".to_string(),\n thinking_model: \"glm-4-air\".to_string(),\n }\n }\n}\n\n/// 模型信息\n#[frb]\n#[derive(Debug, Clone)]\npub struct ModelInfo {\n pub id: String,\n pub name: String,\n pub context_tokens: usize,\n pub supports_thinking: bool,\n}\n\n/// 记忆检索结果\n#[frb]\n#[derive(Debug, Clone)]\npub struct MemorySearchResult {\n pub summary: String,\n pub core_facts: Vec<String>,\n pub relevance_score: f64,\n}\n"}}}}