youkii-xr commited on
Commit
a2782c2
·
verified ·
1 Parent(s): 36bcab9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -55
app.py CHANGED
@@ -9,7 +9,7 @@ import re
9
  from huggingface_hub import hf_hub_download
10
  import tempfile
11
  import numpy as np
12
- from typing import List, Tuple, Dict, Any # REQUIRED FOR MCP
13
 
14
  # --- 1. CONFIGURATION & SECRETS ---
15
  GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
@@ -164,31 +164,19 @@ except Exception as e:
164
  model = None
165
 
166
  # --- 5. MAIN UI PIPELINE (Orchestrator) ---
 
167
 
168
  def process_pipeline(image, conf_threshold):
169
- """
170
- Main function used by the Web UI.
171
- Chains detection -> analytics -> translation.
172
- """
173
  if image is None: return None, "", "", None, "", None, []
174
  if model is None: return None, "Error: Model not loaded.", "", None, "", None, []
175
 
176
  try:
177
- # 1. Detect
178
  img_w, img_h = image.size
179
  annotated_img, detections, crops = core_detect(image, conf_threshold)
180
-
181
- # 2. Extract Keywords
182
  unique_codes = list(set([d['code'] for d in detections]))
183
  mapped_words = [gardiner_map.get(code, f"[{code}]") for code in unique_codes]
184
-
185
- # 3. Translate
186
  mystical, academic = core_translate(mapped_words)
187
-
188
- # 4. Analytics
189
  analytics_plot = core_analytics(detections, img_w, img_h)
190
-
191
- # 5. Reports
192
  text_report = f"Total Symbols: {len(detections)}\nUnique Codes: {', '.join(unique_codes)}"
193
  json_output = {"count": len(detections), "detections": detections}
194
  formatted_mystical = f"""<div class="mystical-container"><h3>✨ THE ANCIENT WHISPER</h3><p>{mystical}</p></div>"""
@@ -198,40 +186,53 @@ def process_pipeline(image, conf_threshold):
198
  except Exception as e:
199
  return None, f"System Failure: {str(e)}", "", None, str(e), None, []
200
 
201
- # --- 6. MCP API FUNCTIONS (Granular & Typed) ---
202
- # IMPORTANT: These functions use Type Hints so Gradio knows how to define the MCP Tool.
203
 
204
- def api_detect_only(image: Image.Image, conf: float = 0.25) -> Tuple[Image.Image, Any]:
205
- """API: Returns JSON detection data and annotated image."""
 
 
 
206
  ann_img, dets, _ = core_detect(image, conf)
207
- return ann_img, {"count": len(dets), "detections": dets}
 
 
 
 
 
 
208
 
209
- def api_translate_only(keywords_text: str) -> Tuple[str, str]:
210
- """API: Translates a comma-separated string of keywords."""
 
 
211
  if isinstance(keywords_text, str):
212
  keywords = [k.strip() for k in keywords_text.split(',')]
213
  else:
214
  keywords = ["Unknown"]
215
  mystical, academic = core_translate(keywords)
216
- # Strip HTML tags for clean API text
217
  clean_mystical = re.sub('<[^<]+?>', '', mystical)
218
  return clean_mystical, academic
219
 
220
- def api_get_supported_codes() -> Dict[str, Any]:
221
- """API: Returns the full Gardiner list."""
222
- return gardiner_data
223
-
224
- def api_get_analytics(json_data: Dict[str, Any]) -> Image.Image:
225
- """API: Generates a plot Image from JSON detection data."""
226
- # MCP cannot display interactive plots, so we convert to Image
227
  dets = json_data.get("detections", [])
228
  fig = core_analytics(dets, 1000, 1000)
229
 
230
- # Save figure to buffer and reload as PIL Image
231
- buf = tempfile.NamedTemporaryFile(suffix=".png", delete=False)
232
- fig.savefig(buf.name, format='png', facecolor='#0f0f23')
 
233
  plt.close(fig)
234
- return Image.open(buf.name)
 
 
 
 
235
 
236
  # --- 7. HTML GENERATORS ---
237
 
@@ -408,50 +409,50 @@ with gr.Blocks(title="Rosetta Decoder Ultimate") as demo:
408
  gr.HTML(trail_script)
409
 
410
  # --- Hidden API Buttons for MCP (Granular Access) ---
