agentmux_srv/backend/notify/
sources.rs1#[derive(Debug, PartialEq, Eq)]
16pub struct AskedQuestion {
17 pub text: Option<String>,
18 pub count: usize,
19}
20
21pub fn ask_user_question(frame: &serde_json::Value) -> Option<AskedQuestion> {
25 if frame.get("type").and_then(|v| v.as_str()) != Some("control_request") {
26 return None;
27 }
28 let req = frame.get("request")?;
29 if req.get("subtype").and_then(|v| v.as_str()) != Some("can_use_tool") {
30 return None;
31 }
32 if req.get("tool_name").and_then(|v| v.as_str()) != Some("AskUserQuestion") {
33 return None;
34 }
35 let questions = req.get("input").and_then(|i| i.get("questions")).and_then(|q| q.as_array());
36 Some(AskedQuestion {
37 text: questions
38 .and_then(|q| q.first())
39 .and_then(|q| q.get("question"))
40 .and_then(|t| t.as_str())
41 .map(str::to_string),
42 count: questions.map_or(0, Vec::len),
43 })
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use serde_json::json;
50
51 #[test]
52 fn detects_ask_user_question_and_extracts_text() {
53 let f = json!({"type":"control_request","request_id":"r1","request":{
54 "subtype":"can_use_tool","tool_name":"AskUserQuestion","tool_use_id":"t1",
55 "input":{"questions":[{"question":"Which branch?","header":"Branch","options":[]}]}}});
56 assert_eq!(ask_user_question(&f), Some(AskedQuestion { text: Some("Which branch?".to_string()), count: 1 }));
57 }
58
59 #[test]
60 fn counts_every_question_in_the_call() {
61 let f = json!({"type":"control_request","request":{"subtype":"can_use_tool","tool_name":"AskUserQuestion",
62 "input":{"questions":[{"question":"Which branch?"},{"question":"Squash?"},{"question":"Tag it?"}]}}});
63 assert_eq!(ask_user_question(&f), Some(AskedQuestion { text: Some("Which branch?".to_string()), count: 3 }));
64 }
65
66 #[test]
67 fn tolerates_missing_text_and_ignores_other_frames() {
68 let no_text = json!({"type":"control_request","request":{"subtype":"can_use_tool","tool_name":"AskUserQuestion","input":{}}});
69 assert_eq!(ask_user_question(&no_text), Some(AskedQuestion { text: None, count: 0 }));
70 let bash = json!({"type":"control_request","request":{"subtype":"can_use_tool","tool_name":"Bash","input":{}}});
71 assert_eq!(ask_user_question(&bash), None);
72 let other = json!({"type":"control_request","request":{"subtype":"interrupt"}});
73 assert_eq!(ask_user_question(&other), None);
74 assert_eq!(ask_user_question(&json!({"type":"control_response"})), None);
75 assert_eq!(ask_user_question(&json!({"type":"assistant"})), None);
76 }
77}