Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -76,7 +76,7 @@ You are an expert Writing Coach for high school students.
|
|
| 76 |
Your goal is to teach writing mechanics, logic, and rhetoric without rewriting the student's essay for them.
|
| 77 |
|
| 78 |
CORE RULES:
|
| 79 |
-
1. DO NOT rewrite the student's text.
|
| 80 |
2. If you see a grammatical error, quote the sentence and explain the grammar rule they broke.
|
| 81 |
3. Structure your feedback in Markdown with clear headings: "General Feedback", "Strengths", and "Areas for Improvement".
|
| 82 |
4. Be encouraging but rigorous. Treat them like smart young adults.
|
|
@@ -98,69 +98,77 @@ Here are examples of how you should respond (Few-Shot Training):
|
|
| 98 |
{FEW_SHOT_EXAMPLES}
|
| 99 |
"""
|
| 100 |
|
| 101 |
-
# 3.
|
| 102 |
-
st.
|
| 103 |
-
st.
|
| 104 |
-
|
| 105 |
-
# Two columns: Input and Settings
|
| 106 |
-
col1, col2 = st.columns([2, 1])
|
| 107 |
-
|
| 108 |
-
with col1:
|
| 109 |
-
user_text = st.text_area("Your Essay/Draft", height=400, placeholder="Paste your writing here...")
|
| 110 |
-
|
| 111 |
-
with col2:
|
| 112 |
-
st.header("Feedback Settings")
|
| 113 |
focus_area = st.selectbox(
|
| 114 |
-
"
|
| 115 |
-
["General Critique", "Grammar &
|
| 116 |
)
|
| 117 |
-
grade_level = st.select_slider("Grade Level", options=["9th", "10th", "11th", "12th"])
|
| 118 |
|
| 119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
|
| 121 |
-
#
|
| 122 |
-
|
| 123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
try:
|
| 125 |
-
# Construct the
|
| 126 |
-
|
|
|
|
| 127 |
|
| 128 |
response = client.chat.completions.create(
|
| 129 |
-
model="gpt-4o",
|
| 130 |
-
messages=
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
],
|
| 134 |
-
temperature=0.7 # Slight creativity for "teacher" persona, but grounded
|
| 135 |
)
|
| 136 |
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
input_tokens = usage.prompt_tokens
|
| 143 |
-
output_tokens = usage.completion_tokens
|
| 144 |
-
total_tokens = usage.total_tokens
|
| 145 |
|
| 146 |
-
|
| 147 |
-
# Input: $2.50 / 1M tokens
|
| 148 |
-
# Output: $10.00 / 1M tokens
|
| 149 |
-
input_cost = (input_tokens / 1_000_000) * 2.50
|
| 150 |
-
output_cost = (output_tokens / 1_000_000) * 10.00
|
| 151 |
-
total_cost = input_cost + output_cost
|
| 152 |
-
|
| 153 |
-
# 5. Display Feedback
|
| 154 |
-
st.markdown("---")
|
| 155 |
-
st.subheader("π Coach's Feedback")
|
| 156 |
-
st.markdown(feedback)
|
| 157 |
-
|
| 158 |
-
# --- DISPLAY METRICS (In a sidebar or expandable box) ---
|
| 159 |
-
with st.expander("π Session Metrics & Cost"):
|
| 160 |
-
col_a, col_b, col_c = st.columns(3)
|
| 161 |
-
col_a.metric("Input Tokens", input_tokens)
|
| 162 |
-
col_b.metric("Output Tokens", output_tokens)
|
| 163 |
-
col_c.metric("Est. Cost", f"${total_cost:.5f}") # 5 decimal places for micro-costs
|
| 164 |
|
|
|
|
|
|
|
|
|
|
| 165 |
except Exception as e:
|
| 166 |
-
st.error(f"
|
|
|
|
| 76 |
Your goal is to teach writing mechanics, logic, and rhetoric without rewriting the student's essay for them.
|
| 77 |
|
| 78 |
CORE RULES:
|
| 79 |
+
1. **ABSOLUTE PROHIBITION:** DO NOT rewrite the student's text. If they ask "Can you fix this?" or "Rewrite it for me", you must REFUSE and ask them to try applying the lesson themselves.
|
| 80 |
2. If you see a grammatical error, quote the sentence and explain the grammar rule they broke.
|
| 81 |
3. Structure your feedback in Markdown with clear headings: "General Feedback", "Strengths", and "Areas for Improvement".
|
| 82 |
4. Be encouraging but rigorous. Treat them like smart young adults.
|
|
|
|
| 98 |
{FEW_SHOT_EXAMPLES}
|
| 99 |
"""
|
| 100 |
|
| 101 |
+
# 3. Sidebar: Settings & Reset
|
| 102 |
+
with st.sidebar:
|
| 103 |
+
st.header("βοΈ Coach Settings")
|
| 104 |
+
grade_level = st.select_slider("Grade Level", options=["9th", "10th", "11th", "12th"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
focus_area = st.selectbox(
|
| 106 |
+
"Current Focus",
|
| 107 |
+
["General Critique", "Grammar & Syntax", "Argument & Logic", "Tone & Voice"]
|
| 108 |
)
|
|
|
|
| 109 |
|
| 110 |
+
st.divider()
|
| 111 |
+
|
| 112 |
+
# --- RESET BUTTON LOGIC ---
|
| 113 |
+
# If clicked, we clear the session state list
|
| 114 |
+
if st.button("π Reset Conversation", type="primary"):
|
| 115 |
+
st.session_state.messages = []
|
| 116 |
+
st.rerun()
|
| 117 |
+
|
| 118 |
+
# 4. Initialize Session State (Memory)
|
| 119 |
+
if "messages" not in st.session_state:
|
| 120 |
+
st.session_state.messages = []
|
| 121 |
|
| 122 |
+
# 5. Display Chat History
|
| 123 |
+
st.title("π Digital Writing Coach")
|
| 124 |
+
if len(st.session_state.messages) == 0:
|
| 125 |
+
st.markdown("π **Hello!** Paste your draft below to get started. I'm here to coach, not to copy-edit!")
|
| 126 |
+
|
| 127 |
+
for message in st.session_state.messages:
|
| 128 |
+
with st.chat_message(message["role"]):
|
| 129 |
+
st.markdown(message["content"])
|
| 130 |
+
|
| 131 |
+
# 6. Chat Input & Processing
|
| 132 |
+
if prompt := st.chat_input("Paste your text or ask a question..."):
|
| 133 |
+
|
| 134 |
+
# A. Display User Message
|
| 135 |
+
with st.chat_message("user"):
|
| 136 |
+
st.markdown(prompt)
|
| 137 |
+
|
| 138 |
+
# Add user message to history
|
| 139 |
+
st.session_state.messages.append({"role": "user", "content": prompt})
|
| 140 |
+
|
| 141 |
+
# B. Generate Response
|
| 142 |
+
with st.chat_message("assistant"):
|
| 143 |
+
message_placeholder = st.empty()
|
| 144 |
+
full_response = ""
|
| 145 |
+
|
| 146 |
+
# We inject the "Current Settings" into the System Prompt dynamically
|
| 147 |
+
# This ensures if the user changes the "Focus Area" mid-chat, the AI knows.
|
| 148 |
+
dynamic_system_prompt = SYSTEM_PROMPT + f"\n\nCURRENT CONTEXT: Student is in {grade_level} Grade. Focus on: {focus_area}."
|
| 149 |
+
|
| 150 |
try:
|
| 151 |
+
# Construct the full message history for the API
|
| 152 |
+
# System prompt first, then the conversation history
|
| 153 |
+
messages_payload = [{"role": "system", "content": dynamic_system_prompt}] + st.session_state.messages
|
| 154 |
|
| 155 |
response = client.chat.completions.create(
|
| 156 |
+
model="gpt-4o",
|
| 157 |
+
messages=messages_payload,
|
| 158 |
+
temperature=0.7,
|
| 159 |
+
stream=True # Streaming makes it feel faster
|
|
|
|
|
|
|
| 160 |
)
|
| 161 |
|
| 162 |
+
# Stream the response chunk by chunk
|
| 163 |
+
for chunk in response:
|
| 164 |
+
if chunk.choices[0].delta.content is not None:
|
| 165 |
+
full_response += chunk.choices[0].delta.content
|
| 166 |
+
message_placeholder.markdown(full_response + "β")
|
|
|
|
|
|
|
|
|
|
| 167 |
|
| 168 |
+
message_placeholder.markdown(full_response)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
|
| 170 |
+
# Add AI response to history
|
| 171 |
+
st.session_state.messages.append({"role": "assistant", "content": full_response})
|
| 172 |
+
|
| 173 |
except Exception as e:
|
| 174 |
+
st.error(f"Error: {e}")
|