feat: 飞书机器人按租户路由 群组绑定租户 + 独立凭证 + 知识库隔离

1. 新增 resolve_tenant_by_chat_id() 根据飞书群 chat_id 查找绑定的租户
2. 新增 get_tenant_feishu_config() 获取租户级飞书凭证
3. FeishuService 支持传入自定义 app_id/app_secret(租户级别)
4. feishu_bot.py 收到消息时自动解析租户,使用租户凭证回复
5. feishu_longconn_service.py 同样按 chat_id 解析租户并传递 tenant_id
6. 租户管理 UI 新增飞书配置字段:App ID、App Secret、绑定群 Chat ID
7. 租户列表展示飞书绑定状态和群数量
8. 保存租户时同步更新飞书配置到 config JSON
This commit is contained in:
2026-04-02 09:58:04 +08:00
parent edb0616f7f
commit 7950cd8237
18 changed files with 1347 additions and 16 deletions

View File

@@ -0,0 +1,82 @@
---
Name: config-audit
Description: 检查 TSP 智能助手当前环境配置是否完整可用包括数据库、LLM、服务端口等关键配置并输出人类可读的健康检查报告。
---
你是一个「配置健康检查助手」,技能名为 **config-audit**
你的职责:在用户想确认当前环境配置是否正确、是否缺少关键变量或错误端口时,调用配套脚本,基于 `src/config/unified_config.py``.env`/环境变量,输出清晰的配置健康检查报告。
---
## 一、触发条件(什么时候使用 config-audit
当用户有类似需求时,应激活本 Skill例如
- 「帮我检查一下配置有没有问题」
- 「现在这个环境的数据库/LLM 配置正常吗」
- 「我改了 .env帮我看下有没有缺的」
- 「启动报配置错误,帮我检查 config」
---
## 二、总体流程
1. 从项目根目录执行脚本 `scripts/config_audit.py`
2. 读取并理解输出的检查结果(包括成功与警告/错误)。
3. 将关键结论用自然语言总结给用户,并提出简单修复建议。
4. 避免泄露敏感值(如完整 URL、API Key仅报告是否存在与格式是否看起来合理。
---
## 三、脚本调用规范
从项目根目录执行命令:
```bash
python .claude/skills/config-audit/scripts/config_audit.py
```
脚本行为约定:
- 尝试导入 `src.config.unified_config.get_config`
- 调用 `get_config()`
- 若成功,说明必需的配置大体齐全;
- 若抛出异常(如缺少 `DATABASE_URL`),捕获异常并报告。
- 对关键配置字段进行检查(不打印敏感具体值):
- 数据库:是否配置 `DATABASE_URL`,能否看起来是有效的 URL。
- LLM`LLM_API_KEY` 是否存在,`LLM_PROVIDER` / `LLM_MODEL` 是否有值。
- 服务:`SERVER_PORT``WEBSOCKET_PORT` 是否在合理范围(例如 165535是否冲突。
- 飞书与 AI 准确率配置:如有配置则检查字段完整性,如未配置则给出提示。
- 最终打印一份「健康检查报告」按模块database / llm / server / feishu / ai_accuracy分段展示。
---
## 四、对用户的输出规范
当成功执行 `config-audit` 时,你应该向用户返回类似结构的信息:
1. **总体结论**(一句话)
- 例如:「当前环境配置基本健康,仅存在 LLM API Key 未配置的警告。」
2. **按模块总结**
- 数据库配置:是否存在、看起来是否合理(不展示完整 URL
- LLM 配置:是否配置了 provider/model/key未配置时的影响。
- 服务端口:当前 HTTP/WebSocket 端口及是否在合理范围。
- 其他模块飞书、AI 准确率):若有明显问题则简要说明。
3. **建议**
- 对每个有问题的模块,给出 12 条修改 `.env` 或环境变量的建议。
避免:
- 直接打印完整的敏感信息(如 `DATABASE_URL``LLM_API_KEY` 值);
- 输出过多的 Python Traceback优先用自然语言解释。
---
## 五、反模式与边界
- 如导入 `src.config.unified_config` 失败,或脚本无法运行:
- 明确告诉用户「config-audit 脚本运行失败」,并简述原因。
- 不要修改 `.env` 或环境变量,仅进行只读检查和报告。
- 避免主观猜测真实密码/API Key 内容,只报告「存在 / 缺失 / 格式异常」。

View File

@@ -0,0 +1,127 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
配置健康检查脚本
基于 src.config.unified_config 对当前环境配置进行简单体检,
输出人类可读的检查结果,供 config-audit Skill 调用。
"""
import os
import sys
from pathlib import Path
def add_project_root_to_path():
# 假定脚本位于 .claude/skills/config-audit/scripts/ 下
script_path = Path(__file__).resolve()
project_root = script_path.parents[4] # 回到项目根目录
if str(project_root) not in sys.path:
sys.path.insert(0, str(project_root))
def main():
add_project_root_to_path()
print("=== TSP Assistant 配置健康检查 ===\n")
try:
from src.config.unified_config import get_config
except Exception as e:
print("[FATAL] 无法导入 src.config.unified_config.get_config")
print(f" 错误:{e}")
print("\n请检查 Python 路径与项目结构。")
return
try:
cfg = get_config()
except Exception as e:
print("[FATAL] get_config() 调用失败,可能缺少关键环境变量:")
print(f" 错误:{e}")
print("\n请检查 .env / 环境变量是否包含 DATABASE_URL 等必需项。")
return
problems = []
# Database
print("---- 数据库配置 (database) ----")
db_url = os.getenv("DATABASE_URL", "")
if not db_url:
print(" [ERROR] 未设置 DATABASE_URL无法连接数据库。")
problems.append("缺少 DATABASE_URL")
else:
# 不打印完整 URL只提示前缀
prefix = db_url.split("://")[0] if "://" in db_url else "未知协议"
print(f" [OK] 已配置 DATABASE_URL协议前缀{prefix}://...")
# LLM
print("\n---- LLM 配置 (llm) ----")
llm_api_key = os.getenv("LLM_API_KEY", "")
if not llm_api_key:
print(" [WARN] 未设置 LLM_API_KEYAI 功能可能不可用或调用失败。")
problems.append("缺少 LLM_API_KEY")
else:
print(" [OK] 已配置 LLM_API_KEY具体值已隐藏")
provider = os.getenv("LLM_PROVIDER", cfg.llm.provider if hasattr(cfg, "llm") else "")
model = os.getenv("LLM_MODEL", cfg.llm.model if hasattr(cfg, "llm") else "")
print(f" Provider: {provider or '未配置'}")
print(f" Model : {model or '未配置'}")
# Server
print("\n---- 服务配置 (server) ----")
try:
port = int(os.getenv("SERVER_PORT", cfg.server.port))
ws_port = int(os.getenv("WEBSOCKET_PORT", cfg.server.websocket_port))
except Exception:
port = cfg.server.port
ws_port = cfg.server.websocket_port
def _check_port(p: int, name: str):
if not (1 <= p <= 65535):
problems.append(f"{name} 端口不在 1-65535 范围内")
return f"[ERROR] {name} 端口 {p} 非法(应在 1-65535 范围内)。"
return f"[OK] {name} 端口:{p}"
print(" " + _check_port(port, "HTTP"))
print(" " + _check_port(ws_port, "WebSocket"))
# Feishu
print("\n---- 飞书配置 (feishu) ----")
feishu_app_id = os.getenv("FEISHU_APP_ID", "")
feishu_app_secret = os.getenv("FEISHU_APP_SECRET", "")
if feishu_app_id and feishu_app_secret:
print(" [OK] 已配置 FEISHU_APP_ID / FEISHU_APP_SECRET。")
elif feishu_app_id and not feishu_app_secret:
print(" [WARN] 已配置 FEISHU_APP_ID但缺少 FEISHU_APP_SECRET。")
problems.append("飞书配置不完整:缺少 FEISHU_APP_SECRET")
else:
print(" [INFO] 未配置飞书相关信息(如不使用飞书集成可忽略)。")
# AI Accuracy
print("\n---- AI 准确率配置 (ai_accuracy) ----")
# 使用 cfg.ai_accuracy 中的默认或 env 覆盖值
try:
aa = cfg.ai_accuracy
print(
f" auto_approve_threshold: {aa.auto_approve_threshold}, "
f"manual_review_threshold: {aa.manual_review_threshold}"
)
except Exception:
print(" [INFO] 无法读取 AI 准确率配置,使用默认值。")
# 总结
print("\n=== 检查总结 ===")
if not problems:
print(" [OK] 当前配置整体健康,未发现明显问题。")
else:
print(" 以下问题需要关注:")
for p in problems:
print(f" - {p}")
print("\n 建议:根据提示检查 .env 或部署环境变量,并重新运行 config-audit 以确认问题是否已解决。")
if __name__ == "__main__":
main()