Files
2026-02-08 23:15:01 +03:00

187 lines
6.1 KiB
Python

import asyncio
import threading
from speech_to_text import record_voice
from llm import get_llm_output
from tts import edge_speak, stop_speaking
from ui import JarvisUI
import sys
from pathlib import Path
from actions.open_app import open_app
from actions.web_search import web_search
from actions.weather_report import weather_action
from actions.send_message import send_message
from memory.memory_manager import load_memory, update_memory
from memory.temporary_memory import TemporaryMemory
interrupt_commands = ["mute", "quit", "exit", "stop"]
temp_memory = TemporaryMemory()
def get_base_dir():
if getattr(sys, "frozen", False):
return Path(sys.executable).parent
return Path(__file__).resolve().parent
BASE_DIR = get_base_dir()
async def get_voice_input():
return await asyncio.to_thread(record_voice)
async def ai_loop(ui: JarvisUI):
while True:
user_text = await get_voice_input()
if not user_text:
continue
if any(cmd in user_text.lower() for cmd in interrupt_commands):
stop_speaking()
temp_memory.reset()
continue
ui.write_log(f"You: {user_text}")
if temp_memory.get_current_question():
param = temp_memory.get_current_question()
temp_memory.update_parameters({param: user_text})
temp_memory.clear_current_question()
user_text = temp_memory.get_last_user_text()
temp_memory.set_last_user_text(user_text)
long_term_memory = load_memory()
def minimal_memory_for_prompt(memory: dict) -> dict:
result = {}
identity = memory.get("identity", {})
preferences = memory.get("preferences", {})
relationships = memory.get("relationships", {})
emotional_state = memory.get("emotional_state", {})
if "name" in identity:
result["user_name"] = identity["name"].get("value")
for k in ["favorite_color", "favorite_food", "favorite_music"]:
if k in preferences:
val = preferences[k].get("value")
if isinstance(val, dict) and "value" in val:
val = val["value"]
result[k] = val
for rel, info in relationships.items():
if isinstance(info, dict) and "name" in info and "value" in info["name"]:
result[f"{rel}_name"] = info["name"]["value"]
for event, info in emotional_state.items():
if "value" in info:
result[f"emotion_{event}"] = info["value"]
return {k: v for k, v in result.items() if v}
memory_for_prompt = minimal_memory_for_prompt(long_term_memory)
history_lines = temp_memory.get_history_for_prompt()
recent_history = "\n".join(history_lines.split("\n")[-5:])
if recent_history:
memory_for_prompt["recent_conversation"] = recent_history
if temp_memory.has_pending_intent():
memory_for_prompt["_pending_intent"] = temp_memory.pending_intent
memory_for_prompt["_collected_params"] = str(temp_memory.get_parameters())
try:
llm_output = get_llm_output(
user_text=user_text,
memory_block=memory_for_prompt
)
except Exception as e:
ui.write_log(f"AI ERROR: {e}")
continue
intent = llm_output.get("intent", "chat")
parameters = llm_output.get("parameters", {})
response = llm_output.get("text")
memory_update = llm_output.get("memory_update")
if memory_update and isinstance(memory_update, dict):
update_memory(memory_update)
temp_memory.set_last_ai_response(response)
if intent == "send_message":
temp_memory.set_pending_intent("send_message")
temp_memory.update_parameters(parameters)
if all(temp_memory.get_parameter(p) for p in ["receiver", "message_text", "platform"]):
threading.Thread(
target=send_message,
kwargs={
"parameters": temp_memory.get_parameters(),
"player": ui,
"session_memory": temp_memory
},
daemon=True
).start()
elif intent == "open_app":
if parameters.get("app_name"):
threading.Thread(
target=open_app,
kwargs={
"parameters": parameters,
"response": response,
"player": ui,
"session_memory": temp_memory
},
daemon=True
).start()
elif intent == "weather_report":
if parameters.get("city"):
threading.Thread(
target=weather_action,
kwargs={
"parameters": parameters,
"player": ui,
"session_memory": temp_memory
},
daemon=True
).start()
elif intent == "search":
if parameters.get("query"):
threading.Thread(
target=web_search,
kwargs={
"parameters": parameters,
"player": ui,
"session_memory": temp_memory
},
daemon=True
).start()
else:
if response:
ui.write_log(f"AI: {response}")
edge_speak(response, ui)
await asyncio.sleep(0.01)
def main():
ui = JarvisUI(BASE_DIR / "face.png", size=(900, 900))
def runner():
asyncio.run(ai_loop(ui))
threading.Thread(target=runner, daemon=True).start()
ui.root.mainloop()
if __name__ == "__main__":
main()