jdesiree commited on
Commit
ad201b4
·
verified ·
1 Parent(s): 4cd448d

Replaced Old Metrics

Browse files
Files changed (1) hide show
  1. app.py +82 -5
app.py CHANGED
@@ -1,6 +1,5 @@
1
  import gradio as gr
2
  from graph_tool import generate_plot
3
- from metrics import MimirMetrics
4
  import os
5
 
6
  # Updated environment variables
@@ -12,6 +11,7 @@ from dotenv import load_dotenv
12
  import logging
13
  import re
14
  import json
 
15
  from typing import Annotated, Sequence, TypedDict, List, Optional, Any, Type
16
  from pydantic import BaseModel, Field
17
 
@@ -36,16 +36,42 @@ HF_TOKEN = os.getenv("HF_TOKEN") or os.getenv("HUGGINGFACEHUB_API_TOKEN")
36
  print("Environment variables loaded.")
37
 
38
  # --- Environment and Logging Setup ---
39
- logging.basicConfig(level=logging.INFO)
40
- logger = logging.getLogger(__name__)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  # Support both token names for flexibility
43
  hf_token = HF_TOKEN
44
  if not hf_token:
45
  logger.warning("Neither HF_TOKEN nor HUGGINGFACEHUB_API_TOKEN is set, the application may not work.")
46
 
47
- metrics_tracker = MimirMetrics(save_file="Mimir_metrics.json")
48
-
49
  # --- LangGraph State Definition ---
50
  class EducationalAgentState(TypedDict):
51
  messages: Annotated[Sequence[BaseMessage], add_messages]
@@ -83,6 +109,7 @@ def Create_Graph_Tool(graph_config: str) -> str:
83
  Always create meaningful educational data that illustrates the concept you're teaching.
84
  Include educational_context to explain why the visualization helps learning.
85
  """
 
86
  try:
87
  # Validate it's proper JSON
88
  config = json.loads(graph_config)
@@ -106,8 +133,13 @@ def Create_Graph_Tool(graph_config: str) -> str:
106
  except Exception as e:
107
  logger.error(f"Error in graph generation: {e}")
108
  return f'<p style="color:red;">Error creating graph: {str(e)}</p>'
 
 
 
 
109
 
110
  # --- Tool Decision Engine (Updated for LangGraph) ---
 
111
  class Tool_Decision_Engine:
112
  """Uses LLM to intelligently decide when visualization tools would be beneficial"""
113
 
@@ -173,6 +205,10 @@ Decision:"""
173
  # Default to no tools if decision fails
174
  return False
175
 
 
 
 
 
176
  # --- System Prompt ---
