Skip to main content

codetether_agent/provider/
mod.rs

1//! AI Provider abstraction layer.
2//!
3//! Unified interface for multiple AI providers (OpenAI, Anthropic, Google,
4//! StepFun, Bedrock, etc.).
5//!
6//! # Architecture
7//!
8//! - [`types`] — shared data types (`Message`, `StreamChunk`, etc.)
9//! - [`traits`] — the `Provider` trait and `ModelInfo`
10//! - [`registry`] — `ProviderRegistry` (name → provider map)
11//! - [`parse`] — model-string parser (`"openai/gpt-4o"` → `(provider, model)`)
12//! - [`init_vault`] — Vault-based provider initialization
13//! - [`init_config`] — TOML-config-based initialization
14//! - [`init_env`] — environment-variable fallback
15//! - [`init_dispatch`] / [`init_dispatch_impl`] — per-provider constructors
16//!
17//! Provider implementations live in their own modules (`openai`, `anthropic`,
18//! `bedrock/`, etc.).
19
20// ── Sub-module declarations ─────────────────────────────────────────
21
22pub mod anthropic;
23pub mod bedrock;
24pub mod copilot;
25pub mod gemini_web;
26pub mod glm5;
27pub mod google;
28pub mod limits;
29#[cfg(feature = "candle-cuda")]
30pub mod local_cuda;
31pub mod util;
32#[cfg(not(feature = "candle-cuda"))]
33#[allow(dead_code)]
34pub mod local_cuda {
35    //! Stub when CUDA is not compiled in.
36    use super::*;
37    use anyhow::{Result, anyhow};
38    use async_trait::async_trait;
39    use futures::stream::BoxStream;
40
41    fn feature_error() -> anyhow::Error {
42        anyhow!("local_cuda requires --features candle-cuda")
43    }
44
45    /// Stub provider type when CUDA support is not compiled in.
46    ///
47    /// All methods return errors; use `cfg(feature = "candle-cuda")` for the
48    /// real implementation.
49    ///
50    /// # Examples
51    ///
52    /// ```rust
53    /// use codetether_agent::provider::local_cuda::LocalCudaProvider;
54    /// assert!(!LocalCudaProvider::is_cuda_available());
55    /// ```
56    pub struct LocalCudaProvider;
57
58    impl LocalCudaProvider {
59        pub fn new(_m: String) -> Result<Self> {
60            Err(feature_error())
61        }
62        pub fn with_model(_m: String, _p: String) -> Result<Self> {
63            Err(feature_error())
64        }
65        pub fn with_paths(
66            _m: String,
67            _p: String,
68            _t: Option<String>,
69            _a: Option<String>,
70        ) -> Result<Self> {
71            Err(feature_error())
72        }
73        pub fn is_cuda_available() -> bool {
74            false
75        }
76        pub fn device_info() -> String {
77            "CUDA unavailable".into()
78        }
79    }
80
81    #[async_trait]
82    impl Provider for LocalCudaProvider {
83        fn name(&self) -> &str {
84            "local_cuda"
85        }
86        async fn list_models(&self) -> Result<Vec<ModelInfo>> {
87            Err(feature_error())
88        }
89        async fn complete(&self, _: CompletionRequest) -> Result<CompletionResponse> {
90            Err(feature_error())
91        }
92        async fn complete_stream(
93            &self,
94            _: CompletionRequest,
95        ) -> Result<BoxStream<'static, StreamChunk>> {
96            Err(feature_error())
97        }
98    }
99
100    #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
101    pub struct LocalCudaConfig {
102        pub model_name: String,
103        pub model_path: Option<String>,
104        pub context_window: Option<usize>,
105        pub max_new_tokens: Option<usize>,
106        pub temperature: Option<f32>,
107        pub top_p: Option<f32>,
108        pub repeat_penalty: Option<f32>,
109        pub cuda_device: Option<usize>,
110    }
111
112    impl Default for LocalCudaConfig {
113        fn default() -> Self {
114            Self {
115                model_name: "qwen3.5-9b".into(),
116                model_path: None,
117                context_window: Some(8192),
118                max_new_tokens: Some(4096),
119                temperature: Some(0.7),
120                top_p: Some(0.9),
121                repeat_penalty: Some(1.1),
122                cuda_device: Some(0),
123            }
124        }
125    }
126}
127
128pub mod metrics;
129pub mod models;
130pub mod moonshot;
131pub mod openai;
132pub mod openai_codex;
133pub mod openrouter;
134pub mod retry;
135pub mod stepfun;
136pub mod vertex_anthropic;
137pub mod vertex_glm;
138pub mod zai;
139
140// ── Internal split modules ──────────────────────────────────────────
141
142mod init_dispatch;
143mod init_dispatch_impl;
144mod init_env;
145mod parse;
146mod registry;
147mod traits;
148mod types;
149
150// ── Public re-exports (preserve the original API surface) ───────────
151
152pub use parse::parse_model_string;
153pub use registry::ProviderRegistry;
154pub use traits::{ModelInfo, Provider};
155pub use types::{
156    CompletionRequest, CompletionResponse, ContentPart, EmbeddingRequest, EmbeddingResponse,
157    FinishReason, Message, Role, StreamChunk, ToolDefinition, Usage,
158};
159
160// ── Initialisation modules (impls on ProviderRegistry) ──────────────
161
162mod init_config;
163mod init_vault;