mathysgrapotte commited on
Commit
33e0ffc
·
1 Parent(s): a25664c

center logs

Browse files
Files changed (3) hide show
  1. main.py +31 -20
  2. pyproject.toml +1 -0
  3. uv.lock +0 -0
main.py CHANGED
@@ -11,6 +11,7 @@ import threading
11
  from contextlib import redirect_stdout, redirect_stderr
12
  import queue
13
  import sys
 
14
 
15
  # Global log queue for streaming logs to Gradio
16
  log_queue = queue.Queue()
@@ -41,17 +42,14 @@ class QueueWriter:
41
  """A stream-like object that writes to a queue, to capture stdout."""
42
  def __init__(self, queue):
43
  self.queue = queue
44
- self.ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
45
 
46
  def write(self, text):
47
  # Print raw output to terminal to preserve colors
48
  sys.__stdout__.write(text)
49
  sys.__stdout__.flush()
50
 
51
- # Clean ANSI codes for Gradio display
52
- clean_text = self.ansi_escape.sub('', text)
53
- if clean_text.strip():
54
- self.queue.put(clean_text.rstrip())
55
 
56
  def flush(self):
57
  # Also flush stdout
@@ -227,20 +225,23 @@ def stream_logs_and_run_agent(module_name):
227
 
228
  # Stream logs while the agent is running
229
  accumulated_logs = ""
230
-
 
231
  while agent_thread.is_alive() or not log_queue.empty():
232
  try:
233
  # Get log message with a short timeout
234
  log_msg = log_queue.get(timeout=0.1)
235
- accumulated_logs += log_msg + "\n"
236
 
237
  # Yield the updated logs
238
- yield f"```text\n{accumulated_logs}\n```", None, None
 
239
 
240
  except queue.Empty:
241
  # If no new logs and thread is still alive, yield current state
242
  if agent_thread.is_alive():
243
- yield f"```text\n{accumulated_logs}\n```", None, None
 
244
  continue
245
 
246
  # Wait for the thread to complete
@@ -255,10 +256,11 @@ def stream_logs_and_run_agent(module_name):
255
  break
256
 
257
  # Return final results
 
258
  if result_container["error"]:
259
- yield f"```text\n{accumulated_logs}\n```", None, None
260
  else:
261
- yield f"```text\n{accumulated_logs}\n```", result_container["ontology_output"], result_container["file_output"]
262
 
263
  def run_interface():
264
  """ Function to run the agent with a Gradio interface.
@@ -320,8 +322,8 @@ def run_interface():
320
  }
321
 
322
  /* Live logs styling */
323
- .live-logs {
324
- background: rgba(33, 37, 41, 0.95) !important;
325
  border: 2px solid rgba(36, 176, 100, 0.4) !important;
326
  border-radius: 15px !important;
327
  color: #e9ecef !important;
@@ -331,24 +333,33 @@ def run_interface():
331
  max-height: 400px !important;
332
  overflow-y: auto !important;
333
  padding: 1rem !important;
 
 
 
 
 
 
334
  white-space: pre-wrap !important;
 
 
 
335
  }
336
 
337
- .live-logs::-webkit-scrollbar {
338
  width: 8px;
339
  }
340
 
341
- .live-logs::-webkit-scrollbar-track {
342
  background: rgba(52, 58, 64, 0.5);
343
  border-radius: 4px;
344
  }
345
 
346
- .live-logs::-webkit-scrollbar-thumb {
347
  background: rgba(36, 176, 100, 0.6);
348
  border-radius: 4px;
349
  }
350
 
351
- .live-logs::-webkit-scrollbar-thumb:hover {
352
  background: rgba(36, 176, 100, 0.8);
353
  }
354
 
@@ -761,9 +772,9 @@ def run_interface():
761
  """)
762
 
763
  # Live log display
764
- live_logs = gr.Markdown(
765
- "**Logs will appear here when the agent starts working...**",
766
- elem_classes="live-logs",
767
  )
768
 
769
  # Event handling for the streaming logs
 
11
  from contextlib import redirect_stdout, redirect_stderr
12
  import queue
13
  import sys
14
+ from ansi2html import Ansi2HTMLConverter as Ansi2HtmlConverter
15
 
16
  # Global log queue for streaming logs to Gradio
17
  log_queue = queue.Queue()
 
