From 58d773b6ad7fc2b53a43529080866a6db5daeb59 Mon Sep 17 00:00:00 2001 From: ymq Date: Thu, 27 Aug 2026 16:11:43 +0800 Subject: [PATCH] =?UTF-8?q?fix(workspace):=20=E4=BC=9A=E8=AF=9D=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E9=A1=B9=E7=9B=AE=E6=94=B9=E7=94=A8=E6=96=B0=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E7=9B=AE=E5=BD=95=20+=20=E5=86=99=E5=85=A5=20director?= =?UTF-8?q?y=5Fname?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:_t_create_project 用旧结构 build_workspace_path({space}/{项目名}),不写 directory_name;而工作空间读取端已迁到新结构 {space}/projects/{英文slug}, 导致会话新建的项目显示「项目目录(不可用)」。 修复: - 改用 build_space_path 拼 {space}/projects/{slug} 并 os.makedirs - slug 保留 [A-Za-z0-9_-],须含字母(避免纯数字如'7'),否则兑底 proj_{短ID} - 写入 directory_name 字段(工作空间读路径依据) - 同 slug 冲突追加短 ID --- pipeline_service/agent_loop_v2.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/pipeline_service/agent_loop_v2.py b/pipeline_service/agent_loop_v2.py index 888e35a..9d639af 100644 --- a/pipeline_service/agent_loop_v2.py +++ b/pipeline_service/agent_loop_v2.py @@ -859,6 +859,7 @@ class AgentExecutor: async def _t_create_project(self, sor, p, pid): import os + import re from appPublic.uniqueID import getID name = p.get("name", "").strip() @@ -874,18 +875,29 @@ class AgentExecutor: if _u: org_id = getattr(_u[0], "orgid", "0") or "0" - # 项目专属工作空间目录(workspace_base 从 appbase params 表读,可动态配置) - # 项目空间 = self.space(通用助手 'general' / 专业产线 pipeline_id),隔离不共享。 - from .workspace import get_workspace_base, build_workspace_path + # 项目专属工作空间目录(新结构:{base}/{org}/{space}/projects/{英文slug}/, + # 与 apps/、modules/ 平级;工作空间控件按此结构读取)。 + # 英文 slug:项目名保留 [A-Za-z0-9_-],且须含字母才有辨识度(避免纯数字如 "7"); + # 纯中文或纯数字名兑底 proj_{短ID}。 + from .workspace import get_workspace_base, build_space_path workspace_base = await get_workspace_base(sor) pid_val = getID() - workspace_dir = build_workspace_path(workspace_base, org_id, self.space, name, pid_val) - os.makedirs(workspace_dir, exist_ok=True) + space_dir = build_space_path(workspace_base, org_id, self.space) + slug = re.sub(r'[^A-Za-z0-9_-]', '', name).strip('_-') + if not slug or not re.search(r'[A-Za-z]', slug): + slug = 'proj_' + pid_val[-8:] + project_dir = os.path.join(space_dir, 'projects', slug) + if os.path.isdir(project_dir): + # 同 slug 已存在(不同项目重名)→ 追加短 ID,避免共享目录互相覆盖 + slug = f"{slug}_{pid_val[-8:]}" + project_dir = os.path.join(space_dir, 'projects', slug) + os.makedirs(project_dir, exist_ok=True) await sor.C("sd_projects", { "id": pid_val, "name": name, "description": desc, "status": "active", "org_id": org_id, - "pipeline_id": self.space, "workspace_dir": workspace_dir, + "pipeline_id": self.space, "workspace_dir": project_dir, + "directory_name": slug, "created_by": self.user_id or "", "default_model": self.model_name or "", })