chore: fix imports

This commit is contained in:
Junyan Qin
2025-11-16 17:44:18 +08:00
parent 75edeb7a01
commit 418cddd657
38 changed files with 110 additions and 248 deletions

View File

@@ -1,23 +0,0 @@
include README.md
include LICENSE
include pyproject.toml
# Include all Python packages
recursive-include langbot *.py
recursive-include pkg *.py
recursive-include libs *.py
# Include templates and resources
recursive-include langbot/templates *
recursive-include res *
# Include compiled frontend files (will be added during build)
recursive-include web/out *
# Exclude unnecessary files
global-exclude *.pyc
global-exclude *.pyo
global-exclude __pycache__
global-exclude .DS_Store
global-exclude *.so
global-exclude *.dylib

118
main.py
View File

@@ -1,117 +1,3 @@
import asyncio
import argparse
# LangBot 终端启动入口
# 在此层级解决依赖项检查。
# LangBot/main.py
import langbot.__main__
asciiart = r"""
_ ___ _
| | __ _ _ _ __ _| _ ) ___| |_
| |__/ _` | ' \/ _` | _ \/ _ \ _|
|____\__,_|_||_\__, |___/\___/\__|
|___/
⭐️ Open Source 开源地址: https://github.com/langbot-app/LangBot
📖 Documentation 文档地址: https://docs.langbot.app
"""
async def main_entry(loop: asyncio.AbstractEventLoop):
parser = argparse.ArgumentParser(description='LangBot')
parser.add_argument(
'--standalone-runtime',
action='store_true',
help='Use standalone plugin runtime / 使用独立插件运行时',
default=False,
)
parser.add_argument('--debug', action='store_true', help='Debug mode / 调试模式', default=False)
args = parser.parse_args()
if args.standalone_runtime:
from pkg.utils import platform
platform.standalone_runtime = True
if args.debug:
from pkg.utils import constants
constants.debug_mode = True
print(asciiart)
import sys
# 检查依赖
from pkg.core.bootutils import deps
missing_deps = await deps.check_deps()
if missing_deps:
print('以下依赖包未安装,将自动安装,请完成后重启程序:')
print(
'These dependencies are missing, they will be installed automatically, please restart the program after completion:'
)
for dep in missing_deps:
print('-', dep)
await deps.install_deps(missing_deps)
print('已自动安装缺失的依赖包,请重启程序。')
print('The missing dependencies have been installed automatically, please restart the program.')
sys.exit(0)
# # 检查pydantic版本如果没有 pydantic.v1则把 pydantic 映射为 v1
# import pydantic.version
# if pydantic.version.VERSION < '2.0':
# import pydantic
# sys.modules['pydantic.v1'] = pydantic
# 检查配置文件
from pkg.core.bootutils import files
generated_files = await files.generate_files()
if generated_files:
print('以下文件不存在,已自动生成:')
print('Following files do not exist and have been automatically generated:')
for file in generated_files:
print('-', file)
from pkg.core import boot
await boot.main(loop)
if __name__ == '__main__':
import os
import sys
# 必须大于 3.10.1
if sys.version_info < (3, 10, 1):
print('需要 Python 3.10.1 及以上版本,当前 Python 版本为:', sys.version)
input('按任意键退出...')
print('Your Python version is not supported. Please exit the program by pressing any key.')
exit(1)
# Check if the current directory is the LangBot project root directory
invalid_pwd = False
if not os.path.exists('main.py'):
invalid_pwd = True
else:
with open('main.py', 'r', encoding='utf-8') as f:
content = f.read()
if 'LangBot/main.py' not in content:
invalid_pwd = True
if invalid_pwd:
print('请在 LangBot 项目根目录下以命令形式运行此程序。')
input('按任意键退出...')
print('Please run this program in the LangBot project root directory in command form.')
print('Press any key to exit...')
exit(1)
loop = asyncio.new_event_loop()
loop.run_until_complete(main_entry(loop))
langbot.__main__.main()

