nxtgauge-ai-assistant/src/main.rs
Tracewebstudio Dev 72d44bbd63 feat: wire NxtgaugeTicketProvider and NxtgaugeHelpCenterProvider to real backend APIs
- Add NxtgaugeTicketProvider: calls /api/support/tickets/ai/create with service key auth
- Add NxtgaugeHelpCenterProvider: calls /api/kb/articles for help search
- Add ExternalService error variant for HTTP call failures
- Add NXTGAUGE_USERS_URL config env var
2026-04-15 18:18:39 +02:00

88 lines
2.2 KiB
Rust

mod chat;
mod config;
mod db;
mod error;
mod forms;
mod handlers;
mod jobs;
mod providers;
mod retrieval;
mod routes;
mod state;
mod tickets;
use std::sync::Arc;
use config::AppConfig;
use providers::help_center::nxtgauge_help_center_provider::NxtgaugeHelpCenterProvider;
use providers::llm::ollama_provider::OllamaAiProvider;
use providers::tickets::nxtgauge_ticket_provider::NxtgaugeTicketProvider;
use retrieval::embeddings::ollama_embedding_provider::OllamaEmbeddingProvider;
use state::AppState;
use tracing::{info, warn};
#[tokio::main]
async fn main() {
init_tracing();
let cfg = AppConfig::from_env();
let database = match db::Database::connect(cfg.database_url.as_deref()).await {
Ok(db) => db,
Err(err) => {
warn!("database initialization failed; continuing without DB: {err}");
db::Database::disabled()
}
};
let ai_provider = Arc::new(OllamaAiProvider::new(
cfg.ollama_base_url.clone(),
cfg.ollama_chat_model.clone(),
));
let embedding_provider = Arc::new(OllamaEmbeddingProvider::new(
cfg.ollama_base_url.clone(),
cfg.ollama_embed_model.clone(),
));
let http_client = reqwest::Client::new();
let help_center_provider = Arc::new(NxtgaugeHelpCenterProvider::new(
http_client.clone(),
cfg.nxtgauge_users_url.clone(),
));
let ticket_provider = Arc::new(NxtgaugeTicketProvider::new(
http_client,
cfg.nxtgauge_users_url.clone(),
cfg.tickets_source.clone(),
));
let state = AppState::new(
cfg.clone(),
database,
ai_provider,
help_center_provider,
ticket_provider,
);
let app = routes::build_router(state);
let bind_addr = cfg.socket_addr();
info!("starting nxtgauge-ai-assistant on {bind_addr}");
let listener = tokio::net::TcpListener::bind(bind_addr)
.await
.expect("failed to bind server socket");
axum::serve(listener, app).await.expect("server crashed");
}
fn init_tracing() {
let default_filter = std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string());
tracing_subscriber::fmt()
.with_env_filter(default_filter)
.with_target(false)
.compact()
.init();
}