pub mod api_types;
pub mod batch;
pub mod capabilities;
pub mod config;
pub mod convert_prompt;
pub mod embedding;
pub mod error;
pub mod files;
pub mod image;
pub mod json_accumulator;
pub mod json_schema;
pub mod language_model;
pub mod options;
pub mod output;
pub mod prepare_tools;
pub mod realtime;
pub mod request;
pub mod speech;
pub mod stream;
pub mod tools;
pub mod transcription;
pub mod video;
use std::sync::Arc;
use ferrin_provider_util::IdGenerator;
use ferrin_provider_util::SharedTransport;
use ferrin_spec::BatchRef;
use ferrin_spec::EmbeddingModelRef;
use ferrin_spec::FilesRef;
use ferrin_spec::Headers;
use ferrin_spec::ImageModelRef;
use ferrin_spec::LanguageModelRef;
use ferrin_spec::ProviderId;
use ferrin_spec::RealtimeFactoryRef;
use ferrin_spec::SpeechModelRef;
use ferrin_spec::TranscriptionModelRef;
use ferrin_spec::VideoModelRef;
use ferrin_spec::error::NoSuchModelError;
use ferrin_spec::error::ProviderError;
use ferrin_spec::provider::Provider;
use secrecy::SecretString;
use url::Url;
pub use crate::batch::GoogleBatch;
pub use crate::config::GoogleConfig;
pub use crate::config::SharedConfig;
pub use crate::embedding::GoogleEmbeddingModel;
pub use crate::files::GoogleFiles;
pub use crate::image::GoogleImageModel;
pub use crate::language_model::GoogleLanguageModel;
pub use crate::realtime::GoogleRealtimeFactory;
pub use crate::realtime::GoogleRealtimeModel;
pub use crate::speech::GoogleSpeechModel;
pub use crate::tools::GoogleTools;
pub use crate::transcription::GoogleTranscriptionModel;
pub use crate::video::GoogleVideoModel;
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
#[derive(Default)]
pub struct GoogleSettings {
pub base_url: Option<Url>,
pub api_key: Option<SecretString>,
pub headers: Headers,
pub name: Option<String>,
pub transport: Option<SharedTransport>,
pub id_generator: Option<Arc<dyn IdGenerator>>,
}
impl std::fmt::Debug for GoogleSettings {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("GoogleSettings")
.field("base_url", &self.base_url)
.field("api_key", &self.api_key.as_ref().map(|_| "***"))
.field("headers", &self.headers)
.field("name", &self.name)
.finish_non_exhaustive()
}
}
pub fn create_google(settings: GoogleSettings) -> Result<GoogleProvider, ProviderError> {
let base_url = match settings.base_url {
Some(url) => ferrin_provider_util::base_url::parse_base_url(url.as_str())?,
None => ferrin_provider_util::base_url::parse_base_url(config::DEFAULT_BASE_URL)?,
};
let transport = match settings.transport {
Some(transport) => transport,
None => ferrin_provider_util::default_transport().map_err(ProviderError::other)?,
};
let mut config = GoogleConfig::with_transport(
settings
.name
.unwrap_or_else(|| config::DEFAULT_NAME.to_owned()),
base_url,
transport,
);
config.api_key = settings.api_key;
config.headers = settings.headers;
if let Some(id_generator) = settings.id_generator {
config.id_generator = id_generator;
}
Ok(GoogleProvider::from_config(Arc::new(config)))
}
#[derive(Debug, Clone)]
pub struct GoogleProvider {
config: SharedConfig,
provider_id: ProviderId,
tools: GoogleTools,
}
impl GoogleProvider {
#[must_use]
pub fn from_config(config: SharedConfig) -> Self {
Self {
provider_id: ProviderId::new(config.name.clone()),
tools: GoogleTools::new(),
config,
}
}
#[must_use]
pub fn config(&self) -> &SharedConfig {
&self.config
}
#[must_use]
pub fn language_model(&self, model_id: &str) -> GoogleLanguageModel {
GoogleLanguageModel::new(self.config.clone(), model_id)
}
#[must_use]
pub fn chat(&self, model_id: &str) -> GoogleLanguageModel {
self.language_model(model_id)
}
#[must_use]
pub fn embedding(&self, model_id: &str) -> GoogleEmbeddingModel {
GoogleEmbeddingModel::new(self.config.clone(), model_id)
}
#[must_use]
pub fn text_embedding(&self, model_id: &str) -> GoogleEmbeddingModel {
self.embedding(model_id)
}
#[must_use]
pub fn image(&self, model_id: &str) -> GoogleImageModel {
GoogleImageModel::new(self.config.clone(), model_id)
}
#[must_use]
pub fn speech(&self, model_id: &str) -> GoogleSpeechModel {
GoogleSpeechModel::new(self.config.clone(), model_id)
}
#[must_use]
pub fn transcription(&self, model_id: &str) -> GoogleTranscriptionModel {
GoogleTranscriptionModel::new(self.config.clone(), model_id)
}
#[must_use]
pub fn video(&self, model_id: &str) -> GoogleVideoModel {
GoogleVideoModel::new(self.config.clone(), model_id)
}
#[must_use]
pub fn files(&self) -> GoogleFiles {
GoogleFiles::new(self.config.clone())
}
#[must_use]
pub fn batch(&self) -> GoogleBatch {
GoogleBatch::new(self.config.clone())
}
#[must_use]
pub fn realtime(&self) -> GoogleRealtimeFactory {
GoogleRealtimeFactory::new(self.config.clone())
}
#[must_use]
pub fn tools(&self) -> &GoogleTools {
&self.tools
}
}
impl Provider for GoogleProvider {
fn provider_id(&self) -> &ProviderId {
&self.provider_id
}
fn language_model(&self, model_id: &str) -> Result<LanguageModelRef, NoSuchModelError> {
Ok(GoogleProvider::language_model(self, model_id).into())
}
fn embedding_model(&self, model_id: &str) -> Result<EmbeddingModelRef, NoSuchModelError> {
Ok(self.embedding(model_id).into())
}
fn image_model(&self, model_id: &str) -> Result<ImageModelRef, NoSuchModelError> {
Ok(self.image(model_id).into())
}
fn transcription_model(
&self,
model_id: &str,
) -> Result<TranscriptionModelRef, NoSuchModelError> {
Ok(self.transcription(model_id).into())
}
fn speech_model(&self, model_id: &str) -> Result<SpeechModelRef, NoSuchModelError> {
Ok(self.speech(model_id).into())
}
fn video_model(&self, model_id: &str) -> Result<VideoModelRef, NoSuchModelError> {
Ok(self.video(model_id).into())
}
fn realtime(&self) -> Option<RealtimeFactoryRef> {
Some(GoogleProvider::realtime(self).into())
}
fn files(&self) -> Option<FilesRef> {
Some(GoogleProvider::files(self).into())
}
fn batch(&self) -> Option<BatchRef> {
Some(GoogleProvider::batch(self).into())
}
}