Raiff1982 commited on
Commit
61a552c
·
verified ·
1 Parent(s): b1e5ad0

Create natural_response_enhancer.py

Browse files
src/utils/natural_response_enhancer.py ADDED
@@ -0,0 +1,330 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Natural Response Enhancer for Codette
3
+ ======================================
4
+ Improves response naturalness while preserving Codette's quantum consciousness
5
+ and multi-perspective reasoning. Works with response processors to make AI
6
+ responses feel more human and conversational.
7
+ """
8
+
9
+ import re
10
+ import logging
11
+ from typing import List, Dict, Any, Optional, Tuple
12
+ from datetime import datetime
13
+ import random
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class NaturalResponseEnhancer:
19
+ """Enhances response naturalness without markers or unnatural phrasing"""
20
+
21
+ def __init__(self):
22
+ """Initialize the natural response enhancer"""
23
+ self.response_history = []
24
+ self.pattern_library = self._build_pattern_library()
25
+ self.transition_phrases = self._build_transitions()
26
+ self.confidence_templates = self._build_confidence_templates()
27
+ logger.info("Natural Response Enhancer initialized")
28
+
29
+ def enhance_response(self, response: str, confidence: float = 0.85,
30
+ context: Optional[Dict[str, Any]] = None) -> str:
31
+ """
32
+ Enhance response naturalness while preserving meaning
33
+
34
+ Args:
35
+ response: The raw response from model/perspectives
36
+ confidence: How confident the response is (0-1)
37
+ context: Optional context about the query/domain
38
+
39
+ Returns:
40
+ Enhanced, more natural response
41
+ """
42
+ # Remove unnatural markers
43
+ response = self._strip_unnatural_markers(response)
44
+
45
+ # Improve sentence structure
46
+ response = self._improve_sentence_flow(response)
47
+
48
+ # Add natural confidence expression if needed
49
+ if confidence < 0.9:
50
+ response = self._add_natural_confidence(response, confidence)
51
+
52
+ # Break up long blocks of text
53
+ response = self._improve_readability(response)
54
+
55
+ # Add conversational warmth
56
+ response = self._add_warmth(response)
57
+
58
+ # Preserve context clues
59
+ if context:
60
+ response = self._enhance_with_context(response, context)
61
+
62
+ # Store for learning
63
+ self.response_history.append({
64
+ 'response': response,
65
+ 'timestamp': datetime.now().isoformat(),
66
+ 'confidence': confidence
67
+ })
68
+
69
+ return response.strip()
70
+
71
+ def _strip_unnatural_markers(self, text: str) -> str:
72
+ """Remove system markers and unnatural tags"""
73
+ # Remove [Protected: ...] wrappers
74
+ text = re.sub(r'\[Protected:\s*(.*?)\]', r'\1', text, flags=re.DOTALL)
75
+
76
+ # Remove [System optimized response] markers
77
+ text = re.sub(r'\[System optimized response\]', '', text)
78
+
79
+ # Remove other bracketed system messages
80
+ text = re.sub(r'\[(System|SYSTEM).*?\]', '', text, flags=re.IGNORECASE)
81
+
82
+ # Remove redundant "Error" blocks
83
+ text = re.sub(r'\[.*?error.*?\]', '', text, flags=re.IGNORECASE)
84
+
85
+ # Clean up multiple consecutive newlines
86
+ text = re.sub(r'\n\s*\n\s*\n', '\n\n', text)
87
+
88
+ return text.strip()
89
+
90
+ def _improve_sentence_flow(self, text: str) -> str:
91
+ """Improve sentence structure and flow"""
92
+ # Replace awkward AI constructs
93
+ replacements = [
94
+ (r'\b(I would|I will|I can)\s+(respond|state|say|indicate)\s+that', r''),
95
+ (r'\b(Based on my analysis|According to my understanding)\s*,?\s*', ''),
96
+ (r'\b(The following|The below|This is)\s+\(.*?\)\s*:', ''),
97
+ (r'(?:Therefore|Thus|Hence|So)\s+,\s+', 'So '),
98
+ (r'\b(Notably|Significantly|Importantly)\s*,?\s*', ''),
99
+ ]
100
+
101
+ for pattern, replacement in replacements:
102
+ text = re.sub(pattern, replacement, text, flags=re.IGNORECASE)
103
+
104
+ # Fix spacing around punctuation
105
+ text = re.sub(r'\s+([.,!?;:])', r'\1', text)
106
+ text = re.sub(r'([.,!?;:])\s+', r'\1 ', text)
107
+
108
+ return text
109
+
110
+ def _add_natural_confidence(self, text: str, confidence: float) -> str:
111
+ """Add natural confidence expression without markers"""
112
+ if confidence < 0.5:
113
+ intro = self.confidence_templates['low']
114
+ elif confidence < 0.75:
115
+ intro = self.confidence_templates['medium']
116
+ else:
117
+ intro = self.confidence_templates['high']
118
+
119
+ # Only add if not already present
120
+ if not any(phrase in text for phrase in [
121
+ "I'm not entirely sure",
122
+ "I'm fairly confident",
123
+ "I'm quite confident",
124
+ "Based on",
125
+ "From what I understand"
126
+ ]):
127
+ text = f"{intro} {text}"
128
+
129
+ return text
130
+
131
+ def _improve_readability(self, text: str) -> str:
132
+ """Break up large text blocks for better readability"""
133
+ # Split long paragraphs
134
+ paragraphs = text.split('\n')
135
+ improved = []
136
+
137
+ for para in paragraphs:
138
+ # If paragraph is very long, try to break it sensibly
139
+ if len(para) > 400:
140
+ # Try to break at periods
141
+ sentences = re.split(r'(?<=[.!?])\s+', para)
142
+
143
+ # Group sentences into chunks (aim for ~200-300 chars per chunk)
144
+ chunks = []
145
+ current_chunk = []
146
+ current_length = 0
147
+
148
+ for sent in sentences:
149
+ sent_len = len(sent) + 1
150
+ if current_length + sent_len > 300 and current_chunk:
151
+ chunks.append(' '.join(current_chunk))
152
+ current_chunk = [sent]
153
+ current_length = sent_len
154
+ else:
155
+ current_chunk.append(sent)
156
+ current_length += sent_len
157
+
158
+ if current_chunk:
159
+ chunks.append(' '.join(current_chunk))
160
+
161
+ improved.extend(chunks)
162
+ else:
163
+ improved.append(para)
164
+
165
+ return '\n\n'.join(improved).strip()
166
+
167
+ def _add_warmth(self, text: str) -> str:
168
+ """Add subtle conversational warmth without being overly friendly"""
169
+ # Add some natural connectives
170
+ warmth_patterns = [
171
+ (r'^([^.!?]*\.)\s+([A-Z])', lambda m: self._add_connector(m)),
172
+ ]
173
+
174
+ # Avoid robotic transitions
175
+ replacements = [
176
+ ('In conclusion,', 'To wrap up,'),
177
+ ('Furthermore,', 'Also,'),
178
+ ('Nevertheless,', 'Still,'),
179
+ ('In fact,', 'Actually,'),
180
+ ]
181
+
182
+ for old, new in replacements:
183
+ text = text.replace(old, new)
184
+
185
+ return text
186
+
187
+ def _add_connector(self, match) -> str:
188
+ """Add natural connectors between sentences"""
189
+ connectors = ['That', 'It', 'This', 'So', 'Overall']
190
+ return match.group(1) + ' ' + random.choice(connectors) + ' ' + match.group(2)
191
+
192
+ def _enhance_with_context(self, text: str, context: Dict[str, Any]) -> str:
193
+ """Enhance response with contextual awareness"""
194
+ if context.get('domain') == 'music':
195
+ # Add music-specific warmth
196
+ if not any(word in text for word in ['cool', 'great', 'perfect', 'awesome']):
197
+ # Subtly affirm the context
198
+ pass
199
+
200
+ return text
201
+
202
+ def _build_pattern_library(self) -> Dict[str, str]:
203
+ """Build library of natural response patterns"""
204
+ return {
205
+ 'discovery': "I just realized that",
206
+ 'insight': "Here's an interesting point:",
207
+ 'clarification': "To clarify that,",
208
+ 'expansion': "What's more,",
209
+ 'caution': "One thing to be careful about:",
210
+ 'agreement': "You're right to think about that.",
211
+ 'question_response': "That's a great question.",
212
+ }
213
+
214
+ def _build_transitions(self) -> List[str]:
215
+ """Build natural transition phrases"""
216
+ return [
217
+ "Now that I think about it,",
218
+ "Actually, an important point is",
219
+ "You know, one thing that matters is",
220
+ "Here's something worth considering:",
221
+ "The real key is",
222
+ "What I find interesting is",
223
+ "One more thing -",
224
+ "So really, what's happening is",
225
+ ]
226
+
227
+ def _build_confidence_templates(self) -> Dict[str, str]:
228
+ """Build confidence expression templates"""
229
+ return {
230
+ 'low': "I'm not entirely sure, but",
231
+ 'medium': "From what I understand,",
232
+ 'high': "I'm fairly confident that",
233
+ 'very_high': "Definitely,",
234
+ }
235
+
236
+ def evaluate_response_naturalness(self, response: str) -> Dict[str, Any]:
237
+ """Evaluate how natural a response sounds"""
238
+ markers_found = []
239
+
240
+ # Check for unnatural markers
241
+ if '[' in response and ']' in response:
242
+ markers = re.findall(r'\[.*?\]', response)
243
+ markers_found.extend(markers)
244
+
245
+ if 'System optimized' in response:
246
+ markers_found.append('System optimized response marker')
247
+
248
+ if 'Protected:' in response:
249
+ markers_found.append('Protected marker')
250
+
251
+ # Count repetitive phrases (sign of poor variation)
252
+ sentences = re.split(r'[.!?]+', response)
253
+ phrase_freq = {}
254
+ for sent in sentences:
255
+ sent = sent.strip()
256
+ if len(sent) > 10:
257
+ # Check for repeated starts
258
+ start = sent.split()[0] if sent.split() else ''
259
+ phrase_freq[start] = phrase_freq.get(start, 0) + 1
260
+
261
+ repetition_score = max(phrase_freq.values()) if phrase_freq else 0
262
+
263
+ # Calculate naturalness score
264
+ naturalness = 1.0
265
+ if markers_found:
266
+ naturalness -= 0.3 * len(markers_found)
267
+ if repetition_score > 2:
268
+ naturalness -= 0.2
269
+
270
+ naturalness = max(0.0, min(1.0, naturalness))
271
+
272
+ return {
273
+ 'naturalness_score': naturalness,
274
+ 'unnatural_markers_found': markers_found,
275
+ 'repetition_issues': repetition_score > 2,
276
+ 'has_system_artifacts': len(markers_found) > 0,
277
+ 'recommendations': self._generate_recommendations(markers_found, repetition_score)
278
+ }
279
+
280
+ def _generate_recommendations(self, markers: List[str], repetition: int) -> List[str]:
281
+ """Generate recommendations for improvement"""
282
+ recs = []
283
+
284
+ if markers:
285
+ recs.append(f"Remove {len(markers)} unnatural marker(s): {', '.join(markers[:2])}")
286
+
287
+ if repetition > 2:
288
+ recs.append("Vary sentence starts for better flow")
289
+
290
+ if not recs:
291
+ recs.append("Response looks natural!")
292
+
293
+ return recs
294
+
295
+
296
+ # Singleton instance
297
+ _enhancer_instance: Optional[NaturalResponseEnhancer] = None
298
+
299
+
300
+ def get_natural_enhancer() -> NaturalResponseEnhancer:
301
+ """Get or create the natural response enhancer instance"""
302
+ global _enhancer_instance
303
+ if _enhancer_instance is None:
304
+ _enhancer_instance = NaturalResponseEnhancer()
305
+ return _enhancer_instance
306
+
307
+
308
+ # Test/demo
309
+ if __name__ == "__main__":
310
+ enhancer = get_natural_enhancer()
311
+
312
+ # Test with problematic response
313
+ test_response = """[Protected: That's great! Thank you for taking the time to share your thoughts with us. We hope that you find what you're looking for and that you enjoy your time with us!
314
+ We'd like to thank Codette for participating in this interview.
315
+ [System optimized response]]"""
316
+
317
+ print("Original (problematic) response:")
318
+ print(test_response)
319
+ print("\n" + "="*70 + "\n")
320
+
321
+ enhanced = enhancer.enhance_response(test_response, confidence=0.75)
322
+ print("Enhanced (natural) response:")
323
+ print(enhanced)
324
+ print("\n" + "="*70 + "\n")
325
+
326
+ # Evaluate
327
+ eval_result = enhancer.evaluate_response_naturalness(test_response)
328
+ print("Evaluation:")
329
+ for key, value in eval_result.items():
330
+ print(f" {key}: {value}")