-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.py
138 lines (117 loc) · 4.77 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# main.py
import sys
import traceback
import asyncio
from contextlib import asynccontextmanager
from gui.app import SCOUT
from modules.logging.logger import setup_logger, set_logging_level, logging
from PySide6.QtWidgets import QApplication
import importlib
import threading
import tracemalloc
import signal
tracemalloc.start()
set_logging_level(logging.INFO)
logger = setup_logger('main')
def custom_excepthook(exc_type, exc_value, exc_traceback):
if issubclass(exc_type, KeyboardInterrupt):
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
logger.error("".join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
sys.excepthook = custom_excepthook
should_exit = False
global_tasks = set()
dynamically_loaded_modules = []
task_lock = threading.Lock()
shutdown_event = asyncio.Event()
@asynccontextmanager
async def background_tasks():
logger.debug("Entering background_tasks context manager")
async def async_main():
while not should_exit:
await asyncio.sleep(0.01)
app.processEvents()
task = asyncio.create_task(async_main())
with task_lock:
global_tasks.add(task)
logger.debug(f"Added task {task} to global_tasks")
try:
yield
finally:
global should_exit
should_exit = True
task.cancel()
with task_lock:
global_tasks.remove(task)
logger.debug(f"Removed task {task} from global_tasks")
await task
logger.debug("Exiting background_tasks context manager")
async def run_app():
logger.debug("Starting main application loop")
try:
async with background_tasks():
await SCOUT_app.async_main()
current_llm_provider = SCOUT_app.provider_manager.get_current_llm_provider()
current_background_provider = SCOUT_app.provider_manager.get_current_background_provider()
logger.debug(f"Current LLM provider: {current_llm_provider}")
logger.debug(f"Current background provider: {current_background_provider}")
providers = {
"OpenAI": ("modules.Providers.OpenAI.OA_gen_response", "modules.Providers.OpenAI.openai_api"),
"Mistral": ("modules.Providers.Mistral.Mistral_gen_response", "modules.Providers.Mistral.Mistral_api"),
"Google": ("modules.Providers.Google.GG_gen_response", None),
"HuggingFace": ("modules.Providers.HuggingFace.HF_gen_response", None),
"Anthropic": ("modules.Providers.Anthropic.Anthropic_gen_response", "modules.Providers.Anthropic.Anthropic_api")
}
for provider, modules in providers.items():
if current_llm_provider == provider and modules[0]:
dynamically_loaded_modules.append(importlib.import_module(modules[0]))
logger.debug(f"Loaded {provider} LLM module")
if current_background_provider == provider and modules[1]:
dynamically_loaded_modules.append(importlib.import_module(modules[1]))
logger.debug(f"Loaded {provider} background provider module")
await asyncio.gather(*global_tasks, return_exceptions=True)
except Exception as e:
logger.error(f"Error in run_app: {e}")
finally:
logger.debug("All tasks completed. Exiting application loop")
for module in dynamically_loaded_modules:
try:
importlib.unload(module)
except Exception as e:
logger.error(f"Error unloading module {module.__name__}: {e}")
async def shutdown():
global should_exit
should_exit = True
if SCOUT_app:
SCOUT_app.close()
await asyncio.gather(*global_tasks, return_exceptions=True)
if SCOUT_app:
SCOUT_app.user_database.close_connection()
SCOUT_app.chat_history_database.close_connection()
logger.info("Application shutdown complete.")
def signal_handler(signum, frame):
logger.info(f"Received signal {signum}")
shutdown_event.set()
async def main():
global app, SCOUT_app
app = QApplication([])
SCOUT_app = SCOUT(shutdown_event=shutdown_event)
logger.info("SCOUT application started")
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
try:
await run_app()
await shutdown_event.wait()
except Exception as e:
logger.error(f"Unexpected error in main: {e}")
finally:
await shutdown()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
logger.info("Received keyboard interrupt. Shutting down.")
except Exception as e:
logger.error(f"An unexpected error occurred: {e}", exc_info=True)
finally:
logger.info("Application has shut down.")