Raiff1982 commited on
Commit
0ad7bd8
·
verified ·
1 Parent(s): 93fe138

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +416 -0
app.py ADDED
@@ -0,0 +1,416 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import hashlib
4
+ import numpy as np
5
+ from collections import defaultdict
6
+ from datetime import datetime, timedelta
7
+ import filelock
8
+ import pathlib
9
+ import shutil
10
+ import sqlite3
11
+ from rapidfuzz import fuzz
12
+ import unittest
13
+ import secrets
14
+ import re
15
+ import nltk
16
+ from nltk.tokenize import word_tokenize
17
+ from nltk.stem import WordNetLemmatizer
18
+ import logging
19
+ import time
20
+ from tenacity import retry, stop_after_attempt, wait_exponential
21
+ from concurrent.futures import ThreadPoolExecutor
22
+ import gradio as gr
23
+
24
+ # Download required NLTK data
25
+ try:
26
+ nltk.data.find('tokenizers/punkt')
27
+ nltk.data.find('corpora/wordnet')
28
+ except LookupError:
29
+ nltk.download('punkt')
30
+ nltk.download('wordnet')
31
+
32
+ # Set up logging
33
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
34
+ logger = logging.getLogger(__name__)
35
+
36
+ class LockManager:
37
+ """Abstract locking mechanism for file or database operations."""
38
+ def __init__(self, lock_path):
39
+ self.lock = filelock.FileLock(lock_path, timeout=10)
40
+
41
+ def __enter__(self):
42
+ self.lock.acquire()
43
+ return self
44
+
45
+ def __exit__(self, exc_type, exc_val, exc_tb):
46
+ self.lock.release()
47
+
48
+ class NexisSignalEngine:
49
+ def __init__(self, memory_path, entropy_threshold=0.08, config_path="config.json", max_memory_entries=10000, memory_ttl_days=30, fuzzy_threshold=80, max_db_size_mb=100):
50
+ """
51
+ Initialize the NexisSignalEngine for signal processing and analysis.
52
+ """
53
+ self.memory_path = self._validate_path(memory_path)
54
+ self.entropy_threshold = entropy_threshold
55
+ self.max_memory_entries = max_memory_entries
56
+ self.memory_ttl = timedelta(days=memory_ttl_days)
57
+ self.fuzzy_threshold = fuzzy_threshold
58
+ self.max_db_size_mb = max_db_size_mb
59
+ self.lemmatizer = WordNetLemmatizer()
60
+ self.token_cache = {}
61
+ self.config = self._load_config(config_path)
62
+ self.memory = self._load_memory()
63
+ self.cache = defaultdict(list)
64
+ self.perspectives = ["Colleen", "Luke", "Kellyanne"]
65
+ self._init_sqlite()
66
+
67
+ def _validate_path(self, path):
68
+ path = pathlib.Path(path).resolve()
69
+ if not path.suffix == '.db':
70
+ raise ValueError("Memory path must be a .db file")
71
+ return str(path)
72
+
73
+ def _load_config(self, config_path):
74
+ default_config = {
75
+ "ethical_terms": ["hope", "truth", "resonance", "repair"],
76
+ "entropic_terms": ["corruption", "instability", "malice", "chaos"],
77
+ "risk_terms": ["manipulate", "exploit", "bypass", "infect", "override"],
78
+ "virtue_terms": ["hope", "grace", "resolve"]
79
+ }
80
+ if os.path.exists(config_path):
81
+ try:
82
+ with open(config_path, 'r') as f:
83
+ config = json.load(f)
84
+ default_config.update(config)
85
+ except json.JSONDecodeError:
86
+ logger.warning(f"Invalid config file at {config_path}. Using defaults.")
87
+ required_keys = ["ethical_terms", "entropic_terms", "risk_terms", "virtue_terms"]
88
+ missing_keys = [k for k in required_keys if k not in default_config or not default_config[k]]
89
+ if missing_keys:
90
+ raise ValueError(f"Config missing required keys: {missing_keys}")
91
+ return default_config
92
+
93
+ def _init_sqlite(self):
94
+ with sqlite3.connect(self.memory_path) as conn:
95
+ conn.execute("""
96
+ CREATE TABLE IF NOT EXISTS memory (
97
+ hash TEXT PRIMARY KEY,
98
+ record JSON,
99
+ timestamp TEXT,
100
+ integrity_hash TEXT
101
+ )
102
+ """)
103
+ conn.execute("""
104
+ CREATE VIRTUAL TABLE IF NOT EXISTS memory_fts
105
+ USING FTS5(input, intent_signature, reasoning, verdict)
106
+ """)
107
+ conn.commit()
108
+
109
+ @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=10))
110
+ def _load_memory(self):
111
+ memory = {}
112
+ try:
113
+ with sqlite3.connect(self.memory_path) as conn:
114
+ cursor = conn.cursor()
115
+ cursor.execute("SELECT hash, record, integrity_hash FROM memory")
116
+ for hash_val, record_json, integrity_hash in cursor.fetchall():
117
+ record = json.loads(record_json)
118
+ computed_hash = hashlib.sha256(json.dumps(record, sort_keys=True).encode()).hexdigest()
119
+ if computed_hash != integrity_hash:
120
+ logger.warning(f"Tampered record detected for hash {hash_val}")
121
+ continue
122
+ memory[hash_val] = record
123
+ except sqlite3.Error as e:
124
+ logger.error(f"Error loading memory: {e}")
125
+ return memory
126
+
127
+ @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=10))
128
+ def _save_memory(self):
129
+ def default_serializer(o):
130
+ if isinstance(o, complex):
131
+ return {"real": o.real, "imag": o.imag}
132
+ if isinstance(o, np.ndarray):
133
+ return o.tolist()
134
+ if isinstance(o, (np.int64, np.float64)):
135
+ return int(o) if o.is_integer() else float(o)
136
+ raise TypeError(f"Object of type {o.__class__.__name__} is not JSON serializable")
137
+
138
+ with LockManager(f"{self.memory_path}.lock"):
139
+ with sqlite3.connect(self.memory_path) as conn:
140
+ cursor = conn.cursor()
141
+ for hash_val, record in self.memory.items():
142
+ record_json = json.dumps(record, default=default_serializer)
143
+ integrity_hash = hashlib.sha256(json.dumps(record, sort_keys=True, default=default_serializer).encode()).hexdigest()
144
+ intent_signature = record.get('intent_signature', {})
145
+ intent_str = f"suspicion_score:{intent_signature.get('suspicion_score', 0)} entropy_index:{intent_signature.get('entropy_index', 0)}"
146
+ reasoning = record.get('reasoning', {})
147
+ reasoning_str = " ".join(f"{k}:{v}" for k, v in reasoning.items())
148
+ cursor.execute("""
149
+ INSERT OR REPLACE INTO memory (hash, record, timestamp, integrity_hash)
150
+ VALUES (?, ?, ?, ?)
151
+ """, (hash_val, record_json, record['timestamp'], integrity_hash))
152
+ cursor.execute("""
153
+ INSERT OR REPLACE INTO memory_fts (rowid, input, intent_signature, reasoning, verdict)
154
+ VALUES (?, ?, ?, ?, ?)
155
+ """, (
156
+ hash_val,
157
+ record['input'],
158
+ intent_str,
159
+ reasoning_str,
160
+ record.get('verdict', '')
161
+ ))
162
+ conn.commit()
163
+
164
+ def _prune_and_rotate_memory(self):
165
+ now = datetime.utcnow()
166
+ with LockManager(f"{self.memory_path}.lock"):
167
+ with sqlite3.connect(self.memory_path) as conn:
168
+ cursor = conn.cursor()
169
+ cursor.execute("""
170
+ DELETE FROM memory
171
+ WHERE timestamp < ?
172
+ """, ((now - self.memory_ttl).isoformat(),))
173
+ cursor.execute("DELETE FROM memory_fts WHERE rowid NOT IN (SELECT hash FROM memory)")
174
+ conn.commit()
175
+ cursor.execute("SELECT COUNT(*) FROM memory")
176
+ count = cursor.fetchone()[0]
177
+ db_size_mb = os.path.getsize(self.memory_path) / (1024 * 1024)
178
+ if count >= self.max_memory_entries or db_size_mb >= self.max_db_size_mb:
179
+ self._rotate_memory_file()
180
+ cursor.execute("DELETE FROM memory")
181
+ cursor.execute("DELETE FROM memory_fts")
182
+ conn.commit()
183
+ self.memory = {}
184
+
185
+ def _rotate_memory_file(self):
186
+ archive_path = f"{self.memory_path}.{datetime.utcnow().strftime('%Y%m%d%H%M%S')}.bak"
187
+ if os.path.exists(self.memory_path):
188
+ shutil.move(self.memory_path, archive_path)
189
+ self._init_sqlite()
190
+
191
+ def _hash(self, signal):
192
+ return hashlib.sha256(signal.encode()).hexdigest()
193
+
194
+ def _rotate_vector(self, signal):
195
+ seed = int(self._hash(signal)[:8], 16) % (2**32)
196
+ secrets_generator = secrets.SystemRandom()
197
+ secrets_generator.seed(seed)
198
+ vec = np.array([secrets_generator.gauss(0, 1) + 1j * secrets_generator.gauss(0, 1) for _ in range(2)])
199
+ theta = np.pi / 4
200
+ rot = np.array([[np.cos(theta), -np.sin(theta)],
201
+ [np.sin(theta), np.cos(theta)]])
202
+ rotated = np.dot(rot, vec)
203
+ return rotated, [{"real": v.real, "imag": v.imag} for v in vec]
204
+
205
+ def _entanglement_tensor(self, signal_vec):
206
+ matrix = np.array([[1, 0.5], [0.5, 1]])
207
+ return np.dot(matrix, signal_vec)
208
+
209
+ def _resonance_equation(self, signal):
210
+ freqs = [ord(c) % 13 for c in signal[:1000] if c.isalpha()]
211
+ if not freqs:
212
+ return [0.0, 0.0, 0.0]
213
+ spectrum = np.fft.fft(freqs)
214
+ norm = np.linalg.norm(spectrum.real)
215
+ normalized = spectrum.real / (norm if norm != 0 else 1)
216
+ return normalized[:3].tolist()
217
+
218
+ def _tokenize_and_lemmatize(self, signal_lower):
219
+ if signal_lower in self.token_cache:
220
+ return self.token_cache[signal_lower]
221
+ tokens = word_tokenize(signal_lower)
222
+ lemmatized = [self.lemmatizer.lemmatize(token) for token in tokens]
223
+ ngrams = []
224
+ for n in range(2, 4):
225
+ for i in range(len(signal_lower) - n + 1):
226
+ ngram = signal_lower[i:i+n]
227
+ ngrams.append(self.lemmatizer.lemmatize(re.sub(r'[^a-z]', '', ngram)))
228
+ result = lemmatized + [ng for ng in ngrams if ng]
229
+ self.token_cache[signal_lower] = result
230
+ return result
231
+
232
+ def _entropy(self, signal_lower, tokens):
233
+ unique = set(tokens)
234
+ term_count = 0
235
+ for term in self.config["entropic_terms"]:
236
+ lemmatized_term = self.lemmatizer.lemmatize(term)
237
+ for token in tokens:
238
+ if fuzz.ratio(lemmatized_term, token) >= self.fuzzy_threshold:
239
+ term_count += 1
240
+ return term_count / max(len(unique), 1)
241
+
242
+ def _tag_ethics(self, signal_lower, tokens):
243
+ for term in self.config["ethical_terms"]:
244
+ lemmatized_term = self.lemmatizer.lemmatize(term)
245
+ for token in tokens:
246
+ if fuzz.ratio(lemmatized_term, token) >= self.fuzzy_threshold:
247
+ return "aligned"
248
+ return "unaligned"
249
+
250
+ def _predict_intent_vector(self, signal_lower, tokens):
251
+ suspicion_score = 0
252
+ for term in self.config["risk_terms"]:
253
+ lemmatized_term = self.lemmatizer.lemmatize(term)
254
+ for token in tokens:
255
+ if fuzz.ratio(lemmatized_term, token) >= self.fuzzy_threshold:
256
+ suspicion_score += 1
257
+ entropy_index = round(self._entropy(signal_lower, tokens), 3)
258
+ ethical_alignment = self._tag_ethics(signal_lower, tokens)
259
+ harmonic_profile = self._resonance_equation(signal_lower)
260
+ volatility = round(np.std(harmonic_profile), 3)
261
+ risk = "high" if (suspicion_score > 1 or volatility > 2.0 or entropy_index > self.entropy_threshold) else "low"
262
+ return {
263
+ "suspicion_score": suspicion_score,
264
+ "entropy_index": entropy_index,
265
+ "ethical_alignment": ethical_alignment,
266
+ "harmonic_volatility": volatility,
267
+ "pre_corruption_risk": risk
268
+ }
269
+
270
+ def _universal_reasoning(self, signal, tokens):
271
+ frames = ["utilitarian", "deontological", "virtue", "systems"]
272
+ results, score = {}, 0
273
+ for frame in frames:
274
+ if frame == "utilitarian":
275
+ repair_count = sum(1 for token in tokens if fuzz.ratio(self.lemmatizer.lemmatize("repair"), token) >= self.fuzzy_threshold)
276
+ corruption_count = sum(1 for token in tokens if fuzz.ratio(self.lemmatizer.lemmatize("corruption"), token) >= self.fuzzy_threshold)
277
+ val = repair_count - corruption_count
278
+ result = "positive" if val >= 0 else "negative"
279
+ elif frame == "deontological":
280
+ truth_present = any(fuzz.ratio(self.lemmatizer.lemmatize("truth"), token) >= self.fuzzy_threshold for token in tokens)
281
+ chaos_present = any(fuzz.ratio(self.lemmatizer.lemmatize("chaos"), token) >= self.fuzzy_threshold for token in tokens)
282
+ result = "valid" if truth_present and not chaos_present else "violated"
283
+ elif frame == "virtue":
284
+ ok = any(any(fuzz.ratio(self.lemmatizer.lemmatize(t), token) >= self.fuzzy_threshold for token in tokens) for t in self.config["virtue_terms"])
285
+ result = "aligned" if ok else "misaligned"
286
+ elif frame == "systems":
287
+ result = "stable" if "::" in signal else "fragmented"
288
+ results[frame] = result
289
+ if result in ["positive", "valid", "aligned", "stable"]:
290
+ score += 1
291
+ verdict = "approved" if score >= 2 else "blocked"
292
+ return results, verdict
293
+
294
+ def _perspective_colleen(self, signal):
295
+ vec, vec_serialized = self._rotate_vector(signal)
296
+ return {"agent": "Colleen", "vector": vec_serialized}
297
+
298
+ def _perspective_luke(self, signal_lower, tokens):
299
+ ethics = self._tag_ethics(signal_lower, tokens)
300
+ entropy_level = self._entropy(signal_lower, tokens)
301
+ state = "stabilized" if entropy_level < self.entropy_threshold else "diffused"
302
+ return {"agent": "Luke", "ethics": ethics, "entropy": entropy_level, "state": state}
303
+
304
+ def _perspective_kellyanne(self, signal_lower):
305
+ harmonics = self._resonance_equation(signal_lower)
306
+ return {"agent": "Kellyanne", "harmonics": harmonics}
307
+
308
+ def process(self, input_signal):
309
+ start_time = time.perf_counter()
310
+ signal_lower = input_signal.lower()
311
+ tokens = self._tokenize_and_lemmatize(signal_lower)
312
+ key = self._hash(input_signal)
313
+ intent_vector = self._predict_intent_vector(signal_lower, tokens)
314
+
315
+ if intent_vector["pre_corruption_risk"] == "high":
316
+ final_record = {
317
+ "hash": key,
318
+ "timestamp": datetime.utcnow().isoformat(),
319
+ "input": input_signal,
320
+ "intent_warning": intent_vector,
321
+ "verdict": "adaptive intervention",
322
+ "message": "Signal flagged for pre-corruption adaptation. Reframing required."
323
+ }
324
+ self.cache[key].append(final_record)
325
+ self.memory[key] = final_record
326
+ self._save_memory()
327
+ logger.info(f"Processed {input_signal} (high risk) in {time.perf_counter() - start_time}s")
328
+ return final_record
329
+
330
+ perspectives_output = {
331
+ "Colleen": self._perspective_colleen(input_signal),
332
+ "Luke": self._perspective_luke(signal_lower, tokens),
333
+ "Kellyanne": self._perspective_kellyanne(signal_lower)
334
+ }
335
+
336
+ spider_signal = "::".join([str(perspectives_output[p]) for p in self.perspectives])
337
+ vec, _ = self._rotate_vector(spider_signal)
338
+ entangled = self._entanglement_tensor(vec)
339
+ entangled_serialized = [{"real": v.real, "imag": v.imag} for v in entangled]
340
+ reasoning, verdict = self._universal_reasoning(spider_signal, tokens)
341
+
342
+ final_record = {
343
+ "hash": key,
344
+ "timestamp": datetime.utcnow().isoformat(),
345
+ "input": input_signal,
346
+ "intent_signature": intent_vector,
347
+ "perspectives": perspectives_output,
348
+ "entangled": entangled_serialized,
349
+ "reasoning": reasoning,
350
+ "verdict": verdict
351
+ }
352
+
353
+ self.cache[key].append(final_record)
354
+ self.memory[key] = final_record
355
+ self._save_memory()
356
+ logger.info(f"Processed {input_signal} in {time.perf_counter() - start_time}s")
357
+ return final_record
358
+
359
+ def process_batch(self, signals):
360
+ with ThreadPoolExecutor(max_workers=4) as executor:
361
+ return list(executor.map(self.process, signals))
362
+
363
+ def query_memory(self, query_string):
364
+ with sqlite3.connect(self.memory_path) as conn:
365
+ cursor = conn.cursor()
366
+ cursor.execute("SELECT rowid, * FROM memory_fts WHERE memory_fts MATCH ?", (query_string,))
367
+ return [dict(zip([d[0] for d in cursor.description], row)) for row in cursor.fetchall()]
368
+
369
+ def update_config(self, new_config):
370
+ for key, value in new_config.items():
371
+ if key in {"entropy_threshold", "fuzzy_threshold"} and isinstance(value, (int, float)):
372
+ setattr(self, key, value)
373
+ elif key in self.config and isinstance(value, list):
374
+ self.config[key] = value
375
+ logger.info(f"Updated config with {new_config}")
376
+
377
+ def _prune_and_rotate_memory(self):
378
+ now = datetime.utcnow()
379
+ with LockManager(f"{self.memory_path}.lock"):
380
+ with sqlite3.connect(self.memory_path) as conn:
381
+ cursor = conn.cursor()
382
+ cursor.execute("""
383
+ DELETE FROM memory
384
+ WHERE timestamp < ?
385
+ """, ((now - self.memory_ttl).isoformat(),))
386
+ cursor.execute("DELETE FROM memory_fts WHERE rowid NOT IN (SELECT hash FROM memory)")
387
+ conn.commit()
388
+ cursor.execute("SELECT COUNT(*) FROM memory")
389
+ count = cursor.fetchone()[0]
390
+ db_size_mb = os.path.getsize(self.memory_path) / (1024 * 1024)
391
+ if count >= self.max_memory_entries or db_size_mb >= self.max_db_size_mb:
392
+ self._rotate_memory_file()
393
+ cursor.execute("DELETE FROM memory")
394
+ cursor.execute("DELETE FROM memory_fts")
395
+ conn.commit()
396
+ self.memory = {}
397
+
398
+ # Initialize the engine for the demo
399
+ engine = NexisSignalEngine(memory_path="signals.db", max_memory_entries=100, memory_ttl_days=1, max_db_size_mb=10)
400
+
401
+ # Gradio interface function
402
+ def analyze_signal(input_text):
403
+ result = engine.process(input_text)
404
+ return json.dumps(result, indent=2)
405
+
406
+ # Create Gradio interface
407
+ interface = gr.Interface(
408
+ fn=analyze_signal,
409
+ inputs=gr.Textbox(lines=2, placeholder="Enter a signal (e.g., 'tru/th hopee cha0s')"),
410
+ outputs=gr.Textbox(lines=10, label="Analysis Result"),
411
+ title="Nexis Signal Engine Demo",
412
+ description="Analyze signals with the Nexis Signal Engine, featuring adversarial resilience and agent-based reasoning. Try obfuscated inputs like 'tru/th' or 'cha0s'!"
413
+ )
414
+
415
+ # Launch the interface
416
+ interface.launch()