From 09f8b85f66e1caf961059985c037c9b6c0327ffa Mon Sep 17 00:00:00 2001 From: ymq Date: Thu, 27 Aug 2026 13:12:34 +0800 Subject: [PATCH] =?UTF-8?q?feat(gateway):=20run=5Fmessage/AgentExecutor=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20default=5Fpipeline=5Fid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 无当前项目时按入口指定产线装载能力(替代硬回退 sdlc_general)。 投标产线会话入口传 bidding_general 即可复用通用 agent 多 session 界面。 --- pipeline_service/agent_loop_v2.py | 4 +++- pipeline_service/gateway.py | 11 +++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pipeline_service/agent_loop_v2.py b/pipeline_service/agent_loop_v2.py index 470a9d7..888e35a 100644 --- a/pipeline_service/agent_loop_v2.py +++ b/pipeline_service/agent_loop_v2.py @@ -66,12 +66,13 @@ class AgentExecutor: generic: bool = False, # True = 纯通用会话(不解析项目、不挂产线能力) session=None, # GatewaySession(会话级状态:approve_all/pending_confirm) session_id: str = "", # 会话内唯一标识(web 多 tab 独立会话;历史隔离键) + default_pipeline_id: str = "", # 无当前项目时的默认产线(入口指定,如 bidding_general) ): self.config = config self.project_id = project_id self.user_id = user_id self.org_id = "" # loaded from project context - self.pipeline_id = "" # loaded from project context(产线能力包 key) + self.pipeline_id = default_pipeline_id or "" # 默认产线(入口指定);有项目时被项目 pipeline_id 覆盖 self.role = role # 产线内角色(技能/工具/prompt 按角色加载) self.generic = generic # 是否纯通用会话 self._session = session # GatewaySession(approve_all/pending_confirm 会话级状态) @@ -399,6 +400,7 @@ class AgentExecutor: self._memory_store = None # 5. pipeline_id 为空时 fallback 到默认产线(保证 slash/ability/skill 统一按产线挂载) + # 入口已指定 default_pipeline_id 时优先用它(投标/开发产线独立入口),否则用引擎默认。 if not self.pipeline_id: try: from pipeline_core import DEFAULT_ABILITY_ID diff --git a/pipeline_service/gateway.py b/pipeline_service/gateway.py index 872598f..5826bde 100644 --- a/pipeline_service/gateway.py +++ b/pipeline_service/gateway.py @@ -119,7 +119,8 @@ class Gateway: async def run_message(self, channel: str, user_id: str, content: str, history=None, role: str = "", generic: bool = False, - base_url: str = "", session_id: str = "") -> AsyncGenerator[str, None]: + base_url: str = "", session_id: str = "", + pipeline_id: str = "") -> AsyncGenerator[str, None]: """统一消息入口:解析上下文 → 加载产线能力 → AgentExecutor 执行 → yield 事件流。 Args: @@ -130,6 +131,8 @@ class Gateway: role: 可选产线内角色(驾驶舱 agent 为空) generic: True = 纯通用会话(不解析项目、不加载产线能力,只用 GENERAL_TOOLS + 通用心智) session_id: 会话内唯一标识(web 多 tab 独立会话用;空 = 单会话) + pipeline_id: 产线默认能力(会话入口指定,如 bidding_general/sdlc_general)。 + 无当前项目时用此产线装载能力,替代硬回退 DEFAULT_ABILITY_ID。 """ from pipeline_core.agent_config import load_agent_config from .agent_loop_v2 import AgentExecutor @@ -139,6 +142,9 @@ class Gateway: ctx = {"pid": "", "pipeline_id": "", "name": ""} else: ctx = await self.resolve_project(user_id, session_id) + # 无当前项目 → 用入口指定的默认产线(投标/开发产线各自独立入口的关键) + if not ctx.get("pipeline_id") and pipeline_id: + ctx["pipeline_id"] = pipeline_id # 2. 会话生命周期(跟踪 project 切换;session_id 区分多 tab 会话) key = self._session_key(channel, user_id, session_id) @@ -165,7 +171,8 @@ class Gateway: config.model_name = ctx["default_llm_name"] executor = AgentExecutor( config=config, project_id=ctx["pid"], user_id=user_id, role=role, - base_url=base_url, generic=generic, session=sess, session_id=session_id) + base_url=base_url, generic=generic, session=sess, session_id=session_id, + default_pipeline_id=pipeline_id) # 4. 转发标准化事件流 async for chunk in executor.run(content, history=history):