Girish Jeswani commited on
Commit
21e8a1d
·
1 Parent(s): ff13d20

gemini changes

Browse files
multi_llm_chatbot_backend/app/llm/gemini_client.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import httpx
2
+ import os
3
+ import json
4
+ from typing import List
5
+ from app.llm.llm_client import LLMClient
6
+
7
+ class GeminiClient(LLMClient):
8
+ def __init__(self, model_name: str = os.getenv("GEMINI_MODEL")):
9
+ self.model_name = model_name
10
+ self.api_key = os.getenv("GEMINI_API_KEY")
11
+ if not self.api_key:
12
+ raise ValueError("GEMINI_API_KEY environment variable is required")
13
+
14
+ self.base_url = "https://generativelanguage.googleapis.com/v1beta/models"
15
+
16
+ async def generate(self, system_prompt: str, context: List[dict]) -> str:
17
+ # Format messages for Gemini API
18
+ formatted_messages = []
19
+
20
+ # Add system instruction
21
+ if system_prompt:
22
+ formatted_messages.append({
23
+ "role": "user",
24
+ "parts": [{"text": f"System instruction: {system_prompt}"}]
25
+ })
26
+ formatted_messages.append({
27
+ "role": "model",
28
+ "parts": [{"text": "I understand. I'll follow these instructions in our conversation."}]
29
+ })
30
+
31
+ # Add conversation history
32
+ for msg in context:
33
+ role = msg['role'].lower()
34
+ content = msg['content']
35
+
36
+ if role == "user":
37
+ formatted_messages.append({
38
+ "role": "user",
39
+ "parts": [{"text": content}]
40
+ })
41
+ elif role in ["methodist", "theorist", "pragmatist"]:
42
+ # These are previous advisor responses, treat as model responses
43
+ formatted_messages.append({
44
+ "role": "model",
45
+ "parts": [{"text": content}]
46
+ })
47
+
48
+ payload = {
49
+ "contents": formatted_messages,
50
+ "generationConfig": {
51
+ "temperature": 0.7,
52
+ "topK": 40,
53
+ "topP": 0.9,
54
+ "maxOutputTokens": 200,
55
+ "stopSequences": []
56
+ },
57
+ "safetySettings": [
58
+ {
59
+ "category": "HARM_CATEGORY_HARASSMENT",
60
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
61
+ },
62
+ {
63
+ "category": "HARM_CATEGORY_HATE_SPEECH",
64
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
65
+ },
66
+ {
67
+ "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
68
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
69
+ },
70
+ {
71
+ "category": "HARM_CATEGORY_DANGEROUS_CONTENT",
72
+ "threshold": "BLOCK_MEDIUM_AND_ABOVE"
73
+ }
74
+ ]
75
+ }
76
+
77
+ try:
78
+ url = f"{self.base_url}/{self.model_name}:generateContent?key={self.api_key}"
79
+
80
+ async with httpx.AsyncClient(timeout=30.0) as client:
81
+ response = await client.post(url, json=payload)
82
+ response.raise_for_status()
83
+
84
+ result = response.json()
85
+
86
+ # Extract text from Gemini response
87
+ if "candidates" in result and len(result["candidates"]) > 0:
88
+ candidate = result["candidates"][0]
89
+ if "content" in candidate and "parts" in candidate["content"]:
90
+ parts = candidate["content"]["parts"]
91
+ if len(parts) > 0 and "text" in parts[0]:
92
+ text = parts[0]["text"].strip()
93
+
94
+ # Clean up common response patterns
95
+ text = text.replace("Here are 2-3 sentence", "").strip()
96
+ text = text.replace("Here's an expansion of the advice:", "").strip()
97
+
98
+ if len(text) < 10 or text in [":", ".", ""]:
99
+ return "I'd be happy to help with that. Could you provide more specific details about what you're looking for?"
100
+
101
+ return text
102
+
103
+ return "I apologize, but I'm having trouble generating a response right now. Please try again."
104
+
105
+ except httpx.HTTPError as e:
106
+ return f"I apologize, but I'm having trouble connecting to generate a response. Please try again."
107
+ except Exception as e:
108
+ return f"I apologize, but I'm having trouble generating a response right now. Please try again."