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