shanusherly commited on
Commit
36dc3c6
·
verified ·
1 Parent(s): 73ca514

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +93 -56
app.py CHANGED
@@ -3,69 +3,86 @@ import gradio as gr
3
  import requests
4
  import google.generativeai as genai
5
 
6
- from langchain_core.prompts import PromptTemplate
7
- from langchain_classic.memory import ConversationBufferMemory
8
-
9
- # ------------------------------------
10
  # Load API keys from environment
11
- # ------------------------------------
12
  GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
13
  ELEVENLABS_API_KEY = os.environ.get("ELEVENLABS_API_KEY")
14
  ELEVENLABS_VOICE_ID = "21m00Tcm4TlvDq8ikWAM"
15
 
 
 
 
 
 
 
 
16
  # Configure Gemini
17
  genai.configure(api_key=GEMINI_API_KEY)
18
 
19
- # ------------------------------------
20
- # Prompt + Memory
21
- # ------------------------------------
22
- template = """You are a helpful assistant.
23
  {chat_history}
24
  User: {user_message}
25
  Chatbot:"""
26
 
27
- prompt = PromptTemplate(
28
- input_variables=["chat_history", "user_message"],
29
- template=template
30
- )
 
31
 
32
- memory = ConversationBufferMemory(memory_key="chat_history")
 
 
33
 
34
- # ------------------------------------
35
- # Gemini Wrapper
36
- # ------------------------------------
37
- gemini_model = genai.GenerativeModel("gemini-2.5-flash")
38
 
39
- class GeminiLLM:
40
- def __init__(self, model):
41
- self.model = model
42
- self.memory_history = []
43
 
44
- def predict(self, user_message):
45
- full_prompt = "You are a helpful assistant.\n"
46
- for msg in self.memory_history:
47
- full_prompt += msg + "\n"
48
- full_prompt += f"User: {user_message}\nChatbot:"
49
 
50
- response = self.model.generate_content(full_prompt)
51
- answer = response.text
52
 
53
- self.memory_history.append(f"User: {user_message}")
54
- self.memory_history.append(f"Chatbot: {answer}")
55
-
56
- if len(self.memory_history) > 20:
57
- self.memory_history = self.memory_history[-20:]
58
 
59
- return answer
 
 
 
60
 
61
- llm_chain = GeminiLLM(gemini_model)
 
 
 
 
 
62
 
63
- # ------------------------------------
64
- # ElevenLabs Audio (Hugging Face friendly)
65
- # ------------------------------------
66
  def generate_audio_elevenlabs(text):
67
- from elevenlabs.client import ElevenLabs
68
- from elevenlabs import save
 
 
 
 
 
 
 
 
69
 
70
  try:
71
  client = ElevenLabs(api_key=ELEVENLABS_API_KEY)
@@ -75,32 +92,52 @@ def generate_audio_elevenlabs(text):
75
  model="eleven_monolingual_v1"
76
  )
77
 
 
78
  output_path = f"/tmp/audio_{abs(hash(text)) % 100000}.mp3"
79
  save(audio, output_path)
80
  return output_path
81
-
82
  except Exception as e:
83
- print("Audio error:", e)
 
84
  return ""
85
 
86
- # ------------------------------------
87
  # Combined response
88
- # ------------------------------------
89
- def get_response_and_audio(message):
90
- text = llm_chain.predict(message)
91
- audio_path = generate_audio_elevenlabs(text)
 
 
 
 
 
 
 
 
 
 
92
  return text, audio_path
93
 
94
- # ------------------------------------
95
- # Gradio ChatHandler (UI unchanged)
96
- # ------------------------------------
97
  def chat_bot_response(message, history):
98
- text, audio_path = get_response_and_audio(message)
 
 
 
 
 
 
 
 
 
99
  return text
100
 
101
- # ------------------------------------
102
- # UI (same as your original)
103
- # ------------------------------------
104
  demo = gr.ChatInterface(
105
  fn=chat_bot_response,
106
  title="🤖 Gemini + ElevenLabs Chatbot",
@@ -112,7 +149,7 @@ demo = gr.ChatInterface(
112
  "What's the weather like today?",
113
  "Explain quantum computing in simple terms"
114
  ],
115
- theme=gr.themes.Soft()
116
  )
117
 
118
  if __name__ == "__main__":
 
3
  import requests
4
  import google.generativeai as genai
5
 
6
+ # -----------------------------
 
 
 
7
  # Load API keys from environment
8
+ # -----------------------------
9
  GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
10
  ELEVENLABS_API_KEY = os.environ.get("ELEVENLABS_API_KEY")
11
  ELEVENLABS_VOICE_ID = "21m00Tcm4TlvDq8ikWAM"
12
 
13
+ # Safety: fail early if no keys
14
+ if not GEMINI_API_KEY:
15
+ raise RuntimeError("Missing GEMINI_API_KEY in environment")
16
+ if not ELEVENLABS_API_KEY:
17
+ # Not strictly fatal if you only want text, but warn:
18
+ print("Warning: ELEVENLABS_API_KEY not set — audio generation will fail.")
19
+
20
  # Configure Gemini
