Spaces:
Running
Running
File size: 3,244 Bytes
95d3f8e 2476d55 95d3f8e 9f88c37 95d3f8e 9f88c37 a00e395 2476d55 9f88c37 a00e395 2476d55 a00e395 2476d55 a00e395 2476d55 a00e395 2476d55 a00e395 9f88c37 a00e395 9f88c37 a00e395 2476d55 9f88c37 a00e395 2476d55 9f88c37 a00e395 9f88c37 2476d55 9f88c37 a00e395 9f88c37 a00e395 9f88c37 a00e395 9f88c37 95d3f8e |
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 |
import json
import hashlib
import re
from typing import Dict, Any, List
class ScenarioNode:
def __init__(self, question: str, options: Dict[str, Any], correct_answer: str = None, feedback: str = None):
self.question = question
self.options = options
self.correct_answer = correct_answer
self.feedback = feedback
def to_dict(self):
return {
"question": self.question,
"options": self.options,
"correct_answer": self.correct_answer,
"feedback": self.feedback
}
class ScenarioBuilder:
def __init__(self, ai_engine):
self.ai_engine = ai_engine
self.scenarios = {}
async def create_scenario_from_query(self, query: str, num_questions: int = 5) -> Dict[str, Any]:
prompt = f"""
You are a medical training assistant.
Based on the topic: "{query}", generate a {num_questions}-question interactive medical scenario. Each question must have:
- a `question` (string)
- an `options` object with keys "A"–"D"
- a `correct_answer` ("A", "B", "C", or "D")
- a `feedback` string
Respond ONLY with this exact JSON format:
[
{{
"question": "...",
"options": {{
"A": "...",
"B": "...",
"C": "...",
"D": "..."
}},
"correct_answer": "A|B|C|D",
"feedback": "..."
}},
...
]
⚠️ No markdown. No prose. No headings. Just valid JSON array. Your job is to act like a JSON API.
"""
try:
# Use Groq for accurate structure
raw_response = self.ai_engine._generate_with_groq(
query=query,
refined_prompt=prompt
)
# Clean any wrapping or garbage
start = raw_response.find("[")
end = raw_response.rfind("]") + 1
json_block = raw_response[start:end].strip()
print("🧪 Raw Groq output preview:", json_block[:200])
scenario_data = json.loads(json_block)
# Turn into ScenarioNode objects
nodes = []
for q in scenario_data:
node = ScenarioNode(
question=q["question"],
options=q["options"],
correct_answer=q["correct_answer"],
feedback=q["feedback"]
)
nodes.append(node)
scenario_id = hashlib.md5(query.encode()).hexdigest()
self.scenarios[scenario_id] = nodes
return {
"scenario_id": scenario_id,
"questions": [n.to_dict() for n in nodes]
}
except json.JSONDecodeError as e:
print("❌ JSON parse error:", e)
print("⚠️ Raw Groq output:", raw_response[:500])
return {
"error": "Failed to parse AI-generated scenario. Invalid JSON format.",
"details": str(e)
}
except Exception as e:
print("❌ Scenario generation error:", e)
return {
"error": "Failed to generate scenario.",
"details": str(e)
}
def get_scenario(self, scenario_id: str) -> List[ScenarioNode]:
return self.scenarios.get(scenario_id)
|