From 4df242e63b0fbcd4c6357433fb5c2d372b5813a1 Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Tue, 24 Mar 2026 22:37:03 +0800 Subject: [PATCH] =?UTF-8?q?format:=20=E6=A0=BC=E5=BC=8F=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../package/yuxi/agents/backends/__init__.py | 2 +- .../package/yuxi/agents/backends/composite.py | 2 +- .../yuxi/agents/backends/sandbox/__init__.py | 10 +++--- .../sandbox/sandbox_local_container.py | 2 +- .../backends/sandbox/sandbox_provisioner.py | 12 +++---- .../sandbox/sandbox_provisioner_base.py | 12 +++---- .../agents/backends/sandbox/sandbox_remote.py | 2 +- .../yuxi/agents/buildin/chatbot/graph.py | 1 + .../yuxi/agents/buildin/deep_agent/graph.py | 6 +--- backend/package/yuxi/agents/context.py | 2 +- .../agents/middlewares/skills_middleware.py | 5 ++- .../yuxi/services/filesystem_service.py | 4 +-- .../services/viewer_filesystem_service.py | 7 ++-- scripts/init.ps1 | 2 +- web/src/components/AgentChatComponent.vue | 4 ++- web/src/components/AgentConfigSidebar.vue | 14 +++----- web/src/components/AgentPanel.vue | 32 +++++++++++-------- web/src/components/McpServersComponent.vue | 1 - .../components/ModelProvidersComponent.vue | 17 ++++------ web/src/components/UserInfoComponent.vue | 16 +++++----- .../components/UserManagementComponent.vue | 4 ++- .../dashboard/ToolStatsComponent.vue | 4 +-- web/src/views/HomeView.vue | 8 ++--- 23 files changed, 76 insertions(+), 93 deletions(-) diff --git a/backend/package/yuxi/agents/backends/__init__.py b/backend/package/yuxi/agents/backends/__init__.py index b5010208..702fa5b7 100644 --- a/backend/package/yuxi/agents/backends/__init__.py +++ b/backend/package/yuxi/agents/backends/__init__.py @@ -27,9 +27,9 @@ from .sandbox import ( get_sandbox_base_port, get_sandbox_host, get_sandbox_image, + get_sandbox_provider, get_sandbox_provisioner_url, get_sandbox_security_opts, - get_sandbox_provider, ) from .skills_backend import SelectedSkillsReadonlyBackend diff --git a/backend/package/yuxi/agents/backends/composite.py b/backend/package/yuxi/agents/backends/composite.py index ec66206b..0c4da3a4 100644 --- a/backend/package/yuxi/agents/backends/composite.py +++ b/backend/package/yuxi/agents/backends/composite.py @@ -4,8 +4,8 @@ from deepagents.backends import CompositeBackend, StateBackend from yuxi.agents.middlewares.skills_middleware import normalize_selected_skills -from .skills_backend import SelectedSkillsReadonlyBackend from .sandbox import get_sandbox_provider +from .skills_backend import SelectedSkillsReadonlyBackend def _get_visible_skills_from_runtime(runtime) -> list[str]: diff --git a/backend/package/yuxi/agents/backends/sandbox/__init__.py b/backend/package/yuxi/agents/backends/sandbox/__init__.py index 694c3dc4..8688a92a 100644 --- a/backend/package/yuxi/agents/backends/sandbox/__init__.py +++ b/backend/package/yuxi/agents/backends/sandbox/__init__.py @@ -16,10 +16,7 @@ - docker_api: Docker API 调用封装 """ -from .sandbox_executor import YuxiSandboxBackend -from .sandbox_info import SandboxInfo -from .sandbox_provisioner import YuxiSandboxProvider, get_sandbox_provider -from .sandbox_provisioner_base import SandboxBackend +from .path_security import normalize_virtual_path from .sandbox_config import ( IDLE_CHECK_INTERVAL, LARGE_TOOL_RESULTS_DIR, @@ -39,9 +36,12 @@ from .sandbox_config import ( get_sandbox_provisioner_url, get_sandbox_security_opts, ) +from .sandbox_executor import YuxiSandboxBackend +from .sandbox_info import SandboxInfo from .sandbox_local_container import LocalContainerBackend +from .sandbox_provisioner import YuxiSandboxProvider, get_sandbox_provider +from .sandbox_provisioner_base import SandboxBackend from .sandbox_remote import RemoteSandboxBackend -from .path_security import normalize_virtual_path __all__ = [ # Executor diff --git a/backend/package/yuxi/agents/backends/sandbox/sandbox_local_container.py b/backend/package/yuxi/agents/backends/sandbox/sandbox_local_container.py index c7723b2f..52d6cf6f 100644 --- a/backend/package/yuxi/agents/backends/sandbox/sandbox_local_container.py +++ b/backend/package/yuxi/agents/backends/sandbox/sandbox_local_container.py @@ -9,9 +9,9 @@ import urllib.parse from yuxi.utils.logging_config import logger from .docker_api import docker_api_request -from .sandbox_provisioner_base import SandboxBackend from .sandbox_config import get_sandbox_host, get_sandbox_security_opts from .sandbox_info import SandboxInfo +from .sandbox_provisioner_base import SandboxBackend class LocalContainerBackend(SandboxBackend): diff --git a/backend/package/yuxi/agents/backends/sandbox/sandbox_provisioner.py b/backend/package/yuxi/agents/backends/sandbox/sandbox_provisioner.py index 547a22db..b3d097b3 100644 --- a/backend/package/yuxi/agents/backends/sandbox/sandbox_provisioner.py +++ b/backend/package/yuxi/agents/backends/sandbox/sandbox_provisioner.py @@ -14,10 +14,6 @@ from yuxi import config as sys_config from yuxi.services.skill_service import get_skills_root_dir from yuxi.utils.logging_config import logger -from .sandbox_local_container import LocalContainerBackend -from .sandbox_remote import RemoteSandboxBackend -from .sandbox_executor import YuxiSandboxBackend -from .sandbox_provisioner_base import SandboxBackend from .sandbox_config import ( IDLE_CHECK_INTERVAL, LARGE_TOOL_RESULTS_DIR, @@ -34,7 +30,11 @@ from .sandbox_config import ( get_sandbox_image, get_sandbox_provisioner_url, ) +from .sandbox_executor import YuxiSandboxBackend from .sandbox_info import SandboxInfo +from .sandbox_local_container import LocalContainerBackend +from .sandbox_provisioner_base import SandboxBackend +from .sandbox_remote import RemoteSandboxBackend class YuxiSandboxProvider: @@ -259,9 +259,7 @@ class YuxiSandboxProvider: self._last_activity.pop(sandbox_id, None) self._warm_pool.pop(sandbox_id, None) thread_ids = [ - thread_id - for thread_id, mapped_id in self._thread_sandboxes.items() - if mapped_id == sandbox_id + thread_id for thread_id, mapped_id in self._thread_sandboxes.items() if mapped_id == sandbox_id ] for thread_id in thread_ids: del self._thread_sandboxes[thread_id] diff --git a/backend/package/yuxi/agents/backends/sandbox/sandbox_provisioner_base.py b/backend/package/yuxi/agents/backends/sandbox/sandbox_provisioner_base.py index 921d94fb..ff2418b9 100644 --- a/backend/package/yuxi/agents/backends/sandbox/sandbox_provisioner_base.py +++ b/backend/package/yuxi/agents/backends/sandbox/sandbox_provisioner_base.py @@ -13,17 +13,13 @@ class SandboxBackend(ABC): thread_id: str, sandbox_id: str, extra_mounts: list[tuple[str, str, bool]] | None = None, - ) -> SandboxInfo: - ... + ) -> SandboxInfo: ... @abstractmethod - def destroy(self, info: SandboxInfo) -> None: - ... + def destroy(self, info: SandboxInfo) -> None: ... @abstractmethod - def is_alive(self, info: SandboxInfo) -> bool: - ... + def is_alive(self, info: SandboxInfo) -> bool: ... @abstractmethod - def discover(self, sandbox_id: str) -> SandboxInfo | None: - ... + def discover(self, sandbox_id: str) -> SandboxInfo | None: ... diff --git a/backend/package/yuxi/agents/backends/sandbox/sandbox_remote.py b/backend/package/yuxi/agents/backends/sandbox/sandbox_remote.py index 9e6e35d7..e04fcd86 100644 --- a/backend/package/yuxi/agents/backends/sandbox/sandbox_remote.py +++ b/backend/package/yuxi/agents/backends/sandbox/sandbox_remote.py @@ -6,8 +6,8 @@ import requests from yuxi.utils.logging_config import logger -from .sandbox_provisioner_base import SandboxBackend from .sandbox_info import SandboxInfo +from .sandbox_provisioner_base import SandboxBackend class RemoteSandboxBackend(SandboxBackend): diff --git a/backend/package/yuxi/agents/buildin/chatbot/graph.py b/backend/package/yuxi/agents/buildin/chatbot/graph.py index 0833768d..01b7c869 100644 --- a/backend/package/yuxi/agents/buildin/chatbot/graph.py +++ b/backend/package/yuxi/agents/buildin/chatbot/graph.py @@ -21,6 +21,7 @@ from yuxi.services.subagent_service import get_subagents_from_names from .prompt import PROMPT + def _create_fs_backend(rt): """创建文件存储后端(支持沙盒执行) diff --git a/backend/package/yuxi/agents/buildin/deep_agent/graph.py b/backend/package/yuxi/agents/buildin/deep_agent/graph.py index bec69710..ba3015ff 100644 --- a/backend/package/yuxi/agents/buildin/deep_agent/graph.py +++ b/backend/package/yuxi/agents/buildin/deep_agent/graph.py @@ -39,11 +39,7 @@ class DeepAgent(BaseAgent): description = "具备规划、深度分析和子智能体协作能力的智能体,可以处理复杂的多步骤任务" context_schema = DeepContext capabilities = ["file_upload", "files", "todo"] # 支持文件上传功能 - metadata = { - "examples": [ - "调研一下多模态 GraphRAG 的相关论文" - ] - } + metadata = {"examples": ["调研一下多模态 GraphRAG 的相关论文"]} def __init__(self, **kwargs): super().__init__(**kwargs) diff --git a/backend/package/yuxi/agents/context.py b/backend/package/yuxi/agents/context.py index d28808f2..62901df6 100644 --- a/backend/package/yuxi/agents/context.py +++ b/backend/package/yuxi/agents/context.py @@ -92,7 +92,7 @@ class BaseContext: default=sys_config.default_model, metadata={ "name": "子智能体的默认模型", - "description": "子智能体的默认模型,会被子智能体的配置覆盖。", + "description": "为所有子智能体设置默认模型,可在各子智能体配置中单独覆盖。", }, ) diff --git a/backend/package/yuxi/agents/middlewares/skills_middleware.py b/backend/package/yuxi/agents/middlewares/skills_middleware.py index efa929eb..f1d6b826 100644 --- a/backend/package/yuxi/agents/middlewares/skills_middleware.py +++ b/backend/package/yuxi/agents/middlewares/skills_middleware.py @@ -404,9 +404,8 @@ class SkillsMiddleware(AgentMiddleware): return None pure = PurePosixPath(raw if raw.startswith("/") else f"/{raw}") parts = [p for p in pure.parts if p not in ("/", "")] - if len(parts) == 3 and parts[0] == "skills" and parts[2] == "SKILL.md": - slug = parts[1] - elif len(parts) == 4 and parts[0] == "mnt" and parts[1] == "skills" and parts[3] == "SKILL.md": + # 只支持 /mnt/skills/{slug}/SKILL.md 格式 + if len(parts) == 4 and parts[0] == "mnt" and parts[1] == "skills" and parts[3] == "SKILL.md": slug = parts[2] else: return None diff --git a/backend/package/yuxi/services/filesystem_service.py b/backend/package/yuxi/services/filesystem_service.py index aff59081..f98ef10a 100644 --- a/backend/package/yuxi/services/filesystem_service.py +++ b/backend/package/yuxi/services/filesystem_service.py @@ -4,15 +4,15 @@ import asyncio from fastapi import HTTPException from sqlalchemy.ext.asyncio import AsyncSession -from yuxi.agents.context import BaseContext from yuxi.agents.backends import ( create_agent_composite_backend, resolve_sandbox_backend_async, ) +from yuxi.agents.context import BaseContext from yuxi.repositories.agent_config_repository import AgentConfigRepository from yuxi.repositories.conversation_repository import ConversationRepository -from yuxi.storage.postgres.models_business import User from yuxi.services.conversation_service import require_user_conversation +from yuxi.storage.postgres.models_business import User async def _resolve_filesystem_context( diff --git a/backend/package/yuxi/services/viewer_filesystem_service.py b/backend/package/yuxi/services/viewer_filesystem_service.py index 8b3465a8..3439df38 100644 --- a/backend/package/yuxi/services/viewer_filesystem_service.py +++ b/backend/package/yuxi/services/viewer_filesystem_service.py @@ -9,12 +9,11 @@ from urllib.parse import quote from fastapi import HTTPException from fastapi.responses import StreamingResponse from sqlalchemy.ext.asyncio import AsyncSession - from yuxi.agents.backends.sandbox import SKILLS_PATH, USER_DATA_PATH from yuxi.agents.backends.skills_backend import SelectedSkillsReadonlyBackend from yuxi.agents.middlewares.skills_middleware import normalize_selected_skills -from yuxi.storage.postgres.models_business import User from yuxi.services.filesystem_service import _resolve_filesystem_state +from yuxi.storage.postgres.models_business import User def _normalize_path(path: str | None) -> str: @@ -117,9 +116,7 @@ async def list_viewer_filesystem_tree( ) if normalized_path == "/": - entries = [ - {"path": f"{USER_DATA_PATH}/", "name": "user-data", "is_dir": True, "size": 0, "modified_at": ""} - ] + entries = [{"path": f"{USER_DATA_PATH}/", "name": "user-data", "is_dir": True, "size": 0, "modified_at": ""}] if selected_skills: entries.append({"path": f"{SKILLS_PATH}/", "name": "skills", "is_dir": True, "size": 0, "modified_at": ""}) return {"entries": entries} diff --git a/scripts/init.ps1 b/scripts/init.ps1 index a9060e2f..6e267f79 100644 --- a/scripts/init.ps1 +++ b/scripts/init.ps1 @@ -67,7 +67,7 @@ $images = @( "ghcr.io/astral-sh/uv:0.7.2", "nginx:alpine", "quay.io/coreos/etcd:v3.5.5", - "postgres:16" + "postgres:16", "redis:7-alpine" ) diff --git a/web/src/components/AgentChatComponent.vue b/web/src/components/AgentChatComponent.vue index 8ba4565d..a9a424d6 100644 --- a/web/src/components/AgentChatComponent.vue +++ b/web/src/components/AgentChatComponent.vue @@ -476,7 +476,9 @@ const isStreaming = computed(() => { }) const isProcessing = computed(() => isStreaming.value) const isSendButtonDisabled = computed(() => { - return sendCooldownActive.value || (((!userInput.value || !currentAgent.value) && !isProcessing.value)) + return ( + sendCooldownActive.value || ((!userInput.value || !currentAgent.value) && !isProcessing.value) + ) }) const startSendCooldown = () => { diff --git a/web/src/components/AgentConfigSidebar.vue b/web/src/components/AgentConfigSidebar.vue index 9868a0bb..89bc580f 100644 --- a/web/src/components/AgentConfigSidebar.vue +++ b/web/src/components/AgentConfigSidebar.vue @@ -58,11 +58,7 @@
- +
{ const segmentConfigKeys = computed(() => { const keys = Object.keys(configurableItems.value) return { - model: keys.filter(key => { + model: keys.filter((key) => { const meta = configurableItems.value[key]?.template_metadata?.kind return meta === 'llm' || meta === 'prompt' }), - tools: keys.filter(key => { + tools: keys.filter((key) => { const meta = configurableItems.value[key]?.template_metadata?.kind return ['tools', 'knowledges', 'mcps', 'skills', 'subagents'].includes(meta) }), - other: keys.filter(key => { + other: keys.filter((key) => { const meta = configurableItems.value[key]?.template_metadata?.kind return !['llm', 'prompt', 'tools', 'knowledges', 'mcps', 'skills', 'subagents'].includes(meta) }) @@ -590,7 +586,7 @@ const filteredConfigurableItems = computed(() => { if (isEmptyConfig.value) return {} const keys = segmentConfigKeys.value[currentSegment.value] || [] const filtered = {} - keys.forEach(key => { + keys.forEach((key) => { filtered[key] = configurableItems.value[key] }) return filtered diff --git a/web/src/components/AgentPanel.vue b/web/src/components/AgentPanel.vue index 75f691e6..bfa21b2f 100644 --- a/web/src/components/AgentPanel.vue +++ b/web/src/components/AgentPanel.vue @@ -136,7 +136,9 @@
{{
             formatContent(currentFile.content)
           }}
-
{{ currentFile.content }}
+
{{
+            currentFile.content
+          }}
{{ JSON.stringify(currentFile, null, 2) }}
@@ -392,7 +394,12 @@ const refreshFileSystem = async () => { loadingFiles.value = true filesystemError.value = '' try { - const res = await getViewerFileSystemTree(props.threadId, '/', props.agentId, props.agentConfigId) + const res = await getViewerFileSystemTree( + props.threadId, + '/', + props.agentId, + props.agentConfigId + ) if (res && res.entries) { dynamicTreeData.value = sortEntries(res.entries).map((entry) => createTreeNode(entry)) expandedKeys.value = [] @@ -413,19 +420,16 @@ onMounted(() => { refreshFileSystem() }) -watch( - [() => props.threadId, () => props.agentId, () => props.agentConfigId], - ([threadId]) => { - if (threadId) { - refreshFileSystem() - } else { - dynamicTreeData.value = [] - expandedKeys.value = [] - selectedKeys.value = [] - filesystemError.value = '' - } +watch([() => props.threadId, () => props.agentId, () => props.agentConfigId], ([threadId]) => { + if (threadId) { + refreshFileSystem() + } else { + dynamicTreeData.value = [] + expandedKeys.value = [] + selectedKeys.value = [] + filesystemError.value = '' } -) +}) const fileTreeData = computed(() => dynamicTreeData.value) diff --git a/web/src/components/McpServersComponent.vue b/web/src/components/McpServersComponent.vue index 5bc87730..5800dd1f 100644 --- a/web/src/components/McpServersComponent.vue +++ b/web/src/components/McpServersComponent.vue @@ -298,7 +298,6 @@ - diff --git a/web/src/components/ModelProvidersComponent.vue b/web/src/components/ModelProvidersComponent.vue index d1846f3a..ff1c55f4 100644 --- a/web/src/components/ModelProvidersComponent.vue +++ b/web/src/components/ModelProvidersComponent.vue @@ -1,16 +1,13 @@