411
- # These buttons are not visible in the UI but expose the API endpoints for Claude
412
- # We call the TYPED functions here so Gradio registers the tool correctly.
413
 
414
  with gr.Column(visible=False):
415
- # 1. Detect Only
416
- btn_mcp_detect = gr.Button("MCP Detect")
417
- api_detect_out_img = gr.Image()
418
  api_detect_out_json = gr.JSON()
419
  btn_mcp_detect.click(
420
- fn=api_detect_only,
421
  inputs=[gr.Image(label="Input Image"), gr.Number(value=0.25, label="Conf")],
422
- outputs=[api_detect_out_img, api_detect_out_json],
423
- api_name="detect_hieroglyphs"
424
  )
425
 
426
- # 2. Translate Only
427
- btn_mcp_trans = gr.Button("MCP Translate")
428
  api_trans_out_mystical = gr.Textbox()
429
  api_trans_out_academic = gr.Textbox()
430
  btn_mcp_trans.click(
431
- fn=api_translate_only,
432
  inputs=[gr.Textbox(label="Keywords")],
433
  outputs=[api_trans_out_mystical, api_trans_out_academic],
434
- api_name="translate_hieroglyphs"
435
  )
436
 
437
- # 3. Analytics Only (Returns IMAGE for MCP)
438
- btn_mcp_analytics = gr.Button("MCP Analytics")
439
- api_analytics_out = gr.Image() # Changed to Image for MCP
440
  btn_mcp_analytics.click(
441
- fn=api_get_analytics,
442
  inputs=[gr.JSON(label="Data")],
443
- outputs=[api_analytics_out],
444
- api_name="get_analytics"
445
  )
446
 
447
  # 4. Get List
448
- btn_mcp_list = gr.Button("MCP List")
449
  api_list_out = gr.JSON()
450
  btn_mcp_list.click(
451
- fn=api_get_supported_codes,
452
  inputs=[],
453
  outputs=[api_list_out],
454
- api_name="get_supported_codes"
455
  )
456
 
457
  # --- Visible UI ---
@@ -496,7 +497,7 @@ with gr.Blocks(title="Rosetta Decoder Ultimate") as demo:
496
  # TAB 3: SETUP
497
  with gr.TabItem("🤖 SYSTEM SETUP"):
498
  gr.HTML(guide_html)
499
- # Expanded code box as requested
500
  gr.Code(value=claude_json_content, language="json", label="claude_desktop_config.json", interactive=False, lines=30)
501
 
502
  # TAB 4: GARDINER CODES
 
9
  from huggingface_hub import hf_hub_download
10
  import tempfile
11
  import numpy as np
12
+ from typing import List, Tuple, Dict, Any
13
 
14
  # --- 1. CONFIGURATION & SECRETS ---
15
  GOOGLE_API_KEY = os.environ.get("GOOGLE_API_KEY")
 
164
  model = None
165
 
166
  # --- 5. MAIN UI PIPELINE (Orchestrator) ---
167
+ # Used for the Web Interface (Returns complex Objects)
168
 
169
  def process_pipeline(image, conf_threshold):
 
 
 
 
170
  if image is None: return None, "", "", None, "", None, []
171
  if model is None: return None, "Error: Model not loaded.", "", None, "", None, []
172
 
173
  try:
 
174
  img_w, img_h = image.size
175
  annotated_img, detections, crops = core_detect(image, conf_threshold)
 
 
176
  unique_codes = list(set([d['code'] for d in detections]))
177
  mapped_words = [gardiner_map.get(code, f"[{code}]") for code in unique_codes]
 
 
178
  mystical, academic = core_translate(mapped_words)
 
 
179
  analytics_plot = core_analytics(detections, img_w, img_h)
 
 
180
  text_report = f"Total Symbols: {len(detections)}\nUnique Codes: {', '.join(unique_codes)}"
181
  json_output = {"count": len(detections), "detections": detections}
182
  formatted_mystical = f"""<div class="mystical-container"><h3>✨ THE ANCIENT WHISPER</h3><p>{mystical}</p></div>"""
 
186
  except Exception as e:
187
  return None, f"System Failure: {str(e)}", "", None, str(e), None, []
188
 
189
+ # --- 6. MCP API FUNCTIONS (Optimized for Claude) ---
190
+ # Changes: Short Names, File Path Returns (No Base64)
191
 
