rairo commited on
Commit
915faa8
·
verified ·
1 Parent(s): fb7ced5

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +82 -36
main.py CHANGED
@@ -188,7 +188,7 @@ def generate_narration_task(text, uid, epiphany_id, layer_name):
188
  api_key = os.environ.get("DEEPGRAM_API_KEY")
189
  if not api_key: return layer_name, None
190
 
191
- DEEPGRAM_URL = "https://api.deepgram.com/v1/speak?model=aura-luna-en"
192
  headers = {"Authorization": f"Token {api_key}", "Content-Type": "text/plain"}
193
  response = requests.post(DEEPGRAM_URL, headers=headers, data=text.encode('utf-8'))
194
  response.raise_for_status()
@@ -477,17 +477,56 @@ def validate_odysseus_v6(t: dict) -> (bool, str):
477
  # -----------------------------------------------------------------------------
478
 
479
  # -----------------------------------------------------------------------------
480
- # ODYSSEUS ENGINE V10: THE SOCRATIC INSTRUMENT (DYNAMIC CODE GEN)
481
  # -----------------------------------------------------------------------------
482
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
483
  @app.route('/api/trial/generate', methods=['POST'])
484
  def generate_trial():
485
  """
486
- Odysseus v10: The Self-Repairing Instrumentalist.
487
- Generates bespoke Vanilla React components with a 3-pass repair loop.
488
  Cost: 1 Spark.
489
  """
490
- logger.info(">>> ODYSSEUS V10: GENERATING TRIAL")
491
  uid = verify_token(request.headers.get('Authorization'))
492
  if not uid: return jsonify({"error": "Unauthorized"}), 401
493
 
@@ -507,39 +546,44 @@ def generate_trial():
507
  if lock_ref.get(): return jsonify({"status": "locked"}), 409
508
  lock_ref.set({"uid": uid, "at": datetime.utcnow().isoformat()})
509
 
510
- # 3. Context Retrieval
511
  layer_obj = db_ref.child(f"epiphanies/{ep_id}/layers/{layer_key}").get() or {}
512
  ctx_text = layer_obj.get("text", "General scientific principles.")
513
 
514
- # 4. Forge & Repair Loop
515
- attempts, forged, last_raw = 0, None, ""
516
 
517
  base_prompt = f"""
518
- You are Athena's Master Instrumentalist. Forge a tactile scientific Instrument for {subject}.
519
- Layer Context: {ctx_text}
520
 
521
  TASK: Write a React component named 'Instrument'.
522
- REQUIREMENTS:
523
- 1. Vanilla React ONLY. No external libraries (No Matter.js). Use SVG/Canvas for visuals.
524
- 2. Tactile: The system must fail/decay if user does nothing.
525
- 3. Handshake: Must accept and call `props.onAction()` (on touch) and `props.onWin()` (on success).
526
- 4. Design: Midnight Navy #0B1120, Gold #D4AF37.
527
-
528
- JSON SCHEMA:
 
 
 
 
 
 
529
  {{
530
- "engine": "odysseus_v10",
531
  "instrument_name": "Title",
532
- "mission_brief": "Goal",
533
- "instrument_manifest": {{ "engine": "odysseus_v10", "interaction": "drag|tap|hold", "win_rule": {{ "type": "zone_dwell" }} }},
534
  "component_code": "const Instrument = (props) => {{ ... }}; export default Instrument;",
535
- "feynman_truth": "The law proven."
536
  }}
537
  """
538
 
539
  try:
540
  while attempts < 3 and not forged:
541
  attempts += 1
542
- current_prompt = base_prompt if attempts == 1 else f"REPAIR THIS CODE: {last_raw}\nERRORS: {last_errs}"
543
 
