From d05571cc96ba2d919883a82c4af9db8469061611 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Wed, 2 Sep 2026 19:05:33 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20list=5Fmessages/=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E4=BA=A7=E7=BA=BF=E9=9A=94=E7=A6=BB=E7=BC=BA?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - list_messages原无过滤返回全表→按user+session+pipeline过滤(跨产线/跨用户泄漏) - agent_model_options接收pipeline_id并传给get_session_project_id,防跨产线项目劫持模型选中态 --- wwwroot/api/agent_chat.dspy | 21 ++++++++++++++++++--- wwwroot/api/agent_model_options.dspy | 5 ++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/wwwroot/api/agent_chat.dspy b/wwwroot/api/agent_chat.dspy index df9a24d..55b3539 100644 --- a/wwwroot/api/agent_chat.dspy +++ b/wwwroot/api/agent_chat.dspy @@ -141,10 +141,25 @@ elif action == 'list_messages': uid = await get_user() if not uid: return json.dumps({"error": "请先登录"}, ensure_ascii=False) + # 产线隔离(2026-09-02):必须按 user + session + pipeline 过滤。 + # 旧实现无过滤返回全表——跨产线/跨用户会话历史泄漏。 + _sid = (params_kw or {}).get('session_id', '') or '' + _pl = (params_kw or {}).get('pipeline_id', '') or '' + _sql = ("SELECT role, content, created_at FROM pipeline_conversations " + "WHERE created_by=${u}$") + _kw = {"u": uid, "lim": 100} + if _sid: + _sql += " AND session_id=${sid}$" + _kw["sid"] = _sid + if _pl: + _sql += " AND pipeline_id=${pl}$" + _kw["pl"] = _pl + # DESC+LIMIT 取最新再倒序(与 _load_history 隔离策略一致;ASC+LIMIT 会取最旧) + _sql += " ORDER BY created_at DESC LIMIT ${lim}$" async with DBPools().sqlorContext(dbname) as sor: - ms = await sor.sqlExe( - "SELECT role,content,created_at FROM pipeline_conversations ORDER BY created_at ASC LIMIT 100", {}) - result = [{"role": getattr(m, 'role', ''), "content": getattr(m, 'content', '')} for m in (ms or [])] + ms = await sor.sqlExe(_sql, _kw) + result = [{"role": getattr(m, 'role', ''), "content": getattr(m, 'content', '')} + for m in reversed(ms or [])] return json.dumps({"success": True, "messages": result}, ensure_ascii=False, default=str) else: diff --git a/wwwroot/api/agent_model_options.dspy b/wwwroot/api/agent_model_options.dspy index ee5c357..38137e7 100644 --- a/wwwroot/api/agent_model_options.dspy +++ b/wwwroot/api/agent_model_options.dspy @@ -13,6 +13,7 @@ dbname = get_module_dbname('pipeline_core') uid = await get_user() org_id = (await get_userorgid()) or '' session_id = (params_kw or {}).get('session_id', '') or '' +pipeline_id = (params_kw or {}).get('pipeline_id', '') or '' async with DBPools().sqlorContext(dbname) as sor: sql = "SELECT id, name, provider, model_id, capabilities FROM llm WHERE status='active'" @@ -28,7 +29,9 @@ async with DBPools().sqlorContext(dbname) as sor: project_model = '' try: from pipeline_service.workspace import get_session_project_id - _pid = await get_session_project_id(sor, uid or '', session_id) + # 产线隔离(2026-09-02):传入口产线,跨产线项目不算本会话项目—— + # 否则平台/其他产线页面的模型选中态会被投标项目的 default_model 劫持 + _pid = await get_session_project_id(sor, uid or '', session_id, pipeline_id) if _pid: _p = await sor.sqlExe( "SELECT default_model FROM sd_projects WHERE id=${p}$", {"p": _pid})