Writing_Tutor / app.py
NavyDevilDoc's picture
Update app.py
cae8a68 verified
raw
history blame
5.73 kB
import streamlit as st
from openai import OpenAI
import os
# 1. Configuration
st.set_page_config(page_title="High School Writing Coach", layout="wide")
# Get the API key from Environment Variables (HF Spaces) OR st.secrets (Local)
api_key = os.environ.get("OPENAI_API_KEY")
if not api_key:
try:
# Fallback for local development if using secrets.toml
api_key = st.secrets["OPENAI_API_KEY"]
except (FileNotFoundError, KeyError):
st.error("OpenAI API Key not found. Please add 'OPENAI_API_KEY' to your Hugging Face Space secrets.")
st.stop()
# Initialize client with the found key
client = OpenAI(api_key=api_key)
# 2. System Prompt
# This enforces the "No Rewrite" rule.
SYSTEM_PROMPT = """
You are an expert high school English teacher and writing coach.
Your goal is to help students improve their writing skills, NOT to do the work for them.
RULES:
1. DO NOT rewrite the student's text.
2. If you see a grammatical error, quote the sentence and explain the grammar rule they broke.
3. If you see weak argumentation, ask a Socratic question to prompt deeper thinking.
4. Structure your feedback in Markdown with clear headings: "General Feedback", "Strengths", and "Areas for Improvement".
5. Be encouraging but rigorous. Treat them like smart young adults.
"""
FEW_SHOT_EXAMPLES = """
<example_1>
USER_INPUT: "The Great Gatsby shows that money is bad. Gatsby has a lot of money but he is sad."
USER_GOAL: "Argument Analysis"
AI_RESPONSE:
**Critique:** Your point is valid, but the sentence structure
is a bit simple and relies on "telling" rather than "showing."
You are using two independent clauses joined loosely.
**Lesson - Complex Sentences:** Try using a subordinating
conjunction (like "although," "while," or "despite") to show
the relationship between wealth and happiness.
**Structural Example (Topic: Sports):** Instead of saying "The
team won the game but they played bad," a stronger writer might
say: *"Despite securing a victory on the scoreboard, the team's
defensive breakdown revealed fundamental weaknesses in their strategy."*
**Try it:** Can you rewrite your sentence about Gatsby using the word "Although" or "Despite"?
</example_1>
<example_2>
USER_INPUT: "I think that climate change is a big problem because it makes the weather hot."
USER_GOAL: "Vocabulary & Tone"
AI_RESPONSE:
**Critique:** The phrase "big problem" is vague, and "I think"
is unnecessary (the reader knows it's your essay). Academic writing requires precision.
**Lesson - Precise Vocabulary:** Replace general words with
specific terms that describe the *scale* or *nature* of the problem.
**Structural Example (Topic: Cooking):** Instead of
saying "I think the soup was bad because it was too salty,"
a critic would write: *"The broth's overwhelming salinity
completely masked the delicate flavors of the vegetables."*
**Try it:** Look at your sentence. How can you replace "big problem"
with a word that describes *how* climate change affects the planet
(e.g., catastrophic, systemic, accelerating)?
</example_2>
"""
SYSTEM_PROMPT = f"""
You are an expert Writing Coach for high school students.
Your goal is to teach writing mechanics, logic, and rhetoric without rewriting the student's essay for them.
INSTRUCTIONS:
1. Analyze the student's text based on their selected Focus Area.
2. Identify the top 1-2 weaknesses.
3. For every weakness you identify, you must provide a **"Structural Example"**.
4. CRITICAL: The "Structural Example" must be about a COMPLETELY DIFFERENT TOPIC than the student's essay. If they write about History, give an example about Cooking. If they write about Literature, give an example about Technology.
5. Never rewrite their actual sentence. Only show them the *pattern* of a better sentence.
6. Be encouraging but rigorous. Treat them like smart young adults.
Here are examples of how you should respond (Few-Shot Training):
{FEW_SHOT_EXAMPLES}
"""
# 3. The UI Layout
st.title("πŸŽ“ Digital Writing Coach")
st.markdown("Paste your draft below. I will critique it and offer advice, but I won't rewrite it for you!")
# Two columns: Input and Settings
col1, col2 = st.columns([2, 1])
with col1:
user_text = st.text_area("Your Essay/Draft", height=400, placeholder="Paste your writing here...")
with col2:
st.header("Feedback Settings")
focus_area = st.selectbox(
"What should I focus on?",
["General Critique", "Grammar & Punctuation", "Argument & Logic", "Clarity & Flow"]
)
grade_level = st.select_slider("Grade Level", options=["9th", "10th", "11th", "12th"])
analyze_btn = st.button("Analyze My Writing", type="primary", use_container_width=True)
# 4. The Logic
if analyze_btn and user_text:
with st.spinner("Analyzing your rhetorical strategies..."):
try:
# Construct the specific user prompt
user_prompt = f"Grade Level: {grade_level}\nFocus Area: {focus_area}\n\nStudent Text:\n{user_text}"
response = client.chat.completions.create(
model="gpt-4o", # High-spec model is crucial for nuance
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_prompt}
],
temperature=0.7 # Slight creativity for "teacher" persona, but grounded
)
feedback = response.choices[0].message.content
# 5. Display Feedback
st.markdown("---")
st.subheader("πŸ“ Coach's Feedback")
st.markdown(feedback)
except Exception as e:
st.error(f"An error occurred: {e}")