544
  res = client.models.generate_content(
545
  model=ATHENA_FLASH,
@@ -550,41 +594,43 @@ def generate_trial():
550
  last_raw = _strip_json_fences(res.text)
551
  candidate = json.loads(last_raw)
552
 
553
- # Validation logic
554
- ok_m, _ = validate_manifest(candidate.get("instrument_manifest"))
555
- ok_c, last_errs = lint_component_code(candidate.get("component_code"))
556
 
557
- if ok_m and ok_c:
558
  forged = candidate
559
  break
 
 
560
 
561
  if not forged:
562
  lock_ref.delete()
563
- return jsonify({"status": "failed", "reason": "Compilation failure"}), 422
564
 
565
- # 5. Atomic Credit Deduction (1 Spark)
566
  user_ref = db_ref.child(f'users/{uid}')
567
  def credits_txn(cur):
568
- cur = cur or 0
569
- return cur - 1 if cur >= 1 else cur
570
 
571
- result = user_ref.child('credits').transaction(credits_txn)
572
- if result < 0:
573
  lock_ref.delete()
574
  return jsonify({"error": "Insufficient Sparks"}), 402
575
 
576
- # 6. Finalize
577
  forged["createdAt"] = datetime.utcnow().isoformat()
578
  db_ref.child(trial_path).set(forged)
579
  lock_ref.delete()
580
 
581
- logger.info(f"Odysseus v10 forged for {subject} in {attempts} attempts.")
582
  return jsonify(forged), 201
583
 
584
  except Exception as e:
585
  lock_ref.delete()
586
- logger.error(f"Forging Global Error: {e}")
587
- return jsonify({"error": "The laws of physics failed to compile."}), 500
588
 
589
  # -----------------------------------------------------------------------------
590
  # 5. THE CHIRON MENTOR & SYSTEM UTILS
 
188
  api_key = os.environ.get("DEEPGRAM_API_KEY")
189
  if not api_key: return layer_name, None
190
 
191
+ DEEPGRAM_URL = "https://api.deepgram.com/v1/speak?model=aura-2-theia-en"
192
  headers = {"Authorization": f"Token {api_key}", "Content-Type": "text/plain"}
193
  response = requests.post(DEEPGRAM_URL, headers=headers, data=text.encode('utf-8'))
194
  response.raise_for_status()
 
477
  # -----------------------------------------------------------------------------
478
 
479
  # -----------------------------------------------------------------------------
480
+ # ODYSSEUS ENGINE V10.1: HARDENED GAME CONSOLE (SYNTAX GUARD + VICTORY HOOKS)
481
  # -----------------------------------------------------------------------------
482
 
483
+ # Enhanced Forbidden Patterns to prevent "Unexpected Token" errors in Babel
484
+ FORBIDDEN_CODE_PATTERNS = [
485
+ r"<!--[\s\S]*?-->", # No HTML comments (Babel killer)
486
+ r"\bonclick\b", # Must be onClick
487
+ r"\bonmousedown\b", # Must be onMouseDown
488
+ r"\bclass=", # Must be className
489
+ r"\bfetch\s*\(", # Security
490
+ r"\bXMLHttpRequest\b",
491
+ r"\bWebSocket\b",
492
+ r"\beval\s*\(",
493
+ r"\bnew\s+Function\s*\(",
494
+ ]
495
+
496
+ REQUIRED_CODE_PATTERNS = [
497
+ r"\bexport\s+default\s+Instrument\b",
498
+ r"props\.onAction", # Must implement handshake
499
+ r"props\.onWin" # Must implement victory
500
+ ]
501
+
502
+ def lint_component_code(code: str) -> (bool, list):
503
+ """Surgical syntax check for codegen reliability."""
504
+ errors = []
505
+ if not isinstance(code, str) or len(code.strip()) < 50:
506
+ return False, ["component_code missing or too short"]
507
+
508
+ for pat in FORBIDDEN_CODE_PATTERNS:
509
+ if re.search(pat, code, re.IGNORECASE):
510
+ errors.append(f"Syntax Violation: Found illegal pattern '{pat}'")
511
+
512
+ for pat in REQUIRED_CODE_PATTERNS:
513
+ if not re.search(pat, code):
514
+ errors.append(f"Protocol Violation: Missing required pattern '{pat}'")
515
+
516
+ # Ensure no raw HTML-style comments are present
517
+ if "<!--" in code or "-->" in code:
518
+ errors.append("Syntax Error: Use {/* */} for comments in JSX, not <!-- -->")
519
+
520
+ return len(errors) == 0, errors
521
+
522
  @app.route('/api/trial/generate', methods=['POST'])
523
  def generate_trial():
524
  """
525
+ Odysseus v10.1: The Hardened Instrumentalist.
526
+ Architects bespoke, interactive React games with a 3-pass syntax repair loop.
527
  Cost: 1 Spark.
528
  """
529
+ logger.info(">>> ODYSSEUS V10.1: FORGING HARDENED INSTRUMENT")
530
  uid = verify_token(request.headers.get('Authorization'))
531
  if not uid: return jsonify({"error": "Unauthorized"}), 401
532
 
 
546
  if lock_ref.get(): return jsonify({"status": "locked"}), 409
547
  lock_ref.set({"uid": uid, "at": datetime.utcnow().isoformat()})
548
 
549
+ # 3. Load Scientific Context
550
  layer_obj = db_ref.child(f"epiphanies/{ep_id}/layers/{layer_key}").get() or {}
551
  ctx_text = layer_obj.get("text", "General scientific principles.")
552
 
553
+ attempts, forged, last_raw, last_errs = 0, None, "", []
 
554
 
555
  base_prompt = f"""
556
+ You are Athena's Master Game Architect. Forge an interactive scientific 'Instrument' for {subject}.
557
+ Context: {ctx_text}
558
 
559
  TASK: Write a React component named 'Instrument'.
560
+ This is a GAME that requires user interaction to achieve a scientific victory.
561
+
562
+ TECHNICAL CONSTRAINTS (STRICT):
563
+ 1. REACT ONLY: Use React hooks (useState, useEffect, useRef). No external libs. Use SVG/Canvas.
564
+ 2. HANDSHAKE: Component receives `{{ onAction, onWin }}` as props.
565
+ - Call `props.onAction()` the moment the user interacts.
566
+ - Call `props.onWin()` when the specific scientific goal is reached.
567
+ 3. WIN CONDITION: You MUST define a logic state (e.g., matching a frequency) that triggers `onWin()`.
568
+ 4. NO COMMENTS: Do not use HTML comments <!-- -->. Use {{/* */}} if needed.
569
+ 5. CAMELCASE: Use className, onClick, onMouseDown, etc.
570
+ 6. ENTROPY: The system must fail/decay if the user stops interacting.
571
+
572
+ JSON OUTPUT SCHEMA:
573
  {{
574
+ "engine": "odysseus_v10.1",
575
  "instrument_name": "Title",
576
+ "mission_brief": "Goal description.",
577
+ "controls_guide": "Manual: 'Drag the X to the Y', 'Tap the Z to pulse', 'Hold the X until Y'.",
578
  "component_code": "const Instrument = (props) => {{ ... }}; export default Instrument;",
579
+ "feynman_truth": "Scientific revelation."
580
  }}
581
  """
582
 
583
  try:
584
  while attempts < 3 and not forged:
585
  attempts += 1
586
+ current_prompt = base_prompt if attempts == 1 else f"REPAIR LOGIC ERROR: {last_errs}\nPREVIOUS CODE: {last_raw}"
587
 
588
  res = client.models.generate_content(
589
  model=ATHENA_FLASH,
 
594
  last_raw = _strip_json_fences(res.text)
595
  candidate = json.loads(last_raw)
596
 
597
+ # Validation Step
598
+ code = candidate.get("component_code", "")
599
+ ok_c, last_errs = lint_component_code(code)
600
 
601
+ if ok_c:
602
  forged = candidate
603
  break
604
+ else:
605
+ logger.warning(f"Attempt {attempts} failed syntax check: {last_errs}")
606
 
607
  if not forged:
608
  lock_ref.delete()
609
+ return jsonify({"status": "failed", "errors": last_errs}), 422
610
 
611
+ # 4. Atomic Credit Check & Deduction (1 Spark)
612
  user_ref = db_ref.child(f'users/{uid}')
613
  def credits_txn(cur):
614
+ if (cur or 0) < 1: return cur
615
+ return cur - 1
616
 
617
+ updated_credits = user_ref.child('credits').transaction(credits_txn)
618
+ if updated_credits is None: # Transaction aborted/failed sparks
619
  lock_ref.delete()
620
  return jsonify({"error": "Insufficient Sparks"}), 402
621
 
622
+ # 5. Persist & Return
623
  forged["createdAt"] = datetime.utcnow().isoformat()
624
  db_ref.child(trial_path).set(forged)
625
  lock_ref.delete()
626
 
627
+ logger.info(f"Odysseus v10.1 success for {subject} in {attempts} attempt(s).")
628
  return jsonify(forged), 201
629
 
630
  except Exception as e:
631
  lock_ref.delete()
632
+ logger.error(f"v10.1 Global Failure: {e}")
633
+ return jsonify({"error": "The laws of the universe failed to stabilize. Retry."}), 500
634
 
635
  # -----------------------------------------------------------------------------
636
  # 5. THE CHIRON MENTOR & SYSTEM UTILS