mirror of
https://github.com/mii443/rust-genai.git
synced 2025-08-22 16:25:27 +00:00
. clippy clean
This commit is contained in:
@ -7,9 +7,8 @@
|
||||
//! Therefore, below we use regular chat, and this crate provides an XaiAdapter.
|
||||
|
||||
use genai::adapter::AdapterKind;
|
||||
use genai::chat::printer::{print_chat_stream, PrintChatStreamOptions};
|
||||
use genai::chat::{ChatMessage, ChatRequest};
|
||||
use genai::resolver::{AuthData, AuthResolver, Endpoint, ServiceTargetResolver};
|
||||
use genai::resolver::{AuthData, Endpoint, ServiceTargetResolver};
|
||||
use genai::{Client, ModelIden, ServiceTarget};
|
||||
|
||||
const MODEL: &str = "grok-beta";
|
||||
@ -25,7 +24,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// -- Build an auth_resolver and the AdapterConfig
|
||||
let target_resolver = ServiceTargetResolver::from_resolver_fn(
|
||||
|service_target: ServiceTarget| -> Result<ServiceTarget, genai::resolver::Error> {
|
||||
let ServiceTarget { endpoint, auth, model } = service_target;
|
||||
let ServiceTarget { model, .. } = service_target;
|
||||
let endpoint = Endpoint::from_static("https://api.x.ai/v1/");
|
||||
let auth = AuthData::from_env("XAI_API_KEY");
|
||||
let model = ModelIden::new(AdapterKind::OpenAI, model.model_name);
|
||||
|
@ -1,5 +1,4 @@
|
||||
use super::groq::MODELS as GROQ_MODELS;
|
||||
use crate::adapter::{Adapter, AdapterDispatcher};
|
||||
use crate::Result;
|
||||
use derive_more::Display;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -2,7 +2,7 @@ use crate::adapter::AdapterKind;
|
||||
use crate::chat::{ChatOptionsSet, ChatRequest, ChatResponse, ChatStreamResponse};
|
||||
use crate::resolver::{AuthData, Endpoint};
|
||||
use crate::webc::WebResponse;
|
||||
use crate::{ClientConfig, ModelIden};
|
||||
use crate::ModelIden;
|
||||
use crate::{Result, ServiceTarget};
|
||||
use reqwest::RequestBuilder;
|
||||
use serde_json::Value;
|
||||
@ -25,7 +25,6 @@ pub trait Adapter {
|
||||
/// To be implemented by Adapters.
|
||||
fn to_web_request_data(
|
||||
service_target: ServiceTarget,
|
||||
config_set: &ClientConfig,
|
||||
service_type: ServiceType,
|
||||
chat_req: ChatRequest,
|
||||
options_set: ChatOptionsSet<'_, '_>,
|
||||
|
@ -7,7 +7,7 @@ use crate::chat::{
|
||||
};
|
||||
use crate::resolver::{AuthData, Endpoint};
|
||||
use crate::webc::WebResponse;
|
||||
use crate::{ClientConfig, ModelIden};
|
||||
use crate::ModelIden;
|
||||
use crate::{Result, ServiceTarget};
|
||||
use reqwest::RequestBuilder;
|
||||
use reqwest_eventsource::EventSource;
|
||||
@ -31,12 +31,12 @@ const MODELS: &[&str] = &[
|
||||
];
|
||||
|
||||
impl Adapter for AnthropicAdapter {
|
||||
fn default_endpoint(kind: AdapterKind) -> Endpoint {
|
||||
fn default_endpoint(_kind: AdapterKind) -> Endpoint {
|
||||
const BASE_URL: &str = "https://api.anthropic.com/v1/";
|
||||
Endpoint::from_static(BASE_URL)
|
||||
}
|
||||
|
||||
fn default_auth(kind: AdapterKind) -> AuthData {
|
||||
fn default_auth(_kind: AdapterKind) -> AuthData {
|
||||
AuthData::from_env("ANTHROPIC_API_KEY")
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ impl Adapter for AnthropicAdapter {
|
||||
Ok(MODELS.iter().map(|s| s.to_string()).collect())
|
||||
}
|
||||
|
||||
fn get_service_url(model: &ModelIden, service_type: ServiceType, endpoint: Endpoint) -> String {
|
||||
fn get_service_url(_model: &ModelIden, service_type: ServiceType, endpoint: Endpoint) -> String {
|
||||
let base_url = endpoint.base_url();
|
||||
match service_type {
|
||||
ServiceType::Chat | ServiceType::ChatStream => format!("{base_url}messages"),
|
||||
@ -54,7 +54,6 @@ impl Adapter for AnthropicAdapter {
|
||||
|
||||
fn to_web_request_data(
|
||||
target: ServiceTarget,
|
||||
client_config: &ClientConfig,
|
||||
service_type: ServiceType,
|
||||
chat_req: ChatRequest,
|
||||
options_set: ChatOptionsSet<'_, '_>,
|
||||
|
@ -6,8 +6,8 @@ use crate::chat::{
|
||||
};
|
||||
use crate::resolver::{AuthData, Endpoint};
|
||||
use crate::webc::{WebResponse, WebStream};
|
||||
use crate::{ClientConfig, ModelIden, ServiceTarget};
|
||||
use crate::{Error, Result};
|
||||
use crate::{ModelIden, ServiceTarget};
|
||||
use reqwest::RequestBuilder;
|
||||
use serde_json::{json, Value};
|
||||
use value_ext::JsonValueExt;
|
||||
@ -24,12 +24,12 @@ const MODELS: &[&str] = &[
|
||||
];
|
||||
|
||||
impl Adapter for CohereAdapter {
|
||||
fn default_endpoint(kind: AdapterKind) -> Endpoint {
|
||||
fn default_endpoint(_kind: AdapterKind) -> Endpoint {
|
||||
const BASE_URL: &str = "https://api.cohere.com/v1/";
|
||||
Endpoint::from_static(BASE_URL)
|
||||
}
|
||||
|
||||
fn default_auth(kind: AdapterKind) -> AuthData {
|
||||
fn default_auth(_kind: AdapterKind) -> AuthData {
|
||||
AuthData::from_env("COHERE_API_KEY")
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ impl Adapter for CohereAdapter {
|
||||
Ok(MODELS.iter().map(|s| s.to_string()).collect())
|
||||
}
|
||||
|
||||
fn get_service_url(model: &ModelIden, service_type: ServiceType, endpoint: Endpoint) -> String {
|
||||
fn get_service_url(_model: &ModelIden, service_type: ServiceType, endpoint: Endpoint) -> String {
|
||||
let base_url = endpoint.base_url();
|
||||
match service_type {
|
||||
ServiceType::Chat | ServiceType::ChatStream => format!("{base_url}chat"),
|
||||
@ -47,7 +47,6 @@ impl Adapter for CohereAdapter {
|
||||
|
||||
fn to_web_request_data(
|
||||
target: ServiceTarget,
|
||||
client_config: &ClientConfig,
|
||||
service_type: ServiceType,
|
||||
chat_req: ChatRequest,
|
||||
options_set: ChatOptionsSet<'_, '_>,
|
||||
|
@ -7,8 +7,8 @@ use crate::chat::{
|
||||
};
|
||||
use crate::resolver::{AuthData, Endpoint};
|
||||
use crate::webc::{WebResponse, WebStream};
|
||||
use crate::{ClientConfig, ModelIden, ServiceTarget};
|
||||
use crate::{Error, Result};
|
||||
use crate::{ModelIden, ServiceTarget};
|
||||
use reqwest::RequestBuilder;
|
||||
use serde_json::{json, Value};
|
||||
use value_ext::JsonValueExt;
|
||||
@ -29,12 +29,12 @@ const MODELS: &[&str] = &[
|
||||
// -X POST 'https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash-latest:generateContent?key=YOUR_API_KEY'
|
||||
|
||||
impl Adapter for GeminiAdapter {
|
||||
fn default_endpoint(kind: AdapterKind) -> Endpoint {
|
||||
fn default_endpoint(_kind: AdapterKind) -> Endpoint {
|
||||
const BASE_URL: &str = "https://generativelanguage.googleapis.com/v1beta/";
|
||||
Endpoint::from_static(BASE_URL)
|
||||
}
|
||||
|
||||
fn default_auth(kind: AdapterKind) -> AuthData {
|
||||
fn default_auth(_kind: AdapterKind) -> AuthData {
|
||||
AuthData::from_env("GEMINI_API_KEY")
|
||||
}
|
||||
|
||||
@ -56,7 +56,6 @@ impl Adapter for GeminiAdapter {
|
||||
|
||||
fn to_web_request_data(
|
||||
target: ServiceTarget,
|
||||
client_config: &ClientConfig,
|
||||
service_type: ServiceType,
|
||||
chat_req: ChatRequest,
|
||||
options_set: ChatOptionsSet<'_, '_>,
|
||||
|
@ -3,7 +3,7 @@ use crate::adapter::{Adapter, AdapterKind, ServiceType, WebRequestData};
|
||||
use crate::chat::{ChatOptionsSet, ChatRequest, ChatResponse, ChatStreamResponse};
|
||||
use crate::resolver::{AuthData, Endpoint};
|
||||
use crate::webc::WebResponse;
|
||||
use crate::{ClientConfig, ModelIden};
|
||||
use crate::ModelIden;
|
||||
use crate::{Result, ServiceTarget};
|
||||
use reqwest::RequestBuilder;
|
||||
|
||||
@ -29,12 +29,12 @@ pub(in crate::adapter) const MODELS: &[&str] = &[
|
||||
|
||||
// The Groq API adapter is modeled after the OpenAI adapter, as the Groq API is compatible with the OpenAI API.
|
||||
impl Adapter for GroqAdapter {
|
||||
fn default_endpoint(kind: AdapterKind) -> Endpoint {
|
||||
fn default_endpoint(_kind: AdapterKind) -> Endpoint {
|
||||
const BASE_URL: &str = "https://api.groq.com/openai/v1/";
|
||||
Endpoint::from_static(BASE_URL)
|
||||
}
|
||||
|
||||
fn default_auth(kind: AdapterKind) -> AuthData {
|
||||
fn default_auth(_kind: AdapterKind) -> AuthData {
|
||||
AuthData::from_env("GROQ_API_KEY")
|
||||
}
|
||||
|
||||
@ -48,7 +48,6 @@ impl Adapter for GroqAdapter {
|
||||
|
||||
fn to_web_request_data(
|
||||
target: ServiceTarget,
|
||||
client_config: &ClientConfig,
|
||||
service_type: ServiceType,
|
||||
chat_req: ChatRequest,
|
||||
chat_options: ChatOptionsSet<'_, '_>,
|
||||
|
@ -5,8 +5,8 @@ use crate::adapter::{Adapter, AdapterKind, ServiceType, WebRequestData};
|
||||
use crate::chat::{ChatOptionsSet, ChatRequest, ChatResponse, ChatStreamResponse};
|
||||
use crate::resolver::{AuthData, Endpoint};
|
||||
use crate::webc::WebResponse;
|
||||
use crate::{ClientConfig, ModelIden, ServiceTarget};
|
||||
use crate::{Error, Result};
|
||||
use crate::{ModelIden, ServiceTarget};
|
||||
use reqwest::RequestBuilder;
|
||||
use serde_json::Value;
|
||||
use value_ext::JsonValueExt;
|
||||
@ -17,12 +17,12 @@ pub struct OllamaAdapter;
|
||||
/// (https://github.com/ollama/ollama/blob/main/docs/openai.md)
|
||||
/// Since the base Ollama API supports `application/x-ndjson` for streaming, whereas others support `text/event-stream`
|
||||
impl Adapter for OllamaAdapter {
|
||||
fn default_endpoint(kind: AdapterKind) -> Endpoint {
|
||||
fn default_endpoint(_kind: AdapterKind) -> Endpoint {
|
||||
const BASE_URL: &str = "http://localhost:11434/v1/";
|
||||
Endpoint::from_static(BASE_URL)
|
||||
}
|
||||
|
||||
fn default_auth(kind: AdapterKind) -> AuthData {
|
||||
fn default_auth(_kind: AdapterKind) -> AuthData {
|
||||
AuthData::from_single("ollama")
|
||||
}
|
||||
|
||||
@ -65,7 +65,6 @@ impl Adapter for OllamaAdapter {
|
||||
|
||||
fn to_web_request_data(
|
||||
target: ServiceTarget,
|
||||
client_config: &ClientConfig,
|
||||
service_type: ServiceType,
|
||||
chat_req: ChatRequest,
|
||||
chat_options: ChatOptionsSet<'_, '_>,
|
||||
|
@ -7,8 +7,8 @@ use crate::chat::{
|
||||
};
|
||||
use crate::resolver::{AuthData, Endpoint};
|
||||
use crate::webc::WebResponse;
|
||||
use crate::{ClientConfig, ModelIden, ServiceTarget};
|
||||
use crate::{Error, Result};
|
||||
use crate::{ModelIden, ServiceTarget};
|
||||
use reqwest::RequestBuilder;
|
||||
use reqwest_eventsource::EventSource;
|
||||
use serde::Deserialize;
|
||||
@ -27,12 +27,12 @@ const MODELS: &[&str] = &[
|
||||
];
|
||||
|
||||
impl Adapter for OpenAIAdapter {
|
||||
fn default_endpoint(kind: AdapterKind) -> Endpoint {
|
||||
fn default_endpoint(_kind: AdapterKind) -> Endpoint {
|
||||
const BASE_URL: &str = "https://api.openai.com/v1/";
|
||||
Endpoint::from_static(BASE_URL)
|
||||
}
|
||||
|
||||
fn default_auth(kind: AdapterKind) -> AuthData {
|
||||
fn default_auth(_kind: AdapterKind) -> AuthData {
|
||||
AuthData::from_env("OPENAI_API_KEY")
|
||||
}
|
||||
|
||||
@ -47,7 +47,6 @@ impl Adapter for OpenAIAdapter {
|
||||
|
||||
fn to_web_request_data(
|
||||
target: ServiceTarget,
|
||||
client_config: &ClientConfig,
|
||||
service_type: ServiceType,
|
||||
chat_req: ChatRequest,
|
||||
chat_options: ChatOptionsSet<'_, '_>,
|
||||
|
@ -3,7 +3,7 @@ use crate::adapter::{Adapter, AdapterKind, ServiceType, WebRequestData};
|
||||
use crate::chat::{ChatOptionsSet, ChatRequest, ChatResponse, ChatStreamResponse};
|
||||
use crate::resolver::{AuthData, Endpoint};
|
||||
use crate::webc::WebResponse;
|
||||
use crate::{ClientConfig, ModelIden};
|
||||
use crate::ModelIden;
|
||||
use crate::{Result, ServiceTarget};
|
||||
use reqwest::RequestBuilder;
|
||||
|
||||
@ -13,12 +13,12 @@ pub(in crate::adapter) const MODELS: &[&str] = &["grok-beta"];
|
||||
|
||||
// The Groq API adapter is modeled after the OpenAI adapter, as the Groq API is compatible with the OpenAI API.
|
||||
impl Adapter for XaiAdapter {
|
||||
fn default_endpoint(kind: AdapterKind) -> Endpoint {
|
||||
fn default_endpoint(_kind: AdapterKind) -> Endpoint {
|
||||
const BASE_URL: &str = "https://api.x.ai/v1/";
|
||||
Endpoint::from_static(BASE_URL)
|
||||
}
|
||||
|
||||
fn default_auth(kind: AdapterKind) -> AuthData {
|
||||
fn default_auth(_kind: AdapterKind) -> AuthData {
|
||||
AuthData::from_env("XAI_API_KEY")
|
||||
}
|
||||
|
||||
@ -32,7 +32,6 @@ impl Adapter for XaiAdapter {
|
||||
|
||||
fn to_web_request_data(
|
||||
target: ServiceTarget,
|
||||
client_config: &ClientConfig,
|
||||
service_type: ServiceType,
|
||||
chat_req: ChatRequest,
|
||||
chat_options: ChatOptionsSet<'_, '_>,
|
||||
|
@ -6,7 +6,7 @@ use crate::adapter::openai::OpenAIAdapter;
|
||||
use crate::adapter::{Adapter, AdapterKind, ServiceType, WebRequestData};
|
||||
use crate::chat::{ChatOptionsSet, ChatRequest, ChatResponse, ChatStreamResponse};
|
||||
use crate::webc::WebResponse;
|
||||
use crate::{ClientConfig, ModelIden};
|
||||
use crate::ModelIden;
|
||||
use crate::{Result, ServiceTarget};
|
||||
use reqwest::RequestBuilder;
|
||||
|
||||
@ -67,34 +67,21 @@ impl Adapter for AdapterDispatcher {
|
||||
|
||||
fn to_web_request_data(
|
||||
target: ServiceTarget,
|
||||
client_config: &ClientConfig,
|
||||
service_type: ServiceType,
|
||||
chat_req: ChatRequest,
|
||||
options_set: ChatOptionsSet<'_, '_>,
|
||||
) -> Result<WebRequestData> {
|
||||
let adapter_kind = &target.model.adapter_kind;
|
||||
match adapter_kind {
|
||||
AdapterKind::OpenAI => {
|
||||
OpenAIAdapter::to_web_request_data(target, client_config, service_type, chat_req, options_set)
|
||||
}
|
||||
AdapterKind::OpenAI => OpenAIAdapter::to_web_request_data(target, service_type, chat_req, options_set),
|
||||
AdapterKind::Anthropic => {
|
||||
AnthropicAdapter::to_web_request_data(target, client_config, service_type, chat_req, options_set)
|
||||
}
|
||||
AdapterKind::Cohere => {
|
||||
CohereAdapter::to_web_request_data(target, client_config, service_type, chat_req, options_set)
|
||||
}
|
||||
AdapterKind::Ollama => {
|
||||
OllamaAdapter::to_web_request_data(target, client_config, service_type, chat_req, options_set)
|
||||
}
|
||||
AdapterKind::Gemini => {
|
||||
GeminiAdapter::to_web_request_data(target, client_config, service_type, chat_req, options_set)
|
||||
}
|
||||
AdapterKind::Groq => {
|
||||
GroqAdapter::to_web_request_data(target, client_config, service_type, chat_req, options_set)
|
||||
}
|
||||
AdapterKind::Xai => {
|
||||
XaiAdapter::to_web_request_data(target, client_config, service_type, chat_req, options_set)
|
||||
AnthropicAdapter::to_web_request_data(target, service_type, chat_req, options_set)
|
||||
}
|
||||
AdapterKind::Cohere => CohereAdapter::to_web_request_data(target, service_type, chat_req, options_set),
|
||||
AdapterKind::Ollama => OllamaAdapter::to_web_request_data(target, service_type, chat_req, options_set),
|
||||
AdapterKind::Gemini => GeminiAdapter::to_web_request_data(target, service_type, chat_req, options_set),
|
||||
AdapterKind::Groq => GroqAdapter::to_web_request_data(target, service_type, chat_req, options_set),
|
||||
AdapterKind::Xai => XaiAdapter::to_web_request_data(target, service_type, chat_req, options_set),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,6 @@
|
||||
|
||||
// region: --- Modules
|
||||
|
||||
mod support;
|
||||
|
||||
mod adapter_kind;
|
||||
mod adapter_types;
|
||||
mod adapters;
|
||||
|
@ -1,4 +0,0 @@
|
||||
use crate::adapter::{Adapter, AdapterDispatcher, AdapterKind};
|
||||
use crate::resolver::AuthData;
|
||||
use crate::{ClientConfig, ModelIden};
|
||||
use crate::{Error, Result};
|
@ -58,7 +58,7 @@ impl Client {
|
||||
let model = target.model.clone();
|
||||
|
||||
let WebRequestData { headers, payload, url } =
|
||||
AdapterDispatcher::to_web_request_data(target, self.config(), ServiceType::Chat, chat_req, options_set)?;
|
||||
AdapterDispatcher::to_web_request_data(target, ServiceType::Chat, chat_req, options_set)?;
|
||||
|
||||
let web_res =
|
||||
self.web_client()
|
||||
@ -89,13 +89,8 @@ impl Client {
|
||||
let target = self.config().resolve_service_target(model)?;
|
||||
let model = target.model.clone();
|
||||
|
||||
let WebRequestData { url, headers, payload } = AdapterDispatcher::to_web_request_data(
|
||||
target,
|
||||
self.config(),
|
||||
ServiceType::ChatStream,
|
||||
chat_req,
|
||||
options_set.clone(),
|
||||
)?;
|
||||
let WebRequestData { url, headers, payload } =
|
||||
AdapterDispatcher::to_web_request_data(target, ServiceType::ChatStream, chat_req, options_set.clone())?;
|
||||
|
||||
let reqwest_builder = self
|
||||
.web_client()
|
||||
|
@ -3,6 +3,7 @@ mod support;
|
||||
use crate::support::common_tests;
|
||||
use genai::adapter::AdapterKind;
|
||||
use genai::resolver::AuthData;
|
||||
use serial_test::serial;
|
||||
|
||||
type Result<T> = core::result::Result<T, Box<dyn std::error::Error>>; // For tests.
|
||||
|
||||
@ -13,11 +14,13 @@ const MODEL: &str = "grok-beta";
|
||||
// region: --- Chat
|
||||
|
||||
#[tokio::test]
|
||||
#[serial(xai)]
|
||||
async fn test_chat_simple_ok() -> Result<()> {
|
||||
common_tests::common_test_chat_simple_ok(MODEL).await
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial(xai)]
|
||||
async fn test_chat_multi_system_ok() -> Result<()> {
|
||||
common_tests::common_test_chat_multi_system_ok(MODEL).await
|
||||
}
|
||||
@ -35,6 +38,7 @@ async fn test_chat_multi_system_ok() -> Result<()> {
|
||||
// }
|
||||
|
||||
#[tokio::test]
|
||||
#[serial(xai)]
|
||||
async fn test_chat_temperature_ok() -> Result<()> {
|
||||
common_tests::common_test_chat_temperature_ok(MODEL).await
|
||||
}
|
||||
@ -51,16 +55,19 @@ async fn test_chat_temperature_ok() -> Result<()> {
|
||||
// region: --- Chat Stream Tests
|
||||
|
||||
#[tokio::test]
|
||||
#[serial(xai)]
|
||||
async fn test_chat_stream_simple_ok() -> Result<()> {
|
||||
common_tests::common_test_chat_stream_simple_ok(MODEL).await
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial(xai)]
|
||||
async fn test_chat_stream_capture_content_ok() -> Result<()> {
|
||||
common_tests::common_test_chat_stream_capture_content_ok(MODEL).await
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial(xai)]
|
||||
async fn test_chat_stream_capture_all_ok() -> Result<()> {
|
||||
common_tests::common_test_chat_stream_capture_all_ok(MODEL).await
|
||||
}
|
||||
@ -70,6 +77,7 @@ async fn test_chat_stream_capture_all_ok() -> Result<()> {
|
||||
// region: --- Resolver Tests
|
||||
|
||||
#[tokio::test]
|
||||
#[serial(xai)]
|
||||
async fn test_resolver_auth_ok() -> Result<()> {
|
||||
common_tests::common_test_resolver_auth_ok(MODEL, AuthData::from_env("XAI_API_KEY")).await
|
||||
}
|
||||
@ -79,6 +87,7 @@ async fn test_resolver_auth_ok() -> Result<()> {
|
||||
// region: --- List
|
||||
|
||||
#[tokio::test]
|
||||
#[serial(xai)]
|
||||
async fn test_list_models() -> Result<()> {
|
||||
common_tests::common_test_list_models(AdapterKind::Xai, "grok-beta").await
|
||||
}
|
||||
|
Reference in New Issue
Block a user