From e0cef1391d7a437c7438d8582bdd4485148f5379 Mon Sep 17 00:00:00 2001 From: z30057876 Date: Sat, 11 Oct 2025 12:17:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/dependency/user.py | 4 ++- apps/models/app.py | 11 ++++-- apps/models/base.py | 4 +-- apps/models/document.py | 8 +++-- apps/models/flow.py | 11 ++++-- apps/routers/appcenter.py | 3 +- apps/routers/auth.py | 10 +++--- apps/routers/blacklist.py | 6 +--- apps/routers/chat.py | 9 ++--- apps/routers/comment.py | 2 +- apps/routers/conversation.py | 3 +- apps/routers/document.py | 4 ++- apps/routers/flow.py | 4 ++- apps/routers/llm.py | 2 +- apps/routers/mcp_service.py | 2 +- apps/routers/parameter.py | 4 ++- apps/routers/record.py | 10 +++--- apps/routers/service.py | 2 +- apps/routers/tag.py | 2 +- apps/routers/user.py | 4 ++- apps/scheduler/call/api/api.py | 3 +- apps/scheduler/call/facts/facts.py | 2 +- apps/scheduler/call/rag/rag.py | 2 +- apps/scheduler/call/suggest/suggest.py | 18 ++++++---- apps/scheduler/executor/__init__.py | 6 ---- apps/scheduler/executor/agent.py | 4 ++- apps/scheduler/executor/base.py | 2 +- apps/scheduler/executor/step.py | 2 +- apps/scheduler/mcp/host.py | 2 +- apps/scheduler/mcp/select.py | 2 +- apps/scheduler/pool/loader/__init__.py | 14 -------- apps/scheduler/pool/loader/call.py | 8 +++-- apps/scheduler/pool/loader/flow.py | 2 +- apps/scheduler/pool/loader/mcp.py | 3 +- apps/scheduler/pool/pool.py | 15 ++++---- apps/scheduler/scheduler/context.py | 10 +++--- apps/scheduler/scheduler/scheduler.py | 19 +++++----- apps/schemas/flow.py | 24 +------------ apps/schemas/flow_topology.py | 27 +++++++++++--- apps/schemas/scheduler.py | 5 +++ apps/services/__init__.py | 49 -------------------------- apps/services/flow.py | 3 +- apps/services/node.py | 4 ++- apps/services/parameter.py | 2 +- apps/services/record.py | 20 +++++------ 45 files changed, 153 insertions(+), 200 deletions(-) diff --git a/apps/dependency/user.py b/apps/dependency/user.py index 38d38095e..44a963b2a 100644 --- a/apps/dependency/user.py +++ b/apps/dependency/user.py @@ -8,7 +8,9 @@ from starlette.exceptions import HTTPException from starlette.requests import HTTPConnection from apps.common.config import config -from apps.services import PersonalTokenManager, SessionManager, UserManager +from apps.services.personal_token import PersonalTokenManager +from apps.services.session import SessionManager +from apps.services.user import UserManager logger = logging.getLogger(__name__) diff --git a/apps/models/app.py b/apps/models/app.py index 68ff16c59..0f41493d1 100644 --- a/apps/models/app.py +++ b/apps/models/app.py @@ -4,6 +4,7 @@ import uuid from datetime import UTC, datetime from enum import Enum as PyEnum +from typing import Any, ClassVar from sqlalchemy import BigInteger, Boolean, DateTime, Enum, ForeignKey, Index, String from sqlalchemy.dialects.postgresql import UUID @@ -57,10 +58,14 @@ class App(Base): Enum(PermissionType), default=PermissionType.PUBLIC, nullable=False, ) """权限类型""" - __table_args__ = ( + # 索引 + idx_published_updated_at: ClassVar[Index] = Index("idx_published_updated_at", "isPublished", "updatedAt") + idx_author_id_name: ClassVar[Index] = Index("idx_author_id_name", "author", "id", "name") + + __table_args__: ClassVar[tuple[Any, ...]] = ( + idx_published_updated_at, + idx_author_id_name, {"extend_existing": True}, - Index("idx_published_updated_at", "isPublished", "updatedAt"), - Index("idx_author_id_name", "author", "id", "name"), ) diff --git a/apps/models/base.py b/apps/models/base.py index 14ce5183f..f009cbf39 100644 --- a/apps/models/base.py +++ b/apps/models/base.py @@ -10,7 +10,5 @@ class Base(MappedAsDataclass, DeclarativeBase): """SQLAlchemy模型基类""" # 生成文档时需要启动这个参数,否则会触发重复导入告警 - __table_args__: ClassVar[tuple[Any, ...]] = ( - {"extend_existing": True}, - ) + __table_args__: ClassVar[dict[str, Any]] = {"extend_existing": True} diff --git a/apps/models/document.py b/apps/models/document.py index 7d7cb48b1..6e9e02405 100644 --- a/apps/models/document.py +++ b/apps/models/document.py @@ -3,6 +3,7 @@ import uuid from datetime import UTC, datetime +from typing import Any, ClassVar from sqlalchemy import DateTime, Float, ForeignKey, Index, String from sqlalchemy.dialects.postgresql import UUID @@ -37,7 +38,10 @@ class Document(Base): nullable=False, ) """文件的创建时间""" - __table_args__ = ( + # 索引 + idx_user_conversation: ClassVar[Index] = Index("idx_user_sub_conversation_id", "userSub", "conversationId") + + __table_args__: ClassVar[tuple[Any, ...]] = ( + idx_user_conversation, {"extend_existing": True}, - Index("idx_user_sub_conversation_id", "userSub", "conversationId"), ) diff --git a/apps/models/flow.py b/apps/models/flow.py index 599c0fae1..21734eeab 100644 --- a/apps/models/flow.py +++ b/apps/models/flow.py @@ -3,6 +3,7 @@ import uuid from datetime import UTC, datetime +from typing import Any, ClassVar from sqlalchemy import Boolean, DateTime, ForeignKey, Index, String, Text from sqlalchemy.dialects.postgresql import UUID @@ -41,8 +42,12 @@ class Flow(Base): nullable=False, ) """Flow的更新时间""" - __table_args__ = ( + # 索引 + idx_app_id_id: ClassVar[Index] = Index("idx_app_id_id", "appId", "id") + idx_app_id_name: ClassVar[Index] = Index("idx_app_id_name", "appId", "name") + + __table_args__: ClassVar[tuple[Any, ...]] = ( + idx_app_id_id, + idx_app_id_name, {"extend_existing": True}, - Index("idx_app_id_id", "appId", "id"), - Index("idx_app_id_name", "appId", "name"), ) diff --git a/apps/routers/appcenter.py b/apps/routers/appcenter.py index 455055670..5fdff565f 100644 --- a/apps/routers/appcenter.py +++ b/apps/routers/appcenter.py @@ -29,7 +29,8 @@ from apps.schemas.appcenter import ( ) from apps.schemas.enum_var import AppFilterType from apps.schemas.response_data import ResponseData -from apps.services import AppCenterManager, MCPServiceManager +from apps.services.appcenter import AppCenterManager +from apps.services.mcp_service import MCPServiceManager logger = logging.getLogger(__name__) router = APIRouter( diff --git a/apps/routers/auth.py b/apps/routers/auth.py index 5300f1994..c6ecc40a1 100644 --- a/apps/routers/auth.py +++ b/apps/routers/auth.py @@ -22,12 +22,10 @@ from apps.schemas.response_data import ( OidcRedirectRsp, ResponseData, ) -from apps.services import ( - PersonalTokenManager, - SessionManager, - TokenManager, - UserManager, -) +from apps.services.personal_token import PersonalTokenManager +from apps.services.session import SessionManager +from apps.services.token import TokenManager +from apps.services.user import UserManager admin_router = APIRouter( prefix="/api/auth", diff --git a/apps/routers/blacklist.py b/apps/routers/blacklist.py index 194aa2207..d1ec7518e 100644 --- a/apps/routers/blacklist.py +++ b/apps/routers/blacklist.py @@ -18,11 +18,7 @@ from apps.schemas.blacklist import ( from apps.schemas.response_data import ( ResponseData, ) -from apps.services import ( - AbuseManager, - QuestionBlacklistManager, - UserBlacklistManager, -) +from apps.services.blacklist import AbuseManager, QuestionBlacklistManager, UserBlacklistManager admin_router = APIRouter( prefix="/api/blacklist", diff --git a/apps/routers/chat.py b/apps/routers/chat.py index 32e8c81c7..fc2a56527 100644 --- a/apps/routers/chat.py +++ b/apps/routers/chat.py @@ -16,12 +16,9 @@ from apps.scheduler.scheduler import Scheduler from apps.scheduler.scheduler.context import save_data from apps.schemas.request_data import RequestData from apps.schemas.response_data import ResponseData -from apps.services import ( - Activity, - FlowManager, - QuestionBlacklistManager, - UserBlacklistManager, -) +from apps.services.activity import Activity +from apps.services.blacklist import QuestionBlacklistManager, UserBlacklistManager +from apps.services.flow import FlowManager RECOMMEND_TRES = 5 _logger = logging.getLogger(__name__) diff --git a/apps/routers/comment.py b/apps/routers/comment.py index ea79c7209..276035ff7 100644 --- a/apps/routers/comment.py +++ b/apps/routers/comment.py @@ -11,7 +11,7 @@ from apps.dependency import verify_personal_token, verify_session from apps.schemas.comment import AddCommentData from apps.schemas.record import RecordComment from apps.schemas.response_data import ResponseData -from apps.services import CommentManager +from apps.services.comment import CommentManager _logger = logging.getLogger(__name__) router = APIRouter( diff --git a/apps/routers/conversation.py b/apps/routers/conversation.py index fa99262eb..0707192b9 100644 --- a/apps/routers/conversation.py +++ b/apps/routers/conversation.py @@ -20,7 +20,8 @@ from apps.schemas.conversation import ( UpdateConversationRsp, ) from apps.schemas.response_data import ResponseData -from apps.services import ConversationManager, DocumentManager +from apps.services.conversation import ConversationManager +from apps.services.document import DocumentManager router = APIRouter( prefix="/api/conversation", diff --git a/apps/routers/document.py b/apps/routers/document.py index daf1de369..ddf076953 100644 --- a/apps/routers/document.py +++ b/apps/routers/document.py @@ -18,7 +18,9 @@ from apps.schemas.document import ( ) from apps.schemas.enum_var import DocumentStatus from apps.schemas.response_data import ResponseData -from apps.services import ConversationManager, DocumentManager, KnowledgeBaseService +from apps.services.conversation import ConversationManager +from apps.services.document import DocumentManager +from apps.services.knowledge_service import KnowledgeBaseService router = APIRouter( prefix="/api/document", diff --git a/apps/routers/flow.py b/apps/routers/flow.py index ab6a084cd..799cd4e53 100644 --- a/apps/routers/flow.py +++ b/apps/routers/flow.py @@ -19,7 +19,9 @@ from apps.schemas.flow import ( from apps.schemas.request_data import PutFlowReq from apps.schemas.response_data import ResponseData from apps.schemas.service import NodeServiceListMsg, NodeServiceListRsp -from apps.services import AppCenterManager, FlowManager, FlowServiceManager +from apps.services.appcenter import AppCenterManager +from apps.services.flow import FlowManager +from apps.services.flow_service import FlowServiceManager router = APIRouter( prefix="/api/flow", diff --git a/apps/routers/llm.py b/apps/routers/llm.py index 8c644736c..ab9cf0d9a 100644 --- a/apps/routers/llm.py +++ b/apps/routers/llm.py @@ -12,7 +12,7 @@ from apps.schemas.response_data import ( ListLLMRsp, ResponseData, ) -from apps.services import LLMManager +from apps.services.llm import LLMManager router = APIRouter( prefix="/api/llm", diff --git a/apps/routers/mcp_service.py b/apps/routers/mcp_service.py index a370da3e4..b59d6aa00 100644 --- a/apps/routers/mcp_service.py +++ b/apps/routers/mcp_service.py @@ -25,7 +25,7 @@ from apps.schemas.mcp_service import ( UploadMCPServiceIconRsp, ) from apps.schemas.response_data import ResponseData -from apps.services import MCPServiceManager +from apps.services.mcp_service import MCPServiceManager _logger = logging.getLogger(__name__) router = APIRouter( diff --git a/apps/routers/parameter.py b/apps/routers/parameter.py index bfc5c1062..3c46d2cd0 100644 --- a/apps/routers/parameter.py +++ b/apps/routers/parameter.py @@ -9,7 +9,9 @@ from fastapi.responses import JSONResponse from apps.dependency.user import verify_personal_token, verify_session from apps.schemas.parameters import Type from apps.schemas.response_data import GetOperaRsp, GetParamsRsp -from apps.services import AppCenterManager, FlowManager, ParameterManager +from apps.services.appcenter import AppCenterManager +from apps.services.flow import FlowManager +from apps.services.parameter import ParameterManager router = APIRouter( prefix="/api/parameter", diff --git a/apps/routers/record.py b/apps/routers/record.py index d6ad82595..b3e488691 100644 --- a/apps/routers/record.py +++ b/apps/routers/record.py @@ -23,12 +23,10 @@ from apps.schemas.response_data import ( RecordListRsp, ResponseData, ) -from apps.services import ( - ConversationManager, - DocumentManager, - RecordManager, - TaskManager, -) +from apps.services.conversation import ConversationManager +from apps.services.document import DocumentManager +from apps.services.record import RecordManager +from apps.services.task import TaskManager router = APIRouter( prefix="/api/record", diff --git a/apps/routers/service.py b/apps/routers/service.py index 6e428540f..46e43b154 100644 --- a/apps/routers/service.py +++ b/apps/routers/service.py @@ -30,7 +30,7 @@ from apps.schemas.service import ( UpdateServiceRequest, UpdateServiceRsp, ) -from apps.services import ServiceCenterManager +from apps.services.service import ServiceCenterManager _logger = logging.getLogger(__name__) router = APIRouter( diff --git a/apps/routers/tag.py b/apps/routers/tag.py index fb566b307..391a28e38 100644 --- a/apps/routers/tag.py +++ b/apps/routers/tag.py @@ -7,7 +7,7 @@ from fastapi.responses import JSONResponse from apps.dependency.user import verify_admin, verify_personal_token, verify_session from apps.schemas.request_data import PostTagData from apps.schemas.response_data import ResponseData -from apps.services import TagManager +from apps.services.tag import TagManager admin_router = APIRouter( prefix="/api/tag", diff --git a/apps/routers/user.py b/apps/routers/user.py index ef991246b..7316ffb29 100644 --- a/apps/routers/user.py +++ b/apps/routers/user.py @@ -9,7 +9,9 @@ from apps.schemas.request_data import UpdateUserSelectedLLMReq, UserUpdateReques from apps.schemas.response_data import ResponseData, UserGetMsp, UserGetRsp, UserSelectedLLMData from apps.schemas.tag import UserTagListResponse from apps.schemas.user import UserInfo -from apps.services import LLMManager, UserManager, UserTagManager +from apps.services.llm import LLMManager +from apps.services.user import UserManager +from apps.services.user_tag import UserTagManager router = APIRouter( prefix="/api/user", diff --git a/apps/scheduler/call/api/api.py b/apps/scheduler/call/api/api.py index e5b0c2c9f..774e10f09 100644 --- a/apps/scheduler/call/api/api.py +++ b/apps/scheduler/call/api/api.py @@ -22,7 +22,8 @@ from apps.schemas.scheduler import ( CallOutputChunk, CallVars, ) -from apps.services import ServiceCenterManager, TokenManager +from apps.services.service import ServiceCenterManager +from apps.services.token import TokenManager from .schema import APIInput, APIOutput diff --git a/apps/scheduler/call/facts/facts.py b/apps/scheduler/call/facts/facts.py index a13bee732..6cbb3889c 100644 --- a/apps/scheduler/call/facts/facts.py +++ b/apps/scheduler/call/facts/facts.py @@ -12,7 +12,7 @@ from apps.models import LanguageType, NodeInfo from apps.scheduler.call.core import CoreCall from apps.schemas.enum_var import CallOutputType from apps.schemas.scheduler import CallInfo, CallOutputChunk, CallVars -from apps.services import UserTagManager +from apps.services.user_tag import UserTagManager from .prompt import DOMAIN_PROMPT, FACTS_PROMPT from .schema import ( diff --git a/apps/scheduler/call/rag/rag.py b/apps/scheduler/call/rag/rag.py index c1e6e5b4e..104d898fa 100644 --- a/apps/scheduler/call/rag/rag.py +++ b/apps/scheduler/call/rag/rag.py @@ -23,7 +23,7 @@ from apps.schemas.scheduler import ( CallOutputChunk, CallVars, ) -from apps.services import DocumentManager +from apps.services.document import DocumentManager from .prompt import QUESTION_REWRITE from .schema import ( diff --git a/apps/scheduler/call/suggest/suggest.py b/apps/scheduler/call/suggest/suggest.py index a23b62055..98927ada6 100644 --- a/apps/scheduler/call/suggest/suggest.py +++ b/apps/scheduler/call/suggest/suggest.py @@ -22,7 +22,9 @@ from apps.schemas.scheduler import ( CallOutputChunk, CallVars, ) -from apps.services import FlowManager, RecordManager, UserTagManager +from apps.services.flow import FlowManager +from apps.services.record import RecordManager +from apps.services.user_tag import UserTagManager from .prompt import SUGGEST_PROMPT from .schema import ( @@ -44,7 +46,7 @@ class Suggestion(CoreCall, input_model=SuggestionInput, output_model=SuggestionO configs: list[SingleFlowSuggestionConfig] = Field(description="问题推荐配置", default=[]) num: int = Field(default=3, ge=1, le=6, description="推荐问题的总数量(当appId为None时使用)") - conversation_id: SkipJsonSchema[uuid.UUID] = Field(description="对话ID", exclude=True) + conversation_id: SkipJsonSchema[uuid.UUID | None] = Field(description="对话ID", exclude=True) @classmethod @@ -76,10 +78,13 @@ class Suggestion(CoreCall, input_model=SuggestionInput, output_model=SuggestionO async def _init(self, call_vars: CallVars) -> SuggestionInput: """初始化""" - self._history_questions = await self._get_history_questions( - call_vars.ids.user_sub, - self.conversation_id, - ) + if self.conversation_id is None: + self._history_questions = [] + else: + self._history_questions = await self._get_history_questions( + call_vars.ids.user_sub, + self.conversation_id, + ) self._app_id = call_vars.ids.app_id self._flow_id = call_vars.ids.executor_id self._env = SandboxedEnvironment( @@ -91,6 +96,7 @@ class Suggestion(CoreCall, input_model=SuggestionInput, output_model=SuggestionO self._avaliable_flows = {} # 只有当_app_id不为None时才获取Flow信息 + if self._app_id is not None: flows = await FlowManager.get_flows_by_app_id(self._app_id) for flow in flows: diff --git a/apps/scheduler/executor/__init__.py b/apps/scheduler/executor/__init__.py index 636c687fc..2e31bb1df 100644 --- a/apps/scheduler/executor/__init__.py +++ b/apps/scheduler/executor/__init__.py @@ -1,8 +1,2 @@ # Copyright (c) Huawei Technologies Co., Ltd. 2023-2025. All rights reserved. """Executor模块""" - -from .agent import MCPAgentExecutor -from .flow import FlowExecutor -from .qa import QAExecutor - -__all__ = ["FlowExecutor", "MCPAgentExecutor", "QAExecutor"] diff --git a/apps/scheduler/executor/agent.py b/apps/scheduler/executor/agent.py index 4694ec968..1626e1798 100644 --- a/apps/scheduler/executor/agent.py +++ b/apps/scheduler/executor/agent.py @@ -19,7 +19,9 @@ from apps.schemas.agent import AgentAppMetadata from apps.schemas.enum_var import EventType from apps.schemas.mcp import Step from apps.schemas.message import FlowParams -from apps.services import AppCenterManager, MCPServiceManager, UserManager +from apps.services.appcenter import AppCenterManager +from apps.services.mcp_service import MCPServiceManager +from apps.services.user import UserManager if TYPE_CHECKING: from apps.models.task import ExecutorCheckpoint diff --git a/apps/scheduler/executor/base.py b/apps/scheduler/executor/base.py index a7e465341..28496445c 100644 --- a/apps/scheduler/executor/base.py +++ b/apps/scheduler/executor/base.py @@ -11,7 +11,7 @@ from apps.schemas.enum_var import EventType from apps.schemas.message import TextAddContent from apps.schemas.record import RecordContent from apps.schemas.scheduler import ExecutorBackground -from apps.services import RecordManager +from apps.services.record import RecordManager if TYPE_CHECKING: from apps.common.queue import MessageQueue diff --git a/apps/scheduler/executor/step.py b/apps/scheduler/executor/step.py index 57a783b88..ef6acf459 100644 --- a/apps/scheduler/executor/step.py +++ b/apps/scheduler/executor/step.py @@ -24,7 +24,7 @@ from apps.schemas.enum_var import ( ) from apps.schemas.message import TextAddContent from apps.schemas.scheduler import CallError, CallOutputChunk, ExecutorBackground -from apps.services import NodeManager +from apps.services.node import NodeManager from .base import BaseExecutor diff --git a/apps/scheduler/mcp/host.py b/apps/scheduler/mcp/host.py index 8e2ead75b..20007dcc6 100644 --- a/apps/scheduler/mcp/host.py +++ b/apps/scheduler/mcp/host.py @@ -17,7 +17,7 @@ from apps.scheduler.pool.mcp.client import MCPClient from apps.scheduler.pool.mcp.pool import MCPPool from apps.schemas.mcp import MCPContext, MCPPlanItem from apps.schemas.scheduler import LLMConfig -from apps.services import MCPServiceManager +from apps.services.mcp_service import MCPServiceManager logger = logging.getLogger(__name__) diff --git a/apps/scheduler/mcp/select.py b/apps/scheduler/mcp/select.py index 00b9219c8..071439314 100644 --- a/apps/scheduler/mcp/select.py +++ b/apps/scheduler/mcp/select.py @@ -10,7 +10,7 @@ from apps.llm import JsonGenerator from apps.models import MCPTools from apps.schemas.mcp import MCPSelectResult from apps.schemas.scheduler import LLMConfig -from apps.services import MCPServiceManager +from apps.services.mcp_service import MCPServiceManager logger = logging.getLogger(__name__) diff --git a/apps/scheduler/pool/loader/__init__.py b/apps/scheduler/pool/loader/__init__.py index c78ef6c4c..27f9731ed 100644 --- a/apps/scheduler/pool/loader/__init__.py +++ b/apps/scheduler/pool/loader/__init__.py @@ -1,16 +1,2 @@ # Copyright (c) Huawei Technologies Co., Ltd. 2023-2025. All rights reserved. """配置加载器""" - -from .app import AppLoader -from .call import CallLoader -from .flow import FlowLoader -from .mcp import MCPLoader -from .service import ServiceLoader - -__all__ = [ - "AppLoader", - "CallLoader", - "FlowLoader", - "MCPLoader", - "ServiceLoader", -] diff --git a/apps/scheduler/pool/loader/call.py b/apps/scheduler/pool/loader/call.py index 8b7791504..f6bc3bdfb 100644 --- a/apps/scheduler/pool/loader/call.py +++ b/apps/scheduler/pool/loader/call.py @@ -1,13 +1,12 @@ # Copyright (c) Huawei Technologies Co., Ltd. 2023-2025. All rights reserved. """Call 加载器""" +import importlib import logging from sqlalchemy import delete -import apps.scheduler.call as system_call from apps.common.postgres import postgres -from apps.common.singleton import SingletonMeta from apps.llm import Embedding from apps.models import NodeInfo from apps.schemas.scheduler import CallInfo @@ -15,13 +14,16 @@ from apps.schemas.scheduler import CallInfo _logger = logging.getLogger(__name__) -class CallLoader(metaclass=SingletonMeta): +class CallLoader: """Call 加载器""" async def _load_system_call(self) -> dict[str, CallInfo]: """加载系统Call""" call_metadata = {} + # 动态导入 apps.scheduler.call 模块 + system_call = importlib.import_module("apps.scheduler.call") + # 检查合法性 for call_id in system_call.__all__: call_cls = getattr(system_call, call_id) diff --git a/apps/scheduler/pool/loader/flow.py b/apps/scheduler/pool/loader/flow.py index d87a05d4c..f410d8ea6 100644 --- a/apps/scheduler/pool/loader/flow.py +++ b/apps/scheduler/pool/loader/flow.py @@ -19,7 +19,7 @@ from apps.models import Flow as FlowInfo from apps.scheduler.util import yaml_enum_presenter, yaml_str_presenter from apps.schemas.enum_var import EdgeType, NodeType from apps.schemas.flow import Flow -from apps.services import NodeManager +from apps.services.node import NodeManager logger = logging.getLogger(__name__) BASE_PATH = Path(config.deploy.data_dir) / "semantics" / "app" diff --git a/apps/scheduler/pool/loader/mcp.py b/apps/scheduler/pool/loader/mcp.py index 2c9ea0d91..6935e361e 100644 --- a/apps/scheduler/pool/loader/mcp.py +++ b/apps/scheduler/pool/loader/mcp.py @@ -12,7 +12,6 @@ from sqlalchemy import and_, delete, select, update from apps.common.postgres import postgres from apps.common.process_handler import ProcessHandler -from apps.common.singleton import SingletonMeta from apps.constants import MCP_PATH from apps.llm import Embedding from apps.models.mcp import MCPActivated, MCPInfo, MCPInstallStatus, MCPTools, MCPType @@ -27,7 +26,7 @@ from apps.schemas.mcp import ( logger = logging.getLogger(__name__) -class MCPLoader(metaclass=SingletonMeta): +class MCPLoader: """ MCP加载模块 diff --git a/apps/scheduler/pool/pool.py b/apps/scheduler/pool/pool.py index 88b12ea70..c33c8770b 100644 --- a/apps/scheduler/pool/pool.py +++ b/apps/scheduler/pool/pool.py @@ -11,24 +11,23 @@ from sqlalchemy import select from apps.common.config import config from apps.common.postgres import postgres +from apps.common.singleton import SingletonMeta from apps.llm import Embedding from apps.models import Flow as FlowInfo from apps.schemas.enum_var import MetadataType from apps.schemas.flow import Flow from .check import FileChecker -from .loader import ( - AppLoader, - CallLoader, - FlowLoader, - MCPLoader, - ServiceLoader, -) +from .loader.app import AppLoader +from .loader.call import CallLoader +from .loader.flow import FlowLoader +from .loader.mcp import MCPLoader +from .loader.service import ServiceLoader logger = logging.getLogger(__name__) -class Pool: +class Pool(metaclass=SingletonMeta): """ 资源池 diff --git a/apps/scheduler/scheduler/context.py b/apps/scheduler/scheduler/context.py index ddaddba85..2265e115f 100644 --- a/apps/scheduler/scheduler/context.py +++ b/apps/scheduler/scheduler/context.py @@ -11,12 +11,10 @@ from apps.schemas.record import ( FlowHistory, RecordContent, ) -from apps.services import ( - AppCenterManager, - DocumentManager, - RecordManager, - TaskManager, -) +from apps.services.appcenter import AppCenterManager +from apps.services.document import DocumentManager +from apps.services.record import RecordManager +from apps.services.task import TaskManager logger = logging.getLogger(__name__) diff --git a/apps/scheduler/scheduler/scheduler.py b/apps/scheduler/scheduler/scheduler.py index 7fec57115..538835cfa 100644 --- a/apps/scheduler/scheduler/scheduler.py +++ b/apps/scheduler/scheduler/scheduler.py @@ -12,7 +12,9 @@ from jinja2.sandbox import SandboxedEnvironment from apps.common.queue import MessageQueue from apps.llm import Embedding, FunctionLLM, JsonGenerator, ReasoningLLM from apps.models import AppType, Conversation, ExecutorStatus, Task, TaskRuntime, User -from apps.scheduler.executor import FlowExecutor, MCPAgentExecutor, QAExecutor +from apps.scheduler.executor.agent import MCPAgentExecutor +from apps.scheduler.executor.flow import FlowExecutor +from apps.scheduler.executor.qa import QAExecutor from apps.scheduler.pool.pool import Pool from apps.schemas.enum_var import EventType from apps.schemas.message import ( @@ -22,15 +24,12 @@ from apps.schemas.message import ( from apps.schemas.request_data import RequestData from apps.schemas.scheduler import LLMConfig, TopFlow from apps.schemas.task import TaskData -from apps.services import ( - Activity, - AppCenterManager, - ConversationManager, - KnowledgeBaseManager, - LLMManager, - TaskManager, - UserManager, -) +from apps.services.activity import Activity +from apps.services.appcenter import AppCenterManager +from apps.services.conversation import ConversationManager +from apps.services.llm import LLMManager +from apps.services.task import TaskManager +from apps.services.user import UserManager from .prompt import FLOW_SELECT diff --git a/apps/schemas/flow.py b/apps/schemas/flow.py index 17007bdfb..697394aee 100644 --- a/apps/schemas/flow.py +++ b/apps/schemas/flow.py @@ -10,7 +10,7 @@ from apps.models import AppType, PermissionType from .appcenter import AppLink from .enum_var import EdgeType, MetadataType -from .flow_topology import FlowItem +from .flow_topology import FlowBasicConfig, FlowCheckStatus, FlowItem, PositionItem from .response_data import ResponseData @@ -23,13 +23,6 @@ class Edge(BaseModel): edge_type: EdgeType | None = Field(description="边的类型", default=EdgeType.NORMAL) -class PositionItem(BaseModel): - """请求/响应中的前端相对位置变量类""" - - x: float = Field(default=0.0) - y: float = Field(default=0.0) - - class Step(BaseModel): """Flow中Step的数据""" @@ -48,21 +41,6 @@ class FlowError(BaseModel): output_format: str | None = Field(description="错误处理节点的输出格式", default=None) -class FlowBasicConfig(BaseModel): - """Flow的基本配置""" - - startStep: uuid.UUID = Field(description="开始节点ID") # noqa: N815 - endStep: uuid.UUID = Field(description="结束节点ID") # noqa: N815 - focusPoint: PositionItem | None = Field(description="当前焦点节点", default=PositionItem(x=0, y=0)) # noqa: N815 - - -class FlowCheckStatus(BaseModel): - """Flow的配置检查状态""" - - debug: bool = Field(description="是否经过调试", default=False) - connectivity: bool = Field(default=False, description="图的开始节点和结束节点是否联通,并且除结束节点都有出边") - - class Flow(BaseModel): """Flow(工作流)的数据格式""" diff --git a/apps/schemas/flow_topology.py b/apps/schemas/flow_topology.py index 20ac2c6cb..9af23233e 100644 --- a/apps/schemas/flow_topology.py +++ b/apps/schemas/flow_topology.py @@ -6,10 +6,7 @@ from typing import Any from pydantic import BaseModel, Field -from apps.schemas.enum_var import SpecialCallType -from apps.schemas.flow import FlowBasicConfig, FlowCheckStatus, PositionItem - -from .enum_var import EdgeType +from .enum_var import EdgeType, SpecialCallType class NodeMetaDataBase(BaseModel): @@ -37,6 +34,13 @@ class NodeServiceItem(BaseModel): created_at: str | None = Field(default=None, alias="createdAt", description="创建时间") +class PositionItem(BaseModel): + """请求/响应中的前端相对位置变量类""" + + x: float = Field(default=0.0) + y: float = Field(default=0.0) + + class NodeItem(BaseModel): """请求/响应中的节点变量类""" @@ -60,6 +64,21 @@ class EdgeItem(BaseModel): branch_id: str = Field(alias="branchId") +class FlowBasicConfig(BaseModel): + """Flow的基本配置""" + + startStep: uuid.UUID = Field(description="开始节点ID") # noqa: N815 + endStep: uuid.UUID = Field(description="结束节点ID") # noqa: N815 + focusPoint: PositionItem | None = Field(description="当前焦点节点", default=PositionItem(x=0, y=0)) # noqa: N815 + + +class FlowCheckStatus(BaseModel): + """Flow的配置检查状态""" + + debug: bool = Field(description="是否经过调试", default=False) + connectivity: bool = Field(default=False, description="图的开始节点和结束节点是否联通,并且除结束节点都有出边") + + class FlowItem(BaseModel): """请求/响应中的流变量类""" diff --git a/apps/schemas/scheduler.py b/apps/schemas/scheduler.py index 6b48db202..72ad05e54 100644 --- a/apps/schemas/scheduler.py +++ b/apps/schemas/scheduler.py @@ -19,6 +19,11 @@ class LLMConfig(BaseModel): function: FunctionLLM | None = Field(description="函数LLM") embedding: Embedding | None = Field(description="Embedding") + class Config: + """配置""" + + arbitrary_types_allowed = True + class CallInfo(BaseModel): """Call的名称和描述""" diff --git a/apps/services/__init__.py b/apps/services/__init__.py index e49001371..8fd10ea62 100644 --- a/apps/services/__init__.py +++ b/apps/services/__init__.py @@ -1,51 +1,2 @@ # Copyright (c) Huawei Technologies Co., Ltd. 2023-2025. All rights reserved. """Manager模块""" -from .activity import Activity -from .appcenter import AppCenterManager -from .blacklist import AbuseManager, QuestionBlacklistManager, UserBlacklistManager -from .comment import CommentManager -from .conversation import ConversationManager -from .document import DocumentManager -from .flow import FlowManager -from .flow_service import FlowServiceManager -from .knowledge_service import KnowledgeBaseService -from .llm import LLMManager -from .mcp_service import MCPServiceManager -from .node import NodeManager -from .parameter import ParameterManager -from .personal_token import PersonalTokenManager -from .record import RecordManager -from .service import ServiceCenterManager -from .session import SessionManager -from .tag import TagManager -from .task import TaskManager -from .token import TokenManager -from .user import UserManager -from .user_tag import UserTagManager - -__all__ = [ - "AbuseManager", - "Activity", - "AppCenterManager", - "CommentManager", - "ConversationManager", - "DocumentManager", - "FlowManager", - "FlowServiceManager", - "KnowledgeBaseService", - "LLMManager", - "MCPServiceManager", - "NodeManager", - "ParameterManager", - "PersonalTokenManager", - "QuestionBlacklistManager", - "RecordManager", - "ServiceCenterManager", - "SessionManager", - "TagManager", - "TaskManager", - "TokenManager", - "UserBlacklistManager", - "UserManager", - "UserTagManager", -] diff --git a/apps/services/flow.py b/apps/services/flow.py index 51abb69d0..72359c899 100644 --- a/apps/services/flow.py +++ b/apps/services/flow.py @@ -19,7 +19,7 @@ from apps.models import Flow as FlowInfo from apps.scheduler.pool.pool import Pool from apps.scheduler.slot.slot import Slot from apps.schemas.enum_var import EdgeType -from apps.schemas.flow import AppMetadata, Edge, Flow, Step +from apps.schemas.flow import AppMetadata, Edge, Flow, PositionItem, Step from apps.schemas.flow_topology import ( EdgeItem, FlowItem, @@ -27,7 +27,6 @@ from apps.schemas.flow_topology import ( NodeMetaDataBase, NodeMetaDataItem, NodeServiceItem, - PositionItem, ) from .node import NodeManager diff --git a/apps/services/node.py b/apps/services/node.py index d212bbbef..28147a50c 100644 --- a/apps/services/node.py +++ b/apps/services/node.py @@ -8,7 +8,6 @@ from sqlalchemy import select from apps.common.postgres import postgres from apps.models import NodeInfo -from apps.scheduler.pool.pool import Pool from apps.schemas.enum_var import SpecialCallType if TYPE_CHECKING: @@ -59,6 +58,9 @@ class NodeManager: @staticmethod async def get_node_params(node_id: str) -> tuple[dict[str, Any], dict[str, Any]]: """获取Node数据""" + # 在此处获取Pool单例,避免循环导入 + from apps.scheduler.pool.pool import Pool # noqa: PLC0415 + # 查找Node信息 if node_id == SpecialCallType.EMPTY.value: # 如果是空节点,返回空Schema diff --git a/apps/services/parameter.py b/apps/services/parameter.py index 6311ad559..facc03a77 100644 --- a/apps/services/parameter.py +++ b/apps/services/parameter.py @@ -12,7 +12,7 @@ from apps.schemas.response_data import ( OperateAndBindType, StepParams, ) -from apps.services import NodeManager +from apps.services.node import NodeManager logger = logging.getLogger(__name__) diff --git a/apps/services/record.py b/apps/services/record.py index eac4e0654..5dd2b999b 100644 --- a/apps/services/record.py +++ b/apps/services/record.py @@ -117,13 +117,13 @@ class RecordManager: return records - @staticmethod - async def update_record_flow_status_to_cancelled_by_task_ids(task_ids: list[str]) -> None: - """更新Record关联的Flow状态""" - try: - {"records.task_id": {"$in": task_ids}, "records.flow.flow_status": {"$nin": [ExecutorStatus.ERROR.value, ExecutorStatus.SUCCESS.value]}}, - {"$set": {"records.$[elem].flow.flow_status": ExecutorStatus.CANCELLED}}, - array_filters=[{"elem.flow.flow_id": {"$in": task_ids}}], - ) - except Exception: - logger.exception("[RecordManager] 更新Record关联的Flow状态失败") + # @staticmethod + # async def update_record_flow_status_to_cancelled_by_task_ids(task_ids: list[str]) -> None: + # """更新Record关联的Flow状态""" + # try: + # {"records.task_id": {"$in": task_ids}, "records.flow.flow_status": {"$nin": [ExecutorStatus.ERROR.value, ExecutorStatus.SUCCESS.value]}}, + # {"$set": {"records.$[elem].flow.flow_status": ExecutorStatus.CANCELLED}}, + # array_filters=[{"elem.flow.flow_id": {"$in": task_ids}}], + # ) + # except Exception: + # logger.exception("[RecordManager] 更新Record关联的Flow状态失败") -- Gitee