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:
@@ -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": {
|
||||
|
||||
Reference in New Issue
Block a user