42
  """A stream-like object that writes to a queue, to capture stdout."""
43
  def __init__(self, queue):
44
  self.queue = queue
 
45
 
46
  def write(self, text):
47
  # Print raw output to terminal to preserve colors
48
  sys.__stdout__.write(text)
49
  sys.__stdout__.flush()
50
 
51
+ # Put the raw text with ANSI codes into the queue for HTML conversion
52
+ self.queue.put(text)
 
 
53
 
54
  def flush(self):
55
  # Also flush stdout
 
225
 
226
  # Stream logs while the agent is running
227
  accumulated_logs = ""
228
+ converter = Ansi2HtmlConverter(dark_bg=True, line_wrap=False)
229
+
230
  while agent_thread.is_alive() or not log_queue.empty():
231
  try:
232
  # Get log message with a short timeout
233
  log_msg = log_queue.get(timeout=0.1)
234
+ accumulated_logs += log_msg
235
 
236
  # Yield the updated logs
237
+ html_logs = converter.convert(accumulated_logs, full=False)
238
+ yield f"<div class='live-logs-container'><pre class='live-logs'>{html_logs}</pre></div>", None, None
239
 
240
  except queue.Empty:
241
  # If no new logs and thread is still alive, yield current state
242
  if agent_thread.is_alive():
243
+ html_logs = converter.convert(accumulated_logs, full=False)
244
+ yield f"<div class='live-logs-container'><pre class='live-logs'>{html_logs}</pre></div>", None, None
245
  continue
246
 
247
  # Wait for the thread to complete
 
256
  break
257
 
258
  # Return final results
259
+ html_logs = converter.convert(accumulated_logs, full=False)
260
  if result_container["error"]:
261
+ yield f"<div class='live-logs-container'><pre class='live-logs'>{html_logs}</pre></div>", None, None
262
  else:
263
+ yield f"<div class='live-logs-container'><pre class='live-logs'>{html_logs}</pre></div>", result_container["ontology_output"], result_container["file_output"]
264
 
265
  def run_interface():
266
  """ Function to run the agent with a Gradio interface.
 
322
  }
323
 
324
  /* Live logs styling */
325
+ .live-logs-container {
326
+ background: #212529 !important;
327
  border: 2px solid rgba(36, 176, 100, 0.4) !important;
328
  border-radius: 15px !important;
329
  color: #e9ecef !important;
 
333
  max-height: 400px !important;
334
  overflow-y: auto !important;
335
  padding: 1rem !important;
336
+ margin: 0 auto !important;
337
+ width: 95% !important;
338
+ text-align: center !important;
339
+ }
340
+
341
+ .live-logs {
342
  white-space: pre-wrap !important;
343
+ word-wrap: break-word;
344
+ display: inline-block !important;
345
+ text-align: left !important;
346
  }
347
 
348
+ .live-logs-container::-webkit-scrollbar {
349
  width: 8px;
350
  }
351
 
352
+ .live-logs-container::-webkit-scrollbar-track {
353
  background: rgba(52, 58, 64, 0.5);
354
  border-radius: 4px;
355
  }
356
 
357
+ .live-logs-container::-webkit-scrollbar-thumb {
358
  background: rgba(36, 176, 100, 0.6);
359
  border-radius: 4px;
360
  }
361
 
362
+ .live-logs-container::-webkit-scrollbar-thumb:hover {
363
  background: rgba(36, 176, 100, 0.8);
364
  }
365
 
 
772
  """)
773
 
774
  # Live log display
775
+ live_logs = gr.HTML(
776
+ "<div class='live-logs-container'><pre class='live-logs'>Logs will appear here...</pre></div>",
777
+ label="smolagents live logs"
778
  )
779
 
780
  # Event handling for the streaming logs
pyproject.toml CHANGED
@@ -15,4 +15,5 @@ dependencies = [
15
  "smolagents[litellm,mcp]>=1.17.0",
16
  "textblob>=0.19.0",
17
  "aiohttp>=3.8.0",
 
18
  ]
 
15
  "smolagents[litellm,mcp]>=1.17.0",
16
  "textblob>=0.19.0",
17
  "aiohttp>=3.8.0",
18
+ "ansi2html>=1.9.2",
19
  ]
uv.lock CHANGED
The diff for this file is too large to render. See raw diff