File size: 4,470 Bytes
ce2143e
50e8ea8
 
ee76500
9da4039
ee76500
9da4039
50e8ea8
ce2143e
9da4039
b5ed3e9
9da4039
ce2143e
28988d3
9da4039
 
512f375
 
 
 
 
 
50e8ea8
dc67156
 
 
 
 
 
 
 
 
 
 
 
 
b5ed3e9
 
 
9da4039
 
 
 
 
 
 
 
 
 
 
 
 
 
512f375
50e8ea8
 
 
 
9da4039
 
512f375
b5ed3e9
01d3269
9da4039
f11ae7d
50e8ea8
 
 
9da4039
50e8ea8
9da4039
 
515005b
50e8ea8
 
9da4039
 
ce2143e
01d3269
50e8ea8
 
 
 
 
 
 
28988d3
01d3269
50e8ea8
 
9da4039
 
512f375
dc67156
50e8ea8
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import streamlit as st
from src.services.ai_service import AITutorService
from src.utils.session import get_tutor_context

class AITutor:
    def __init__(self):
        self.service = AITutorService()
        self.last_question = None  # Store the last question asked

    def display_chat_interface(self):
        """Display the enhanced chat interface with voice output"""
        st.header("AI Tutor")

        # Voice controls
        col1, col2 = st.columns([3, 2])
        with col1:
            # Initialize voice_active in session_state if it doesn't exist
            if "voice_active" not in st.session_state:
                st.session_state.voice_active = False

            voice_active = st.checkbox("Enable Voice", key="voice_active")  # Corrected line

            if voice_active:
                st.markdown("""
                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path d="M15 8V16M11 8V16M7 12H5C3.89543 12 3 12.8954 3 14V16C3 17.1046 3.89543 18 5 18H7V12ZM19 12V16C19 17.1046 18.1046 18 17 18H15" stroke="#4A90E2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    </svg>
                    Voice On
                """, unsafe_allow_html=True)
            else:
                st.markdown("""
                    <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path d="M15 8V16M11 8V16M7 12H5C3.89543 12 3 12.8954 3 14V16C3 17.1046 3.89543 18 5 18H7V12ZM19 12V16C19 17.1046 18.1046 18 17 18H15" stroke="#B0B0B0" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                    </svg>
                    Voice Off
                """, unsafe_allow_html=True)
        with col2:
            if self.service.tts_mode:
                st.info(f"Using {self.service.tts_mode.upper()} TTS")

        # Topic selection
        topics = [None, 'Physics', 'Mathematics', 'Computer Science', 'Artificial Intelligence']
        selected_topic = st.selectbox(
            "Select Topic",
            topics,
            format_func=lambda x: 'All Topics' if x is None else x,
            key="topic_selector"
        )

        context = get_tutor_context()
        if selected_topic != context['current_topic']:
            context['current_topic'] = selected_topic

        # Display chat container using st.empty
        chat_container = st.empty()
        with chat_container.container():  # Use nested container
            # Display chat history with voice output
            for message in context['chat_history']:
                with st.chat_message(message["role"]):
                    st.write(message["content"])
                    if message["role"] == "assistant" and st.session_state.voice_active:  # Use session state
                        self.service.speak(message["content"])

        # Chat input
        prompt = st.text_input("Ask your question...", key="chat_input")
        if prompt and prompt != self.last_question:  # Check if the question is new
            self.handle_user_input(prompt, chat_container)  # Pass the container
            self.last_question = prompt  # Update the last question asked

    def handle_user_input(self, user_input: str, chat_container):  # Accept the container
        """Process user input and generate response"""
        context = get_tutor_context()

        # Add user message
        context['chat_history'].append({
            "role": "user",
            "content": user_input
        })

        # Update the chat container immediately with the user message
        with chat_container.container():  # Use nested container
            for message in context['chat_history']:
                with st.chat_message(message["role"]):
                    st.write(message["content"])

        # Generate and display AI response
        response = self.service.generate_response(user_input, context['current_topic'])

        # Add AI response
        context['chat_history'].append({
            "role": "assistant",
            "content": response,
            "speak": True
        })

        # Update the chat container again with the AI's response
        with chat_container.container():  # Use nested container
            for message in context['chat_history']:
                with st.chat_message(message["role"]):
                    st.write(message["content"])