diff --git a/backend/package/yuxi/agents/__init__.py b/backend/package/yuxi/agents/__init__.py index 7011018f..418871c6 100644 --- a/backend/package/yuxi/agents/__init__.py +++ b/backend/package/yuxi/agents/__init__.py @@ -4,6 +4,9 @@ from yuxi.agents.base import BaseAgent # 从 buildin 模块导入 agent_manager from yuxi.agents.context import BaseContext +# MCP - Agent 层统一入口(自动过滤 disabled_tools) +from yuxi.agents.mcp.service import get_enabled_mcp_tools + # Model utilities - 模型加载 from yuxi.agents.models import load_chat_model from yuxi.agents.state import BaseState @@ -11,9 +14,6 @@ from yuxi.agents.state import BaseState # Tools - 核心工具函数 from yuxi.agents.toolkits.utils import get_tool_info -# MCP - Agent 层统一入口(自动过滤 disabled_tools) -from yuxi.agents.mcp.service import get_enabled_mcp_tools - __all__ = [ # Base classes "BaseAgent", diff --git a/backend/package/yuxi/agents/backends/sandbox/backend.py b/backend/package/yuxi/agents/backends/sandbox/backend.py index debeac3d..14ec5ddb 100644 --- a/backend/package/yuxi/agents/backends/sandbox/backend.py +++ b/backend/package/yuxi/agents/backends/sandbox/backend.py @@ -33,7 +33,6 @@ from yuxi.utils.paths import ( from .provider import get_sandbox_provider, sandbox_id_for_thread - _USER_DATA_ROOT = "/" + VIRTUAL_PATH_PREFIX.strip("/") _WORKSPACE_ROOT = f"{_USER_DATA_ROOT}/{WORKSPACE_DIR_NAME}" _UPLOADS_ROOT = f"{_USER_DATA_ROOT}/{UPLOADS_DIR_NAME}" diff --git a/backend/package/yuxi/agents/buildin/__init__.py b/backend/package/yuxi/agents/buildin/__init__.py index b93a6d1a..eaa286d3 100644 --- a/backend/package/yuxi/agents/buildin/__init__.py +++ b/backend/package/yuxi/agents/buildin/__init__.py @@ -3,9 +3,9 @@ import importlib import inspect from pathlib import Path -from yuxi.utils.singleton import SingletonMeta from yuxi.agents.base import BaseAgent from yuxi.utils import logger +from yuxi.utils.singleton import SingletonMeta class AgentManager(metaclass=SingletonMeta): diff --git a/backend/package/yuxi/agents/buildin/deep_agent/graph.py b/backend/package/yuxi/agents/buildin/deep_agent/graph.py index 585a3634..535c4bbd 100644 --- a/backend/package/yuxi/agents/buildin/deep_agent/graph.py +++ b/backend/package/yuxi/agents/buildin/deep_agent/graph.py @@ -17,8 +17,8 @@ from yuxi.agents.middlewares import ( ) from yuxi.agents.middlewares.knowledge_base_middleware import KnowledgeBaseMiddleware from yuxi.agents.middlewares.skills_middleware import SkillsMiddleware -from yuxi.agents.toolkits.buildin.tools import _create_tavily_search from yuxi.agents.subagents.service import build_subagent_middleware_specs, get_subagents_from_slugs +from yuxi.agents.toolkits.buildin.tools import _create_tavily_search from yuxi.agents.toolkits.service import resolve_configured_runtime_tools from yuxi.utils import logger from yuxi.utils.datetime_utils import shanghai_now diff --git a/backend/package/yuxi/agents/mcp/service.py b/backend/package/yuxi/agents/mcp/service.py index 27ded5a6..82f2fa52 100644 --- a/backend/package/yuxi/agents/mcp/service.py +++ b/backend/package/yuxi/agents/mcp/service.py @@ -17,6 +17,7 @@ from typing import Any, cast from langchain_mcp_adapters.client import MultiServerMCPClient from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession + from yuxi.storage.postgres.models_business import MCPServer from yuxi.utils import logger diff --git a/backend/package/yuxi/agents/middlewares/skills_middleware.py b/backend/package/yuxi/agents/middlewares/skills_middleware.py index a6af1343..6e860e9d 100644 --- a/backend/package/yuxi/agents/middlewares/skills_middleware.py +++ b/backend/package/yuxi/agents/middlewares/skills_middleware.py @@ -14,10 +14,10 @@ from langchain.tools.tool_node import ToolCallRequest from langgraph.types import Command from sqlalchemy.ext.asyncio import AsyncSession -from yuxi.agents.toolkits import get_all_tool_instances -from yuxi.agents.skills.repository import SkillRepository from yuxi.agents.mcp.service import get_enabled_mcp_tools +from yuxi.agents.skills.repository import SkillRepository from yuxi.agents.skills.service import is_valid_skill_slug, list_accessible_skills, normalize_string_list +from yuxi.agents.toolkits import get_all_tool_instances from yuxi.storage.postgres.manager import pg_manager from yuxi.utils.logging_config import logger diff --git a/backend/package/yuxi/agents/skills/remote_install.py b/backend/package/yuxi/agents/skills/remote_install.py index 1b3bada1..1b5a01e4 100644 --- a/backend/package/yuxi/agents/skills/remote_install.py +++ b/backend/package/yuxi/agents/skills/remote_install.py @@ -10,6 +10,7 @@ from pathlib import Path from typing import TYPE_CHECKING from sqlalchemy.ext.asyncio import AsyncSession + from yuxi.agents.skills.service import import_skill_dir, is_valid_skill_slug if TYPE_CHECKING: diff --git a/backend/package/yuxi/agents/skills/service.py b/backend/package/yuxi/agents/skills/service.py index a3002fdf..bfe9cf36 100644 --- a/backend/package/yuxi/agents/skills/service.py +++ b/backend/package/yuxi/agents/skills/service.py @@ -16,9 +16,10 @@ from typing import Any import yaml from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession + from yuxi import config as sys_config -from yuxi.agents.skills.repository import SkillRepository from yuxi.agents.mcp.service import get_enabled_mcp_server_slugs +from yuxi.agents.skills.repository import SkillRepository from yuxi.storage.postgres.models_business import Skill, User from yuxi.utils.logging_config import logger diff --git a/backend/package/yuxi/agents/subagents/service.py b/backend/package/yuxi/agents/subagents/service.py index 6bed264c..9782ff89 100644 --- a/backend/package/yuxi/agents/subagents/service.py +++ b/backend/package/yuxi/agents/subagents/service.py @@ -8,6 +8,7 @@ from typing import Any from deepagents.middleware.subagents import GENERAL_PURPOSE_SUBAGENT from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession + from yuxi.agents.subagents.repository import SubAgentRepository from yuxi.storage.postgres.manager import pg_manager from yuxi.storage.postgres.models_business import SubAgent diff --git a/backend/package/yuxi/agents/toolkits/buildin/tools.py b/backend/package/yuxi/agents/toolkits/buildin/tools.py index 70b0abeb..af5f169a 100644 --- a/backend/package/yuxi/agents/toolkits/buildin/tools.py +++ b/backend/package/yuxi/agents/toolkits/buildin/tools.py @@ -10,7 +10,6 @@ from langgraph.prebuilt.tool_node import ToolRuntime from langgraph.types import Command, interrupt from pydantic import BaseModel, Field -from yuxi import config from yuxi.agents.toolkits.registry import ToolExtraMetadata, _all_tool_instances, _extra_registry, tool from yuxi.storage.minio import aupload_file_to_minio from yuxi.utils import logger diff --git a/backend/package/yuxi/agents/toolkits/kbs/tools.py b/backend/package/yuxi/agents/toolkits/kbs/tools.py index 0375c1ae..953316ed 100644 --- a/backend/package/yuxi/agents/toolkits/kbs/tools.py +++ b/backend/package/yuxi/agents/toolkits/kbs/tools.py @@ -4,11 +4,10 @@ import inspect from typing import Any from langgraph.prebuilt.tool_node import ToolRuntime - -from yuxi.agents.toolkits.registry import tool from pydantic import BaseModel, Field from yuxi import knowledge_base +from yuxi.agents.toolkits.registry import tool from yuxi.knowledge.base import KnowledgeBase from yuxi.knowledge.schemas import ( FindInputSchema, @@ -226,11 +225,7 @@ async def query_kb(kb_id: str, query_text: str, file_name: str | None = None, ru else: result = retriever(query_text, **kwargs) - if ( - isinstance(result, dict) - and result.get("kb_id") == target_kb_id - and isinstance(result.get("results"), list) - ): + if isinstance(result, dict) and result.get("kb_id") == target_kb_id and isinstance(result.get("results"), list): return SearchOutputSchema(**result).model_dump() return KnowledgeBase.build_search_output(target_kb_id, result) diff --git a/backend/package/yuxi/config/app.py b/backend/package/yuxi/config/app.py index d7d4de67..4b413852 100644 --- a/backend/package/yuxi/config/app.py +++ b/backend/package/yuxi/config/app.py @@ -97,7 +97,9 @@ class Config(BaseModel): self.sandbox_exec_timeout_seconds = int( os.getenv("SANDBOX_EXEC_TIMEOUT_SECONDS") or self.sandbox_exec_timeout_seconds or 180 ) - self.sandbox_max_output_bytes = int(os.getenv("SANDBOX_MAX_OUTPUT_BYTES") or self.sandbox_max_output_bytes or 262144) + self.sandbox_max_output_bytes = int( + os.getenv("SANDBOX_MAX_OUTPUT_BYTES") or self.sandbox_max_output_bytes or 262144 + ) self.sandbox_keepalive_interval_seconds = int( os.getenv("SANDBOX_KEEPALIVE_INTERVAL_SECONDS") or self.sandbox_keepalive_interval_seconds or 30 ) diff --git a/backend/package/yuxi/knowledge/chunking/ragflow_like/presets.py b/backend/package/yuxi/knowledge/chunking/ragflow_like/presets.py index 79eb2529..aae796db 100644 --- a/backend/package/yuxi/knowledge/chunking/ragflow_like/presets.py +++ b/backend/package/yuxi/knowledge/chunking/ragflow_like/presets.py @@ -33,6 +33,7 @@ CHUNK_PRESET_DESCRIPTIONS: dict[str, str] = { CHUNK_ENGINE_VERSION = "ragflow_like_v1" GENERAL_INTERNAL_PARSER_ID = "naive" + def deep_merge(base: dict[str, Any], override: dict[str, Any]) -> dict[str, Any]: result = deepcopy(base) for key, value in (override or {}).items(): diff --git a/backend/package/yuxi/knowledge/graphs/__init__.py b/backend/package/yuxi/knowledge/graphs/__init__.py index fe3c9688..c73ba9c9 100644 --- a/backend/package/yuxi/knowledge/graphs/__init__.py +++ b/backend/package/yuxi/knowledge/graphs/__init__.py @@ -1,3 +1,3 @@ from .milvus_graph_service import MilvusGraphService -__all__ = ["MilvusGraphService"] \ No newline at end of file +__all__ = ["MilvusGraphService"] diff --git a/backend/package/yuxi/knowledge/graphs/extractors/base.py b/backend/package/yuxi/knowledge/graphs/extractors/base.py index 8724c8a9..72f09ee5 100644 --- a/backend/package/yuxi/knowledge/graphs/extractors/base.py +++ b/backend/package/yuxi/knowledge/graphs/extractors/base.py @@ -4,7 +4,6 @@ from abc import ABC, abstractmethod from collections.abc import Callable from typing import Any - from yuxi.knowledge.graphs.graph_utils import normalize_entity_name diff --git a/backend/package/yuxi/knowledge/graphs/extractors/llm.py b/backend/package/yuxi/knowledge/graphs/extractors/llm.py index b7e4e2c2..2f0c3761 100644 --- a/backend/package/yuxi/knowledge/graphs/extractors/llm.py +++ b/backend/package/yuxi/knowledge/graphs/extractors/llm.py @@ -8,7 +8,6 @@ from yuxi.models.chat import select_model from .base import GraphExtractor - DEFAULT_TRIPLE_EXTRACTION_PROMPT = """请从下面文本中抽取实体和实体关系,返回严格 JSON,不要输出解释。 JSON 格式: { diff --git a/backend/package/yuxi/knowledge/graphs/milvus_graph_service.py b/backend/package/yuxi/knowledge/graphs/milvus_graph_service.py index 57ff2372..f22c949e 100644 --- a/backend/package/yuxi/knowledge/graphs/milvus_graph_service.py +++ b/backend/package/yuxi/knowledge/graphs/milvus_graph_service.py @@ -15,6 +15,9 @@ from yuxi.knowledge.graphs.graph_utils import ( normalize_entity_name, ) from yuxi.knowledge.graphs.milvus_graph_vector_store import MilvusGraphVectorStore +from yuxi.repositories.knowledge_base_repository import KnowledgeBaseRepository +from yuxi.repositories.knowledge_chunk_repository import KnowledgeChunkRepository +from yuxi.repositories.knowledge_graph_repository import KnowledgeGraphRepository from yuxi.storage.neo4j import ( Neo4jConnectionManager, get_shared_neo4j_connection, @@ -22,9 +25,6 @@ from yuxi.storage.neo4j import ( neo4j_write, safe_neo4j_label, ) -from yuxi.repositories.knowledge_base_repository import KnowledgeBaseRepository -from yuxi.repositories.knowledge_chunk_repository import KnowledgeChunkRepository -from yuxi.repositories.knowledge_graph_repository import KnowledgeGraphRepository from yuxi.utils import logger from yuxi.utils.datetime_utils import utc_isoformat diff --git a/backend/package/yuxi/knowledge/implementations/milvus.py b/backend/package/yuxi/knowledge/implementations/milvus.py index 3869a2b1..b82b8bc1 100644 --- a/backend/package/yuxi/knowledge/implementations/milvus.py +++ b/backend/package/yuxi/knowledge/implementations/milvus.py @@ -22,10 +22,10 @@ from pymilvus import ( from yuxi.knowledge.base import FileStatus, KnowledgeBase from yuxi.knowledge.chunking.ragflow_like.dispatcher import chunk_markdown -from yuxi.knowledge.utils.kb_utils import resolve_processing_params -from yuxi.repositories.knowledge_chunk_repository import KnowledgeChunkRepository -from yuxi.models.providers.cache import model_cache from yuxi.knowledge.parser.unified import Parser +from yuxi.knowledge.utils.kb_utils import resolve_processing_params +from yuxi.models.providers.cache import model_cache +from yuxi.repositories.knowledge_chunk_repository import KnowledgeChunkRepository from yuxi.utils import hashstr, logger from yuxi.utils.datetime_utils import utc_isoformat diff --git a/backend/package/yuxi/knowledge/manager.py b/backend/package/yuxi/knowledge/manager.py index 15c375d5..4425bbd7 100644 --- a/backend/package/yuxi/knowledge/manager.py +++ b/backend/package/yuxi/knowledge/manager.py @@ -8,7 +8,6 @@ from yuxi.storage.postgres.models_business import User from yuxi.utils import logger from yuxi.utils.datetime_utils import utc_isoformat - DEFAULT_SHARE_CONFIG = {"access_level": "global", "department_ids": [], "user_uids": []} ACCESS_LEVELS = {"global", "department", "user"} diff --git a/backend/package/yuxi/knowledge/utils/kb_utils.py b/backend/package/yuxi/knowledge/utils/kb_utils.py index 51734ca5..1c74ca1f 100644 --- a/backend/package/yuxi/knowledge/utils/kb_utils.py +++ b/backend/package/yuxi/knowledge/utils/kb_utils.py @@ -5,7 +5,6 @@ from yuxi.knowledge.chunking.ragflow_like.presets import resolve_chunk_processin from yuxi.utils import hashstr, logger from yuxi.utils.datetime_utils import utc_isoformat - _DROPPED_PROCESSING_PARAM_KEYS = { "_preprocessed_map", "auto_index", diff --git a/backend/package/yuxi/models/providers/service.py b/backend/package/yuxi/models/providers/service.py index 0b8d1c8b..a4b6ee0e 100644 --- a/backend/package/yuxi/models/providers/service.py +++ b/backend/package/yuxi/models/providers/service.py @@ -7,6 +7,7 @@ from typing import Any import httpx from sqlalchemy.ext.asyncio import AsyncSession + from yuxi.models.providers.builtin import BUILTIN_PROVIDERS from yuxi.models.providers.repository import ( create_model_provider, diff --git a/backend/package/yuxi/repositories/message_feedback_repository.py b/backend/package/yuxi/repositories/message_feedback_repository.py index 8a79e29e..091b96fa 100644 --- a/backend/package/yuxi/repositories/message_feedback_repository.py +++ b/backend/package/yuxi/repositories/message_feedback_repository.py @@ -34,8 +34,6 @@ class MessageFeedbackRepository: """检查用户是否已对消息反馈""" async with pg_manager.get_async_session_context() as session: result = await session.execute( - select(MessageFeedback.id).where( - MessageFeedback.message_id == message_id, MessageFeedback.uid == uid - ) + select(MessageFeedback.id).where(MessageFeedback.message_id == message_id, MessageFeedback.uid == uid) ) return result.scalar_one_or_none() is not None diff --git a/backend/package/yuxi/services/chat_service.py b/backend/package/yuxi/services/chat_service.py index 4dc6a743..460920ad 100644 --- a/backend/package/yuxi/services/chat_service.py +++ b/backend/package/yuxi/services/chat_service.py @@ -12,7 +12,6 @@ from yuxi.agents.backends.sandbox.paths import sandbox_workspace_agents_prompt_f from yuxi.agents.buildin import agent_manager from yuxi.agents.context import normalize_agent_context_config from yuxi.agents.state import AgentStatePayload -from yuxi.utils.guard import content_guard from yuxi.repositories.agent_repository import AgentRepository from yuxi.repositories.conversation_repository import ConversationRepository from yuxi.services.conversation_service import serialize_attachment @@ -24,6 +23,7 @@ from yuxi.services.langfuse_service import ( ) from yuxi.storage.postgres.manager import pg_manager from yuxi.storage.postgres.models_business import Agent, User +from yuxi.utils.guard import content_guard from yuxi.utils.logging_config import logger from yuxi.utils.question_utils import ( normalize_questions as _normalize_interrupt_questions, diff --git a/backend/package/yuxi/services/conversation_service.py b/backend/package/yuxi/services/conversation_service.py index f7b00205..10e50d4a 100644 --- a/backend/package/yuxi/services/conversation_service.py +++ b/backend/package/yuxi/services/conversation_service.py @@ -16,12 +16,12 @@ from yuxi.knowledge.parser import Parser from yuxi.repositories.agent_repository import AgentRepository from yuxi.repositories.conversation_repository import ConversationRepository from yuxi.services.mention_search_service import invalidate_mention_cache -from yuxi.utils.upload_utils import read_upload_with_limit, write_upload_to_path from yuxi.storage.minio import StorageError, get_minio_client from yuxi.storage.postgres.models_business import User from yuxi.utils.datetime_utils import utc_isoformat from yuxi.utils.logging_config import logger from yuxi.utils.paths import VIRTUAL_PATH_UPLOADS +from yuxi.utils.upload_utils import read_upload_with_limit, write_upload_to_path ATTACHMENT_ALLOWED_EXTENSIONS: tuple[str, ...] = () MAX_ATTACHMENT_SIZE_BYTES = 5 * 1024 * 1024 # 5 MB diff --git a/backend/package/yuxi/services/oidc_service.py b/backend/package/yuxi/services/oidc_service.py index 5a8f953b..d1263c85 100644 --- a/backend/package/yuxi/services/oidc_service.py +++ b/backend/package/yuxi/services/oidc_service.py @@ -18,13 +18,12 @@ from pydantic import BaseModel, Field from sqlalchemy import select from sqlalchemy.exc import IntegrityError from yuxi.repositories.user_repository import UserRepository +from yuxi.services.operation_log_service import log_operation from yuxi.storage.postgres.models_business import Department, User +from yuxi.utils.auth_utils import AuthUtils from yuxi.utils.datetime_utils import utc_now_naive from yuxi.utils.logging_config import logger -from yuxi.utils.auth_utils import AuthUtils -from yuxi.services.operation_log_service import log_operation - # 前端 OIDC 回调路由路径(与 web/src/router/index.js 中的路由保持一致) FRONTEND_CALLBACK_PATH = "/auth/oidc/callback" # 登录页路径 diff --git a/backend/package/yuxi/services/run_worker.py b/backend/package/yuxi/services/run_worker.py index 05594074..8d33bcf6 100644 --- a/backend/package/yuxi/services/run_worker.py +++ b/backend/package/yuxi/services/run_worker.py @@ -10,16 +10,16 @@ from dataclasses import dataclass, field from sqlalchemy import select from sqlalchemy.exc import OperationalError +from yuxi.agents.mcp.service import ensure_builtin_mcp_servers_in_db +from yuxi.agents.skills.service import init_builtin_skills from yuxi.repositories.agent_run_repository import TERMINAL_RUN_STATUSES, AgentRunRepository from yuxi.services.chat_service import stream_agent_chat, stream_agent_resume -from yuxi.agents.mcp.service import ensure_builtin_mcp_servers_in_db from yuxi.services.run_queue_service import ( append_run_stream_event, clear_cancel_signal, has_cancel_signal, wait_for_cancel_signal, ) -from yuxi.agents.skills.service import init_builtin_skills from yuxi.storage.postgres.manager import pg_manager from yuxi.storage.postgres.models_business import User from yuxi.utils.logging_config import logger diff --git a/backend/package/yuxi/services/viewer_filesystem_service.py b/backend/package/yuxi/services/viewer_filesystem_service.py index 98f31e91..e28bec0b 100644 --- a/backend/package/yuxi/services/viewer_filesystem_service.py +++ b/backend/package/yuxi/services/viewer_filesystem_service.py @@ -26,10 +26,18 @@ from yuxi.services.agent_runtime_service import resolve_thread_agent_runtime_con from yuxi.services.file_preview import detect_preview_type from yuxi.services.workspace_service import ( create_workspace_directory as create_workspace_directory_entry, +) +from yuxi.services.workspace_service import ( delete_workspace_path, - download_workspace_file as download_workspace_file_response, list_workspace_tree, +) +from yuxi.services.workspace_service import ( + download_workspace_file as download_workspace_file_response, +) +from yuxi.services.workspace_service import ( read_workspace_file_content as read_workspace_file_content_response, +) +from yuxi.services.workspace_service import ( upload_workspace_file as upload_workspace_file_entry, ) from yuxi.storage.postgres.models_business import User diff --git a/backend/package/yuxi/services/workspace_service.py b/backend/package/yuxi/services/workspace_service.py index 7b5bc6a6..eedbcbd5 100644 --- a/backend/package/yuxi/services/workspace_service.py +++ b/backend/package/yuxi/services/workspace_service.py @@ -14,10 +14,10 @@ from fastapi.responses import FileResponse, StreamingResponse from yuxi.agents.backends.sandbox.paths import _global_user_data_dir, ensure_workspace_default_files from yuxi.services.file_preview import detect_preview_type from yuxi.services.mention_search_service import invalidate_workspace_mention_cache -from yuxi.utils.upload_utils import MAX_UPLOAD_SIZE_BYTES, write_upload_to_buffer from yuxi.storage.postgres.models_business import User from yuxi.utils.datetime_utils import utc_isoformat_from_timestamp from yuxi.utils.paths import VIRTUAL_PATH_WORKSPACE, WORKSPACE_DIR_NAME +from yuxi.utils.upload_utils import MAX_UPLOAD_SIZE_BYTES, write_upload_to_buffer EDITABLE_WORKSPACE_SUFFIXES = {".md", ".markdown", ".mdx", ".txt"} MAX_WORKSPACE_UPLOAD_SIZE_BYTES = MAX_UPLOAD_SIZE_BYTES diff --git a/backend/package/yuxi/storage/minio/utils.py b/backend/package/yuxi/storage/minio/utils.py index 2b2854db..caf1a63b 100644 --- a/backend/package/yuxi/storage/minio/utils.py +++ b/backend/package/yuxi/storage/minio/utils.py @@ -7,7 +7,6 @@ import os import uuid from fastapi import UploadFile - from yuxi.utils.upload_utils import read_upload_with_limit from .client import aupload_file_to_minio diff --git a/backend/package/yuxi/storage/neo4j/manager.py b/backend/package/yuxi/storage/neo4j/manager.py index 138e9aab..81a9c605 100644 --- a/backend/package/yuxi/storage/neo4j/manager.py +++ b/backend/package/yuxi/storage/neo4j/manager.py @@ -6,10 +6,10 @@ import threading from collections.abc import Callable from typing import Any -from neo4j import GraphDatabase as GD - from yuxi.utils import logger +from neo4j import GraphDatabase as GD + _SAFE_NEO4J_LABEL_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$") _shared_neo4j_connection: Neo4jConnectionManager | None = None _shared_neo4j_connection_lock = threading.Lock() diff --git a/backend/package/yuxi/storage/postgres/manager.py b/backend/package/yuxi/storage/postgres/manager.py index b9a77502..f1727e1d 100644 --- a/backend/package/yuxi/storage/postgres/manager.py +++ b/backend/package/yuxi/storage/postgres/manager.py @@ -11,7 +11,6 @@ from sqlalchemy.orm import declarative_base from yuxi.storage.postgres.models_business import Base as BusinessBase from yuxi.storage.postgres.models_knowledge import Base as KnowledgeBase from yuxi.utils import logger - from yuxi.utils.singleton import SingletonMeta # 合并两个 Base diff --git a/backend/package/yuxi/utils/auth_utils.py b/backend/package/yuxi/utils/auth_utils.py index 7b2adc5c..05e14e53 100644 --- a/backend/package/yuxi/utils/auth_utils.py +++ b/backend/package/yuxi/utils/auth_utils.py @@ -6,6 +6,7 @@ from typing import Any import jwt from argon2 import PasswordHasher from argon2.exceptions import InvalidHash, VerificationError, VerifyMismatchError + from yuxi.utils.datetime_utils import utc_now JWT_ALGORITHM = "HS256" diff --git a/web/src/apis/graph_api.js b/web/src/apis/graph_api.js index 889522ca..930aa826 100644 --- a/web/src/apis/graph_api.js +++ b/web/src/apis/graph_api.js @@ -6,7 +6,13 @@ export const graphApi = { }, getSubgraph: async (params) => { - const { kb_id, node_label = '*', max_depth = 2, max_nodes = 100, exclude_chunk = false } = params + const { + kb_id, + node_label = '*', + max_depth = 2, + max_nodes = 100, + exclude_chunk = false + } = params if (!kb_id) { throw new Error('kb_id is required') diff --git a/web/src/apis/skill_api.js b/web/src/apis/skill_api.js index 19313341..618889d7 100644 --- a/web/src/apis/skill_api.js +++ b/web/src/apis/skill_api.js @@ -1,4 +1,12 @@ -import { apiGet, apiPost, apiDelete, apiAdminGet, apiAdminPost, apiAdminPut, apiAdminDelete } from './base' +import { + apiGet, + apiPost, + apiDelete, + apiAdminGet, + apiAdminPost, + apiAdminPut, + apiAdminDelete +} from './base' const BASE_URL = '/api/system/skills' const USER_BASE_URL = '/api/skills' diff --git a/web/src/components/AccountSettingsComponent.vue b/web/src/components/AccountSettingsComponent.vue index de0feeae..a0beea2e 100644 --- a/web/src/components/AccountSettingsComponent.vue +++ b/web/src/components/AccountSettingsComponent.vue @@ -64,7 +64,12 @@ @keydown.esc.stop.prevent="cancelField" @blur="cancelField" /> - @@ -289,11 +294,7 @@ watch( } ) -watch( - () => [userStore.username, userStore.phoneNumber], - syncProfileDraft, - { immediate: true } -) +watch(() => [userStore.username, userStore.phoneNumber], syncProfileDraft, { immediate: true }) \ No newline at end of file + diff --git a/web/src/components/MessageInputComponent.vue b/web/src/components/MessageInputComponent.vue index 5f02982a..e46df558 100644 --- a/web/src/components/MessageInputComponent.vue +++ b/web/src/components/MessageInputComponent.vue @@ -99,7 +99,11 @@
@@ -204,7 +208,11 @@
@@ -411,7 +419,10 @@ const getRawNodeLength = (node) => { if (isTextNode(node)) return node.textContent?.length || 0 if (isMentionNode(node)) return node.dataset.mentionRaw?.length || 0 if (isLineBreakNode(node)) return 1 - return Array.from(node.childNodes || []).reduce((total, child) => total + getRawNodeLength(child), 0) + return Array.from(node.childNodes || []).reduce( + (total, child) => total + getRawNodeLength(child), + 0 + ) } const serializeEditorNode = (node) => { @@ -462,7 +473,11 @@ const createEditorMentionElement = (segment) => { const label = document.createElement('span') label.className = 'mention-ref-label' - label.textContent = getMentionDisplayLabel(segment.type, segment.value, mentionDisplayLabels.value) + label.textContent = getMentionDisplayLabel( + segment.type, + segment.value, + mentionDisplayLabels.value + ) token.appendChild(label) return token @@ -475,7 +490,9 @@ const renderEditorContent = (raw = '') => { editor.replaceChildren() parseMentionText(raw).forEach((segment) => { editor.appendChild( - segment.kind === 'text' ? document.createTextNode(segment.text) : createEditorMentionElement(segment) + segment.kind === 'text' + ? document.createTextNode(segment.text) + : createEditorMentionElement(segment) ) }) lastSyncedEditorValue = String(raw || '') @@ -549,7 +566,10 @@ const getDomPointForRawOffset = (rawOffset) => { let remaining = offset const pointBeforeNode = (node) => ({ node: node.parentNode || editor, offset: childIndex(node) }) - const pointAfterNode = (node) => ({ node: node.parentNode || editor, offset: childIndex(node) + 1 }) + const pointAfterNode = (node) => ({ + node: node.parentNode || editor, + offset: childIndex(node) + 1 + }) const visit = (node) => { if (!node) return null @@ -872,7 +892,12 @@ const insertMention = (item) => { const mentionValue = item.insertValue || item.value const mentionText = `${formatMentionToken(item.type, mentionValue)} ` - const newValue = replaceRawRange(currentValue, activeMention.start, activeMention.end, mentionText) + const newValue = replaceRawRange( + currentValue, + activeMention.start, + activeMention.end, + mentionText + ) const newCursorPos = activeMention.start + mentionText.length mentionPopupVisible.value = false diff --git a/web/src/components/ModelSelectorComponent.vue b/web/src/components/ModelSelectorComponent.vue index c5139f16..8f095afa 100644 --- a/web/src/components/ModelSelectorComponent.vue +++ b/web/src/components/ModelSelectorComponent.vue @@ -1,5 +1,10 @@