Spaces:
Running
Running
Update backend/main.py
Browse files- backend/main.py +23 -69
backend/main.py
CHANGED
|
@@ -39,77 +39,23 @@ def health_check():
|
|
| 39 |
def generate_level():
|
| 40 |
"""
|
| 41 |
Generates a new level (Maze, Blockly, or Time Challenge).
|
| 42 |
-
|
| 43 |
-
Expected JSON:
|
| 44 |
-
{
|
| 45 |
-
"mode": "maze",
|
| 46 |
-
"difficulty": "Easy", # optional manual fallback
|
| 47 |
-
"history": [ ... ] # optional; when present, adaptive difficulty is used
|
| 48 |
-
}
|
| 49 |
"""
|
| 50 |
-
data = request.json
|
| 51 |
mode = data.get('mode', 'maze')
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
requested_count = data.get('count', 5)
|
| 55 |
|
| 56 |
try:
|
| 57 |
-
|
| 58 |
-
if
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
adaptive_reason = evaluation.get("reason", "Adaptive evaluation applied.")
|
| 62 |
-
else:
|
| 63 |
-
chosen_difficulty = requested_difficulty
|
| 64 |
-
adaptive_reason = "No history provided; using requested/default difficulty."
|
| 65 |
-
|
| 66 |
-
try:
|
| 67 |
-
count = int(requested_count)
|
| 68 |
-
except Exception:
|
| 69 |
-
count = 5
|
| 70 |
-
count = max(1, min(count, 10))
|
| 71 |
-
|
| 72 |
-
levels = []
|
| 73 |
-
for _ in range(count):
|
| 74 |
-
level_data = scenario_agent.generate_level(mode, chosen_difficulty)
|
| 75 |
-
if not level_data:
|
| 76 |
-
raise Exception("Empty level data returned")
|
| 77 |
-
|
| 78 |
-
# FOOLPROOF: If the AI generated a full arc (wrong scenario_agent version), extract its levels instead of nesting!
|
| 79 |
-
if "levels" in level_data and isinstance(level_data["levels"], list):
|
| 80 |
-
levels.extend(level_data["levels"])
|
| 81 |
-
break # We got all 5 levels at once, no need to loop further
|
| 82 |
-
else:
|
| 83 |
-
level_data.setdefault("_adaptive", {
|
| 84 |
-
"enabled": True,
|
| 85 |
-
"chosen_difficulty": chosen_difficulty,
|
| 86 |
-
"reason": adaptive_reason
|
| 87 |
-
})
|
| 88 |
-
levels.append(level_data)
|
| 89 |
-
|
| 90 |
-
arc_title_map = {
|
| 91 |
-
"adventure": "Adventure Mission Arc",
|
| 92 |
-
"blockly": "Adventure Mission Arc",
|
| 93 |
-
"puzzle": "Puzzle Mission Arc",
|
| 94 |
-
"puzzles": "Puzzle Mission Arc",
|
| 95 |
-
"maze": "Puzzle Mission Arc",
|
| 96 |
-
"time_challenge": "Time Challenge Arc",
|
| 97 |
-
}
|
| 98 |
-
story_arc_title = arc_title_map.get(str(mode).strip().lower(), "AI Mission Arc")
|
| 99 |
-
|
| 100 |
-
return jsonify({
|
| 101 |
-
"story_arc_title": story_arc_title,
|
| 102 |
-
"levels": levels,
|
| 103 |
-
"_adaptive": {
|
| 104 |
-
"enabled": True,
|
| 105 |
-
"chosen_difficulty": chosen_difficulty,
|
| 106 |
-
"reason": adaptive_reason
|
| 107 |
-
}
|
| 108 |
-
})
|
| 109 |
except Exception as e:
|
| 110 |
print(f"CRITICAL ERROR /api/level/generate: {e}")
|
| 111 |
-
# Final Safety Net: Return a basic
|
| 112 |
-
|
|
|
|
| 113 |
"type": "maze",
|
| 114 |
"level_id": "emergency_fallback",
|
| 115 |
"title": "System Practice",
|
|
@@ -118,7 +64,17 @@ def generate_level():
|
|
| 118 |
"allowed_blocks": ["move_forward"],
|
| 119 |
"tutorial_text": "Move to the goal."
|
| 120 |
}
|
| 121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 122 |
|
| 123 |
@app.route('/api/level/feedback', methods=['POST'])
|
| 124 |
def level_feedback():
|
|
@@ -129,14 +85,13 @@ def level_feedback():
|
|
| 129 |
data = request.json or {}
|
| 130 |
level_data = data.get('level_data')
|
| 131 |
rating = data.get('rating')
|
| 132 |
-
developer_feedback = data.get('developer_feedback')
|
| 133 |
|
| 134 |
if not level_data or not rating:
|
| 135 |
return jsonify({"message": "Invalid data ignored"}), 400
|
| 136 |
|
| 137 |
try:
|
| 138 |
# Teach the agent!
|
| 139 |
-
scenario_agent.
|
| 140 |
return jsonify({"status": "learned", "message": "Thanks for the feedback!"})
|
| 141 |
except Exception as e:
|
| 142 |
print(f"Feedback Error: {e}")
|
|
@@ -183,4 +138,3 @@ def generate_hint():
|
|
| 183 |
if __name__ == '__main__':
|
| 184 |
port = int(os.environ.get('PORT', 5000))
|
| 185 |
app.run(host='0.0.0.0', port=port, debug=True)
|
| 186 |
-
|
|
|
|
| 39 |
def generate_level():
|
| 40 |
"""
|
| 41 |
Generates a new level (Maze, Blockly, or Time Challenge).
|
| 42 |
+
Expected JSON: { "mode": "maze", "difficulty": "Easy", "topic": "Space" (optional) }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
"""
|
| 44 |
+
data = request.json
|
| 45 |
mode = data.get('mode', 'maze')
|
| 46 |
+
difficulty = data.get('difficulty', 'Easy')
|
| 47 |
+
topic = data.get('topic')
|
|
|
|
| 48 |
|
| 49 |
try:
|
| 50 |
+
level_data = scenario_agent.generate_level(mode, difficulty, topic)
|
| 51 |
+
if not level_data:
|
| 52 |
+
raise Exception("Empty level data returned")
|
| 53 |
+
return jsonify(level_data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
except Exception as e:
|
| 55 |
print(f"CRITICAL ERROR /api/level/generate: {e}")
|
| 56 |
+
# Final Safety Net: Return a basic fallback if everything else explodes
|
| 57 |
+
import copy
|
| 58 |
+
fallback_base = {
|
| 59 |
"type": "maze",
|
| 60 |
"level_id": "emergency_fallback",
|
| 61 |
"title": "System Practice",
|
|
|
|
| 64 |
"allowed_blocks": ["move_forward"],
|
| 65 |
"tutorial_text": "Move to the goal."
|
| 66 |
}
|
| 67 |
+
levels = []
|
| 68 |
+
for i in range(5):
|
| 69 |
+
lvl = copy.deepcopy(fallback_base)
|
| 70 |
+
lvl["level_id"] = f"{lvl['level_id']}_{i+1}"
|
| 71 |
+
lvl["title"] = f"{lvl['title']} - Phase {i+1}"
|
| 72 |
+
levels.append(lvl)
|
| 73 |
+
|
| 74 |
+
return jsonify({
|
| 75 |
+
"story_arc_title": "Emergency System Arc",
|
| 76 |
+
"levels": levels
|
| 77 |
+
})
|
| 78 |
|
| 79 |
@app.route('/api/level/feedback', methods=['POST'])
|
| 80 |
def level_feedback():
|
|
|
|
| 85 |
data = request.json or {}
|
| 86 |
level_data = data.get('level_data')
|
| 87 |
rating = data.get('rating')
|
|
|
|
| 88 |
|
| 89 |
if not level_data or not rating:
|
| 90 |
return jsonify({"message": "Invalid data ignored"}), 400
|
| 91 |
|
| 92 |
try:
|
| 93 |
# Teach the agent!
|
| 94 |
+
scenario_agent.learn_from_feedback(level_data, int(rating))
|
| 95 |
return jsonify({"status": "learned", "message": "Thanks for the feedback!"})
|
| 96 |
except Exception as e:
|
| 97 |
print(f"Feedback Error: {e}")
|
|
|
|
| 138 |
if __name__ == '__main__':
|
| 139 |
port = int(os.environ.get('PORT', 5000))
|
| 140 |
app.run(host='0.0.0.0', port=port, debug=True)
|
|
|