feat: 增强 Agent 系统和完善项目结构

主要改进:
- Agent 增强: 订单查询、售后支持、客服路由等功能优化
- 新增语言检测和 Token 管理模块
- 改进 Chatwoot webhook 处理和用户标识
- MCP 服务器增强: 订单 MCP 和 Strapi MCP 功能扩展
- 新增商城客户端、知识库、缓存和同步模块
- 添加多语言提示词系统 (YAML)
- 完善项目结构: 整理文档、脚本和测试文件
- 新增调试和测试工具脚本

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
wangliang
2026-01-16 16:28:47 +08:00
parent 0e59f3067e
commit e093995368
48 changed files with 5263 additions and 395 deletions

View File

@@ -1,6 +1,6 @@
"""
HTTP Routes for Strapi MCP Server
Provides direct HTTP access to knowledge base functions
Provides direct HTTP access to knowledge base functions (with local cache)
"""
from typing import Optional, List
import httpx
@@ -11,6 +11,7 @@ from pydantic_settings import BaseSettings
from pydantic import ConfigDict
from config_loader import load_config, get_category_endpoint
from knowledge_base import get_kb
class Settings(BaseSettings):
@@ -18,6 +19,8 @@ class Settings(BaseSettings):
strapi_api_url: str
strapi_api_token: str = ""
log_level: str = "INFO"
sync_on_startup: bool = True # Run initial sync on startup
sync_interval_minutes: int = 60 # Sync interval in minutes
model_config = ConfigDict(env_file=".env")
@@ -45,6 +48,16 @@ async def get_company_info_http(section: str = "contact", locale: str = "en"):
locale: Language locale (default: en)
Supported: en, nl, de, es, fr, it, tr
"""
# Try local knowledge base first
kb = get_kb()
try:
local_result = kb.get_company_info(section, locale)
if local_result["success"]:
return local_result
except Exception as e:
print(f"Local KB error: {e}")
# Fallback to Strapi API
try:
# Map section names to API endpoints
section_map = {
@@ -96,6 +109,12 @@ async def get_company_info_http(section: str = "contact", locale: str = "en"):
"content": profile.get("content")
}
# Save to local cache for next time
try:
kb.save_company_info(section, locale, result_data)
except Exception as e:
print(f"Failed to save to local cache: {e}")
return {
"success": True,
"data": result_data
@@ -116,13 +135,23 @@ async def query_faq_http(
locale: str = "en",
limit: int = 10
):
"""Get FAQ by category - HTTP wrapper
"""Get FAQ by category - HTTP wrapper (with local cache fallback)
Args:
category: FAQ category (register, order, pre-order, payment, shipment, return, other)
locale: Language locale (default: en)
limit: Maximum results to return
"""
# Try local knowledge base first
kb = get_kb()
try:
local_result = kb.query_faq(category, locale, limit)
if local_result["count"] > 0:
return local_result
except Exception as e:
print(f"Local KB error: {e}")
# Fallback to Strapi API (if local cache is empty)
try:
# 从配置文件获取端点
if strapi_config:
@@ -151,7 +180,8 @@ async def query_faq_http(
"count": 0,
"category": category,
"locale": locale,
"results": []
"results": [],
"_source": "strapi_api"
}
# Handle different response formats
@@ -178,7 +208,7 @@ async def query_faq_http(
elif isinstance(item_data, list):
faq_list = item_data
# Format results
# Format results and save to local cache
results = []
for item in faq_list[:limit]:
faq_item = {
@@ -209,12 +239,19 @@ async def query_faq_http(
if "question" in faq_item or "answer" in faq_item:
results.append(faq_item)
# Save to local cache for next time
try:
kb.save_faq_batch(faq_list, category, locale)
except Exception as e:
print(f"Failed to save to local cache: {e}")
return {
"success": True,
"count": len(results),
"category": category,
"locale": locale,
"results": results
"results": results,
"_source": "strapi_api"
}
except Exception as e:
@@ -222,7 +259,8 @@ async def query_faq_http(
"success": False,
"error": str(e),
"category": category,
"results": []
"results": [],
"_source": "error"
}
@@ -360,7 +398,16 @@ async def search_knowledge_base_http(query: str, locale: str = "en", limit: int
locale: Language locale
limit: Maximum results
"""
# Search FAQ across all categories
# Try local knowledge base first using FTS
kb = get_kb()
try:
local_result = kb.search_faq(query, locale, limit)
if local_result["count"] > 0:
return local_result
except Exception as e:
print(f"Local KB search error: {e}")
# Fallback to searching FAQ across all categories via Strapi API
return await search_faq_http(query, locale, limit)
@@ -371,6 +418,16 @@ async def get_policy_http(policy_type: str, locale: str = "en"):
policy_type: Type of policy (return_policy, privacy_policy, etc.)
locale: Language locale
"""
# Try local knowledge base first
kb = get_kb()
try:
local_result = kb.get_policy(policy_type, locale)
if local_result["success"]:
return local_result
except Exception as e:
print(f"Local KB error: {e}")
# Fallback to Strapi API
try:
# Map policy types to endpoints
policy_map = {
@@ -404,6 +461,21 @@ async def get_policy_http(policy_type: str, locale: str = "en"):
}
item = data["data"]
policy_data = {
"title": item.get("title"),
"summary": item.get("summary"),
"content": item.get("content"),
"version": item.get("version"),
"effective_date": item.get("effective_date")
}
# Save to local cache for next time
try:
kb.save_policy(policy_type, locale, policy_data)
except Exception as e:
print(f"Failed to save to local cache: {e}")
return {
"success": True,
"data": {