DocUA commited on
Commit
38ec34c
·
1 Parent(s): 7605012

Updated integration with Google Gemini AI, replacing the library with the new google-genai. Added new AI models, updated provider configuration, and improved query processing. Fixed bugs in response generation and logging. Changed default values for models in the configuration. Testing was successful.

Browse files
Files changed (2) hide show
  1. ai_client.py +33 -19
  2. ai_providers_config.py +12 -8
ai_client.py CHANGED
@@ -21,8 +21,8 @@ from ai_providers_config import (
21
 
22
  # Import provider-specific clients
23
  try:
24
- import google.generativeai as genai
25
- from google.generativeai import types
26
  GEMINI_AVAILABLE = True
27
  except ImportError:
28
  GEMINI_AVAILABLE = False
@@ -93,52 +93,66 @@ class BaseAIClient(ABC):
93
  logger.info(log_message)
94
 
95
  class GeminiClient(BaseAIClient):
96
- """Google Gemini AI client"""
97
 
98
  def __init__(self, model: AIModel, temperature: float = 0.3):
99
  super().__init__(AIProvider.GEMINI, model, temperature)
100
 
101
  if not GEMINI_AVAILABLE:
102
- raise ImportError("Google Generative AI library not available. Install with: pip install google-generativeai")
103
-
104
  api_key = os.getenv("GEMINI_API_KEY")
105
  if not api_key:
106
  raise ValueError("GEMINI_API_KEY environment variable not set")
107
 
108
  self.client = genai.Client(api_key=api_key)
 
109
 
110
  def generate_response(self, system_prompt: str, user_prompt: str, temperature: Optional[float] = None) -> str:
111
- """Generate response from Gemini"""
112
- temp = temperature if temperature is not None else self.temperature
113
-
 
114
  try:
 
115
  contents = [
116
  types.Content(
117
  role="user",
118
  parts=[types.Part.from_text(text=user_prompt)],
119
- ),
120
  ]
121
 
 
122
  config = types.GenerateContentConfig(
123
- temperature=temp,
124
- system_instruction=[
125
- types.Part.from_text(text=system_prompt),
126
- ],
127
  )
128
 
129
- response = ""
 
 
 
 
 
 
 
130
  for chunk in self.client.models.generate_content_stream(
131
- model=self.model.value,
132
  contents=contents,
133
  config=config,
134
  ):
135
- response += chunk.text
 
136
 
137
- response = response.strip()
138
- return response
 
 
139
 
140
  except Exception as e:
141
- raise RuntimeError(f"Gemini API error: {str(e)}")
 
 
142
 
143
  class AnthropicClient(BaseAIClient):
144
  """Anthropic Claude AI client"""
 
21
 
22
  # Import provider-specific clients
23
  try:
24
+ import google.genai as genai
25
+ from google.genai import types
26
  GEMINI_AVAILABLE = True
27
  except ImportError:
28
  GEMINI_AVAILABLE = False
 
93
  logger.info(log_message)
94
 
95
  class GeminiClient(BaseAIClient):
96
+ """Google Gemini AI client using the new google-genai library"""
97
 
98
  def __init__(self, model: AIModel, temperature: float = 0.3):
99
  super().__init__(AIProvider.GEMINI, model, temperature)
100
 
101
  if not GEMINI_AVAILABLE:
102
+ raise ImportError("Google GenAI library not available. Install with: pip install google-genai")
103
+
104
  api_key = os.getenv("GEMINI_API_KEY")
105
  if not api_key:
106
  raise ValueError("GEMINI_API_KEY environment variable not set")
107
 
108
  self.client = genai.Client(api_key=api_key)
109
+ self.model_name = model.value
110
 
111
  def generate_response(self, system_prompt: str, user_prompt: str, temperature: Optional[float] = None) -> str:
112
+ """Generate response from Gemini using the new API"""
113
+ if temperature is None:
114
+ temperature = self.temperature
115
+
116
  try:
117
+ # Prepare the content parts
118
  contents = [
119
  types.Content(
120
  role="user",
121
  parts=[types.Part.from_text(text=user_prompt)],
122
+ )
123
  ]
124
 
125
+ # Configure generation settings
126
  config = types.GenerateContentConfig(
127
+ temperature=temperature,
128
+ thinking_config=types.ThinkingConfig(thinking_budget=0),
 
 
129
  )
130
 
131
+ # Add system prompt if provided
132
+ if system_prompt:
133
+ config.system_instruction = [
134
+ types.Part.from_text(text=system_prompt)
135
+ ]
136
+
137
+ # Generate the response
138
+ response_text = ""
139
  for chunk in self.client.models.generate_content_stream(
140
+ model=self.model_name,
141
  contents=contents,
142
  config=config,
143
  ):
144
+ if chunk.text:
145
+ response_text += chunk.text
146
 
147
+ # Log the interaction
148
+ self._log_interaction(system_prompt, user_prompt, response_text, "gemini")
149
+
150
+ return response_text
151
 
152
  except Exception as e:
153
+ error_msg = f"Gemini API error: {str(e)}"
154
+ logging.error(error_msg)
155
+ raise RuntimeError(error_msg) from e
156
 
157
  class AnthropicClient(BaseAIClient):
158
  """Anthropic Claude AI client"""
ai_providers_config.py CHANGED
@@ -19,11 +19,13 @@ class AIModel(Enum):
19
  """Supported AI models"""
20
  # Gemini models
21
  GEMINI_2_5_FLASH = "gemini-2.5-flash"
 
22
  GEMINI_2_5_PRO = "gemini-2.5-pro"
23
  GEMINI_1_5_PRO = "gemini-1.5-pro"
24
 
25
  # Anthropic models
26
  CLAUDE_SONNET_4 = "claude-sonnet-4-20250514"
 
27
  CLAUDE_SONNET_3_5 = "claude-3-5-sonnet-20241022"
28
  CLAUDE_HAIKU_3_5 = "claude-3-5-haiku-20241022"
29
 
@@ -31,11 +33,12 @@ class AIModel(Enum):
31
  PROVIDER_CONFIGS = {
32
  AIProvider.GEMINI: {
33
  "api_key_env": "GEMINI_API_KEY",
34
- "default_model": AIModel.GEMINI_2_5_FLASH,
35
  "default_temperature": 0.3,
36
  "max_tokens": None, # Gemini handles this automatically
37
  "available_models": [
38
  AIModel.GEMINI_2_5_FLASH,
 
39
  AIModel.GEMINI_2_5_PRO,
40
  AIModel.GEMINI_1_5_PRO
41
  ]
@@ -47,6 +50,7 @@ PROVIDER_CONFIGS = {
47
  "max_tokens": 20000,
48
  "available_models": [
49
  AIModel.CLAUDE_SONNET_4,
 
50
  AIModel.CLAUDE_SONNET_3_5,
51
  AIModel.CLAUDE_HAIKU_3_5
52
  ]
@@ -59,42 +63,42 @@ AGENT_CONFIGURATIONS = {
59
  "MainLifestyleAssistant": {
60
  "provider": AIProvider.ANTHROPIC,
61
  "model": AIModel.CLAUDE_SONNET_4,
62
- "temperature": 0.3,
63
  "reasoning": "Complex lifestyle coaching requires advanced reasoning capabilities"
64
  },
65
 
66
  # All other agents use Google Gemini
67
  "EntryClassifier": {
68
  "provider": AIProvider.GEMINI,
69
- "model": AIModel.GEMINI_2_5_FLASH,
70
  "temperature": 0.1,
71
  "reasoning": "Fast classification task, optimized for speed"
72
  },
73
 
74
  "TriageExitClassifier": {
75
  "provider": AIProvider.GEMINI,
76
- "model": AIModel.GEMINI_2_5_FLASH,
77
  "temperature": 0.2,
78
  "reasoning": "Medical triage decisions require consistency"
79
  },
80
 
81
  "MedicalAssistant": {
82
- "provider": AIProvider.GEMINI,
83
- "model": AIModel.GEMINI_2_5_PRO,
84
  "temperature": 0.2,
85
  "reasoning": "Medical guidance requires reliable, consistent responses"
86
  },
87
 
88
  "SoftMedicalTriage": {
89
  "provider": AIProvider.GEMINI,
90
- "model": AIModel.GEMINI_2_5_FLASH,
91
  "temperature": 0.3,
92
  "reasoning": "Gentle triage can use faster model"
93
  },
94
 
95
  "LifestyleProfileUpdater": {
96
  "provider": AIProvider.GEMINI,
97
- "model": AIModel.GEMINI_2_5_PRO,
98
  "temperature": 0.2,
99
  "reasoning": "Profile analysis requires detailed processing"
100
  }
 
19
  """Supported AI models"""
20
  # Gemini models
21
  GEMINI_2_5_FLASH = "gemini-2.5-flash"
22
+ GEMINI_2_0_FLASH = "gemini-2.0-flash"
23
  GEMINI_2_5_PRO = "gemini-2.5-pro"
24
  GEMINI_1_5_PRO = "gemini-1.5-pro"
25
 
26
  # Anthropic models
27
  CLAUDE_SONNET_4 = "claude-sonnet-4-20250514"
28
+ CLAUDE_SONNET_3_7 = "claude-3-7-sonnet-20250219"
29
  CLAUDE_SONNET_3_5 = "claude-3-5-sonnet-20241022"
30
  CLAUDE_HAIKU_3_5 = "claude-3-5-haiku-20241022"
31
 
 
33
  PROVIDER_CONFIGS = {
34
  AIProvider.GEMINI: {
35
  "api_key_env": "GEMINI_API_KEY",
36
+ "default_model": AIModel.GEMINI_2_0_FLASH,
37
  "default_temperature": 0.3,
38
  "max_tokens": None, # Gemini handles this automatically
39
  "available_models": [
40
  AIModel.GEMINI_2_5_FLASH,
41
+ AIModel.GEMINI_2_0_FLASH,
42
  AIModel.GEMINI_2_5_PRO,
43
  AIModel.GEMINI_1_5_PRO
44
  ]
 
50
  "max_tokens": 20000,
51
  "available_models": [
52
  AIModel.CLAUDE_SONNET_4,
53
+ AIModel.CLAUDE_SONNET_3_7,
54
  AIModel.CLAUDE_SONNET_3_5,
55
  AIModel.CLAUDE_HAIKU_3_5
56
  ]
 
63
  "MainLifestyleAssistant": {
64
  "provider": AIProvider.ANTHROPIC,
65
  "model": AIModel.CLAUDE_SONNET_4,
66
+ "temperature": 0.2,
67
  "reasoning": "Complex lifestyle coaching requires advanced reasoning capabilities"
68
  },
69
 
70
  # All other agents use Google Gemini
71
  "EntryClassifier": {
72
  "provider": AIProvider.GEMINI,
73
+ "model": AIModel.GEMINI_2_0_FLASH,
74
  "temperature": 0.1,
75
  "reasoning": "Fast classification task, optimized for speed"
76
  },
77
 
78
  "TriageExitClassifier": {
79
  "provider": AIProvider.GEMINI,
80
+ "model": AIModel.GEMINI_2_0_FLASH,
81
  "temperature": 0.2,
82
  "reasoning": "Medical triage decisions require consistency"
83
  },
84
 
85
  "MedicalAssistant": {
86
+ "provider": AIProvider.ANTHROPIC,
87
+ "model": AIModel.CLAUDE_SONNET_4,
88
  "temperature": 0.2,
89
  "reasoning": "Medical guidance requires reliable, consistent responses"
90
  },
91
 
92
  "SoftMedicalTriage": {
93
  "provider": AIProvider.GEMINI,
94
+ "model": AIModel.GEMINI_2_0_FLASH,
95
  "temperature": 0.3,
96
  "reasoning": "Gentle triage can use faster model"
97
  },
98
 
99
  "LifestyleProfileUpdater": {
100
  "provider": AIProvider.GEMINI,
101
+ "model": AIModel.GEMINI_2_5_FLASH,
102
  "temperature": 0.2,
103
  "reasoning": "Profile analysis requires detailed processing"
104
  }