1use anyhow::Result;
2use clap::{ArgAction, Parser};
3use pai_core::adapters::HardcodedFlowRunner;
4use pai_core::domain::{EventBus, SessionManager};
5use pai_core::ports::{InferenceError, InferencePort};
6use std::path::PathBuf;
7use std::sync::Arc;
8use tracing::{debug, error, info};
9use tracing_subscriber::FmtSubscriber;
10
11#[derive(Parser, Debug)]
13#[command(author, version, about, long_about = None)]
14struct Args {
15 #[arg(short, long)]
17 config: Option<PathBuf>,
18
19 #[arg(short, long, action = ArgAction::Count)]
21 verbose: u8,
22}
23
24#[tokio::main]
25async fn main() -> Result<()> {
26 let args = Args::parse();
28
29 let log_level = match args.verbose {
31 0 => tracing::Level::INFO,
32 1 => tracing::Level::DEBUG,
33 _ => tracing::Level::TRACE,
34 };
35
36 let subscriber = FmtSubscriber::builder().with_max_level(log_level).finish();
37
38 tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
39
40 #[derive(Debug)]
42 struct StubInference;
43
44 impl InferencePort for StubInference {
45 fn complete(&self, prompt: &str) -> Result<String, InferenceError> {
46 Ok(format!("[stub] {prompt}"))
47 }
48 }
49
50 let (event_bus, event_rx) = EventBus::channel(64);
51 let flow_runner = Arc::new(HardcodedFlowRunner::new(
52 Arc::new(StubInference),
53 event_bus.clone(),
54 ));
55 let session = SessionManager::new(flow_runner, event_bus);
56
57 tokio::spawn(async move {
60 let mut event_rx = event_rx;
61 while let Some(ev) = event_rx.recv().await {
62 debug!(target: "pai_engine::event_bus", ?ev, "domain event");
63 }
64 });
65 info!(
66 "Booting paiOS engine workspace (session state: {:?})...",
67 session.state_machine().state()
68 );
69
70 if let Some(path) = args.config {
71 info!("Using configuration from: {}", path.display());
72 } else {
73 info!("No configuration file provided, using defaults.");
74 }
75
76 if let Err(e) = tokio::signal::ctrl_c().await {
80 error!("Failed to listen for shutdown signal: {e}");
81 }
82
83 info!("Shutdown signal received. Exiting paiOS engine.");
84
85 Ok(())
86}