mirror of
https://github.com/kimjammer/Neuro
synced 2025-05-15 07:00:28 -04:00
llmWrappers are now subclasses of abstractLLMWrapper, so different llms can be used seamlessly.
115 lines
3.7 KiB
Python
115 lines
3.7 KiB
Python
# Python Module Imports
|
|
import signal
|
|
import sys
|
|
import time
|
|
import threading
|
|
import asyncio
|
|
|
|
# Class Imports
|
|
from signals import Signals
|
|
from prompter import Prompter
|
|
from llmWrappers.llmState import LLMState
|
|
from llmWrappers.textLLMWrapper import TextLLMWrapper
|
|
from llmWrappers.imageLLMWrapper import ImageLLMWrapper
|
|
from stt import STT
|
|
from tts import TTS
|
|
from modules.twitchClient import TwitchClient
|
|
from modules.audioPlayer import AudioPlayer
|
|
from modules.vtubeStudio import VtubeStudio
|
|
from modules.multimodal import MultiModal
|
|
from modules.customPrompt import CustomPrompt
|
|
from modules.memory import Memory
|
|
from socketioServer import SocketIOServer
|
|
|
|
|
|
async def main():
|
|
print("Starting Project...")
|
|
|
|
# Register signal handler so that all threads can be exited.
|
|
def signal_handler(sig, frame):
|
|
print('Received CTRL + C, attempting to gracefully exit. Close all dashboard windows to speed up shutdown.')
|
|
signals.terminate = True
|
|
stt.API.shutdown()
|
|
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
signal.signal(signal.SIGTERM, signal_handler)
|
|
|
|
# CORE FILES
|
|
|
|
# Singleton object that every module will be able to read/write to
|
|
signals = Signals()
|
|
|
|
# MODULES
|
|
# Modules that start disabled CANNOT be enabled while the program is running.
|
|
modules = {}
|
|
module_threads = {}
|
|
|
|
# Create STT
|
|
stt = STT(signals)
|
|
# Create TTS
|
|
tts = TTS(signals)
|
|
# Create LLMWrappers
|
|
llmState = LLMState()
|
|
llms = {
|
|
"text": TextLLMWrapper(signals, tts, llmState, modules),
|
|
"image": ImageLLMWrapper(signals, tts, llmState, modules)
|
|
}
|
|
# Create Prompter
|
|
prompter = Prompter(signals, llms, modules)
|
|
|
|
# Create Discord bot
|
|
# modules['discord'] = DiscordClient(signals, stt, enabled=False)
|
|
# Create Twitch bot
|
|
modules['twitch'] = TwitchClient(signals, enabled=False)
|
|
# Create audio player
|
|
modules['audio_player'] = AudioPlayer(signals, enabled=True)
|
|
# Create Vtube Studio plugin
|
|
modules['vtube_studio'] = VtubeStudio(signals, enabled=True)
|
|
# Create Multimodal module
|
|
modules['multimodal'] = MultiModal(signals, enabled=False)
|
|
# Create Custom Prompt module
|
|
modules['custom_prompt'] = CustomPrompt(signals, enabled=True)
|
|
# Create Memory module
|
|
modules['memory'] = Memory(signals, enabled=True)
|
|
|
|
# Create Socket.io server
|
|
# The specific llmWrapper it gets doesn't matter since state is shared between all llmWrappers
|
|
sio = SocketIOServer(signals, stt, tts, llms["text"], prompter, modules=modules)
|
|
|
|
# Create threads (As daemons, so they exit when the main thread exits)
|
|
prompter_thread = threading.Thread(target=prompter.prompt_loop, daemon=True)
|
|
stt_thread = threading.Thread(target=stt.listen_loop, daemon=True)
|
|
sio_thread = threading.Thread(target=sio.start_server, daemon=True)
|
|
# Start Threads
|
|
sio_thread.start()
|
|
prompter_thread.start()
|
|
stt_thread.start()
|
|
|
|
# Create and start threads for modules
|
|
for name, module in modules.items():
|
|
module_thread = threading.Thread(target=module.init_event_loop, daemon=True)
|
|
module_threads[name] = module_thread
|
|
module_thread.start()
|
|
|
|
while not signals.terminate:
|
|
time.sleep(0.1)
|
|
print("TERMINATING ======================")
|
|
|
|
# Wait for child threads to exit before exiting main thread
|
|
|
|
# Wait for all modules to finish
|
|
for module_thread in module_threads.values():
|
|
module_thread.join()
|
|
|
|
sio_thread.join()
|
|
print("SIO EXITED ======================")
|
|
prompter_thread.join()
|
|
print("PROMPTER EXITED ======================")
|
|
# stt_thread.join()
|
|
# print("STT EXITED ======================")
|
|
|
|
print("All threads exited, shutdown complete")
|
|
sys.exit(0)
|
|
|
|
if __name__ == '__main__':
|
|
asyncio.run(main())
|