refactor: how to add a node type in workflow (#558)

This commit is contained in:
shentongmartin
2025-08-05 14:02:33 +08:00
committed by GitHub
parent 5dafd81a3f
commit bb6ff0026b
96 changed files with 8305 additions and 8717 deletions

View File

@@ -37,8 +37,11 @@ import (
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/adaptor"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/compose"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/convert"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/intentdetector"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/llm"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
"github.com/coze-dev/coze-studio/backend/infra/contract/cache"
"github.com/coze-dev/coze-studio/backend/infra/contract/chatmodel"
"github.com/coze-dev/coze-studio/backend/infra/contract/idgen"
@@ -73,7 +76,7 @@ func NewWorkflowRepository(idgen idgen.IDGenerator, db *gorm.DB, redis cache.Cmd
return repo.NewRepository(idgen, db, redis, tos, cpStore, chatModel)
}
func (i *impl) ListNodeMeta(ctx context.Context, nodeTypes map[entity.NodeType]bool) (map[string][]*entity.NodeTypeMeta, []entity.Category, error) {
func (i *impl) ListNodeMeta(_ context.Context, nodeTypes map[entity.NodeType]bool) (map[string][]*entity.NodeTypeMeta, []entity.Category, error) {
// Initialize result maps
nodeMetaMap := make(map[string][]*entity.NodeTypeMeta)
@@ -82,7 +85,7 @@ func (i *impl) ListNodeMeta(ctx context.Context, nodeTypes map[entity.NodeType]b
if meta.Disabled {
return false
}
nodeType := meta.Type
nodeType := meta.Key
if nodeTypes == nil || len(nodeTypes) == 0 {
return true // No filter, include all
}
@@ -192,10 +195,10 @@ func extractInputsAndOutputsNamedInfoList(c *vo.Canvas) (inputs []*vo.NamedTypeI
if startNode != nil && endNode != nil {
break
}
if node.Type == vo.BlockTypeBotStart {
if node.Type == entity.NodeTypeEntry.IDStr() {
startNode = node
}
if node.Type == vo.BlockTypeBotEnd {
if node.Type == entity.NodeTypeExit.IDStr() {
endNode = node
}
}
@@ -207,7 +210,7 @@ func extractInputsAndOutputsNamedInfoList(c *vo.Canvas) (inputs []*vo.NamedTypeI
if err != nil {
return nil, err
}
nInfo, err := adaptor.VariableToNamedTypeInfo(v)
nInfo, err := convert.VariableToNamedTypeInfo(v)
if err != nil {
return nil, err
}
@@ -220,7 +223,7 @@ func extractInputsAndOutputsNamedInfoList(c *vo.Canvas) (inputs []*vo.NamedTypeI
if endNode != nil {
outputs, err = slices.TransformWithErrorCheck(endNode.Data.Inputs.InputParameters, func(a *vo.Param) (*vo.NamedTypeInfo, error) {
return adaptor.BlockInputToNamedTypeInfo(a.Name, a.Input)
return convert.BlockInputToNamedTypeInfo(a.Name, a.Input)
})
if err != nil {
logs.Warn(fmt.Sprintf("transform end node inputs to named info failed, err=%v", err))
@@ -316,6 +319,34 @@ func (i *impl) GetWorkflowReference(ctx context.Context, id int64) (map[int64]*v
return ret, nil
}
type workflowIdentity struct {
ID string `json:"id"`
Version string `json:"version"`
}
func getAllSubWorkflowIdentities(c *vo.Canvas) []*workflowIdentity {
workflowEntities := make([]*workflowIdentity, 0)
var collectSubWorkFlowEntities func(nodes []*vo.Node)
collectSubWorkFlowEntities = func(nodes []*vo.Node) {
for _, n := range nodes {
if n.Type == entity.NodeTypeSubWorkflow.IDStr() {
workflowEntities = append(workflowEntities, &workflowIdentity{
ID: n.Data.Inputs.WorkflowID,
Version: n.Data.Inputs.WorkflowVersion,
})
}
if len(n.Blocks) > 0 {
collectSubWorkFlowEntities(n.Blocks)
}
}
}
collectSubWorkFlowEntities(c.Nodes)
return workflowEntities
}
func (i *impl) ValidateTree(ctx context.Context, id int64, validateConfig vo.ValidateTreeConfig) ([]*cloudworkflow.ValidateTreeInfo, error) {
wfValidateInfos := make([]*cloudworkflow.ValidateTreeInfo, 0)
issues, err := validateWorkflowTree(ctx, validateConfig)
@@ -337,7 +368,7 @@ func (i *impl) ValidateTree(ctx context.Context, id int64, validateConfig vo.Val
fmt.Errorf("failed to unmarshal canvas schema: %w", err))
}
subWorkflowIdentities := c.GetAllSubWorkflowIdentities()
subWorkflowIdentities := getAllSubWorkflowIdentities(c)
if len(subWorkflowIdentities) > 0 {
var ids []int64
@@ -421,25 +452,21 @@ func (i *impl) collectNodePropertyMap(ctx context.Context, canvas *vo.Canvas) (m
}
for _, n := range canvas.Nodes {
if n.Type == vo.BlockTypeBotSubWorkflow {
nodeSchema := &compose.NodeSchema{
if n.Type == entity.NodeTypeSubWorkflow.IDStr() {
nodeSchema := &schema.NodeSchema{
Key: vo.NodeKey(n.ID),
Type: entity.NodeTypeSubWorkflow,
Name: n.Data.Meta.Title,
}
err := adaptor.SetInputsForNodeSchema(n, nodeSchema)
if err != nil {
return nil, err
}
blockType, err := entityNodeTypeToBlockType(nodeSchema.Type)
err := convert.SetInputsForNodeSchema(n, nodeSchema)
if err != nil {
return nil, err
}
prop := &vo.NodeProperty{
Type: string(blockType),
IsEnableUserQuery: nodeSchema.IsEnableUserQuery(),
IsEnableChatHistory: nodeSchema.IsEnableChatHistory(),
IsRefGlobalVariable: nodeSchema.IsRefGlobalVariable(),
Type: nodeSchema.Type.IDStr(),
IsEnableUserQuery: isEnableUserQuery(nodeSchema),
IsEnableChatHistory: isEnableChatHistory(nodeSchema),
IsRefGlobalVariable: isRefGlobalVariable(nodeSchema),
}
nodePropertyMap[string(nodeSchema.Key)] = prop
wid, err := strconv.ParseInt(n.Data.Inputs.WorkflowID, 10, 64)
@@ -478,20 +505,16 @@ func (i *impl) collectNodePropertyMap(ctx context.Context, canvas *vo.Canvas) (m
prop.SubWorkflow = ret
} else {
nodeSchemas, _, err := adaptor.NodeToNodeSchema(ctx, n)
nodeSchemas, _, err := adaptor.NodeToNodeSchema(ctx, n, canvas)
if err != nil {
return nil, err
}
for _, nodeSchema := range nodeSchemas {
blockType, err := entityNodeTypeToBlockType(nodeSchema.Type)
if err != nil {
return nil, err
}
nodePropertyMap[string(nodeSchema.Key)] = &vo.NodeProperty{
Type: string(blockType),
IsEnableUserQuery: nodeSchema.IsEnableUserQuery(),
IsEnableChatHistory: nodeSchema.IsEnableChatHistory(),
IsRefGlobalVariable: nodeSchema.IsRefGlobalVariable(),
Type: nodeSchema.Type.IDStr(),
IsEnableUserQuery: isEnableUserQuery(nodeSchema),
IsEnableChatHistory: isEnableChatHistory(nodeSchema),
IsRefGlobalVariable: isRefGlobalVariable(nodeSchema),
}
}
@@ -500,6 +523,60 @@ func (i *impl) collectNodePropertyMap(ctx context.Context, canvas *vo.Canvas) (m
return nodePropertyMap, nil
}
func isEnableUserQuery(s *schema.NodeSchema) bool {
if s == nil {
return false
}
if s.Type != entity.NodeTypeEntry {
return false
}
if len(s.OutputSources) == 0 {
return false
}
for _, source := range s.OutputSources {
fieldPath := source.Path
if len(fieldPath) == 1 && (fieldPath[0] == "BOT_USER_INPUT" || fieldPath[0] == "USER_INPUT") {
return true
}
}
return false
}
func isEnableChatHistory(s *schema.NodeSchema) bool {
if s == nil {
return false
}
switch s.Type {
case entity.NodeTypeLLM:
llmParam := s.Configs.(*llm.Config).LLMParams
return llmParam.EnableChatHistory
case entity.NodeTypeIntentDetector:
llmParam := s.Configs.(*intentdetector.Config).LLMParams
return llmParam.EnableChatHistory
default:
return false
}
}
func isRefGlobalVariable(s *schema.NodeSchema) bool {
for _, source := range s.InputSources {
if source.IsRefGlobalVariable() {
return true
}
}
for _, source := range s.OutputSources {
if source.IsRefGlobalVariable() {
return true
}
}
return false
}
func canvasToRefs(referringID int64, canvasStr string) (map[entity.WorkflowReferenceKey]struct{}, error) {
var canvas vo.Canvas
if err := sonic.UnmarshalString(canvasStr, &canvas); err != nil {
@@ -510,7 +587,7 @@ func canvasToRefs(referringID int64, canvasStr string) (map[entity.WorkflowRefer
var getRefFn func([]*vo.Node) error
getRefFn = func(nodes []*vo.Node) error {
for _, node := range nodes {
if node.Type == vo.BlockTypeBotSubWorkflow {
if node.Type == entity.NodeTypeSubWorkflow.IDStr() {
referredID, err := strconv.ParseInt(node.Data.Inputs.WorkflowID, 10, 64)
if err != nil {
return vo.WrapError(errno.ErrSchemaConversionFail, err)
@@ -521,19 +598,21 @@ func canvasToRefs(referringID int64, canvasStr string) (map[entity.WorkflowRefer
ReferType: vo.ReferTypeSubWorkflow,
ReferringBizType: vo.ReferringBizTypeWorkflow,
}] = struct{}{}
} else if node.Type == vo.BlockTypeBotLLM {
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
for _, w := range node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList {
referredID, err := strconv.ParseInt(w.WorkflowID, 10, 64)
if err != nil {
return vo.WrapError(errno.ErrSchemaConversionFail, err)
} else if node.Type == entity.NodeTypeLLM.IDStr() {
if node.Data.Inputs.LLM != nil {
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
for _, w := range node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList {
referredID, err := strconv.ParseInt(w.WorkflowID, 10, 64)
if err != nil {
return vo.WrapError(errno.ErrSchemaConversionFail, err)
}
wfRefs[entity.WorkflowReferenceKey{
ReferredID: referredID,
ReferringID: referringID,
ReferType: vo.ReferTypeTool,
ReferringBizType: vo.ReferringBizTypeWorkflow,
}] = struct{}{}
}
wfRefs[entity.WorkflowReferenceKey{
ReferredID: referredID,
ReferringID: referringID,
ReferType: vo.ReferTypeTool,
ReferringBizType: vo.ReferringBizTypeWorkflow,
}] = struct{}{}
}
}
} else if len(node.Blocks) > 0 {
@@ -832,7 +911,7 @@ func (i *impl) CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID int6
validateAndBuildWorkflowReference = func(nodes []*vo.Node, wf *copiedWorkflow) error {
for _, node := range nodes {
if node.Type == vo.BlockTypeBotSubWorkflow {
if node.Type == entity.NodeTypeSubWorkflow.IDStr() {
var (
v *vo.DraftInfo
wfID int64
@@ -883,7 +962,7 @@ func (i *impl) CopyWorkflowFromAppToLibrary(ctx context.Context, workflowID int6
}
if node.Type == vo.BlockTypeBotLLM {
if node.Type == entity.NodeTypeLLM.IDStr() {
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
for _, w := range node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList {
var (
@@ -1086,7 +1165,7 @@ func (i *impl) DuplicateWorkflowsByAppID(ctx context.Context, sourceAppID, targe
var buildWorkflowReference func(nodes []*vo.Node, wf *copiedWorkflow) error
buildWorkflowReference = func(nodes []*vo.Node, wf *copiedWorkflow) error {
for _, node := range nodes {
if node.Type == vo.BlockTypeBotSubWorkflow {
if node.Type == entity.NodeTypeSubWorkflow.IDStr() {
var (
v *vo.DraftInfo
wfID int64
@@ -1121,7 +1200,7 @@ func (i *impl) DuplicateWorkflowsByAppID(ctx context.Context, sourceAppID, targe
}
}
if node.Type == vo.BlockTypeBotLLM {
if node.Type == entity.NodeTypeLLM.IDStr() {
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
for _, w := range node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList {
var (
@@ -1323,8 +1402,8 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int
var collectDependence func(nodes []*vo.Node) error
collectDependence = func(nodes []*vo.Node) error {
for _, node := range nodes {
switch node.Type {
case vo.BlockTypeBotAPI:
switch entity.IDStrToNodeType(node.Type) {
case entity.NodeTypePlugin:
apiParams := slices.ToMap(node.Data.Inputs.APIParams, func(e *vo.Param) (string, *vo.Param) {
return e.Name, e
})
@@ -1347,7 +1426,7 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int
ds.PluginIDs = append(ds.PluginIDs, pID)
}
case vo.BlockTypeBotDatasetWrite, vo.BlockTypeBotDataset:
case entity.NodeTypeKnowledgeIndexer, entity.NodeTypeKnowledgeRetriever:
datasetListInfoParam := node.Data.Inputs.DatasetParam[0]
datasetIDs := datasetListInfoParam.Input.Value.Content.([]any)
for _, id := range datasetIDs {
@@ -1357,7 +1436,7 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int
}
ds.KnowledgeIDs = append(ds.KnowledgeIDs, k)
}
case vo.BlockTypeDatabase, vo.BlockTypeDatabaseSelect, vo.BlockTypeDatabaseInsert, vo.BlockTypeDatabaseDelete, vo.BlockTypeDatabaseUpdate:
case entity.NodeTypeDatabaseCustomSQL, entity.NodeTypeDatabaseQuery, entity.NodeTypeDatabaseInsert, entity.NodeTypeDatabaseDelete, entity.NodeTypeDatabaseUpdate:
dsList := node.Data.Inputs.DatabaseInfoList
if len(dsList) == 0 {
return fmt.Errorf("database info is requird")
@@ -1369,7 +1448,7 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int
}
ds.DatabaseIDs = append(ds.DatabaseIDs, dsID)
}
case vo.BlockTypeBotLLM:
case entity.NodeTypeLLM:
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.PluginFCParam != nil {
for idx := range node.Data.Inputs.FCParam.PluginFCParam.PluginList {
pl := node.Data.Inputs.FCParam.PluginFCParam.PluginList[idx]
@@ -1396,7 +1475,7 @@ func (i *impl) GetWorkflowDependenceResource(ctx context.Context, workflowID int
}
}
case vo.BlockTypeBotSubWorkflow:
case entity.NodeTypeSubWorkflow:
wfID, err := strconv.ParseInt(node.Data.Inputs.WorkflowID, 10, 64)
if err != nil {
return err
@@ -1567,8 +1646,8 @@ func replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(nodes []*vo.Node, r
)
for _, node := range nodes {
switch node.Type {
case vo.BlockTypeBotSubWorkflow:
switch entity.IDStrToNodeType(node.Type) {
case entity.NodeTypeSubWorkflow:
if !hasWorkflowRelated {
continue
}
@@ -1580,7 +1659,7 @@ func replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(nodes []*vo.Node, r
node.Data.Inputs.WorkflowID = strconv.FormatInt(wf.ID, 10)
node.Data.Inputs.WorkflowVersion = wf.Version
}
case vo.BlockTypeBotAPI:
case entity.NodeTypePlugin:
if !hasPluginRelated {
continue
}
@@ -1623,7 +1702,7 @@ func replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(nodes []*vo.Node, r
apiIDParam.Input.Value.Content = strconv.FormatInt(refApiID, 10)
}
case vo.BlockTypeBotLLM:
case entity.NodeTypeLLM:
if hasWorkflowRelated && node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
for idx := range node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList {
wf := node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList[idx]
@@ -1669,7 +1748,7 @@ func replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(nodes []*vo.Node, r
}
}
case vo.BlockTypeBotDataset, vo.BlockTypeBotDatasetWrite:
case entity.NodeTypeKnowledgeIndexer, entity.NodeTypeKnowledgeRetriever:
if !hasKnowledgeRelated {
continue
}
@@ -1685,7 +1764,7 @@ func replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(nodes []*vo.Node, r
}
}
case vo.BlockTypeDatabase, vo.BlockTypeDatabaseSelect, vo.BlockTypeDatabaseInsert, vo.BlockTypeDatabaseDelete, vo.BlockTypeDatabaseUpdate:
case entity.NodeTypeDatabaseCustomSQL, entity.NodeTypeDatabaseQuery, entity.NodeTypeDatabaseInsert, entity.NodeTypeDatabaseDelete, entity.NodeTypeDatabaseUpdate:
if !hasDatabaseRelated {
continue
}
@@ -1713,3 +1792,7 @@ func replaceRelatedWorkflowOrExternalResourceInWorkflowNodes(nodes []*vo.Node, r
}
return nil
}
func RegisterAllNodeAdaptors() {
adaptor.RegisterAllNodeAdaptors()
}

View File

@@ -24,11 +24,9 @@ import (
cloudworkflow "github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
"github.com/coze-dev/coze-studio/backend/domain/workflow/crossdomain/variable"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/adaptor"
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/canvas/validate"
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
"github.com/coze-dev/coze-studio/backend/pkg/sonic"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
@@ -199,158 +197,3 @@ func isIncremental(prev version, next version) bool {
return next.Patch > prev.Patch
}
func replaceRelatedWorkflowOrPluginInWorkflowNodes(nodes []*vo.Node, relatedWorkflows map[int64]entity.IDVersionPair, relatedPlugins map[int64]vo.PluginEntity) error {
for _, node := range nodes {
if node.Type == vo.BlockTypeBotSubWorkflow {
workflowID, err := strconv.ParseInt(node.Data.Inputs.WorkflowID, 10, 64)
if err != nil {
return err
}
if wf, ok := relatedWorkflows[workflowID]; ok {
node.Data.Inputs.WorkflowID = strconv.FormatInt(wf.ID, 10)
node.Data.Inputs.WorkflowVersion = wf.Version
}
}
if node.Type == vo.BlockTypeBotAPI {
apiParams := slices.ToMap(node.Data.Inputs.APIParams, func(e *vo.Param) (string, *vo.Param) {
return e.Name, e
})
pluginIDParam, ok := apiParams["pluginID"]
if !ok {
return fmt.Errorf("plugin id param is not found")
}
pID, err := strconv.ParseInt(pluginIDParam.Input.Value.Content.(string), 10, 64)
if err != nil {
return err
}
pluginVersionParam, ok := apiParams["pluginVersion"]
if !ok {
return fmt.Errorf("plugin version param is not found")
}
if refPlugin, ok := relatedPlugins[pID]; ok {
pluginIDParam.Input.Value.Content = refPlugin.PluginID
if refPlugin.PluginVersion != nil {
pluginVersionParam.Input.Value.Content = *refPlugin.PluginVersion
}
}
}
if node.Type == vo.BlockTypeBotLLM {
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.WorkflowFCParam != nil {
for idx := range node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList {
wf := node.Data.Inputs.FCParam.WorkflowFCParam.WorkflowList[idx]
workflowID, err := strconv.ParseInt(wf.WorkflowID, 10, 64)
if err != nil {
return err
}
if refWf, ok := relatedWorkflows[workflowID]; ok {
wf.WorkflowID = strconv.FormatInt(refWf.ID, 10)
wf.WorkflowVersion = refWf.Version
}
}
}
if node.Data.Inputs.FCParam != nil && node.Data.Inputs.FCParam.PluginFCParam != nil {
for idx := range node.Data.Inputs.FCParam.PluginFCParam.PluginList {
pl := node.Data.Inputs.FCParam.PluginFCParam.PluginList[idx]
pluginID, err := strconv.ParseInt(pl.PluginID, 10, 64)
if err != nil {
return err
}
if refPlugin, ok := relatedPlugins[pluginID]; ok {
pl.PluginID = strconv.FormatInt(refPlugin.PluginID, 10)
if refPlugin.PluginVersion != nil {
pl.PluginVersion = *refPlugin.PluginVersion
}
}
}
}
}
if len(node.Blocks) > 0 {
err := replaceRelatedWorkflowOrPluginInWorkflowNodes(node.Blocks, relatedWorkflows, relatedPlugins)
if err != nil {
return err
}
}
}
return nil
}
// entityNodeTypeToBlockType converts an entity.NodeType to the corresponding vo.BlockType.
func entityNodeTypeToBlockType(nodeType entity.NodeType) (vo.BlockType, error) {
switch nodeType {
case entity.NodeTypeEntry:
return vo.BlockTypeBotStart, nil
case entity.NodeTypeExit:
return vo.BlockTypeBotEnd, nil
case entity.NodeTypeLLM:
return vo.BlockTypeBotLLM, nil
case entity.NodeTypePlugin:
return vo.BlockTypeBotAPI, nil
case entity.NodeTypeCodeRunner:
return vo.BlockTypeBotCode, nil
case entity.NodeTypeKnowledgeRetriever:
return vo.BlockTypeBotDataset, nil
case entity.NodeTypeSelector:
return vo.BlockTypeCondition, nil
case entity.NodeTypeSubWorkflow:
return vo.BlockTypeBotSubWorkflow, nil
case entity.NodeTypeDatabaseCustomSQL:
return vo.BlockTypeDatabase, nil
case entity.NodeTypeOutputEmitter:
return vo.BlockTypeBotMessage, nil
case entity.NodeTypeTextProcessor:
return vo.BlockTypeBotText, nil
case entity.NodeTypeQuestionAnswer:
return vo.BlockTypeQuestion, nil
case entity.NodeTypeBreak:
return vo.BlockTypeBotBreak, nil
case entity.NodeTypeVariableAssigner:
return vo.BlockTypeBotAssignVariable, nil
case entity.NodeTypeVariableAssignerWithinLoop:
return vo.BlockTypeBotLoopSetVariable, nil
case entity.NodeTypeLoop:
return vo.BlockTypeBotLoop, nil
case entity.NodeTypeIntentDetector:
return vo.BlockTypeBotIntent, nil
case entity.NodeTypeKnowledgeIndexer:
return vo.BlockTypeBotDatasetWrite, nil
case entity.NodeTypeBatch:
return vo.BlockTypeBotBatch, nil
case entity.NodeTypeContinue:
return vo.BlockTypeBotContinue, nil
case entity.NodeTypeInputReceiver:
return vo.BlockTypeBotInput, nil
case entity.NodeTypeDatabaseUpdate:
return vo.BlockTypeDatabaseUpdate, nil
case entity.NodeTypeDatabaseQuery:
return vo.BlockTypeDatabaseSelect, nil
case entity.NodeTypeDatabaseDelete:
return vo.BlockTypeDatabaseDelete, nil
case entity.NodeTypeHTTPRequester:
return vo.BlockTypeBotHttp, nil
case entity.NodeTypeDatabaseInsert:
return vo.BlockTypeDatabaseInsert, nil
case entity.NodeTypeVariableAggregator:
return vo.BlockTypeBotVariableMerge, nil
case entity.NodeTypeJsonSerialization:
return vo.BlockTypeJsonSerialization, nil
case entity.NodeTypeJsonDeserialization:
return vo.BlockTypeJsonDeserialization, nil
case entity.NodeTypeKnowledgeDeleter:
return vo.BlockTypeBotDatasetDelete, nil
default:
return "", vo.WrapError(errno.ErrSchemaConversionFail,
fmt.Errorf("cannot map entity node type '%s' to a workflow.NodeTemplateType", nodeType))
}
}