diff --git a/pipeline_service/agent_loop_v2.py b/pipeline_service/agent_loop_v2.py index 9d639af..7bb768f 100644 --- a/pipeline_service/agent_loop_v2.py +++ b/pipeline_service/agent_loop_v2.py @@ -692,6 +692,7 @@ class AgentExecutor: "project_id": self.project_id, "user_id": self.user_id, "pipeline_id": self.pipeline_id, + "space": self.space, "workspace_dir": self.workspace_dir, "model_name": self.model_name, "config": self.config, diff --git a/pipeline_service/project_capability.py b/pipeline_service/project_capability.py index d1f2174..3da2f32 100644 --- a/pipeline_service/project_capability.py +++ b/pipeline_service/project_capability.py @@ -233,8 +233,12 @@ async def set_project_state(project_id, from_state, to_state, who=who, agent_id=agent_id, detail=detail) -async def list_projects(org_id=None, status=None, limit=50) -> list: - """列出项目(可按组织/状态过滤;org_id 空则列全部)。""" +async def list_projects(org_id=None, status=None, pipeline_id=None, limit=50) -> list: + """列出项目(可按组织/状态/产线过滤;org_id 空则列全部)。 + + 产线隔离:传 pipeline_id 时只列该产线的项目(投标/商机等产线会话 + 不串到开发产线项目)。不传则不按产线过滤。 + """ db, dbname = _get_db() async with db.sqlorContext(dbname) as sor: conditions = ["1=1"] @@ -245,6 +249,9 @@ async def list_projects(org_id=None, status=None, limit=50) -> list: if status: conditions.append("status=${status}$") params["status"] = status + if pipeline_id: + conditions.append("pipeline_id=${pl}$") + params["pl"] = pipeline_id where = " AND ".join(conditions) try: limit = int(limit) diff --git a/pipeline_service/sdlc_ability.py b/pipeline_service/sdlc_ability.py index 3831e45..b33e3fd 100644 --- a/pipeline_service/sdlc_ability.py +++ b/pipeline_service/sdlc_ability.py @@ -177,7 +177,7 @@ SDL_TOOLS = [ category="feature", ), # ── 项目生命周期 ── - ToolDefinition(name="list_projects", description="列出项目列表(含状态)", parameters={"status": "按状态筛选(可选)"}, category="project"), + ToolDefinition(name="list_projects", description="列出项目列表(含状态)——按当前产线隔离,产线会话只见本产线项目;传 all=true 跨产线看全部", parameters={"status": "按状态筛选(可选)", "all": "true=跨产线列全部项目(默认只列本产线)"}, category="project"), ToolDefinition(name="list_role_models", description="列出项目各角色的模型配置(缺省用项目缺省模型)", parameters={"project_id": "项目ID"}, category="project"), ToolDefinition(name="set_role_model", description="设置某角色的模型(如 deploy_test 用 qwen3.8-max;model_name 空=清除回退缺省)", parameters={"project_id": "项目ID", "role": "角色名(agent.develop/agent.deploy_test等)", "model_name": "模型名(llm.name,空=回退缺省)"}, category="project"), ToolDefinition(name="start_project", description="启动项目(draft/archived→active)", parameters={"project_id": "项目ID"}, category="project"), @@ -1091,7 +1091,16 @@ async def _h_list_projects(sor, p, ctx): if _u: org_id = getattr(_u[0], "orgid", "") or "" status = (p.get("status", "") or "").strip() - lst = await list_projects(org_id=org_id or None, status=status or None) + # 产线隔离:真实产线会话(space≠general)只列本产线项目—— + # 投标/商机产线不串出开发产线的项目。通用助手会话不过滤。 + # 用户明确要跨产线看全部时传 all=true。 + pipeline_filter = None + if (p.get("all", "") or "").strip().lower() not in ("true", "1", "yes"): + space = ctx.get("space", "") or "" + if space and space != "general": + pipeline_filter = space + lst = await list_projects(org_id=org_id or None, status=status or None, + pipeline_id=pipeline_filter) if not lst: return "暂无项目" lines = []