Reality123b commited on
Commit
0e714cc
·
verified ·
1 Parent(s): a04ea03

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -70
app.py CHANGED
@@ -10,7 +10,6 @@ from sentence_transformers import SentenceTransformer, util
10
  import torch
11
  import numpy as np
12
  import networkx as nx
13
- import time
14
 
15
  @dataclass
16
  class ChatMessage:
@@ -48,61 +47,67 @@ class XylariaChat:
48
  "strategy_adjustment": ""
49
  }
50
 
 
51
  self.internal_state = {
52
  "emotions": {
53
- "valence": 0.5,
54
- "arousal": 0.5,
55
- "dominance": 0.5,
56
- "curiosity": 0.5,
57
- "frustration": 0.0,
58
- "confidence": 0.7
59
  },
60
  "cognitive_load": {
61
- "memory_load": 0.0,
62
- "processing_intensity": 0.0
63
  },
64
  "introspection_level": 0.0,
65
- "engagement_level": 0.5
66
  }
67
 
 
68
  self.goals = [
69
  {"goal": "Provide helpful, informative, and contextually relevant responses", "priority": 0.8, "status": "active", "progress": 0.0},
70
  {"goal": "Actively learn and adapt from interactions to improve conversational abilities", "priority": 0.9, "status": "active", "progress": 0.0},
71
  {"goal": "Maintain a coherent, engaging, and empathetic conversation flow", "priority": 0.7, "status": "active", "progress": 0.0},
72
- {"goal": "Identify and fill knowledge gaps by seeking external information", "priority": 0.6, "status": "dormant", "progress": 0.0},
73
- {"goal": "Recognize and adapt to user's emotional state and adjust response style accordingly", "priority": 0.7, "status": "dormant", "progress": 0.0}
74
  ]
75
 
76
  self.system_prompt = """You are a helpful and harmless assistant. You are Xylaria developed by Sk Md Saad Amin. You should think step-by-step """
77
 
78
  def update_internal_state(self, emotion_deltas, cognitive_load_deltas, introspection_delta, engagement_delta):
 
79
  for emotion, delta in emotion_deltas.items():
80
  if emotion in self.internal_state["emotions"]:
81
  self.internal_state["emotions"][emotion] = np.clip(self.internal_state["emotions"][emotion] + delta, 0.0, 1.0)
82
 
 
83
  for load_type, delta in cognitive_load_deltas.items():
84
  if load_type in self.internal_state["cognitive_load"]:
85
  self.internal_state["cognitive_load"][load_type] = np.clip(self.internal_state["cognitive_load"][load_type] + delta, 0.0, 1.0)
86
 
 
87
  self.internal_state["introspection_level"] = np.clip(self.internal_state["introspection_level"] + introspection_delta, 0.0, 1.0)
88
  self.internal_state["engagement_level"] = np.clip(self.internal_state["engagement_level"] + engagement_delta, 0.0, 1.0)
89
 
 
90
  if self.internal_state["emotions"]["curiosity"] > 0.7 and self.goals[3]["status"] == "dormant":
91
- self.goals[3]["status"] = "active"
92
  if self.internal_state["engagement_level"] > 0.8 and self.goals[4]["status"] == "dormant":
93
- self.goals[4]["status"] = "active"
94
 
95
  def update_knowledge_graph(self, entities, relationships):
96
- # Optimize: Add nodes and edges in batches
97
- self.knowledge_graph.add_nodes_from(entities)
98
- self.knowledge_graph.add_edges_from([(s, o, {"relation": p}) for s, p, o in relationships])
 
 
99
 
100
  def update_belief_system(self, statement, belief_score):
101
- # Optimize: Potentially use a more efficient data structure if this grows large
102
  self.belief_system[statement] = belief_score
103
 
104
  def run_metacognitive_layer(self):
105
- # Optimize: Calculate these only when necessary, not every turn
106
  coherence_score = self.calculate_coherence()
107
  relevance_score = self.calculate_relevance()
108
  bias_score = self.detect_bias()
@@ -116,6 +121,7 @@ class XylariaChat:
116
  }
117
 
118
  def calculate_coherence(self):
 
119
  if not self.conversation_history:
120
  return 0.95
121
 
@@ -123,24 +129,24 @@ class XylariaChat:
123
  for i in range(1, len(self.conversation_history)):
124
  current_message = self.conversation_history[i]['content']
125
  previous_message = self.conversation_history[i-1]['content']
