Skip to main content

codex_convert_proxy/providers/
default.rs

1//! Default generic provider implementation.
2//!
3//! This provider is used as a fallback when the provider name is not found
4//! in the registry. It makes minimal assumptions about the provider,
5//! assuming most providers follow the OpenAI-compatible Chat API format.
6//!
7//! Unlike named providers (GLM, Kimi, etc.), `DefaultProvider` is **not**
8//! registered in the static factory registry. Instead, [`create_provider`]
9//! constructs it directly when no matching registry entry is found. This
10//! keeps the fallback mechanism separate from the user-facing provider
11//! namespace.
12
13use crate::providers::trait_::Provider;
14use crate::types::chat_api::{ChatRequest, ChatResponse, ChatStreamChunk};
15
16/// Default provider that makes minimal assumptions.
17///
18/// This provider assumes:
19/// - Standard OpenAI-compatible API path: `/chat/completions`
20///   (the `/v1` prefix comes from the backend URL's base_path)
21/// - Model names are passed through as-is
22/// - No special request/response transformations needed
23///
24/// Use this as a fallback for providers not explicitly supported.
25///
26/// The `backend_name` field preserves the backend name from the config
27/// (e.g., `"qwen"`, `"yi"`) so that logging and diagnostics can identify
28/// which backend a request was routed to, even though the provider
29/// implementation is the generic default.
30pub struct DefaultProvider {
31    /// The original backend name from config, preserved for diagnostics.
32    backend_name: String,
33}
34
35impl Default for DefaultProvider {
36    fn default() -> Self {
37        Self {
38            backend_name: "default".to_string(),
39        }
40    }
41}
42
43impl DefaultProvider {
44    /// Create a new DefaultProvider with the original backend name.
45    ///
46    /// The `backend_name` is the name the user specified in `config.json`
47    /// (e.g., `"qwen"`, `"yi-lightning"`). It is preserved for logging
48    /// and diagnostics; the provider type is always `"default"`.
49    pub fn new(backend_name: &str) -> Self {
50        Self {
51            backend_name: backend_name.to_lowercase(),
52        }
53    }
54}
55
56impl Provider for DefaultProvider {
57    /// Returns `"default"` to indicate this is the generic fallback provider.
58    fn name(&self) -> &'static str {
59        "default"
60    }
61
62    /// Returns the original backend name from config (e.g., `"qwen"`,
63    /// `"yi-lightning"`), making it easy to identify which backend a
64    /// request was routed to in logs and diagnostics.
65    fn display_name(&self) -> &str {
66        &self.backend_name
67    }
68
69    fn chat_completions_path(&self) -> String {
70        // Standard OpenAI-compatible path (without /v1 prefix)
71        "/chat/completions".to_string()
72    }
73
74    // No transformations - pass through as-is
75    fn transform_request(&self, _request: &mut ChatRequest) {}
76
77    fn transform_response(&self, _response: &mut ChatResponse) {}
78
79    fn transform_stream_chunk(&self, _chunk: &mut ChatStreamChunk) {}
80}