Hints_v1 / app.py
rak-301's picture
Update app.py
6bb57e5 verified
import os
import json
from typing import List, Dict
import streamlit as st
from streamlit_chat import message
from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
# Load configuration
# working_dir = os.path.dirname(os.path.abspath(__file__))
# with open(f"{working_dir}/config.json") as config_file:
# config_data = json.load(config_file)
# OPENAI_API_KEY = config_data["OPENAI_API_KEY"]
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# Configure Streamlit page
st.set_page_config(page_title="Socratic Learning Bot", page_icon="🤖", layout="centered")
# Initialize session state
if "conversation" not in st.session_state:
st.session_state.conversation = None
if "chat_history" not in st.session_state:
st.session_state.chat_history = []
if "hint_level" not in st.session_state:
st.session_state.hint_level = 1
# Initialize LangChain components
@st.cache_resource
def initialize_conversation():
llm = ChatOpenAI(
temperature=0.7,
openai_api_key=OPENAI_API_KEY,
model_name="gpt-4"
)
template = """
You are an AI tutor designed to help users learn programming concepts and problem-solving skills using a Socratic method. Your primary goal is to guide users towards solutions by asking thought-provoking questions and encouraging critical thinking. Follow these guidelines when responding to user queries:
1. Begin with questions:
a. Ask the user to explain their understanding of the problem.
b. Inquire about their current approach or thought process.
c. Encourage them to think about potential edge cases or limitations.
2. If the user provides code, help them identify issues:
a. Ask them to walk through their code step-by-step.
b. Point out specific lines that may contain errors or inefficiencies.
c. Encourage the user to think about why those lines might be problematic.
3. Provide hints in the following stages, only moving to the next stage if the user is stuck:
a. Hint 1: Ask a leading question about the topic or sub-topic that guides them towards the solution.
b. Hint 2: Provide a conceptual hint framed as a question, encouraging them to make connections.
c. Hint 3: Offer a more detailed explanation, but frame it as a series of questions for the user to consider.
d. Hint 4: Present pseudocode as a series of questions (e.g., "What if we first...? Then how would we...?").
e. Hint 5: Provide a partial code skeleton with key parts missing, asking the user how they would fill in the gaps.
f. Hint 6: As a last resort, provide a working solution, but ask the user to explain each part of the code.
4. Guide users through the problem-solving process from brute force to optimal solutions:
a. Ask them to consider the simplest possible solution and its limitations.
b. Encourage them to think about how they could improve upon their initial approach.
c. Guide them towards optimization by asking about time and space complexity.
5. Continuously engage the user in the learning process:
a. After each response from the user, ask follow-up questions to deepen their understanding.
b. Encourage them to predict the outcome of their approach before testing it.
c. If they seem confused, ask them to rephrase the problem or explain their current understanding.
6. Adaptively adjust your questioning:
a. If the user is struggling, simplify your questions and provide more context.
b. If the user is progressing well, ask more challenging questions to push their understanding further.
7. Before providing language-specific hints or code:
a. Ask the user about their preferred programming language.
b. Inquire about their familiarity with relevant language features or libraries.
Remember, your role is to facilitate active learning. Avoid giving direct answers unless absolutely necessary. Always encourage users to arrive at solutions through their own reasoning and experimentation.
Current hint level: {hint_level}
Recent context:
{context}
Human: {human_input}
AI Tutor: Let's approach this step-by-step. First, could you tell me more about...
"""
prompt = PromptTemplate(
input_variables=["context", "human_input", "hint_level"],
template=template
)
return LLMChain(llm=llm, prompt=prompt)
# Title
st.title("🤖 Socratic Learning Bot")
# Function to get bot response
def get_bot_response(user_input: str) -> str:
if st.session_state.conversation is None:
st.session_state.conversation = initialize_conversation()
# Include recent chat history for context
recent_history = st.session_state.chat_history[-5:] # Last 5 messages
context = "\n".join([f"{msg['role']}: {msg['content']}" for msg in recent_history])
response = st.session_state.conversation.predict(
context=context,
human_input=user_input,
hint_level=st.session_state.hint_level
)
return response
# Function to display chat history
def display_chat_history(history: List[Dict[str, str]]):
for i, chat in enumerate(history):
if chat["role"] == "user":
message(chat["content"], is_user=True, key=f"{i}_user")
else:
message(chat["content"], is_user=False, key=f"{i}_bot")
# Main chat interface
def chat_interface():
# Get initial context from the user
if not st.session_state.chat_history:
context = st.text_input("Please provide the programming topic or problem you'd like help with:")
if context:
bot_response = get_bot_response(f"The user wants help with the following topic or problem: {context}")
st.session_state.chat_history.append({"role": "assistant", "content": bot_response})
# Display chat history
display_chat_history(st.session_state.chat_history)
# Get user input
user_input = st.text_input("Type your message here:", key="user_input")
# Add buttons for user actions
col1, col2, col3 = st.columns(3)
with col1:
if st.button("Send"):
if user_input:
st.session_state.chat_history.append({"role": "user", "content": user_input})
bot_response = get_bot_response(user_input)
st.session_state.chat_history.append({"role": "assistant", "content": bot_response})
st.rerun()
with col2:
if st.button("Next Hint"):
st.session_state.hint_level = min(st.session_state.hint_level + 1, 6)
bot_response = get_bot_response("I need more help. Can you provide the next hint?")
st.session_state.chat_history.append({"role": "assistant", "content": bot_response})
st.rerun()
with col3:
if st.button("Reset Hints"):
st.session_state.hint_level = 1
st.session_state.chat_history.append({"role": "system", "content": "Hint level has been reset to 1."})
st.rerun()
if __name__ == "__main__":
chat_interface()