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