From 1bacf9fa69fd0891f1b508bf0423388db27f0e6a Mon Sep 17 00:00:00 2001 From: Salman Paracha Date: Sun, 7 Sep 2025 12:27:03 -0700 Subject: [PATCH] cleaned up test cases and removed unnecessary crates --- crates/hermesllm/src/lib.rs | 16 -------- crates/hermesllm/src/providers/adapters.rs | 47 ---------------------- crates/hermesllm/src/providers/id.rs | 5 +-- crates/hermesllm/src/providers/mod.rs | 2 - crates/hermesllm/src/providers/response.rs | 45 ++++++++++++--------- 5 files changed, 29 insertions(+), 86 deletions(-) delete mode 100644 crates/hermesllm/src/providers/adapters.rs diff --git a/crates/hermesllm/src/lib.rs b/crates/hermesllm/src/lib.rs index 8ebc40d6..88a4aa7b 100644 --- a/crates/hermesllm/src/lib.rs +++ b/crates/hermesllm/src/lib.rs @@ -8,7 +8,6 @@ pub mod clients; pub use providers::request::{ProviderRequestType, ProviderRequest, ProviderRequestError}; pub use providers::response::{ProviderResponseType, ProviderStreamResponseType, ProviderResponse, ProviderStreamResponse, ProviderResponseError, TokenUsage, SseEvent, SseStreamIter}; pub use providers::id::ProviderId; -pub use providers::adapters::{has_compatible_api, supported_apis}; //TODO: Refactor such that commons doesn't depend on Hermes. For now this will clean up strings @@ -28,21 +27,6 @@ mod tests { assert_eq!(ProviderId::from("arch"), ProviderId::Arch); } - #[test] - fn test_provider_api_compatibility() { - assert!(has_compatible_api(&ProviderId::OpenAI, CHAT_COMPLETIONS_PATH)); - assert!(!has_compatible_api(&ProviderId::OpenAI, "/v1/embeddings")); - } - - #[test] - fn test_provider_supported_apis() { - let apis = supported_apis(&ProviderId::OpenAI); - assert!(apis.contains(&CHAT_COMPLETIONS_PATH)); - - // Test that provider supports the expected API endpoints - assert!(has_compatible_api(&ProviderId::OpenAI, CHAT_COMPLETIONS_PATH)); - } - #[test] fn test_provider_streaming_response() { // Test streaming response parsing with sample SSE data diff --git a/crates/hermesllm/src/providers/adapters.rs b/crates/hermesllm/src/providers/adapters.rs deleted file mode 100644 index 4cf918b1..00000000 --- a/crates/hermesllm/src/providers/adapters.rs +++ /dev/null @@ -1,47 +0,0 @@ -use crate::providers::id::ProviderId; -use crate::{CHAT_COMPLETIONS_PATH, MESSAGES_PATH}; - -#[derive(Debug, Clone)] -pub enum AdapterType { - OpenAICompatible, - AnthropicCompatible, - // Future: Gemini, etc. -} - -/// Provider adapter configuration -#[derive(Debug, Clone)] -pub struct ProviderConfig { - pub supported_apis: &'static [&'static str], - pub adapter_type: AdapterType, -} - -/// Check if provider has compatible API -pub fn has_compatible_api(provider_id: &ProviderId, api_path: &str) -> bool { - let config = get_provider_config(provider_id); - config.supported_apis.iter().any(|&supported| supported == api_path) -} - -/// Get supported APIs for provider -pub fn supported_apis(provider_id: &ProviderId) -> Vec<&'static str> { - let config = get_provider_config(provider_id); - config.supported_apis.to_vec() -} - -/// Get provider configuration -pub fn get_provider_config(provider_id: &ProviderId) -> ProviderConfig { - match provider_id { - ProviderId::OpenAI | ProviderId::Groq | ProviderId::Mistral | ProviderId::Deepseek - | ProviderId::Arch | ProviderId::Gemini | ProviderId::GitHub => { - ProviderConfig { - supported_apis: &[CHAT_COMPLETIONS_PATH], - adapter_type: AdapterType::OpenAICompatible, - } - } - ProviderId::Anthropic => { - ProviderConfig { - supported_apis: &[MESSAGES_PATH], - adapter_type: AdapterType::AnthropicCompatible, - } - } - } -} diff --git a/crates/hermesllm/src/providers/id.rs b/crates/hermesllm/src/providers/id.rs index 6ffb0e71..26933adc 100644 --- a/crates/hermesllm/src/providers/id.rs +++ b/crates/hermesllm/src/providers/id.rs @@ -36,9 +36,8 @@ impl ProviderId { pub fn compatible_api_for_client(&self, client_api: &SupportedAPIs) -> SupportedAPIs { match (self, client_api) { // Claude/Anthropic providers natively support Anthropic APIs - (ProviderId::Anthropic, SupportedAPIs::AnthropicMessagesAPI(_)) => client_api.clone(), - // Claude/Anthropic providers can also support OpenAI chat completions by mapping to Anthropic Messages - (ProviderId::Anthropic, SupportedAPIs::OpenAIChatCompletions(OpenAIApi::ChatCompletions)) => SupportedAPIs::AnthropicMessagesAPI(AnthropicApi::Messages), + (ProviderId::Anthropic, SupportedAPIs::AnthropicMessagesAPI(_)) => SupportedAPIs::AnthropicMessagesAPI(AnthropicApi::Messages), + (ProviderId::Anthropic, SupportedAPIs::OpenAIChatCompletions(OpenAIApi::ChatCompletions)) => SupportedAPIs::OpenAIChatCompletions(OpenAIApi::ChatCompletions), // OpenAI-compatible providers only support OpenAI chat completions (ProviderId::OpenAI | ProviderId::Groq | ProviderId::Mistral | ProviderId::Deepseek | ProviderId::Arch | ProviderId::Gemini | ProviderId::GitHub, SupportedAPIs::AnthropicMessagesAPI(_)) => SupportedAPIs::OpenAIChatCompletions(OpenAIApi::ChatCompletions), diff --git a/crates/hermesllm/src/providers/mod.rs b/crates/hermesllm/src/providers/mod.rs index 6b9a3e9c..601af955 100644 --- a/crates/hermesllm/src/providers/mod.rs +++ b/crates/hermesllm/src/providers/mod.rs @@ -6,9 +6,7 @@ pub mod id; pub mod request; pub mod response; -pub mod adapters; pub use id::ProviderId; pub use request::{ProviderRequestType, ProviderRequest, ProviderRequestError} ; pub use response::{ProviderResponseType, ProviderResponse, ProviderStreamResponse, TokenUsage }; -pub use adapters::*; diff --git a/crates/hermesllm/src/providers/response.rs b/crates/hermesllm/src/providers/response.rs index fd757f7c..478ecfdb 100644 --- a/crates/hermesllm/src/providers/response.rs +++ b/crates/hermesllm/src/providers/response.rs @@ -11,6 +11,13 @@ use crate::apis::anthropic::MessagesStreamEvent; use crate::clients::endpoints::SupportedAPIs; use crate::apis::anthropic::MessagesResponse; +/// Trait for token usage information +pub trait TokenUsage { + fn completion_tokens(&self) -> usize; + fn prompt_tokens(&self) -> usize; + fn total_tokens(&self) -> usize; +} + #[derive(Serialize, Debug, Clone)] #[serde(untagged)] pub enum ProviderResponseType { @@ -424,14 +431,6 @@ where } } -/// Trait for token usage information -pub trait TokenUsage { - fn completion_tokens(&self) -> usize; - fn prompt_tokens(&self) -> usize; - fn total_tokens(&self) -> usize; -} - - #[derive(Debug)] pub struct ProviderResponseError { pub message: String, @@ -547,18 +546,28 @@ mod tests { #[test] fn test_openai_response_from_bytes_with_claude_provider() { - // Claude provider receives Anthropic response but client expects OpenAI format - // Upstream API = Anthropic, Client API = OpenAI -> parse Anthropic, convert to OpenAI + // Claude provider using OpenAI-compatible API returns OpenAI format response + // Client API = OpenAI, Provider = Anthropic -> Anthropic returns OpenAI format via their compatible API let resp = json!({ - "id": "msg_01ABC123", - "type": "message", - "role": "assistant", - "content": [ - { "type": "text", "text": "Hello! How can I help you today?" } - ], + "id": "chatcmpl-01ABC123", + "object": "chat.completion", + "created": 1677652288, "model": "claude-3-sonnet-20240229", - "stop_reason": "end_turn", - "usage": { "input_tokens": 10, "output_tokens": 25, "cache_creation_input_tokens": 5, "cache_read_input_tokens": 3 } + "choices": [ + { + "index": 0, + "message": { + "role": "assistant", + "content": "Hello! How can I help you today?" + }, + "finish_reason": "stop" + } + ], + "usage": { + "prompt_tokens": 10, + "completion_tokens": 25, + "total_tokens": 35 + } }); let bytes = serde_json::to_vec(&resp).unwrap(); let result = ProviderResponseType::try_from((bytes.as_slice(), &SupportedAPIs::OpenAIChatCompletions(OpenAIApi::ChatCompletions), &ProviderId::Anthropic));