use anyhow::{Context, Result};
use clap::Parser;
use console::style;
use dotenvy::dotenv;
use opencrates::cli::{Cli, EnhancedCli};
use opencrates::providers::OpenAIProvider;
use opencrates::utils::cache::CacheManager;
use opencrates::utils::logging;
use opencrates::utils::metrics::OpenCratesMetrics;
use opencrates::utils::openai_agents::{
AgentManager, CrateAssistant, OpenAIClient, OpenAIClientConfig,
};
use std::process;
use std::sync::Arc;
use tracing::{info, warn, Level};
#[tokio::main]
async fn main() {
if let Err(e) = run().await {
eprintln!("{} {}", style("ERROR:").red().bold(), e);
let mut source = e.source();
while let Some(err) = source {
eprintln!("{} {}", style(" caused by:").dim(), err);
source = err.source();
}
process::exit(1);
}
}
async fn run() -> Result<()> {
dotenv().ok();
let cli = Cli::parse();
let level = if cli.verbose {
Level::DEBUG
} else if cli.quiet {
Level::ERROR
} else {
Level::INFO
};
logging::init(level);
info!("Starting OpenCrates v{}", env!("CARGO_PKG_VERSION"));
let _agents = initialize_agents().await?;
info!("AI agents initialized successfully");
let mut enhanced_cli = EnhancedCli::new_with_config(cli.config.clone())
.await
.context("Failed to initialize OpenCrates CLI")?;
enhanced_cli
.run(cli)
.await
.context("CLI execution failed")?;
info!("OpenCrates operation completed successfully");
Ok(())
}
async fn initialize_agents() -> Result<AgentManager> {
let api_key =
std::env::var("OPENAI_API_KEY").context("OPENAI_API_KEY environment variable not set")?;
if api_key.is_empty() {
warn!("OpenAI API key is empty - some features may not work");
}
let metrics = Arc::new(OpenCratesMetrics::new().await?);
let cache = Arc::new(CacheManager::new());
let config = OpenAIClientConfig {
api_key,
base_url: "https://api.openai.com/v1".to_string(),
model: "gpt-4o".to_string(),
max_tokens: Some(4096),
temperature: Some(0.7),
timeout: std::time::Duration::from_secs(60),
max_retries: 3,
};
let openai_client = Arc::new(OpenAIClient::new(config, metrics.clone(), cache.clone()));
let _assistant = CrateAssistant::new(openai_client.clone()).await?;
let openai_provider = OpenAIProvider::new().await?;
let agent_manager = AgentManager::new(openai_provider).await?;
info!(
"Agent manager initialized with {} agents",
agent_manager.list_agents().await.len()
);
Ok(agent_manager)
}