feat: 上传文件后端提取文本内容(docx/txt)作为中性上下文注入agent,结合prompt由agent决定动作

This commit is contained in:
ymq 2026-08-15 18:55:13 +08:00
parent 395ddd1deb
commit 5c8f8f695a

View File

@ -1,9 +1,28 @@
# cockpit_chat.dspy - SDLC Agent Loop v3.1 (streaming NDJSON) # cockpit_chat.dspy - SDLC Agent Loop v3.1 (streaming NDJSON)
import aiohttp import aiohttp
import os import os
import re
import shutil import shutil
import zipfile
from ahserver.filestorage import FileStorage from ahserver.filestorage import FileStorage
def _extract_text(path, name):
"""提取文件文本内容(docx/txt/md等),返回文本或空字符串。二进制/无法解析返回空。"""
ext = os.path.splitext(name)[1].lower()
try:
if ext in ('.txt', '.md', '.json', '.csv', '.py', '.log', '.yaml', '.yml', '.xml', '.html', '.ini'):
with open(path, 'r', encoding='utf-8', errors='ignore') as f:
return f.read()[:15000]
if ext == '.docx':
with zipfile.ZipFile(path) as z:
xml = z.read('word/document.xml').decode('utf-8', errors='ignore')
texts = re.findall(r'<w:t[^>]*>(.*?)</w:t>', xml)
return '\n'.join(texts)[:15000]
except Exception:
pass
return ''
action = (params_kw or {}).get('action', 'send_message') action = (params_kw or {}).get('action', 'send_message')
# AgentIO sends JSON body without action field — detect from message_text presence # AgentIO sends JSON body without action field — detect from message_text presence
if action != 'send_message': if action != 'send_message':
@ -567,8 +586,14 @@ if action == 'send_message':
except Exception as _e: except Exception as _e:
debug(f"UPLOAD FAIL {_fp}: {_e}") debug(f"UPLOAD FAIL {_fp}: {_e}")
if uploaded_files: if uploaded_files:
_fl = "\n".join(f"- {n}(工作空间路径: {d})" for n, d in uploaded_files) _parts = []
msgs.append({"role": "system", "content": f"用户本次上传了文件,已保存到工作空间 uploads/ 目录,可用 read_file 工具读取文件内容。文件清单:\n{_fl}"}) for _n, _d in uploaded_files:
_txt = _extract_text(_d, _n)
if _txt:
_parts.append(f"【文件 {_n} 内容】\n{_txt}")
else:
_parts.append(f"【文件 {_n}】无法直接读取文本(可能是二进制),相对路径 uploads/{_n},可用 run_command 处理")
msgs.append({"role": "system", "content": "用户本次上传了文件,内容如下:\n\n" + "\n\n".join(_parts)})
msgs.append({"role":"user","content":message_text}) msgs.append({"role":"user","content":message_text})
if uid: if uid:
await sor.C('pipeline_conversations',{'id':getID(),'role':'user','content':message_text,'msg_type':'text','org_id':org_id,'created_by':uid,'iteration_id':ctx['pid'] or ''}) await sor.C('pipeline_conversations',{'id':getID(),'role':'user','content':message_text,'msg_type':'text','org_id':org_id,'created_by':uid,'iteration_id':ctx['pid'] or ''})