diff --git a/pipeline_service/agent_loop_v2.py b/pipeline_service/agent_loop_v2.py index 5386720..2308f8b 100644 --- a/pipeline_service/agent_loop_v2.py +++ b/pipeline_service/agent_loop_v2.py @@ -287,35 +287,7 @@ class AgentExecutor: async def _init_components(self): """懒加载各组件""" - # Tool Registry - try: - from pipeline_core.tool_registry import get_tool_registry - self._tool_registry = get_tool_registry() - # 把 config.tools 注册进 registry(registry 是全局单例,可能为空) - if self._tool_registry and self.config.tools: - existing = set(self._tool_registry.get_tool_names()) - for t in self.config.tools: - if t.name not in existing: - self._tool_registry.register(t) - except ImportError: - self._tool_registry = None - - # Skill Loader — 三级隔离 - try: - from pipeline_core.skill_loader import get_skill_loader - base_dir = self.config.skills.base_dir - self._skill_loader = get_skill_loader(base_dir) - except ImportError: - self._skill_loader = None - - # Memory Store - try: - from pipeline_core.memory_store import get_memory_store - self._memory_store = get_memory_store() - except ImportError: - self._memory_store = None - - # 加载 org_id + workspace_dir + pipeline_id(从项目上下文) + # 1. 加载 org_id + workspace_dir + pipeline_id(从项目上下文,需先于 skill 加载) if self.project_id: try: from sqlor.dbpools import DBPools @@ -333,7 +305,37 @@ class AgentExecutor: except Exception: pass - # pipeline_id 为空时 fallback 到默认产线(保证 slash/ability/skill 统一按产线挂载) + # 2. Tool Registry + try: + from pipeline_core.tool_registry import get_tool_registry + self._tool_registry = get_tool_registry() + # 把 config.tools 注册进 registry(registry 是全局单例,可能为空) + if self._tool_registry and self.config.tools: + existing = set(self._tool_registry.get_tool_names()) + for t in self.config.tools: + if t.name not in existing: + self._tool_registry.register(t) + except ImportError: + self._tool_registry = None + + # 3. Skill Loader — base_dir 动态解析到机构工作目录(多租户隔离) + try: + from pipeline_core.skill_loader import get_skill_loader + base_dir = await self._resolve_skills_base_dir() + self._skill_loader = get_skill_loader(base_dir) + if base_dir: + self._skill_loader.reload() + except Exception: + self._skill_loader = None + + # 4. Memory Store + try: + from pipeline_core.memory_store import get_memory_store + self._memory_store = get_memory_store() + except ImportError: + self._memory_store = None + + # 5. pipeline_id 为空时 fallback 到默认产线(保证 slash/ability/skill 统一按产线挂载) if not self.pipeline_id: try: from pipeline_core import DEFAULT_ABILITY_ID @@ -341,6 +343,20 @@ class AgentExecutor: except ImportError: pass + async def _resolve_skills_base_dir(self): + """技能根目录 = 机构工作目录/skills/(多租户隔离,不在全局应用目录)。""" + try: + from sqlor.dbpools import DBPools + from pipeline_service.workspace import get_workspace_base + from pipeline_core.skill_pack import ensure_org_skills + db = DBPools() + async with db.sqlorContext("pipeline") as sor: + ws_base = await get_workspace_base(sor) + org_id = self.org_id or '0' + return ensure_org_skills(ws_base, org_id) + except Exception: + return self.config.skills.base_dir + async def _build_system_prompt(self, user_input: str) -> str: """组装完整 system prompt = 基础 prompt + 记忆 + 技能 + 工具列表""" prompt = self.config.system_prompt