Justxd22 commited on
Commit
b0e3465
Β·
1 Parent(s): 0b52667

Add logging Box with functionality for API requests and responses

Browse files
Files changed (2) hide show
  1. TODO.md +2 -2
  2. app.py +49 -1
TODO.md CHANGED
@@ -6,16 +6,16 @@
6
  - find the texture missing
7
  - typing effect
8
  - pre-generate suspects cartoony potraits
 
9
 
10
 
11
  # Doing
12
- - bottom gradio box to see internal MCP tools calls out/in
13
  - add ai
14
  - mode selection
15
  - numbered steps to launch game
16
 
17
  - sound/music
18
- - eleven labs tts/voice
19
  - video embeded
20
  - divider
21
  - mcp showcase with title "try tools without playing"
 
6
  - find the texture missing
7
  - typing effect
8
  - pre-generate suspects cartoony potraits
9
+ - bottom gradio box to see internal MCP tools calls out/in
10
 
11
 
12
  # Doing
13
+ - eleven labs tts/voice
14
  - add ai
15
  - mode selection
16
  - numbered steps to launch game
17
 
18
  - sound/music
 
19
  - video embeded
20
  - divider
21
  - mcp showcase with title "try tools without playing"
app.py CHANGED
@@ -2,6 +2,7 @@ import gradio as gr
2
  import os
3
  import json
4
  import uvicorn
 
5
  from fastapi import FastAPI
6
  from fastapi.staticfiles import StaticFiles
7
  from game import game_engine
@@ -13,6 +14,17 @@ app = FastAPI()
13
  os.makedirs("ui/static", exist_ok=True)
14
  app.mount("/static", StaticFiles(directory="ui/static"), name="static")
15
 
 
 
 
 
 
 
 
 
 
 
 
16
  # --- API Bridge ---
17
 
18
  class BridgeRequest(BaseModel):
@@ -23,8 +35,15 @@ class BridgeRequest(BaseModel):
23
  async def api_bridge(request: BridgeRequest):
24
  """Direct API endpoint for game logic communication."""
25
  input_data = json.dumps({"action": request.action, "data": request.data})
 
 
 
26
  print(f"API Bridge Received: {input_data}")
27
  response = session.handle_input(input_data)
 
 
 
 
28
  return response or {}
29
 
30
  # --- Game Logic Wrapper ---
@@ -347,12 +366,14 @@ def start_game_from_ui(case_name):
347
  )
348
 
349
  css = """
350
- #bridge-input, #bridge-output { display: none !important; }
351
  .gradio-container { padding: 0 !important; max-width: 100% !important; height: 100vh !important; display: flex; flex-direction: column; }
352
  #game-frame-container { flex-grow: 1; height: 100% !important; border: none; overflow: hidden; padding: 0; }
353
  #game-frame-container > .html-container { height: 100% !important; display: flex; flex-direction: column; }
354
  #game-frame-container .prose { flex-grow: 1; height: 100% !important; max-width: 100% !important; }
355
  footer { display: none !important; }
 
 
356
  """
357
 
358
  with gr.Blocks(title="Murder.Ai", fill_height=True) as demo:
@@ -376,6 +397,28 @@ with gr.Blocks(title="Murder.Ai", fill_height=True) as demo:
376
  bridge_input = gr.Textbox(elem_id="bridge-input", visible=True)
377
  bridge_output = gr.Textbox(elem_id="bridge-output", visible=True)
378
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  # Start Game Event
380
  start_btn.click(
381
  fn=start_game_from_ui,
@@ -383,6 +426,11 @@ with gr.Blocks(title="Murder.Ai", fill_height=True) as demo:
383
  outputs=[selector_row, game_group, bridge_output]
384
  )
385
 
 
 
 
 
 
386
  # Bridge Logic (Python -> JS)
