refactor: 将客服后端重构为宿主可嵌入模块
- 注入数据库、运行时配置、统一响应、文件存储和平台 AI 能力,补充业务读写工具与客户快捷操作契约。 - 移除模块内重复的组织、客户、工单、标签、技能、旧工作流、MCP 和迁移实现,将身份权限与业务主体交由宿主管理。 - 使用 libSQL 重构向量存储,并完善图片消息、访客身份、排队调度、企业微信和支持聊天页面。 - 统一 HTTP、DTO 与 WebSocket 的 snake_case 协议,补齐模块初始化、业务动作和公共载荷等回归测试。
This commit is contained in:
@@ -3,8 +3,6 @@ package dashboard
|
||||
import (
|
||||
"code.tczkiot.com/wlw/ai-agent/internal/builders"
|
||||
"code.tczkiot.com/wlw/ai-agent/internal/pkg/httpx"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"code.tczkiot.com/wlw/ai-agent/internal/models"
|
||||
"code.tczkiot.com/wlw/ai-agent/internal/pkg/constants"
|
||||
@@ -12,7 +10,6 @@ import (
|
||||
"code.tczkiot.com/wlw/ai-agent/internal/pkg/dto/response"
|
||||
"code.tczkiot.com/wlw/ai-agent/internal/pkg/enums"
|
||||
"code.tczkiot.com/wlw/ai-agent/internal/pkg/i18nx"
|
||||
"code.tczkiot.com/wlw/ai-agent/internal/pkg/toolx"
|
||||
"code.tczkiot.com/wlw/ai-agent/internal/pkg/utils"
|
||||
"code.tczkiot.com/wlw/ai-agent/internal/services"
|
||||
|
||||
@@ -240,6 +237,7 @@ func buildAIAgentResponseWithLocale(item *models.AIAgent, locale string) respons
|
||||
ret := response.AIAgentResponse{
|
||||
ID: item.ID,
|
||||
Name: item.Name,
|
||||
Avatar: item.Avatar,
|
||||
Description: item.Description,
|
||||
Status: item.Status,
|
||||
StatusName: enums.GetStatusLabel(item.Status),
|
||||
@@ -261,11 +259,7 @@ func buildAIAgentResponseWithLocale(item *models.AIAgent, locale string) respons
|
||||
FallbackModeName: enums.GetAIAgentFallbackModeLabel(item.FallbackMode),
|
||||
FallbackMessage: item.FallbackMessage,
|
||||
KnowledgeBaseIDs: utils.SplitInt64s(item.KnowledgeIDs),
|
||||
SkillIDs: utils.SplitInt64s(item.SkillIDs),
|
||||
Skills: make([]response.AIAgentSkillResponse, 0),
|
||||
Teams: make([]response.AIAgentTeamResponse, 0),
|
||||
MCPTools: make([]response.AIAgentMCPToolResponse, 0),
|
||||
WorkflowBindings: make([]response.AIAgentWorkflowBindingResponse, 0),
|
||||
PublishedRevisionID: item.PublishedRevisionID,
|
||||
SortNo: item.SortNo,
|
||||
CreatedAt: item.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
@@ -284,69 +278,5 @@ func buildAIAgentResponseWithLocale(item *models.AIAgent, locale string) respons
|
||||
})
|
||||
}
|
||||
}
|
||||
for _, id := range ret.SkillIDs {
|
||||
if skill := services.SkillDefinitionService.Get(id); skill != nil {
|
||||
ret.Skills = append(ret.Skills, response.AIAgentSkillResponse{
|
||||
ID: skill.ID,
|
||||
Name: skill.Name,
|
||||
})
|
||||
}
|
||||
}
|
||||
if raw := strings.TrimSpace(item.AllowedMCPTools); raw != "" {
|
||||
var mcpTools []request.AIAgentMCPToolRequest
|
||||
if err := json.Unmarshal([]byte(raw), &mcpTools); err == nil {
|
||||
for _, tool := range mcpTools {
|
||||
toolCode := strings.TrimSpace(tool.ToolCode)
|
||||
if toolCode == "" {
|
||||
toolCode = toolx.BuildMCPToolCode(tool.ServerCode, tool.ToolName)
|
||||
}
|
||||
toolCode = toolx.NormalizeToolCodeAlias(toolCode)
|
||||
if toolx.ResolveToolSourceType(toolCode) != enums.ToolSourceTypeMCP {
|
||||
continue
|
||||
}
|
||||
serverCode := strings.TrimSpace(tool.ServerCode)
|
||||
toolName := strings.TrimSpace(tool.ToolName)
|
||||
if registeredServerCode, registeredToolName, ok := toolx.GetRegisteredToolIdentity(toolCode); ok {
|
||||
serverCode = registeredServerCode
|
||||
toolName = registeredToolName
|
||||
} else if parsedServerCode, parsedToolName := toolx.SplitMCPToolCode(toolCode); parsedServerCode != "" && parsedToolName != "" {
|
||||
serverCode = parsedServerCode
|
||||
toolName = parsedToolName
|
||||
}
|
||||
title := strings.TrimSpace(tool.Title)
|
||||
if title == "" {
|
||||
if registeredTitle := toolx.GetRegisteredToolTitleLocale(toolCode, locale); registeredTitle != "" {
|
||||
title = registeredTitle
|
||||
}
|
||||
}
|
||||
description := strings.TrimSpace(tool.Description)
|
||||
if description == "" {
|
||||
if registeredDescription := toolx.GetRegisteredToolDescriptionLocale(toolCode, locale); registeredDescription != "" {
|
||||
description = registeredDescription
|
||||
}
|
||||
}
|
||||
ret.MCPTools = append(ret.MCPTools, response.AIAgentMCPToolResponse{
|
||||
ToolCode: toolCode,
|
||||
ServerCode: serverCode,
|
||||
ToolName: toolName,
|
||||
Title: title,
|
||||
Description: description,
|
||||
RiskLevel: tool.RiskLevel,
|
||||
RequireConfirmation: tool.RequireConfirmation,
|
||||
Arguments: tool.Arguments,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, binding := range services.AIAgentService.ListWorkflowBindings(item.ID) {
|
||||
if binding.Workflow == nil || binding.Version == nil {
|
||||
continue
|
||||
}
|
||||
ret.WorkflowBindings = append(ret.WorkflowBindings, response.AIAgentWorkflowBindingResponse{
|
||||
ID: binding.Binding.ID, WorkflowID: binding.Binding.WorkflowID, WorkflowVersionID: binding.Binding.WorkflowVersionID,
|
||||
WorkflowName: binding.Workflow.Name, WorkflowVersion: binding.Version.Version, ToolName: binding.Binding.ToolName,
|
||||
TriggerInstruction: binding.Binding.TriggerInstruction, Priority: binding.Binding.Priority, Enabled: binding.Binding.Enabled,
|
||||
})
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user