Update app.py
Browse files
app.py
CHANGED
|
@@ -1113,13 +1113,13 @@ class LibrarianCurve:
|
|
| 1113 |
class VoiceServicesModule(IModule):
|
| 1114 |
def __init__(self, hive_instance: "Hive"):
|
| 1115 |
super().__init__(hive_instance)
|
| 1116 |
-
if _HAVE_VAD: # type: ignore
|
| 1117 |
-
hive_instance.vad_service = VADService(aggressiveness=CFG["VOICE_VAD_AGGRESSIVENESS"])
|
| 1118 |
-
hive_instance.asr_service = ASRService()
|
| 1119 |
-
hive_instance.tts_service = TTSService()
|
| 1120 |
-
hive_instance.video_service = VideoService()
|
| 1121 |
|
| 1122 |
def start(self):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1123 |
if self.hive.video_service: self.hive.video_service.start()
|
| 1124 |
|
| 1125 |
def stop(self):
|
|
@@ -1127,20 +1127,13 @@ class VoiceServicesModule(IModule):
|
|
| 1127 |
|
| 1128 |
class VideoService(IModule):
|
| 1129 |
"""Handles video capture from a webcam."""
|
| 1130 |
-
def __init__(self, hive_instance: "Hive"):
|
| 1131 |
-
super().__init__(hive_instance)
|
| 1132 |
-
self.cap = None
|
| 1133 |
-
self.stop_event = threading.Event()
|
| 1134 |
-
self.frame_lock = threading.Lock()
|
| 1135 |
-
self.latest_frame = None
|
| 1136 |
-
|
| 1137 |
def start(self):
|
| 1138 |
-
if
|
| 1139 |
-
|
| 1140 |
-
|
| 1141 |
-
|
| 1142 |
-
self.cap = None
|
| 1143 |
|
|
|
|
| 1144 |
def get_frame(self):
|
| 1145 |
if not self.cap: return None
|
| 1146 |
ret, frame = self.cap.read()
|
|
@@ -1154,6 +1147,18 @@ class PersistenceEngine(IModule):
|
|
| 1154 |
def start(self): pass
|
| 1155 |
def stop(self): pass
|
| 1156 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1157 |
# ----------- Hive core -----------
|
| 1158 |
|
| 1159 |
# type: ignore
|
|
@@ -1213,6 +1218,18 @@ class CurveStoreModule(CurveStore, IModule): # type: ignore
|
|
| 1213 |
def start(self): pass
|
| 1214 |
def stop(self): pass
|
| 1215 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1216 |
class EngineModule(EngineCurve, IModule):
|
| 1217 |
def __init__(self, hive_instance: "Hive"):
|
| 1218 |
IModule.__init__(self, hive_instance)
|
|
@@ -1494,22 +1511,29 @@ class Hive:
|
|
| 1494 |
|
| 1495 |
def chat(self, message:str, effective_role:str, caller_id: Optional[str],
|
| 1496 |
k:int=None, max_new_tokens:int=256, temperature:float=None, prompt_override: Optional[str] = None) -> str: # type: ignore
|
| 1497 |
-
temp = temperature if temperature is not None else (self.decoding_temperature if
|
| 1498 |
|
| 1499 |
if self.lite_mode:
|
| 1500 |
prompt = f"<|user|>\n{message}</s>\n<|assistant|>\n"
|
| 1501 |
full_reply = "".join(list(self.chat_stream(prompt, max_new_tokens, temp)))
|
| 1502 |
return full_reply
|
| 1503 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1504 |
kk = k if k is not None else (self.retrieval_k if hasattr(self, 'retrieval_k') else 6)
|
| 1505 |
snippets = self._get_retrieval_context(message, effective_role, caller_id, kk) # type: ignore
|
| 1506 |
|
| 1507 |
prompt = self.compiler.compile( # type: ignore
|
| 1508 |
-
final_message,
|
| 1509 |
-
snippets,
|
| 1510 |
-
token_budget=int(CFG["CTX_TOKENS"]),
|
| 1511 |
-
intent=intent,
|
| 1512 |
-
|
|
|
|
| 1513 |
)
|
| 1514 |
|
| 1515 |
full_output = "".join(list(self.chat_stream(prompt, max_new_tokens, temp))) # type: ignore
|
|
|
|
| 1113 |
class VoiceServicesModule(IModule):
|
| 1114 |
def __init__(self, hive_instance: "Hive"):
|
| 1115 |
super().__init__(hive_instance)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1116 |
|
| 1117 |
def start(self):
|
| 1118 |
+
if _HAVE_VAD:
|
| 1119 |
+
self.hive.vad_service = VADService(aggressiveness=CFG["VOICE_VAD_AGGRESSIVENESS"])
|
| 1120 |
+
self.hive.asr_service = ASRService()
|
| 1121 |
+
self.hive.tts_service = TTSService()
|
| 1122 |
+
self.hive.video_service = VideoService(self.hive)
|
| 1123 |
if self.hive.video_service: self.hive.video_service.start()
|
| 1124 |
|
| 1125 |
def stop(self):
|
|
|
|
| 1127 |
|
| 1128 |
class VideoService(IModule):
|
| 1129 |
"""Handles video capture from a webcam."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1130 |
def start(self):
|
| 1131 |
+
if self.hive.video_service: self.hive.video_service.start()
|
| 1132 |
+
|
| 1133 |
+
def stop(self):
|
| 1134 |
+
if self.hive.video_service: self.hive.video_service.stop_event.set()
|
|
|
|
| 1135 |
|
| 1136 |
+
class VideoService(IModule):
|
| 1137 |
def get_frame(self):
|
| 1138 |
if not self.cap: return None
|
| 1139 |
ret, frame = self.cap.read()
|
|
|
|
| 1147 |
def start(self): pass
|
| 1148 |
def stop(self): pass
|
| 1149 |
|
| 1150 |
+
class VADService:
|
| 1151 |
+
def __init__(self, aggressiveness=2): pass
|
| 1152 |
+
def process_stream(self, audio_chunk): yield audio_chunk
|
| 1153 |
+
|
| 1154 |
+
class TTSService:
|
| 1155 |
+
def synthesize(self, text, uid):
|
| 1156 |
+
v = get_tts("en")
|
| 1157 |
+
aud, _ = v.synthesize(text)
|
| 1158 |
+
sr = v.sample_rate
|
| 1159 |
+
outp=os.path.join(tempfile.gettempdir(), f"hive_tts_{int(time.time())}.wav")
|
| 1160 |
+
sf.write(outp, aud if aud is not None else np.zeros(1), sr or 22050, subtype="PCM_16"); return outp
|
| 1161 |
+
|
| 1162 |
# ----------- Hive core -----------
|
| 1163 |
|
| 1164 |
# type: ignore
|
|
|
|
| 1218 |
def start(self): pass
|
| 1219 |
def stop(self): pass
|
| 1220 |
|
| 1221 |
+
class LibrarianModule(LibrarianCurve, IModule):
|
| 1222 |
+
def __init__(self, hive_instance: "Hive"):
|
| 1223 |
+
IModule.__init__(self, hive_instance)
|
| 1224 |
+
LibrarianCurve.__init__(self, hive_instance.store, hive_instance.kstore)
|
| 1225 |
+
def start(self): pass
|
| 1226 |
+
def stop(self): pass
|
| 1227 |
+
|
| 1228 |
+
class DialogueManager(IModule):
|
| 1229 |
+
"""Handles the core turn-taking logic of the chatbot."""
|
| 1230 |
+
def start(self): self.model_bridge = ModelBridge(self.hive)
|
| 1231 |
+
def stop(self): pass
|
| 1232 |
+
|
| 1233 |
class EngineModule(EngineCurve, IModule):
|
| 1234 |
def __init__(self, hive_instance: "Hive"):
|
| 1235 |
IModule.__init__(self, hive_instance)
|
|
|
|
| 1511 |
|
| 1512 |
def chat(self, message:str, effective_role:str, caller_id: Optional[str],
|
| 1513 |
k:int=None, max_new_tokens:int=256, temperature:float=None, prompt_override: Optional[str] = None) -> str: # type: ignore
|
| 1514 |
+
temp = temperature if temperature is not None else (self.decoding_temperature if hasattr(self, 'decoding_temperature') else 0.7)
|
| 1515 |
|
| 1516 |
if self.lite_mode:
|
| 1517 |
prompt = f"<|user|>\n{message}</s>\n<|assistant|>\n"
|
| 1518 |
full_reply = "".join(list(self.chat_stream(prompt, max_new_tokens, temp)))
|
| 1519 |
return full_reply
|
| 1520 |
|
| 1521 |
+
user_profile = self.persistence.load_json("users", caller_id or "guest", default={})
|
| 1522 |
+
user_lang = user_profile.get("language", "en")
|
| 1523 |
+
phonics_on = user_profile.get("phonics_on", False)
|
| 1524 |
+
|
| 1525 |
+
final_message, intent = self._prepare_chat_input(message, user_lang, phonics_on, prompt_override)
|
| 1526 |
+
|
| 1527 |
kk = k if k is not None else (self.retrieval_k if hasattr(self, 'retrieval_k') else 6)
|
| 1528 |
snippets = self._get_retrieval_context(message, effective_role, caller_id, kk) # type: ignore
|
| 1529 |
|
| 1530 |
prompt = self.compiler.compile( # type: ignore
|
| 1531 |
+
final_instruction=final_message,
|
| 1532 |
+
snippets=snippets,
|
| 1533 |
+
token_budget=int(CFG["CTX_TOKENS"]),
|
| 1534 |
+
intent=intent,
|
| 1535 |
+
user_prefs={"language": user_lang},
|
| 1536 |
+
role=effective_role
|
| 1537 |
)
|
| 1538 |
|
| 1539 |
full_output = "".join(list(self.chat_stream(prompt, max_new_tokens, temp))) # type: ignore
|