100 lines
3.0 KiB
Go
100 lines
3.0 KiB
Go
package runtime
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
|
|
"cs-agent/internal/ai/runtime/registry"
|
|
"cs-agent/internal/ai/runtime/tools"
|
|
"cs-agent/internal/models"
|
|
"cs-agent/internal/pkg/toolx"
|
|
)
|
|
|
|
type toolCatalog struct {
|
|
registry *registry.Registry
|
|
}
|
|
|
|
func newToolCatalog() *toolCatalog {
|
|
return &toolCatalog{
|
|
registry: registry.NewRegistry(buildRuntimeStaticTools()...),
|
|
}
|
|
}
|
|
|
|
func buildRuntimeStaticTools() []registry.Tool {
|
|
builders := map[string]func() registry.Tool{
|
|
toolx.GraphTriageServiceRequest.Code: func() registry.Tool { return tools.NewTriageServiceRequestTool() },
|
|
toolx.GraphAnalyzeConversation.Code: func() registry.Tool { return tools.NewAnalyzeConversationTool() },
|
|
toolx.GraphPrepareTicketDraft.Code: func() registry.Tool { return tools.NewPrepareTicketDraftTool() },
|
|
toolx.GraphCreateTicketConfirm.Code: func() registry.Tool { return tools.NewCreateTicketGraphTool() },
|
|
toolx.GraphHandoffConversation.Code: func() registry.Tool { return tools.NewHandoffGraphTool() },
|
|
}
|
|
ret := make([]registry.Tool, 0, len(builders))
|
|
for _, spec := range toolx.ListRuntimeStaticToolSpecs() {
|
|
build := builders[strings.TrimSpace(spec.Code)]
|
|
if build == nil {
|
|
continue
|
|
}
|
|
ret = append(ret, build())
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func (c *toolCatalog) resolveForRun(req *Request) (*registry.ToolSet, error) {
|
|
if req == nil || req.ToolSet != nil || c == nil || c.registry == nil {
|
|
return nil, nil
|
|
}
|
|
return c.registry.Resolve(registry.Context{
|
|
Conversation: req.Conversation,
|
|
AIAgent: req.AIAgent,
|
|
AIConfig: req.AIConfig,
|
|
UserMessage: req.UserMessage,
|
|
AllowedToolCodes: c.resolveAllowedToolCodes(req.AIAgent, req.SelectedSkill),
|
|
})
|
|
}
|
|
|
|
func (c *toolCatalog) resolveForResume(req *ResumeRequest) (*registry.ToolSet, error) {
|
|
if req == nil || req.ToolSet != nil || c == nil || c.registry == nil {
|
|
return nil, nil
|
|
}
|
|
return c.registry.Resolve(registry.Context{
|
|
Conversation: req.Conversation,
|
|
AIAgent: req.AIAgent,
|
|
AIConfig: req.AIConfig,
|
|
AllowedToolCodes: c.parseAgentAllowedToolCodes(req.AIAgent),
|
|
})
|
|
}
|
|
|
|
func (c *toolCatalog) parseSkillAllowedToolCodes(skill *models.SkillDefinition) []string {
|
|
if skill == nil {
|
|
return nil
|
|
}
|
|
raw := strings.TrimSpace(skill.ToolWhitelist)
|
|
if raw == "" {
|
|
return nil
|
|
}
|
|
var items []string
|
|
if err := json.Unmarshal([]byte(raw), &items); err != nil {
|
|
return nil
|
|
}
|
|
return toolx.NormalizeToolCodes(items)
|
|
}
|
|
|
|
func (c *toolCatalog) parseAgentAllowedToolCodes(aiAgent *models.AIAgent) []string {
|
|
if aiAgent == nil || strings.TrimSpace(aiAgent.AllowedMCPTools) == "" {
|
|
return nil
|
|
}
|
|
items, err := toolx.ParseAgentMCPToolsJSON(aiAgent.AllowedMCPTools)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
ret := make([]string, 0, len(items))
|
|
for _, item := range items {
|
|
ret = append(ret, item.ToolCode)
|
|
}
|
|
return toolx.NormalizeToolCodes(ret)
|
|
}
|
|
|
|
func (c *toolCatalog) resolveAllowedToolCodes(aiAgent *models.AIAgent, skill *models.SkillDefinition) []string {
|
|
return toolx.IntersectToolCodes(c.parseAgentAllowedToolCodes(aiAgent), c.parseSkillAllowedToolCodes(skill))
|
|
}
|