Update app.py
Browse files
app.py
CHANGED
|
@@ -1088,7 +1088,17 @@ class ChangeManager:
|
|
| 1088 |
pref=os.path.join(OPT_DIR,"preferred_model.json"); json.dump({"model_id":name,"ts":time.time()}, open(pref,"w",encoding="utf-8"))
|
| 1089 |
return True,"model preference recorded (takes effect after restart)"
|
| 1090 |
if kind=="code":
|
| 1091 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1092 |
try:
|
| 1093 |
target=os.path.abspath(__file__); backup=target+f".bak_{int(time.time())}"; shutil.copyfile(target,backup)
|
| 1094 |
open(target,"w",encoding="utf-8").write(prop.get("patch_text","")); return True,"code updated (backup created); restart recommended"
|
|
@@ -1117,6 +1127,7 @@ class SelfOptimizerModule(SelfOptimizer, IModule):
|
|
| 1117 |
# ----------- Hive core -----------
|
| 1118 |
# --- Memory & Manifest Helpers (auto-inserted) ---
|
| 1119 |
import tempfile, urllib.request, tarfile, zipfile
|
|
|
|
| 1120 |
from pathlib import Path as _Path
|
| 1121 |
|
| 1122 |
|
|
@@ -1163,6 +1174,7 @@ class Hive:
|
|
| 1163 |
self.caps = caps or probe_caps()
|
| 1164 |
self.lite_mode = lite
|
| 1165 |
self.module_manager = ModuleManager()
|
|
|
|
| 1166 |
|
| 1167 |
if not model_id:
|
| 1168 |
model_id, info = pick_model(self.caps)
|
|
@@ -1552,20 +1564,6 @@ def launch_ui(bootstrap_instance: "Bootstrap"):
|
|
| 1552 |
return hist+[[m, reply]], ""
|
| 1553 |
msg.submit(talk,[msg,uid_state,role_state,mode_state,chatbot],[chatbot,msg])
|
| 1554 |
|
| 1555 |
-
def get_vocab_words_for_user(uid):
|
| 1556 |
-
"""Helper to get all vocabulary words for a user."""
|
| 1557 |
-
if not uid: return set()
|
| 1558 |
-
log_path = os.path.join(CFG["HIVE_HOME"], "users", "conversations", f"{uid}.jsonl")
|
| 1559 |
-
if not os.path.exists(log_path): return set()
|
| 1560 |
-
try:
|
| 1561 |
-
with open(log_path, "r", encoding="utf-8") as f:
|
| 1562 |
-
content = f.read()
|
| 1563 |
-
words = {w for w in re.findall(r'\b\w{7,}\b', content.lower()) if w not in ["assistant", "message"]}
|
| 1564 |
-
return words
|
| 1565 |
-
except Exception:
|
| 1566 |
-
return set()
|
| 1567 |
-
|
| 1568 |
-
|
| 1569 |
def do_memory_summary(uid):
|
| 1570 |
if not uid: return "Please log in to see your memory summary."
|
| 1571 |
log_path = os.path.join(CFG["HIVE_HOME"], "users", "conversations", f"{uid}.jsonl")
|
|
@@ -1839,6 +1837,7 @@ class Bootstrap:
|
|
| 1839 |
self.hive_lite_instance: Optional[Hive] = None
|
| 1840 |
self.hive_ready = threading.Event()
|
| 1841 |
self.env: Optional[Dict] = None
|
|
|
|
| 1842 |
|
| 1843 |
def initialize_persistent_storage(self, base_path: str):
|
| 1844 |
"""Creates the canonical directory structure as per spec."""
|
|
@@ -1873,6 +1872,7 @@ class Bootstrap:
|
|
| 1873 |
|
| 1874 |
# Create a 'lite' instance immediately for basic chat
|
| 1875 |
print("[Bootstrap] Initializing Lite Hive core...")
|
|
|
|
| 1876 |
self.hive_lite_instance = Hive(lite=True)
|
| 1877 |
print("[Bootstrap] Lite Hive core is ready.")
|
| 1878 |
|
|
@@ -1883,6 +1883,7 @@ class Bootstrap:
|
|
| 1883 |
# Now initialize the full instance in the background. This is the slow part.
|
| 1884 |
def full_init_task():
|
| 1885 |
print("[Bootstrap] Initializing Full Hive core in background...")
|
|
|
|
| 1886 |
self.hive_instance = Hive(lite=False)
|
| 1887 |
self.hive_ready.set() # Signal that the full Hive instance is ready
|
| 1888 |
print("[Bootstrap] Full Hive core is ready.")
|
|
@@ -1897,6 +1898,21 @@ class Bootstrap:
|
|
| 1897 |
|
| 1898 |
ui_thread.join() # Keep main thread alive
|
| 1899 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1900 |
def setup_memory(self):
|
| 1901 |
"""Handles memory restoration and staged ingestion."""
|
| 1902 |
def _memory_task():
|
|
|
|
| 1088 |
pref=os.path.join(OPT_DIR,"preferred_model.json"); json.dump({"model_id":name,"ts":time.time()}, open(pref,"w",encoding="utf-8"))
|
| 1089 |
return True,"model preference recorded (takes effect after restart)"
|
| 1090 |
if kind=="code":
|
| 1091 |
+
is_pi = 'raspberrypi' in platform.machine().lower()
|
| 1092 |
+
if is_pi and self.hive_cls.bootstrap_instance:
|
| 1093 |
+
print("[ChangeManager] Raspberry Pi detected, attempting hot-reload.")
|
| 1094 |
+
try:
|
| 1095 |
+
target=os.path.abspath(__file__)
|
| 1096 |
+
with open(target, "w", encoding="utf-8") as f: f.write(prop.get("patch_text",""))
|
| 1097 |
+
self.hive_cls.bootstrap_instance.soft_restart()
|
| 1098 |
+
return True, "Code hot-reloaded without a full reboot."
|
| 1099 |
+
except Exception as e:
|
| 1100 |
+
return False, f"Hot-reload failed: {e}. A manual restart is required."
|
| 1101 |
+
|
| 1102 |
try:
|
| 1103 |
target=os.path.abspath(__file__); backup=target+f".bak_{int(time.time())}"; shutil.copyfile(target,backup)
|
| 1104 |
open(target,"w",encoding="utf-8").write(prop.get("patch_text","")); return True,"code updated (backup created); restart recommended"
|
|
|
|
| 1127 |
# ----------- Hive core -----------
|
| 1128 |
# --- Memory & Manifest Helpers (auto-inserted) ---
|
| 1129 |
import tempfile, urllib.request, tarfile, zipfile
|
| 1130 |
+
import importlib
|
| 1131 |
from pathlib import Path as _Path
|
| 1132 |
|
| 1133 |
|
|
|
|
| 1174 |
self.caps = caps or probe_caps()
|
| 1175 |
self.lite_mode = lite
|
| 1176 |
self.module_manager = ModuleManager()
|
| 1177 |
+
Hive.bootstrap_instance = None # Class attribute to hold bootstrap instance
|
| 1178 |
|
| 1179 |
if not model_id:
|
| 1180 |
model_id, info = pick_model(self.caps)
|
|
|
|
| 1564 |
return hist+[[m, reply]], ""
|
| 1565 |
msg.submit(talk,[msg,uid_state,role_state,mode_state,chatbot],[chatbot,msg])
|
| 1566 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1567 |
def do_memory_summary(uid):
|
| 1568 |
if not uid: return "Please log in to see your memory summary."
|
| 1569 |
log_path = os.path.join(CFG["HIVE_HOME"], "users", "conversations", f"{uid}.jsonl")
|
|
|
|
| 1837 |
self.hive_lite_instance: Optional[Hive] = None
|
| 1838 |
self.hive_ready = threading.Event()
|
| 1839 |
self.env: Optional[Dict] = None
|
| 1840 |
+
self.app: Optional[fastapi.FastAPI] = None
|
| 1841 |
|
| 1842 |
def initialize_persistent_storage(self, base_path: str):
|
| 1843 |
"""Creates the canonical directory structure as per spec."""
|
|
|
|
| 1872 |
|
| 1873 |
# Create a 'lite' instance immediately for basic chat
|
| 1874 |
print("[Bootstrap] Initializing Lite Hive core...")
|
| 1875 |
+
Hive.bootstrap_instance = self
|
| 1876 |
self.hive_lite_instance = Hive(lite=True)
|
| 1877 |
print("[Bootstrap] Lite Hive core is ready.")
|
| 1878 |
|
|
|
|
| 1883 |
# Now initialize the full instance in the background. This is the slow part.
|
| 1884 |
def full_init_task():
|
| 1885 |
print("[Bootstrap] Initializing Full Hive core in background...")
|
| 1886 |
+
Hive.bootstrap_instance = self
|
| 1887 |
self.hive_instance = Hive(lite=False)
|
| 1888 |
self.hive_ready.set() # Signal that the full Hive instance is ready
|
| 1889 |
print("[Bootstrap] Full Hive core is ready.")
|
|
|
|
| 1898 |
|
| 1899 |
ui_thread.join() # Keep main thread alive
|
| 1900 |
|
| 1901 |
+
def soft_restart(self):
|
| 1902 |
+
"""Performs a hot-reload of the application logic without restarting the process."""
|
| 1903 |
+
print("[Bootstrap] Performing soft restart (hot-reload)...")
|
| 1904 |
+
self.hive_ready.clear()
|
| 1905 |
+
|
| 1906 |
+
# Reload the app module to get the new code
|
| 1907 |
+
import app
|
| 1908 |
+
importlib.reload(app)
|
| 1909 |
+
|
| 1910 |
+
# Re-initialize the full hive instance with the new code
|
| 1911 |
+
print("[Bootstrap] Re-initializing Full Hive core after hot-reload...")
|
| 1912 |
+
self.hive_instance = app.Hive(lite=False)
|
| 1913 |
+
self.hive_ready.set()
|
| 1914 |
+
print("[Bootstrap] Soft restart complete. New code is active.")
|
| 1915 |
+
|
| 1916 |
def setup_memory(self):
|
| 1917 |
"""Handles memory restoration and staged ingestion."""
|
| 1918 |
def _memory_task():
|