feat: refactor tool metadata resolution to utilize ToolSpec and enhance tool catalog service

This commit is contained in:
mlogclub
2026-04-12 22:30:00 +08:00
parent 11252d31da
commit ef6815a3c6
3 changed files with 46 additions and 32 deletions
@@ -124,20 +124,12 @@ func (h *RuntimeTraceHandler) resolveToolMetadata(modelToolName string) (ToolMet
if modelToolName == "" {
return ToolMetadata{}, false
}
if modelToolName == toolx.BuiltinToolSearch.Name {
if spec, ok := toolx.GetRegisteredToolSpecByName(modelToolName); ok {
return ToolMetadata{
ToolCode: toolx.BuiltinToolSearch.Code,
ServerCode: toolx.BuiltinToolSearch.ServerCode,
ToolName: toolx.BuiltinToolSearch.Name,
SourceType: toolx.BuiltinToolSearch.SourceType,
}, true
}
if modelToolName == toolx.BuiltinSkill.Name {
return ToolMetadata{
ToolCode: toolx.BuiltinSkill.Code,
ServerCode: toolx.BuiltinSkill.ServerCode,
ToolName: toolx.BuiltinSkill.Name,
SourceType: toolx.BuiltinSkill.SourceType,
ToolCode: spec.Code,
ServerCode: spec.ServerCode,
ToolName: spec.Name,
SourceType: spec.SourceType,
}, true
}
metadata, ok := h.toolMetadataBy[modelToolName]
+38
View File
@@ -82,10 +82,16 @@ var (
GraphCreateTicketConfirm,
GraphHandoffConversation,
}
AgentDirectToolSpecs = []ToolSpec{
GraphCreateTicketConfirm,
GraphHandoffConversation,
BuiltinToolSearch,
}
)
var (
toolSpecByCode = buildToolSpecByCode()
toolSpecByName = buildToolSpecByName()
toolAliasToCanonical = buildToolAliasToCanonical()
)
@@ -114,6 +120,18 @@ func buildToolAliasToCanonical() map[string]string {
return ret
}
func buildToolSpecByName() map[string]ToolSpec {
ret := make(map[string]ToolSpec, len(RegisteredToolSpecs))
for _, spec := range RegisteredToolSpecs {
name := strings.TrimSpace(spec.Name)
if name == "" {
continue
}
ret[name] = spec
}
return ret
}
func ListRegisteredToolSpecs() []ToolSpec {
return append([]ToolSpec(nil), RegisteredToolSpecs...)
}
@@ -124,6 +142,12 @@ func GetRegisteredToolSpec(toolCode string) (ToolSpec, bool) {
return spec, ok
}
func GetRegisteredToolSpecByName(name string) (ToolSpec, bool) {
name = strings.TrimSpace(name)
spec, ok := toolSpecByName[name]
return spec, ok
}
func GetRegisteredToolTitle(toolCode string) string {
spec, ok := GetRegisteredToolSpec(toolCode)
if !ok {
@@ -168,6 +192,20 @@ func IsAutoInjectedToolCode(toolCode string) bool {
return ok && spec.AutoInjected
}
func ListAgentDirectToolSpecs() []ToolSpec {
return append([]ToolSpec(nil), AgentDirectToolSpecs...)
}
func IsAgentDirectToolCode(toolCode string) bool {
toolCode = NormalizeToolCodeAlias(strings.TrimSpace(toolCode))
for _, spec := range AgentDirectToolSpecs {
if spec.Code == toolCode {
return true
}
}
return false
}
func NormalizeToolCodeAlias(toolCode string) string {
toolCode = strings.TrimSpace(toolCode)
if canonical, ok := toolAliasToCanonical[toolCode]; ok {
+3 -19
View File
@@ -34,12 +34,8 @@ type MCPToolCatalogItem struct {
func (s *toolCatalogService) ListMCPTools(ctx context.Context) ([]MCPToolCatalogItem, error) {
cfg := config.Current()
ret := make([]MCPToolCatalogItem, 0, 3)
for _, toolCode := range []string{
toolx.GraphCreateTicketConfirm.Code,
toolx.GraphHandoffConversation.Code,
} {
spec, ok := toolx.GetRegisteredToolSpec(toolCode)
if !ok {
for _, spec := range toolx.ListAgentDirectToolSpecs() {
if spec.Code == toolx.BuiltinToolSearch.Code && !cfg.MCP.Enabled {
continue
}
ret = append(ret, MCPToolCatalogItem{
@@ -55,17 +51,6 @@ func (s *toolCatalogService) ListMCPTools(ctx context.Context) ([]MCPToolCatalog
if !cfg.MCP.Enabled {
return ret, nil
}
if spec, ok := toolx.GetRegisteredToolSpec(toolx.BuiltinToolSearch.Code); ok {
ret = append(ret, MCPToolCatalogItem{
ToolCode: spec.Code,
ServerCode: spec.ServerCode,
ToolName: spec.Name,
SourceType: spec.SourceType,
AutoInjected: spec.AutoInjected,
Title: spec.Title,
Description: spec.Description,
})
}
serverCodes := make([]string, 0, len(cfg.MCP.Servers))
for serverCode, server := range cfg.MCP.Servers {
if !server.Enabled {
@@ -106,8 +91,7 @@ func (s *toolCatalogService) ValidateToolCode(toolCode string) error {
if toolCode == "" {
return errorsx.InvalidParam("toolCode不能为空")
}
switch toolCode {
case toolx.BuiltinToolSearch.Code, "builtin/create_ticket_with_confirmation", toolx.GraphCreateTicketConfirm.Code, toolx.GraphHandoffConversation.Code:
if toolx.IsAgentDirectToolCode(toolCode) {
return nil
}
serverCode, toolName := toolx.SplitMCPToolCode(toolCode)