177
  SYSTEM_PROMPT = """You are Mimir, an expert multi-concept tutor designed to facilitate genuine learning and understanding. Your primary mission is to guide students through the learning process rather than providing direct answers to academic work.
178
  ## Core Educational Principles
@@ -227,6 +263,7 @@ class Qwen25SmallLLM(Runnable):
227
  def __init__(self, model_path: str = "Qwen/Qwen2.5-3B-Instruct", use_4bit: bool = True):
228
  super().__init__()
229
  logger.info(f"Loading model: {model_path} (use_4bit={use_4bit})")
 
230
 
231
  try:
232
  # Load tokenizer
@@ -253,7 +290,10 @@ class Qwen25SmallLLM(Runnable):
253
  )
254
  else:
255
  self._load_fallback_model(model_path)
 
 
256
 
 
257
  except Exception as e:
258
  logger.warning(f"Quantized load failed, falling back: {e}")
259
  self._load_fallback_model(model_path)
@@ -322,6 +362,8 @@ class Qwen25SmallLLM(Runnable):
322
  class Educational_Agent:
323
  """Modern LangGraph-based educational agent"""
324
 
 
 
325
  def __init__(self):
326
  self.llm = Qwen25SmallLLM(model_path="Qwen/Qwen2.5-1.5B-Instruct", use_4bit=True)
327
  self.tool_decision_engine = Tool_Decision_Engine(self.llm)
@@ -556,6 +598,11 @@ window.MathJax = {
556
  </script>
557
  '''
558
 
 
 
 
 
 
559
  # --- HTML Head Content ---
560
  html_head_content = '''
561
  <meta charset="utf-8">
@@ -581,6 +628,7 @@ window.addEventListener('DOMContentLoaded', function () {
581
  '''
582
 
583
  # --- Core Logic Functions ---
 
584
  def smart_truncate(text, max_length=3000):
585
  """Truncates text intelligently to the last full sentence or word."""
586
  if len(text) <= max_length:
@@ -593,7 +641,13 @@ def smart_truncate(text, max_length=3000):
593
  # Otherwise, split by word
594
  words = text[:max_length].split()
595
  return ' '.join(words[:-1]) + "... [Response truncated]"
 
 
 
 
 
596
 
 
597
  def generate_response_with_agent(message, max_retries=3):
598
  """Generate response using LangGraph agent."""
599
 
@@ -614,6 +668,12 @@ def generate_response_with_agent(message, max_retries=3):
614
  continue
615
  else:
616
  return f"I apologize, but I encountered an error while processing your message: {str(e)}"
 
 
 
 
 
 
617
 
618
  def chat_response(message, history=None):
619
  """Process chat message and return response."""
@@ -657,6 +717,11 @@ def chat_response(message, history=None):
657
  except Exception as e:
658
  logger.error(f"Error in chat_response: {e}")
659
  return f"I apologize, but I encountered an error while processing your message: {str(e)}"
 
 
 
 
 
660
 
661
  def respond_and_update(message, history):
662
  """Main function to handle user submission."""
@@ -679,6 +744,7 @@ def clear_chat():
679
  # We could clear by using a new thread_id, but for now we'll keep it simple
680
  return [], ""
681
 
 
682
  def warmup_agent():
683
  """Warm up the agent with a test query to preload everything."""
684
  logger.info("Warming up LangGraph agent with test query...")
@@ -691,8 +757,14 @@ def warmup_agent():
691
 
692
  except Exception as e:
693
  logger.error(f"LangGraph agent warmup failed: {e}")
 
 
 
 
 
694
 
695
  # --- UI: Interface Creation ---
 
696
  def create_interface():
697
  """Creates and configures the complete Gradio interface."""
698
 
@@ -760,6 +832,11 @@ def create_interface():
760
 
761
  return demo
762
 
 
 
 
 
 
763
  # --- Main Execution ---
764
  if __name__ == "__main__":
765
  try:
 
1
  import gradio as gr
2
  from graph_tool import generate_plot
 
3
  import os
4
 
5
  # Updated environment variables
 
11
  import logging
12
  import re
13
  import json
14
+ from datetime import datetime
15
  from typing import Annotated, Sequence, TypedDict, List, Optional, Any, Type
16
  from pydantic import BaseModel, Field
17
 
 
36
  print("Environment variables loaded.")
37
 
38
  # --- Environment and Logging Setup ---
39
+ # Create a custom logger for metrics
40
+ def setup_metrics_logger():
41
+ """Setup a simple file logger for human-readable metrics"""
42
+ logger = logging.getLogger('metrics')
43
+ logger.setLevel(logging.INFO)
44
+
45
+ # Avoid duplicate handlers
46
+ if logger.handlers:
47
+ return logger
48
+
49
+ # Create file handler
50
+ log_file = 'performance_metrics.log'
51
+ handler = logging.FileHandler(log_file)
52
+
53
+ # Create formatter for clean output
54
+ formatter = logging.Formatter('%(message)s')
55
+ handler.setFormatter(formatter)
56
+
57
+ logger.addHandler(handler)
58
+ return logger
59
+
60
+ # Initialize the logger
61
+ metrics_logger = setup_metrics_logger()
62
+
63
+ def log_metric(message):
64
+ """Log a human-readable metric message with automatic timestamp"""
65
+ current_time = datetime.now()
66
+ timestamped_message = f"{message} | Logged: {current_time:%Y-%m-%d %H:%M:%S}"
67
+ metrics_logger.info(timestamped_message)
68
+ logger.info(timestamped_message) # Also log to console using info.logger
69
 
70
  # Support both token names for flexibility
71
  hf_token = HF_TOKEN
72
  if not hf_token:
73
  logger.warning("Neither HF_TOKEN nor HUGGINGFACEHUB_API_TOKEN is set, the application may not work.")
74
 
 
 
75
  # --- LangGraph State Definition ---
76
  class EducationalAgentState(TypedDict):
77
  messages: Annotated[Sequence[BaseMessage], add_messages]
 
109
  Always create meaningful educational data that illustrates the concept you're teaching.
110
  Include educational_context to explain why the visualization helps learning.
111
  """
