2025-12-08 14:08:49 -03:00
|
|
|
use axum::extract::{Extension, State};
|
|
|
|
|
use axum::http::StatusCode;
|
|
|
|
|
use axum::Json;
|
2025-11-20 13:28:35 -03:00
|
|
|
use axum::{
|
|
|
|
|
routing::{get, post},
|
|
|
|
|
Router,
|
|
|
|
|
};
|
2025-12-02 21:09:43 -03:00
|
|
|
use dotenvy::dotenv;
|
2025-11-28 13:50:28 -03:00
|
|
|
use log::{error, info, trace, warn};
|
2025-10-12 20:12:49 -03:00
|
|
|
use std::collections::HashMap;
|
2025-11-20 13:28:35 -03:00
|
|
|
use std::net::SocketAddr;
|
2025-11-11 09:42:52 -03:00
|
|
|
use std::sync::Arc;
|
2025-11-20 13:28:35 -03:00
|
|
|
use tower_http::cors::CorsLayer;
|
|
|
|
|
use tower_http::trace::TraceLayer;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-22 22:54:45 -03:00
|
|
|
use botserver::basic;
|
|
|
|
|
use botserver::core;
|
|
|
|
|
use botserver::shared;
|
2025-11-27 23:10:43 -03:00
|
|
|
|
2025-11-22 22:54:45 -03:00
|
|
|
#[cfg(feature = "console")]
|
|
|
|
|
use botserver::console;
|
|
|
|
|
|
|
|
|
|
// Re-exports from core
|
|
|
|
|
use botserver::core::automation;
|
|
|
|
|
use botserver::core::bootstrap;
|
|
|
|
|
use botserver::core::bot;
|
|
|
|
|
use botserver::core::config;
|
|
|
|
|
use botserver::core::package_manager;
|
|
|
|
|
use botserver::core::session;
|
|
|
|
|
|
|
|
|
|
// Feature-gated modules
|
|
|
|
|
#[cfg(feature = "attendance")]
|
|
|
|
|
mod attendance;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "calendar")]
|
|
|
|
|
mod calendar;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "compliance")]
|
|
|
|
|
mod compliance;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "directory")]
|
|
|
|
|
mod directory;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "drive")]
|
2025-11-22 12:26:16 -03:00
|
|
|
mod drive;
|
2025-11-22 22:54:45 -03:00
|
|
|
|
2025-10-07 10:53:09 -03:00
|
|
|
#[cfg(feature = "email")]
|
2025-10-06 10:30:17 -03:00
|
|
|
mod email;
|
2025-11-22 22:54:45 -03:00
|
|
|
|
|
|
|
|
#[cfg(feature = "instagram")]
|
|
|
|
|
mod instagram;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "llm")]
|
2025-11-07 16:40:19 -03:00
|
|
|
mod llm;
|
2025-11-22 22:54:45 -03:00
|
|
|
|
|
|
|
|
#[cfg(feature = "meet")]
|
2025-10-18 12:01:39 -03:00
|
|
|
mod meet;
|
2025-11-22 22:54:45 -03:00
|
|
|
|
|
|
|
|
#[cfg(feature = "msteams")]
|
|
|
|
|
mod msteams;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "nvidia")]
|
2025-11-07 16:40:19 -03:00
|
|
|
mod nvidia;
|
2025-11-22 22:54:45 -03:00
|
|
|
|
|
|
|
|
#[cfg(feature = "vectordb")]
|
|
|
|
|
mod vector_db;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "weba")]
|
|
|
|
|
mod weba;
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "whatsapp")]
|
|
|
|
|
mod whatsapp;
|
|
|
|
|
|
2025-10-16 11:43:02 -03:00
|
|
|
use crate::automation::AutomationService;
|
2025-10-18 19:08:00 -03:00
|
|
|
use crate::bootstrap::BootstrapManager;
|
2025-10-07 10:53:09 -03:00
|
|
|
#[cfg(feature = "email")]
|
2025-10-19 11:08:23 -03:00
|
|
|
use crate::email::{
|
`@media (prefers-color-scheme: dark)`
- ✅ Enhanced accessibility features (focus states, reduced motion)
- ✅ Added connection status component styles
- ✅ Improved responsive design
- ✅ Added utility classes for common patterns
- ✅ Added semantic HTML5 elements (`<header>`, `<main>`, `<nav>`)
- ✅ Comprehensive ARIA labels and roles for accessibility
- ✅ Keyboard navigation support (Alt+1-4 for sections, Esc for menus)
- ✅ Better event handling and state management
- ✅ Theme change subscriber with meta theme-color sync
- ✅ Online/offline connection monitoring
- ✅ Enhanced console logging with app info
- ✅ `THEMES.md` (400+ lines) - Complete theme system guide
- ✅ `README.md` (433+ lines) - Main application documentation
- ✅ `COMPONENTS.md` (773+ lines) - UI component library reference
- ✅ `QUICKSTART.md` (359+ lines) - Quick start guide for developers
- ✅ `REBUILD_NOTES.md` - This summary document
**Theme files define base colors:** ```css :root { --primary: 217 91%
60%; /* HSL: blue */ --background: 0 0% 100%; /* HSL: white */ } ```
**App.css bridges to working variables:** ```css :root { --accent-color:
hsl(var(--primary)); --primary-bg: hsl(var(--background));
--accent-light: hsla(var(--primary) / 0.1); } ```
**Components use working variables:** ```css .button { background:
var(--accent-color); color: hsl(var(--primary-foreground)); } ```
- ✅ Keyboard shortcuts (Alt+1-4, Esc)
- ✅ System dark mode detection
- ✅ Theme change event subscription
- ✅ Automatic document title updates
- ✅ Meta theme-color synchronization
- ✅ Enhanced console logging
- ✅ Better error handling
- ✅ Improved accessibility
- ✅ Theme switching via dropdown
- ✅ Theme persistence to localStorage
- ✅ Apps menu with section switching
- ✅ Dynamic section loading (Chat, Drive, Tasks, Mail)
- ✅ WebSocket chat functionality
- ✅ Alpine.js integration for other modules
- ✅ Responsive design
- ✅ Loading states
- [x] Theme switching works across all 19 themes
- [x] All sections load correctly
- [x] Keyboard shortcuts functional
- [x] Responsive on mobile/tablet/desktop
- [x] Accessibility features working
- [x] No console errors
- [x] Theme persistence works
- [x] Dark mode detection works
``` documentation/ ├── README.md # Main docs - start here ├──
QUICKSTART.md # 5-minute guide ├── THEMES.md # Theme system details ├──
COMPONENTS.md # UI component library └── REBUILD_NOTES.md # This summary
```
1. **HSL Bridge System**: Allows theme files to use shadcn-style HSL
variables while the app automatically derives working CSS properties
2. **No Breaking Changes**: All existing functionality preserved and
enhanced
3. **Developer-Friendly**: Comprehensive documentation for customization
4. **Accessibility First**: ARIA labels, keyboard navigation, focus
management
5. **Performance Optimized**: Instant theme switching, minimal reflows
- **Rebuild**: ✅ Complete
- **Testing**: ✅ Passed
- **Documentation**: ✅ Complete
- **Production Ready**: ✅ Yes
The rebuild successfully integrates the theme system throughout the UI
while maintaining all functionality and adding comprehensive
documentation for future development.
2025-11-21 09:28:02 -03:00
|
|
|
add_email_account, delete_email_account, get_emails, get_latest_email_from,
|
|
|
|
|
list_email_accounts, list_emails, list_folders, save_click, save_draft, send_email,
|
2025-10-19 11:08:23 -03:00
|
|
|
};
|
2025-11-22 22:54:45 -03:00
|
|
|
use botserver::core::bot::channels::{VoiceAdapter, WebChannelAdapter};
|
|
|
|
|
use botserver::core::bot::websocket_handler;
|
|
|
|
|
use botserver::core::bot::BotOrchestrator;
|
|
|
|
|
use botserver::core::config::AppConfig;
|
2025-11-27 15:19:17 -03:00
|
|
|
|
2025-11-22 22:54:45 -03:00
|
|
|
// use crate::file::upload_file; // Module doesn't exist
|
|
|
|
|
#[cfg(feature = "directory")]
|
|
|
|
|
use crate::directory::auth_handler;
|
|
|
|
|
#[cfg(feature = "meet")]
|
2025-10-18 12:01:39 -03:00
|
|
|
use crate::meet::{voice_start, voice_stop};
|
2025-10-18 19:08:00 -03:00
|
|
|
use crate::package_manager::InstallMode;
|
2025-11-02 07:50:57 -03:00
|
|
|
use crate::session::{create_session, get_session_history, get_sessions, start_session};
|
2025-10-11 20:02:14 -03:00
|
|
|
use crate::shared::state::AppState;
|
2025-11-11 09:42:52 -03:00
|
|
|
use crate::shared::utils::create_conn;
|
2025-11-11 15:01:57 -03:00
|
|
|
use crate::shared::utils::create_s3_operator;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
// Use BootstrapProgress from lib.rs
|
|
|
|
|
use botserver::BootstrapProgress;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-08 14:08:49 -03:00
|
|
|
/// Health check endpoint handler
|
|
|
|
|
/// Returns server health status for monitoring and load balancers
|
|
|
|
|
async fn health_check(State(state): State<Arc<AppState>>) -> (StatusCode, Json<serde_json::Value>) {
|
|
|
|
|
// Check database connectivity
|
|
|
|
|
let db_ok = state.conn.get().is_ok();
|
|
|
|
|
|
|
|
|
|
let status = if db_ok { "healthy" } else { "degraded" };
|
|
|
|
|
let code = if db_ok {
|
|
|
|
|
StatusCode::OK
|
|
|
|
|
} else {
|
|
|
|
|
StatusCode::SERVICE_UNAVAILABLE
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
(
|
|
|
|
|
code,
|
|
|
|
|
Json(serde_json::json!({
|
|
|
|
|
"status": status,
|
|
|
|
|
"service": "botserver",
|
|
|
|
|
"version": env!("CARGO_PKG_VERSION"),
|
|
|
|
|
"database": db_ok
|
|
|
|
|
})),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Simple health check without state (for basic liveness probes)
|
|
|
|
|
async fn health_check_simple() -> (StatusCode, Json<serde_json::Value>) {
|
|
|
|
|
(
|
|
|
|
|
StatusCode::OK,
|
|
|
|
|
Json(serde_json::json!({
|
|
|
|
|
"status": "ok",
|
|
|
|
|
"service": "botserver",
|
|
|
|
|
"version": env!("CARGO_PKG_VERSION")
|
|
|
|
|
})),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-20 13:28:35 -03:00
|
|
|
async fn run_axum_server(
|
2025-11-19 14:00:57 -03:00
|
|
|
app_state: Arc<AppState>,
|
|
|
|
|
port: u16,
|
2025-11-20 13:28:35 -03:00
|
|
|
_worker_count: usize,
|
2025-11-19 14:00:57 -03:00
|
|
|
) -> std::io::Result<()> {
|
2025-11-20 13:28:35 -03:00
|
|
|
// CORS configuration
|
|
|
|
|
let cors = CorsLayer::new()
|
|
|
|
|
.allow_origin(tower_http::cors::Any)
|
|
|
|
|
.allow_methods(tower_http::cors::Any)
|
|
|
|
|
.allow_headers(tower_http::cors::Any)
|
|
|
|
|
.max_age(std::time::Duration::from_secs(3600));
|
|
|
|
|
|
2025-11-29 16:29:28 -03:00
|
|
|
use crate::core::urls::ApiUrls;
|
|
|
|
|
|
2025-11-27 09:38:50 -03:00
|
|
|
// Build API router with module-specific routes
|
|
|
|
|
let mut api_router = Router::new()
|
2025-12-08 14:08:49 -03:00
|
|
|
// Health check endpoints - both /health and /api/health for compatibility
|
|
|
|
|
.route("/health", get(health_check_simple))
|
|
|
|
|
.route(ApiUrls::HEALTH, get(health_check))
|
2025-11-29 16:29:28 -03:00
|
|
|
.route(ApiUrls::SESSIONS, post(create_session))
|
|
|
|
|
.route(ApiUrls::SESSIONS, get(get_sessions))
|
2025-11-20 13:28:35 -03:00
|
|
|
.route(
|
2025-12-02 21:09:43 -03:00
|
|
|
&ApiUrls::SESSION_HISTORY.replace(":id", "{session_id}"),
|
2025-11-20 13:28:35 -03:00
|
|
|
get(get_session_history),
|
|
|
|
|
)
|
2025-11-29 16:29:28 -03:00
|
|
|
.route(
|
2025-12-02 21:09:43 -03:00
|
|
|
&ApiUrls::SESSION_START.replace(":id", "{session_id}"),
|
2025-11-29 16:29:28 -03:00
|
|
|
post(start_session),
|
|
|
|
|
)
|
2025-11-26 22:54:22 -03:00
|
|
|
// WebSocket route
|
2025-11-29 16:29:28 -03:00
|
|
|
.route(ApiUrls::WS, get(websocket_handler))
|
2025-11-27 23:10:43 -03:00
|
|
|
// Merge drive routes using the configure() function
|
|
|
|
|
.merge(botserver::drive::configure());
|
2025-11-22 22:54:45 -03:00
|
|
|
|
2025-11-26 22:54:22 -03:00
|
|
|
// Add feature-specific routes
|
2025-11-22 22:54:45 -03:00
|
|
|
#[cfg(feature = "directory")]
|
|
|
|
|
{
|
2025-11-29 16:29:28 -03:00
|
|
|
api_router = api_router
|
|
|
|
|
.route(ApiUrls::AUTH, get(auth_handler))
|
|
|
|
|
.merge(crate::core::directory::api::configure_user_routes());
|
2025-11-22 22:54:45 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "meet")]
|
|
|
|
|
{
|
|
|
|
|
api_router = api_router
|
2025-11-29 16:29:28 -03:00
|
|
|
.route(ApiUrls::VOICE_START, post(voice_start))
|
|
|
|
|
.route(ApiUrls::VOICE_STOP, post(voice_stop))
|
|
|
|
|
.route(ApiUrls::WS_MEET, get(crate::meet::meeting_websocket))
|
2025-11-26 22:54:22 -03:00
|
|
|
.merge(crate::meet::configure());
|
2025-11-22 22:54:45 -03:00
|
|
|
}
|
|
|
|
|
|
2025-11-26 22:54:22 -03:00
|
|
|
#[cfg(feature = "email")]
|
2025-11-22 22:54:45 -03:00
|
|
|
{
|
2025-11-26 22:54:22 -03:00
|
|
|
api_router = api_router.merge(crate::email::configure());
|
2025-11-22 22:54:45 -03:00
|
|
|
}
|
|
|
|
|
|
2025-11-26 22:54:22 -03:00
|
|
|
// Add calendar routes with CalDAV if feature is enabled
|
|
|
|
|
#[cfg(feature = "calendar")]
|
|
|
|
|
{
|
|
|
|
|
let calendar_engine =
|
|
|
|
|
Arc::new(crate::calendar::CalendarEngine::new(app_state.conn.clone()));
|
|
|
|
|
|
|
|
|
|
// Start reminder job
|
|
|
|
|
let reminder_engine = Arc::clone(&calendar_engine);
|
|
|
|
|
tokio::spawn(async move {
|
|
|
|
|
crate::calendar::start_reminder_job(reminder_engine).await;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Add CalDAV router
|
|
|
|
|
api_router = api_router.merge(crate::calendar::caldav::create_caldav_router(
|
|
|
|
|
calendar_engine,
|
|
|
|
|
));
|
|
|
|
|
}
|
2025-11-22 12:26:16 -03:00
|
|
|
|
2025-11-26 22:54:22 -03:00
|
|
|
// Add task engine routes
|
2025-11-27 08:34:24 -03:00
|
|
|
api_router = api_router.merge(botserver::tasks::configure_task_routes());
|
2025-11-20 13:28:35 -03:00
|
|
|
|
2025-11-27 09:38:50 -03:00
|
|
|
// Add calendar routes if calendar feature is enabled
|
|
|
|
|
#[cfg(feature = "calendar")]
|
|
|
|
|
{
|
|
|
|
|
api_router = api_router.merge(crate::calendar::configure_calendar_routes());
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-02 21:09:43 -03:00
|
|
|
// Add suite application routes (gap analysis implementations)
|
|
|
|
|
api_router = api_router.merge(botserver::analytics::configure_analytics_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::paper::configure_paper_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::research::configure_research_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::sources::configure_sources_routes());
|
|
|
|
|
api_router = api_router.merge(botserver::designer::configure_designer_routes());
|
2025-11-29 16:29:28 -03:00
|
|
|
|
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
|
|
|
// Add WhatsApp webhook routes if feature is enabled
|
|
|
|
|
#[cfg(feature = "whatsapp")]
|
|
|
|
|
{
|
|
|
|
|
api_router = api_router.merge(crate::whatsapp::configure());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add attendance/CRM routes for human handoff
|
|
|
|
|
#[cfg(feature = "attendance")]
|
|
|
|
|
{
|
|
|
|
|
api_router = api_router.merge(crate::attendance::configure_attendance_routes());
|
|
|
|
|
}
|
|
|
|
|
|
feat(auth): Add OAuth login for Google, Discord, Reddit, Twitter, Microsoft, Facebook
- Create core/oauth module with OAuthProvider enum and shared types
- Implement providers.rs with auth URLs, token exchange, user info endpoints
- Add routes for /auth/oauth/providers, /auth/oauth/{provider}, and callbacks
- Update login.html with OAuth button grid and dynamic provider loading
- Add OAuth config settings to config.csv with setup documentation and links
- Uses HTMX for login form, minimal JS for OAuth provider visibility
2025-12-04 22:53:40 -03:00
|
|
|
// Add OAuth authentication routes
|
|
|
|
|
api_router = api_router.merge(crate::core::oauth::routes::configure());
|
|
|
|
|
|
2025-11-20 13:28:35 -03:00
|
|
|
let app = Router::new()
|
2025-12-02 21:09:43 -03:00
|
|
|
// API routes
|
2025-11-26 22:54:22 -03:00
|
|
|
.merge(api_router.with_state(app_state.clone()))
|
2025-11-28 15:06:30 -03:00
|
|
|
.layer(Extension(app_state.clone()))
|
2025-11-20 14:28:21 -03:00
|
|
|
// Layers
|
2025-11-20 13:28:35 -03:00
|
|
|
.layer(cors)
|
|
|
|
|
.layer(TraceLayer::new_for_http());
|
|
|
|
|
|
2025-11-29 16:29:28 -03:00
|
|
|
// Always use HTTPS - load certificates from botserver-stack
|
|
|
|
|
let cert_dir = std::path::Path::new("./botserver-stack/conf/system/certificates");
|
|
|
|
|
let cert_path = cert_dir.join("api/server.crt");
|
|
|
|
|
let key_path = cert_dir.join("api/server.key");
|
|
|
|
|
|
2025-11-20 13:28:35 -03:00
|
|
|
// Bind to address
|
|
|
|
|
let addr = SocketAddr::from(([0, 0, 0, 0], port));
|
|
|
|
|
|
2025-12-08 14:08:49 -03:00
|
|
|
// Check if TLS is disabled via environment variable (for local development)
|
|
|
|
|
let disable_tls = std::env::var("BOTSERVER_DISABLE_TLS")
|
|
|
|
|
.map(|v| v == "true" || v == "1")
|
|
|
|
|
.unwrap_or(false);
|
|
|
|
|
|
|
|
|
|
// Check if certificates exist and TLS is not disabled
|
|
|
|
|
if !disable_tls && cert_path.exists() && key_path.exists() {
|
2025-11-29 16:29:28 -03:00
|
|
|
// Use HTTPS with existing certificates
|
|
|
|
|
let tls_config = axum_server::tls_rustls::RustlsConfig::from_pem_file(cert_path, key_path)
|
|
|
|
|
.await
|
|
|
|
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
|
2025-11-20 13:28:35 -03:00
|
|
|
|
2025-11-29 16:29:28 -03:00
|
|
|
info!("HTTPS server listening on {} with TLS", addr);
|
|
|
|
|
|
2025-12-02 21:09:43 -03:00
|
|
|
let handle = axum_server::Handle::new();
|
2025-11-29 16:29:28 -03:00
|
|
|
axum_server::bind_rustls(addr, tls_config)
|
2025-12-02 21:09:43 -03:00
|
|
|
.handle(handle)
|
2025-11-29 16:29:28 -03:00
|
|
|
.serve(app.into_make_service())
|
|
|
|
|
.await
|
|
|
|
|
} else {
|
2025-12-08 14:08:49 -03:00
|
|
|
// Use HTTP - either TLS is disabled or certificates don't exist
|
|
|
|
|
if disable_tls {
|
|
|
|
|
info!("TLS disabled via BOTSERVER_DISABLE_TLS environment variable");
|
|
|
|
|
} else {
|
|
|
|
|
warn!("TLS certificates not found, using HTTP");
|
|
|
|
|
}
|
2025-11-29 16:29:28 -03:00
|
|
|
|
|
|
|
|
let listener = tokio::net::TcpListener::bind(addr).await?;
|
2025-12-08 14:08:49 -03:00
|
|
|
info!("HTTP server listening on {}", addr);
|
2025-11-29 16:29:28 -03:00
|
|
|
axum::serve(listener, app.into_make_service())
|
|
|
|
|
.await
|
|
|
|
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
|
|
|
|
|
}
|
2025-11-19 14:00:57 -03:00
|
|
|
}
|
|
|
|
|
|
2025-10-19 14:02:47 -03:00
|
|
|
#[tokio::main]
|
2025-10-16 11:43:02 -03:00
|
|
|
async fn main() -> std::io::Result<()> {
|
2025-12-07 02:13:28 -03:00
|
|
|
// Install rustls crypto provider (ring) before any TLS operations
|
|
|
|
|
// This must be done before any code that might use rustls
|
|
|
|
|
let _ = rustls::crypto::ring::default_provider().install_default();
|
|
|
|
|
|
|
|
|
|
// Load .env for VAULT_* variables only (all other secrets come from Vault)
|
|
|
|
|
dotenvy::dotenv().ok();
|
|
|
|
|
|
|
|
|
|
// Initialize SecretsManager early - this connects to Vault if configured
|
|
|
|
|
// Only VAULT_ADDR, VAULT_TOKEN, and VAULT_SKIP_VERIFY should be in .env
|
|
|
|
|
if let Err(e) = crate::shared::utils::init_secrets_manager().await {
|
2025-12-08 00:19:29 -03:00
|
|
|
warn!(
|
|
|
|
|
"Failed to initialize SecretsManager: {}. Falling back to env vars.",
|
|
|
|
|
e
|
|
|
|
|
);
|
2025-12-07 02:13:28 -03:00
|
|
|
} else {
|
|
|
|
|
info!("SecretsManager initialized - fetching secrets from Vault");
|
|
|
|
|
}
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
|
|
|
|
|
// Initialize logger early to capture all logs with filters for noisy libraries
|
2025-11-29 17:27:13 -03:00
|
|
|
let rust_log = {
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
// Default log level for botserver and suppress all other crates
|
2025-11-28 13:50:28 -03:00
|
|
|
// Note: r2d2 is set to warn to see database connection pool warnings
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
"info,botserver=info,\
|
|
|
|
|
aws_sigv4=off,aws_smithy_checksums=off,aws_runtime=off,aws_smithy_http_client=off,\
|
|
|
|
|
aws_smithy_runtime=off,aws_smithy_runtime_api=off,aws_sdk_s3=off,aws_config=off,\
|
|
|
|
|
aws_credential_types=off,aws_http=off,aws_sig_auth=off,aws_types=off,\
|
|
|
|
|
mio=off,tokio=off,tokio_util=off,tower=off,tower_http=off,\
|
|
|
|
|
reqwest=off,hyper=off,hyper_util=off,h2=off,\
|
|
|
|
|
rustls=off,rustls_pemfile=off,tokio_rustls=off,\
|
|
|
|
|
tracing=off,tracing_core=off,tracing_subscriber=off,\
|
2025-11-28 13:50:28 -03:00
|
|
|
diesel=off,diesel_migrations=off,r2d2=warn,\
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
serde=off,serde_json=off,\
|
|
|
|
|
axum=off,axum_core=off,\
|
|
|
|
|
tonic=off,prost=off,\
|
|
|
|
|
lettre=off,imap=off,mailparse=off,\
|
|
|
|
|
crossterm=off,ratatui=off,\
|
|
|
|
|
tauri=off,tauri_runtime=off,tauri_utils=off,\
|
|
|
|
|
notify=off,ignore=off,walkdir=off,\
|
|
|
|
|
want=off,try_lock=off,futures=off,\
|
|
|
|
|
base64=off,bytes=off,encoding_rs=off,\
|
|
|
|
|
url=off,percent_encoding=off,\
|
|
|
|
|
ring=off,webpki=off,\
|
|
|
|
|
hickory_resolver=off,hickory_proto=off"
|
|
|
|
|
.to_string()
|
2025-12-02 21:09:43 -03:00
|
|
|
};
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
|
|
|
|
|
// Set the RUST_LOG env var if not already set
|
|
|
|
|
std::env::set_var("RUST_LOG", &rust_log);
|
|
|
|
|
|
|
|
|
|
env_logger::Builder::from_env(env_logger::Env::default())
|
|
|
|
|
.write_style(env_logger::WriteStyle::Always)
|
|
|
|
|
.init();
|
|
|
|
|
|
2025-11-11 15:01:57 -03:00
|
|
|
println!(
|
|
|
|
|
"Starting {} {}...",
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
"General Bots".to_string(),
|
2025-11-11 15:01:57 -03:00
|
|
|
env!("CARGO_PKG_VERSION")
|
|
|
|
|
);
|
|
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
use crate::llm::local::ensure_llama_servers_running;
|
|
|
|
|
use botserver::config::ConfigManager;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let args: Vec<String> = std::env::args().collect();
|
|
|
|
|
let no_ui = args.contains(&"--noui".to_string());
|
2025-11-28 13:50:28 -03:00
|
|
|
let no_console = args.contains(&"--noconsole".to_string());
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-29 17:27:13 -03:00
|
|
|
// Configuration comes from Directory service, not .env files
|
2025-11-19 14:00:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
let (progress_tx, _progress_rx) = tokio::sync::mpsc::unbounded_channel::<BootstrapProgress>();
|
|
|
|
|
let (state_tx, _state_rx) = tokio::sync::mpsc::channel::<Arc<AppState>>(1);
|
2025-11-15 09:48:46 -03:00
|
|
|
|
2025-11-19 14:00:57 -03:00
|
|
|
// Handle CLI commands
|
2025-11-15 19:08:26 -03:00
|
|
|
if args.len() > 1 {
|
|
|
|
|
let command = &args[1];
|
|
|
|
|
match command.as_str() {
|
2025-11-20 13:28:35 -03:00
|
|
|
"install" | "remove" | "list" | "status" | "start" | "stop" | "restart" | "--help"
|
|
|
|
|
| "-h" => match package_manager::cli::run().await {
|
2025-11-15 19:08:26 -03:00
|
|
|
Ok(_) => return Ok(()),
|
|
|
|
|
Err(e) => {
|
|
|
|
|
eprintln!("CLI error: {}", e);
|
|
|
|
|
return Err(std::io::Error::new(
|
|
|
|
|
std::io::ErrorKind::Other,
|
|
|
|
|
format!("CLI command failed: {}", e),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
},
|
2025-11-19 14:00:57 -03:00
|
|
|
_ => {}
|
2025-11-15 19:08:26 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-07 02:13:28 -03:00
|
|
|
// Start UI thread if console is enabled (default) and not disabled by --noconsole or --noui
|
|
|
|
|
let ui_handle: Option<std::thread::JoinHandle<()>> = if !no_console && !no_ui {
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
#[cfg(feature = "console")]
|
|
|
|
|
{
|
|
|
|
|
let progress_rx = Arc::new(tokio::sync::Mutex::new(_progress_rx));
|
|
|
|
|
let state_rx = Arc::new(tokio::sync::Mutex::new(_state_rx));
|
|
|
|
|
|
|
|
|
|
Some(
|
|
|
|
|
std::thread::Builder::new()
|
|
|
|
|
.name("ui-thread".to_string())
|
|
|
|
|
.spawn(move || {
|
2025-11-22 22:54:45 -03:00
|
|
|
let mut ui = botserver::console::XtreeUI::new();
|
|
|
|
|
ui.set_progress_channel(progress_rx.clone());
|
|
|
|
|
|
|
|
|
|
let rt = tokio::runtime::Builder::new_current_thread()
|
|
|
|
|
.enable_all()
|
|
|
|
|
.build()
|
|
|
|
|
.expect("Failed to create UI runtime");
|
|
|
|
|
|
|
|
|
|
rt.block_on(async {
|
|
|
|
|
tokio::select! {
|
|
|
|
|
result = async {
|
|
|
|
|
let mut rx = state_rx.lock().await;
|
|
|
|
|
rx.recv().await
|
|
|
|
|
} => {
|
|
|
|
|
if let Some(app_state) = result {
|
|
|
|
|
ui.set_app_state(app_state);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_ = tokio::time::sleep(tokio::time::Duration::from_secs(300)) => {
|
|
|
|
|
eprintln!("UI initialization timeout");
|
2025-11-19 14:00:57 -03:00
|
|
|
}
|
|
|
|
|
}
|
2025-11-22 22:54:45 -03:00
|
|
|
});
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-22 22:54:45 -03:00
|
|
|
if let Err(e) = ui.start_ui() {
|
|
|
|
|
eprintln!("UI error: {}", e);
|
|
|
|
|
}
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
})
|
|
|
|
|
.expect("Failed to spawn UI thread"),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
#[cfg(not(feature = "console"))]
|
|
|
|
|
{
|
2025-11-28 13:50:28 -03:00
|
|
|
if !no_console {
|
|
|
|
|
eprintln!("Console feature not compiled. Rebuild with --features console or use --noconsole to suppress this message");
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
}
|
|
|
|
|
None
|
|
|
|
|
}
|
2025-11-11 09:42:52 -03:00
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let install_mode = if args.contains(&"--container".to_string()) {
|
|
|
|
|
InstallMode::Container
|
|
|
|
|
} else {
|
|
|
|
|
InstallMode::Local
|
|
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let tenant = if let Some(idx) = args.iter().position(|a| a == "--tenant") {
|
|
|
|
|
args.get(idx + 1).cloned()
|
|
|
|
|
} else {
|
|
|
|
|
None
|
|
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-06 14:55:42 -03:00
|
|
|
// Set custom stack path if provided (for testing)
|
|
|
|
|
if let Some(idx) = args.iter().position(|a| a == "--stack-path") {
|
|
|
|
|
if let Some(path) = args.get(idx + 1) {
|
|
|
|
|
std::env::set_var("BOTSERVER_STACK_PATH", path);
|
|
|
|
|
info!("Using custom stack path: {}", path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-19 14:00:57 -03:00
|
|
|
// Bootstrap
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Starting bootstrap process...");
|
2025-11-11 09:42:52 -03:00
|
|
|
let progress_tx_clone = progress_tx.clone();
|
|
|
|
|
let cfg = {
|
|
|
|
|
progress_tx_clone
|
|
|
|
|
.send(BootstrapProgress::StartingBootstrap)
|
|
|
|
|
.ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Creating BootstrapManager...");
|
2025-11-11 09:42:52 -03:00
|
|
|
let mut bootstrap = BootstrapManager::new(install_mode.clone(), tenant.clone()).await;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-08 00:19:29 -03:00
|
|
|
// Check if bootstrap has completed by looking for:
|
|
|
|
|
// 1. .env with VAULT_TOKEN
|
|
|
|
|
// 2. Vault init.json exists (actual credentials)
|
|
|
|
|
// Both must exist for bootstrap to be considered complete
|
|
|
|
|
let env_path = std::path::Path::new("./.env");
|
|
|
|
|
let vault_init_path = std::path::Path::new("./botserver-stack/conf/vault/init.json");
|
|
|
|
|
let bootstrap_completed = env_path.exists() && vault_init_path.exists() && {
|
|
|
|
|
// Check if .env contains VAULT_TOKEN (not just exists)
|
|
|
|
|
std::fs::read_to_string(env_path)
|
|
|
|
|
.map(|content| content.contains("VAULT_TOKEN="))
|
|
|
|
|
.unwrap_or(false)
|
|
|
|
|
};
|
2025-11-29 17:27:13 -03:00
|
|
|
|
2025-12-08 00:19:29 -03:00
|
|
|
let cfg = if bootstrap_completed {
|
2025-11-29 17:27:13 -03:00
|
|
|
trace!("Services already configured, ensuring all are running...");
|
2025-11-28 13:50:28 -03:00
|
|
|
info!("Ensuring database and drive services are running...");
|
2025-11-11 15:01:57 -03:00
|
|
|
progress_tx_clone
|
|
|
|
|
.send(BootstrapProgress::StartingComponent(
|
|
|
|
|
"all services".to_string(),
|
|
|
|
|
))
|
|
|
|
|
.ok();
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Calling bootstrap.start_all()...");
|
2025-11-28 13:50:28 -03:00
|
|
|
|
|
|
|
|
// Ensure critical services are started
|
|
|
|
|
if let Err(e) = bootstrap.ensure_services_running().await {
|
|
|
|
|
warn!("Some services might not be running: {}", e);
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-11 15:01:57 -03:00
|
|
|
bootstrap
|
|
|
|
|
.start_all()
|
2025-12-08 00:19:29 -03:00
|
|
|
.await
|
2025-11-11 15:01:57 -03:00
|
|
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("bootstrap.start_all() completed");
|
2025-11-11 15:01:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Connecting to database...");
|
2025-11-11 09:42:52 -03:00
|
|
|
progress_tx_clone
|
|
|
|
|
.send(BootstrapProgress::ConnectingDatabase)
|
|
|
|
|
.ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Creating database connection...");
|
2025-11-11 09:42:52 -03:00
|
|
|
match create_conn() {
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
Ok(pool) => {
|
|
|
|
|
trace!("Database connection successful, loading config from database");
|
|
|
|
|
AppConfig::from_database(&pool)
|
|
|
|
|
.unwrap_or_else(|_| AppConfig::from_env().expect("Failed to load config"))
|
|
|
|
|
}
|
|
|
|
|
Err(e) => {
|
|
|
|
|
trace!(
|
|
|
|
|
"Database connection failed: {:?}, loading config from env",
|
|
|
|
|
e
|
|
|
|
|
);
|
|
|
|
|
AppConfig::from_env().expect("Failed to load config from env")
|
|
|
|
|
}
|
2025-10-18 19:08:00 -03:00
|
|
|
}
|
2025-11-11 09:42:52 -03:00
|
|
|
} else {
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!(".env file not found, running bootstrap.bootstrap()...");
|
2025-11-12 12:48:06 -03:00
|
|
|
_ = bootstrap.bootstrap().await;
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("bootstrap.bootstrap() completed");
|
2025-11-11 15:01:57 -03:00
|
|
|
progress_tx_clone
|
|
|
|
|
.send(BootstrapProgress::StartingComponent(
|
|
|
|
|
"all services".to_string(),
|
|
|
|
|
))
|
|
|
|
|
.ok();
|
|
|
|
|
bootstrap
|
|
|
|
|
.start_all()
|
2025-12-08 00:19:29 -03:00
|
|
|
.await
|
2025-11-11 15:01:57 -03:00
|
|
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?;
|
2025-11-11 11:12:54 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
match create_conn() {
|
|
|
|
|
Ok(pool) => AppConfig::from_database(&pool)
|
|
|
|
|
.unwrap_or_else(|_| AppConfig::from_env().expect("Failed to load config")),
|
|
|
|
|
Err(_) => AppConfig::from_env().expect("Failed to load config from env"),
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-11-11 15:01:57 -03:00
|
|
|
|
2025-12-08 00:19:29 -03:00
|
|
|
trace!("Config loaded, syncing templates to database...");
|
2025-11-11 09:42:52 -03:00
|
|
|
progress_tx_clone
|
|
|
|
|
.send(BootstrapProgress::UploadingTemplates)
|
|
|
|
|
.ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-08 00:19:29 -03:00
|
|
|
// First sync config.csv to database (fast, no S3 needed)
|
|
|
|
|
if let Err(e) = bootstrap.sync_templates_to_database() {
|
|
|
|
|
warn!("Failed to sync templates to database: {}", e);
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
} else {
|
2025-12-08 00:19:29 -03:00
|
|
|
trace!("Templates synced to database");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Then upload to drive with timeout to prevent blocking on MinIO issues
|
|
|
|
|
match tokio::time::timeout(
|
|
|
|
|
std::time::Duration::from_secs(30),
|
|
|
|
|
bootstrap.upload_templates_to_drive(&cfg),
|
|
|
|
|
)
|
|
|
|
|
.await
|
|
|
|
|
{
|
|
|
|
|
Ok(Ok(_)) => {
|
|
|
|
|
trace!("Templates uploaded to drive successfully");
|
|
|
|
|
}
|
|
|
|
|
Ok(Err(e)) => {
|
|
|
|
|
warn!("Template drive upload error (non-blocking): {}", e);
|
|
|
|
|
}
|
|
|
|
|
Err(_) => {
|
|
|
|
|
warn!("Template drive upload timed out after 30s, continuing startup...");
|
|
|
|
|
}
|
2025-10-18 19:08:00 -03:00
|
|
|
}
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
Ok::<AppConfig, std::io::Error>(cfg)
|
2025-10-18 19:08:00 -03:00
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Bootstrap config phase complete");
|
2025-11-11 09:42:52 -03:00
|
|
|
let cfg = cfg?;
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Reloading dotenv...");
|
2025-11-11 09:42:52 -03:00
|
|
|
dotenv().ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Creating database pool again...");
|
2025-11-11 09:42:52 -03:00
|
|
|
progress_tx.send(BootstrapProgress::ConnectingDatabase).ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let pool = match create_conn() {
|
2025-11-28 13:50:28 -03:00
|
|
|
Ok(pool) => {
|
|
|
|
|
// Run automatic migrations
|
|
|
|
|
trace!("Running database migrations...");
|
|
|
|
|
info!("Running database migrations...");
|
|
|
|
|
if let Err(e) = crate::shared::utils::run_migrations(&pool) {
|
|
|
|
|
error!("Failed to run migrations: {}", e);
|
|
|
|
|
// Continue anyway as some migrations might have already been applied
|
|
|
|
|
warn!("Continuing despite migration errors - database might be partially migrated");
|
|
|
|
|
} else {
|
|
|
|
|
info!("Database migrations completed successfully");
|
|
|
|
|
}
|
|
|
|
|
pool
|
|
|
|
|
}
|
2025-11-11 09:42:52 -03:00
|
|
|
Err(e) => {
|
|
|
|
|
error!("Failed to create database pool: {}", e);
|
|
|
|
|
progress_tx
|
|
|
|
|
.send(BootstrapProgress::BootstrapError(format!(
|
|
|
|
|
"Database pool creation failed: {}",
|
|
|
|
|
e
|
|
|
|
|
)))
|
|
|
|
|
.ok();
|
|
|
|
|
return Err(std::io::Error::new(
|
|
|
|
|
std::io::ErrorKind::ConnectionRefused,
|
|
|
|
|
format!("Database pool creation failed: {}", e),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-08 00:19:29 -03:00
|
|
|
// Load config from database (which now has values from config.csv)
|
|
|
|
|
info!("Loading config from database after template sync...");
|
|
|
|
|
let refreshed_cfg = AppConfig::from_database(&pool).unwrap_or_else(|e| {
|
|
|
|
|
warn!(
|
|
|
|
|
"Failed to load config from database: {}, falling back to env",
|
|
|
|
|
e
|
|
|
|
|
);
|
|
|
|
|
AppConfig::from_env().expect("Failed to load config from env")
|
|
|
|
|
});
|
|
|
|
|
let config = std::sync::Arc::new(refreshed_cfg.clone());
|
|
|
|
|
info!(
|
|
|
|
|
"Server configured to listen on {}:{}",
|
|
|
|
|
config.server.host, config.server.port
|
|
|
|
|
);
|
|
|
|
|
|
2025-11-29 16:29:28 -03:00
|
|
|
let cache_url = "rediss://localhost:6379".to_string();
|
2025-11-11 09:42:52 -03:00
|
|
|
let redis_client = match redis::Client::open(cache_url.as_str()) {
|
|
|
|
|
Ok(client) => Some(Arc::new(client)),
|
|
|
|
|
Err(e) => {
|
|
|
|
|
log::warn!("Failed to connect to Redis: {}", e);
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
};
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let web_adapter = Arc::new(WebChannelAdapter::new());
|
|
|
|
|
let voice_adapter = Arc::new(VoiceAdapter::new());
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 10:34:06 -03:00
|
|
|
let drive = create_s3_operator(&config.drive)
|
2025-11-11 09:42:52 -03:00
|
|
|
.await
|
|
|
|
|
.expect("Failed to initialize Drive");
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let session_manager = Arc::new(tokio::sync::Mutex::new(session::SessionManager::new(
|
|
|
|
|
pool.get().unwrap(),
|
|
|
|
|
redis_client.clone(),
|
|
|
|
|
)));
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-22 12:26:16 -03:00
|
|
|
// Create default Zitadel config (can be overridden with env vars)
|
2025-11-22 22:54:45 -03:00
|
|
|
#[cfg(feature = "directory")]
|
|
|
|
|
let zitadel_config = botserver::directory::client::ZitadelConfig {
|
2025-11-29 16:29:28 -03:00
|
|
|
issuer_url: "https://localhost:8080".to_string(),
|
|
|
|
|
issuer: "https://localhost:8080".to_string(),
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
client_id: "client_id".to_string(),
|
|
|
|
|
client_secret: "client_secret".to_string(),
|
2025-11-29 16:29:28 -03:00
|
|
|
redirect_uri: "https://localhost:8080/callback".to_string(),
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
project_id: "default".to_string(),
|
2025-11-29 16:29:28 -03:00
|
|
|
api_url: "https://localhost:8080".to_string(),
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
service_account_key: None,
|
2025-11-22 12:26:16 -03:00
|
|
|
};
|
2025-11-22 22:54:45 -03:00
|
|
|
#[cfg(feature = "directory")]
|
|
|
|
|
let auth_service = Arc::new(tokio::sync::Mutex::new(
|
|
|
|
|
botserver::directory::AuthService::new(zitadel_config)
|
|
|
|
|
.await
|
|
|
|
|
.unwrap(),
|
|
|
|
|
));
|
2025-11-11 09:42:52 -03:00
|
|
|
let config_manager = ConfigManager::new(pool.clone());
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let mut bot_conn = pool.get().expect("Failed to get database connection");
|
2025-12-08 00:19:29 -03:00
|
|
|
let (default_bot_id, default_bot_name) = crate::bot::get_default_bot(&mut bot_conn);
|
|
|
|
|
info!(
|
|
|
|
|
"Using default bot: {} (id: {})",
|
|
|
|
|
default_bot_name, default_bot_id
|
|
|
|
|
);
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let llm_url = config_manager
|
2025-12-08 00:19:29 -03:00
|
|
|
.get_config(&default_bot_id, "llm-url", Some("http://localhost:8081"))
|
|
|
|
|
.unwrap_or_else(|_| "http://localhost:8081".to_string());
|
|
|
|
|
info!("LLM URL: {}", llm_url);
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-26 15:27:47 -03:00
|
|
|
// Create base LLM provider
|
|
|
|
|
let base_llm_provider = Arc::new(botserver::llm::OpenAIClient::new(
|
2025-11-11 09:42:52 -03:00
|
|
|
"empty".to_string(),
|
|
|
|
|
Some(llm_url.clone()),
|
2025-11-22 22:54:45 -03:00
|
|
|
)) as Arc<dyn botserver::llm::LLMProvider>;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-26 15:27:47 -03:00
|
|
|
// Wrap with cache if redis is available
|
|
|
|
|
let llm_provider: Arc<dyn botserver::llm::LLMProvider> = if let Some(ref cache) = redis_client {
|
|
|
|
|
// Set up embedding service for semantic matching
|
|
|
|
|
let embedding_url = config_manager
|
|
|
|
|
.get_config(
|
|
|
|
|
&default_bot_id,
|
|
|
|
|
"embedding-url",
|
2025-12-08 00:19:29 -03:00
|
|
|
Some("http://localhost:8082"),
|
2025-11-26 15:27:47 -03:00
|
|
|
)
|
2025-12-08 00:19:29 -03:00
|
|
|
.unwrap_or_else(|_| "http://localhost:8082".to_string());
|
2025-11-26 15:27:47 -03:00
|
|
|
let embedding_model = config_manager
|
|
|
|
|
.get_config(&default_bot_id, "embedding-model", Some("all-MiniLM-L6-v2"))
|
|
|
|
|
.unwrap_or_else(|_| "all-MiniLM-L6-v2".to_string());
|
2025-12-08 00:19:29 -03:00
|
|
|
info!("Embedding URL: {}", embedding_url);
|
|
|
|
|
info!("Embedding Model: {}", embedding_model);
|
2025-11-26 15:27:47 -03:00
|
|
|
|
|
|
|
|
let embedding_service = Some(Arc::new(botserver::llm::cache::LocalEmbeddingService::new(
|
|
|
|
|
embedding_url,
|
|
|
|
|
embedding_model,
|
|
|
|
|
))
|
|
|
|
|
as Arc<dyn botserver::llm::cache::EmbeddingService>);
|
|
|
|
|
|
|
|
|
|
// Create cache config
|
|
|
|
|
let cache_config = botserver::llm::cache::CacheConfig {
|
|
|
|
|
ttl: 3600, // 1 hour TTL
|
|
|
|
|
semantic_matching: true,
|
|
|
|
|
similarity_threshold: 0.85, // 85% similarity threshold
|
|
|
|
|
max_similarity_checks: 100,
|
|
|
|
|
key_prefix: "llm_cache".to_string(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Arc::new(botserver::llm::cache::CachedLLMProvider::with_db_pool(
|
|
|
|
|
base_llm_provider,
|
|
|
|
|
cache.clone(),
|
|
|
|
|
cache_config,
|
|
|
|
|
embedding_service,
|
|
|
|
|
pool.clone(),
|
|
|
|
|
))
|
|
|
|
|
} else {
|
|
|
|
|
base_llm_provider
|
|
|
|
|
};
|
|
|
|
|
|
2025-11-26 22:54:22 -03:00
|
|
|
// Initialize Knowledge Base Manager
|
|
|
|
|
let kb_manager = Arc::new(botserver::core::kb::KnowledgeBaseManager::new("work"));
|
|
|
|
|
|
2025-11-27 08:34:24 -03:00
|
|
|
// Initialize TaskEngine
|
|
|
|
|
let task_engine = Arc::new(botserver::tasks::TaskEngine::new(pool.clone()));
|
|
|
|
|
|
2025-11-27 13:53:16 -03:00
|
|
|
// Initialize MetricsCollector
|
|
|
|
|
let metrics_collector = botserver::core::shared::analytics::MetricsCollector::new();
|
|
|
|
|
|
|
|
|
|
// Initialize TaskScheduler (will be set after AppState creation)
|
|
|
|
|
let task_scheduler = None;
|
|
|
|
|
|
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
|
|
|
// Create broadcast channel for attendant notifications (human handoff)
|
|
|
|
|
let (attendant_tx, _attendant_rx) = tokio::sync::broadcast::channel::<
|
|
|
|
|
botserver::core::shared::state::AttendantNotification,
|
|
|
|
|
>(1000);
|
|
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let app_state = Arc::new(AppState {
|
2025-11-27 13:53:16 -03:00
|
|
|
drive: Some(drive.clone()),
|
|
|
|
|
s3_client: Some(drive),
|
2025-11-11 09:42:52 -03:00
|
|
|
config: Some(cfg.clone()),
|
|
|
|
|
conn: pool.clone(),
|
2025-12-07 02:13:28 -03:00
|
|
|
database_url: crate::shared::utils::get_database_url_sync().unwrap_or_default(),
|
2025-11-11 09:42:52 -03:00
|
|
|
bucket_name: "default.gbai".to_string(),
|
|
|
|
|
cache: redis_client.clone(),
|
|
|
|
|
session_manager: session_manager.clone(),
|
2025-11-27 13:53:16 -03:00
|
|
|
metrics_collector,
|
|
|
|
|
task_scheduler,
|
2025-11-11 09:42:52 -03:00
|
|
|
llm_provider: llm_provider.clone(),
|
2025-11-22 22:54:45 -03:00
|
|
|
#[cfg(feature = "directory")]
|
2025-11-11 09:42:52 -03:00
|
|
|
auth_service: auth_service.clone(),
|
|
|
|
|
channels: Arc::new(tokio::sync::Mutex::new({
|
|
|
|
|
let mut map = HashMap::new();
|
|
|
|
|
map.insert(
|
|
|
|
|
"web".to_string(),
|
2025-11-22 22:54:45 -03:00
|
|
|
web_adapter.clone() as Arc<dyn botserver::core::bot::channels::ChannelAdapter>,
|
2025-11-11 09:42:52 -03:00
|
|
|
);
|
|
|
|
|
map
|
|
|
|
|
})),
|
|
|
|
|
response_channels: Arc::new(tokio::sync::Mutex::new(HashMap::new())),
|
|
|
|
|
web_adapter: web_adapter.clone(),
|
|
|
|
|
voice_adapter: voice_adapter.clone(),
|
2025-11-26 22:54:22 -03:00
|
|
|
kb_manager: Some(kb_manager.clone()),
|
2025-11-27 08:34:24 -03:00
|
|
|
task_engine: task_engine,
|
Add Suite app documentation, templates, and Askama config
- Add askama.toml for template configuration (ui/ directory)
- Add Suite app documentation with flow diagrams (SVG)
- App launcher, chat flow, drive flow, tasks flow
- Individual app docs: chat, drive, tasks, mail, etc.
- Add HTML templates for Suite apps
- Base template with header and app launcher
- Auth login page
- Chat, Drive, Mail, Meet, Tasks templates
- Partial templates for messages, sessions, notifications
- Add Extensions type to AppState for type-erased storage
- Add mTLS module for service-to-service authentication
- Update web handlers to use new template paths (suite/)
- Fix auth module to avoid axum-extra TypedHeader dependency
2025-11-30 21:00:48 -03:00
|
|
|
extensions: botserver::core::shared::state::Extensions::new(),
|
feat(attendance): Add LLM-assisted attendant features
- Real-time tips when customer messages arrive
- Message polishing with one click
- Smart reply generation (3 contextual suggestions)
- Auto-summary when attendant takes conversation
- LLM-powered sentiment analysis with escalation warnings
WhatsApp Attendant Commands:
- /queue, /take, /status, /transfer, /resolve
- /tips, /polish, /replies, /summary, /help
- Portuguese versions: /fila, /pegar, /dicas, /polir, /respostas, /resumo
Config options (config.csv):
- attendant-llm-tips
- attendant-polish-message
- attendant-smart-replies
- attendant-auto-summary
- attendant-sentiment-analysis
API Endpoints:
- POST /api/attendance/llm/tips
- POST /api/attendance/llm/polish
- POST /api/attendance/llm/smart-replies
- GET /api/attendance/llm/summary/{session_id}
- POST /api/attendance/llm/sentiment
- GET /api/attendance/llm/config/{bot_id}
Uses bot's system prompt for consistency between bot and human-assisted responses.
2025-12-05 13:47:15 -03:00
|
|
|
attendant_broadcast: Some(attendant_tx),
|
2025-11-11 09:42:52 -03:00
|
|
|
});
|
2025-11-27 13:53:16 -03:00
|
|
|
|
|
|
|
|
// Initialize TaskScheduler with the AppState
|
|
|
|
|
let task_scheduler = Arc::new(botserver::tasks::scheduler::TaskScheduler::new(
|
|
|
|
|
app_state.clone(),
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
// Update AppState with the task scheduler using Arc::get_mut (requires mutable reference)
|
|
|
|
|
// Since we can't mutate Arc directly, we'll need to use unsafe or recreate AppState
|
|
|
|
|
// For now, we'll start the scheduler without updating the field
|
|
|
|
|
task_scheduler.start().await;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-26 22:54:22 -03:00
|
|
|
// Start website crawler service
|
|
|
|
|
if let Err(e) = botserver::core::kb::ensure_crawler_service_running(app_state.clone()).await {
|
|
|
|
|
log::warn!("Failed to start website crawler service: {}", e);
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
state_tx.send(app_state.clone()).await.ok();
|
|
|
|
|
progress_tx.send(BootstrapProgress::BootstrapComplete).ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
info!(
|
|
|
|
|
"Starting HTTP server on {}:{}",
|
|
|
|
|
config.server.host, config.server.port
|
|
|
|
|
);
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-11-11 09:42:52 -03:00
|
|
|
let worker_count = std::thread::available_parallelism()
|
|
|
|
|
.map(|n| n.get())
|
|
|
|
|
.unwrap_or(4);
|
2025-11-15 09:48:46 -03:00
|
|
|
|
2025-12-03 07:15:54 -03:00
|
|
|
// Initialize automation service for episodic memory
|
2025-11-27 23:10:43 -03:00
|
|
|
let _automation_service =
|
|
|
|
|
botserver::core::automation::AutomationService::new(app_state.clone());
|
2025-12-03 07:15:54 -03:00
|
|
|
info!("Automation service initialized with episodic memory scheduler");
|
2025-11-27 15:19:17 -03:00
|
|
|
|
2025-11-19 14:00:57 -03:00
|
|
|
// Mount bots
|
2025-11-11 09:42:52 -03:00
|
|
|
let bot_orchestrator = BotOrchestrator::new(app_state.clone());
|
|
|
|
|
tokio::spawn(async move {
|
|
|
|
|
if let Err(e) = bot_orchestrator.mount_all_bots().await {
|
|
|
|
|
error!("Failed to mount bots: {}", e);
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-11-19 14:00:57 -03:00
|
|
|
|
|
|
|
|
// Start automation service
|
2025-11-11 09:42:52 -03:00
|
|
|
let automation_state = app_state.clone();
|
2025-11-19 14:00:57 -03:00
|
|
|
tokio::spawn(async move {
|
|
|
|
|
let automation = AutomationService::new(automation_state);
|
|
|
|
|
automation.spawn().await.ok();
|
2025-11-11 09:42:52 -03:00
|
|
|
});
|
2025-11-19 14:00:57 -03:00
|
|
|
|
|
|
|
|
// Start LLM servers
|
2025-11-11 09:42:52 -03:00
|
|
|
let app_state_for_llm = app_state.clone();
|
|
|
|
|
tokio::spawn(async move {
|
|
|
|
|
if let Err(e) = ensure_llama_servers_running(app_state_for_llm).await {
|
|
|
|
|
error!("Failed to start LLM servers: {}", e);
|
|
|
|
|
}
|
|
|
|
|
});
|
Add .env.example with comprehensive configuration template
The commit adds a complete example environment configuration file
documenting all available settings for BotServer, including logging,
database, server, drive, LLM, Redis, email, and feature flags.
Also removes hardcoded environment variable usage throughout the
codebase, replacing them with configuration via config.csv or
appropriate defaults. This includes:
- WhatsApp, Teams, Instagram adapter configurations
- Weather API key handling
- Email and directory service configurations
- Console feature conditionally compiles monitoring code
- Improved logging configuration with library suppression
2025-11-28 13:19:03 -03:00
|
|
|
trace!("Initial data setup task spawned");
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-02 21:09:43 -03:00
|
|
|
// Run HTTP server directly
|
|
|
|
|
trace!("Starting HTTP server on port {}...", config.server.port);
|
|
|
|
|
run_axum_server(app_state, config.server.port, worker_count).await?;
|
2025-11-19 14:00:57 -03:00
|
|
|
|
2025-12-02 21:09:43 -03:00
|
|
|
// Wait for UI thread to finish if it was started
|
|
|
|
|
if let Some(handle) = ui_handle {
|
|
|
|
|
handle.join().ok();
|
2025-11-19 14:00:57 -03:00
|
|
|
}
|
|
|
|
|
|
2025-11-15 09:48:46 -03:00
|
|
|
Ok(())
|
2025-10-06 10:30:17 -03:00
|
|
|
}
|