steer_cli/commands/
serve.rs1use async_trait::async_trait;
2use eyre::{Result, eyre};
3use tracing::info;
4
5use super::Command;
6use steer_core::api::Model;
7use steer_core::session::SessionManagerConfig;
8
9pub struct ServeCommand {
10 pub port: u16,
11 pub bind: String,
12 pub model: Model,
13 pub session_db: Option<std::path::PathBuf>,
14}
15
16#[async_trait]
17impl Command for ServeCommand {
18 async fn execute(&self) -> Result<()> {
19 let addr = format!("{}:{}", self.bind, self.port)
20 .parse()
21 .map_err(|e| eyre!("Invalid bind address: {}", e))?;
22
23 info!("Starting gRPC server on {}", addr);
24
25 let db_path = match &self.session_db {
27 Some(path) => path.clone(),
28 None => steer_core::utils::session::create_session_store_path()?,
29 };
30
31 let config = steer_grpc::ServiceHostConfig::new(
32 db_path,
33 SessionManagerConfig {
34 max_concurrent_sessions: 100,
35 default_model: self.model,
36 auto_persist: true,
37 },
38 addr,
39 )
40 .map_err(|e| eyre!("Failed to create service config: {}", e))?;
41
42 let mut host = steer_grpc::ServiceHost::new(config)
43 .await
44 .map_err(|e| eyre!("Failed to create service host: {}", e))?;
45 host.start()
46 .await
47 .map_err(|e| eyre!("Failed to start server: {}", e))?;
48
49 info!("gRPC server started on {}", addr);
50 println!("Server listening on {}", addr);
51 println!("Press Ctrl+C to shutdown");
52
53 tokio::signal::ctrl_c().await?;
55 info!("Shutdown signal received");
56
57 host.shutdown()
58 .await
59 .map_err(|e| eyre!("Failed to shutdown server: {}", e))?;
60 info!("Server shutdown complete");
61
62 Ok(())
63 }
64}