Geometry_Lesson / app.py
mayzinoo's picture
Update app.py
8651b5b verified
import os
import re
import gradio as gr
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from langchain_chroma import Chroma
from langchain_community.embeddings import HuggingFaceEmbeddings
# Load embedding model and vector store from persisted DB
embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
vector_store = Chroma(
embedding_function=embedding_model,
persist_directory="geometry_db", # relative folder inside your Hugging Face Space
collection_name="geometry_sol"
)
# Load OpenAI key (set this in Hugging Face Space Secrets)
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
# Load the LLM (GPT-3.5)
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0.3)
# Unified prompt to auto-detect intent
template = PromptTemplate(
input_variables=["context", "query"],
template="""
You are a Virginia high school Geometry assistant. Based on the user question below, determine the correct response type and answer accordingly:
User Question:
{query}
Based on the following SOL text:
{context}
Response Rules:
- If the question is asking for an **SOL number**, respond with:
1. The exact SOL code (e.g., G.RLT.1)
2. The exact description line from the SOL guide
⚠️ Do not summarize. Only copy directly from the context.
- If the user asks for a **lesson plan**, provide:
- Simple explanation of the concept
- Real-world example
- Engaging class activity
Format the output clearly with bullet points.
- If the user asks for a **worksheet**, include:
- Concept summary
- A worked example
- 3 practice problems
Format the output clearly with bullet points.
- If the user asks for **proofs**, include:
- Student-friendly explanation
- Real-world connection
- One short class activity
Format the output clearly with bullet points.
- If the user asks for **flashcards**, generate 5 cards, each with:
- A clear question
- A short answer
Format the output clearly with bullet points.
Only answer one way depending on the intent of the question.
"""
)
# Optional: shortcut to solve simple math problems (like area of rectangle)
def try_math_solver(query):
match = re.search(r"rectangle.*l\s*=\s*(\d+).+w\s*=\s*(\d+)", query.lower())
if match:
l, w = int(match.group(1)), int(match.group(2))
return f"The area of the rectangle is {l} × {w} = {l * w} square units."
return None
# RAG function using unified intent-aware prompt
def rag_query(query):
docs = vector_store.similarity_search(query, k=2)
context = "\n\n".join([doc.page_content for doc in docs])
prompt = template.format_prompt(context=context, query=query).to_string()
return llm.invoke(prompt).content
# Gradio app function
def ask_geometry_sol(query):
math_result = try_math_solver(query)
if math_result:
return math_result
try:
return rag_query(query)
except Exception as e:
return f"⚠️ Error: {type(e).__name__} - {str(e)}"
# Gradio UI (no need for manual response type selection anymore!)
iface = gr.Interface(
fn=ask_geometry_sol,
inputs=gr.Textbox(label="Enter your Geometry SOL question or topic"),
outputs="text",
title="📘 Virginia Geometry SOL Assistant",
description="Ask about any 2023 Geometry SOL (Standards of Learning). The assistant will auto-detect if you want a lesson plan, worksheet, proof, flashcards, or SOL reference."
)
if __name__ == "__main__":
iface.launch()