387
  bridge_output.change(
388
  None,
 
2
  import os
3
  import json
4
  import uvicorn
5
+ import time
6
  from fastapi import FastAPI
7
  from fastapi.staticfiles import StaticFiles
8
  from game import game_engine
 
14
  os.makedirs("ui/static", exist_ok=True)
15
  app.mount("/static", StaticFiles(directory="ui/static"), name="static")
16
 
17
+ # --- Global Logging ---
18
+ LOG_BUFFER = []
19
+
20
+ def add_log(message):
21
+ timestamp = time.strftime("%H:%M:%S")
22
+ entry = f"[{timestamp}] {message}\n" + "-"*40 + "\n"
23
+ LOG_BUFFER.append(entry)
24
+ # Keep last 50 logs
25
+ if len(LOG_BUFFER) > 50:
26
+ LOG_BUFFER.pop(0)
27
+
28
  # --- API Bridge ---
29
 
30
  class BridgeRequest(BaseModel):
 
35
  async def api_bridge(request: BridgeRequest):
36
  """Direct API endpoint for game logic communication."""
37
  input_data = json.dumps({"action": request.action, "data": request.data})
38
+
39
+ # Log Request
40
+ add_log(f"IN: {input_data}")
41
  print(f"API Bridge Received: {input_data}")
42
  response = session.handle_input(input_data)
43
+ # Log Response
44
+ if response:
45
+ add_log(f"OUT: {json.dumps(response)}")
46
+
47
  return response or {}
48
 
49
  # --- Game Logic Wrapper ---
 
366
  )
367
 
368
  css = """
369
+ #bridge-input, #bridge-output, #log-input { display: none !important; }
370
  .gradio-container { padding: 0 !important; max-width: 100% !important; height: 100vh !important; display: flex; flex-direction: column; }
371
  #game-frame-container { flex-grow: 1; height: 100% !important; border: none; overflow: hidden; padding: 0; }
372
  #game-frame-container > .html-container { height: 100% !important; display: flex; flex-direction: column; }
373
  #game-frame-container .prose { flex-grow: 1; height: 100% !important; max-width: 100% !important; }
374
  footer { display: none !important; }
375
+ /* Allow scrolling for logs */
376
+ .gradio-container { overflow-y: auto !important; }
377
  """
378
 
379
  with gr.Blocks(title="Murder.Ai", fill_height=True) as demo:
 
397
  bridge_input = gr.Textbox(elem_id="bridge-input", visible=True)
398
  bridge_output = gr.Textbox(elem_id="bridge-output", visible=True)
399
 
400
+ # Log Box
401
+ with gr.Accordion("System Logs (MCP Traffic)", open=False):
402
+ with gr.Row():
403
+ refresh_logs_btn = gr.Button("πŸ”„ Refresh Logs", scale=0)
404
+ auto_refresh = gr.Checkbox(label="Auto-refresh (1s)", value=False, scale=0)
405
+ log_box = gr.Textbox(label="Traffic", lines=10, max_lines=10, interactive=False, autoscroll=True, elem_id="visible-log-box")
406
+
407
+ # Log Polling
408
+ log_timer = gr.Timer(1, active=False)
409
+
410
+ def poll_logs():
411
+ return "".join(LOG_BUFFER)
412
+
413
+ log_timer.tick(fn=poll_logs, outputs=log_box)
414
+
415
+ refresh_logs_btn.click(fn=poll_logs, outputs=log_box)
416
+
417
+ def toggle_timer(active):
418
+ return gr.Timer(active=active)
419
+
420
+ auto_refresh.change(fn=toggle_timer, inputs=auto_refresh, outputs=log_timer)
421
+
422
  # Start Game Event
423
  start_btn.click(
424
  fn=start_game_from_ui,
 
426
  outputs=[selector_row, game_group, bridge_output]
427
  )
428
 
429
+ # Bridge Logic with Logging (Legacy/Fallback)
430
+ def bridge_logic_with_log(input_data, current_log):
431
+ # ... existing logic ...
432
+ return None, None # Disabled
433
+
434
  # Bridge Logic (Python -> JS)
435
  bridge_output.change(
436
  None,