View File

@@ -107,8 +107,7 @@ requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[tool.setuptools]
packages = { find = {} }
include-package-data = true
package-data = { "langbot" = ["templates/*"] }
[dependency-groups]
dev = [

View File

@@ -31,12 +31,12 @@ async def main_entry(loop: asyncio.AbstractEventLoop):
args = parser.parse_args()
if args.standalone_runtime:
from pkg.utils import platform
from langbot.pkg.utils import platform
platform.standalone_runtime = True
if args.debug:
from pkg.utils import constants
from langbot.pkg.utils import constants
constants.debug_mode = True
@@ -60,7 +60,7 @@ async def main_entry(loop: asyncio.AbstractEventLoop):
sys.exit(0)
# Check configuration files
from pkg.core.bootutils import files
from langbot.pkg.core.bootutils import files
generated_files = await files.generate_files()
@@ -70,7 +70,7 @@ async def main_entry(loop: asyncio.AbstractEventLoop):
for file in generated_files:
print('-', file)
from pkg.core import boot
from langbot.pkg.core import boot
await boot.main(loop)

View File

@@ -1,12 +1,12 @@
# 微信公众号的加解密算法与企业微信一样,所以直接使用企业微信的加解密算法文件
import time
import traceback
from libs.wecom_api.WXBizMsgCrypt3 import WXBizMsgCrypt
from langbot.libs.wecom_api.WXBizMsgCrypt3 import WXBizMsgCrypt
import xml.etree.ElementTree as ET
from quart import Quart, request
import hashlib
from typing import Callable
from .oaevent import OAEvent
from langbot.libs.official_account_api.oaevent import OAEvent
import asyncio

View File

@@ -1,4 +1,4 @@
from libs.wechatpad_api.util.http_util import post_json
from langbot.libs.wechatpad_api.util.http_util import post_json
class ChatRoomApi:

View File

@@ -1,4 +1,4 @@
from libs.wechatpad_api.util.http_util import post_json
from langbot.libs.wechatpad_api.util.http_util import post_json
import httpx
import base64

View File

@@ -1,4 +1,4 @@
from libs.wechatpad_api.util.http_util import post_json, get_json
from langbot.libs.wechatpad_api.util.http_util import post_json, get_json
class LoginApi:

View File

@@ -1,4 +1,4 @@
from libs.wechatpad_api.util.http_util import post_json
from langbot.libs.wechatpad_api.util.http_util import post_json
class MessageApi:

View File

@@ -1,4 +1,4 @@
from libs.wechatpad_api.util.http_util import post_json, async_request, get_json
from langbot.libs.wechatpad_api.util.http_util import post_json, async_request, get_json
class UserApi:

View File

@@ -1,9 +1,9 @@
from libs.wechatpad_api.api.login import LoginApi
from libs.wechatpad_api.api.friend import FriendApi
from libs.wechatpad_api.api.message import MessageApi
from libs.wechatpad_api.api.user import UserApi
from libs.wechatpad_api.api.downloadpai import DownloadApi
from libs.wechatpad_api.api.chatroom import ChatRoomApi
from langbot.libs.wechatpad_api.api.login import LoginApi
from langbot.libs.wechatpad_api.api.friend import FriendApi
from langbot.libs.wechatpad_api.api.message import MessageApi
from langbot.libs.wechatpad_api.api.user import UserApi
from langbot.libs.wechatpad_api.api.downloadpai import DownloadApi
from langbot.libs.wechatpad_api.api.chatroom import ChatRoomApi
class WeChatPadClient:

View File

@@ -16,7 +16,7 @@ import struct
from Crypto.Cipher import AES
import xml.etree.cElementTree as ET
import socket
from libs.wecom_ai_bot_api import ierror
from langbot.libs.wecom_ai_bot_api import ierror
"""

View File

@@ -13,9 +13,9 @@ import httpx
from Crypto.Cipher import AES
from quart import Quart, request, Response, jsonify
from libs.wecom_ai_bot_api import wecombotevent
from libs.wecom_ai_bot_api.WXBizMsgCrypt3 import WXBizMsgCrypt
from pkg.platform.logger import EventLogger
from langbot.libs.wecom_ai_bot_api import wecombotevent
from langbot.libs.wecom_ai_bot_api.WXBizMsgCrypt3 import WXBizMsgCrypt
from langbot.pkg.platform.logger import EventLogger
@dataclass

View File

@@ -2,7 +2,7 @@ import os
import json
import importlib.resources as resources
from .. import model as file_model
from langbot.pkg.config import model as file_model
class JSONConfigFile(file_model.ConfigFile):

View File

@@ -2,7 +2,7 @@ import os
import yaml
import importlib.resources as resources
from .. import model as file_model
from langbot.pkg.config import model as file_model
class YAMLConfigFile(file_model.ConfigFile):

View File

@@ -8,7 +8,7 @@ import os
from ..platform import botmgr as im_mgr
from ..provider.session import sessionmgr as llm_session_mgr
from ..provider.modelmgr import modelmgr as llm_model_mgr
from ..provider.tools import toolmgr as llm_tool_mgr
from langbot.pkg.provider.tools import toolmgr as llm_tool_mgr
from ..config import manager as config_mgr
from ..command import cmdmgr
from ..plugin import connector as plugin_connector

View File

@@ -37,7 +37,7 @@ class BuildAppStage(stage.BootingStage):
ap.task_mgr = taskmgr.AsyncTaskManager(ap)
discover = discover_engine.ComponentDiscoveryEngine(ap)
discover.discover_blueprint('components.yaml')
discover.discover_blueprint('templates/components.yaml')
ap.discover = discover
proxy_mgr = proxy.ProxyManager(ap)

View File

@@ -6,7 +6,8 @@ import os
import yaml
import pydantic
from ..core import app
from langbot.pkg.core import app
from langbot.pkg.utils import importutil
class I18nString(pydantic.BaseModel):
@@ -165,7 +166,7 @@ class Component(pydantic.BaseModel):
if module_path.endswith('.py'):
module_path = module_path[:-3]
module_path = module_path.replace('/', '.').replace('\\', '.')
module = importlib.import_module(module_path)
module = importlib.import_module(f'langbot.{module_path}')
return getattr(module, self.execution.python.attr)
def to_plain_dict(self) -> dict:
@@ -193,16 +194,17 @@ class ComponentDiscoveryEngine:
def load_component_manifest(self, path: str, owner: str = 'builtin', no_save: bool = False) -> Component | None:
"""加载组件清单"""
with open(path, 'r', encoding='utf-8') as f:
manifest = yaml.safe_load(f)
if not Component.is_component_manifest(manifest):
return None
comp = Component(owner=owner, manifest=manifest, rel_path=path)
if not no_save:
if comp.kind not in self.components:
self.components[comp.kind] = []
self.components[comp.kind].append(comp)
return comp
# with open(path, 'r', encoding='utf-8') as f:
# manifest = yaml.safe_load(f)
manifest = yaml.safe_load(importutil.read_resource_file(path))
if not Component.is_component_manifest(manifest):
return None
comp = Component(owner=owner, manifest=manifest, rel_path=path)
if not no_save:
if comp.kind not in self.components:
self.components[comp.kind] = []
self.components[comp.kind].append(comp)
return comp
def load_component_manifests_in_dir(
self,
@@ -217,7 +219,8 @@ class ComponentDiscoveryEngine:
def recursive_load_component_manifests_in_dir(path: str, depth: int = 1):
if depth > max_depth:
return
for file in os.listdir(path):
for file in importutil.list_resource_files(path):
if (not os.path.isdir(os.path.join(path, file))) and (file.endswith('.yaml') or file.endswith('.yml')):
comp = self.load_component_manifest(os.path.join(path, file), owner, no_save)
if comp is not None:

View File

@@ -1,13 +1,13 @@
import traceback
import typing
from libs.dingtalk_api.dingtalkevent import DingTalkEvent
from langbot.libs.dingtalk_api.dingtalkevent import DingTalkEvent
import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter
import langbot_plugin.api.entities.builtin.platform.events as platform_events
import langbot_plugin.api.entities.builtin.platform.entities as platform_entities
from libs.dingtalk_api.api import DingTalkClient
from langbot.libs.dingtalk_api.api import DingTalkClient
import datetime
from ..logger import EventLogger
from langbot.pkg.platform.logger import EventLogger
class DingTalkMessageConverter(abstract_platform_adapter.AbstractMessageConverter):

View File

@@ -5,13 +5,13 @@ import traceback
import pydantic
import datetime
import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter
from libs.official_account_api.oaevent import OAEvent
from libs.official_account_api.api import OAClient
from libs.official_account_api.api import OAClientForLongerResponse
from langbot.libs.official_account_api.oaevent import OAEvent
from langbot.libs.official_account_api.api import OAClient
from langbot.libs.official_account_api.api import OAClientForLongerResponse
import langbot_plugin.api.entities.builtin.platform.entities as platform_entities
import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.entities.builtin.platform.events as platform_events
from ..logger import EventLogger
from langbot.pkg.platform.logger import EventLogger
class OAMessageConverter(abstract_platform_adapter.AbstractMessageConverter):

View File

@@ -9,10 +9,10 @@ import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platf
import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.entities.builtin.platform.events as platform_events
import langbot_plugin.api.entities.builtin.platform.entities as platform_entities
from libs.qq_official_api.api import QQOfficialClient
from libs.qq_official_api.qqofficialevent import QQOfficialEvent
from ...utils import image
from ..logger import EventLogger
from langbot.libs.qq_official_api.api import QQOfficialClient
from langbot.libs.qq_official_api.qqofficialevent import QQOfficialEvent
from langbot.pkg.utils import image
from langbot.pkg.platform.logger import EventLogger
class QQOfficialMessageConverter(abstract_platform_adapter.AbstractMessageConverter):

View File

@@ -5,15 +5,15 @@ import traceback
import datetime
from libs.slack_api.api import SlackClient
from langbot.libs.slack_api.api import SlackClient
import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter
from libs.slack_api.slackevent import SlackEvent
from langbot.libs.slack_api.slackevent import SlackEvent
import langbot_plugin.api.entities.builtin.platform.events as platform_events
import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.entities.builtin.platform.entities as platform_entities
from langbot_plugin.api.entities.builtin.command import errors as command_errors
from ...utils import image
from ..logger import EventLogger
from langbot.pkg.utils import image
from langbot.pkg.platform.logger import EventLogger
class SlackMessageConverter(abstract_platform_adapter.AbstractMessageConverter):

View File

@@ -4,7 +4,7 @@ import json
import time
import httpx
from libs.wechatpad_api.client import WeChatPadClient
from langbot.libs.wechatpad_api.client import WeChatPadClient
import typing
import asyncio
@@ -16,7 +16,7 @@ import threading
import quart
from ..logger import EventLogger
from langbot.pkg.platform.logger import EventLogger
import xml.etree.ElementTree as ET
from typing import Optional, Tuple
from functools import partial

View File

@@ -5,11 +5,11 @@ import traceback
import datetime
from libs.wecom_api.api import WecomClient
from langbot.libs.wecom_api.api import WecomClient
import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter
from libs.wecom_api.wecomevent import WecomEvent
from ...utils import image
from ..logger import EventLogger
from langbot.libs.wecom_api.wecomevent import WecomEvent
from langbot.pkg.utils import image
from langbot.pkg.platform.logger import EventLogger
import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.entities.builtin.platform.events as platform_events
import langbot_plugin.api.entities.builtin.platform.entities as platform_entities

View File

@@ -8,9 +8,9 @@ import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platf
import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.entities.builtin.platform.events as platform_events
import langbot_plugin.api.entities.builtin.platform.entities as platform_entities
from ..logger import EventLogger
from libs.wecom_ai_bot_api.wecombotevent import WecomBotEvent
from libs.wecom_ai_bot_api.api import WecomBotClient
from langbot.pkg.platform.logger import EventLogger
from langbot.libs.wecom_ai_bot_api.wecombotevent import WecomBotEvent
from langbot.libs.wecom_ai_bot_api.api import WecomBotClient
class WecomBotMessageConverter(abstract_platform_adapter.AbstractMessageConverter):

View File

@@ -6,9 +6,9 @@ import traceback
import datetime
import pydantic
from libs.wecom_customer_service_api.api import WecomCSClient
from langbot.libs.wecom_customer_service_api.api import WecomCSClient
import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter
from libs.wecom_customer_service_api.wecomcsevent import WecomCSEvent
from langbot.libs.wecom_customer_service_api.wecomcsevent import WecomCSEvent
import langbot_plugin.api.entities.builtin.platform.entities as platform_entities
import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.entities.builtin.platform.events as platform_events

View File

@@ -4,12 +4,12 @@ import typing
import json
import base64
from .. import runner
from ...core import app
from langbot.pkg.provider import runner
from langbot.pkg.core import app
import langbot_plugin.api.entities.builtin.provider.message as provider_message
from ...utils import image
from langbot.pkg.utils import image
import langbot_plugin.api.entities.builtin.pipeline.query as pipeline_query
from libs.coze_server_api.client import AsyncCozeAPIClient
from langbot.libs.coze_server_api.client import AsyncCozeAPIClient
@runner.runner_class('coze-api')

View File

@@ -6,12 +6,12 @@ import uuid
import base64
from .. import runner
from ...core import app
from langbot.pkg.provider import runner
from langbot.pkg.core import app
import langbot_plugin.api.entities.builtin.provider.message as provider_message
from ...utils import image
from langbot.pkg.utils import image
import langbot_plugin.api.entities.builtin.pipeline.query as pipeline_query
from libs.dify_service_api.v1 import client, errors
from langbot.libs.dify_service_api.v1 import client, errors
@runner.runner_class('dify-service-api')

View File

@@ -3,9 +3,9 @@ from __future__ import annotations
import typing
from ...core import app
from ...utils import importutil
from . import loaders
from .loaders import mcp as mcp_loader, plugin as plugin_loader
from langbot.pkg.utils import importutil
from langbot.pkg.provider.tools import loaders
from langbot.pkg.provider.tools.loaders import mcp as mcp_loader, plugin as plugin_loader
import langbot_plugin.api.entities.builtin.resource.tool as resource_tool
importutil.import_modules_in_pkg(loaders)

View File

@@ -4,13 +4,13 @@ import uuid
import zipfile
import io
from .services import parser, chunker
from pkg.core import app
from pkg.rag.knowledge.services.embedder import Embedder
from pkg.rag.knowledge.services.retriever import Retriever
from langbot.pkg.core import app
from langbot.pkg.rag.knowledge.services.embedder import Embedder
from langbot.pkg.rag.knowledge.services.retriever import Retriever
import sqlalchemy
from ...entity.persistence import rag as persistence_rag
from pkg.core import taskmgr
from ...entity.rag import retriever as retriever_entities
from langbot.pkg.entity.persistence import rag as persistence_rag
from langbot.pkg.core import taskmgr
from langbot.pkg.entity.rag import retriever as retriever_entities
class RuntimeKnowledgeBase:

View File

@@ -2,8 +2,8 @@ from __future__ import annotations
import json
from typing import List
from pkg.rag.knowledge.services import base_service
from pkg.core import app
from langbot.pkg.rag.knowledge.services import base_service
from langbot.pkg.core import app
from langchain_text_splitters import RecursiveCharacterTextSplitter

View File

@@ -1,10 +1,10 @@
from __future__ import annotations
import uuid
from typing import List
from pkg.rag.knowledge.services.base_service import BaseService
from ....entity.persistence import rag as persistence_rag
from ....core import app
from ....provider.modelmgr.requester import RuntimeEmbeddingModel
from langbot.pkg.rag.knowledge.services.base_service import BaseService
from langbot.pkg.entity.persistence import rag as persistence_rag
from langbot.pkg.core import app
from langbot.pkg.provider.modelmgr.requester import RuntimeEmbeddingModel
import sqlalchemy

View File

@@ -9,7 +9,7 @@ import markdown
from bs4 import BeautifulSoup
import re
import asyncio # Import asyncio for async operations
from pkg.core import app
from langbot.pkg.core import app
class FileParser:

View File

@@ -1,5 +1,5 @@
import importlib
import importlib.util
import importlib.resources
import os
import typing
@@ -25,7 +25,7 @@ def import_dot_style_dir(dot_sep_path: str):
return import_dir(os.path.join(*sec))
def import_dir(path: str):
def import_dir(path: str, path_prefix: str = 'langbot.'):
for file in os.listdir(path):
if file.endswith('.py') and file != '__init__.py':
full_path = os.path.join(path, file)
@@ -33,10 +33,13 @@ def import_dir(path: str):
rel_path = rel_path[1:]
rel_path = rel_path.replace('/', '.')[:-3]
rel_path = rel_path.replace('\\', '.')
importlib.import_module(rel_path)
importlib.import_module(f'{path_prefix}{rel_path}')
if __name__ == '__main__':
from pkg.platform import types
def read_resource_file(resource_path: str) -> str:
with importlib.resources.files('langbot').joinpath(resource_path).open('r', encoding='utf-8') as f:
return f.read()
import_modules_in_pkg(types)
def list_resource_files(resource_path: str) -> list[str]:
return [f.name for f in importlib.resources.files('langbot').joinpath(resource_path).iterdir()]

View File

@@ -2,8 +2,8 @@ from __future__ import annotations
import asyncio
from typing import Any
from chromadb import PersistentClient
from pkg.vector.vdb import VectorDatabase
from pkg.core import app
from langbot.pkg.vector.vdb import VectorDatabase
from langbot.pkg.core import app
import chromadb
import chromadb.errors

View File

@@ -3,8 +3,8 @@ from __future__ import annotations
from typing import Any, Dict, List
from qdrant_client import AsyncQdrantClient, models
from pkg.core import app
from pkg.vector.vdb import VectorDatabase
from langbot.pkg.core import app
from langbot.pkg.vector.vdb import VectorDatabase
class QdrantVectorDatabase(VectorDatabase):

View File

@@ -7,9 +7,6 @@ metadata:
zh_Hans: 内置组件
spec:
components:
ComponentTemplate:
fromFiles:
- pkg/provider/modelmgr/requester.yaml
MessagePlatformAdapter:
fromDirs:
- path: pkg/platform/sources/

View File

@@ -10,16 +10,13 @@ This file provides infrastructure for all pipeline tests, including:
from __future__ import annotations
import pytest
from unittest.mock import AsyncMock, MagicMock, Mock
from typing import Any
from unittest.mock import AsyncMock, Mock
import langbot_plugin.api.entities.builtin.pipeline.query as pipeline_query
import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.entities.builtin.platform.events as platform_events
import langbot_plugin.api.entities.builtin.provider.session as provider_session
import langbot_plugin.api.entities.builtin.provider.message as provider_message
from pkg.pipeline import entities as pipeline_entities
from langbot.pkg.pipeline import entities as pipeline_entities
class MockApplication:
@@ -203,7 +200,7 @@ def sample_query(sample_message_chain, sample_message_event, mock_adapter):
variables={},
resp_messages=[],
resp_message_chain=None,
current_stage_name=None
current_stage_name=None,
)
return query