fix(rag-access): RC4加解密显式传key(对称约定)+会话agent通道挂检索工具(全产线共享)

This commit is contained in:
ymq 2026-09-04 16:12:17 +08:00
parent 21c8c16daa
commit ae3967c3b0
3 changed files with 49 additions and 4 deletions

View File

@ -21,8 +21,6 @@ import logging
import aiohttp
from appPublic.rc4 import password as _rc4_encode
from appPublic.rc4 import unpassword as _rc4_decode
from appPublic.uniqueID import getID
from sqlor.dbpools import DBPools
@ -36,6 +34,26 @@ _RAG_TIMEOUT = aiohttp.ClientTimeout(total=90, connect=10)
_key_cache = {} # user_id -> apikey进程内重启后从 params 重建)
def _get_password_key():
"""RC4 密钥与平台敏感字段同约定config.password_key空则平台默认"""
try:
from appPublic.jsonConfig import getConfig
return getConfig().password_key or 'QRIVSRHrthhwyjy176556332'
except Exception:
return 'QRIVSRHrthhwyjy176556332'
def _key_encode(plain):
from appPublic.rc4 import password
return password(plain, key=_get_password_key())
def _key_decode(enc):
from appPublic.rc4 import unpassword
# 参数顺序code=密文, key=密钥(写反解不出,历史踩过)
return unpassword(enc, _get_password_key())
def _get_db():
db = DBPools()
if not db.databases:
@ -109,7 +127,7 @@ async def _load_cached_key(sor, user_id):
if not enc:
return ""
try:
return _rc4_decode(enc) or ""
return _key_decode(enc) or ""
except Exception as e:
logger.warning("rag key decode failed for %s: %s", user_id, e)
return ""
@ -140,7 +158,7 @@ async def get_owner_apikey(owner_id):
key = res["apikey"]
# RC4 加密存 params与平台密码字段约定一致
pname = _KEY_PARAM_PREFIX + str(owner_id)
enc = _rc4_encode(key)
enc = _key_encode(key)
await sor.sqlExe(
"INSERT INTO params (id, params_name, params_value) VALUES (${i}$, ${n}$, ${v}$) "
"ON DUPLICATE KEY UPDATE params_value=${v}$",

View File

@ -234,6 +234,9 @@ SDL_TOOLS = [
ToolDefinition(name="list_envs", description="查看项目部署环境列表", parameters={"env_type": "环境类型(可选)", "status": "按状态筛选(可选)"}, category="deploy"),
ToolDefinition(name="configure_env", description="配置部署环境(configured)", parameters={"env_type": "环境类型(test/staging/production)", "host": "SSH主机", "user": "SSH用户", "deploy_path": "部署目录", "port": "SSH端口(可选)"}, category="deploy"),
ToolDefinition(name="verify_env", description="验证环境通过(configured→verified)", parameters={"env_id": "环境ID"}, category="deploy"),
# ── 知识库按项目owner权限统一走 rag 对外 API──
ToolDefinition(name="rag_search", description="检索知识库按项目owner权限自动限定可检范围。查资料/找依据/了解背景时用;不确定有哪些库先调 rag_kb_list", parameters={"query": "检索内容", "kb_id": "知识库ID(可选,缺省检索全部可见库)", "top_k": "返回条数(可选,默认10)"}, category="knowledge"),
ToolDefinition(name="rag_kb_list", description="列出项目可见的知识库(名称+ID+文档数),检索前先确认有哪些库", parameters={}, category="knowledge"),
]
@ -1818,6 +1821,25 @@ async def _h_verify_env(sor, p, ctx):
return f"OK: {msg}" if ok else f"ERROR: {msg}"
# ── 知识库按项目owner权限统一走 rag 对外 API──
async def _h_rag_search(sor, p, ctx):
pid = ctx.get("project_id", "")
if not pid:
return "请先切换到项目"
from .rag_client import tool_rag_search
return await tool_rag_search(pid, p.get("query", ""), kb_id=p.get("kb_id", ""),
top_k=p.get("top_k", 10))
async def _h_rag_kb_list(sor, p, ctx):
pid = ctx.get("project_id", "")
if not pid:
return "请先切换到项目"
from .rag_client import tool_rag_kb_list
return await tool_rag_kb_list(pid)
# ── 注册能力包 ──
SDL_HANDLERS = {
@ -1897,6 +1919,9 @@ SDL_HANDLERS = {
"list_envs": _h_list_envs,
"configure_env": _h_configure_env,
"verify_env": _h_verify_env,
# ── 知识库 ──
"rag_search": _h_rag_search,
"rag_kb_list": _h_rag_kb_list,
}

View File

@ -34,6 +34,8 @@ _GENERIC_TOOL_NAMES = [
"reopen_project", "pause_project", "resume_project", "backup_project",
# 角色模型
"list_role_models", "set_role_model",
# 知识库按项目owner权限检索所有产线会话 agent 通用)
"rag_search", "rag_kb_list",
]
SHARED_TOOLS = []