provisioning-platform/crates/ai-service/src/main.rs

86 lines
3 KiB
Rust

//! AI service binary - HTTP wrapper for AI capabilities including RAG, MCP tool
//! invocation, and knowledge graphs
use std::net::SocketAddr;
use std::sync::Arc;
use ai_service::{handlers, AiService, DEFAULT_PORT};
use axum::Router;
use clap::Parser;
#[derive(Parser, Debug)]
#[command(name = "ai-service")]
#[command(about = "HTTP service for AI capabilities including RAG, MCP tool invocation, DAG operations, and knowledge graphs", long_about = None)]
struct Args {
/// Configuration file path (highest priority)
#[arg(short = 'c', long, env = "AI_SERVICE_CONFIG")]
config: Option<std::path::PathBuf>,
/// Configuration directory (searches for ai-service.ncl|toml|json)
#[arg(long, env = "PROVISIONING_CONFIG_DIR")]
config_dir: Option<std::path::PathBuf>,
/// Deployment mode (solo, multiuser, cicd, enterprise)
#[arg(short = 'm', long, env = "AI_SERVICE_MODE")]
mode: Option<String>,
/// Service bind address
#[arg(short = 'H', long, default_value = "127.0.0.1")]
host: String,
/// Service bind port
#[arg(short = 'p', long, default_value_t = DEFAULT_PORT)]
port: u16,
/// Print all #[onto_api] registered routes as JSON and exit.
/// Pipe to api-catalog-ai-service.json: `just export-api-catalog`
#[arg(long)]
dump_api_catalog: bool,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Parse CLI arguments FIRST (so --help works before any other processing)
let args = Args::parse();
if args.dump_api_catalog {
println!("{}", ontoref_ontology::api::dump_catalog_json());
return Ok(());
}
// Initialize centralized observability (logging, metrics, health checks)
let _guard = observability::init_from_env("ai-service", env!("CARGO_PKG_VERSION"))?;
// Check if ai-service is enabled in deployment-mode.ncl
if let Ok(deployment) = platform_config::load_deployment_mode() {
if let Ok(enabled) = deployment.is_service_enabled("ai_service") {
if !enabled {
tracing::warn!("⚠ AI Service is DISABLED in deployment-mode.ncl");
std::process::exit(1);
}
tracing::info!("✓ AI Service is ENABLED in deployment-mode.ncl");
}
}
// Try to load ai-service.ncl
if let Ok(config) = platform_config::load_service_config_from_ncl("ai-service") {
tracing::info!("✓ Loaded ai-service configuration from NCL");
tracing::debug!("Config: {:?}", config);
}
let addr: SocketAddr = format!("{}:{}", args.host, args.port).parse()?;
// Create service
let service = Arc::new(AiService::new(addr));
tracing::info!("Starting AI service on {}", addr);
// Create router
let app = Router::new()
.merge(handlers::create_routes(service))
.fallback(|| async { (axum::http::StatusCode::NOT_FOUND, "Not found") });
// Start server
let listener = tokio::net::TcpListener::bind(&addr).await?;
axum::serve(listener, app).await?;
Ok(())
}