agentzero_channels/channels/
cli.rs1use super::helpers;
2use crate::{Channel, ChannelMessage, SendMessage};
3use async_trait::async_trait;
4use tokio::io::{self, AsyncBufReadExt, BufReader};
5
6super::channel_meta!(CLI_DESCRIPTOR, "cli", "CLI");
7
8pub struct CliChannel;
9
10#[async_trait]
11impl Channel for CliChannel {
12 fn name(&self) -> &str {
13 "cli"
14 }
15
16 async fn send(&self, message: &SendMessage) -> anyhow::Result<()> {
17 println!("{}", message.content);
18 Ok(())
19 }
20
21 async fn listen(
22 &self,
23 tx: tokio::sync::mpsc::Sender<ChannelMessage>,
24 ) -> anyhow::Result<()> {
25 let stdin = io::stdin();
26 let reader = BufReader::new(stdin);
27 let mut lines = reader.lines();
28
29 while let Ok(Some(line)) = lines.next_line().await {
30 let line = line.trim().to_string();
31 if line.is_empty() {
32 continue;
33 }
34 if line == "/quit" || line == "/exit" {
35 break;
36 }
37
38 let msg = ChannelMessage {
39 id: helpers::new_message_id(),
40 sender: "user".to_string(),
41 reply_target: "user".to_string(),
42 content: line,
43 channel: "cli".to_string(),
44 timestamp: helpers::now_epoch_secs(),
45 thread_ts: None,
46 privacy_boundary: String::new(),
47 };
48
49 if tx.send(msg).await.is_err() {
50 break;
51 }
52 }
53 Ok(())
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn cli_channel_name() {
63 let ch = CliChannel;
64 assert_eq!(ch.name(), "cli");
65 }
66
67 #[tokio::test]
68 async fn cli_channel_send_does_not_panic() {
69 let ch = CliChannel;
70 let msg = SendMessage::new("test output", "user");
71 assert!(ch.send(&msg).await.is_ok());
72 }
73
74 #[tokio::test]
75 async fn cli_channel_health_check() {
76 let ch = CliChannel;
77 assert!(ch.health_check().await);
78 }
79}