use std::env;
use async_trait::async_trait;
use crate::error::{Result as SdkResult, SdkError};
use super::interface::{
GenerateRequest, GenerateResponse, LanguageModel, StreamHandle, StreamRequest,
};
use super::openai_chat::{OpenAiChatConfig, OpenAiChatProvider};
const DEFAULT_BASE_URL: &str = "https://api.fireworks.ai/inference/v1";
const MODEL_PREFIX: &str = "fireworks";
#[derive(Clone, Debug)]
pub struct FireworksConfig {
pub api_key: String,
pub base_url: String,
}
impl FireworksConfig {
pub fn new(api_key: impl Into<String>) -> Self {
Self {
api_key: api_key.into(),
base_url: DEFAULT_BASE_URL.to_string(),
}
}
pub fn with_base_url(mut self, base_url: impl Into<String>) -> Self {
self.base_url = base_url.into();
self
}
pub fn from_env() -> SdkResult<Self> {
let api_key = env::var("FIREWORKS_API_KEY").map_err(|_| SdkError::Configuration {
message: "FIREWORKS_API_KEY must be set".to_string(),
field: Some("FIREWORKS_API_KEY".to_string()),
})?;
let mut config = FireworksConfig::new(api_key);
if let Ok(base) = env::var("FIREWORKS_BASE_URL") {
if !base.trim().is_empty() {
config.base_url = base;
}
}
Ok(config)
}
}
#[derive(Clone)]
pub struct FireworksProvider {
inner: OpenAiChatProvider,
}
impl FireworksProvider {
pub fn new(config: FireworksConfig) -> SdkResult<Self> {
let inner_config = OpenAiChatConfig::new(config.api_key)
.with_base_url(config.base_url)
.with_model_prefix(Some(MODEL_PREFIX));
let inner = OpenAiChatProvider::new(inner_config)?;
Ok(Self { inner })
}
pub fn from_env() -> SdkResult<Self> {
let config = FireworksConfig::from_env()?;
Self::new(config)
}
pub async fn generate(&self, request: GenerateRequest) -> SdkResult<GenerateResponse> {
self.inner.generate(request).await
}
pub async fn stream(&self, request: StreamRequest) -> SdkResult<StreamHandle> {
self.inner.stream(request).await
}
}
#[async_trait]
impl LanguageModel for FireworksProvider {
async fn generate(&self, request: GenerateRequest) -> SdkResult<GenerateResponse> {
self.inner.generate(request).await
}
async fn stream(&self, request: StreamRequest) -> SdkResult<StreamHandle> {
self.inner.stream(request).await
}
}