From f179a12d2347d83b38c5b8925eb730a9d1328d03 Mon Sep 17 00:00:00 2001 From: ymq Date: Thu, 10 Sep 2026 18:36:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(cockpit):=20=E4=B8=8A=E4=BC=A0=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E8=B5=B0=E5=8E=9F=E7=94=9F=E8=A7=86=E8=A7=89=E5=A4=9A?= =?UTF-8?q?=E6=A8=A1=E6=80=81=E2=80=94=E2=80=94is=5Fimage=E5=88=86?= =?UTF-8?q?=E6=B5=81=E4=B8=8D=E8=BF=9B=E6=96=87=E6=9C=AC=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=96=87,=20image=5Fpaths=E4=BC=A0gateway;=5Floc=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E5=9B=BE=E7=89=87=E5=8D=95=E5=88=97(read=5Ffile?= =?UTF-8?q?=E4=B8=8D=E6=94=AF=E6=8C=81=E8=AF=BB=E5=9B=BE,=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=B7=B2=E5=A4=9A=E6=A8=A1=E6=80=81=E6=B3=A8=E5=85=A5?= =?UTF-8?q?,=20=E5=90=8E=E7=BB=AD=E5=A4=84=E7=90=86=E7=94=A8invoke=5Fmodel?= =?UTF-8?q?=20i2t),=E6=B6=88=E9=99=A4=E4=BA=8C=E8=BF=9B=E5=88=B6=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E8=AF=BB=E5=8F=96=E7=9A=84=E7=9F=9B=E7=9B=BE=E6=8F=90?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wwwroot/api/cockpit_chat_v2.dspy | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/wwwroot/api/cockpit_chat_v2.dspy b/wwwroot/api/cockpit_chat_v2.dspy index f5e8930..1b5bd25 100644 --- a/wwwroot/api/cockpit_chat_v2.dspy +++ b/wwwroot/api/cockpit_chat_v2.dspy @@ -63,6 +63,7 @@ if action == 'send_message': # 2. 收集 (绝对路径, 文件名),稍后复制进项目根目录,让会话 agent 的 read_file 能找到 file_ctx = '' _uploads = [] # [(src_abs, filename)] + _img_uploads = [] # 图片上传(原生视觉,2026-09-10):不进文本上下文,走多模态注入 _fval = (params_kw or {}).get('file') _fpaths = _fval if isinstance(_fval, list) else ([_fval] if _fval else []) for _fp in _fpaths: @@ -70,6 +71,13 @@ if action == 'send_message': _abs = FileStorage().realPath(_fp) _name = os.path.basename(_abs) _uploads.append((_abs, _name)) + from pipeline_core.upload_tools import is_image + if is_image(_name): + # 图片走原生视觉(gateway.build_image_parts 构造多模态 parts), + # 不进文本上下文——避免「二进制无法读取」与「图片已注入」矛盾提示。 + # 仍随 copy_uploads_to_project 落盘项目根(agent 可再用 i2t 处理) + _img_uploads.append((_abs, _name)) + continue _txt = _extract_text(_abs, _name) if _txt: file_ctx += f"【文件 {_name} 内容】\n{_txt}\n\n" @@ -106,8 +114,16 @@ if action == 'send_message': if file_ctx or _saved_files: _loc = '' if _saved_files: - _loc = "文件已保存到项目根目录(" + _pdir + "),可用 read_file 直接读取:\n" - _loc += "\n".join(" - " + n for n, _ in _saved_files) + "\n\n" + from pipeline_core.upload_tools import is_image as _isimg + _txt_saved = [(n, pth) for n, pth in _saved_files if not _isimg(n)] + _img_saved = [(n, pth) for n, pth in _saved_files if _isimg(n)] + if _txt_saved: + _loc = "文件已保存到项目根目录(" + _pdir + "),可用 read_file 直接读取:\n" + _loc += "\n".join(" - " + n for n, _ in _txt_saved) + "\n\n" + if _img_saved: + # 图片 read_file 读不了——多模态已注入(或超限被拒),路径仅供 i2t 等后续处理 + _loc += "图片已保存到项目根目录(read_file 不支持读图;图片内容已按多模态注入,如需再次处理可用 invoke_model i2t):\n" + _loc += "\n".join(" - " + n for n, _ in _img_saved) + "\n\n" prompt = "用户本次上传了以下文件:\n" + _loc + file_ctx + "\n用户指令:" + prompt # ── 走 gateway 统一入口(Web AgentIO 通道)── @@ -125,7 +141,7 @@ if action == 'send_message': # 运行 gateway(输出 content 流式格式,供前端 AgentIO→AgentOut 渲染)。 # pipeline_id 声明本产线:激活会话项目跨产线隔离——残留的投标/商机项目 # 不会劫持开发产线驾驶舱(否则全局兜底指向跨产线项目时整会话变投标大脑)。 - async for chunk in gateway.run_message("web", uid, prompt, model_id=model_id, session_id=session_id, pipeline_id='sdlc_general'): + async for chunk in gateway.run_message("web", uid, prompt, model_id=model_id, session_id=session_id, pipeline_id='sdlc_general', image_paths=_img_uploads or None): data = json.loads(chunk) t = data.get('type', '')