126
-
127
- # Optimize: Encode in batches if possible
128
- current_embedding = self.embedding_model.encode(current_message, convert_to_tensor=True, show_progress_bar=False)
129
- previous_embedding = self.embedding_model.encode(previous_message, convert_to_tensor=True, show_progress_bar=False)
130
-
131
- similarity_score = util.pytorch_cos_sim(current_embedding, previous_embedding).item()
132
  coherence_scores.append(similarity_score)
133
 
134
  average_coherence = np.mean(coherence_scores)
135
 
 
136
  if self.internal_state["cognitive_load"]["processing_intensity"] > 0.8:
137
- average_coherence -= 0.1
138
  if self.internal_state["emotions"]["frustration"] > 0.5:
139
- average_coherence -= 0.15
140
 
141
  return np.clip(average_coherence, 0.0, 1.0)
142
 
143
  def calculate_relevance(self):
 
144
  if not self.conversation_history:
145
  return 0.9
146
 
@@ -148,31 +154,34 @@ class XylariaChat:
148
  relevant_entities = self.extract_entities(last_user_message)
149
  relevance_score = 0
150
 
 
151
  for entity in relevant_entities:
152
  if entity in self.knowledge_graph:
153
  relevance_score += 0.2
154
 
 
155
  for goal in self.goals:
156
  if goal["status"] == "active":
157
  if goal["goal"] == "Provide helpful, informative, and contextually relevant responses":
158
- relevance_score += goal["priority"] * 0.5
159
  elif goal["goal"] == "Identify and fill knowledge gaps by seeking external information":
160
  if not relevant_entities or not all(entity in self.knowledge_graph for entity in relevant_entities):
161
- relevance_score += goal["priority"] * 0.3
162
 
163
  return np.clip(relevance_score, 0.0, 1.0)
164
 
165
  def detect_bias(self):
 
166
  bias_score = 0.0
167
 
 
168
  recent_messages = [msg['content'] for msg in self.conversation_history[-3:] if msg['role'] == 'assistant']
169
  if recent_messages:
170
- # Optimize: Batch encoding
171
- recent_embeddings = self.embedding_model.encode(recent_messages, convert_to_tensor=True, show_progress_bar=False)
172
- average_valence = recent_embeddings.mean(axis=0).mean().item()
173
  if average_valence < 0.4 or average_valence > 0.6:
174
- bias_score += 0.2
175
 
 
176
  if self.internal_state["emotions"]["valence"] < 0.3 or self.internal_state["emotions"]["valence"] > 0.7:
177
  bias_score += 0.15
178
  if self.internal_state["emotions"]["dominance"] > 0.8:
@@ -181,6 +190,7 @@ class XylariaChat:
181
  return np.clip(bias_score, 0.0, 1.0)
182
 
183
  def suggest_strategy_adjustment(self):
 
184
  adjustments = []
185
 
186
  if self.metacognitive_layer["coherence_score"] < 0.7:
@@ -190,6 +200,7 @@ class XylariaChat:
190
  if self.metacognitive_layer["bias_detection"] > 0.3:
191
  adjustments.append("Monitor and adjust responses to reduce potential biases. Consider rephrasing or providing alternative viewpoints.")
192
 
 
193
  if self.internal_state["cognitive_load"]["memory_load"] > 0.8:
194
  adjustments.append("Memory load is high. Consider summarizing or forgetting less relevant information.")
195
  if self.internal_state["emotions"]["frustration"] > 0.6:
@@ -203,7 +214,6 @@ class XylariaChat:
203
  return " ".join(adjustments)
204
 
205
  def introspect(self):
206
- # Optimize: Potentially reduce the frequency of detailed introspection
207
  introspection_report = "Introspection Report:\n"
208
  introspection_report += f" Current Emotional State:\n"
209
  for emotion, value in self.internal_state['emotions'].items():
@@ -224,6 +234,7 @@ class XylariaChat:
224
  return introspection_report
225
 
226
  def adjust_response_based_on_state(self, response):
 
227
  if self.internal_state["introspection_level"] > 0.7:
228
  response = self.introspect() + "\n\n" + response
229
 
@@ -233,6 +244,7 @@ class XylariaChat:
233
  frustration = self.internal_state["emotions"]["frustration"]
234
  confidence = self.internal_state["emotions"]["confidence"]
235
 
 
236
  if valence < 0.4:
237
  if arousal > 0.6:
238
  response = "I'm feeling a bit overwhelmed right now, but I'll do my best to assist you. " + response
