wactorz_interfaces/
cli.rs1use anyhow::Result;
14use tokio::io::{AsyncBufReadExt, BufReader};
15
16use wactorz_core::{ActorSystem, Message};
17
18pub async fn run_cli(system: ActorSystem) -> Result<()> {
23 let stdin = tokio::io::stdin();
24 let mut reader = BufReader::new(stdin).lines();
25
26 println!("AgentFlow CLI — type a message or /help for commands.");
27
28 while let Some(line) = reader.next_line().await? {
29 let trimmed = line.trim();
30 if trimmed.is_empty() {
31 continue;
32 }
33
34 if let Some(cmd) = trimmed.strip_prefix('/') {
35 handle_command(cmd, &system).await?;
36 if cmd.trim() == "quit" {
37 break;
38 }
39 } else {
40 dispatch_to_main_actor(trimmed, &system).await?;
41 }
42 }
43
44 Ok(())
45}
46
47async fn handle_command(cmd: &str, system: &ActorSystem) -> Result<()> {
49 let parts: Vec<&str> = cmd.splitn(2, ' ').collect();
50 match parts.as_slice() {
51 ["help"] => {
52 println!("Commands: /list, /stop <name>, /status, /quit");
53 }
54 ["list"] => {
55 let actors = system.registry.list().await;
56 for entry in actors {
57 println!(" {:<20} {} ({})", entry.name, entry.id, entry.state);
58 }
59 }
60 ["stop", name] => {
61 system.stop_actor(name).await?;
62 println!("Sent stop signal to '{name}'");
63 }
64 ["status"] => {
65 let actors = system.registry.list().await;
66 println!("System status: {} actor(s)", actors.len());
67 for e in &actors {
68 println!(" {} {} — {}", e.name, e.id, e.state);
69 }
70 }
71 ["quit"] => {
72 println!("Shutting down…");
73 system.shutdown().await?;
74 }
75 _ => {
76 println!("Unknown command: /{cmd}. Type /help.");
77 }
78 }
79 Ok(())
80}
81
82async fn dispatch_to_main_actor(text: &str, system: &ActorSystem) -> Result<()> {
84 let entry = system
85 .registry
86 .get_by_name("main-actor")
87 .await
88 .ok_or_else(|| anyhow::anyhow!("main-actor not found"))?;
89 let msg = Message::text(None, Some(entry.id.clone()), text);
90 system.registry.send(&entry.id, msg).await
91}