use crate::adapter::{AdapterDispatcher, AdapterKind};
use crate::chat::ChatOptions;
use crate::client::{ModelSpec, ServiceTarget};
use crate::embed::EmbedOptions;
use crate::resolver::{AuthData, AuthResolver, ModelMapper, ServiceTargetResolver};
use crate::{Error, ModelIden, Result, WebConfig};
#[derive(Debug, Default, Clone)]
pub struct ClientConfig {
pub(super) auth_resolver: Option<AuthResolver>,
pub(super) service_target_resolver: Option<ServiceTargetResolver>,
pub(super) model_mapper: Option<ModelMapper>,
pub(super) web_config: Option<WebConfig>,
pub(super) chat_options: Option<ChatOptions>,
pub(super) embed_options: Option<EmbedOptions>,
}
impl ClientConfig {
pub fn with_auth_resolver(mut self, auth_resolver: AuthResolver) -> Self {
self.auth_resolver = Some(auth_resolver);
self
}
pub fn with_model_mapper(mut self, model_mapper: ModelMapper) -> Self {
self.model_mapper = Some(model_mapper);
self
}
pub fn with_service_target_resolver(mut self, service_target_resolver: ServiceTargetResolver) -> Self {
self.service_target_resolver = Some(service_target_resolver);
self
}
pub fn with_chat_options(mut self, options: ChatOptions) -> Self {
self.chat_options = Some(options);
self
}
pub fn with_embed_options(mut self, options: EmbedOptions) -> Self {
self.embed_options = Some(options);
self
}
pub fn with_web_config(mut self, web_config: WebConfig) -> Self {
self.web_config = Some(web_config);
self
}
pub fn web_config(&self) -> Option<&WebConfig> {
self.web_config.as_ref()
}
}
impl ClientConfig {
pub fn auth_resolver(&self) -> Option<&AuthResolver> {
self.auth_resolver.as_ref()
}
pub fn service_target_resolver(&self) -> Option<&ServiceTargetResolver> {
self.service_target_resolver.as_ref()
}
pub fn model_mapper(&self) -> Option<&ModelMapper> {
self.model_mapper.as_ref()
}
pub fn chat_options(&self) -> Option<&ChatOptions> {
self.chat_options.as_ref()
}
pub fn embed_options(&self) -> Option<&EmbedOptions> {
self.embed_options.as_ref()
}
}
impl ClientConfig {
pub async fn resolve_service_target(&self, model: ModelIden) -> Result<ServiceTarget> {
let model = self.run_model_mapper(model.clone())?;
let auth = self.run_auth_resolver(model.clone()).await?;
let endpoint = AdapterDispatcher::default_endpoint(model.adapter_kind);
let service_target = ServiceTarget {
model: model.clone(),
auth,
endpoint,
};
let service_target = self.run_service_target_resolver(service_target).await?;
Ok(service_target)
}
fn run_model_mapper(&self, model: ModelIden) -> Result<ModelIden> {
match self.model_mapper() {
Some(model_mapper) => model_mapper.map_model(model.clone()),
None => Ok(model.clone()),
}
.map_err(|resolver_error| Error::Resolver {
model_iden: model.clone(),
resolver_error,
})
}
async fn run_auth_resolver(&self, model: ModelIden) -> Result<AuthData> {
match self.auth_resolver() {
Some(auth_resolver) => {
let auth_data = auth_resolver
.resolve(model.clone())
.await
.map_err(|err| Error::Resolver {
model_iden: model.clone(),
resolver_error: err,
})?
.unwrap_or_else(|| AdapterDispatcher::default_auth(model.adapter_kind));
Ok(auth_data)
}
None => Ok(AdapterDispatcher::default_auth(model.adapter_kind)),
}
}
async fn run_service_target_resolver(&self, service_target: ServiceTarget) -> Result<ServiceTarget> {
let model = service_target.model.clone();
match self.service_target_resolver() {
Some(service_target_resolver) => {
service_target_resolver
.resolve(service_target)
.await
.map_err(|resolver_error| Error::Resolver {
model_iden: model,
resolver_error,
})
}
None => Ok(service_target),
}
}
pub async fn resolve_model_spec(&self, spec: ModelSpec) -> Result<ServiceTarget> {
match spec {
ModelSpec::Name(name) => {
let adapter_kind = AdapterKind::from_model(&name)?;
let model = ModelIden::new(adapter_kind, name);
self.resolve_service_target(model).await
}
ModelSpec::Iden(model) => self.resolve_service_target(model).await,
ModelSpec::Target(target) => self.run_service_target_resolver(target).await,
}
}
}