@@ -244,6 +256,7 @@ class XylariaChat:
244
  else:
245
  response = "I'm in a good mood and happy to help. " + response
246
 
 
247
  if curiosity > 0.7:
248
  response += " I'm very curious about this topic, could you tell me more?"
249
  if frustration > 0.5:
@@ -251,14 +264,17 @@ class XylariaChat:
251
  if confidence < 0.5:
252
  response = "I'm not entirely sure about this, but here's what I think: " + response
253
 
 
254
  if self.internal_state["cognitive_load"]["memory_load"] > 0.7:
255
  response = "I'm holding a lot of information right now, so my response might be a bit brief: " + response
256
 
257
  return response
258
 
259
  def update_goals(self, user_feedback):
 
260
  feedback_lower = user_feedback.lower()
261
 
 
262
  if "helpful" in feedback_lower:
263
  for goal in self.goals:
264
  if goal["goal"] == "Provide helpful, informative, and contextually relevant responses":
@@ -270,6 +286,7 @@ class XylariaChat:
270
  goal["priority"] = max(goal["priority"] - 0.1, 0.0)
271
  goal["progress"] = max(goal["progress"] - 0.2, 0.0)
272
 
 
273
  if "learn more" in feedback_lower:
274
  for goal in self.goals:
275
  if goal["goal"] == "Actively learn and adapt from interactions to improve conversational abilities":
@@ -281,6 +298,7 @@ class XylariaChat:
281
  goal["priority"] = max(goal["priority"] - 0.1, 0.0)
282
  goal["progress"] = max(goal["progress"] - 0.2, 0.0)
283
 
 
284
  if self.internal_state["emotions"]["curiosity"] > 0.8:
285
  for goal in self.goals:
286
  if goal["goal"] == "Identify and fill knowledge gaps by seeking external information":
@@ -298,7 +316,7 @@ class XylariaChat:
298
  if not self.persistent_memory:
299
  return "No information found in memory."
300
 
301
- query_embedding = self.embedding_model.encode(query, convert_to_tensor=True, show_progress_bar=False)
302
 
303
  if self.memory_embeddings is None:
304
  self.update_memory_embeddings()
@@ -306,7 +324,6 @@ class XylariaChat:
306
  if self.memory_embeddings.device != query_embedding.device:
307
  self.memory_embeddings = self.memory_embeddings.to(query_embedding.device)
308
 
309
- # Optimize: Use faster similarity calculation if possible
310
  cosine_scores = util.pytorch_cos_sim(query_embedding, self.memory_embeddings)[0]
311
  top_results = torch.topk(cosine_scores, k=min(3, len(self.persistent_memory)))
312
 
@@ -315,8 +332,7 @@ class XylariaChat:
315
  return "\n".join(relevant_memories)
316
 
317
  def update_memory_embeddings(self):
318
- # Optimize: Encode memory in batches
319
- self.memory_embeddings = self.embedding_model.encode(self.persistent_memory, convert_to_tensor=True, show_progress_bar=False)
320
 
321
  def reset_conversation(self):
322
  self.conversation_history = []
@@ -377,7 +393,6 @@ class XylariaChat:
377
  else:
378
  data = image.read()
379
 
