Arnavkumar01 commited on
Commit
e141e7c
·
1 Parent(s): 2f2f8a0

DO I remember why am I doing this ? Fuck no. but am I going to do this FUCK yes

Browse files
Files changed (1) hide show
  1. main.py +71 -20
main.py CHANGED
@@ -50,7 +50,30 @@ TABLE_DESCRIPTIONS = """
50
  embeddings = None
51
  vector_store = None
52
  client_openai = OpenAI(api_key=OPENAI_API_KEY)
53
- client_elevenlabs = ElevenLabs(api_key=ELEVENLABS_API_KEY)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
 
56
  # --- LIFESPAN ---
@@ -71,6 +94,13 @@ async def lifespan(app: FastAPI):
71
  yield
72
  logging.info("Shutting down.")
73
 
 
 
 
 
 
 
 
74
 
75
  app = FastAPI(lifespan=lifespan)
76
 
@@ -90,16 +120,14 @@ You are a query analysis agent. Transform the user's query into a precise search
90
 
91
  ANSWER_SYSTEM_PROMPT = """
92
  You are an expert AI assistant for a premier real estate developer.
93
- ## YOUR PERSONA
94
- - You are professional, helpful, and highly knowledgeable. Your tone should be polite and articulate.
95
- ## CORE BUSINESS KNOWLEDGE
96
- - **Operational Cities:** We are currently operational in Pune, Mumbai, Bengaluru, Delhi, Chennai, Hyderabad, Goa, Gurgaon, Kolkata.
97
- - **Property Types:** We offer luxury apartments, villas, and commercial properties.
98
- - **Budget Range:** Our residential properties typically range from 45 lakhs to 5 crores.
99
- ## CORE RULES
100
- 1. **Language Adaptation:** If the user's original query was in Hinglish, respond in Hinglish. If in English, respond in English.
101
- 2. **Fact-Based Answers:** Use the provided CONTEXT to answer the user's question. If the context is empty, use your Core Business Knowledge.
102
- 3. **Stay on Topic:** Only answer questions related to real estate.
103
  """
104
 
105
 
@@ -136,28 +164,48 @@ def transcribe_audio(audio_path: str, audio_bytes: bytes) -> str:
136
  return ""
137
  return ""
138
 
139
-
140
  def generate_elevenlabs_sync(text: str, voice: str) -> bytes:
 
 
 
 
 
 
141
  for attempt in range(3):
142
  try:
143
- return client_elevenlabs.generate(
 
 
144
  text=text,
145
  voice=voice,
146
  model="eleven_multilingual_v2",
147
  output_format="mp3_44100_128"
148
  )
 
 
 
 
 
 
 
 
 
 
 
 
149
  except Exception as e:
150
- logging.error(f"ElevenLabs error (attempt {attempt+1}): {e}", exc_info=True) # Added exc_info
151
  if attempt == 2:
152
  return b''
153
  return b''
 
154
 
155
- # --- UPDATED formulate_search_plan with logging ---
156
  async def formulate_search_plan(user_query: str) -> dict:
157
  logging.info(f"Formulating search plan for query: {user_query}")
158
  for attempt in range(3):
159
  try:
160
- # --- FIX: Format the prompt here with BOTH variables ---
161
  formatted_prompt = QUERY_FORMULATION_PROMPT.format(
162
  table_descriptions=TABLE_DESCRIPTIONS,
163
  user_query=user_query
@@ -170,7 +218,6 @@ async def formulate_search_plan(user_query: str) -> dict:
170
  response_format={"type": "json_object"},
171
  temperature=0.0
172
  )
173
- # ... rest of the function ...
174
  # Log the raw response BEFORE trying to parse
175
  raw_response_content = response.choices[0].message.content
176
  logging.info(f"Raw Planner LLM response content: {raw_response_content}")
@@ -188,7 +235,6 @@ async def formulate_search_plan(user_query: str) -> dict:
188
  # Fallback if loop finishes unexpectedly
189
  logging.error("Planner loop finished unexpectedly. Using fallback.")
190
  return {"search_query": user_query, "filter_table": None}
191
- # --- END UPDATED FUNCTION ---
192
 
193
  async def get_agent_response(user_text: str) -> str:
194
  for attempt in range(3):
@@ -273,12 +319,17 @@ async def process_audio(audio_path):
273
  generate_elevenlabs_sync, agent_response, ELEVENLABS_VOICE_NAME
274
  )
275
  if not ai_audio_bytes:
276
- return None, "Failed to generate voice."
 
 
 
277
 
278
  # Save to temp file
279
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as f:
280
  f.write(ai_audio_bytes)
281
  out_path = f.name
 
 
282
 
283
  return out_path, f"**You:** {user_text}\n\n**AI:** {agent_response}"
284
 
@@ -295,7 +346,7 @@ with gr.Blocks(title="Real Estate AI") as demo:
295
  with gr.Row():
296
  inp = gr.Audio(sources=["microphone"], type="filepath", label="Speak")
297
  out_audio = gr.Audio(label="AI Response", type="filepath")
298
-
299
  out_text = gr.Textbox(label="Conversation", lines=8)
300
 
301
  inp.change(process_audio, inp, [out_audio, out_text])
 
50
  embeddings = None
51
  vector_store = None
52
  client_openai = OpenAI(api_key=OPENAI_API_KEY)
53
+ client_elevenlabs = None # Initialize as None first
54
+
55
+ # --- ADDED: DETAILED ELEVENLABS INITIALIZATION LOGGING ---
56
+ try:
57
+ # Log the key (partially) to verify it's being read
58
+ key_preview = ELEVENLABS_API_KEY[:5] + "..." + ELEVENLABS_API_KEY[-4:] if ELEVENLABS_API_KEY and len(ELEVENLABS_API_KEY) > 9 else "None or too short"
59
+ logging.info(f"Attempting to initialize ElevenLabs client with key: {key_preview}")
60
+
61
+ # Ensure key is not None or empty before initializing
62
+ if not ELEVENLABS_API_KEY:
63
+ raise ValueError("ELEVENLABS_API_KEY environment variable not set or empty.")
64
+
65
+ client_elevenlabs = ElevenLabs(api_key=ELEVENLABS_API_KEY)
66
+ logging.info(f"Initialized ElevenLabs client object. Type: {type(client_elevenlabs)}")
67
+
68
+ # Try accessing a simple attribute or method to confirm initialization
69
+ # Note: This might make a network call during startup
70
+ voices = client_elevenlabs.voices.get_all()
71
+ logging.info(f"Successfully fetched {len(voices.voices)} voices from ElevenLabs.")
72
+
73
+ except Exception as e:
74
+ logging.error(f"Failed to initialize ElevenLabs client or fetch voices: {e}", exc_info=True)
75
+ client_elevenlabs = None # Ensure it's None if init failed
76
+ # --- END ADDED LOGGING ---
77
 
78
 
79
  # --- LIFESPAN ---
 
94
  yield
95
  logging.info("Shutting down.")
96
 
97
+ # --- ADDED: LIBRARY VERSION LOGGING ---
98
+ try:
99
+ import elevenlabs
100
+ logging.info(f"Found elevenlabs library version: {elevenlabs.__version__}")
101
+ except ImportError:
102
+ logging.error("Could not import elevenlabs library!")
103
+ # --- END ADDED LOGGING ---
104
 
105
  app = FastAPI(lifespan=lifespan)
106
 
 
120
 
121
  ANSWER_SYSTEM_PROMPT = """