192
+ def api_detect(image: Image.Image, conf: float = 0.25) -> Tuple[str, Dict[str, Any]]:
193
+ """
194
+ detect: Scans image for hieroglyphs.
195
+ Returns: 1. File path to the annotated image. 2. JSON summary of findings.
196
+ """
197
  ann_img, dets, _ = core_detect(image, conf)
198
+
199
+ # SAVE to temp file and return PATH string
200
+ with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as t:
201
+ ann_img.save(t.name)
202
+ path = t.name
203
+
204
+ return path, {"count": len(dets), "detections": dets}
205
 
206
+ def api_translate(keywords_text: str) -> Tuple[str, str]:
207
+ """
208
+ translate: Takes comma-separated codes (e.g. 'G43, X1'). Returns Mystical & Academic text.
209
+ """
210
  if isinstance(keywords_text, str):
211
  keywords = [k.strip() for k in keywords_text.split(',')]
212
  else:
213
  keywords = ["Unknown"]
214
  mystical, academic = core_translate(keywords)
 
215
  clean_mystical = re.sub('<[^<]+?>', '', mystical)
216
  return clean_mystical, academic
217
 
218
+ def api_analytics(json_data: Dict[str, Any]) -> str:
219
+ """
220
+ analytics: Takes JSON detection data.
221
+ Returns: File path to the generated statistical chart image.
222
+ """
 
 
223
  dets = json_data.get("detections", [])
224
  fig = core_analytics(dets, 1000, 1000)
225
 
226
+ # SAVE to temp file and return PATH string
227
+ with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as t:
228
+ fig.savefig(t.name, format='png', facecolor='#0f0f23')
229
+ path = t.name
230
  plt.close(fig)
231
+ return path
232
+
233
+ def api_list_codes() -> Dict[str, Any]:
234
+ """list_codes: Returns the full supported Gardiner code database."""
235
+ return gardiner_data
236
 
237
  # --- 7. HTML GENERATORS ---
238
 
 
409
  gr.HTML(trail_script)
410
 
411
  # --- Hidden API Buttons for MCP (Granular Access) ---
412
+ # These buttons define the TOOLS for Claude.
413
+ # Note: We output 'gr.Textbox' for images now, so it returns the FILE PATH string.
414
 
415
  with gr.Column(visible=False):
416
+ # 1. Detect (Returns Path & JSON)
417
+ btn_mcp_detect = gr.Button("Detect")
418
+ api_detect_out_path = gr.Textbox()
419
  api_detect_out_json = gr.JSON()
420
  btn_mcp_detect.click(
421
+ fn=api_detect,
422
  inputs=[gr.Image(label="Input Image"), gr.Number(value=0.25, label="Conf")],
423
+ outputs=[api_detect_out_path, api_detect_out_json],
424
+ api_name="detect" # Short name
425
  )
426
 
427
+ # 2. Translate
428
+ btn_mcp_trans = gr.Button("Translate")
429
  api_trans_out_mystical = gr.Textbox()
430
  api_trans_out_academic = gr.Textbox()
431
  btn_mcp_trans.click(
432
+ fn=api_translate,
433
  inputs=[gr.Textbox(label="Keywords")],
434
  outputs=[api_trans_out_mystical, api_trans_out_academic],
435
+ api_name="translate" # Short name
436
  )
437
 
438
+ # 3. Analytics (Returns Path)
439
+ btn_mcp_analytics = gr.Button("Analytics")
440
+ api_analytics_out_path = gr.Textbox()
441
  btn_mcp_analytics.click(
442
+ fn=api_analytics,
443
  inputs=[gr.JSON(label="Data")],
444
+ outputs=[api_analytics_out_path],
445
+ api_name="analytics" # Short name
446
  )
447
 
448
  # 4. Get List
449
+ btn_mcp_list = gr.Button("List")
450
  api_list_out = gr.JSON()
451
  btn_mcp_list.click(
452
+ fn=api_list_codes,
453
  inputs=[],
454
  outputs=[api_list_out],
455
+ api_name="list_codes"
456
  )
457
 
458
  # --- Visible UI ---
 
497
  # TAB 3: SETUP
498
  with gr.TabItem("🤖 SYSTEM SETUP"):
499
  gr.HTML(guide_html)
500
+ # Expanded Code Box
501
  gr.Code(value=claude_json_content, language="json", label="claude_desktop_config.json", interactive=False, lines=30)
502
 
503
  # TAB 4: GARDINER CODES