fix: 修复前台4项问题(MCP列举/微信技能上限/Word资产栏/技能MCP反馈) + 同步容器live状态
- #549 平台MCP列举: 注入全量已启用MCP清单, AI不再凭空编造 - #550 微信Bot技能自动发现上限 15->300 - #551 知识库Word文档同步资产后Word栏可见 + 双向删除同步(assets/knowledge级联软删) - #552 对话反馈实际使用的技能/MCP(used_mcp字段), 含历史消息序列化 - 同步容器内其他未提交live改动(im_bot_platform/TokenDashboard/WechatBot/ChatPage)
This commit is contained in:
1 parent
7fb7c07f57
commit
1578d68f95
10 files changed
+1927
-1719
No files matched your search
@@ -4094,7 +4094,28 @@ def _resolve_active_mcp_servers(db: Session, mcp_ids: list) -> list:
|
||||
|
||||
|
||||
|
||||
def _discover_installed_skills(db: Session, user_id: str, limit: int = 15) -> list:
|
||||
def _list_enabled_mcp_servers(db: Session) -> list:
|
||||
"""返回平台所有已启用(is_enabled=True)的 MCP 服务清单,供 AI 准确回答"平台有哪些 MCP"。"""
|
||||
servers = db.query(MCPServer).filter(MCPServer.is_enabled == True).all()
|
||||
out = []
|
||||
for s in servers:
|
||||
try:
|
||||
headers = json.loads(s.headers) if isinstance(s.headers, str) else (s.headers or {})
|
||||
except Exception:
|
||||
headers = {}
|
||||
out.append({
|
||||
"id": s.id,
|
||||
"name": s.name,
|
||||
"description": s.description or "",
|
||||
"transport": s.transport_type or "streamable_http",
|
||||
"endpoint": s.url or "",
|
||||
"url": s.url or "",
|
||||
"headers": headers,
|
||||
})
|
||||
return out
|
||||
|
||||
|
||||
def _discover_installed_skills(db: Session, user_id: str, limit: int = 300) -> list:
|
||||
|
||||
|
||||
|
||||
@@ -5311,6 +5332,7 @@ def _build_system_prompt(
|
||||
mcp_functions: list = None,
|
||||
|
||||
auto_discovered: bool = False,
|
||||
all_mcp: list = None,
|
||||
|
||||
) -> tuple:
|
||||
|
||||
@@ -5745,6 +5767,15 @@ def _build_system_prompt(
|
||||
|
||||
|
||||
|
||||
# 平台全量 MCP 清单(Issue:让用户询问"平台有哪些 MCP"时 AI 能准确列举,而非凭空编造)
|
||||
if all_mcp:
|
||||
_mcp_inventory = "\n".join([f"- {m.get('name','')}: {m.get('description','') or '(未填写描述)'}" for m in all_mcp])
|
||||
system_parts.append(
|
||||
f"【平台已安装的 MCP 应用清单(共 {len(all_mcp)} 个,均为平台真实接入并启用)】\n{_mcp_inventory}\n"
|
||||
"当用户询问“平台有哪些 MCP / 接入了哪些 MCP / 有哪些工具服务”时,请严格依据以上清单准确列举名称与功能,"
|
||||
"不要编造或遗漏,也不要把未列出的服务说成已接入。"
|
||||
)
|
||||
|
||||
# MCP 应用注入(Issue 3:让用户询问 MCP 能力时,AI 能“看到”该 MCP 的资料与地址)
|
||||
|
||||
|
||||
@@ -7074,6 +7105,7 @@ def get_messages(
|
||||
|
||||
|
||||
"used_skills": msg.used_skills or [],
|
||||
"used_mcp": msg.used_mcp or [],
|
||||
|
||||
|
||||
|
||||
@@ -8090,6 +8122,7 @@ async def send_message(
|
||||
mcp_functions=mcp_function_definitions,
|
||||
|
||||
auto_discovered=used_auto_skills,
|
||||
all_mcp=_list_enabled_mcp_servers(db),
|
||||
|
||||
)
|
||||
|
||||
@@ -8103,6 +8136,10 @@ async def send_message(
|
||||
|
||||
|
||||
|
||||
# 实际调用追踪(Issue:反馈真实使用的技能/MCP,而非注入的全部)
|
||||
called_skill_names = []
|
||||
called_mcp_names = []
|
||||
|
||||
messages = [{"role": "system", "content": system_prompt}]
|
||||
|
||||
|
||||
@@ -8433,6 +8470,8 @@ async def send_message(
|
||||
|
||||
)
|
||||
|
||||
called_mcp_names.append(_srv.get("name", ""))
|
||||
|
||||
else:
|
||||
|
||||
tool_result = _execute_skill_tool(
|
||||
@@ -8441,6 +8480,12 @@ async def send_message(
|
||||
|
||||
)
|
||||
|
||||
_sk = next((s for s in skills if s.get("func_name") == func_name), None)
|
||||
|
||||
if _sk:
|
||||
|
||||
called_skill_names.append(_sk.get("name", ""))
|
||||
|
||||
|
||||
|
||||
messages.append({
|
||||
@@ -8671,7 +8716,7 @@ async def send_message(
|
||||
|
||||
|
||||
|
||||
# 更新used_skills
|
||||
# 更新used_skills / used_mcp:优先反馈用户显式指定的;否则反馈本轮实际调用的
|
||||
|
||||
|
||||
|
||||
@@ -8679,15 +8724,91 @@ async def send_message(
|
||||
|
||||
|
||||
|
||||
if skills:
|
||||
used_mcp = []
|
||||
|
||||
|
||||
|
||||
used_skills = [s["name"] for s in skills]
|
||||
if effective_skill_ids:
|
||||
|
||||
|
||||
|
||||
ai_msg.used_skills = used_skills
|
||||
# 用户显式选择了技能 -> 反馈配对的技能名
|
||||
|
||||
|
||||
|
||||
try:
|
||||
|
||||
|
||||
|
||||
_sel = _resolve_market_skills(db, effective_skill_ids, user_id)
|
||||
|
||||
|
||||
|
||||
used_skills = [s["name"] for s in _sel]
|
||||
|
||||
|
||||
|
||||
except Exception:
|
||||
|
||||
|
||||
|
||||
used_skills = []
|
||||
|
||||
|
||||
|
||||
elif called_skill_names:
|
||||
|
||||
|
||||
|
||||
# 未显式选技能 -> 反馈 AI 本轮实际调用的技能(可能为空)
|
||||
|
||||
|
||||
|
||||
used_skills = list(dict.fromkeys(called_skill_names))
|
||||
|
||||
|
||||
|
||||
if effective_mcp_ids:
|
||||
|
||||
|
||||
|
||||
# 用户显式选择了 MCP -> 反馈配对的 MCP 名
|
||||
|
||||
|
||||
|
||||
try:
|
||||
|
||||
|
||||
|
||||
_sel_mcp = _resolve_active_mcp_servers(db, effective_mcp_ids)
|
||||
|
||||
|
||||
|
||||
used_mcp = [m["name"] for m in _sel_mcp]
|
||||
|
||||
|
||||
|
||||
except Exception:
|
||||
|
||||
|
||||
|
||||
used_mcp = []
|
||||
|
||||
|
||||
|
||||
elif called_mcp_names:
|
||||
|
||||
|
||||
|
||||
used_mcp = list(dict.fromkeys(called_mcp_names))
|
||||
|
||||
|
||||
|
||||
ai_msg.used_skills = used_skills
|
||||
|
||||
|
||||
|
||||
ai_msg.used_mcp = used_mcp
|
||||
|
||||
|
||||
|
||||
@@ -8980,6 +9101,7 @@ async def send_message(
|
||||
|
||||
|
||||
"used_skills": used_skills,
|
||||
"used_mcp": used_mcp,
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user