hassanienabbasitse24 commited on
Commit
e72b508
·
1 Parent(s): b98f6f7
Files changed (2) hide show
  1. app/api/auth.py +17 -0
  2. app/services/evaluator.py +46 -30
app/api/auth.py CHANGED
@@ -81,6 +81,23 @@ async def handle_auth(request: Request, req: AuthRequest):
81
  if "token" in data:
82
  log.info("[auth] token present (len=%d)", len(str(data["token"])))
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  return data
85
 
86
 
 
81
  if "token" in data:
82
  log.info("[auth] token present (len=%d)", len(str(data["token"])))
83
 
84
+ # Normalize response: promote access_token / session to top level
85
+ # if the edge function wrapped them inside a "data" key
86
+ if "access_token" not in data and "session" not in data:
87
+ nested = data.get("data")
88
+ if isinstance(nested, dict):
89
+ if "access_token" in nested:
90
+ data["access_token"] = nested["access_token"]
91
+ log.info("[auth] Promoted access_token from data.%s", "access_token")
92
+ if "session" in nested and isinstance(nested["session"], dict):
93
+ data["session"] = nested["session"]
94
+ log.info("[auth] Promoted session from data.session")
95
+ if "user" in nested and isinstance(nested["user"], dict) and "user_id" not in data:
96
+ uid = nested["user"].get("id") or nested["user"].get("user_id") or nested["user"].get("sub")
97
+ if uid:
98
+ data["user_id"] = uid
99
+ log.info("[auth] Promoted user_id from data.user")
100
+
101
  return data
102
 
103
 
app/services/evaluator.py CHANGED
@@ -168,39 +168,55 @@ async def ai_evaluate_code_fix(challenge_id: str, fixed_code: str, team_role: st
168
 
169
  print(f"[ai-evaluate-code-fix] challenge={challenge_id} lang={language}")
170
 
171
- try:
172
- async with httpx.AsyncClient(timeout=60) as client:
173
- resp = await client.post(
174
- GROQ_API_URL,
175
- json={
176
- "model": "llama-3.3-70b-versatile",
177
- "messages": [
178
- {"role": "system", "content": "أنت مقيّم أكواد أمني. أعد JSON فقط."},
179
- {"role": "user", "content": eval_prompt},
180
- ],
181
- "temperature": 0.2,
182
- "max_tokens": 1024,
183
- },
184
- headers={
185
- "Content-Type": "application/json",
186
- "Authorization": f"Bearer {GROQ_API_KEY}",
187
- },
188
- )
189
- except Exception as e:
190
- return {"secured": False, "feedback": f"AI request failed: {e}"}
 
 
191
 
192
- if resp.status_code != 200:
193
- return {"secured": False, "feedback": f"AI evaluation error: {resp.status_code}"}
 
194
 
195
- try:
196
- content = resp.json()["choices"][0]["message"]["content"]
197
- evaluation = parse_json_safe(content)
198
- except Exception as e:
199
- return {"secured": False, "feedback": f"AI response parse failed: {e}"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
 
201
- if not isinstance(evaluation, dict):
202
- return {"secured": False, "feedback": "AI response was not a JSON object"}
203
- return evaluation
204
 
205
 
206
  async def evaluate_code_fix(req, background_tasks: BackgroundTasks) -> dict:
 
168
 
169
  print(f"[ai-evaluate-code-fix] challenge={challenge_id} lang={language}")
170
 
171
+ async def _call_ai(api_url: str, api_key: str, model: str) -> Optional[dict]:
172
+ """Call an AI provider and return parsed evaluation dict, or None on failure."""
173
+ try:
174
+ async with httpx.AsyncClient(timeout=60) as client:
175
+ resp = await client.post(
176
+ api_url,
177
+ json={
178
+ "model": model,
179
+ "messages": [
180
+ {"role": "system", "content": "أنت مقيّم أكواد أمني. أعد JSON فقط."},
181
+ {"role": "user", "content": eval_prompt},
182
+ ],
183
+ "temperature": 0.2,
184
+ "max_tokens": 1024,
185
+ },
186
+ headers={
187
+ "Content-Type": "application/json",
188
+ "Authorization": f"Bearer {api_key}",
189
+ },
190
+ )
191
+ except Exception:
192
+ return None
193
 
194
+ if resp.status_code != 200:
195
+ print(f"[ai-evaluate-code-fix] {api_url} returned {resp.status_code}")
196
+ return None
197
 
198
+ try:
199
+ content = resp.json()["choices"][0]["message"]["content"]
200
+ evaluation = parse_json_safe(content)
201
+ except Exception:
202
+ return None
203
+
204
+ if not isinstance(evaluation, dict):
205
+ return None
206
+ return evaluation
207
+
208
+ # Tier 1: Groq
209
+ evaluation = await _call_ai(GROQ_API_URL, GROQ_API_KEY, "llama-3.3-70b-versatile")
210
+ if evaluation is not None:
211
+ return evaluation
212
+
213
+ # Tier 2: Mistral (fallback)
214
+ print("[ai-evaluate-code-fix] Groq failed, trying Mistral...")
215
+ evaluation = await _call_ai(MISTRAL_API_URL, MISTRAL_API_KEY, MISTRAL_MODEL)
216
+ if evaluation is not None:
217
+ return evaluation
218
 
219
+ return {"secured": False, "feedback": "AI evaluation error: 401"}
 
 
220
 
221
 
222
  async def evaluate_code_fix(req, background_tasks: BackgroundTasks) -> dict: