File size: 6,288 Bytes
936df9d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83edd7c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
936df9d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import os
import openai
import random
from flask import Flask, Blueprint, request, jsonify, current_app
from flask_cors import CORS

# --- Blueprint ---
writting_bp = Blueprint("writting", __name__)

app = Flask(__name__)
CORS(app)

# openai.api_key = "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"


# ---- API key from env/config (no hard-coded key) ----
_OPENAI_API_KEY_FALLBACK = os.getenv("OPENAI_API_KEY", "")

def _ensure_openai_key():
    """Set openai.api_key from app config or env before each API call."""
    api_key = (current_app.config.get("OPENAI_API_KEY") if current_app else None) or _OPENAI_API_KEY_FALLBACK
    if api_key:
        openai.api_key = api_key

previous_topics = set()

def is_similar(new_topic):
    """Check if the new topic is too similar to previously generated ones."""
    for topic in previous_topics:
        if new_topic.lower() in topic.lower() or topic.lower() in new_topic.lower():
            return True
    return False

# ---- Routes converted to Blueprint (paths unchanged) ----
@writting_bp.route('/generate-writing-topics', methods=['POST'])
# @app.route('/generate-writing-topics', methods=['POST'])
def generate_writing_topics():
    global previous_topics
    try:
        data = request.json
        grade_level = data.get("grade_level", "lower").lower()

        valid_levels = {"lower", "middle", "upper"}
        if grade_level not in valid_levels:
            return jsonify({"error": "Invalid grade level."}), 400


        prompt = f"""
        Generate a completely **random and unpredictable** writing topic for a {grade_level}-grade student.
        The topic should:
        - Be age-appropriate for {grade_level}-grade students.
        - Be something **new and unexpected**.
        - Avoid overused or common writing prompts.
        - Be **appropriate in complexity based on the grade level**:
          - **For younger students**, make topics more **imaginative and storytelling-driven**.
          - **For middle-level students**, introduce **more structured thinking, problem-solving, or decision-making elements**. Avoid relying only on fantasy—ensure topics also include **real-world ethical dilemmas, debates, and problem-solving challenges**.
          - **For upper-level students**, push for **analytical, ethical, or futuristic discussions requiring critical thinking**.
        - Follow no specific structure or category.
        - Be **one sentence long**.
        - **Format the output as:** "Writing topic: <your topic here>"
        """






        # Generate topic with full randomness
        max_retries = 7
        retries = 0
        while retries < max_retries:
            response = openai.chat.completions.create(
                model="gpt-4-turbo",
                messages=[{"role": "user", "content": prompt}],
                max_tokens=50,
                temperature=1.8,  # High randomness for maximum diversity
                top_p=0.95  # Allows broader AI output
            )
            new_topic = response.choices[0].message.content.strip()
            # Ensure AI follows correct format
            if "Writing topic:" in new_topic:
                new_topic = new_topic.replace("Writing topic:", "").strip()

            # Check uniqueness before returning
            if not is_similar(new_topic) and new_topic not in previous_topics:
                previous_topics.add(new_topic)
                return jsonify({"topic": new_topic}), 200

            retries += 1

        return jsonify({"error": "Failed to generate a unique topic"}), 500

    except Exception as e:
        print(f"Error: {e}")
        return jsonify({"error": "An error occurred"}), 500

@writting_bp.route('/validate-response', methods=['POST'])
# @app.route('/validate-response', methods=['POST'])
def validate_response():
    """
    Validate user response against the provided topic using GPT.
    """
    try:
        data = request.json
        topic = data.get("topic")
        response_text = data.get("response")

        if not topic or not response_text:
            return jsonify({"error": "Both 'topic' and 'response' fields are required."}), 400

        # Define the prompt for GPT to evaluate the response
        validation_prompt = (
                    f"You are a strict writing teacher. "
                    f"Score: <number>/10\n\n"
                    f"Check the student's response for grammar, spelling, punctuation, and sentence structure. "
                    f"Give feedback in simple, clear English that a 10-year-old can understand. "
                    f"Keep the feedback neat and easy to read. "
                    f"Use this exact format:\n\n"
                    f"What is good:\n"
                    f"- <two short points about strengths>\n"
                    f"Needs fixing:\n"
                    f"- <two short points about mistakes>\n"
                    f"How to improve:\n"
                    f"- <one short, clear tip or rewrite>\n"
                   
                    f"Topic: '{topic}'. Response: '{response_text}'."
         )

            

        messages = [
            {"role": "system", "content": "You are a helpful writing teacher."},
            {"role": "user", "content": validation_prompt}
        ]

        # Call GPT for validation using OpenAI's ChatCompletion API
        result = openai.chat.completions.create(
            model="gpt-4-turbo",
            messages=messages,
            max_tokens=1500,
            temperature=0.7
        )
        feedback = result.choices[0].message.content.strip()
        return jsonify({"feedback": feedback}), 200

    except Exception as e:
        print(f"Error validating response: {e}")
        return jsonify({"error": "An error occurred while validating the response."}), 500


# if __name__ == '__main__':
#     app.run(host='0.0.0.0', port=8000, debug=True)

# --- Optional: standalone run (local testing) ---
if __name__ == '__main__':
    app = Flask(__name__)
    CORS(app)
    app.config["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY", "")
    app.register_blueprint(writting_bp, url_prefix='')
    app.run(host='0.0.0.0', port=8000, debug=True)