diff --git a/internal/ai/runtime/executor/tooling.go b/internal/ai/runtime/executor/tooling.go index e3b1d14..709e1f3 100644 --- a/internal/ai/runtime/executor/tooling.go +++ b/internal/ai/runtime/executor/tooling.go @@ -93,7 +93,6 @@ func toolSetStaticToolMetadata(toolSet *registry.ToolSet) map[string]registry.To item.ToolCode = strings.TrimSpace(item.ToolCode) item.ServerCode = strings.TrimSpace(item.ServerCode) item.ToolName = strings.TrimSpace(item.ToolName) - item.SourceType = strings.TrimSpace(item.SourceType) ret[trimmedName] = item } return ret diff --git a/internal/ai/runtime/internal/impl/callbacks/agent_trace_handler.go b/internal/ai/runtime/internal/impl/callbacks/agent_trace_handler.go index 15f6fb0..1c7e0f4 100644 --- a/internal/ai/runtime/internal/impl/callbacks/agent_trace_handler.go +++ b/internal/ai/runtime/internal/impl/callbacks/agent_trace_handler.go @@ -7,6 +7,7 @@ import ( "time" impladapter "cs-agent/internal/ai/runtime/internal/impl/adapter" + "cs-agent/internal/pkg/enums" "cs-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" @@ -18,7 +19,7 @@ type ToolMetadata struct { ToolCode string ServerCode string ToolName string - SourceType string + SourceType enums.ToolSourceType } type RuntimeTraceHandler struct { @@ -101,7 +102,7 @@ func (h *RuntimeTraceHandler) WrapInvokableToolCall(_ context.Context, endpoint item.ErrorMessage = err.Error() } h.collector.AddToolItem(item) - if metadata, ok := h.resolveToolMetadata(item.ToolName); ok && strings.TrimSpace(metadata.SourceType) == toolx.GraphCreateTicketConfirm.ServerCode { + if metadata, ok := h.resolveToolMetadata(item.ToolName); ok && metadata.SourceType == enums.ToolSourceTypeGraph { recommendedAction, riskLevel, ticketDraftReady := parseGraphToolOutcome(item.ToolCode, result) h.collector.AddGraphToolItem(GraphToolTraceItem{ ToolCode: item.ToolCode, diff --git a/internal/ai/runtime/internal/impl/factory/tool_factory.go b/internal/ai/runtime/internal/impl/factory/tool_factory.go index 1d32139..79005ee 100644 --- a/internal/ai/runtime/internal/impl/factory/tool_factory.go +++ b/internal/ai/runtime/internal/impl/factory/tool_factory.go @@ -8,6 +8,7 @@ import ( impladapter "cs-agent/internal/ai/runtime/internal/impl/adapter" runtimetooling "cs-agent/internal/ai/runtime/tooling" "cs-agent/internal/models" + "cs-agent/internal/pkg/enums" "cs-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" @@ -34,7 +35,7 @@ func (f *ToolFactory) BuildMCPTools(aiAgent *models.AIAgent) ([]runtimetooling.M if toolCode == "" { toolCode = toolx.BuildMCPToolCode(item.ServerCode, item.ToolName) } - if toolx.ResolveToolSourceType(toolCode) != "mcp" { + if toolx.ResolveToolSourceType(toolCode) != enums.ToolSourceTypeMCP { continue } serverCode, toolName := toolx.SplitMCPToolCode(toolCode) diff --git a/internal/ai/runtime/internal/impl/factory/tool_helpers.go b/internal/ai/runtime/internal/impl/factory/tool_helpers.go index f90d910..e01ef1e 100644 --- a/internal/ai/runtime/internal/impl/factory/tool_helpers.go +++ b/internal/ai/runtime/internal/impl/factory/tool_helpers.go @@ -8,6 +8,7 @@ import ( "cs-agent/internal/ai/runtime/registry" runtimetooling "cs-agent/internal/ai/runtime/tooling" "cs-agent/internal/models" + "cs-agent/internal/pkg/enums" "cs-agent/internal/pkg/toolx" ) @@ -37,7 +38,7 @@ func buildRuntimeTraceToolMetadata( ToolCode: strings.TrimSpace(item.ToolCode), ServerCode: strings.TrimSpace(item.ServerCode), ToolName: strings.TrimSpace(item.ToolName), - SourceType: "mcp", + SourceType: enums.ToolSourceTypeMCP, } } for modelName, metadata := range staticToolMetadata { @@ -45,7 +46,6 @@ func buildRuntimeTraceToolMetadata( metadata.ToolCode = strings.TrimSpace(metadata.ToolCode) metadata.ServerCode = strings.TrimSpace(metadata.ServerCode) metadata.ToolName = strings.TrimSpace(metadata.ToolName) - metadata.SourceType = strings.TrimSpace(metadata.SourceType) if modelName == "" || metadata.ToolCode == "" { continue } diff --git a/internal/ai/runtime/registry/registry.go b/internal/ai/runtime/registry/registry.go index 6eb4fcf..eb83ae6 100644 --- a/internal/ai/runtime/registry/registry.go +++ b/internal/ai/runtime/registry/registry.go @@ -60,8 +60,8 @@ func (r *Registry) Resolve(ctx Context) (*ToolSet, error) { if strings.TrimSpace(resolvedMetadata.ToolName) == "" { resolvedMetadata.ToolName = toolName } - if strings.TrimSpace(resolvedMetadata.SourceType) == "" { - resolvedMetadata.SourceType = strings.TrimSpace(spec.SourceType) + if resolvedMetadata.SourceType == "" { + resolvedMetadata.SourceType = spec.SourceType } ret.StaticToolMetadata[toolName] = ToolMetadata{ ToolCode: resolvedMetadata.ToolCode, diff --git a/internal/ai/runtime/registry/types.go b/internal/ai/runtime/registry/types.go index 198923f..248f128 100644 --- a/internal/ai/runtime/registry/types.go +++ b/internal/ai/runtime/registry/types.go @@ -2,6 +2,7 @@ package registry import ( "cs-agent/internal/models" + "cs-agent/internal/pkg/enums" "cs-agent/internal/pkg/toolx" einotool "github.com/cloudwego/eino/components/tool" @@ -19,7 +20,7 @@ type ToolMetadata struct { ToolCode string ServerCode string ToolName string - SourceType string + SourceType enums.ToolSourceType } // ToolSet 描述当前运行时可直接挂载到 ToolsNode 上的固定工具集合。 diff --git a/internal/pkg/dto/response/mcp_response.go b/internal/pkg/dto/response/mcp_response.go index 930e7c8..0580433 100644 --- a/internal/pkg/dto/response/mcp_response.go +++ b/internal/pkg/dto/response/mcp_response.go @@ -1,6 +1,9 @@ package response -import "cs-agent/internal/ai/mcps" +import ( + "cs-agent/internal/ai/mcps" + "cs-agent/internal/pkg/enums" +) type MCPConnectionResponse struct { ServerCode string `json:"serverCode"` @@ -66,15 +69,15 @@ func BuildMCPToolInfoResponses(items []mcps.ToolInfo) []MCPToolInfoResponse { } type MCPToolCatalogResponse struct { - ToolCode string `json:"toolCode"` - ServerCode string `json:"serverCode"` - ToolName string `json:"toolName"` - SourceType string `json:"sourceType"` - AutoInjected bool `json:"autoInjected"` - Title string `json:"title"` - Description string `json:"description"` - InputSchema any `json:"inputSchema"` - OutputSchema any `json:"outputSchema,omitempty"` + ToolCode string `json:"toolCode"` + ServerCode string `json:"serverCode"` + ToolName string `json:"toolName"` + SourceType enums.ToolSourceType `json:"sourceType"` + AutoInjected bool `json:"autoInjected"` + Title string `json:"title"` + Description string `json:"description"` + InputSchema any `json:"inputSchema"` + OutputSchema any `json:"outputSchema,omitempty"` } type MCPToolResultContentResponse struct { diff --git a/internal/pkg/enums/tool.go b/internal/pkg/enums/tool.go new file mode 100644 index 0000000..bdb4605 --- /dev/null +++ b/internal/pkg/enums/tool.go @@ -0,0 +1,24 @@ +package enums + +type ToolSourceType string + +const ( + ToolSourceTypeMCP ToolSourceType = "mcp" + ToolSourceTypeGraph ToolSourceType = "graph" + ToolSourceTypeBuiltin ToolSourceType = "builtin" +) + +var ToolSourceTypeValues = []ToolSourceType{ + ToolSourceTypeMCP, + ToolSourceTypeGraph, + ToolSourceTypeBuiltin, +} + +func IsValidToolSourceType(sourceType ToolSourceType) bool { + for _, item := range ToolSourceTypeValues { + if item == sourceType { + return true + } + } + return false +} diff --git a/internal/pkg/toolx/builtin_tools.go b/internal/pkg/toolx/builtin_tools.go index 67f643f..06c5fd8 100644 --- a/internal/pkg/toolx/builtin_tools.go +++ b/internal/pkg/toolx/builtin_tools.go @@ -1,6 +1,10 @@ package toolx -import "strings" +import ( + "strings" + + "cs-agent/internal/pkg/enums" +) type ToolSpec struct { Code string @@ -8,7 +12,7 @@ type ToolSpec struct { Name string Title string Description string - SourceType string + SourceType enums.ToolSourceType AutoInjected bool DirectAccess bool RuntimeStatic bool @@ -20,7 +24,7 @@ type ToolMetadata struct { ToolCode string ServerCode string ToolName string - SourceType string + SourceType enums.ToolSourceType } var ( @@ -30,7 +34,7 @@ var ( Name: "tool_search", Title: "搜索并调用动态工具", Description: "用于搜索当前允许使用的 MCP 工具,并在确认目标 toolCode 后动态调用该工具。适合处理长尾工具,不应替代固定内置流程工具。", - SourceType: "builtin", + SourceType: enums.ToolSourceTypeBuiltin, AutoInjected: true, DirectAccess: true, Appendix: strings.TrimSpace(` @@ -46,7 +50,7 @@ var ( Name: "skill", Title: "加载专项技能说明", Description: "用于加载当前命中的专项技能说明文档。仅在本轮已命中 Skill 时可用,适合将专项处理规则按需注入上下文。", - SourceType: "builtin", + SourceType: enums.ToolSourceTypeBuiltin, AutoInjected: true, } GraphTriageServiceRequest = ToolSpec{ @@ -55,7 +59,7 @@ var ( Name: "triage_service_request", Title: "升级分流判断", Description: "Graph Tool。用于综合分析当前对话,判断应继续解答、整理工单草稿还是转人工,并在需要建单时一并整理工单草稿。", - SourceType: "graph", + SourceType: enums.ToolSourceTypeGraph, RuntimeStatic: true, Appendix: strings.TrimSpace(` 当你需要判断“继续解答 / 建单 / 转人工”这类复杂升级路径时,优先先调用 triage_service_request 这个 Graph Tool,并遵守以下规则: @@ -72,7 +76,7 @@ var ( Name: "analyze_conversation", Title: "分析对话风险与摘要", Description: "Graph Tool。用于整理当前对话摘要、识别风险信号,并给出继续解答、建单或转人工的建议。", - SourceType: "graph", + SourceType: enums.ToolSourceTypeGraph, RuntimeStatic: true, Appendix: strings.TrimSpace(` 当对话可能涉及投诉升级、退款赔偿、明显负面情绪、是否要建单、是否要转人工等复杂判断时,优先调用 analyze_conversation 这个 Graph Tool,并遵守以下规则: @@ -88,7 +92,7 @@ var ( Name: "prepare_ticket_draft", Title: "整理工单草稿", Description: "Graph Tool。用于根据当前会话和已收集信息整理工单草稿,输出建议标题、描述、缺失字段和追问建议。", - SourceType: "graph", + SourceType: enums.ToolSourceTypeGraph, RuntimeStatic: true, Appendix: strings.TrimSpace(` 当用户已经表达了建单、投诉、报障、售后处理等诉求,但工单标题、描述或问题整理还比较散乱时,优先调用 prepare_ticket_draft 这个 Graph Tool,并遵守以下规则: @@ -104,7 +108,7 @@ var ( Name: "create_ticket_with_confirmation", Title: "创建工单确认流程", Description: "Graph Tool。用于封装建单参数整理、用户确认、真正建单和结果返回的确定性流程。", - SourceType: "graph", + SourceType: enums.ToolSourceTypeGraph, DirectAccess: true, RuntimeStatic: true, Aliases: []string{"builtin/create_ticket_with_confirmation"}, @@ -123,7 +127,7 @@ var ( Name: "handoff_to_human", Title: "转人工确认流程", Description: "Graph Tool。用于封装转人工原因整理、用户确认、真正转人工和结果返回的确定性流程。", - SourceType: "graph", + SourceType: enums.ToolSourceTypeGraph, DirectAccess: true, RuntimeStatic: true, Appendix: strings.TrimSpace(` @@ -229,18 +233,18 @@ func GetRegisteredToolIdentity(toolCode string) (serverCode, toolName string, ok return spec.ServerCode, spec.Name, true } -func ResolveToolSourceType(toolCode string) string { +func ResolveToolSourceType(toolCode string) enums.ToolSourceType { if spec, ok := GetRegisteredToolSpec(toolCode); ok { return spec.SourceType } toolCode = strings.TrimSpace(toolCode) switch { case strings.HasPrefix(toolCode, "graph/"): - return "graph" + return enums.ToolSourceTypeGraph case strings.HasPrefix(toolCode, "builtin/"): - return "builtin" + return enums.ToolSourceTypeBuiltin default: - return "mcp" + return enums.ToolSourceTypeMCP } } @@ -309,7 +313,7 @@ func BuildToolAppendicesForCodes(hasDynamicMCPTools bool, toolCodes []string) [] return ret } -func BuildToolMetadata(toolCode string) (serverCode, toolName, sourceType string, ok bool) { +func BuildToolMetadata(toolCode string) (serverCode, toolName string, sourceType enums.ToolSourceType, ok bool) { spec, ok := GetRegisteredToolSpec(toolCode) if !ok { return "", "", ResolveToolSourceType(toolCode), false @@ -331,7 +335,7 @@ func ResolveToolMetadata(toolCode string, fallbackName string) ToolMetadata { ToolCode: toolCode, ServerCode: strings.TrimSpace(serverCode), ToolName: strings.TrimSpace(toolName), - SourceType: strings.TrimSpace(sourceType), + SourceType: sourceType, } } diff --git a/internal/services/tool_catalog_service.go b/internal/services/tool_catalog_service.go index fb3cca3..22a6860 100644 --- a/internal/services/tool_catalog_service.go +++ b/internal/services/tool_catalog_service.go @@ -7,6 +7,7 @@ import ( "cs-agent/internal/ai/mcps" "cs-agent/internal/pkg/config" + "cs-agent/internal/pkg/enums" "cs-agent/internal/pkg/errorsx" "cs-agent/internal/pkg/toolx" ) @@ -23,7 +24,7 @@ type MCPToolCatalogItem struct { ToolCode string ServerCode string ToolName string - SourceType string + SourceType enums.ToolSourceType AutoInjected bool Title string Description string @@ -69,7 +70,7 @@ func (s *toolCatalogService) ListMCPTools(ctx context.Context) ([]MCPToolCatalog ToolCode: toolx.BuildMCPToolCode(serverCode, item.Name), ServerCode: serverCode, ToolName: strings.TrimSpace(item.Name), - SourceType: "mcp", + SourceType: enums.ToolSourceTypeMCP, AutoInjected: false, Title: strings.TrimSpace(item.Title), Description: strings.TrimSpace(item.Description), diff --git a/web/app/(console)/ai-agents/_components/edit.tsx b/web/app/(console)/ai-agents/_components/edit.tsx index 338aa13..4c411b6 100644 --- a/web/app/(console)/ai-agents/_components/edit.tsx +++ b/web/app/(console)/ai-agents/_components/edit.tsx @@ -38,6 +38,7 @@ import { type CreateAIAgentPayload, type KnowledgeBase, type MCPToolCatalogItem, + type MCPToolSourceType, type SkillDefinition, fetchAIAgent, fetchAIConfigsAll, @@ -63,7 +64,7 @@ type DirectToolOption = { value: string; label: string; meta: DirectToolItem; - sourceType: string; + sourceType: MCPToolSourceType; autoInjected: boolean; groupLabel: string; }; diff --git a/web/lib/api/admin.ts b/web/lib/api/admin.ts index c31313e..3597af0 100644 --- a/web/lib/api/admin.ts +++ b/web/lib/api/admin.ts @@ -359,11 +359,13 @@ export type MCPToolInfo = { outputSchema?: unknown } +export type MCPToolSourceType = "mcp" | "graph" | "builtin" + export type MCPToolCatalogItem = { toolCode: string serverCode: string toolName: string - sourceType: string + sourceType: MCPToolSourceType autoInjected: boolean title: string description: string