Spaces:
Sleeping
Sleeping
| 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}") |