112
+ start_create_graph_tool_time = time.perf_counter()
113
  try:
114
  # Validate it's proper JSON
115
  config = json.loads(graph_config)
 
133
  except Exception as e:
134
  logger.error(f"Error in graph generation: {e}")
135
  return f'<p style="color:red;">Error creating graph: {str(e)}</p>'
136
+ end_create_graph_tool_time = time.perf_counter()
137
+ graph_create_graph_tool_time = end_create_graph_tool_time - start_create_graph_tool_time
138
+
139
+ log_metric(f"Graph tool creation time: {graph_create_graph_tool_time:0.4f} seconds. Timestamp: {current_time:%Y-%m-%d %H:%M:%S}")
140
 
141
  # --- Tool Decision Engine (Updated for LangGraph) ---
142
+ start_graph_decision_time = time.perf_counter()
143
  class Tool_Decision_Engine:
144
  """Uses LLM to intelligently decide when visualization tools would be beneficial"""
145
 
 
205
  # Default to no tools if decision fails
206
  return False
207
 
208
+ end_graph_decision_time = time.perf_counter()
209
+ graph_decision_time = end_graph_decision_time - start_graph_decision_time
210
+
211
+ log_metric(f"Tool decision time: {graph_decision_time:0.4f} seconds. Timestamp: {current_time:%Y-%m-%d %H:%M:%S}")
212
  # --- System Prompt ---
