Update app.py
Browse files
app.py
CHANGED
|
@@ -21,6 +21,7 @@ MEMORY_MANIFEST = {
|
|
| 21 |
import os, sys, re, json, time, shutil, tempfile, subprocess, platform, socket, threading, importlib, hashlib, unicodedata, urllib.request, base64
|
| 22 |
from dataclasses import dataclass
|
| 23 |
from typing import Optional, List, Dict, Tuple
|
|
|
|
| 24 |
# ----------- light bootstrap (safe) -----------
|
| 25 |
def _ensure(pkgs: List[str]):
|
| 26 |
for p in pkgs: # type: ignore
|
|
@@ -527,6 +528,27 @@ class ASRService:
|
|
| 527 |
"""Handles ASR, including transcription and language detection."""
|
| 528 |
def __init__(self):
|
| 529 |
self.model = get_asr()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 530 |
ASR_MODELS={"tiny":"tiny","base":"base","small":"small","medium":"medium","large":"large-v3"}
|
| 531 |
def _asr_model_name(): return ASR_MODELS.get(CFG["VOICE_ASR_MODEL"],"small")
|
| 532 |
_ASR=None
|
|
@@ -948,6 +970,14 @@ class VideoService(threading.Thread):
|
|
| 948 |
while not self.stop_event.is_set():
|
| 949 |
time.sleep(1)
|
| 950 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 951 |
# ----------- wifi auto-connect (non-blocking) -----------
|
| 952 |
NET_STATE_DB=os.path.join(CFG["STATE_DIR"],"wifi_known.json")
|
| 953 |
|
|
@@ -1404,6 +1434,13 @@ class SelfOptimizerModule(SelfOptimizer, IModule):
|
|
| 1404 |
IModule.__init__(self, hive_instance)
|
| 1405 |
SelfOptimizer.__init__(self, hive_instance)
|
| 1406 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1407 |
class PersistenceEngine(IModule):
|
| 1408 |
"""Implements the PersistenceEngine from Part 1, Section 7.9."""
|
| 1409 |
def __init__(self, hive_instance: "Hive"):
|
|
@@ -1554,6 +1591,7 @@ class Hive:
|
|
| 1554 |
self.module_manager.register("compiler", CompilerModule(self))
|
| 1555 |
self.module_manager.register("selfopt", SelfOptimizerModule(self))
|
| 1556 |
self.module_manager.register("voice_video", VoiceServicesModule(self))
|
|
|
|
| 1557 |
self.module_manager.register("persistence", PersistenceEngine(self))
|
| 1558 |
self.module_manager.register("kstore", KnowledgeStoreModule(self))
|
| 1559 |
self.dialogue_manager = DialogueManager(self)
|
|
@@ -1609,19 +1647,19 @@ class Hive:
|
|
| 1609 |
self.pipe = pipeline("text-generation", model=self.model, tokenizer=self.tok, device=self.device, stopping_criteria=self.stopping_criteria)
|
| 1610 |
|
| 1611 |
@property
|
| 1612 |
-
def store(self) -> CurveStore: return self.module_manager.modules["store"] # type: ignore
|
| 1613 |
@property
|
| 1614 |
def librarian(self) -> 'LibrarianCurve': return self.module_manager.modules["librarian"] # type: ignore
|
| 1615 |
@property
|
| 1616 |
-
def engine(self) -> EngineCurve: return self.module_manager.modules["engine"] # type: ignore
|
| 1617 |
@property
|
| 1618 |
-
def overlay(self) -> RuntimeOverlay: return self.module_manager.modules["overlay"] # type: ignore
|
| 1619 |
@property
|
| 1620 |
-
def changes(self) -> ChangeManager: return self.module_manager.modules["changes"] # type: ignore
|
| 1621 |
@property
|
| 1622 |
-
def compiler(self) -> PromptCompiler: return self.module_manager.modules["compiler"] # type: ignore
|
| 1623 |
@property
|
| 1624 |
-
def selfopt(self) -> SelfOptimizer: return self.module_manager.modules["selfopt"] # type: ignore
|
| 1625 |
|
| 1626 |
def _prepare_chat_input(self, message: str, user_lang: str, phonics_on: bool, prompt_override: str | None) -> tuple[str, str]:
|
| 1627 |
"""Determines intent and prepares the final message for the LLM."""
|
|
@@ -2404,6 +2442,7 @@ class Bootstrap:
|
|
| 2404 |
self.hive_instance: Optional[Hive] = None
|
| 2405 |
self.hive_lite_instance: Optional[Hive] = None
|
| 2406 |
self.hive_ready = threading.Event()
|
|
|
|
| 2407 |
self.env: Optional[Dict] = None
|
| 2408 |
self.app: Optional[gr.Blocks] = None
|
| 2409 |
self.ui_thread: Optional[threading.Thread] = None
|
|
@@ -2438,12 +2477,14 @@ class Bootstrap:
|
|
| 2438 |
# but for now, we'll keep it for immediate responsiveness.
|
| 2439 |
if self.caps.get("is_low_memory"):
|
| 2440 |
print("[Bootstrap] Low memory mode: Lite instance will be minimal.")
|
|
|
|
| 2441 |
|
| 2442 |
self.video_service = VideoService()
|
| 2443 |
print("[Bootstrap] Lite Hive core is ready.")
|
| 2444 |
|
| 2445 |
# Now initialize the full instance in the background. This is the slow part.
|
| 2446 |
def full_init_task():
|
|
|
|
| 2447 |
print("[Bootstrap] Initializing Full Hive core in background...")
|
| 2448 |
Hive.bootstrap_instance = self
|
| 2449 |
self.hive_instance = Hive(lite=False)
|
|
@@ -2451,12 +2492,17 @@ class Bootstrap:
|
|
| 2451 |
self.hive_instance.embedding_worker.start()
|
| 2452 |
self.hive_ready.set() # Signal that the full Hive instance is ready
|
| 2453 |
self.setup_memory()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2454 |
print("[Bootstrap] Full Hive core is ready.")
|
| 2455 |
|
| 2456 |
self.ui_thread = threading.Thread(target=self.launch, daemon=True)
|
| 2457 |
-
|
| 2458 |
threading.Thread(target=full_init_task, daemon=True).start()
|
| 2459 |
-
|
| 2460 |
# Register graceful shutdown handler and launch the UI in the main thread
|
| 2461 |
import signal
|
| 2462 |
signal.signal(signal.SIGINT, self.graceful_shutdown)
|
|
@@ -2537,14 +2583,6 @@ class Bootstrap:
|
|
| 2537 |
print("[Bootstrap] Exiting.")
|
| 2538 |
sys.exit(0)
|
| 2539 |
|
| 2540 |
-
# ----------- entry -----------
|
| 2541 |
-
class KnowledgeStoreModule(KnowledgeStore, IModule):
|
| 2542 |
-
def __init__(self, hive_instance: "Hive"):
|
| 2543 |
-
IModule.__init__(self, hive_instance)
|
| 2544 |
-
KnowledgeStore.__init__(self, hive_instance.config["HIVE_HOME"])
|
| 2545 |
-
def start(self): pass
|
| 2546 |
-
def stop(self): pass
|
| 2547 |
-
|
| 2548 |
if __name__=="__main__":
|
| 2549 |
bootstrap = Bootstrap(CFG)
|
| 2550 |
bootstrap.run()
|
|
|
|
| 21 |
import os, sys, re, json, time, shutil, tempfile, subprocess, platform, socket, threading, importlib, hashlib, unicodedata, urllib.request, base64
|
| 22 |
from dataclasses import dataclass
|
| 23 |
from typing import Optional, List, Dict, Tuple
|
| 24 |
+
from pathlib import Path as _Path
|
| 25 |
# ----------- light bootstrap (safe) -----------
|
| 26 |
def _ensure(pkgs: List[str]):
|
| 27 |
for p in pkgs: # type: ignore
|
|
|
|
| 528 |
"""Handles ASR, including transcription and language detection."""
|
| 529 |
def __init__(self):
|
| 530 |
self.model = get_asr()
|
| 531 |
+
|
| 532 |
+
def transcribe(self, audio_path: str, uid: Optional[str], forced_lang: Optional[str] = None) -> dict:
|
| 533 |
+
prior = _load_json(ADAPT_DB, {}).get(uid or "guest", {}).get("lang_prior")
|
| 534 |
+
language = forced_lang or prior or None
|
| 535 |
+
segs, info = self.model.transcribe(audio_path, language=language, beam_size=5, vad_filter=True)
|
| 536 |
+
text = " ".join([s.text for s in segs]).strip()
|
| 537 |
+
|
| 538 |
+
detected_lang = info.language
|
| 539 |
+
if not forced_lang and text:
|
| 540 |
+
prof = _load_json(ADAPT_DB, {})
|
| 541 |
+
p = prof.get(uid or "guest", {})
|
| 542 |
+
p["lang_prior"] = detected_lang
|
| 543 |
+
prof[uid or "guest"] = p
|
| 544 |
+
_save_json(ADAPT_DB, prof)
|
| 545 |
+
|
| 546 |
+
return {"text": text, "language": detected_lang, "confidence": info.language_probability, "segments": [{"start": s.start, "end": s.end, "text": s.text} for s in segs]}
|
| 547 |
+
|
| 548 |
+
class ASRService_placeholder:
|
| 549 |
+
"""Handles ASR, including transcription and language detection."""
|
| 550 |
+
def __init__(self):
|
| 551 |
+
self.model = get_asr()
|
| 552 |
ASR_MODELS={"tiny":"tiny","base":"base","small":"small","medium":"medium","large":"large-v3"}
|
| 553 |
def _asr_model_name(): return ASR_MODELS.get(CFG["VOICE_ASR_MODEL"],"small")
|
| 554 |
_ASR=None
|
|
|
|
| 970 |
while not self.stop_event.is_set():
|
| 971 |
time.sleep(1)
|
| 972 |
|
| 973 |
+
class EngineCurve:
|
| 974 |
+
def __init__(self):
|
| 975 |
+
self.stats={"runs":0,"ok":0,"latency_ms":[]}
|
| 976 |
+
self.router_rules=[]
|
| 977 |
+
def choose_route(self, msg:str)->str:
|
| 978 |
+
# This is a simplified version. The full logic is now in IntentRouter.
|
| 979 |
+
return "tutor"
|
| 980 |
+
def run(self, message:str, snippets:List[Dict])->Dict: return {"ok":True,"route":"tutor"}
|
| 981 |
# ----------- wifi auto-connect (non-blocking) -----------
|
| 982 |
NET_STATE_DB=os.path.join(CFG["STATE_DIR"],"wifi_known.json")
|
| 983 |
|
|
|
|
| 1434 |
IModule.__init__(self, hive_instance)
|
| 1435 |
SelfOptimizer.__init__(self, hive_instance)
|
| 1436 |
|
| 1437 |
+
class LibrarianModule(LibrarianCurve, IModule):
|
| 1438 |
+
def __init__(self, hive_instance: "Hive"):
|
| 1439 |
+
IModule.__init__(self, hive_instance)
|
| 1440 |
+
LibrarianCurve.__init__(self, hive_instance.store, hive_instance.k_store)
|
| 1441 |
+
hive_instance.retrieval_k=6
|
| 1442 |
+
hive_instance.web_threshold=0.40
|
| 1443 |
+
|
| 1444 |
class PersistenceEngine(IModule):
|
| 1445 |
"""Implements the PersistenceEngine from Part 1, Section 7.9."""
|
| 1446 |
def __init__(self, hive_instance: "Hive"):
|
|
|
|
| 1591 |
self.module_manager.register("compiler", CompilerModule(self))
|
| 1592 |
self.module_manager.register("selfopt", SelfOptimizerModule(self))
|
| 1593 |
self.module_manager.register("voice_video", VoiceServicesModule(self))
|
| 1594 |
+
self.module_manager.register("engine", EngineModule(self))
|
| 1595 |
self.module_manager.register("persistence", PersistenceEngine(self))
|
| 1596 |
self.module_manager.register("kstore", KnowledgeStoreModule(self))
|
| 1597 |
self.dialogue_manager = DialogueManager(self)
|
|
|
|
| 1647 |
self.pipe = pipeline("text-generation", model=self.model, tokenizer=self.tok, device=self.device, stopping_criteria=self.stopping_criteria)
|
| 1648 |
|
| 1649 |
@property
|
| 1650 |
+
def store(self) -> 'CurveStore': return self.module_manager.modules["store"] # type: ignore
|
| 1651 |
@property
|
| 1652 |
def librarian(self) -> 'LibrarianCurve': return self.module_manager.modules["librarian"] # type: ignore
|
| 1653 |
@property
|
| 1654 |
+
def engine(self) -> 'EngineCurve': return self.module_manager.modules["engine"] # type: ignore
|
| 1655 |
@property
|
| 1656 |
+
def overlay(self) -> 'RuntimeOverlay': return self.module_manager.modules["overlay"] # type: ignore
|
| 1657 |
@property
|
| 1658 |
+
def changes(self) -> 'ChangeManager': return self.module_manager.modules["changes"] # type: ignore
|
| 1659 |
@property
|
| 1660 |
+
def compiler(self) -> 'PromptCompiler': return self.module_manager.modules["compiler"] # type: ignore
|
| 1661 |
@property
|
| 1662 |
+
def selfopt(self) -> 'SelfOptimizer': return self.module_manager.modules["selfopt"] # type: ignore
|
| 1663 |
|
| 1664 |
def _prepare_chat_input(self, message: str, user_lang: str, phonics_on: bool, prompt_override: str | None) -> tuple[str, str]:
|
| 1665 |
"""Determines intent and prepares the final message for the LLM."""
|
|
|
|
| 2442 |
self.hive_instance: Optional[Hive] = None
|
| 2443 |
self.hive_lite_instance: Optional[Hive] = None
|
| 2444 |
self.hive_ready = threading.Event()
|
| 2445 |
+
self.voice_ready = threading.Event()
|
| 2446 |
self.env: Optional[Dict] = None
|
| 2447 |
self.app: Optional[gr.Blocks] = None
|
| 2448 |
self.ui_thread: Optional[threading.Thread] = None
|
|
|
|
| 2477 |
# but for now, we'll keep it for immediate responsiveness.
|
| 2478 |
if self.caps.get("is_low_memory"):
|
| 2479 |
print("[Bootstrap] Low memory mode: Lite instance will be minimal.")
|
| 2480 |
+
self.hive_lite_instance = Hive(lite=True)
|
| 2481 |
|
| 2482 |
self.video_service = VideoService()
|
| 2483 |
print("[Bootstrap] Lite Hive core is ready.")
|
| 2484 |
|
| 2485 |
# Now initialize the full instance in the background. This is the slow part.
|
| 2486 |
def full_init_task():
|
| 2487 |
+
# Voice init is part of the full core setup
|
| 2488 |
print("[Bootstrap] Initializing Full Hive core in background...")
|
| 2489 |
Hive.bootstrap_instance = self
|
| 2490 |
self.hive_instance = Hive(lite=False)
|
|
|
|
| 2492 |
self.hive_instance.embedding_worker.start()
|
| 2493 |
self.hive_ready.set() # Signal that the full Hive instance is ready
|
| 2494 |
self.setup_memory()
|
| 2495 |
+
|
| 2496 |
+
print("[Bootstrap] Initializing Voice models (ASR/TTS) in background...")
|
| 2497 |
+
get_asr()
|
| 2498 |
+
get_tts(CFG["TTS_LANG"])
|
| 2499 |
+
self.voice_ready.set()
|
| 2500 |
+
print("[Bootstrap] Voice models are ready.")
|
| 2501 |
+
|
| 2502 |
print("[Bootstrap] Full Hive core is ready.")
|
| 2503 |
|
| 2504 |
self.ui_thread = threading.Thread(target=self.launch, daemon=True)
|
|
|
|
| 2505 |
threading.Thread(target=full_init_task, daemon=True).start()
|
|
|
|
| 2506 |
# Register graceful shutdown handler and launch the UI in the main thread
|
| 2507 |
import signal
|
| 2508 |
signal.signal(signal.SIGINT, self.graceful_shutdown)
|
|
|
|
| 2583 |
print("[Bootstrap] Exiting.")
|
| 2584 |
sys.exit(0)
|
| 2585 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2586 |
if __name__=="__main__":
|
| 2587 |
bootstrap = Bootstrap(CFG)
|
| 2588 |
bootstrap.run()
|