21
  genai.configure(api_key=GEMINI_API_KEY)
22
 
23
+ # -----------------------------
24
+ # Simple prompt template + memory (no LangChain)
25
+ # -----------------------------
26
+ PROMPT_TEMPLATE = """You are a helpful assistant.
27
  {chat_history}
28
  User: {user_message}
29
  Chatbot:"""
30
 
31
+ # Use a simple in-memory ring buffer for conversation (keeps last N messages)
32
+ class SimpleMemory:
33
+ def __init__(self, max_messages=20):
34
+ self.max_messages = max_messages
35
+ self.history = [] # list of strings like "User: ...", "Chatbot: ..."
36
 
37
+ def add_user(self, text):
38
+ self.history.append(f"User: {text}")
39
+ self._trim()
40
 
41
+ def add_bot(self, text):
42
+ self.history.append(f"Chatbot: {text}")
43
+ self._trim()
 
44
 
45
+ def _trim(self):
46
+ if len(self.history) > self.max_messages:
47
+ self.history = self.history[-self.max_messages:]
 
48
 
49
+ def as_text(self):
50
+ return "\n".join(self.history)
 
 
 
51
 
52
+ memory = SimpleMemory(max_messages=20)
 
53
 
54
+ # -----------------------------
55
+ # Gemini wrapper (simple)
56
+ # -----------------------------
57
+ # Keep a single model instance
58
+ gemini_model = genai.GenerativeModel("gemini-2.5-flash")
59
 
60
+ def generate_text_with_gemini(user_message):
61
+ # Build full prompt
62
+ chat_history = memory.as_text()
63
+ full_prompt = PROMPT_TEMPLATE.format(chat_history=chat_history, user_message=user_message)
64
 
65
+ # Use the SDK to generate
66
+ # NOTE: API may return a response object; using .generate_content as before
67
+ response = gemini_model.generate_content(full_prompt)
68
+ # response.text contains the assistant output
69
+ text = response.text if hasattr(response, "text") else str(response)
70
+ return text
71
 
72
+ # -----------------------------
73
+ # ElevenLabs audio generation (lazy import)
74
+ # -----------------------------
75
  def generate_audio_elevenlabs(text):
76
+ """
77
+ Returns output_path on success, empty string on failure.
78
+ Uses /tmp directory (Hugging Face friendly).
79
+ """
80
+ try:
81
+ from elevenlabs.client import ElevenLabs
82
+ from elevenlabs import save
83
+ except Exception as e:
84
+ print("ElevenLabs import failed:", e)
85
+ return ""
86
 
87
  try:
88
  client = ElevenLabs(api_key=ELEVENLABS_API_KEY)
 
92
  model="eleven_monolingual_v1"
93
  )
94
 
95
+ # Safe temp path for HF Spaces
96
  output_path = f"/tmp/audio_{abs(hash(text)) % 100000}.mp3"
97
  save(audio, output_path)
98
  return output_path
 
99
  except Exception as e:
100
+ # log and return empty result so UI still shows text
101
+ print("ElevenLabs generation error:", e)
102
  return ""
103
 
104
+ # -----------------------------
105
  # Combined response
106
+ # -----------------------------
107
+ def get_text_and_audio(user_message):
108
+ # Text
109
+ text = generate_text_with_gemini(user_message)
110
+
111
+ # Update memory
112
+ memory.add_user(user_message)
113
+ memory.add_bot(text)
114
+
115
+ # Audio (non-blocking style: we still run it but return text even if audio fails)
116
+ audio_path = ""
117
+ if ELEVENLABS_API_KEY:
118
+ audio_path = generate_audio_elevenlabs(text)
119
+
120
  return text, audio_path
121
 
122
+ # -----------------------------
123
+ # Chat handler used by Gradio UI (unchanged UI)
124
+ # -----------------------------
125
  def chat_bot_response(message, history):
126
+ """
127
+ Gradio ChatInterface function signature:
128
+ - message: new user message (string)
129
+ - history: prior messages (list) provided by Gradio (we don't need to rely on it)
130
+ Return: text response (Gradio ChatInterface will render it)
131
+ """
132
+ text, audio_path = get_text_and_audio(message)
133
+
134
+ # Optionally: attach audio playback by returning a dict or specific component.
135
+ # To keep the UI identical and simple, we return text only — same behavior as before.
136
  return text
137
 
138
+ # -----------------------------
139
+ # UI (exact ChatInterface parameters preserved, including theme)
140
+ # -----------------------------
141
  demo = gr.ChatInterface(
142
  fn=chat_bot_response,
143
  title="🤖 Gemini + ElevenLabs Chatbot",
 
149
  "What's the weather like today?",
150
  "Explain quantum computing in simple terms"
151
  ],
152
+ theme=gr.themes.Soft() # keep theme — requirements pin ensures support
153
  )
154
 
155
  if __name__ == "__main__":