#!/usr/bin/env python3 """ Oracle Jump Query - AI Skill 通过中转服务查询远程 Oracle 存储过程元数据 使用方式: python oracle_skill.py analyze BOS M_RETAIL_SUBMIT python oracle_skill.py list BOS python oracle_skill.py source BOS M_RETAIL_SUBMIT python oracle_skill.py deps BOS M_RETAIL_SUBMIT python oracle_skill.py tables BOS M_RETAIL_SUBMIT python oracle_skill.py servers """ import json import os import sys import requests # ============================================================ # 配置(修改为你的中转服务地址和认证信息) # ============================================================ TRANSIT_URL = "http://bos.henlo.net:6357" AUTH_TOKEN = "" DEFAULT_SERVER_ID = "server-001" def get_script_dir(): """获取脚本自身所在目录""" return os.path.dirname(os.path.abspath(__file__)) def get_config(): """从 config.json 加载配置(优先脚本目录,其次当前目录)""" # 优先从脚本同目录加载 cfg_path = os.path.join(get_script_dir(), "config.json") try: with open(cfg_path, "r", encoding="utf-8") as f: cfg = json.load(f) return cfg except FileNotFoundError: pass # 其次从当前目录加载 try: with open("config.json", "r", encoding="utf-8") as f: cfg = json.load(f) return cfg except FileNotFoundError: return None def make_headers(): """构建 HTTP 请求头""" headers = {"Content-Type": "application/json"} token = AUTH_TOKEN cfg = get_config() if cfg: token = cfg.get("auth_token", token) if token: headers["Authorization"] = f"Bearer {token}" return headers def get_transit_url(): """获取中转服务 URL""" cfg = get_config() if cfg and "transit_url" in cfg: return cfg["transit_url"] return TRANSIT_URL def get_server_id(): """获取默认服务器 ID""" cfg = get_config() if cfg and "server_id" in cfg: return cfg["server_id"] return DEFAULT_SERVER_ID def query(server_id, action, schema="", name="", timeout=60): """发送查询请求到中转服务""" url = f"{get_transit_url()}/api/query" payload = { "server_id": server_id, "action": action, "schema": schema, "name": name, "timeout": timeout, } try: resp = requests.post(url, json=payload, headers=make_headers(), timeout=timeout + 5) resp.raise_for_status() return resp.json() except requests.exceptions.ConnectionError: return {"success": False, "error": "无法连接中转服务,请检查地址和端口"} except requests.exceptions.Timeout: return {"success": False, "error": "请求超时,Agent 可能未响应"} except requests.exceptions.HTTPError as e: return {"success": False, "error": f"HTTP 错误: {e}"} def list_servers(): """列出所有在线的 Agent 服务器""" url = f"{get_transit_url()}/api/servers" try: resp = requests.get(url, headers=make_headers(), timeout=10) resp.raise_for_status() return resp.json() except Exception as e: return {"error": str(e)} def health_check(): """检查中转服务健康状态""" url = f"{get_transit_url()}/api/health" try: resp = requests.get(url, timeout=5) resp.raise_for_status() return resp.json() except Exception as e: return {"error": str(e)} def print_result(result): """格式化输出结果""" if result.get("success"): data = result.get("data", "") print(data) else: error = result.get("error", "未知错误") print(f"❌ 错误: {error}") def interactive_mode(): """交互式模式""" print("=" * 50) print(" Oracle Jump Query - AI Skill") print(" 输入 help 查看命令,exit 退出") print("=" * 50) # Check transit server health = health_check() if "error" in health: print(f"⚠️ 中转服务不可用: {health['error']}") print("请检查 config.json 中的 transit_url 配置") else: print(f"✅ 中转服务正常 (在线 Agent: {health.get('agents', 0)})") print() while True: try: line = input("> ").strip() except (EOFError, KeyboardInterrupt): print("\n再见!") break if not line: continue parts = line.split() cmd = parts[0].lower() if cmd == "exit" or cmd == "quit": print("再见!") break elif cmd == "help": print(""" 可用命令: analyze - 分析存储过程(源码+依赖+表+触发器) list - 列出 schema 下的所有存储过程 source - 获取存储过程源码 deps - 获取存储过程依赖 tables - 获取相关表结构 servers - 列出在线 Agent health - 检查中转服务状态 server - 切换目标服务器 exit - 退出 """) elif cmd == "servers": result = list_servers() if "error" in result: print(f"❌ {result['error']}") else: servers = result.get("servers", []) if not servers: print("没有在线的 Agent") else: for s in servers: print(f" 🟢 {s['server_id']}") elif cmd == "health": result = health_check() if "error" in result: print(f"❌ {result['error']}") else: print(f"✅ 中转服务正常 (在线 Agent: {result.get('agents', 0)})") elif cmd == "server": if len(parts) < 2: print(f"当前服务器: {get_server_id()}") else: global DEFAULT_SERVER_ID DEFAULT_SERVER_ID = parts[1] print(f"切换到服务器: {parts[1]}") elif cmd == "analyze": if len(parts) < 3: print("用法: analyze ") continue result = query(get_server_id(), "analyze_procedure", parts[1], parts[2], timeout=120) print_result(result) elif cmd == "list": if len(parts) < 2: print("用法: list ") continue result = query(get_server_id(), "list_procedures", parts[1], timeout=30) print_result(result) elif cmd == "source": if len(parts) < 3: print("用法: source ") continue result = query(get_server_id(), "get_source", parts[1], parts[2], timeout=60) print_result(result) elif cmd == "deps": if len(parts) < 3: print("用法: deps ") continue result = query(get_server_id(), "get_dependencies", parts[1], parts[2], timeout=60) print_result(result) elif cmd == "tables": if len(parts) < 3: print("用法: tables ") continue result = query(get_server_id(), "get_tables", parts[1], parts[2], timeout=60) print_result(result) else: print(f"未知命令: {cmd},输入 help 查看帮助") def main(): if len(sys.argv) == 1: interactive_mode() return cmd = sys.argv[1].lower() if cmd == "servers": result = list_servers() print(json.dumps(result, indent=2, ensure_ascii=False)) elif cmd == "health": result = health_check() print(json.dumps(result, indent=2, ensure_ascii=False)) elif cmd == "analyze" and len(sys.argv) >= 4: result = query(get_server_id(), "analyze_procedure", sys.argv[2], sys.argv[3], timeout=120) print_result(result) elif cmd == "list" and len(sys.argv) >= 3: result = query(get_server_id(), "list_procedures", sys.argv[2], timeout=30) print_result(result) elif cmd == "source" and len(sys.argv) >= 4: result = query(get_server_id(), "get_source", sys.argv[2], sys.argv[3], timeout=60) print_result(result) elif cmd == "deps" and len(sys.argv) >= 4: result = query(get_server_id(), "get_dependencies", sys.argv[2], sys.argv[3], timeout=60) print_result(result) elif cmd == "tables" and len(sys.argv) >= 4: result = query(get_server_id(), "get_tables", sys.argv[2], sys.argv[3], timeout=60) print_result(result) else: print(__doc__) if __name__ == "__main__": main()