-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.py
executable file
·146 lines (118 loc) · 5.44 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
139
140
141
142
143
144
145
146
# main.py
import sys
import traceback
import asyncio
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
tracemalloc.start()
# Set logging level
set_logging_level(logging.INFO)
# Setup main logger
logger = setup_logger('main')
# Custom exception hook to log uncaught exceptions
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()
async def run_app():
"""Run the main application loop."""
dynamically_loaded_modules = []
logger.debug("Starting main application loop")
# Create a task for SCOUT_app.async_main()
sc_task = asyncio.create_task(SCOUT_app.async_main())
with task_lock:
global_tasks.add(sc_task)
logger.debug(f"Added task {sc_task} to global_tasks")
try:
await sc_task
except asyncio.CancelledError:
logger.info("SCOUT_app.async_main() task cancelled")
finally:
with task_lock:
global_tasks.remove(sc_task)
logger.debug(f"Removed task {sc_task} from global_tasks")
# Load providers after async_main is cancelled
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}")
if current_llm_provider == "OpenAI":
dynamically_loaded_modules.append(importlib.import_module("modules.Providers.OpenAI.OA_gen_response"))
logger.debug("Loaded OpenAI LLM module")
elif current_llm_provider == "Mistral":
dynamically_loaded_modules.append(importlib.import_module("modules.Providers.Mistral.Mistral_gen_response"))
logger.debug("Loaded Mistral LLM module")
elif current_llm_provider == "Google":
dynamically_loaded_modules.append(importlib.import_module("modules.Providers.Google.GG_gen_response"))
logger.debug("Loaded Google LLM module")
elif current_llm_provider == "HuggingFace":
dynamically_loaded_modules.append(importlib.import_module("modules.Providers.HuggingFace.HF_gen_response"))
logger.debug("Loaded HuggingFace LLM module")
elif current_llm_provider == "Anthropic":
dynamically_loaded_modules.append(importlib.import_module("modules.Providers.Anthropic.Anthropic_gen_response"))
logger.debug("Loaded Anthropic LLM module")
if current_background_provider == "OpenAI":
dynamically_loaded_modules.append(importlib.import_module("modules.Providers.OpenAI.openai_api"))
logger.debug("Loaded OpenAI background provider module")
elif current_background_provider == "Mistral":
dynamically_loaded_modules.append(importlib.import_module("modules.Providers.Mistral.Mistral_api"))
logger.debug("Loaded Mistral background provider module")
elif current_background_provider == "Anthropic":
dynamically_loaded_modules.append(importlib.import_module("modules.Providers.Anthropic.Anthropic_api"))
logger.debug("Loaded Anthropic background provider module")
for module in dynamically_loaded_modules:
try:
importlib.reload(module) # Changed from unload to reload for safety
logger.debug(f"Reloaded module {module.__name__}")
except Exception as e:
logger.error(f"Error reloading module {module.__name__}: {e}")
await asyncio.gather(*global_tasks, return_exceptions=True)
logger.debug("All tasks completed. Exiting application loop")
async def shutdown():
"""Handles all cleanup and shutdown tasks."""
global should_exit
should_exit = True
logger.info("Initiating shutdown...")
# Signal the GUI to close
if SCOUT_app:
SCOUT_app.close() # Close the GUI window
# Quit the QApplication event loop
app.quit()
# Cancel all tasks except the current one
tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
logger.info(f"Cancelling {len(tasks)} pending tasks.")
for task in tasks:
task.cancel()
await asyncio.gather(*tasks, return_exceptions=True)
# Close databases
if SCOUT_app:
SCOUT_app.user_database.close_connection()
SCOUT_app.chat_history_database.close_connection()
logger.info("Application shutdown complete.")
async def main():
"""Initialize and start the application."""
global app, SCOUT_app
app = QApplication([])
SCOUT_app = SCOUT(shutdown_event=shutdown_event)
logger.info("SCOUT application started")
await run_app()
await shutdown_event.wait()
await shutdown()
if __name__ == "__main__":
try:
asyncio.run(main())
except RuntimeError as e:
logger.error(f"RuntimeError during asyncio.run: {e}")
except Exception as e:
logger.error(f"Unhandled exception: {e}")