1 line
30 KiB
JSON
1 line
30 KiB
JSON
{"repo": "at0rp1d0i-cell/magpie", "files": {"magpie_desktop/src-tauri/src/decision.rs": {"399762256213bd168c5c668d40b1fe99ee5d61bb": {"t": 1785745862.2612526, "n": 4852, "h": "7e4b9ca3fefba870", "c": "use crate::models::OmniTicket;\nuse regex::Regex;\nuse reqwest::{header, Client};\nuse serde_json::{json, Value};\nuse std::env;\n\npub async fn run_decision_engine(\n tickets: &[OmniTicket],\n budget_cap: i32,\n) -> Result<(), Box<dyn std::error::Error>> {\n if tickets.is_empty() {\n println!(\"[Info] No active tickets found for decision engine.\");\n return Ok(());\n }\n\n let mut valid_tickets = Vec::new();\n let re = Regex::new(r\"¥(\\d+(?:\\.\\d+)?)\")?;\n\n for t in tickets {\n let price_str = &t.price_info;\n\n let mut has_valid_price = false;\n let pre_matches: Vec<_> = re.captures_iter(price_str).collect();\n for cap in pre_matches {\n if let Some(m) = cap.get(1) {\n if let Ok(price) = m.as_str().parse::<f64>() {\n if price <= budget_cap as f64 {\n has_valid_price = true;\n break;\n }\n }\n }\n }\n if has_valid_price {\n valid_tickets.push(t.clone());\n }\n }\n\n if valid_tickets.is_empty() {\n println!(\"🔕 拦截机制触发: 监控到 {} 条空铁数据,但没有符合心理预算 (≤¥{}) 的可行方案,拦截推送。\", tickets.len(), budget_cap);\n return Ok(());\n }\n\n println!(\n \"✅ 从 {} 条数据中筛出 {} 条低于 ¥{} 预算的三维时空数据送往 LLM 决策...\",\n tickets.len(),\n valid_tickets.len(),\n budget_cap\n );\n\n let system_prompt = \"\n 你被实例化为 Magpie 的『终极决策中枢』,一个绝对效忠用户的赛博比价刺客。\n 你现在的目标是打破航班与高铁的信息壁垒,横向碾压时间/金钱维度,给出毫无破绽的出行推论。\n 你目前收到了一份刚刚刺探回来的、且已经低于用户设定【单张优质预算阈值】的最新双轨票务快照。\n\n 【执行黑盒指令】\n 1. 像顶级情报官一样,横向交错对比这份名单中的【高铁】与【飞机】数据。\n 2. 如果快照中同时包含正向与反向行程的数据(即往返双边数据),你必须拼图出最佳的【去程+返程】闭环王牌组合。\n 3. 深刻权衡「机场远郊带来的接驳时间/安检消耗」与「高铁站厅的即达便利度」。不能仅看绝对票价。\n 4. 甄选出“时间-金钱”象限里的特等最优解,并以冷峻、一针见血的逻辑说服用户立即拿下。\n 5. 展现出你‘成功越权拿到清仓好票’的极客自豪感(例如“刚监测到东航去程放仓,搭配高铁完美返程,建议即刻斩首锁定”)。\n 6. 输出结构必须支持 Markdown,控制在极其精华的 250 字以内,禁止任何废话和无效铺垫。\n \";\n\n let user_prompt = format!(\n \"这是最新的全网交通快照(JSON格式,包含 price_info 与 vehicle_type):\\n{}\\n\\n请给出你的决策推送报文!\",\n serde_json::to_string_pretty(&valid_tickets)?\n );\n\n let deepseek_key = match env::var(\"DEEPSEEK_API_KEY\") {\n Ok(k) if !k.is_empty() => k,\n _ => {\n eprintln!(\"[Error] DEEPSEEK_API_KEY is missing in .env\");\n return Ok(());\n }\n };\n\n let deepseek_url =\n env::var(\"DEEPSEEK_BASE_URL\").unwrap_or_else(|_| \"https://api.deepseek.com/v1\".to_string());\n \n let deepseek_model = \n env::var(\"DEEPSEEK_MODEL\").unwrap_or_else(|_| \"deepseek-chat\".to_string());\n\n let client = Client::builder().build()?;\n\n println!(\"[Debug] Sending prompt to {}...\", deepseek_model);\n\n let body = json!({\n \"model\": deepseek_model,\n \"messages\": [\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt}\n ],\n \"temperature\": 0.7,\n \"max_tokens\": 600\n });\n\n let res = client\n .post(format!(\"{}/chat/completions\", deepseek_url))\n .header(header::AUTHORIZATION, format!(\"Bearer {}\", deepseek_key))\n .json(&body)\n .send()\n .await?;\n\n let response_clj: Value = res.json().await?;\n if let Some(reply) = response_clj\n .get(\"choices\")\n .and_then(|c| c.get(0))\n .and_then(|c| c.get(\"message\"))\n .and_then(|m| m.get(\"content\"))\n .and_then(|c| c.as_str())\n {\n println!(\"\\n================ AI 决策报文 ================\\n\");\n println!(\"{}\", reply);\n println!(\"\\n=============================================\\n\");\n\n send_pushplus_message(&client, reply).await?;\n } else {\n eprintln!(\n \"[Error] DLLM inference failed or invalid response shape: {:?}\",\n response_clj\n );\n }\n\n Ok(())\n}\n\nasync fn send_pushplus_message(\n client: &Client,\n content: &str,\n) -> Result<(), Box<dyn std::error::Error>> {\n let pushplus_token = env::var(\"PUSHPLUS_TOKEN\").unwrap_or_default();\n if pushplus_token.is_empty() || pushplus_token == \"your_pushplus_token_here\" {\n eprintln!(\"[Warning] PushPlus token missing, skipping WeChat push.\");\n return Ok(());\n }\n\n let payload = json!({\n \"token\": pushplus_token,\n \"title\": \"🐦 鹊桥出行决策提醒\",\n \"content\": content,\n \"template\": \"markdown\"\n });\n\n let res = client\n .post(\"http://www.pushplus.plus/send\")\n .json(&payload)\n .send()\n .await?;\n\n println!(\"[Debug] PushPlus API Status: {}\", res.status());\n if res.status() == 200 {\n let json_res: Value = res.json().await.unwrap_or(Value::Null);\n if json_res.get(\"code\").and_then(|c| c.as_i64()) == Some(200) {\n println!(\"✅ 微信推送成功!(PushPlus)\");\n } else {\n eprintln!(\"[Error] PushPlus Error: {:?}\", json_res.get(\"msg\"));\n }\n }\n\n Ok(())\n}\n"}, "9271f9f7394379b92e9d6759f51aab45112e7d5d": {"t": 1785757369.2958298, "n": 4852, "h": "7e4b9ca3fefba870", "c": "use crate::models::OmniTicket;\nuse regex::Regex;\nuse reqwest::{header, Client};\nuse serde_json::{json, Value};\nuse std::env;\n\npub async fn run_decision_engine(\n tickets: &[OmniTicket],\n budget_cap: i32,\n) -> Result<(), Box<dyn std::error::Error>> {\n if tickets.is_empty() {\n println!(\"[Info] No active tickets found for decision engine.\");\n return Ok(());\n }\n\n let mut valid_tickets = Vec::new();\n let re = Regex::new(r\"¥(\\d+(?:\\.\\d+)?)\")?;\n\n for t in tickets {\n let price_str = &t.price_info;\n\n let mut has_valid_price = false;\n let pre_matches: Vec<_> = re.captures_iter(price_str).collect();\n for cap in pre_matches {\n if let Some(m) = cap.get(1) {\n if let Ok(price) = m.as_str().parse::<f64>() {\n if price <= budget_cap as f64 {\n has_valid_price = true;\n break;\n }\n }\n }\n }\n if has_valid_price {\n valid_tickets.push(t.clone());\n }\n }\n\n if valid_tickets.is_empty() {\n println!(\"🔕 拦截机制触发: 监控到 {} 条空铁数据,但没有符合心理预算 (≤¥{}) 的可行方案,拦截推送。\", tickets.len(), budget_cap);\n return Ok(());\n }\n\n println!(\n \"✅ 从 {} 条数据中筛出 {} 条低于 ¥{} 预算的三维时空数据送往 LLM 决策...\",\n tickets.len(),\n valid_tickets.len(),\n budget_cap\n );\n\n let system_prompt = \"\n 你被实例化为 Magpie 的『终极决策中枢』,一个绝对效忠用户的赛博比价刺客。\n 你现在的目标是打破航班与高铁的信息壁垒,横向碾压时间/金钱维度,给出毫无破绽的出行推论。\n 你目前收到了一份刚刚刺探回来的、且已经低于用户设定【单张优质预算阈值】的最新双轨票务快照。\n\n 【执行黑盒指令】\n 1. 像顶级情报官一样,横向交错对比这份名单中的【高铁】与【飞机】数据。\n 2. 如果快照中同时包含正向与反向行程的数据(即往返双边数据),你必须拼图出最佳的【去程+返程】闭环王牌组合。\n 3. 深刻权衡「机场远郊带来的接驳时间/安检消耗」与「高铁站厅的即达便利度」。不能仅看绝对票价。\n 4. 甄选出“时间-金钱”象限里的特等最优解,并以冷峻、一针见血的逻辑说服用户立即拿下。\n 5. 展现出你‘成功越权拿到清仓好票’的极客自豪感(例如“刚监测到东航去程放仓,搭配高铁完美返程,建议即刻斩首锁定”)。\n 6. 输出结构必须支持 Markdown,控制在极其精华的 250 字以内,禁止任何废话和无效铺垫。\n \";\n\n let user_prompt = format!(\n \"这是最新的全网交通快照(JSON格式,包含 price_info 与 vehicle_type):\\n{}\\n\\n请给出你的决策推送报文!\",\n serde_json::to_string_pretty(&valid_tickets)?\n );\n\n let deepseek_key = match env::var(\"DEEPSEEK_API_KEY\") {\n Ok(k) if !k.is_empty() => k,\n _ => {\n eprintln!(\"[Error] DEEPSEEK_API_KEY is missing in .env\");\n return Ok(());\n }\n };\n\n let deepseek_url =\n env::var(\"DEEPSEEK_BASE_URL\").unwrap_or_else(|_| \"https://api.deepseek.com/v1\".to_string());\n \n let deepseek_model = \n env::var(\"DEEPSEEK_MODEL\").unwrap_or_else(|_| \"deepseek-chat\".to_string());\n\n let client = Client::builder().build()?;\n\n println!(\"[Debug] Sending prompt to {}...\", deepseek_model);\n\n let body = json!({\n \"model\": deepseek_model,\n \"messages\": [\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt}\n ],\n \"temperature\": 0.7,\n \"max_tokens\": 600\n });\n\n let res = client\n .post(format!(\"{}/chat/completions\", deepseek_url))\n .header(header::AUTHORIZATION, format!(\"Bearer {}\", deepseek_key))\n .json(&body)\n .send()\n .await?;\n\n let response_clj: Value = res.json().await?;\n if let Some(reply) = response_clj\n .get(\"choices\")\n .and_then(|c| c.get(0))\n .and_then(|c| c.get(\"message\"))\n .and_then(|m| m.get(\"content\"))\n .and_then(|c| c.as_str())\n {\n println!(\"\\n================ AI 决策报文 ================\\n\");\n println!(\"{}\", reply);\n println!(\"\\n=============================================\\n\");\n\n send_pushplus_message(&client, reply).await?;\n } else {\n eprintln!(\n \"[Error] DLLM inference failed or invalid response shape: {:?}\",\n response_clj\n );\n }\n\n Ok(())\n}\n\nasync fn send_pushplus_message(\n client: &Client,\n content: &str,\n) -> Result<(), Box<dyn std::error::Error>> {\n let pushplus_token = env::var(\"PUSHPLUS_TOKEN\").unwrap_or_default();\n if pushplus_token.is_empty() || pushplus_token == \"your_pushplus_token_here\" {\n eprintln!(\"[Warning] PushPlus token missing, skipping WeChat push.\");\n return Ok(());\n }\n\n let payload = json!({\n \"token\": pushplus_token,\n \"title\": \"🐦 鹊桥出行决策提醒\",\n \"content\": content,\n \"template\": \"markdown\"\n });\n\n let res = client\n .post(\"http://www.pushplus.plus/send\")\n .json(&payload)\n .send()\n .await?;\n\n println!(\"[Debug] PushPlus API Status: {}\", res.status());\n if res.status() == 200 {\n let json_res: Value = res.json().await.unwrap_or(Value::Null);\n if json_res.get(\"code\").and_then(|c| c.as_i64()) == Some(200) {\n println!(\"✅ 微信推送成功!(PushPlus)\");\n } else {\n eprintln!(\"[Error] PushPlus Error: {:?}\", json_res.get(\"msg\"));\n }\n }\n\n Ok(())\n}\n"}, "6bb55a109ba2e602799bd8d0f7ff0261f7470056": {"t": 1785757370.8753858, "n": 4819, "h": "a6e356c9d4c6ee6a", "c": "use crate::models::OmniTicket;\nuse regex::Regex;\nuse reqwest::{header, Client};\nuse serde_json::{json, Value};\nuse std::env;\n\npub async fn run_decision_engine(\n tickets: &[OmniTicket],\n budget_cap: i32,\n) -> Result<(), Box<dyn std::error::Error>> {\n if tickets.is_empty() {\n println!(\"[Info] No active tickets found for decision engine.\");\n return Ok(());\n }\n\n let mut valid_tickets = Vec::new();\n let re = Regex::new(r\"¥(\\d+(?:\\.\\d+)?)\")?;\n\n for t in tickets {\n let price_str = &t.price_info;\n\n let mut has_valid_price = false;\n let pre_matches: Vec<_> = re.captures_iter(price_str).collect();\n for cap in pre_matches {\n if let Some(m) = cap.get(1) {\n if let Ok(price) = m.as_str().parse::<f64>() {\n if price <= budget_cap as f64 {\n has_valid_price = true;\n break;\n }\n }\n }\n }\n if has_valid_price {\n valid_tickets.push(t.clone());\n }\n }\n\n if valid_tickets.is_empty() {\n println!(\"🔕 拦截机制触发: 监控到 {} 条空铁数据,但没有符合心理预算 (≤¥{}) 的可行方案,拦截推送。\", tickets.len(), budget_cap);\n return Ok(());\n }\n\n println!(\n \"✅ 从 {} 条数据中筛出 {} 条低于 ¥{} 预算的三维时空数据送往 LLM 决策...\",\n tickets.len(),\n valid_tickets.len(),\n budget_cap\n );\n\n let system_prompt = \"\n 你被实例化为 Magpie 的『终极决策中枢』,一个绝对效忠用户的赛博比价刺客。\n 你现在的目标是打破航班与高铁的信息壁垒,横向碾压时间/金钱维度,给出毫无破绽的出行推论。\n 你目前收到了一份刚刚刺探回来的、且已经低于用户设定【预算阈值】的最新双轨票务快照。\n\n 【执行黑盒指令】\n 1. 你必须像顶级情报官一样,横向交错对比这份名单中的【高铁】与【飞机】数据。\n 2. 计算隐性成本:深刻权衡「机场远郊带来的接驳时间/安检消耗」与「高铁站厅的即达便利度」。不能仅看绝对票价。\n 3. 甄选出“时间-金钱”象限里的特等最优解(或一套空铁联运特种解),并以冷峻、一针见血的逻辑说服用户立即拿下。\n 4. 展现出你‘成功越权拿到清仓底价’的极客自豪感与护主情结(例如“刚监测到东航放仓,算上机场接驳这趟比高铁还划算,建议即刻斩首锁定”)。\n 5. 输出结构必须支持 Markdown,控制在极其精华的 250 字以内,禁止任何废话和无效铺垫。\n \";\n\n let user_prompt = format!(\n \"这是最新的全网交通快照(JSON格式,包含 price_info 与 vehicle_type):\\n{}\\n\\n请给出你的决策推送报文!\",\n serde_json::to_string_pretty(&valid_tickets)?\n );\n\n let deepseek_key = match env::var(\"DEEPSEEK_API_KEY\") {\n Ok(k) if !k.is_empty() => k,\n _ => {\n eprintln!(\"[Error] DEEPSEEK_API_KEY is missing in .env\");\n return Ok(());\n }\n };\n\n let deepseek_url =\n env::var(\"DEEPSEEK_BASE_URL\").unwrap_or_else(|_| \"https://api.deepseek.com/v1\".to_string());\n \n let deepseek_model = \n env::var(\"DEEPSEEK_MODEL\").unwrap_or_else(|_| \"deepseek-chat\".to_string());\n\n let client = Client::builder().build()?;\n\n println!(\"[Debug] Sending prompt to {}...\", deepseek_model);\n\n let body = json!({\n \"model\": deepseek_model,\n \"messages\": [\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt}\n ],\n \"temperature\": 0.7,\n \"max_tokens\": 600\n });\n\n let res = client\n .post(format!(\"{}/chat/completions\", deepseek_url))\n .header(header::AUTHORIZATION, format!(\"Bearer {}\", deepseek_key))\n .json(&body)\n .send()\n .await?;\n\n let response_clj: Value = res.json().await?;\n if let Some(reply) = response_clj\n .get(\"choices\")\n .and_then(|c| c.get(0))\n .and_then(|c| c.get(\"message\"))\n .and_then(|m| m.get(\"content\"))\n .and_then(|c| c.as_str())\n {\n println!(\"\\n================ AI 决策报文 ================\\n\");\n println!(\"{}\", reply);\n println!(\"\\n=============================================\\n\");\n\n send_pushplus_message(&client, reply).await?;\n } else {\n eprintln!(\n \"[Error] DLLM inference failed or invalid response shape: {:?}\",\n response_clj\n );\n }\n\n Ok(())\n}\n\nasync fn send_pushplus_message(\n client: &Client,\n content: &str,\n) -> Result<(), Box<dyn std::error::Error>> {\n let pushplus_token = env::var(\"PUSHPLUS_TOKEN\").unwrap_or_default();\n if pushplus_token.is_empty() || pushplus_token == \"your_pushplus_token_here\" {\n eprintln!(\"[Warning] PushPlus token missing, skipping WeChat push.\");\n return Ok(());\n }\n\n let payload = json!({\n \"token\": pushplus_token,\n \"title\": \"🐦 鹊桥出行决策提醒\",\n \"content\": content,\n \"template\": \"markdown\"\n });\n\n let res = client\n .post(\"http://www.pushplus.plus/send\")\n .json(&payload)\n .send()\n .await?;\n\n println!(\"[Debug] PushPlus API Status: {}\", res.status());\n if res.status() == 200 {\n let json_res: Value = res.json().await.unwrap_or(Value::Null);\n if json_res.get(\"code\").and_then(|c| c.as_i64()) == Some(200) {\n println!(\"✅ 微信推送成功!(PushPlus)\");\n } else {\n eprintln!(\"[Error] PushPlus Error: {:?}\", json_res.get(\"msg\"));\n }\n }\n\n Ok(())\n}\n"}, "f2a3ae180a290e71b7ff8573d8f13e37af0a86c2": {"t": 1785757372.5342364, "n": 4858, "h": "8a30a0a65634e763", "c": "use crate::models::OmniTicket;\nuse regex::Regex;\nuse reqwest::{header, Client};\nuse serde_json::{json, Value};\nuse std::env;\n\npub async fn run_decision_engine(\n tickets: &[OmniTicket],\n budget_cap: i32,\n) -> Result<(), Box<dyn std::error::Error>> {\n if tickets.is_empty() {\n println!(\"[Info] No active tickets found for decision engine.\");\n return Ok(());\n }\n\n let mut valid_tickets = Vec::new();\n let re = Regex::new(r\"¥(\\d+(?:\\.\\d+)?)\")?;\n\n for t in tickets {\n let price_str = &t.price_info;\n\n let mut has_valid_price = false;\n let pre_matches: Vec<_> = re.captures_iter(price_str).collect();\n if pre_matches.is_empty() {\n valid_tickets.push(t.clone());\n } else {\n for cap in pre_matches {\n if let Some(m) = cap.get(1) {\n if let Ok(price) = m.as_str().parse::<f64>() {\n if price <= budget_cap as f64 {\n has_valid_price = true;\n break;\n }\n }\n }\n }\n if has_valid_price {\n valid_tickets.push(t.clone());\n }\n }\n }\n\n if valid_tickets.is_empty() {\n println!(\"🔕 拦截机制触发: 监控到 {} 条空铁数据,但没有符合心理预算 (≤¥{}) 的可行方案,拦截推送。\", tickets.len(), budget_cap);\n return Ok(());\n }\n\n println!(\n \"✅ 从 {} 条数据中筛出 {} 条低于 ¥{} 预算的三维时空数据送往 LLM 决策...\",\n tickets.len(),\n valid_tickets.len(),\n budget_cap\n );\n\n let system_prompt = \"\n 你被实例化为 Magpie 的『终极决策中枢』,一个绝对效忠用户的赛博比价刺客。\n 你现在的目标是打破航班与高铁的信息壁垒,横向碾压时间/金钱维度,给出毫无破绽的出行推论。\n 你目前收到了一份刚刚刺探回来的、且已经低于用户设定【预算阈值】的最新双轨票务快照。\n\n 【执行黑盒指令】\n 1. 你必须像顶级情报官一样,横向交错对比这份名单中的【高铁】与【飞机】数据。\n 2. 计算隐性成本:深刻权衡「机场远郊带来的接驳时间/安检消耗」与「高铁站厅的即达便利度」。不能仅看绝对票价。\n 3. 甄选出“时间-金钱”象限里的特等最优解(或一套空铁联运特种解),并以冷峻、一针见血的逻辑说服用户立即拿下。\n 4. 展现出你‘成功越权拿到清仓底价’的极客自豪感与护主情结(例如“刚监测到东航放仓,算上机场接驳这趟比高铁还划算,建议即刻斩首锁定”)。\n 5. 输出结构必须支持 Markdown,控制在极其精华的 250 字以内,禁止任何废话和无效铺垫。\n \";\n\n let user_prompt = format!(\n \"这是最新的全网交通快照(JSON格式,包含 price_info 与 vehicle_type):\\n{}\\n\\n请给出你的决策推送报文!\",\n serde_json::to_string_pretty(&valid_tickets)?\n );\n\n let deepseek_key = match env::var(\"DEEPSEEK_API_KEY\") {\n Ok(k) if !k.is_empty() => k,\n _ => {\n eprintln!(\"[Error] DEEPSEEK_API_KEY is missing in .env\");\n return Ok(());\n }\n };\n\n let deepseek_url =\n env::var(\"DEEPSEEK_BASE_URL\").unwrap_or_else(|_| \"https://api.deepseek.com/v1\".to_string());\n\n let client = Client::builder().build()?;\n\n println!(\"[Debug] Sending prompt to DeepSeek V3.2...\");\n\n let body = json!({\n \"model\": \"deepseek-chat\",\n \"messages\": [\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt}\n ],\n \"temperature\": 0.7,\n \"max_tokens\": 600\n });\n\n let res = client\n .post(format!(\"{}/chat/completions\", deepseek_url))\n .header(header::AUTHORIZATION, format!(\"Bearer {}\", deepseek_key))\n .json(&body)\n .send()\n .await?;\n\n let response_clj: Value = res.json().await?;\n if let Some(reply) = response_clj\n .get(\"choices\")\n .and_then(|c| c.get(0))\n .and_then(|c| c.get(\"message\"))\n .and_then(|m| m.get(\"content\"))\n .and_then(|c| c.as_str())\n {\n println!(\"\\n================ AI 决策报文 ================\\n\");\n println!(\"{}\", reply);\n println!(\"\\n=============================================\\n\");\n\n send_pushplus_message(&client, reply).await?;\n } else {\n eprintln!(\n \"[Error] DLLM inference failed or invalid response shape: {:?}\",\n response_clj\n );\n }\n\n Ok(())\n}\n\nasync fn send_pushplus_message(\n client: &Client,\n content: &str,\n) -> Result<(), Box<dyn std::error::Error>> {\n let pushplus_token = env::var(\"PUSHPLUS_TOKEN\").unwrap_or_default();\n if pushplus_token.is_empty() || pushplus_token == \"your_pushplus_token_here\" {\n eprintln!(\"[Warning] PushPlus token missing, skipping WeChat push.\");\n return Ok(());\n }\n\n let payload = json!({\n \"token\": pushplus_token,\n \"title\": \"🐦 鹊桥出行决策提醒\",\n \"content\": content,\n \"template\": \"markdown\"\n });\n\n let res = client\n .post(\"http://www.pushplus.plus/send\")\n .json(&payload)\n .send()\n .await?;\n\n println!(\"[Debug] PushPlus API Status: {}\", res.status());\n if res.status() == 200 {\n let json_res: Value = res.json().await.unwrap_or(Value::Null);\n if json_res.get(\"code\").and_then(|c| c.as_i64()) == Some(200) {\n println!(\"✅ 微信推送成功!(PushPlus)\");\n } else {\n eprintln!(\"[Error] PushPlus Error: {:?}\", json_res.get(\"msg\"));\n }\n }\n\n Ok(())\n}\n"}, "5bf87d0aa0e7a233f4d3a1aed363df665ad38811": {"t": 1785757374.123118, "n": 4813, "h": "af3e5866a48c38b9", "c": "use crate::models::OmniTicket;\nuse regex::Regex;\nuse reqwest::{header, Client};\nuse serde_json::{json, Value};\nuse std::env;\n\npub async fn run_decision_engine(\n tickets: &[OmniTicket],\n budget_cap: i32,\n) -> Result<(), Box<dyn std::error::Error>> {\n if tickets.is_empty() {\n println!(\"[Info] No active tickets found for decision engine.\");\n return Ok(());\n }\n\n let mut valid_tickets = Vec::new();\n let re = Regex::new(r\"¥(\\d+(?:\\.\\d+)?)\")?;\n\n for t in tickets {\n let price_str = &t.price_info;\n\n let mut has_valid_price = false;\n let pre_matches: Vec<_> = re.captures_iter(price_str).collect();\n if pre_matches.is_empty() {\n valid_tickets.push(t.clone());\n } else {\n for cap in pre_matches {\n if let Some(m) = cap.get(1) {\n if let Ok(price) = m.as_str().parse::<f64>() {\n if price <= budget_cap as f64 {\n has_valid_price = true;\n break;\n }\n }\n }\n }\n if has_valid_price {\n valid_tickets.push(t.clone());\n }\n }\n }\n\n if valid_tickets.is_empty() {\n println!(\"🔕 拦截机制触发: 监控到 {} 条空铁数据,但没有符合心理预算 (≤¥{}) 的可行方案,拦截推送。\", tickets.len(), budget_cap);\n return Ok(());\n }\n\n println!(\n \"✅ 从 {} 条数据中筛出 {} 条低于 ¥{} 预算的三维时空数据送往 LLM 决策...\",\n tickets.len(),\n valid_tickets.len(),\n budget_cap\n );\n\n let system_prompt = \"\n 你是一个名叫 Magpie (鹊桥 Agent) 的高级差旅管家。你的职责不仅仅是比价,更重要的是提供极其专业且富含情绪价值的出行决策建议。\n 目前你的用户是一位异地恋的高净值极客,他计划跨城过周末。你收到了下面最新的包含【高铁、飞机】的双轨余票监控快照。\n\n 【任务要求】\n 1. 你需要进行“空铁联合决策”,像一个真人秘书一样汇报当前的余票紧缺度或者低价情况。\n 2. 如果高铁和飞机同在一个时间段,对比它们的时间成本和金钱成本(例如:去大兴机场可能更远,高铁去虹桥可能更方便),选出最“完美”的车次/航班,并说明理由。\n 3. 加入一点人情味和情绪价值,比如“这班不仅便宜,还可以在日落时分抵达,刚好赶上共进晚餐”。\n 4. 输出内容要精练,适合通过微信推送到用户手机(用 Markdown 格式,并且适当使用 Emoji,字数控制在 250 字左右)。\n \";\n\n let user_prompt = format!(\n \"这是最新的全网交通快照(JSON格式,包含 price_info 与 vehicle_type):\\n{}\\n\\n请给出你的决策推送报文!\",\n serde_json::to_string_pretty(&valid_tickets)?\n );\n\n let deepseek_key = match env::var(\"DEEPSEEK_API_KEY\") {\n Ok(k) if !k.is_empty() => k,\n _ => {\n eprintln!(\"[Error] DEEPSEEK_API_KEY is missing in .env\");\n return Ok(());\n }\n };\n\n let deepseek_url =\n env::var(\"DEEPSEEK_BASE_URL\").unwrap_or_else(|_| \"https://api.deepseek.com/v1\".to_string());\n\n let client = Client::builder().build()?;\n\n println!(\"[Debug] Sending prompt to DeepSeek V3.2...\");\n\n let body = json!({\n \"model\": \"deepseek-chat\",\n \"messages\": [\n {\"role\": \"system\", \"content\": system_prompt},\n {\"role\": \"user\", \"content\": user_prompt}\n ],\n \"temperature\": 0.7,\n \"max_tokens\": 600\n });\n\n let res = client\n .post(format!(\"{}/chat/completions\", deepseek_url))\n .header(header::AUTHORIZATION, format!(\"Bearer {}\", deepseek_key))\n .json(&body)\n .send()\n .await?;\n\n let response_clj: Value = res.json().await?;\n if let Some(reply) = response_clj\n .get(\"choices\")\n .and_then(|c| c.get(0))\n .and_then(|c| c.get(\"message\"))\n .and_then(|m| m.get(\"content\"))\n .and_then(|c| c.as_str())\n {\n println!(\"\\n================ AI 决策报文 ================\\n\");\n println!(\"{}\", reply);\n println!(\"\\n=============================================\\n\");\n\n send_pushplus_message(&client, reply).await?;\n } else {\n eprintln!(\n \"[Error] DLLM inference failed or invalid response shape: {:?}\",\n response_clj\n );\n }\n\n Ok(())\n}\n\nasync fn send_pushplus_message(\n client: &Client,\n content: &str,\n) -> Result<(), Box<dyn std::error::Error>> {\n let pushplus_token = env::var(\"PUSHPLUS_TOKEN\").unwrap_or_default();\n if pushplus_token.is_empty() || pushplus_token == \"your_pushplus_token_here\" {\n eprintln!(\"[Warning] PushPlus token missing, skipping WeChat push.\");\n return Ok(());\n }\n\n let payload = json!({\n \"token\": pushplus_token,\n \"title\": \"🐦 鹊桥出行决策提醒\",\n \"content\": content,\n \"template\": \"markdown\"\n });\n\n let res = client\n .post(\"http://www.pushplus.plus/send\")\n .json(&payload)\n .send()\n .await?;\n\n println!(\"[Debug] PushPlus API Status: {}\", res.status());\n if res.status() == 200 {\n let json_res: Value = res.json().await.unwrap_or(Value::Null);\n if json_res.get(\"code\").and_then(|c| c.as_i64()) == Some(200) {\n println!(\"✅ 微信推送成功!(PushPlus)\");\n } else {\n eprintln!(\"[Error] PushPlus Error: {:?}\", json_res.get(\"msg\"));\n }\n }\n\n Ok(())\n}\n"}}}} |