完整 AgentSkill:词库外部化 + 全部脚本/Skill 脱敏上传

- 高危词库从 process.py 抽到 config.toml [security] section
- process.py 改为 _get_high_risk_words() 动态加载(配置优先)
- 新增 15 个 QQ 操作脚本(已脱敏:QQ号/IP/Token → 占位符)
- 新增 8 个 SKILL.md(qq-messenger/management/resolver/napcat-extras 等)
- 新增 SKILL.md 入口(完整部署方案文档)
- 保留 SDK 框架(plugin_modules.py, file_store_api.py, package.py 等)
This commit is contained in:
Claw
2026-05-04 16:23:59 +08:00
parent d7d33c39a4
commit e1fbd31c64
35 changed files with 5058 additions and 276 deletions

103
scripts/qq_get_file.py Normal file
View File

@ -0,0 +1,103 @@
#!/usr/bin/env python3
"""
从 QQ 接收文件/图片 - 通过 NapCat (OneBot) HTTP API
自动下载到 qqagent 工作区的 files/ 目录,供 agent 直接使用。
用法:
python3 qq_get_file.py --file <file_id>
→ 下载到 files/ 目录
→ 输出保存路径、文件名、大小、类型
python3 qq_get_file.py --file <file_id> --info --json
→ 只查文件信息(不下)
"""
import json
import sys
import os
import argparse
import requests
CQHTTP_URL = "http://YOUR_NAP CAT_HOST:25570"
FILES_DIR = "YOUR_WORKSPACE_PATH/files"
def get_file(file_id: str) -> dict:
resp = requests.post(
f"{CQHTTP_URL}/get_file",
json={"file_id": file_id},
timeout=15
)
resp.raise_for_status()
data = resp.json()
if data.get("status") != "ok":
raise Exception(f"API error: {data}")
return data["data"]
def save_file(file_info: dict) -> tuple[str, str]:
"""下载文件到 FILES_DIR,返回 (本地路径, 文件名)"""
os.makedirs(FILES_DIR, exist_ok=True)
filename = file_info.get("file_name", "unknown")
local_path = os.path.join(FILES_DIR, filename)
if file_info.get("base64"):
import base64
with open(local_path, "wb") as f:
f.write(base64.b64decode(file_info["base64"]))
else:
url = file_info.get("url", "")
if not url:
raise Exception("No base64 or url available")
resp = requests.get(url, timeout=30)
resp.raise_for_status()
with open(local_path, "wb") as f:
f.write(resp.content)
return local_path, filename
def detect_type(filename: str) -> str:
ext = filename.lower().rsplit(".", 1)[-1] if "." in filename else ""
image_exts = {"jpg", "jpeg", "png", "gif", "bmp", "webp"}
return "图片" if ext in image_exts else "文件"
def main():
parser = argparse.ArgumentParser(description="从 QQ 接收文件")
parser.add_argument("--file", required=True, help="文件 ID(file_id)")
parser.add_argument("--output", help="保存目录(默认 files/)")
parser.add_argument("--info", action="store_true", help="只查文件信息,不下")
parser.add_argument("--json", action="store_true", help="JSON 格式输出")
args = parser.parse_args()
try:
file_info = get_file(args.file)
if args.info or args.json:
info = {
"file_id": args.file,
"name": file_info.get("file_name"),
"size": file_info.get("file_size"),
"has_base64": bool(file_info.get("base64")),
}
print(json.dumps(info, ensure_ascii=False, indent=2))
return
save_dir = args.output or FILES_DIR
local_path, filename = save_file(file_info)
ftype = detect_type(filename)
print(f"✅ 已保存到 {local_path}")
print(f" 文件名: {filename}")
print(f" 大小: {file_info.get('file_size')} bytes")
print(f" 类型: {ftype}")
except Exception as e:
print(f"❌ 错误: {e}")
sys.exit(1)
if __name__ == "__main__":
main()