diff --git a/pipeline_service/agent_loop.py b/pipeline_service/agent_loop.py index aab3fc0..fe495ea 100644 --- a/pipeline_service/agent_loop.py +++ b/pipeline_service/agent_loop.py @@ -22,7 +22,7 @@ from contextlib import asynccontextmanager logger = logging.getLogger("pipeline.agent_loop") -from .workspace import WORKSPACE_BASE +from .workspace import WORKSPACE_BASE, build_space_path, GENERAL_SPACE ROLE_ALIASES = { 'developer': 'agent.develop', 'dev': 'agent.develop', 'development': 'agent.develop', 'coding': 'agent.develop', @@ -671,13 +671,17 @@ async def _get_space_dir(sor, project_id): """返回产线工作空间(机构工作空间层){space}/——角色 agent 工具路径基准。 新规下角色在 projects/{项目}/docs/、apps/、modules/ 下读写, - 这些相对路径的基准是 {space}/(不是项目目录 {space}/{项目名})。 + 这些相对路径的基准是 {space}/。用 build_space_path(org_id + pipeline_id)构造, + 不依赖 workspace_dir 路径结构(workspace_dir 迁到 {space}/projects/{项目名} 后 dirname 会错)。 """ - ws = await _get_workspace_dir(sor, project_id) - if not ws: - return ws - # workspace_dir = {base}/{org}/{space}/{项目名},空间目录 = 其父目录 - return os.path.dirname(ws.rstrip('/')) + recs = await sor.sqlExe( + "SELECT org_id, pipeline_id FROM sd_projects WHERE id=${pid}$ LIMIT 1", + {"pid": project_id}) + if not recs: + return _resolve_workspace('') + org_id = getattr(recs[0], 'org_id', '0') or '0' + space = getattr(recs[0], 'pipeline_id', '') or GENERAL_SPACE + return build_space_path(WORKSPACE_BASE, org_id, space) def _parse_skill_frontmatter(content): diff --git a/pipeline_service/workspace.py b/pipeline_service/workspace.py index 993a370..1deeded 100644 --- a/pipeline_service/workspace.py +++ b/pipeline_service/workspace.py @@ -158,13 +158,24 @@ async def get_workspace_dir(sor, uid, session_id=''): async def get_space_dir(sor, uid, session_id=''): """返回机构工作空间层 {space}/(projects/apps/modules 三目录所在)。 - 新结构:项目目录迁到 {space}/projects/{项目名}/,与 apps/、modules/ 平级。 - workspace_dir 仍是旧结构 {space}/{项目名},space = 其父目录。 + 用 build_space_path(org_id + pipeline_id)构造,不依赖 workspace_dir 的路径结构 + (workspace_dir 迁移到 {space}/projects/{项目名} 后 dirname 会错)。 """ - ws_dir, workspace_base = await get_workspace_dir(sor, uid, session_id) - if not ws_dir: + workspace_base = await get_workspace_base(sor) + pid = await get_session_project_id(sor, uid, session_id) + if not pid: return '', workspace_base - return os.path.dirname(ws_dir.rstrip('/')), workspace_base + try: + proj = await sor.sqlExe( + "SELECT org_id, pipeline_id FROM sd_projects WHERE id=${p}$ LIMIT 1", + {"p": pid}) + if proj: + org_id = getattr(proj[0], 'org_id', '0') or '0' + space = getattr(proj[0], 'pipeline_id', '') or GENERAL_SPACE + return build_space_path(workspace_base, org_id, space), workspace_base + except Exception: + pass + return '', workspace_base async def get_project_dir(sor, uid, session_id=''):