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:
82
.kiro/skills/config-audit/SKILL.md
Normal file
82
.kiro/skills/config-audit/SKILL.md
Normal 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` 是否在合理范围(例如 1–65535),是否冲突。
|
||||
- 飞书与 AI 准确率配置:如有配置则检查字段完整性,如未配置则给出提示。
|
||||
- 最终打印一份「健康检查报告」,按模块(database / llm / server / feishu / ai_accuracy)分段展示。
|
||||
|
||||
---
|
||||
|
||||
## 四、对用户的输出规范
|
||||
|
||||
当成功执行 `config-audit` 时,你应该向用户返回类似结构的信息:
|
||||
|
||||
1. **总体结论**(一句话)
|
||||
- 例如:「当前环境配置基本健康,仅存在 LLM API Key 未配置的警告。」
|
||||
2. **按模块总结**
|
||||
- 数据库配置:是否存在、看起来是否合理(不展示完整 URL)。
|
||||
- LLM 配置:是否配置了 provider/model/key,未配置时的影响。
|
||||
- 服务端口:当前 HTTP/WebSocket 端口及是否在合理范围。
|
||||
- 其他模块(飞书、AI 准确率):若有明显问题则简要说明。
|
||||
3. **建议**
|
||||
- 对每个有问题的模块,给出 1~2 条修改 `.env` 或环境变量的建议。
|
||||
|
||||
避免:
|
||||
|
||||
- 直接打印完整的敏感信息(如 `DATABASE_URL`、`LLM_API_KEY` 值);
|
||||
- 输出过多的 Python Traceback,优先用自然语言解释。
|
||||
|
||||
---
|
||||
|
||||
## 五、反模式与边界
|
||||
|
||||
- 如导入 `src.config.unified_config` 失败,或脚本无法运行:
|
||||
- 明确告诉用户「config-audit 脚本运行失败」,并简述原因。
|
||||
- 不要修改 `.env` 或环境变量,仅进行只读检查和报告。
|
||||
- 避免主观猜测真实密码/API Key 内容,只报告「存在 / 缺失 / 格式异常」。
|
||||
|
||||
127
.kiro/skills/config-audit/scripts/config_audit.py
Normal file
127
.kiro/skills/config-audit/scripts/config_audit.py
Normal 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_KEY,AI 功能可能不可用或调用失败。")
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user