{"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,\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,\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,\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,\n pub turn_range_start: u32,\n pub turn_range_end: u32,\n pub created_at: i64,\n pub keywords: Vec,\n #[serde(default)]\n pub compression_generation: u32,\n #[serde(default)]\n pub context_card: Option,\n #[serde(default)]\n pub fact_tiers: Vec,\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,\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,\n pub api_url: String,\n pub chat_model: String,\n pub thinking_model: Option,\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 {\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,\n pub key_entities: Vec,\n pub emotional_tone: String,\n pub causal_links: Vec,\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,\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,\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,\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,\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,\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,\n pub turn_range_start: u32,\n pub turn_range_end: u32,\n pub created_at: i64,\n pub keywords: Vec,\n #[serde(default)]\n pub compression_generation: u32,\n #[serde(default)]\n pub context_card: Option,\n #[serde(default)]\n pub fact_tiers: Vec,\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,\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,\n pub api_url: String,\n pub chat_model: String,\n pub thinking_model: Option,\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 {\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,\n pub key_entities: Vec,\n pub emotional_tone: String,\n pub causal_links: Vec,\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,\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,\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,\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,\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,\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,\n pub turn_range_start: u32,\n pub turn_range_end: u32,\n pub created_at: i64,\n pub keywords: Vec,\n #[serde(default)]\n pub compression_generation: u32,\n #[serde(default)]\n pub context_card: Option,\n #[serde(default)]\n pub fact_tiers: Vec,\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,\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,\n pub api_url: String,\n pub chat_model: String,\n pub thinking_model: Option,\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 {\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,\n pub key_entities: Vec,\n pub emotional_tone: String,\n pub causal_links: Vec,\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,\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,\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,\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,\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,\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,\n pub turn_range_start: u32,\n pub turn_range_end: u32,\n pub created_at: i64,\n pub keywords: Vec,\n #[serde(default)]\n pub compression_generation: u32,\n #[serde(default)]\n pub context_card: Option,\n #[serde(default)]\n pub fact_tiers: Vec,\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,\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,\n pub key_entities: Vec,\n pub emotional_tone: String,\n pub causal_links: Vec,\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,\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,\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,\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,\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,\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,\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,\n /// 压缩代数:每次被合并/压缩时 +1,代数越高信息损耗风险越大\n #[serde(default)]\n pub compression_generation: u32,\n /// 上下文增强卡片 — 结构化元信息,提升检索精度\n #[serde(default)]\n pub context_card: Option,\n /// 每条核心事实的排级分类,与 core_facts 一一对应\n #[serde(default)]\n pub fact_tiers: Vec,\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,\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,\n /// 关键实体(人物、地点、物品等)\n pub key_entities: Vec,\n /// 情感基调(正/负/中性 + 强度)\n pub emotional_tone: String,\n /// 因果关联:与其他记忆的关联描述\n pub causal_links: Vec,\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,\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,\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,\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,\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,\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,\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,\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,\n pub relevance_score: f64,\n}\n"}}}}