fix(read_file): 截断显式告知+offset分段读——根治静默截断同类病
This commit is contained in:
parent
06130bcbef
commit
2d913c1d12
@ -985,10 +985,16 @@ class AgentExecutor:
|
||||
xml = z.read('word/document.xml').decode('utf-8', errors='ignore')
|
||||
texts = _re.findall(r'<w:t[^>]*>(.*?)</w:t>', xml)
|
||||
return ('\n'.join(texts)[:30000]) or '(docx 无文本内容)'
|
||||
# 纯文本类:直接读
|
||||
# 纯文本类:直接读(offset 分段 + 截断显式告知——禁止静默截断)
|
||||
if ext in ('.txt', '.md', '.json', '.csv', '.py', '.log', '.yaml', '.yml', '.xml', '.html', '.ini', ''):
|
||||
offset = int(p.get("offset") or 0)
|
||||
with open(full, encoding="utf-8", errors="ignore") as f:
|
||||
return f.read()[:30000]
|
||||
full_txt = f.read()
|
||||
chunk = full_txt[offset:offset + 30000]
|
||||
if offset + 30000 < len(full_txt):
|
||||
chunk += (f"\n\n[⚠️ 截断提示:以上为第 {offset}~{offset + len(chunk.rstrip())} 字符,"
|
||||
f"全文共 {len(full_txt)} 字符。读后文请再次 read_file 并传 offset={offset + 30000}。]")
|
||||
return chunk
|
||||
# 其他二进制
|
||||
return f"该文件是二进制格式({ext or '无扩展名'}),无法直接读取文本。可改用 run_command 处理,或让用户上传文本版本。"
|
||||
except Exception as e:
|
||||
@ -1285,13 +1291,18 @@ class AgentExecutor:
|
||||
async with db.sqlorContext("pipeline") as sor:
|
||||
# 会话级隔离(web 多 tab 独立会话)
|
||||
if self.session_id:
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT role, content FROM pipeline_conversations "
|
||||
"WHERE session_id=${sid}$ AND created_by=${uid}$ "
|
||||
"ORDER BY created_at ASC LIMIT ${lim}$",
|
||||
{"sid": self.session_id, "uid": self.user_id or "",
|
||||
"lim": self.config.history_limit},
|
||||
)
|
||||
# 产线隔离(2026-08-31 修复跨产线串扰):各产线页面默认 tab 共用
|
||||
# session_id='default',历史若不按产线过滤,投标页会加载开发页的
|
||||
# 对话(如"元景项目/新建demo项目"),LLM 跟着最后上下文答错产线。
|
||||
sql = ("SELECT role, content FROM pipeline_conversations "
|
||||
"WHERE session_id=${sid}$ AND created_by=${uid}$ ")
|
||||
params = {"sid": self.session_id, "uid": self.user_id or "",
|
||||
"lim": self.config.history_limit}
|
||||
if self.pipeline_id and not self.generic:
|
||||
sql += "AND pipeline_id=${pl}$ "
|
||||
params["pl"] = self.pipeline_id
|
||||
sql += "ORDER BY created_at ASC LIMIT ${lim}$"
|
||||
recs = await sor.sqlExe(sql, params)
|
||||
else:
|
||||
# 项目隔离
|
||||
pid = self.project_id
|
||||
@ -1349,6 +1360,7 @@ class AgentExecutor:
|
||||
"created_by": self.user_id or "",
|
||||
"iteration_id": self.project_id or "",
|
||||
"session_id": self.session_id or "",
|
||||
"pipeline_id": self.pipeline_id or "",
|
||||
})
|
||||
# 助手回复(不含 tool_call JSON!)
|
||||
reply_clean = reply
|
||||
@ -1361,6 +1373,7 @@ class AgentExecutor:
|
||||
"created_by": self.user_id or "",
|
||||
"iteration_id": self.project_id or "",
|
||||
"session_id": self.session_id or "",
|
||||
"pipeline_id": self.pipeline_id or "",
|
||||
})
|
||||
except Exception as e:
|
||||
logger.warning(f"Session save failed: {e}")
|
||||
|
||||
@ -100,27 +100,42 @@ async def get_max_task_retry(sor):
|
||||
return 3
|
||||
|
||||
|
||||
async def get_session_project_id(sor, uid, session_id=''):
|
||||
async def get_session_project_id(sor, uid, session_id='', pipeline_id=''):
|
||||
"""按会话解析当前项目 id。
|
||||
|
||||
session_id 非空时优先读 pipeline_session_settings(web 多 tab 各自项目上下文),
|
||||
无记录或表不存在时回退全局 pipeline_agent_settings.current_project_id。
|
||||
|
||||
pipeline_id 产线隔离(2026-08-31 修复跨产线串扰):各产线页面默认 tab 共用
|
||||
session_id='default',而 session/全局记录不区分产线——投标页会读到开发页切换
|
||||
的项目。传入 pipeline_id 时,解析出的项目必须属于该产线(sd_projects.pipeline_id
|
||||
匹配)才生效,否则视为无记录继续回退;不匹配的记录**不删除**(它属于另一产线
|
||||
的合法上下文)。
|
||||
|
||||
存在性校验(悬空引用防护):记录指向的项目若已从 sd_projects 删除,
|
||||
视为无效——顺手清掉死记录(自愈,避免每次请求重复命中),继续回退全局;
|
||||
全局也无效则返回 ''。若不清理,删除项目后该会话的所有项目相关入口
|
||||
(工作空间/任务/菜单)都会被死引用遮蔽,报「请先在会话中切换项目」。
|
||||
"""
|
||||
async def _valid(pid):
|
||||
"""pid 对应项目存在则原样返回;不存在返回 '';查询异常保守放行(不因校验误伤功能)。"""
|
||||
if not pid:
|
||||
return ''
|
||||
async def _project_pipeline(pid):
|
||||
"""项目所属 pipeline_id;不存在返回 None;查询异常返回 ''(保守放行)。"""
|
||||
try:
|
||||
recs = await sor.sqlExe(
|
||||
"SELECT 1 FROM sd_projects WHERE id=${p}$ LIMIT 1", {"p": pid})
|
||||
return pid if recs else ''
|
||||
"SELECT pipeline_id FROM sd_projects WHERE id=${p}$ LIMIT 1", {"p": pid})
|
||||
if not recs:
|
||||
return None
|
||||
return getattr(recs[0], 'pipeline_id', '') or ''
|
||||
except Exception:
|
||||
return pid
|
||||
return ''
|
||||
|
||||
async def _valid(pid):
|
||||
"""pid 存在(且产线匹配,若指定)则返回 pid;否则 ''。"""
|
||||
pl = await _project_pipeline(pid)
|
||||
if pl is None:
|
||||
return ''
|
||||
if pipeline_id and pl and pl != pipeline_id:
|
||||
return ''
|
||||
return pid
|
||||
|
||||
if session_id:
|
||||
try:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user