apollo/memory/
principal.rs1use std::collections::HashMap;
4use std::sync::Arc;
5
6use crate::memory::MemoryBackend;
7
8pub const PRINCIPAL_NS: &str = "principal";
9pub const ALIASES_KEY: &str = "chat_aliases";
10
11pub fn default_aliases(principal_id: &str) -> HashMap<String, String> {
12 let mut m = HashMap::new();
13 m.insert("cli".to_string(), principal_id.to_string());
14 m.insert("heartbeat".to_string(), principal_id.to_string());
15 m
16}
17
18pub async fn load_chat_aliases(
19 memory: &Arc<dyn MemoryBackend>,
20 principal_id: &str,
21) -> HashMap<String, String> {
22 let mut aliases = default_aliases(principal_id);
23 if let Ok(Some(entry)) = memory.recall(PRINCIPAL_NS, ALIASES_KEY).await {
24 if let Ok(extra) = serde_json::from_str::<HashMap<String, String>>(&entry.value) {
25 aliases.extend(extra);
26 }
27 }
28 aliases
29}
30
31pub fn resolve_history_chat_ids(
32 incoming_chat_id: &str,
33 principal_id: &str,
34 aliases: &HashMap<String, String>,
35) -> Vec<String> {
36 let mut ids: Vec<String> = Vec::new();
37 let canonical = aliases
38 .get(incoming_chat_id)
39 .cloned()
40 .unwrap_or_else(|| incoming_chat_id.to_string());
41
42 ids.push(canonical.clone());
43 ids.push(incoming_chat_id.to_string());
44
45 for (alias, target) in aliases {
46 if target == &canonical || target == principal_id {
47 ids.push(alias.clone());
48 }
49 }
50 ids.push(principal_id.to_string());
51 ids.sort();
52 ids.dedup();
53 ids
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn resolve_ids() {
62 let mut a = default_aliases("user-1");
63 a.insert("12345".to_string(), "user-1".to_string());
64 let ids = resolve_history_chat_ids("12345", "user-1", &a);
65 assert!(ids.contains(&"12345".to_string()));
66 assert!(ids.contains(&"user-1".to_string()));
67 }
68}