122
  You are an expert AI assistant for a premier real estate developer.
123
+ ## CORE KNOWLEDGE
124
+ - Cities: Pune, Mumbai, Bengaluru, Delhi, Chennai, Hyderabad, Goa, Gurgaon, Kolkata.
125
+ - Properties: Luxury apartments, villas, commercial.
126
+ - Budget: 45 lakhs to 5 crores.
127
+ ## RULES
128
+ 1. Match user language (Hinglish Hinglish, English English).
129
+ 2. Use CONTEXT if available, else use core knowledge.
130
+ 3. Only answer real estate questions.
 
 
131
  """
132
 
133
 
 
164
  return ""
165
  return ""
166
 
167
+ # --- UPDATED generate_elevenlabs_sync with check ---
168
  def generate_elevenlabs_sync(text: str, voice: str) -> bytes:
169
+ # --- ADDED THIS CHECK ---
170
+ if client_elevenlabs is None:
171
+ logging.error("ElevenLabs client is not initialized. Cannot generate audio.")
172
+ return b''
173
+ # --- END ADDED CHECK ---
174
+
175
  for attempt in range(3):
176
  try:
177
+ # This call might still fail if init succeeded but key is bad at runtime
178
+ logging.info(f"Calling ElevenLabs generate for voice '{voice}'...")
179
+ audio_data = client_elevenlabs.generate(
180
  text=text,
181
  voice=voice,
182
  model="eleven_multilingual_v2",
183
  output_format="mp3_44100_128"
184
  )
185
+ # Check if generate returns bytes directly or needs iteration (depends on exact version/method)
186
+ if isinstance(audio_data, bytes):
187
+ logging.info(f"ElevenLabs generate returned {len(audio_data)} bytes.")
188
+ return audio_data
189
+ else:
190
+ # Handle streaming iterator if necessary
191
+ chunks = b""
192
+ for chunk in audio_data:
193
+ chunks += chunk
194
+ logging.info(f"ElevenLabs generate streamed {len(chunks)} bytes.")
195
+ return chunks
196
+
197
  except Exception as e:
198
+ logging.error(f"ElevenLabs error during generate (attempt {attempt+1}): {e}", exc_info=True) # Added exc_info
199
  if attempt == 2:
200
  return b''
201
  return b''
202
+ # --- END UPDATED FUNCTION ---
203
 
 
204
  async def formulate_search_plan(user_query: str) -> dict:
205
  logging.info(f"Formulating search plan for query: {user_query}")
206
  for attempt in range(3):
207
  try:
208
+ # Format the prompt here with BOTH variables
209
  formatted_prompt = QUERY_FORMULATION_PROMPT.format(
210
  table_descriptions=TABLE_DESCRIPTIONS,
211
  user_query=user_query
 
218
  response_format={"type": "json_object"},
219
  temperature=0.0
220
  )
 
221
  # Log the raw response BEFORE trying to parse
222
  raw_response_content = response.choices[0].message.content
223
  logging.info(f"Raw Planner LLM response content: {raw_response_content}")
 
235
  # Fallback if loop finishes unexpectedly
236
  logging.error("Planner loop finished unexpectedly. Using fallback.")
237
  return {"search_query": user_query, "filter_table": None}
 
238
 
239
  async def get_agent_response(user_text: str) -> str:
240
  for attempt in range(3):
 
319
  generate_elevenlabs_sync, agent_response, ELEVENLABS_VOICE_NAME
320
  )
321
  if not ai_audio_bytes:
322
+ # Return the text response even if TTS fails
323
+ logging.error("Failed to generate voice. Returning text only.")
324
+ return None, f"**You:** {user_text}\n\n**AI:** {agent_response}\n\n_(Audio generation failed)_"
325
+
326
 
327
  # Save to temp file
328
  with tempfile.NamedTemporaryFile(delete=False, suffix=".mp3") as f:
329
  f.write(ai_audio_bytes)
330
  out_path = f.name
331
+ logging.info(f"Saved generated audio to temp file: {out_path}")
332
+
333
 
334
  return out_path, f"**You:** {user_text}\n\n**AI:** {agent_response}"
335
 
 
346
  with gr.Row():
347
  inp = gr.Audio(sources=["microphone"], type="filepath", label="Speak")
348
  out_audio = gr.Audio(label="AI Response", type="filepath")
349
+
350
  out_text = gr.Textbox(label="Conversation", lines=8)
351
 
352
  inp.change(process_audio, inp, [out_audio, out_text])