1use serde_json::{json, Value};
10
11use crate::scripting::event_handler::EventPattern;
12use crate::scripting::{EventHandlerConfig, EventHandlerType};
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum Driver {
16 Manual,
18 Llm,
21 Silent,
23 Rules,
25}
26
27impl Driver {
28 pub fn label(&self) -> &'static str {
30 match self {
31 Driver::Manual => "MANUAL",
32 Driver::Llm => "LLM",
33 Driver::Silent => "SILENT",
34 Driver::Rules => "RULES",
35 }
36 }
37
38 pub fn describe(&self) -> &'static str {
40 match self {
41 Driver::Manual => "you answer each event here",
42 Driver::Llm => "the model answers, from the instruction",
43 Driver::Silent => "events are acknowledged and never answered",
44 Driver::Rules => "a wildcard rule answers (script or fixed actions)",
45 }
46 }
47
48 pub fn next(&self) -> Driver {
51 match self {
52 Driver::Manual => Driver::Llm,
53 Driver::Llm => Driver::Silent,
54 Driver::Silent | Driver::Rules => Driver::Manual,
55 }
56 }
57}
58
59pub fn driver_of(routing: Option<&EventHandlerConfig>) -> Driver {
61 let Some(config) = routing else {
62 return Driver::Llm;
63 };
64 let wildcard = config
65 .handlers
66 .iter()
67 .find(|h| matches!(h.event_pattern, EventPattern::Wildcard));
68 match wildcard.map(|h| &h.handler) {
69 None => Driver::Llm,
70 Some(EventHandlerType::Manual { .. }) => Driver::Manual,
71 Some(EventHandlerType::Llm { .. }) => Driver::Llm,
72 Some(EventHandlerType::Static { actions }) if actions.is_empty() => Driver::Silent,
73 Some(EventHandlerType::Static { .. }) | Some(EventHandlerType::Script { .. }) => {
74 Driver::Rules
75 }
76 }
77}
78
79pub fn specific_rule_count(routing: Option<&EventHandlerConfig>) -> usize {
81 routing
82 .map(|c| {
83 c.handlers
84 .iter()
85 .filter(|h| !matches!(h.event_pattern, EventPattern::Wildcard))
86 .count()
87 })
88 .unwrap_or(0)
89}
90
91pub fn handlers_with_driver(routing: Option<&EventHandlerConfig>, driver: Driver) -> Vec<Value> {
98 let mut out: Vec<Value> = routing
99 .map(|c| {
100 c.handlers
101 .iter()
102 .filter(|h| !matches!(h.event_pattern, EventPattern::Wildcard))
103 .filter_map(|h| serde_json::to_value(h).ok())
104 .collect()
105 })
106 .unwrap_or_default();
107 match driver {
108 Driver::Llm => {}
109 Driver::Silent => out.push(json!({
110 "event_pattern": "*",
111 "handler": {"type": "static", "actions": []}
112 })),
113 Driver::Manual | Driver::Rules => out.push(json!({
114 "event_pattern": "*",
115 "handler": {"type": "manual"}
116 })),
117 }
118 out
119}