codetether_agent/provider/
google.rs1use super::{CompletionRequest, CompletionResponse, ModelInfo, Provider, StreamChunk};
4use anyhow::Result;
5use async_trait::async_trait;
6
7pub struct GoogleProvider {
8 api_key: String,
9}
10
11impl std::fmt::Debug for GoogleProvider {
12 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13 f.debug_struct("GoogleProvider")
14 .field("api_key", &"<REDACTED>")
15 .field("api_key_len", &self.api_key.len())
16 .finish()
17 }
18}
19
20impl GoogleProvider {
21 pub fn new(api_key: String) -> Result<Self> {
22 tracing::debug!(
23 provider = "google",
24 api_key_len = api_key.len(),
25 "Creating Google provider"
26 );
27 Ok(Self { api_key })
28 }
29
30 fn validate_api_key(&self) -> Result<()> {
32 if self.api_key.is_empty() {
33 anyhow::bail!("Google API key is empty");
34 }
35 if self.api_key.len() < 10 {
36 tracing::warn!(provider = "google", "API key seems unusually short");
37 }
38 Ok(())
39 }
40}
41
42#[async_trait]
43impl Provider for GoogleProvider {
44 fn name(&self) -> &str {
45 "google"
46 }
47
48 async fn list_models(&self) -> Result<Vec<ModelInfo>> {
49 tracing::debug!(provider = "google", "Listing available models");
50 self.validate_api_key()?;
51
52 Ok(vec![
53 ModelInfo {
54 id: "gemini-2.5-pro".to_string(),
55 name: "Gemini 2.5 Pro".to_string(),
56 provider: "google".to_string(),
57 context_window: 1_000_000,
58 max_output_tokens: Some(65_536),
59 supports_vision: true,
60 supports_tools: true,
61 supports_streaming: true,
62 input_cost_per_million: Some(1.25),
63 output_cost_per_million: Some(10.0),
64 },
65 ModelInfo {
66 id: "gemini-2.5-flash".to_string(),
67 name: "Gemini 2.5 Flash".to_string(),
68 provider: "google".to_string(),
69 context_window: 1_000_000,
70 max_output_tokens: Some(65_536),
71 supports_vision: true,
72 supports_tools: true,
73 supports_streaming: true,
74 input_cost_per_million: Some(0.15),
75 output_cost_per_million: Some(0.6),
76 },
77 ])
78 }
79
80 async fn complete(&self, request: CompletionRequest) -> Result<CompletionResponse> {
81 tracing::debug!(
82 provider = "google",
83 model = %request.model,
84 message_count = request.messages.len(),
85 tool_count = request.tools.len(),
86 "Starting completion request"
87 );
88
89 self.validate_api_key()?;
91
92 anyhow::bail!("Google provider not yet implemented")
94 }
95
96 async fn complete_stream(
97 &self,
98 request: CompletionRequest,
99 ) -> Result<futures::stream::BoxStream<'static, StreamChunk>> {
100 tracing::debug!(
101 provider = "google",
102 model = %request.model,
103 message_count = request.messages.len(),
104 "Starting streaming completion request"
105 );
106
107 self.validate_api_key()?;
108 anyhow::bail!("Google provider not yet implemented")
109 }
110}