pub mod circuit_breaker;
pub mod client;
pub mod context;
pub mod models;
pub mod provider;
pub mod registry;
pub mod types;
pub use circuit_breaker::CircuitBreaker;
pub use client::AiClient;
pub use models::{AiModel, ModelProvider};
pub use provider::AiProvider;
pub use registry::{ProviderConfig, all_providers, get_provider};
pub use types::{CreateIssueResponse, CreditsStatus, TriageResponse};
use crate::history::AiStats;
pub const CEREBRAS_API_URL: &str = "https://api.cerebras.ai/v1/chat/completions";
pub const CEREBRAS_API_KEY_ENV: &str = "CEREBRAS_API_KEY";
pub const GEMINI_API_URL: &str =
"https://generativelanguage.googleapis.com/v1beta/openai/chat/completions";
pub const GEMINI_API_KEY_ENV: &str = "GEMINI_API_KEY";
pub const GROQ_API_URL: &str = "https://api.groq.com/openai/v1/chat/completions";
pub const GROQ_API_KEY_ENV: &str = "GROQ_API_KEY";
pub const OPENROUTER_API_URL: &str = "https://openrouter.ai/api/v1/chat/completions";
pub const OPENROUTER_API_KEY_ENV: &str = "OPENROUTER_API_KEY";
#[derive(Debug, Clone)]
pub struct AiResponse {
pub triage: TriageResponse,
pub stats: AiStats,
}
#[must_use]
pub fn is_free_model(model: &str) -> bool {
model.ends_with(":free")
}
pub async fn create_issue(
title: &str,
body: &str,
repo: &str,
) -> anyhow::Result<(CreateIssueResponse, AiStats)> {
let config = crate::config::load_config()?;
let client = AiClient::new(&config.ai.provider, &config.ai)?;
client.create_issue(title, body, repo).await
}