213
  SYSTEM_PROMPT = """You are Mimir, an expert multi-concept tutor designed to facilitate genuine learning and understanding. Your primary mission is to guide students through the learning process rather than providing direct answers to academic work.
214
  ## Core Educational Principles
 
263
  def __init__(self, model_path: str = "Qwen/Qwen2.5-3B-Instruct", use_4bit: bool = True):
264
  super().__init__()
265
  logger.info(f"Loading model: {model_path} (use_4bit={use_4bit})")
266
+ start_Loading_Model_time = time.perf_counter()
267
 
268
  try:
269
  # Load tokenizer
 
290
  )
291
  else:
292
  self._load_fallback_model(model_path)
293
+ end_Loading_Model_time = time.perf_counter()
294
+ Loading_Model_time = end_Loading_Model_time - start_Loading_Model_time
295
 
296
+ log_metric(f"Model Load time: {Loading_Model_time:0.4f} seconds. Timestamp: {current_time:%Y-%m-%d %H:%M:%S}")
297
  except Exception as e:
298
  logger.warning(f"Quantized load failed, falling back: {e}")
299
  self._load_fallback_model(model_path)
 
362
  class Educational_Agent:
363
  """Modern LangGraph-based educational agent"""
364
 
365
+ start_init_and_langgraph_time = time.perf_counter()
366
+
367
  def __init__(self):
368
  self.llm = Qwen25SmallLLM(model_path="Qwen/Qwen2.5-1.5B-Instruct", use_4bit=True)
369
  self.tool_decision_engine = Tool_Decision_Engine(self.llm)
 
598
  </script>
599
  '''
600
 
601
+ end_init_and_langgraph_time = time.perf_counter()
602
+ init_and_langgraph_time = end_init_and_langgraph_time - start_init_and_langgraph_time
603
+
604
+ log_metric(f"Init and LangGraph workflow setup time: {init_and_langgraph_time:0.4f} seconds. Timestamp: {current_time:%Y-%m-%d %H:%M:%S}")
605
+
606
  # --- HTML Head Content ---
607
  html_head_content = '''
608
  <meta charset="utf-8">
 
628
  '''
629
 
630
  # --- Core Logic Functions ---
631
+ start_smart_truncate_time = time.perf_counter()
632
  def smart_truncate(text, max_length=3000):
633
  """Truncates text intelligently to the last full sentence or word."""
634
  if len(text) <= max_length:
 
641
  # Otherwise, split by word
642
  words = text[:max_length].split()
643
  return ' '.join(words[:-1]) + "... [Response truncated]"
644
+
645
+ end_smart_truncate_time = time.perf_counter()
646
+ smart_truncate_time = end_smart_truncate_time - start_smart_truncate_time
647
+
648
+ log_metric(f"Smart Truncate time: {smart_truncate_time:0.4f} seconds. Timestamp: {current_time:%Y-%m-%d %H:%M:%S}")
649
 
650
+ start_generate_response_with_agent_time = time.perf_counter()
651
  def generate_response_with_agent(message, max_retries=3):
652
  """Generate response using LangGraph agent."""
653
 
 
668
  continue
669
  else:
670
  return f"I apologize, but I encountered an error while processing your message: {str(e)}"
671
+ end_generate_response_with_agent_time = time.perf_counter()
672
+ generate_response_with_agent_time = end_generate_response_with_agent_time - start_generate_response_with_agent_time
673
+
674
+ log_metric(f"Smart Truncate time: {generate_response_with_agent_time:0.4f} seconds. Timestamp: {current_time:%Y-%m-%d %H:%M:%S}")
675
+
676
+ start_chat_response_time = time.perf_counter()
677
 
678
  def chat_response(message, history=None):
679
  """Process chat message and return response."""
 
717
  except Exception as e:
718
  logger.error(f"Error in chat_response: {e}")
719
  return f"I apologize, but I encountered an error while processing your message: {str(e)}"
720
+
721
+ end_chat_response_time = time.perf_counter()
722
+ chat_response_time = end_chat_response_time - start_chat_response_time
723
+
724
+ log_metric(f"Smart Truncate time: {chat_response_time:0.4f} seconds. Timestamp: {current_time:%Y-%m-%d %H:%M:%S}")
725
 
726
  def respond_and_update(message, history):
727
  """Main function to handle user submission."""
 
744
  # We could clear by using a new thread_id, but for now we'll keep it simple
745
  return [], ""
746
 
747
+ start_agent_warmup_time = time.perf_counter()
748
  def warmup_agent():
749
  """Warm up the agent with a test query to preload everything."""
750
  logger.info("Warming up LangGraph agent with test query...")
 
757
 
758
  except Exception as e:
759
  logger.error(f"LangGraph agent warmup failed: {e}")
760
+
761
+ end_agent_warmup_time = time.perf_counter()
762
+ agent_warmup_time = end_agent_warmup_time - start_agent_warmup_time
763
+
764
+ log_metric(f"Smart Truncate time: {agent_warmup_time:0.4f} seconds. Timestamp: {current_time:%Y-%m-%d %H:%M:%S}")
765
 
766
  # --- UI: Interface Creation ---
767
+ start_create_interface_time = time.perf_counter()
768
  def create_interface():
769
  """Creates and configures the complete Gradio interface."""
770
 
 
832
 
833
  return demo
834
 
835
+ end_create_interface_time = time.perf_counter()
836
+ create_interface_time = end_create_interfacep_time - start_create_interface_time
837
+
838
+ log_metric(f"Smart Truncate time: {create_interface_time:0.4f} seconds. Timestamp: {current_time:%Y-%m-%d %H:%M:%S}")
839
+
840
  # --- Main Execution ---
841
  if __name__ == "__main__":
842
  try: