fix(isolation): 通用会话剔除shell类工具+上传落专属目录
- load_agent_config generic 时剔除 category=shell(run_command 无法圈禁在工作目录内,
拿到即可遍历整个工作空间枚举各产线项目——第6层泄漏的 schema 层防线)
- upload_tools.resolve_upload_dir 加 generic 参数:通用会话上传落 _general/{uid}
专属目录,与 AgentExecutor 文件根一致
- agent_chat_generic.dspy: 上传解析传 generic=True
This commit is contained in:
parent
e9b1ba37ca
commit
523ddf451d
@ -389,8 +389,10 @@ async def load_agent_config(pipeline_id: str = None, project_id: str = None, gen
|
||||
# 的 schema 里会出现 switch_project/project_info/list_my_projects 等,
|
||||
# LLM 看到就能查看/切换/操作任何产线的项目(含他人产线的)。
|
||||
# 执行层在 agent_loop_v2._dispatch_sdlc_tool 还有一道拦截兜底。
|
||||
# 同时剔除 shell 类工具(run_command):shell 无法圈禁在工作目录内,
|
||||
# 通用会话拿到就能遍历整个工作空间枚举各产线项目(第 6 层泄漏)。
|
||||
if generic:
|
||||
tools = [t for t in tools if t.category != "project"]
|
||||
tools = [t for t in tools if t.category not in ("project", "shell")]
|
||||
prompt = base.system_prompt
|
||||
if ability:
|
||||
tools = _merge_tools(ability.tools, tools)
|
||||
|
||||
@ -34,12 +34,16 @@ def extract_text(path, name):
|
||||
return '', 0, False
|
||||
|
||||
|
||||
async def resolve_upload_dir(sor, uid, session_id=''):
|
||||
async def resolve_upload_dir(sor, uid, session_id='', generic: bool = False):
|
||||
"""上传文件落盘目录:有当前项目 → 项目根目录;无项目 → workspace 会话目录。
|
||||
|
||||
两个位置都在会话 agent 的 read_file 根内(项目根 / WORKSPACE_BASE),
|
||||
保证「上传放的位置 = agent 读的位置」。
|
||||
返回 (dir, rel_prefix):rel_prefix 是相对 read_file 根的路径前缀(项目根为 '')。
|
||||
|
||||
generic=True(纯通用会话,2026-09-05 产线隔离):无项目时落用户专属
|
||||
通用工作目录 _general/{uid}——与 AgentExecutor 的文件根一致
|
||||
(_resolve_ws_path 越界保护只认该目录),rel_prefix 为 ''。
|
||||
"""
|
||||
try:
|
||||
from pipeline_service.workspace import (
|
||||
@ -54,6 +58,9 @@ async def resolve_upload_dir(sor, uid, session_id=''):
|
||||
return pdir, ''
|
||||
except Exception:
|
||||
pass
|
||||
if generic:
|
||||
from pipeline_service.workspace import generic_workspace_dir
|
||||
return generic_workspace_dir(uid), ''
|
||||
sess = (session_id or uid or 'default').replace('/', '_').replace('..', '_')
|
||||
return os.path.join(WORKSPACE_BASE, '_uploads', sess), '_uploads/' + sess + '/'
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ if action == 'send_message':
|
||||
try:
|
||||
_dbname = get_module_dbname('pipeline_core')
|
||||
async with DBPools().sqlorContext(_dbname) as sor:
|
||||
_udir, _rel = await resolve_upload_dir(sor, uid, '')
|
||||
_udir, _rel = await resolve_upload_dir(sor, uid, '', generic=True)
|
||||
_saved = save_uploads(_udir, _uploads)
|
||||
_byname = {os.path.basename(src): n for (src, _n), (n, _p) in zip(_uploads, _saved)}
|
||||
_items = []
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user