File size: 4,103 Bytes
573a91c
b1d7b45
573a91c
 
5e7d66d
573a91c
2e7fddb
1cbaef1
573a91c
 
 
 
 
 
 
 
 
 
 
 
 
2e7fddb
573a91c
7b40abc
573a91c
f73409e
573a91c
 
 
 
 
 
f73409e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
573a91c
363044b
2644316
 
 
 
d799db8
2644316
877e6c6
 
2644316
877e6c6
6f004d2
2644316
 
6f004d2
2644316
877e6c6
2644316
 
877e6c6
fa9d910
6f004d2
573a91c
 
64ac0ad
 
 
 
 
6210ec7
64ac0ad
 
 
 
 
 
f017e89
64ac0ad
 
 
 
 
 
 
 
 
 
6210ec7
 
6f004d2
573a91c
f7e42e2
573a91c
f7e42e2
573a91c
f7e42e2
 
 
fdbee17
6210ec7
f7e42e2
 
573a91c
f7e42e2
573a91c
f7e42e2
64ac0ad
573a91c
 
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import os
import re
import zipfile
import gradio as gr
from langchain_openai import ChatOpenAI
from langchain.embeddings import HuggingFaceEmbeddings
from langchain_chroma import Chroma
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
from langchain.chains import LLMChain

# Unzip vector DB if not already extracted
if not os.path.exists("geometry_chroma"):
    with zipfile.ZipFile("geometry_chroma.zip", 'r') as zip_ref:
        zip_ref.extractall(".")

# Load vector DB
embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
vectordb = Chroma(persist_directory="geometry_chroma", embedding_function=embedding_model)
retriever = vectordb.as_retriever()

# Set OpenAI key (use Secrets or .env later)
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")

llm = ChatOpenAI(model_name="gpt-4.1", temperature=0.2)

# ✅ Prompt templates
templates = {
    "flashcard": PromptTemplate(
        input_variables=["context", "query"],
        template="""
{context}

Create 5 flashcards based on the topic: "{query}"
Each flashcard should include:
- A clear question
- A short answer
Focus on high school geometry understanding.
"""
    ),
    "lesson plan": PromptTemplate(
        input_variables=["context", "query"],
        template="""
Given the following retrieved SOL text:
{context}

Generate a Geometry lesson plan based on: "{query}"
Include:
1. Simple explanation of the concept.
2. Real-world example.
3. Engaging class activity.
Be concise and curriculum-aligned for high school.
"""
    ),
    "worksheet": PromptTemplate(
        input_variables=["context", "query"],
        template="""
{context}

Create a student worksheet for: "{query}"
Include:
- Concept summary
- A worked example
- 3 practice problems
"""
    ),
    "proofs": PromptTemplate(
        input_variables=["context", "query"],
        template="""
{context}

Generate a proof-focused geometry lesson plan for: "{query}"
Include:
- Student-friendly explanation
- Real-world connection
- One short class activity
"""
    ),
   "general question": ChatPromptTemplate.from_messages([
        HumanMessagePromptTemplate.from_template(
            """
You are a Virginia Geometry SOL assistant.

From the following SOL context:
{context}

Identify the SOL standard (e.g., G.RLT.1) that best matches this query: "{query}"

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 from the context.
"""
        )
    ])



}

def generate_prompt_output(prompt_type, query, retriever, llm):
    try:
        import re
        sol_match = re.search(r"\bG\.[A-Z]+\.\d+\b", query)
        matched_code = sol_match.group(0) if sol_match else None

        if matched_code:
            all_docs = retriever.vectorstore._collection.get(include=['documents', 'metadatas'])
            filtered = []
            for doc_text, metadata in zip(all_docs['documents'], all_docs['metadatas']):
                if metadata.get('standard') == matched_code:
                    filtered.append(doc_text)

            context = "\n\n".join(filtered)
        else:
            docs = retriever.get_relevant_documents(query)
            context = "\n\n".join([doc.page_content for doc in docs])

        chain = LLMChain(llm=llm, prompt=templates[prompt_type])
        return chain.run({"context": context, "query": query}).strip()

    except Exception as e:
        return f"❌ Error: {str(e)}"




# ✅ Gradio UI
with gr.Blocks() as demo:
    gr.Markdown("# 📐 Geometry Teaching Assistant")

    with gr.Row():
        query = gr.Textbox(label="Enter a geometry topic")
        prompt_type = gr.Dropdown(
            ["general question", "lesson plan", "worksheet", "proofs", "flashcard"],
            value="general question",
            label="Prompt Type"
        )

    output = gr.Textbox(label="Generated Output", lines=12, interactive=True)
    btn = gr.Button("Generate")

    btn.click(fn=generate_prompt_output, inputs=[prompt_type, query], outputs=output)

demo.launch()