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