rairo commited on
Commit
a41baa0
·
verified ·
1 Parent(s): 4633fab

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +47 -4
main.py CHANGED
@@ -239,6 +239,39 @@ def generate_master_blueprint_task(subject, flattened_data, uid, epiphany_id):
239
  logger.error(f"Master Blueprint Thread Error: {e}")
240
  return None
241
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  # -----------------------------------------------------------------------------
243
  # 4. PRIMARY ENDPOINTS: GENERATE & THEIA SWEEP
244
  # -----------------------------------------------------------------------------
@@ -377,7 +410,7 @@ def generate_epiphany():
377
 
378
  @app.route('/api/epiphany/theia', methods=['POST'])
379
  def theia_sweep():
380
- """Standalone Theia Mode: Bounding Box Annotations with DB Persistence."""
381
  logger.info(">>> THEIA SWEEP INITIATED")
382
  uid = verify_token(request.headers.get('Authorization'))
383
  if not uid: return jsonify({'error': 'Unauthorized'}), 401
@@ -397,7 +430,16 @@ def theia_sweep():
397
  if user_data.get('credits', 0) < 4:
398
  return jsonify({'error': 'Need 4 Sparks for a Theia Sweep.'}), 402
399
 
 
 
 
 
400
  image_file = request.files['image']
 
 
 
 
 
401
  subject = existing_data.get('subject', 'Complex System')
402
 
403
  sweep_prompt = f"""
@@ -411,7 +453,7 @@ def theia_sweep():
411
  """
412
 
413
  try:
414
- pil_image = Image.open(io.BytesIO(image_file.read())).convert('RGB')
415
  res = client.models.generate_content(
416
  model=ATHENA_FLASH,
417
  contents=[sweep_prompt, pil_image],
@@ -422,8 +464,9 @@ def theia_sweep():
422
  )
423
 
424
  raw_json = res.text.strip()
425
- if "```json" in raw_json:
426
- raw_json = re.search(r'```json\n(.*?)\n```', raw_json, re.DOTALL).group(1)
 
427
 
428
  annotations = json.loads(raw_json)
429
 
 
239
  logger.error(f"Master Blueprint Thread Error: {e}")
240
  return None
241
 
242
+ #Prepare hi fidelity images to proper scale
243
+ def prepare_vision_bytes(image_bytes, max_size_mb=9.5):
244
+ """
245
+ Surgically compresses/resizes image bytes to stay under the 10MB API limit.
246
+ Target: 9.5MB to allow a safe margin for the rest of the request payload.
247
+ """
248
+ size_mb = len(image_bytes) / (1024 * 1024)
249
+ if size_mb <= max_size_mb:
250
+ return image_bytes
251
+
252
+ logger.info(f"Vision Scaler: Image is {size_mb:.2f}MB. Optimizing for API...")
253
+ try:
254
+ img = Image.open(io.BytesIO(image_bytes))
255
+
256
+ # Target resolution: 2048px on the long side is optimal for Gemini detection
257
+ max_dim = 2048
258
+ w, h = img.size
259
+ if max(w, h) > max_dim:
260
+ scale = max_dim / max(w, h)
261
+ img = img.resize((int(w * scale), int(h * scale)), Image.Resampling.LANCZOS)
262
+
263
+ output = io.BytesIO()
264
+ # Convert to RGB (removes Alpha channel if present to save space)
265
+ # Save as optimized JPEG at 85% quality
266
+ img.convert('RGB').save(output, format="JPEG", quality=85, optimize=True)
267
+ new_bytes = output.getvalue()
268
+
269
+ new_size_mb = len(new_bytes)/(1024*1024)
270
+ logger.info(f"Vision Scaler: Optimization complete. New size: {new_size_mb:.2f}MB")
271
+ return new_bytes
272
+ except Exception as e:
273
+ logger.error(f"Vision Scaler Failure: {e}")
274
+ return image_bytes # Fallback to original and hope for the best
275
  # -----------------------------------------------------------------------------
276
  # 4. PRIMARY ENDPOINTS: GENERATE & THEIA SWEEP
277
  # -----------------------------------------------------------------------------
 
410
 
411
  @app.route('/api/epiphany/theia', methods=['POST'])
412
  def theia_sweep():
413
+ """Standalone Theia Mode: Bounding Box Annotations with Vision Scaling."""
414
  logger.info(">>> THEIA SWEEP INITIATED")
415
  uid = verify_token(request.headers.get('Authorization'))
416
  if not uid: return jsonify({'error': 'Unauthorized'}), 401
 
430
  if user_data.get('credits', 0) < 4:
431
  return jsonify({'error': 'Need 4 Sparks for a Theia Sweep.'}), 402
432
 
433
+ # --- IMAGE PRE-PROCESSING ---
434
+ if 'image' not in request.files:
435
+ return jsonify({'error': 'image file is required.'}), 400
436
+
437
  image_file = request.files['image']
438
+ raw_bytes = image_file.read()
439
+
440
+ # Surgical Fix: Stay under 10MB limit
441
+ image_bytes = prepare_vision_bytes(raw_bytes)
442
+
443
  subject = existing_data.get('subject', 'Complex System')
444
 
445
  sweep_prompt = f"""
 
453
  """
454
 
455
  try:
456
+ pil_image = Image.open(io.BytesIO(image_bytes)).convert('RGB')
457
  res = client.models.generate_content(
458
  model=ATHENA_FLASH,
459
  contents=[sweep_prompt, pil_image],
 
464
  )
465
 
466
  raw_json = res.text.strip()
467
+ # Use helper to strip fences if present
468
+ if "```" in raw_json:
469
+ raw_json = _strip_json_fences(raw_json)
470
 
471
  annotations = json.loads(raw_json)
472