openclaw_channels/
routing.rs1use openclaw_core::types::{AgentId, ChannelId, PeerId};
4
5pub struct AgentRouter {
7 routes: Vec<RouteRule>,
8 default_agent: AgentId,
9}
10
11#[derive(Debug, Clone)]
13pub struct RouteRule {
14 pub channel: Option<String>,
16 pub peer_pattern: Option<String>,
18 pub agent_id: AgentId,
20 pub priority: i32,
22}
23
24impl AgentRouter {
25 #[must_use]
27 pub const fn new(default_agent: AgentId) -> Self {
28 Self {
29 routes: Vec::new(),
30 default_agent,
31 }
32 }
33
34 pub fn add_rule(&mut self, rule: RouteRule) {
36 self.routes.push(rule);
37 self.routes.sort_by(|a, b| b.priority.cmp(&a.priority));
38 }
39
40 #[must_use]
42 pub fn route(&self, channel: &ChannelId, peer_id: &PeerId) -> &AgentId {
43 for rule in &self.routes {
44 if let Some(ch) = &rule.channel {
45 if ch != "*" && ch != channel.as_ref() {
46 continue;
47 }
48 }
49
50 if let Some(pattern) = &rule.peer_pattern {
51 if pattern != "*" && pattern != peer_id.as_ref() {
52 continue;
53 }
54 }
55
56 return &rule.agent_id;
57 }
58
59 &self.default_agent
60 }
61}
62
63impl Default for AgentRouter {
64 fn default() -> Self {
65 Self::new(AgentId::default_agent())
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn test_default_routing() {
75 let router = AgentRouter::default();
76 let agent = router.route(&ChannelId::telegram(), &PeerId::new("123"));
77 assert_eq!(agent.as_ref(), "default");
78 }
79
80 #[test]
81 fn test_specific_routing() {
82 let mut router = AgentRouter::default();
83 router.add_rule(RouteRule {
84 channel: Some("telegram".to_string()),
85 peer_pattern: Some("vip123".to_string()),
86 agent_id: AgentId::new("vip-agent"),
87 priority: 100,
88 });
89
90 let agent = router.route(&ChannelId::telegram(), &PeerId::new("vip123"));
91 assert_eq!(agent.as_ref(), "vip-agent");
92
93 let agent = router.route(&ChannelId::telegram(), &PeerId::new("other"));
94 assert_eq!(agent.as_ref(), "default");
95 }
96}