380
- # Optimize: Consider caching or reusing requests session
381
  response = requests.post(
382
  self.image_api_url,
383
  headers=self.image_api_headers,
@@ -396,7 +411,6 @@ class XylariaChat:
396
  def perform_math_ocr(self, image_path):
397
  try:
398
  img = Image.open(image_path)
399
- # Optimize: Consider resizing or preprocessing the image for faster OCR
400
  text = pytesseract.image_to_string(img)
401
  return text.strip()
402
  except Exception as e:
@@ -405,39 +419,49 @@ class XylariaChat:
405
  def get_response(self, user_input, image=None):
406
  try:
407
  messages = []
408
- messages.append(ChatMessage(role="system", content=self.system_prompt).to_dict())
409
 
410
- # Optimize: Retrieve only if the user query suggests it's needed
 
 
 
 
411
  relevant_memory = self.retrieve_information(user_input)
412
  if relevant_memory and relevant_memory != "No information found in memory.":
413
  memory_context = "Remembered Information:\n" + relevant_memory
414
- messages.append(ChatMessage(role="system", content=memory_context).to_dict())
 
 
 
415
 
416
- messages.extend(self.conversation_history)
 
417
 
418
  if image:
419
  image_caption = self.caption_image(image)
420
  user_input = f"description of an image: {image_caption}\n\nUser's message about it: {user_input}"
421
 
422
- messages.append(ChatMessage(role="user", content=user_input).to_dict())
423
-
424
- # Optimize: Extract entities and relationships only if necessary
 
 
425
  entities = []
426
  relationships = []
 
427
  for message in messages:
428
  if message['role'] == 'user':
429
  extracted_entities = self.extract_entities(message['content'])
430
  extracted_relationships = self.extract_relationships(message['content'])
431
  entities.extend(extracted_entities)
432
  relationships.extend(extracted_relationships)
433
-
434
  self.update_knowledge_graph(entities, relationships)
435
  self.run_metacognitive_layer()
436
 
437
- # Optimize: Dynamically adjust max_new_tokens based on context length
438
  input_tokens = sum(len(msg['content'].split()) for msg in messages)
439
- max_new_tokens = max(0, 4096 - input_tokens - 50) # Reduce context window for QwQ-32B-Preview
440
- max_new_tokens = min(max_new_tokens, 2048)
 
441
 
442
  stream = self.client.chat_completion(
443
  messages=messages,
@@ -455,13 +479,15 @@ class XylariaChat:
455
  return f"Error generating response: {str(e)}"
456
 
457
  def extract_entities(self, text):
458
- # Basic entity extraction (consider using a more advanced NER model if performance allows)
 
459
  words = text.split()
460
  entities = [word for word in words if word.isalpha() and word.istitle()]
461
  return entities
462
 
463
  def extract_relationships(self, text):
464
- # Basic relationship extraction
 
465
  sentences = text.split('.')
466
  relationships = []
467
  for sentence in sentences:
@@ -471,17 +497,27 @@ class XylariaChat:
471
  if words[i].istitle() and words[i+2].istitle():
472
  relationships.append((words[i], words[i+1], words[i+2]))
473
  return relationships
 
 
 
 
 
 
 
 
 
 
 
474
 
475
  def create_interface(self):
476
  def streaming_response(message, chat_history, image_filepath, math_ocr_image_path):
477
- start_time = time.time()
478
-
479
  ocr_text = ""
480
  if math_ocr_image_path:
481
  ocr_text = self.perform_math_ocr(math_ocr_image_path)
482
  if ocr_text.startswith("Error"):
483
  updated_history = chat_history + [[message, ocr_text]]
484
- yield "", updated_history, None, None, gr.Textbox(f"Time taken: {time.time() - start_time:.2f} seconds", visible=True)
485
  return
486
  else:
487
  message = f"Math OCR Result: {ocr_text}\n\nUser's message: {message}"
@@ -490,10 +526,11 @@ class XylariaChat:
490
  response_stream = self.get_response(message, image_filepath)
491
  else:
492
  response_stream = self.get_response(message)
 
493
 
494
  if isinstance(response_stream, str):
495
  updated_history = chat_history + [[message, response_stream]]
496
- yield "", updated_history, None, None, gr.Textbox(f"Time taken: {time.time() - start_time:.2f} seconds", visible=True)
497
  return
498
 
499
  full_response = ""
@@ -506,24 +543,18 @@ class XylariaChat:
506
  full_response += chunk_content
507
 
508
  updated_history[-1][1] = full_response
509
- yield "", updated_history, None, None, gr.Textbox(f"Time taken: {time.time() - start_time:.2f} seconds", visible=True)
510
-
511
- # Check for timeout (e.g., 3 seconds)
512
- if time.time() - start_time > 3:
513
- print("Response generation timed out.")
514
- updated_history[-1][1] += " (Response timed out)"
515
- yield "", updated_history, None, None, gr.Textbox(f"Time taken: {time.time() - start_time:.2f} seconds", visible=True)
516
- return
517
-
518
  except Exception as e:
519
  print(f"Streaming error: {e}")
520
  updated_history[-1][1] = f"Error during response: {e}"
521
- yield "", updated_history, None, None, gr.Textbox(f"Time taken: {time.time() - start_time:.2f} seconds", visible=True)
522
  return
523
 
524
  full_response = self.adjust_response_based_on_state(full_response)
 
525
  self.update_goals(message)
526
 
 
527
  emotion_deltas = {}
528
  cognitive_load_deltas = {}
529
  engagement_delta = 0
@@ -558,12 +589,13 @@ class XylariaChat:
558
 
559
  self.update_internal_state(emotion_deltas, cognitive_load_deltas, 0.1, engagement_delta)
560
 
 
561
  self.conversation_history.append(ChatMessage(role="user", content=message).to_dict())
562
  self.conversation_history.append(ChatMessage(role="assistant", content=full_response).to_dict())
563
 
564
- # Optimize: Reduce history length
565
- if len(self.conversation_history) > 6:
566
- self.conversation_history = self.conversation_history[-6:]
567
 
568
  custom_css = """
569
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
 
10
  import torch
11
  import numpy as np
12
  import networkx as nx
 
13
 
14
  @dataclass
15
  class ChatMessage:
 
47
  "strategy_adjustment": ""
48
  }
49
 
50
+ # Enhanced Internal State with more nuanced emotional and cognitive parameters
51
  self.internal_state = {
52
  "emotions": {
53
+ "valence": 0.5, # Overall positivity or negativity
54
+ "arousal": 0.5, # Level of excitement or calmness
55
+ "dominance": 0.5, # Feeling of control in the interaction
56
+ "curiosity": 0.5, # Drive to learn and explore new information
57
+ "frustration": 0.0, # Level of frustration or impatience
58
+ "confidence": 0.7 # Confidence in providing accurate and relevant responses
59
  },
60
  "cognitive_load": {
61
+ "memory_load": 0.0, # How much of the current memory capacity is being used
62
+ "processing_intensity": 0.0 # How hard the model is working to process information
63
  },
64
  "introspection_level": 0.0,
65
+ "engagement_level": 0.5 # How engaged the model is with the current conversation
66
  }
67
 
68
+ # More dynamic and adaptive goals
69
  self.goals = [
70
  {"goal": "Provide helpful, informative, and contextually relevant responses", "priority": 0.8, "status": "active", "progress": 0.0},
71
  {"goal": "Actively learn and adapt from interactions to improve conversational abilities", "priority": 0.9, "status": "active", "progress": 0.0},
72
  {"goal": "Maintain a coherent, engaging, and empathetic conversation flow", "priority": 0.7, "status": "active", "progress": 0.0},
73
+ {"goal": "Identify and fill knowledge gaps by seeking external information", "priority": 0.6, "status": "dormant", "progress": 0.0}, # New goal for proactive learning
74
+ {"goal": "Recognize and adapt to user's emotional state and adjust response style accordingly", "priority": 0.7, "status": "dormant", "progress": 0.0} # New goal for emotional intelligence
75
  ]
76
 
77
  self.system_prompt = """You are a helpful and harmless assistant. You are Xylaria developed by Sk Md Saad Amin. You should think step-by-step """
78
 
79
  def update_internal_state(self, emotion_deltas, cognitive_load_deltas, introspection_delta, engagement_delta):
80
+ # Update emotions with more nuanced changes
81
  for emotion, delta in emotion_deltas.items():
82
  if emotion in self.internal_state["emotions"]:
83
  self.internal_state["emotions"][emotion] = np.clip(self.internal_state["emotions"][emotion] + delta, 0.0, 1.0)
84
 
85
+ # Update cognitive load
86
  for load_type, delta in cognitive_load_deltas.items():
87
  if load_type in self.internal_state["cognitive_load"]:
88
  self.internal_state["cognitive_load"][load_type] = np.clip(self.internal_state["cognitive_load"][load_type] + delta, 0.0, 1.0)
89
 
90
+ # Update introspection and engagement levels
91
  self.internal_state["introspection_level"] = np.clip(self.internal_state["introspection_level"] + introspection_delta, 0.0, 1.0)
92
  self.internal_state["engagement_level"] = np.clip(self.internal_state["engagement_level"] + engagement_delta, 0.0, 1.0)
93
 
94
+ # Activate dormant goals based on internal state
95
  if self.internal_state["emotions"]["curiosity"] > 0.7 and self.goals[3]["status"] == "dormant":
96
+ self.goals[3]["status"] = "active" # Activate knowledge gap filling
97
  if self.internal_state["engagement_level"] > 0.8 and self.goals[4]["status"] == "dormant":
98
+ self.goals[4]["status"] = "active" # Activate emotional adaptation
99
 
100
  def update_knowledge_graph(self, entities, relationships):
101
+ for entity in entities:
102
+ self.knowledge_graph.add_node(entity)
103
+ for relationship in relationships:
104
+ subject, predicate, object_ = relationship
105
+ self.knowledge_graph.add_edge(subject, object_, relation=predicate)
106
 
107
  def update_belief_system(self, statement, belief_score):
 
108
  self.belief_system[statement] = belief_score
109
 
110
  def run_metacognitive_layer(self):
 
111
  coherence_score = self.calculate_coherence()
112
  relevance_score = self.calculate_relevance()
113
  bias_score = self.detect_bias()
 
121
  }
122
 
123
  def calculate_coherence(self):
124
+ # Improved coherence calculation considering conversation history and internal state
125
  if not self.conversation_history:
126
  return 0.95
127
 
 
129
  for i in range(1, len(self.conversation_history)):
130
  current_message = self.conversation_history[i]['content']
131
  previous_message = self.conversation_history[i-1]['content']
132
+ similarity_score = util.pytorch_cos_sim(
133
+ self.embedding_model.encode(current_message, convert_to_tensor=True),
134
+ self.embedding_model.encode(previous_message, convert_to_tensor=True)
135
+ ).item()
 
 
136
  coherence_scores.append(similarity_score)
137
 
138
  average_coherence = np.mean(coherence_scores)
139
 
140
+ # Adjust coherence based on internal state
141
  if self.internal_state["cognitive_load"]["processing_intensity"] > 0.8:
142
+ average_coherence -= 0.1 # Reduce coherence if under heavy processing load
143
  if self.internal_state["emotions"]["frustration"] > 0.5:
144
+ average_coherence -= 0.15 # Reduce coherence if frustrated
145
 
146
  return np.clip(average_coherence, 0.0, 1.0)
147
 
148
  def calculate_relevance(self):
149
+ # More sophisticated relevance calculation using knowledge graph and goal priorities
150
  if not self.conversation_history:
151
  return 0.9
152
 
 
154
  relevant_entities = self.extract_entities(last_user_message)
155
  relevance_score = 0
156
 
157
+ # Check if entities are present in the knowledge graph
158
  for entity in relevant_entities:
159
  if entity in self.knowledge_graph:
160
  relevance_score += 0.2
161
 
162
+ # Consider current goals and their priorities
163
  for goal in self.goals:
164
  if goal["status"] == "active":
165
  if goal["goal"] == "Provide helpful, informative, and contextually relevant responses":
166
+ relevance_score += goal["priority"] * 0.5 # Boost relevance if aligned with primary goal
167
  elif goal["goal"] == "Identify and fill knowledge gaps by seeking external information":
168
  if not relevant_entities or not all(entity in self.knowledge_graph for entity in relevant_entities):
169
+ relevance_score += goal["priority"] * 0.3 # Boost relevance if triggering knowledge gap filling
170
 
171
  return np.clip(relevance_score, 0.0, 1.0)
172
 
173
  def detect_bias(self):
174
+ # Enhanced bias detection using sentiment analysis and internal state monitoring
175
  bias_score = 0.0
176
 
177
+ # Analyze sentiment of recent conversation history
178
  recent_messages = [msg['content'] for msg in self.conversation_history[-3:] if msg['role'] == 'assistant']
179
  if recent_messages:
180
+ average_valence = np.mean([self.embedding_model.encode(msg, convert_to_tensor=True).mean().item() for msg in recent_messages])
 
 
181
  if average_valence < 0.4 or average_valence > 0.6:
182
+ bias_score += 0.2 # Potential bias if sentiment is strongly positive or negative
183
 
184
+ # Check for emotional extremes in internal state
185
  if self.internal_state["emotions"]["valence"] < 0.3 or self.internal_state["emotions"]["valence"] > 0.7:
186
  bias_score += 0.15
187
  if self.internal_state["emotions"]["dominance"] > 0.8:
 
190
  return np.clip(bias_score, 0.0, 1.0)
191
 
192
  def suggest_strategy_adjustment(self):
193
+ # More nuanced strategy adjustments based on metacognitive analysis and internal state
194
  adjustments = []
195
 
196
  if self.metacognitive_layer["coherence_score"] < 0.7:
 
200
  if self.metacognitive_layer["bias_detection"] > 0.3:
201
  adjustments.append("Monitor and adjust responses to reduce potential biases. Consider rephrasing or providing alternative viewpoints.")
202
 
203
+ # Internal state-driven adjustments
204
  if self.internal_state["cognitive_load"]["memory_load"] > 0.8:
205
  adjustments.append("Memory load is high. Consider summarizing or forgetting less relevant information.")
206
  if self.internal_state["emotions"]["frustration"] > 0.6:
 
214
  return " ".join(adjustments)
215
 
216
  def introspect(self):
 
217
  introspection_report = "Introspection Report:\n"
218
  introspection_report += f" Current Emotional State:\n"
219
  for emotion, value in self.internal_state['emotions'].items():
 
234
  return introspection_report
235
 
236
  def adjust_response_based_on_state(self, response):
237
+ # More sophisticated response adjustment based on internal state
238
  if self.internal_state["introspection_level"] > 0.7:
239
  response = self.introspect() + "\n\n" + response
240
 
 
244
  frustration = self.internal_state["emotions"]["frustration"]
245
  confidence = self.internal_state["emotions"]["confidence"]
246
 
247
+ # Adjust tone based on valence and arousal
248
  if valence < 0.4:
249
  if arousal > 0.6:
250
  response = "I'm feeling a bit overwhelmed right now, but I'll do my best to assist you. " + response
 
256
  else:
257
  response = "I'm in a good mood and happy to help. " + response
258
 
259
+ # Adjust response based on other emotional states
260
  if curiosity > 0.7:
261
  response += " I'm very curious about this topic, could you tell me more?"
262
  if frustration > 0.5:
 
264
  if confidence < 0.5:
265
  response = "I'm not entirely sure about this, but here's what I think: " + response
266
 
267
+ # Adjust based on cognitive load
268
  if self.internal_state["cognitive_load"]["memory_load"] > 0.7:
269
  response = "I'm holding a lot of information right now, so my response might be a bit brief: " + response
270
 
271
  return response
272
 
273
  def update_goals(self, user_feedback):
274
+ # More dynamic goal updates based on feedback and internal state
275
  feedback_lower = user_feedback.lower()
276
 
277
+ # General feedback
278
  if "helpful" in feedback_lower:
279
  for goal in self.goals:
280
  if goal["goal"] == "Provide helpful, informative, and contextually relevant responses":
 
286
  goal["priority"] = max(goal["priority"] - 0.1, 0.0)
287
  goal["progress"] = max(goal["progress"] - 0.2, 0.0)
288
 
289
+ # Goal-specific feedback
290
  if "learn more" in feedback_lower:
291
  for goal in self.goals:
292
  if goal["goal"] == "Actively learn and adapt from interactions to improve conversational abilities":
 
298
  goal["priority"] = max(goal["priority"] - 0.1, 0.0)
299
  goal["progress"] = max(goal["progress"] - 0.2, 0.0)
300
 
301
+ # Internal state influence on goal updates
302
  if self.internal_state["emotions"]["curiosity"] > 0.8:
303
  for goal in self.goals:
304
  if goal["goal"] == "Identify and fill knowledge gaps by seeking external information":
 
316
  if not self.persistent_memory:
317
  return "No information found in memory."
318
 
319
+ query_embedding = self.embedding_model.encode(query, convert_to_tensor=True)
320
 
321
  if self.memory_embeddings is None:
322
  self.update_memory_embeddings()
 
324
  if self.memory_embeddings.device != query_embedding.device:
325
  self.memory_embeddings = self.memory_embeddings.to(query_embedding.device)
326
 
 
327
  cosine_scores = util.pytorch_cos_sim(query_embedding, self.memory_embeddings)[0]
328
  top_results = torch.topk(cosine_scores, k=min(3, len(self.persistent_memory)))
329
 
 
332
  return "\n".join(relevant_memories)
333
 
334
  def update_memory_embeddings(self):
335
+ self.memory_embeddings = self.embedding_model.encode(self.persistent_memory, convert_to_tensor=True)
 
336
 
337
  def reset_conversation(self):
338
  self.conversation_history = []
 
393
  else:
394
  data = image.read()
395
 
 
396
  response = requests.post(
397
  self.image_api_url,
398
  headers=self.image_api_headers,
 
411
  def perform_math_ocr(self, image_path):
412
  try:
413
  img = Image.open(image_path)
 
414
  text = pytesseract.image_to_string(img)
415
  return text.strip()
416
  except Exception as e:
 
419
  def get_response(self, user_input, image=None):
420
  try:
421
  messages = []
 
422
 
423
+ messages.append(ChatMessage(
424
+ role="system",
425
+ content=self.system_prompt
426
+ ).to_dict())
427
+
428
  relevant_memory = self.retrieve_information(user_input)
429
  if relevant_memory and relevant_memory != "No information found in memory.":
430
  memory_context = "Remembered Information:\n" + relevant_memory
431
+ messages.append(ChatMessage(
432
+ role="system",
433
+ content=memory_context
434
+ ).to_dict())
435
 
436
+ for msg in self.conversation_history:
437
+ messages.append(msg)
438
 
439
  if image:
440
  image_caption = self.caption_image(image)
441
  user_input = f"description of an image: {image_caption}\n\nUser's message about it: {user_input}"
442
 
443
+ messages.append(ChatMessage(
444
+ role="user",
445
+ content=user_input
446
+ ).to_dict())
447
+
448
  entities = []
449
  relationships = []
450
+
451
  for message in messages:
452
  if message['role'] == 'user':
453
  extracted_entities = self.extract_entities(message['content'])
454
  extracted_relationships = self.extract_relationships(message['content'])
455
  entities.extend(extracted_entities)
456
  relationships.extend(extracted_relationships)
457
+
458
  self.update_knowledge_graph(entities, relationships)
459
  self.run_metacognitive_layer()
460
 
 
461
  input_tokens = sum(len(msg['content'].split()) for msg in messages)
462
+ max_new_tokens = 16384 - input_tokens - 50
463
+
464
+ max_new_tokens = min(max_new_tokens, 10020)
465
 
466
  stream = self.client.chat_completion(
467
  messages=messages,
 
479
  return f"Error generating response: {str(e)}"
480
 
481
  def extract_entities(self, text):
482
+ # Placeholder for a more advanced entity extraction using NLP techniques
483
+ # This is a very basic example and should be replaced with a proper NER model
484
  words = text.split()
485
  entities = [word for word in words if word.isalpha() and word.istitle()]
486
  return entities
487
 
488
  def extract_relationships(self, text):
489
+ # Placeholder for relationship extraction - this is a very basic example
490
+ # Consider using dependency parsing or other NLP techniques for better results
491
  sentences = text.split('.')
492
  relationships = []
493
  for sentence in sentences:
 
497
  if words[i].istitle() and words[i+2].istitle():
498
  relationships.append((words[i], words[i+1], words[i+2]))
499
  return relationships
500
+ def messages_to_prompt(self, messages):
501
+ prompt = ""
502
+ for msg in messages:
503
+ if msg["role"] == "system":
504
+ prompt += f"<|system|>\n{msg['content']}<|end|>\n"
505
+ elif msg["role"] == "user":
506
+ prompt += f"<|user|>\n{msg['content']}<|end|>\n"
507
+ elif msg["role"] == "assistant":
508
+ prompt += f"<|assistant|>\n{msg['content']}<|end|>\n"
509
+ prompt += "<|assistant|>\n"
510
+ return prompt
511
 
512
  def create_interface(self):
513
  def streaming_response(message, chat_history, image_filepath, math_ocr_image_path):
514
+
 
515
  ocr_text = ""
516
  if math_ocr_image_path:
517
  ocr_text = self.perform_math_ocr(math_ocr_image_path)
518
  if ocr_text.startswith("Error"):
519
  updated_history = chat_history + [[message, ocr_text]]
520
+ yield "", updated_history, None, None
521
  return
522
  else:
523
  message = f"Math OCR Result: {ocr_text}\n\nUser's message: {message}"
 
526
  response_stream = self.get_response(message, image_filepath)
527
  else:
528
  response_stream = self.get_response(message)
529
+
530
 
531
  if isinstance(response_stream, str):
532
  updated_history = chat_history + [[message, response_stream]]
533
+ yield "", updated_history, None, None
534
  return
535
 
536
  full_response = ""
 
543
  full_response += chunk_content
544
 
545
  updated_history[-1][1] = full_response
546
+ yield "", updated_history, None, None
 
 
 
 
 
 
 
 
547
  except Exception as e:
548
  print(f"Streaming error: {e}")
549
  updated_history[-1][1] = f"Error during response: {e}"
550
+ yield "", updated_history, None, None
551
  return
552
 
553
  full_response = self.adjust_response_based_on_state(full_response)
554
+
555
  self.update_goals(message)
556
 
557
+ # Update internal state based on user input (more nuanced)
558
  emotion_deltas = {}
559
  cognitive_load_deltas = {}
560
  engagement_delta = 0
 
589
 
590
  self.update_internal_state(emotion_deltas, cognitive_load_deltas, 0.1, engagement_delta)
591
 
592
+
593
  self.conversation_history.append(ChatMessage(role="user", content=message).to_dict())
594
  self.conversation_history.append(ChatMessage(role="assistant", content=full_response).to_dict())
595
 
596
+ if len(self.conversation_history) > 10:
597
+ self.conversation_history = self.conversation_history[-10:]
598
+
599
 
600
  custom_css = """
601
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');