diff --git a/main.py b/main.py index 4f3373df..e4dbef02 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,5 @@ -import asyncio - +# QChatGPT 终端启动入口 +# 在此层级解决依赖项检查。 asciiart = r""" ___ ___ _ _ ___ ___ _____ @@ -11,8 +11,44 @@ 📖文档地址: https://q.rkcn.top """ -if __name__ == '__main__': + +async def main_entry(): print(asciiart) + import sys + + # 检查依赖 + + from pkg.core.bootutils import deps + + missing_deps = await deps.check_deps() + + if missing_deps: + print("以下依赖包未安装,将自动安装,请完成后重启程序:") + for dep in missing_deps: + print("-", dep) + await deps.install_deps(missing_deps) + print("已自动安装缺失的依赖包,请重启程序。") + sys.exit(0) + + # 检查配置文件 + + from pkg.core.bootutils import files + + generated_files = await files.generate_files() + + if generated_files: + print("以下文件不存在,已自动生成,请按需修改配置文件后重启:") + for file in generated_files: + print("-", file) + + sys.exit(0) + from pkg.core import boot - asyncio.run(boot.main()) + await boot.main() + + +if __name__ == '__main__': + import asyncio + + asyncio.run(main_entry()) diff --git a/pkg/core/app.py b/pkg/core/app.py index a31d2f77..80f6cc3c 100644 --- a/pkg/core/app.py +++ b/pkg/core/app.py @@ -13,8 +13,8 @@ from ..audit.center import v2 as center_mgr from ..command import cmdmgr from ..plugin import manager as plugin_mgr -from . import pool, controller -from ..pipeline import stagemgr +from ..pipeline import pool +from ..pipeline import controller, stagemgr from ..utils import version as version_mgr, proxy as proxy_mgr diff --git a/pkg/core/boot.py b/pkg/core/boot.py index 3ecfa8ae..c5790306 100644 --- a/pkg/core/boot.py +++ b/pkg/core/boot.py @@ -1,143 +1,29 @@ from __future__ import print_function -import os -import sys - -from .bootutils import files -from .bootutils import deps -from .bootutils import log -from .bootutils import config - from . import app -from . import pool -from . import controller -from ..pipeline import stagemgr from ..audit import identifier -from ..provider.session import sessionmgr as llm_session_mgr -from ..provider.requester import modelmgr as llm_model_mgr -from ..provider.sysprompt import sysprompt as llm_prompt_mgr -from ..provider.tools import toolmgr as llm_tool_mgr -from ..platform import manager as im_mgr -from ..command import cmdmgr -from ..plugin import manager as plugin_mgr -from ..audit.center import v2 as center_v2 -from ..utils import version, proxy, announce - -use_override = False - - -async def make_app() -> app.Application: - global use_override - - generated_files = await files.generate_files() +from . import stage +from .stages import load_config, setup_logger, build_app - if generated_files: - print("以下文件不存在,已自动生成,请按需修改配置文件后重启:") - for file in generated_files: - print("-", file) - sys.exit(0) +stage_order = [ + "LoadConfigStage", + "SetupLoggerStage", + "BuildAppStage" +] - missing_deps = await deps.check_deps() - if missing_deps: - print("以下依赖包未安装,将自动安装,请完成后重启程序:") - for dep in missing_deps: - print("-", dep) - await deps.install_deps(missing_deps) - sys.exit(0) - - qcg_logger = await log.init_logging() +async def make_app() -> app.Application: # 生成标识符 identifier.init() - # ========== 加载配置文件 ========== - - command_cfg = await config.load_json_config("data/config/command.json", "templates/command.json") - pipeline_cfg = await config.load_json_config("data/config/pipeline.json", "templates/pipeline.json") - platform_cfg = await config.load_json_config("data/config/platform.json", "templates/platform.json") - provider_cfg = await config.load_json_config("data/config/provider.json", "templates/provider.json") - system_cfg = await config.load_json_config("data/config/system.json", "templates/system.json") - - # ========== 构建应用实例 ========== ap = app.Application() - ap.logger = qcg_logger - - ap.command_cfg = command_cfg - ap.pipeline_cfg = pipeline_cfg - ap.platform_cfg = platform_cfg - ap.provider_cfg = provider_cfg - ap.system_cfg = system_cfg - - proxy_mgr = proxy.ProxyManager(ap) - await proxy_mgr.initialize() - ap.proxy_mgr = proxy_mgr - - ver_mgr = version.VersionManager(ap) - await ver_mgr.initialize() - ap.ver_mgr = ver_mgr - - center_v2_api = center_v2.V2CenterAPI( - ap, - basic_info={ - "host_id": identifier.identifier["host_id"], - "instance_id": identifier.identifier["instance_id"], - "semantic_version": ver_mgr.get_current_version(), - "platform": sys.platform, - }, - runtime_info={ - "admin_id": "{}".format(system_cfg.data["admin-sessions"]), - "msg_source": str([ - adapter_cfg['adapter'] if 'adapter' in adapter_cfg else 'unknown' - for adapter_cfg in platform_cfg.data['platform-adapters'] if adapter_cfg['enable'] - ]), - }, - ) - ap.ctr_mgr = center_v2_api - - # 发送公告 - ann_mgr = announce.AnnouncementManager(ap) - await ann_mgr.show_announcements() - - ap.query_pool = pool.QueryPool() - - await ap.ver_mgr.show_version_update() - - plugin_mgr_inst = plugin_mgr.PluginManager(ap) - await plugin_mgr_inst.initialize() - ap.plugin_mgr = plugin_mgr_inst - - cmd_mgr_inst = cmdmgr.CommandManager(ap) - await cmd_mgr_inst.initialize() - ap.cmd_mgr = cmd_mgr_inst - - llm_model_mgr_inst = llm_model_mgr.ModelManager(ap) - await llm_model_mgr_inst.initialize() - ap.model_mgr = llm_model_mgr_inst - - llm_session_mgr_inst = llm_session_mgr.SessionManager(ap) - await llm_session_mgr_inst.initialize() - ap.sess_mgr = llm_session_mgr_inst - - llm_prompt_mgr_inst = llm_prompt_mgr.PromptManager(ap) - await llm_prompt_mgr_inst.initialize() - ap.prompt_mgr = llm_prompt_mgr_inst - - llm_tool_mgr_inst = llm_tool_mgr.ToolManager(ap) - await llm_tool_mgr_inst.initialize() - ap.tool_mgr = llm_tool_mgr_inst - - im_mgr_inst = im_mgr.PlatformManager(ap=ap) - await im_mgr_inst.initialize() - ap.im_mgr = im_mgr_inst - - stage_mgr = stagemgr.StageManager(ap) - await stage_mgr.initialize() - ap.stage_mgr = stage_mgr - ctrl = controller.Controller(ap) - ap.ctrl = ctrl + for stage_name in stage_order: + stage_cls = stage.preregistered_stages[stage_name] + stage_inst = stage_cls() + await stage_inst.run(ap) await ap.initialize() diff --git a/pkg/core/bootutils/log.py b/pkg/core/bootutils/log.py index 308ca8c4..d7b6da0a 100644 --- a/pkg/core/bootutils/log.py +++ b/pkg/core/bootutils/log.py @@ -16,6 +16,10 @@ async def init_logging() -> logging.Logger: + # 删除所有现有的logger + for handler in logging.root.handlers[:]: + logging.root.removeHandler(handler) + level = logging.INFO if "DEBUG" in os.environ and os.environ["DEBUG"] in ["true", "1"]: @@ -46,7 +50,7 @@ async def init_logging() -> logging.Logger: qcg_logger.debug("日志初始化完成,日志级别:%s" % level) logging.basicConfig( - level=logging.INFO, # 设置日志输出格式 + level=logging.CRITICAL, # 设置日志输出格式 format="[DEPR][%(asctime)s.%(msecs)03d] %(pathname)s (%(lineno)d) - [%(levelname)s] :\n%(message)s", # 日志输出的格式 # -8表示占位符,让输出左对齐,输出长度都为8位 diff --git a/pkg/core/stage.py b/pkg/core/stage.py new file mode 100644 index 00000000..cb8e90eb --- /dev/null +++ b/pkg/core/stage.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +import abc +import typing + +from . import app + + +preregistered_stages: dict[str, typing.Type[BootingStage]] = {} + +def stage_class( + name: str +): + def decorator(cls: typing.Type[BootingStage]) -> typing.Type[BootingStage]: + preregistered_stages[name] = cls + return cls + + return decorator + + +class BootingStage(abc.ABC): + """启动阶段 + """ + name: str = None + + @abc.abstractmethod + async def run(self, ap: app.Application): + """启动 + """ + pass diff --git a/pkg/core/stages/__init__.py b/pkg/core/stages/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pkg/core/stages/build_app.py b/pkg/core/stages/build_app.py new file mode 100644 index 00000000..7a840b86 --- /dev/null +++ b/pkg/core/stages/build_app.py @@ -0,0 +1,95 @@ +from __future__ import annotations + +import sys + +from .. import stage, app +from ...utils import version, proxy, announce +from ...audit.center import v2 as center_v2 +from ...audit import identifier +from ...pipeline import pool, controller, stagemgr +from ...plugin import manager as plugin_mgr +from ...command import cmdmgr +from ...provider.session import sessionmgr as llm_session_mgr +from ...provider.requester import modelmgr as llm_model_mgr +from ...provider.sysprompt import sysprompt as llm_prompt_mgr +from ...provider.tools import toolmgr as llm_tool_mgr +from ...platform import manager as im_mgr + + +@stage.stage_class("BuildAppStage") +class BuildAppStage(stage.BootingStage): + """构建应用阶段 + """ + + async def run(self, ap: app.Application): + """启动 + """ + + proxy_mgr = proxy.ProxyManager(ap) + await proxy_mgr.initialize() + ap.proxy_mgr = proxy_mgr + + ver_mgr = version.VersionManager(ap) + await ver_mgr.initialize() + ap.ver_mgr = ver_mgr + + center_v2_api = center_v2.V2CenterAPI( + ap, + basic_info={ + "host_id": identifier.identifier["host_id"], + "instance_id": identifier.identifier["instance_id"], + "semantic_version": ver_mgr.get_current_version(), + "platform": sys.platform, + }, + runtime_info={ + "admin_id": "{}".format(ap.system_cfg.data["admin-sessions"]), + "msg_source": str([ + adapter_cfg['adapter'] if 'adapter' in adapter_cfg else 'unknown' + for adapter_cfg in ap.platform_cfg.data['platform-adapters'] if adapter_cfg['enable'] + ]), + }, + ) + ap.ctr_mgr = center_v2_api + + # 发送公告 + ann_mgr = announce.AnnouncementManager(ap) + await ann_mgr.show_announcements() + + ap.query_pool = pool.QueryPool() + + await ap.ver_mgr.show_version_update() + + plugin_mgr_inst = plugin_mgr.PluginManager(ap) + await plugin_mgr_inst.initialize() + ap.plugin_mgr = plugin_mgr_inst + + cmd_mgr_inst = cmdmgr.CommandManager(ap) + await cmd_mgr_inst.initialize() + ap.cmd_mgr = cmd_mgr_inst + + llm_model_mgr_inst = llm_model_mgr.ModelManager(ap) + await llm_model_mgr_inst.initialize() + ap.model_mgr = llm_model_mgr_inst + + llm_session_mgr_inst = llm_session_mgr.SessionManager(ap) + await llm_session_mgr_inst.initialize() + ap.sess_mgr = llm_session_mgr_inst + + llm_prompt_mgr_inst = llm_prompt_mgr.PromptManager(ap) + await llm_prompt_mgr_inst.initialize() + ap.prompt_mgr = llm_prompt_mgr_inst + + llm_tool_mgr_inst = llm_tool_mgr.ToolManager(ap) + await llm_tool_mgr_inst.initialize() + ap.tool_mgr = llm_tool_mgr_inst + + im_mgr_inst = im_mgr.PlatformManager(ap=ap) + await im_mgr_inst.initialize() + ap.im_mgr = im_mgr_inst + + stage_mgr = stagemgr.StageManager(ap) + await stage_mgr.initialize() + ap.stage_mgr = stage_mgr + + ctrl = controller.Controller(ap) + ap.ctrl = ctrl diff --git a/pkg/core/stages/load_config.py b/pkg/core/stages/load_config.py new file mode 100644 index 00000000..0ee2c1e4 --- /dev/null +++ b/pkg/core/stages/load_config.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +from .. import stage, app +from ..bootutils import config + + +@stage.stage_class("LoadConfigStage") +class LoadConfigStage(stage.BootingStage): + """加载配置文件阶段 + """ + + async def run(self, ap: app.Application): + """启动 + """ + ap.command_cfg = await config.load_json_config("data/config/command.json", "templates/command.json") + ap.pipeline_cfg = await config.load_json_config("data/config/pipeline.json", "templates/pipeline.json") + ap.platform_cfg = await config.load_json_config("data/config/platform.json", "templates/platform.json") + ap.provider_cfg = await config.load_json_config("data/config/provider.json", "templates/provider.json") + ap.system_cfg = await config.load_json_config("data/config/system.json", "templates/system.json") diff --git a/pkg/core/stages/setup_logger.py b/pkg/core/stages/setup_logger.py new file mode 100644 index 00000000..02446b85 --- /dev/null +++ b/pkg/core/stages/setup_logger.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from .. import stage, app +from ..bootutils import log + + +@stage.stage_class("SetupLoggerStage") +class SetupLoggerStage(stage.BootingStage): + """设置日志器阶段 + """ + + async def run(self, ap: app.Application): + """启动 + """ + ap.logger = await log.init_logging() diff --git a/pkg/core/controller.py b/pkg/pipeline/controller.py similarity index 98% rename from pkg/core/controller.py rename to pkg/pipeline/controller.py index 42ef435c..a48c664d 100644 --- a/pkg/core/controller.py +++ b/pkg/pipeline/controller.py @@ -4,8 +4,8 @@ import typing import traceback -from . import app, entities -from ..pipeline import entities as pipeline_entities +from ..core import app, entities +from . import entities as pipeline_entities from ..plugin import events diff --git a/pkg/core/pool.py b/pkg/pipeline/pool.py similarity index 98% rename from pkg/core/pool.py rename to pkg/pipeline/pool.py index 5c8000dd..15149296 100644 --- a/pkg/core/pool.py +++ b/pkg/pipeline/pool.py @@ -4,7 +4,7 @@ import mirai -from . import entities +from ..core import entities from ..platform import adapter as msadapter