Spaces:
Runtime error
Runtime error
Upload 10 files
Browse files- app/chatbot.py +7 -7
- app/gradio_interface.py +34 -8
- app/lecture_generator.py +1 -5
- app/rag_system.py +3 -10
- app/utils.py +0 -4
- app/voice_synthesizer.py +6 -6
app/chatbot.py
CHANGED
@@ -5,19 +5,15 @@ from typing import Dict, Any, List, Optional
|
|
5 |
from datetime import datetime
|
6 |
from app.models import ChatMessage, ChatSession
|
7 |
from app.rag_system import RAGSystem
|
8 |
-
from dotenv import load_dotenv
|
9 |
-
|
10 |
-
# Load environment variables
|
11 |
-
load_dotenv()
|
12 |
|
13 |
logger = logging.getLogger(__name__)
|
14 |
|
15 |
class RAGChatbot:
|
16 |
"""RAG-powered chatbot with memory of PDF and lecture content"""
|
17 |
|
18 |
-
def __init__(self):
|
19 |
-
self.client = openai.OpenAI(api_key=
|
20 |
-
self.rag_system = RAGSystem()
|
21 |
self.sessions: Dict[str, ChatSession] = {}
|
22 |
self.max_context_length = 8000 # Token limit for context
|
23 |
|
@@ -253,3 +249,7 @@ Always strive to be helpful while being honest about the limitations of your kno
|
|
253 |
except Exception as e:
|
254 |
logger.error(f"Failed to update session content {session_id}: {str(e)}")
|
255 |
return False
|
|
|
|
|
|
|
|
|
|
5 |
from datetime import datetime
|
6 |
from app.models import ChatMessage, ChatSession
|
7 |
from app.rag_system import RAGSystem
|
|
|
|
|
|
|
|
|
8 |
|
9 |
logger = logging.getLogger(__name__)
|
10 |
|
11 |
class RAGChatbot:
|
12 |
"""RAG-powered chatbot with memory of PDF and lecture content"""
|
13 |
|
14 |
+
def __init__(self, openai_api_key: str):
|
15 |
+
self.client = openai.OpenAI(api_key=openai_api_key)
|
16 |
+
self.rag_system = RAGSystem(openai_api_key=openai_api_key)
|
17 |
self.sessions: Dict[str, ChatSession] = {}
|
18 |
self.max_context_length = 8000 # Token limit for context
|
19 |
|
|
|
249 |
except Exception as e:
|
250 |
logger.error(f"Failed to update session content {session_id}: {str(e)}")
|
251 |
return False
|
252 |
+
|
253 |
+
def set_api_key(self, api_key: str):
|
254 |
+
"""Set the OpenAI API key dynamically."""
|
255 |
+
self.client = openai.OpenAI(api_key=api_key)
|
app/gradio_interface.py
CHANGED
@@ -14,10 +14,11 @@ from app.chatbot import RAGChatbot
|
|
14 |
logger = logging.getLogger(__name__)
|
15 |
|
16 |
# Initialize components
|
|
|
17 |
pdf_processor = PDFProcessor()
|
18 |
lecture_generator = LectureGenerator()
|
19 |
-
voice_synthesizer = VoiceSynthesizer()
|
20 |
-
chatbot = RAGChatbot()
|
21 |
|
22 |
# Global state for sessions
|
23 |
current_session = None
|
@@ -60,6 +61,15 @@ def create_gradio_interface():
|
|
60 |
|
61 |
# Session state
|
62 |
session_id_state = gr.State(value=str(uuid.uuid4()))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
with gr.Tab("📄 PDF Upload & Processing"):
|
65 |
with gr.Row():
|
@@ -138,10 +148,13 @@ def create_gradio_interface():
|
|
138 |
refresh_stats_btn = gr.Button("Refresh Stats")
|
139 |
|
140 |
# Event handlers
|
141 |
-
def process_pdf_handler(pdf_file, style, examples, learning_objectives, session_id):
|
142 |
"""Handle PDF processing or topic-based lecture generation"""
|
143 |
global session_data
|
144 |
-
|
|
|
|
|
|
|
145 |
try:
|
146 |
# Check if we have either PDF or learning objectives
|
147 |
if pdf_file is None and not learning_objectives.strip():
|
@@ -304,12 +317,15 @@ def create_gradio_interface():
|
|
304 |
logger.error(f"Audio generation error: {str(e)}")
|
305 |
return None
|
306 |
|
307 |
-
def chat_handler(message, history, session_id):
|
308 |
"""Handle chat messages"""
|
309 |
if not message.strip():
|
310 |
return history, ""
|
311 |
|
312 |
try:
|
|
|
|
|
|
|
313 |
response_result = chatbot.get_response(session_id, message)
|
314 |
|
315 |
if response_result['success']:
|
@@ -346,10 +362,20 @@ def create_gradio_interface():
|
|
346 |
"""Get chat statistics"""
|
347 |
return chatbot.get_session_stats(session_id)
|
348 |
|
|
|
|
|
|
|
|
|
349 |
# Wire up event handlers
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
process_btn.click(
|
351 |
fn=process_pdf_handler,
|
352 |
-
inputs=[pdf_upload, lecture_style, include_examples, learning_objectives, session_id_state],
|
353 |
outputs=[processing_status, pdf_info, session_id_state]
|
354 |
).then(
|
355 |
fn=update_lecture_display,
|
@@ -371,13 +397,13 @@ def create_gradio_interface():
|
|
371 |
|
372 |
send_btn.click(
|
373 |
fn=chat_handler,
|
374 |
-
inputs=[msg_input, chatbot_interface, session_id_state],
|
375 |
outputs=[chatbot_interface, msg_input]
|
376 |
)
|
377 |
|
378 |
msg_input.submit(
|
379 |
fn=chat_handler,
|
380 |
-
inputs=[msg_input, chatbot_interface, session_id_state],
|
381 |
outputs=[chatbot_interface, msg_input]
|
382 |
)
|
383 |
|
|
|
14 |
logger = logging.getLogger(__name__)
|
15 |
|
16 |
# Initialize components
|
17 |
+
openai_api_key = os.getenv("OPENAI_API_KEY", "")
|
18 |
pdf_processor = PDFProcessor()
|
19 |
lecture_generator = LectureGenerator()
|
20 |
+
voice_synthesizer = VoiceSynthesizer(openai_api_key=openai_api_key)
|
21 |
+
chatbot = RAGChatbot(openai_api_key=openai_api_key)
|
22 |
|
23 |
# Global state for sessions
|
24 |
current_session = None
|
|
|
61 |
|
62 |
# Session state
|
63 |
session_id_state = gr.State(value=str(uuid.uuid4()))
|
64 |
+
openai_key_state = gr.State(value="")
|
65 |
+
|
66 |
+
with gr.Tab("🔑 API Key Setup"):
|
67 |
+
openai_key_input = gr.Textbox(
|
68 |
+
label="OpenAI API Key",
|
69 |
+
placeholder="Enter your OpenAI API key here",
|
70 |
+
type="password"
|
71 |
+
)
|
72 |
+
save_key_btn = gr.Button("Save API Key")
|
73 |
|
74 |
with gr.Tab("📄 PDF Upload & Processing"):
|
75 |
with gr.Row():
|
|
|
148 |
refresh_stats_btn = gr.Button("Refresh Stats")
|
149 |
|
150 |
# Event handlers
|
151 |
+
def process_pdf_handler(pdf_file, style, examples, learning_objectives, session_id, openai_key):
|
152 |
"""Handle PDF processing or topic-based lecture generation"""
|
153 |
global session_data
|
154 |
+
|
155 |
+
# Pass the OpenAI key to the chatbot or other components
|
156 |
+
chatbot.set_api_key(openai_key)
|
157 |
+
|
158 |
try:
|
159 |
# Check if we have either PDF or learning objectives
|
160 |
if pdf_file is None and not learning_objectives.strip():
|
|
|
317 |
logger.error(f"Audio generation error: {str(e)}")
|
318 |
return None
|
319 |
|
320 |
+
def chat_handler(message, history, session_id, openai_key):
|
321 |
"""Handle chat messages"""
|
322 |
if not message.strip():
|
323 |
return history, ""
|
324 |
|
325 |
try:
|
326 |
+
# Pass the OpenAI key to the chatbot
|
327 |
+
chatbot.set_api_key(openai_key)
|
328 |
+
|
329 |
response_result = chatbot.get_response(session_id, message)
|
330 |
|
331 |
if response_result['success']:
|
|
|
362 |
"""Get chat statistics"""
|
363 |
return chatbot.get_session_stats(session_id)
|
364 |
|
365 |
+
def save_openai_key(key):
|
366 |
+
"""Save the OpenAI API key to the session state"""
|
367 |
+
return key
|
368 |
+
|
369 |
# Wire up event handlers
|
370 |
+
save_key_btn.click(
|
371 |
+
fn=save_openai_key,
|
372 |
+
inputs=[openai_key_input],
|
373 |
+
outputs=[openai_key_state]
|
374 |
+
)
|
375 |
+
|
376 |
process_btn.click(
|
377 |
fn=process_pdf_handler,
|
378 |
+
inputs=[pdf_upload, lecture_style, include_examples, learning_objectives, session_id_state, openai_key_state],
|
379 |
outputs=[processing_status, pdf_info, session_id_state]
|
380 |
).then(
|
381 |
fn=update_lecture_display,
|
|
|
397 |
|
398 |
send_btn.click(
|
399 |
fn=chat_handler,
|
400 |
+
inputs=[msg_input, chatbot_interface, session_id_state, openai_key_state],
|
401 |
outputs=[chatbot_interface, msg_input]
|
402 |
)
|
403 |
|
404 |
msg_input.submit(
|
405 |
fn=chat_handler,
|
406 |
+
inputs=[msg_input, chatbot_interface, session_id_state, openai_key_state],
|
407 |
outputs=[chatbot_interface, msg_input]
|
408 |
)
|
409 |
|
app/lecture_generator.py
CHANGED
@@ -11,15 +11,11 @@ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
|
|
11 |
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
12 |
from reportlab.lib.units import inch
|
13 |
from reportlab.lib.colors import HexColor
|
14 |
-
from dotenv import load_dotenv
|
15 |
-
|
16 |
-
# Load environment variables
|
17 |
-
load_dotenv()
|
18 |
|
19 |
logger = logging.getLogger(__name__)
|
20 |
|
21 |
# Set up OpenAI client
|
22 |
-
openai.api_key =
|
23 |
|
24 |
class LectureState(TypedDict):
|
25 |
pdf_content: str
|
|
|
11 |
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
12 |
from reportlab.lib.units import inch
|
13 |
from reportlab.lib.colors import HexColor
|
|
|
|
|
|
|
|
|
14 |
|
15 |
logger = logging.getLogger(__name__)
|
16 |
|
17 |
# Set up OpenAI client
|
18 |
+
openai.api_key = None # Placeholder, should be set externally
|
19 |
|
20 |
class LectureState(TypedDict):
|
21 |
pdf_content: str
|
app/rag_system.py
CHANGED
@@ -7,27 +7,20 @@ from typing import List, Dict, Any, Optional
|
|
7 |
import uuid
|
8 |
from datetime import datetime
|
9 |
import numpy as np
|
10 |
-
from dotenv import load_dotenv
|
11 |
-
|
12 |
-
# Load environment variables
|
13 |
-
load_dotenv()
|
14 |
|
15 |
logger = logging.getLogger(__name__)
|
16 |
|
17 |
class RAGSystem:
|
18 |
"""Retrieval-Augmented Generation system for chatbot functionality"""
|
19 |
|
20 |
-
def __init__(self, persist_directory: str = "chroma_db"):
|
21 |
-
self.client = openai.OpenAI(api_key=
|
22 |
|
23 |
# Initialize ChromaDB
|
24 |
self.chroma_client = chromadb.PersistentClient(path=persist_directory)
|
25 |
|
26 |
# Create embedding function
|
27 |
-
self.embedding_function = embedding_functions.
|
28 |
-
api_key=os.getenv("OPENAI_API_KEY", ""),
|
29 |
-
model_name="text-embedding-ada-002"
|
30 |
-
)
|
31 |
|
32 |
# Collections for different document types
|
33 |
self.pdf_collection = self._get_or_create_collection("pdf_documents")
|
|
|
7 |
import uuid
|
8 |
from datetime import datetime
|
9 |
import numpy as np
|
|
|
|
|
|
|
|
|
10 |
|
11 |
logger = logging.getLogger(__name__)
|
12 |
|
13 |
class RAGSystem:
|
14 |
"""Retrieval-Augmented Generation system for chatbot functionality"""
|
15 |
|
16 |
+
def __init__(self, openai_api_key: str, persist_directory: str = "chroma_db"):
|
17 |
+
self.client = openai.OpenAI(api_key=openai_api_key)
|
18 |
|
19 |
# Initialize ChromaDB
|
20 |
self.chroma_client = chromadb.PersistentClient(path=persist_directory)
|
21 |
|
22 |
# Create embedding function
|
23 |
+
self.embedding_function = embedding_functions.DefaultEmbeddingFunction()
|
|
|
|
|
|
|
24 |
|
25 |
# Collections for different document types
|
26 |
self.pdf_collection = self._get_or_create_collection("pdf_documents")
|
app/utils.py
CHANGED
@@ -4,7 +4,6 @@ import hashlib
|
|
4 |
from typing import Dict, Any, Optional
|
5 |
from datetime import datetime
|
6 |
import json
|
7 |
-
from dotenv import load_dotenv
|
8 |
|
9 |
def setup_logging():
|
10 |
"""Setup logging configuration"""
|
@@ -156,9 +155,6 @@ def measure_execution_time(func):
|
|
156 |
|
157 |
return wrapper
|
158 |
|
159 |
-
# Load environment variables
|
160 |
-
load_dotenv()
|
161 |
-
|
162 |
# Initialize logging when module is imported
|
163 |
setup_logging()
|
164 |
|
|
|
4 |
from typing import Dict, Any, Optional
|
5 |
from datetime import datetime
|
6 |
import json
|
|
|
7 |
|
8 |
def setup_logging():
|
9 |
"""Setup logging configuration"""
|
|
|
155 |
|
156 |
return wrapper
|
157 |
|
|
|
|
|
|
|
158 |
# Initialize logging when module is imported
|
159 |
setup_logging()
|
160 |
|
app/voice_synthesizer.py
CHANGED
@@ -5,23 +5,23 @@ from typing import Dict, Any, Optional
|
|
5 |
from pathlib import Path
|
6 |
import tempfile
|
7 |
import io
|
8 |
-
from dotenv import load_dotenv
|
9 |
-
|
10 |
-
# Load environment variables
|
11 |
-
load_dotenv()
|
12 |
|
13 |
logger = logging.getLogger(__name__)
|
14 |
|
15 |
class VoiceSynthesizer:
|
16 |
"""Handles text-to-speech conversion for lecture content"""
|
17 |
|
18 |
-
def __init__(self):
|
19 |
-
self.client = openai.OpenAI(api_key=
|
20 |
self.supported_voices = [
|
21 |
"alloy", "echo", "fable", "onyx", "nova", "shimmer"
|
22 |
]
|
23 |
self.default_voice = "nova"
|
24 |
|
|
|
|
|
|
|
|
|
25 |
def synthesize_lecture(self, lecture_content: str, voice: str = None, output_path: str = None) -> Dict[str, Any]:
|
26 |
"""
|
27 |
Convert lecture text to speech using OpenAI TTS
|
|
|
5 |
from pathlib import Path
|
6 |
import tempfile
|
7 |
import io
|
|
|
|
|
|
|
|
|
8 |
|
9 |
logger = logging.getLogger(__name__)
|
10 |
|
11 |
class VoiceSynthesizer:
|
12 |
"""Handles text-to-speech conversion for lecture content"""
|
13 |
|
14 |
+
def __init__(self, openai_api_key: str):
|
15 |
+
self.client = openai.OpenAI(api_key=openai_api_key)
|
16 |
self.supported_voices = [
|
17 |
"alloy", "echo", "fable", "onyx", "nova", "shimmer"
|
18 |
]
|
19 |
self.default_voice = "nova"
|
20 |
|
21 |
+
def set_api_key(self, api_key: str):
|
22 |
+
"""Set the OpenAI API key dynamically."""
|
23 |
+
self.client = openai.OpenAI(api_key=api_key)
|
24 |
+
|
25 |
def synthesize_lecture(self, lecture_content: str, voice: str = None, output_path: str = None) -> Dict[str, Any]:
|
26 |
"""
|
27 |
Convert lecture text to speech using OpenAI TTS
|