diff --git a/pipeline_service/rag_client.py b/pipeline_service/rag_client.py index b50262c..f79886f 100644 --- a/pipeline_service/rag_client.py +++ b/pipeline_service/rag_client.py @@ -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}$", diff --git a/pipeline_service/sdlc_ability.py b/pipeline_service/sdlc_ability.py index 102e7b9..98ed760 100644 --- a/pipeline_service/sdlc_ability.py +++ b/pipeline_service/sdlc_ability.py @@ -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, } diff --git a/pipeline_service/shared_ability.py b/pipeline_service/shared_ability.py index 4b0dbc0..b77fa13 100644 --- a/pipeline_service/shared_ability.py +++ b/pipeline_service/shared_ability.py @@ -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 = []