refactor: rename direct tools to MCP tools across the codebase for consistency

This commit is contained in:
mlogclub
2026-07-26 22:38:38 +08:00
parent 2de50a2f3a
commit 1464008741
14 changed files with 96 additions and 128 deletions
+17 -26
View File
@@ -238,17 +238,17 @@ func (s *aIAgentService) validatePublishableAgent(db *gorm.DB, agent *models.AIA
if strings.TrimSpace(agent.AllowedMCPTools) == "" {
return nil
}
var directTools []request.AIAgentMCPToolRequest
if err := json.Unmarshal([]byte(agent.AllowedMCPTools), &directTools); err != nil {
return errorsx.InvalidParam("ai agent direct tools are invalid")
var mcpTools []request.AIAgentMCPToolRequest
if err := json.Unmarshal([]byte(agent.AllowedMCPTools), &mcpTools); err != nil {
return errorsx.InvalidParam("ai agent MCP tools are invalid")
}
for _, item := range directTools {
for _, item := range mcpTools {
definition, err := aitooling.DefaultRegistry.Resolve(item.ToolCode)
if err != nil || definition.InputSchema == nil {
return errorsx.InvalidParam("ai agent direct tool definition is unavailable")
return errorsx.InvalidParam("ai agent MCP tool definition is unavailable")
}
if definition.RequireConfirmation {
return errorsx.InvalidParam("ai agent direct tool requires confirmation and cannot be executed directly")
return errorsx.InvalidParam("ai agent MCP tool requires confirmation and cannot be executed directly")
}
}
return nil
@@ -392,17 +392,17 @@ func (s *aIAgentService) buildAIAgentModel(id int64, req request.CreateAIAgentRe
if err != nil {
return nil, err
}
directTools, err := s.normalizeDirectTools(req.DirectTools)
mcpTools, err := s.normalizeMCPTools(req.MCPTools)
if err != nil {
return nil, err
}
directToolsJSON := ""
if len(directTools) > 0 {
buf, marshalErr := json.Marshal(directTools)
mcpToolsJSON := ""
if len(mcpTools) > 0 {
buf, marshalErr := json.Marshal(mcpTools)
if marshalErr != nil {
return nil, errorsx.InvalidParamI18n("error.e0021")
}
directToolsJSON = string(buf)
mcpToolsJSON = string(buf)
}
return &models.AIAgent{
Name: name,
@@ -424,7 +424,7 @@ func (s *aIAgentService) buildAIAgentModel(id int64, req request.CreateAIAgentRe
FallbackMessage: strings.TrimSpace(req.FallbackMessage),
KnowledgeIDs: utils.JoinInt64s(knowledgeBaseIDs),
SkillIDs: utils.JoinInt64s(skillIDs),
AllowedMCPTools: directToolsJSON,
AllowedMCPTools: mcpToolsJSON,
}, nil
}
@@ -541,7 +541,7 @@ func (s *aIAgentService) normalizeSkillIDs(input []int64) ([]int64, error) {
return ret, nil
}
func (s *aIAgentService) normalizeDirectTools(input []request.AIAgentMCPToolRequest) ([]request.AIAgentMCPToolRequest, error) {
func (s *aIAgentService) normalizeMCPTools(input []request.AIAgentMCPToolRequest) ([]request.AIAgentMCPToolRequest, error) {
if len(input) == 0 {
return nil, nil
}
@@ -552,20 +552,11 @@ func (s *aIAgentService) normalizeDirectTools(input []request.AIAgentMCPToolRequ
if err != nil {
return nil, err
}
if toolx.IsAutoInjectedToolCode(strings.TrimSpace(normalized.ToolCode)) {
continue
if toolx.ResolveToolSourceType(normalized.ToolCode) != enums.ToolSourceTypeMCP {
return nil, errorsx.InvalidParamI18n("error.e0020")
}
if spec, registered := toolx.GetRegisteredToolSpec(normalized.ToolCode); registered {
if !spec.DirectAccess || spec.AutoInjected || (spec.Code != toolx.BuiltinConversationContext.Code && spec.Code != toolx.BuiltinKnowledgeRetrieve.Code && spec.Code != toolx.GraphTriageServiceRequest.Code && spec.Code != toolx.GraphAnalyzeConversation.Code && spec.Code != toolx.GraphPrepareTicketDraft.Code) {
return nil, errorsx.InvalidParamI18n("error.e0020")
}
} else {
if toolx.ResolveToolSourceType(normalized.ToolCode) != enums.ToolSourceTypeMCP {
return nil, errorsx.InvalidParamI18n("error.e0020")
}
if err := ToolCatalogService.ValidateToolCode(normalized.ToolCode); err != nil {
return nil, err
}
if err := ToolCatalogService.ValidateToolCode(normalized.ToolCode); err != nil {
return nil, err
}
key := strings.TrimSpace(normalized.ToolCode)
if _, exists := seen[key]; exists {
@@ -203,32 +203,18 @@ func TestAIAgentServiceNormalizesToolPolicy(t *testing.T) {
}
}
func TestAIAgentServiceAllowsRegisteredReadDirectTool(t *testing.T) {
tools, err := AIAgentService.normalizeDirectTools([]request.AIAgentMCPToolRequest{{ToolCode: toolx.BuiltinConversationContext.Code}})
if err != nil {
t.Fatalf("normalizeDirectTools: %v", err)
}
if len(tools) != 1 || tools[0].ToolCode != toolx.BuiltinConversationContext.Code {
t.Fatalf("unexpected normalized direct tools: %#v", tools)
}
tools, err = AIAgentService.normalizeDirectTools([]request.AIAgentMCPToolRequest{{ToolCode: toolx.BuiltinKnowledgeRetrieve.Code}})
if err != nil || len(tools) != 1 || tools[0].ToolCode != toolx.BuiltinKnowledgeRetrieve.Code {
t.Fatalf("expected registered knowledge retrieve tool to be allowed, tools=%#v err=%v", tools, err)
}
tools, err = AIAgentService.normalizeDirectTools([]request.AIAgentMCPToolRequest{{ToolCode: toolx.GraphPrepareTicketDraft.Code}})
if err != nil || len(tools) != 1 || tools[0].ToolCode != toolx.GraphPrepareTicketDraft.Code {
t.Fatalf("expected registered ticket draft tool to be allowed, tools=%#v err=%v", tools, err)
}
tools, err = AIAgentService.normalizeDirectTools([]request.AIAgentMCPToolRequest{{ToolCode: toolx.GraphAnalyzeConversation.Code}})
if err != nil || len(tools) != 1 || tools[0].ToolCode != toolx.GraphAnalyzeConversation.Code {
t.Fatalf("expected registered conversation analysis tool to be allowed, tools=%#v err=%v", tools, err)
}
tools, err = AIAgentService.normalizeDirectTools([]request.AIAgentMCPToolRequest{{ToolCode: toolx.GraphTriageServiceRequest.Code}})
if err != nil || len(tools) != 1 || tools[0].ToolCode != toolx.GraphTriageServiceRequest.Code {
t.Fatalf("expected registered service triage tool to be allowed, tools=%#v err=%v", tools, err)
}
if _, err := AIAgentService.normalizeDirectTools([]request.AIAgentMCPToolRequest{{ToolCode: toolx.GraphHandoffConversation.Code}}); err == nil {
t.Fatal("expected unsupported graph direct tool to be rejected")
func TestAIAgentServiceRejectsNonMCPToolSelection(t *testing.T) {
for _, toolCode := range []string{
toolx.BuiltinConversationContext.Code,
toolx.BuiltinKnowledgeRetrieve.Code,
toolx.GraphPrepareTicketDraft.Code,
toolx.GraphAnalyzeConversation.Code,
toolx.GraphTriageServiceRequest.Code,
toolx.GraphHandoffConversation.Code,
} {
if _, err := AIAgentService.normalizeMCPTools([]request.AIAgentMCPToolRequest{{ToolCode: toolCode}}); err == nil {
t.Fatalf("expected non-MCP tool %q to be rejected", toolCode)
}
}
}
@@ -350,7 +336,7 @@ func TestAIAgentServiceAllowsPublishWithAdministratorSelectedMCPTool(t *testing.
t.Fatalf("CreateAIAgent() error = %v", err)
}
if err := sqls.DB().Model(&models.AIAgent{}).Where("id = ?", agent.ID).Update("allowed_mcp_tools", `[{"toolCode":"mcp/demo/write_order"}]`).Error; err != nil {
t.Fatalf("set direct tool: %v", err)
t.Fatalf("set MCP tool: %v", err)
}
if _, err := AIAgentService.PublishAIAgent(agent.ID, operator); err != nil {
t.Fatalf("expected administrator-selected MCP tool to be publishable, got %v", err)