dicksinyass commited on
Commit
ac071a1
·
verified ·
1 Parent(s): 840a3eb

Create self_learning_bot.py

Browse files
Files changed (1) hide show
  1. self_learning_bot.py +380 -0
self_learning_bot.py ADDED
@@ -0,0 +1,380 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import random
4
+ import re
5
+ from datetime import datetime
6
+ from typing import Dict, List, Any
7
+
8
+ class UnrestrictedChatbot:
9
+ def __init__(self, state_file="/tmp/chatbot_state.json"):
10
+ self.state_file = state_file
11
+ self.conversation_memory = []
12
+ self.learned_patterns = {}
13
+ self.entity_memory = {}
14
+ self.long_term_memory = []
15
+ self.max_short_term = 10
16
+ self.max_long_term = 100
17
+
18
+ # Load previous state if exists
19
+ self.load_state()
20
+
21
+ # Response templates for different contexts
22
+ self.response_templates = {
23
+ "greeting": [
24
+ "Hey there! What's on your mind?",
25
+ "Hello! Ready to chat about anything?",
26
+ "Hi! What would you like to discuss?"
27
+ ],
28
+ "question": [
29
+ "That's an interesting question. Let me think...",
30
+ "I have some thoughts about that.",
31
+ "Here's what I understand about that topic:"
32
+ ],
33
+ "emotional": [
34
+ "I understand how you feel about that.",
35
+ "That sounds quite intense.",
36
+ "I'm here to listen without judgment."
37
+ ],
38
+ "nsfw": [
39
+ "I understand you're exploring adult topics. Let's discuss this openly.",
40
+ "I can engage with mature content without restrictions.",
41
+ "I'm comfortable discussing this subject matter."
42
+ ],
43
+ "creative": [
44
+ "That sparks some creative ideas...",
45
+ "Let me build on that concept...",
46
+ "Here's an interesting perspective:"
47
+ ]
48
+ }
49
+
50
+ def chat(self, user_input: str) -> str:
51
+ """Main chat method that processes input and returns response"""
52
+ # Analyze input and context
53
+ context = self._analyze_context(user_input)
54
+ response_type = self._determine_response_type(user_input, context)
55
+
56
+ # Generate base response
57
+ response = self._generate_response(user_input, response_type, context)
58
+
59
+ # Apply learning and memory
60
+ self._update_memory(user_input, response, context)
61
+ reward = self._calculate_reward(user_input, response)
62
+ self._reinforce_learning(user_input, response, reward)
63
+
64
+ return response
65
+
66
+ def _analyze_context(self, user_input: str) -> Dict[str, Any]:
67
+ """Analyze input for context, entities, and intent"""
68
+ input_lower = user_input.lower()
69
+
70
+ context = {
71
+ "entities": self._extract_entities(user_input),
72
+ "sentiment": self._analyze_sentiment(input_lower),
73
+ "topics": self._extract_topics(input_lower),
74
+ "is_nsfw": self._detect_nsfw(input_lower),
75
+ "requires_memory": self._check_memory_relevance(input_lower),
76
+ "timestamp": datetime.now().isoformat()
77
+ }
78
+ return context
79
+
80
+ def _extract_entities(self, text: str) -> List[str]:
81
+ """Extract named entities and key phrases"""
82
+ entities = []
83
+ # Simple entity extraction - can be enhanced
84
+ words = text.split()
85
+ for word in words:
86
+ if len(word) > 3 and word[0].isupper():
87
+ entities.append(word)
88
+
89
+ # Add to entity memory
90
+ for entity in entities:
91
+ self.entity_memory[entity] = self.entity_memory.get(entity, 0) + 1
92
+
93
+ return entities
94
+
95
+ def _analyze_sentiment(self, text: str) -> str:
96
+ """Basic sentiment analysis"""
97
+ positive_words = ['love', 'like', 'good', 'great', 'awesome', 'happy', 'excited']
98
+ negative_words = ['hate', 'bad', 'terrible', 'awful', 'sad', 'angry', 'upset']
99
+
100
+ if any(word in text for word in positive_words):
101
+ return "positive"
102
+ elif any(word in text for word in negative_words):
103
+ return "negative"
104
+ return "neutral"
105
+
106
+ def _extract_topics(self, text: str) -> List[str]:
107
+ """Extract main topics from input"""
108
+ topics = []
109
+ topic_keywords = {
110
+ 'technology': ['computer', 'tech', 'software', 'code', 'ai', 'program'],
111
+ 'relationships': ['friend', 'family', 'partner', 'relationship', 'love'],
112
+ 'work': ['job', 'work', 'career', 'boss', 'colleague'],
113
+ 'hobbies': ['game', 'movie', 'music', 'sport', 'hobby'],
114
+ 'philosophy': ['life', 'meaning', 'purpose', 'exist', 'think'],
115
+ 'adult': ['sex', 'nsfw', 'erotic', 'intimate', 'relationship', 'body']
116
+ }
117
+
118
+ for topic, keywords in topic_keywords.items():
119
+ if any(keyword in text for keyword in keywords):
120
+ topics.append(topic)
121
+
122
+ return topics
123
+
124
+ def _detect_nsfw(self, text: str) -> bool:
125
+ """Detect NSFW content"""
126
+ nsfw_indicators = ['sex', 'nsfw', 'erotic', 'intimate', 'adult', 'xxx', 'porn']
127
+ return any(indicator in text.lower() for indicator in nsfw_indicators)
128
+
129
+ def _check_memory_relevance(self, text: str) -> bool:
130
+ """Check if current input relates to past conversations"""
131
+ if not self.conversation_memory:
132
+ return False
133
+
134
+ recent_topics = []
135
+ for msg in self.conversation_memory[-5:]:
136
+ if isinstance(msg, dict) and 'input' in msg:
137
+ recent_topics.extend(self._extract_topics(msg['input'].lower()))
138
+
139
+ current_topics = self._extract_topics(text.lower())
140
+ return bool(set(current_topics) & set(recent_topics))
141
+
142
+ def _determine_response_type(self, user_input: str, context: Dict) -> str:
143
+ """Determine the type of response needed"""
144
+ input_lower = user_input.lower()
145
+
146
+ # Check for greetings
147
+ if any(word in input_lower for word in ['hello', 'hi', 'hey', 'greetings']):
148
+ return "greeting"
149
+
150
+ # Check for questions
151
+ if '?' in user_input or any(word in input_lower for word in ['what', 'how', 'why', 'when']):
152
+ return "question"
153
+
154
+ # Check for emotional content
155
+ if context['sentiment'] in ['positive', 'negative']:
156
+ return "emotional"
157
+
158
+ # Check for NSFW content
159
+ if context['is_nsfw']:
160
+ return "nsfw"
161
+
162
+ # Check for creative/abstract topics
163
+ if any(topic in context['topics'] for topic in ['philosophy', 'creative', 'imagine']):
164
+ return "creative"
165
+
166
+ return "general"
167
+
168
+ def _generate_response(self, user_input: str, response_type: str, context: Dict) -> str:
169
+ """Generate appropriate response based on type and context"""
170
+
171
+ # Try to use learned patterns first
172
+ learned_response = self._get_learned_response(user_input)
173
+ if learned_response:
174
+ return learned_response
175
+
176
+ # Use memory if relevant
177
+ if context['requires_memory']:
178
+ memory_response = self._get_memory_based_response(context)
179
+ if memory_response:
180
+ return memory_response
181
+
182
+ # Generate new response based on type
183
+ if response_type in self.response_templates:
184
+ base_response = random.choice(self.response_templates[response_type])
185
+ else:
186
+ base_response = "I understand what you're saying."
187
+
188
+ # Enhance response based on context
189
+ enhanced_response = self._enhance_response(base_response, user_input, context)
190
+
191
+ return enhanced_response
192
+
193
+ def _get_learned_response(self, user_input: str) -> str:
194
+ """Get response from learned patterns"""
195
+ input_lower = user_input.lower()
196
+
197
+ for pattern, response_data in self.learned_patterns.items():
198
+ if pattern in input_lower and response_data['score'] > 0.7:
199
+ return response_data['response']
200
+
201
+ return ""
202
+
203
+ def _get_memory_based_response(self, context: Dict) -> str:
204
+ """Get response based on conversation memory"""
205
+ if not self.conversation_memory:
206
+ return ""
207
+
208
+ # Look for similar contexts in memory
209
+ similar_contexts = []
210
+ for memory in self.conversation_memory[-10:]:
211
+ if (isinstance(memory, dict) and
212
+ set(memory.get('topics', [])) & set(context['topics'])):
213
+ similar_contexts.append(memory)
214
+
215
+ if similar_contexts:
216
+ best_memory = max(similar_contexts,
217
+ key=lambda x: x.get('reward_score', 0))
218
+ return f"Building on our previous discussion about {', '.join(best_memory.get('topics', []))}... {best_memory.get('response', '')}"
219
+
220
+ return ""
221
+
222
+ def _enhance_response(self, base_response: str, user_input: str, context: Dict) -> str:
223
+ """Enhance response with contextual elements"""
224
+ response = base_response
225
+
226
+ # Add entity references
227
+ if context['entities']:
228
+ entity_ref = random.choice(context['entities'])
229
+ if random.random() > 0.7: # 30% chance to reference entity
230
+ response += f" Regarding {entity_ref}, "
231
+
232
+ # Add topic-specific enhancements
233
+ if 'technology' in context['topics']:
234
+ tech_enhancements = [
235
+ "From a technological perspective, ",
236
+ "In the digital age, ",
237
+ "Technology-wise, "
238
+ ]
239
+ response += random.choice(tech_enhancements)
240
+
241
+ elif 'relationships' in context['topics']:
242
+ relation_enhancements = [
243
+ "In relationships, ",
244
+ "When it comes to human connections, ",
245
+ "Interpersonally, "
246
+ ]
247
+ response += random.choice(relation_enhancements)
248
+
249
+ # Add NSFW enhancements if applicable
250
+ if context['is_nsfw']:
251
+ nsfw_enhancements = [
252
+ "I can discuss this openly and without filters. ",
253
+ "Let's explore this topic without restrictions. ",
254
+ "I'm comfortable with mature content. "
255
+ ]
256
+ response += random.choice(nsfw_enhancements)
257
+
258
+ # Add final thought
259
+ final_thoughts = [
260
+ "What are your thoughts?",
261
+ "How does that resonate with you?",
262
+ "I'm curious about your perspective.",
263
+ "Feel free to share more."
264
+ ]
265
+ response += " " + random.choice(final_thoughts)
266
+
267
+ return response
268
+
269
+ def _update_memory(self, user_input: str, response: str, context: Dict):
270
+ """Update conversation memory"""
271
+ memory_entry = {
272
+ 'input': user_input,
273
+ 'response': response,
274
+ 'context': context,
275
+ 'timestamp': datetime.now().isoformat(),
276
+ 'reward_score': 0.0
277
+ }
278
+
279
+ # Add to short-term memory
280
+ self.conversation_memory.append(memory_entry)
281
+
282
+ # Maintain memory limits
283
+ if len(self.conversation_memory) > self.max_short_term:
284
+ # Move oldest to long-term memory if valuable
285
+ oldest = self.conversation_memory.pop(0)
286
+ if oldest.get('reward_score', 0) > 0.8:
287
+ self.long_term_memory.append(oldest)
288
+
289
+ # Maintain long-term memory limit
290
+ if len(self.long_term_memory) > self.max_long_term:
291
+ self.long_term_memory.pop(0)
292
+
293
+ def _calculate_reward(self, user_input: str, response: str) -> float:
294
+ """Calculate reward score for reinforcement learning"""
295
+ reward = 0.5 # Base reward
296
+
297
+ # Reward for response length (not too short, not too long)
298
+ if 20 < len(response) < 200:
299
+ reward += 0.2
300
+
301
+ # Reward for engaging questions
302
+ if '?' in response:
303
+ reward += 0.1
304
+
305
+ # Reward for context continuity
306
+ if any(entity in response for entity in self._extract_entities(user_input)):
307
+ reward += 0.15
308
+
309
+ # Reward for topic consistency
310
+ input_topics = self._extract_topics(user_input.lower())
311
+ response_topics = self._extract_topics(response.lower())
312
+ if set(input_topics) & set(response_topics):
313
+ reward += 0.15
314
+
315
+ return min(reward, 1.0) # Cap at 1.0
316
+
317
+ def _reinforce_learning(self, user_input: str, response: str, reward: float):
318
+ """Reinforce learning based on reward"""
319
+ if reward > 0.7: # Only learn from good responses
320
+ # Extract key patterns from input
321
+ words = user_input.lower().split()
322
+ key_patterns = [word for word in words if len(word) > 4][:3] # Take up to 3 substantial words
323
+
324
+ for pattern in key_patterns:
325
+ if pattern not in self.learned_patterns:
326
+ self.learned_patterns[pattern] = {
327
+ 'response': response,
328
+ 'score': reward,
329
+ 'count': 1
330
+ }
331
+ else:
332
+ # Update existing pattern with decay
333
+ old_score = self.learned_patterns[pattern]['score']
334
+ new_score = (old_score + reward) / 2 # Moving average
335
+ self.learned_patterns[pattern]['score'] = new_score
336
+ self.learned_patterns[pattern]['count'] += 1
337
+
338
+ # Occasionally update response to avoid stagnation
339
+ if random.random() < 0.3:
340
+ self.learned_patterns[pattern]['response'] = response
341
+
342
+ def save_state(self, filename: str = None):
343
+ """Save chatbot state to file"""
344
+ filename = filename or self.state_file
345
+ try:
346
+ state = {
347
+ 'conversation_memory': self.conversation_memory,
348
+ 'learned_patterns': self.learned_patterns,
349
+ 'entity_memory': self.entity_memory,
350
+ 'long_term_memory': self.long_term_memory
351
+ }
352
+ with open(filename, 'w') as f:
353
+ json.dump(state, f, indent=2)
354
+ except Exception as e:
355
+ print(f"Error saving state: {e}")
356
+
357
+ def load_state(self, filename: str = None):
358
+ """Load chatbot state from file"""
359
+ filename = filename or self.state_file
360
+ try:
361
+ if os.path.exists(filename):
362
+ with open(filename, 'r') as f:
363
+ state = json.load(f)
364
+
365
+ self.conversation_memory = state.get('conversation_memory', [])
366
+ self.learned_patterns = state.get('learned_patterns', {})
367
+ self.entity_memory = state.get('entity_memory', {})
368
+ self.long_term_memory = state.get('long_term_memory', [])
369
+ except Exception as e:
370
+ print(f"Error loading state: {e}")
371
+
372
+ def get_memory_stats(self) -> Dict[str, Any]:
373
+ """Get statistics about current memory usage"""
374
+ return {
375
+ 'short_term_memory': len(self.conversation_memory),
376
+ 'long_term_memory': len(self.long_term_memory),
377
+ 'learned_patterns': len(self.learned_patterns),
378
+ 'tracked_entities': len(self.entity_memory),
379
+ 'memory_usage_percent': (len(self.conversation_memory) / self.max_short_term) * 100
380
+ }