genai 0.7.0-beta.7

Multi-AI Providers Library for Rust. (OpenAI, Gemini, Anthropic, Ollama, AWS Bedrock, Vertex, Groq, DeepSeek, GitHub Copilot and many more)
Documentation
use crate::ModelIden;
use crate::adapter::adapters::openai::OpenAIAdapter;
use crate::adapter::{Adapter, AdapterKind, ServiceType, WebRequestData};
use crate::chat::{ChatOptionsSet, ChatRequest, ChatResponse, ChatStreamResponse};
use crate::embed::{EmbedOptionsSet, EmbedRequest, EmbedResponse};
use crate::resolver::{AuthData, Endpoint};
use crate::webc::{WebClient, WebResponse};
use crate::{Result, ServiceTarget};
use reqwest::RequestBuilder;
use serde_json::json;

pub struct OmlxAdapter;

impl Adapter for OmlxAdapter {
	const DEFAULT_API_KEY_ENV_NAME: Option<&'static str> = Some("OMLX_API_KEY");

	fn default_endpoint(_kind: AdapterKind) -> Endpoint {
		const DEFAULT_URL: &str = "http://127.0.0.1:8000/v1";
		let url = std::env::var("OMLX_ENDPOINT").unwrap_or_else(|_| DEFAULT_URL.to_string());
		Endpoint::from_owned(url)
	}

	fn default_auth(_kind: AdapterKind) -> AuthData {
		match Self::DEFAULT_API_KEY_ENV_NAME {
			Some(env_name) => {
				if std::env::var(env_name).is_ok() {
					AuthData::from_env(env_name)
				} else {
					AuthData::None
				}
			}
			None => AuthData::None,
		}
	}

	async fn all_model_names(
		kind: AdapterKind,
		endpoint: Endpoint,
		auth: AuthData,
		web_client: &WebClient,
	) -> Result<Vec<String>> {
		OpenAIAdapter::list_model_names_for_end_target(kind, endpoint, auth, web_client).await
	}

	fn get_service_url(model: &ModelIden, service_type: ServiceType, endpoint: Endpoint) -> Result<String> {
		OpenAIAdapter::util_get_service_url(model, service_type, endpoint)
	}

	fn to_web_request_data(
		target: ServiceTarget,
		service_type: ServiceType,
		chat_req: ChatRequest,
		options_set: ChatOptionsSet<'_, '_>,
	) -> Result<WebRequestData> {
		// Extract reasoning effort keyword before consuming options_set
		let effort_keyword = options_set.reasoning_effort().and_then(|e| e.as_keyword());

		let mut web_req_data =
			OpenAIAdapter::util_to_web_request_data(target, service_type, chat_req, options_set, None)?;

		if let Some(keyword) = effort_keyword {
			web_req_data.payload["chat_template_kwargs"] = json!({
				"enable_thinking": true,
				"reasoning_effort": keyword,
				"preserve_thinking": false,
			});
		}

		Ok(web_req_data)
	}

	fn to_chat_response(
		model_iden: ModelIden,
		web_response: WebResponse,
		options_set: ChatOptionsSet<'_, '_>,
	) -> Result<ChatResponse> {
		OpenAIAdapter::to_chat_response(model_iden, web_response, options_set)
	}

	fn to_chat_stream(
		model_iden: ModelIden,
		reqwest_builder: RequestBuilder,
		options_set: ChatOptionsSet<'_, '_>,
	) -> Result<ChatStreamResponse> {
		OpenAIAdapter::to_chat_stream(model_iden, reqwest_builder, options_set)
	}

	fn to_embed_request_data(
		service_target: ServiceTarget,
		embed_req: EmbedRequest,
		options_set: EmbedOptionsSet<'_, '_>,
	) -> Result<WebRequestData> {
		OpenAIAdapter::to_embed_request_data(service_target, embed_req, options_set)
	}

	fn to_embed_response(
		model_iden: ModelIden,
		web_response: WebResponse,
		options_set: EmbedOptionsSet<'_, '_>,
	) -> Result<EmbedResponse> {
		OpenAIAdapter::to_embed_response(model_iden, web_response, options_set)
	}
}