From d9b9980877f9acb9018e1e074ecb83287ed1e045 Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Tue, 24 Mar 2026 15:46:01 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=87=8D=E6=9E=84=E5=86=85=E7=BD=AE?= =?UTF-8?q?=E6=8A=80=E8=83=BD=E7=9B=AE=E5=BD=95=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91=EF=BC=8C=E6=94=B9=E4=B8=BA=E5=A4=8D=E5=88=B6=E4=BB=A5?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E6=B2=99=E7=9B=92=E5=9C=BA=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package/yuxi/config/static/models.py | 2 +- .../package/yuxi/services/skill_service.py | 22 ++++++++++++------- docs/develop-guides/roadmap.md | 5 +++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/backend/package/yuxi/config/static/models.py b/backend/package/yuxi/config/static/models.py index 885bbc25..83cc2707 100644 --- a/backend/package/yuxi/config/static/models.py +++ b/backend/package/yuxi/config/static/models.py @@ -118,7 +118,7 @@ DEFAULT_CHAT_MODEL_PROVIDERS: dict[str, ChatModelProvider] = { "minimax": ChatModelProvider( name="MiniMax", url="https://platform.minimaxi.com/document/introduction", - base_url="https://api.minimax.io/v1", + base_url="https://api.minimaxi.com/v1", default="MiniMax-M2.7", env="MINIMAX_API_KEY", models=[ diff --git a/backend/package/yuxi/services/skill_service.py b/backend/package/yuxi/services/skill_service.py index 5a5ea0d6..1021aa0a 100644 --- a/backend/package/yuxi/services/skill_service.py +++ b/backend/package/yuxi/services/skill_service.py @@ -99,18 +99,24 @@ def _is_builtin_managed(item: Skill, slug: str) -> bool: return (item.created_by or "") in {"system", BUILTIN_SKILL_OPERATOR} -def _ensure_symlink_target(target_dir: Path, source_dir: Path) -> None: +def _dirs_equal(dir1: Path, dir2: Path) -> bool: + """检查两个目录内容是否相同(通过文件列表比较)""" + if not dir1.exists() or not dir2.exists(): + return False + list1 = sorted([f.relative_to(dir1) for f in dir1.rglob("*") if f.is_file()]) + list2 = sorted([f.relative_to(dir2) for f in dir2.rglob("*") if f.is_file()]) + return list1 == list2 + + +def _copy_skill_target(target_dir: Path, source_dir: Path) -> None: if target_dir.is_symlink(): - if target_dir.resolve() == source_dir.resolve(): - return target_dir.unlink() elif target_dir.exists(): + if _dirs_equal(target_dir, source_dir): + return raise ValueError(f"技能目录已存在且非内置链接,无法托管: {target_dir}") - try: - target_dir.symlink_to(source_dir, target_is_directory=True) - except OSError as e: - raise ValueError(f"创建内置技能链接失败: {target_dir} -> {source_dir} ({e})") from e + shutil.copytree(source_dir, target_dir, symlinks=False, dirs_exist_ok=True) async def get_skill_dependency_options(db: AsyncSession) -> dict[str, list[str] | list[dict]]: @@ -615,7 +621,7 @@ async def init_builtin_skills(db: AsyncSession, *, created_by: str = "system") - skill_dependencies = configured_skills or _normalize_string_list(meta.get("skill_dependencies")) target_dir = skills_root / slug - _ensure_symlink_target(target_dir, source_dir) + _copy_skill_target(target_dir, source_dir) item = await repo.get_by_slug(slug) if item and not _is_builtin_managed(item, slug): diff --git a/docs/develop-guides/roadmap.md b/docs/develop-guides/roadmap.md index 63af2d15..f2fb7729 100644 --- a/docs/develop-guides/roadmap.md +++ b/docs/develop-guides/roadmap.md @@ -21,6 +21,10 @@ - 工具传递给模型的时候,使用英文,但部分模型不支持中文函数名(如gpt-4o-mini,deepseek 官方接口) - 生成基准测试会把所有的向量都计算一遍不合理 +- RUNs API 导致的问题 +- 双击导致的暂停问题 +- 自定义embedding和rerank模型的配置问题 + ## v0.6 @@ -28,6 +32,7 @@ - 新增 API Key 管理功能,支持外部系统通过 API Key 调用 Agent 对话接口(`POST /api/chat/agent/{agent_id}`)。统一使用 `Authorization: Bearer ` 认证,API Key 以 `yxkey_` 开头。获取 API Key 即代表拥有绑定用户的所有接口访问权限。 - 将 后端代码 和 agents 解耦,agents 作为单独的 package 使用 - 添加 subagents +- 将内置 skills 的初始化从符号链接改为复制,以兼容沙盒绑定场景 ## v0.5