refactor: how to add a node type in workflow (#558)
This commit is contained in:
@@ -28,6 +28,9 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
compose2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/compose"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/batch"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/entry"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/exit"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
)
|
||||
|
||||
func TestBatch(t *testing.T) {
|
||||
@@ -52,7 +55,7 @@ func TestBatch(t *testing.T) {
|
||||
return in, nil
|
||||
}
|
||||
|
||||
lambdaNode1 := &compose2.NodeSchema{
|
||||
lambdaNode1 := &schema.NodeSchema{
|
||||
Key: "lambda",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(lambda1),
|
||||
@@ -86,7 +89,7 @@ func TestBatch(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
lambdaNode2 := &compose2.NodeSchema{
|
||||
lambdaNode2 := &schema.NodeSchema{
|
||||
Key: "index",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(lambda2),
|
||||
@@ -103,7 +106,7 @@ func TestBatch(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
lambdaNode3 := &compose2.NodeSchema{
|
||||
lambdaNode3 := &schema.NodeSchema{
|
||||
Key: "consumer",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(lambda3),
|
||||
@@ -135,23 +138,22 @@ func TestBatch(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
ns := &compose2.NodeSchema{
|
||||
Key: "batch_node_key",
|
||||
Type: entity.NodeTypeBatch,
|
||||
ns := &schema.NodeSchema{
|
||||
Key: "batch_node_key",
|
||||
Type: entity.NodeTypeBatch,
|
||||
Configs: &batch.Config{},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
Path: compose.FieldPath{"array_1"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"array_1"},
|
||||
},
|
||||
},
|
||||
@@ -160,7 +162,7 @@ func TestBatch(t *testing.T) {
|
||||
Path: compose.FieldPath{"array_2"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"array_2"},
|
||||
},
|
||||
},
|
||||
@@ -214,11 +216,11 @@ func TestBatch(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -246,18 +248,18 @@ func TestBatch(t *testing.T) {
|
||||
return map[string]any{"success": true}, nil
|
||||
}
|
||||
|
||||
parentLambdaNode := &compose2.NodeSchema{
|
||||
parentLambdaNode := &schema.NodeSchema{
|
||||
Key: "parent_predecessor_1",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(parentLambda),
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema.WorkflowSchema{
|
||||
Nodes: []*schema.NodeSchema{
|
||||
entryN,
|
||||
parentLambdaNode,
|
||||
ns,
|
||||
exit,
|
||||
exitN,
|
||||
lambdaNode1,
|
||||
lambdaNode2,
|
||||
lambdaNode3,
|
||||
@@ -267,7 +269,7 @@ func TestBatch(t *testing.T) {
|
||||
"index": "batch_node_key",
|
||||
"consumer": "batch_node_key",
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema.Connection{
|
||||
{
|
||||
FromNode: entity.EntryNodeKey,
|
||||
ToNode: "parent_predecessor_1",
|
||||
|
||||
@@ -40,7 +40,11 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
compose2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/compose"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/emitter"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/entry"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/exit"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/llm"
|
||||
schema2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/infra/contract/modelmgr"
|
||||
"github.com/coze-dev/coze-studio/backend/internal/testutil"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
|
||||
@@ -108,22 +112,20 @@ func TestLLM(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
llmNode := &compose2.NodeSchema{
|
||||
llmNode := &schema2.NodeSchema{
|
||||
Key: "llm_node_key",
|
||||
Type: entity.NodeTypeLLM,
|
||||
Configs: map[string]any{
|
||||
"SystemPrompt": "{{sys_prompt}}",
|
||||
"UserPrompt": "{{query}}",
|
||||
"OutputFormat": llm.FormatText,
|
||||
"LLMParams": &model.LLMParams{
|
||||
Configs: &llm.Config{
|
||||
SystemPrompt: "{{sys_prompt}}",
|
||||
UserPrompt: "{{query}}",
|
||||
OutputFormat: llm.FormatText,
|
||||
LLMParams: &model.LLMParams{
|
||||
ModelName: modelName,
|
||||
},
|
||||
},
|
||||
@@ -132,7 +134,7 @@ func TestLLM(t *testing.T) {
|
||||
Path: compose.FieldPath{"sys_prompt"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"sys_prompt"},
|
||||
},
|
||||
},
|
||||
@@ -141,7 +143,7 @@ func TestLLM(t *testing.T) {
|
||||
Path: compose.FieldPath{"query"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"query"},
|
||||
},
|
||||
},
|
||||
@@ -162,11 +164,11 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema2.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -181,20 +183,20 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema2.WorkflowSchema{
|
||||
Nodes: []*schema2.NodeSchema{
|
||||
entryN,
|
||||
llmNode,
|
||||
exit,
|
||||
exitN,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema2.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: llmNode.Key,
|
||||
},
|
||||
{
|
||||
FromNode: llmNode.Key,
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -228,27 +230,20 @@ func TestLLM(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
llmNode := &compose2.NodeSchema{
|
||||
llmNode := &schema2.NodeSchema{
|
||||
Key: "llm_node_key",
|
||||
Type: entity.NodeTypeLLM,
|
||||
Configs: map[string]any{
|
||||
"SystemPrompt": "you are a helpful assistant",
|
||||
"UserPrompt": "what's the largest country in the world and it's area size in square kilometers?",
|
||||
"OutputFormat": llm.FormatJSON,
|
||||
"IgnoreException": true,
|
||||
"DefaultOutput": map[string]any{
|
||||
"country_name": "unknown",
|
||||
"area_size": int64(0),
|
||||
},
|
||||
"LLMParams": &model.LLMParams{
|
||||
Configs: &llm.Config{
|
||||
SystemPrompt: "you are a helpful assistant",
|
||||
UserPrompt: "what's the largest country in the world and it's area size in square kilometers?",
|
||||
OutputFormat: llm.FormatJSON,
|
||||
LLMParams: &model.LLMParams{
|
||||
ModelName: modelName,
|
||||
},
|
||||
},
|
||||
@@ -264,11 +259,11 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema2.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -292,20 +287,20 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema2.WorkflowSchema{
|
||||
Nodes: []*schema2.NodeSchema{
|
||||
entryN,
|
||||
llmNode,
|
||||
exit,
|
||||
exitN,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema2.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: llmNode.Key,
|
||||
},
|
||||
{
|
||||
FromNode: llmNode.Key,
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -337,22 +332,20 @@ func TestLLM(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
llmNode := &compose2.NodeSchema{
|
||||
llmNode := &schema2.NodeSchema{
|
||||
Key: "llm_node_key",
|
||||
Type: entity.NodeTypeLLM,
|
||||
Configs: map[string]any{
|
||||
"SystemPrompt": "you are a helpful assistant",
|
||||
"UserPrompt": "list the top 5 largest countries in the world",
|
||||
"OutputFormat": llm.FormatMarkdown,
|
||||
"LLMParams": &model.LLMParams{
|
||||
Configs: &llm.Config{
|
||||
SystemPrompt: "you are a helpful assistant",
|
||||
UserPrompt: "list the top 5 largest countries in the world",
|
||||
OutputFormat: llm.FormatMarkdown,
|
||||
LLMParams: &model.LLMParams{
|
||||
ModelName: modelName,
|
||||
},
|
||||
},
|
||||
@@ -363,11 +356,11 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema2.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -382,20 +375,20 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema2.WorkflowSchema{
|
||||
Nodes: []*schema2.NodeSchema{
|
||||
entryN,
|
||||
llmNode,
|
||||
exit,
|
||||
exitN,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema2.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: llmNode.Key,
|
||||
},
|
||||
{
|
||||
FromNode: llmNode.Key,
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -456,22 +449,20 @@ func TestLLM(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
openaiNode := &compose2.NodeSchema{
|
||||
openaiNode := &schema2.NodeSchema{
|
||||
Key: "openai_llm_node_key",
|
||||
Type: entity.NodeTypeLLM,
|
||||
Configs: map[string]any{
|
||||
"SystemPrompt": "you are a helpful assistant",
|
||||
"UserPrompt": "plan a 10 day family visit to China.",
|
||||
"OutputFormat": llm.FormatText,
|
||||
"LLMParams": &model.LLMParams{
|
||||
Configs: &llm.Config{
|
||||
SystemPrompt: "you are a helpful assistant",
|
||||
UserPrompt: "plan a 10 day family visit to China.",
|
||||
OutputFormat: llm.FormatText,
|
||||
LLMParams: &model.LLMParams{
|
||||
ModelName: modelName,
|
||||
},
|
||||
},
|
||||
@@ -482,14 +473,14 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
deepseekNode := &compose2.NodeSchema{
|
||||
deepseekNode := &schema2.NodeSchema{
|
||||
Key: "deepseek_llm_node_key",
|
||||
Type: entity.NodeTypeLLM,
|
||||
Configs: map[string]any{
|
||||
"SystemPrompt": "you are a helpful assistant",
|
||||
"UserPrompt": "thoroughly plan a 10 day family visit to China. Use your reasoning ability.",
|
||||
"OutputFormat": llm.FormatText,
|
||||
"LLMParams": &model.LLMParams{
|
||||
Configs: &llm.Config{
|
||||
SystemPrompt: "you are a helpful assistant",
|
||||
UserPrompt: "thoroughly plan a 10 day family visit to China. Use your reasoning ability.",
|
||||
OutputFormat: llm.FormatText,
|
||||
LLMParams: &model.LLMParams{
|
||||
ModelName: modelName,
|
||||
},
|
||||
},
|
||||
@@ -503,12 +494,11 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
emitterNode := &compose2.NodeSchema{
|
||||
emitterNode := &schema2.NodeSchema{
|
||||
Key: "emitter_node_key",
|
||||
Type: entity.NodeTypeOutputEmitter,
|
||||
Configs: map[string]any{
|
||||
"Template": "prefix {{inputObj.field1}} {{input2}} {{deepseek_reasoning}} \n\n###\n\n {{openai_output}} \n\n###\n\n {{deepseek_output}} {{inputObj.field2}} suffix",
|
||||
"Mode": nodes.Streaming,
|
||||
Configs: &emitter.Config{
|
||||
Template: "prefix {{inputObj.field1}} {{input2}} {{deepseek_reasoning}} \n\n###\n\n {{openai_output}} \n\n###\n\n {{deepseek_output}} {{inputObj.field2}} suffix",
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -542,7 +532,7 @@ func TestLLM(t *testing.T) {
|
||||
Path: compose.FieldPath{"inputObj"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"inputObj"},
|
||||
},
|
||||
},
|
||||
@@ -551,7 +541,7 @@ func TestLLM(t *testing.T) {
|
||||
Path: compose.FieldPath{"input2"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"input2"},
|
||||
},
|
||||
},
|
||||
@@ -559,11 +549,11 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema2.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.UseAnswerContent,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.UseAnswerContent,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -596,17 +586,17 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema2.WorkflowSchema{
|
||||
Nodes: []*schema2.NodeSchema{
|
||||
entryN,
|
||||
openaiNode,
|
||||
deepseekNode,
|
||||
emitterNode,
|
||||
exit,
|
||||
exitN,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema2.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: openaiNode.Key,
|
||||
},
|
||||
{
|
||||
@@ -614,7 +604,7 @@ func TestLLM(t *testing.T) {
|
||||
ToNode: emitterNode.Key,
|
||||
},
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: deepseekNode.Key,
|
||||
},
|
||||
{
|
||||
@@ -623,7 +613,7 @@ func TestLLM(t *testing.T) {
|
||||
},
|
||||
{
|
||||
FromNode: emitterNode.Key,
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -26,15 +26,20 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
compose2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/compose"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/entry"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/exit"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/loop"
|
||||
_break "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/loop/break"
|
||||
_continue "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/loop/continue"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/variableassigner"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
)
|
||||
|
||||
func TestLoop(t *testing.T) {
|
||||
t.Run("by iteration", func(t *testing.T) {
|
||||
// start-> loop_node_key[innerNode->continue] -> end
|
||||
innerNode := &compose2.NodeSchema{
|
||||
innerNode := &schema.NodeSchema{
|
||||
Key: "innerNode",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(func(ctx context.Context, in map[string]any) (out map[string]any, err error) {
|
||||
@@ -54,31 +59,30 @@ func TestLoop(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
continueNode := &compose2.NodeSchema{
|
||||
Key: "continueNode",
|
||||
Type: entity.NodeTypeContinue,
|
||||
continueNode := &schema.NodeSchema{
|
||||
Key: "continueNode",
|
||||
Type: entity.NodeTypeContinue,
|
||||
Configs: &_continue.Config{},
|
||||
}
|
||||
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
loopNode := &compose2.NodeSchema{
|
||||
loopNode := &schema.NodeSchema{
|
||||
Key: "loop_node_key",
|
||||
Type: entity.NodeTypeLoop,
|
||||
Configs: map[string]any{
|
||||
"LoopType": loop.ByIteration,
|
||||
Configs: &loop.Config{
|
||||
LoopType: loop.ByIteration,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
Path: compose.FieldPath{loop.Count},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"count"},
|
||||
},
|
||||
},
|
||||
@@ -97,11 +101,11 @@ func TestLoop(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -116,11 +120,11 @@ func TestLoop(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema.WorkflowSchema{
|
||||
Nodes: []*schema.NodeSchema{
|
||||
entryN,
|
||||
loopNode,
|
||||
exit,
|
||||
exitN,
|
||||
innerNode,
|
||||
continueNode,
|
||||
},
|
||||
@@ -128,7 +132,7 @@ func TestLoop(t *testing.T) {
|
||||
"innerNode": "loop_node_key",
|
||||
"continueNode": "loop_node_key",
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema.Connection{
|
||||
{
|
||||
FromNode: "loop_node_key",
|
||||
ToNode: "innerNode",
|
||||
@@ -142,12 +146,12 @@ func TestLoop(t *testing.T) {
|
||||
ToNode: "loop_node_key",
|
||||
},
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "loop_node_key",
|
||||
},
|
||||
{
|
||||
FromNode: "loop_node_key",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -168,7 +172,7 @@ func TestLoop(t *testing.T) {
|
||||
|
||||
t.Run("infinite", func(t *testing.T) {
|
||||
// start-> loop_node_key[innerNode->break] -> end
|
||||
innerNode := &compose2.NodeSchema{
|
||||
innerNode := &schema.NodeSchema{
|
||||
Key: "innerNode",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(func(ctx context.Context, in map[string]any) (out map[string]any, err error) {
|
||||
@@ -188,24 +192,23 @@ func TestLoop(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
breakNode := &compose2.NodeSchema{
|
||||
Key: "breakNode",
|
||||
Type: entity.NodeTypeBreak,
|
||||
breakNode := &schema.NodeSchema{
|
||||
Key: "breakNode",
|
||||
Type: entity.NodeTypeBreak,
|
||||
Configs: &_break.Config{},
|
||||
}
|
||||
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
loopNode := &compose2.NodeSchema{
|
||||
loopNode := &schema.NodeSchema{
|
||||
Key: "loop_node_key",
|
||||
Type: entity.NodeTypeLoop,
|
||||
Configs: map[string]any{
|
||||
"LoopType": loop.Infinite,
|
||||
Configs: &loop.Config{
|
||||
LoopType: loop.Infinite,
|
||||
},
|
||||
OutputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -220,11 +223,11 @@ func TestLoop(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -239,11 +242,11 @@ func TestLoop(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema.WorkflowSchema{
|
||||
Nodes: []*schema.NodeSchema{
|
||||
entryN,
|
||||
loopNode,
|
||||
exit,
|
||||
exitN,
|
||||
innerNode,
|
||||
breakNode,
|
||||
},
|
||||
@@ -251,7 +254,7 @@ func TestLoop(t *testing.T) {
|
||||
"innerNode": "loop_node_key",
|
||||
"breakNode": "loop_node_key",
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema.Connection{
|
||||
{
|
||||
FromNode: "loop_node_key",
|
||||
ToNode: "innerNode",
|
||||
@@ -265,12 +268,12 @@ func TestLoop(t *testing.T) {
|
||||
ToNode: "loop_node_key",
|
||||
},
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "loop_node_key",
|
||||
},
|
||||
{
|
||||
FromNode: "loop_node_key",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -290,14 +293,14 @@ func TestLoop(t *testing.T) {
|
||||
t.Run("by array", func(t *testing.T) {
|
||||
// start-> loop_node_key[innerNode->variable_assign] -> end
|
||||
|
||||
innerNode := &compose2.NodeSchema{
|
||||
innerNode := &schema.NodeSchema{
|
||||
Key: "innerNode",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(func(ctx context.Context, in map[string]any) (out map[string]any, err error) {
|
||||
item1 := in["item1"].(string)
|
||||
item2 := in["item2"].(string)
|
||||
count := in["count"].(int)
|
||||
return map[string]any{"total": int(count) + len(item1) + len(item2)}, nil
|
||||
return map[string]any{"total": count + len(item1) + len(item2)}, nil
|
||||
}),
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -330,16 +333,18 @@ func TestLoop(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
assigner := &compose2.NodeSchema{
|
||||
assigner := &schema.NodeSchema{
|
||||
Key: "assigner",
|
||||
Type: entity.NodeTypeVariableAssignerWithinLoop,
|
||||
Configs: []*variableassigner.Pair{
|
||||
{
|
||||
Left: vo.Reference{
|
||||
FromPath: compose.FieldPath{"count"},
|
||||
VariableType: ptr.Of(vo.ParentIntermediate),
|
||||
Configs: &variableassigner.InLoopConfig{
|
||||
Pairs: []*variableassigner.Pair{
|
||||
{
|
||||
Left: vo.Reference{
|
||||
FromPath: compose.FieldPath{"count"},
|
||||
VariableType: ptr.Of(vo.ParentIntermediate),
|
||||
},
|
||||
Right: compose.FieldPath{"total"},
|
||||
},
|
||||
Right: compose.FieldPath{"total"},
|
||||
},
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
@@ -355,19 +360,17 @@ func TestLoop(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -382,12 +385,13 @@ func TestLoop(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
loopNode := &compose2.NodeSchema{
|
||||
loopNode := &schema.NodeSchema{
|
||||
Key: "loop_node_key",
|
||||
Type: entity.NodeTypeLoop,
|
||||
Configs: map[string]any{
|
||||
"LoopType": loop.ByArray,
|
||||
"IntermediateVars": map[string]*vo.TypeInfo{
|
||||
Configs: &loop.Config{
|
||||
LoopType: loop.ByArray,
|
||||
InputArrays: []string{"items1", "items2"},
|
||||
IntermediateVars: map[string]*vo.TypeInfo{
|
||||
"count": {
|
||||
Type: vo.DataTypeInteger,
|
||||
},
|
||||
@@ -408,7 +412,7 @@ func TestLoop(t *testing.T) {
|
||||
Path: compose.FieldPath{"items1"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"items1"},
|
||||
},
|
||||
},
|
||||
@@ -417,7 +421,7 @@ func TestLoop(t *testing.T) {
|
||||
Path: compose.FieldPath{"items2"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"items2"},
|
||||
},
|
||||
},
|
||||
@@ -442,11 +446,11 @@ func TestLoop(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema.WorkflowSchema{
|
||||
Nodes: []*schema.NodeSchema{
|
||||
entryN,
|
||||
loopNode,
|
||||
exit,
|
||||
exitN,
|
||||
innerNode,
|
||||
assigner,
|
||||
},
|
||||
@@ -454,7 +458,7 @@ func TestLoop(t *testing.T) {
|
||||
"innerNode": "loop_node_key",
|
||||
"assigner": "loop_node_key",
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema.Connection{
|
||||
{
|
||||
FromNode: "loop_node_key",
|
||||
ToNode: "innerNode",
|
||||
@@ -468,12 +472,12 @@ func TestLoop(t *testing.T) {
|
||||
ToNode: "loop_node_key",
|
||||
},
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "loop_node_key",
|
||||
},
|
||||
{
|
||||
FromNode: "loop_node_key",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -43,8 +43,11 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
compose2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/compose"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/entry"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/exit"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/qa"
|
||||
repo2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/repo"
|
||||
schema2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/infra/impl/checkpoint"
|
||||
mock "github.com/coze-dev/coze-studio/backend/internal/mock/infra/contract/idgen"
|
||||
storageMock "github.com/coze-dev/coze-studio/backend/internal/mock/infra/contract/storage"
|
||||
@@ -106,26 +109,25 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
mockey.Mock(workflow.GetRepository).Return(repo).Build()
|
||||
|
||||
t.Run("answer directly, no structured output", func(t *testing.T) {
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
}}
|
||||
entryN := &schema2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
ns := &compose2.NodeSchema{
|
||||
ns := &schema2.NodeSchema{
|
||||
Key: "qa_node_key",
|
||||
Type: entity.NodeTypeQuestionAnswer,
|
||||
Configs: map[string]any{
|
||||
"QuestionTpl": "{{input}}",
|
||||
"AnswerType": qa.AnswerDirectly,
|
||||
Configs: &qa.Config{
|
||||
QuestionTpl: "{{input}}",
|
||||
AnswerType: qa.AnswerDirectly,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
Path: compose.FieldPath{"input"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"query"},
|
||||
},
|
||||
},
|
||||
@@ -133,11 +135,11 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema2.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -152,20 +154,20 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema2.WorkflowSchema{
|
||||
Nodes: []*schema2.NodeSchema{
|
||||
entryN,
|
||||
ns,
|
||||
exit,
|
||||
exitN,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema2.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "qa_node_key",
|
||||
},
|
||||
{
|
||||
FromNode: "qa_node_key",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -210,30 +212,28 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
mockModelManager.EXPECT().GetModel(gomock.Any(), gomock.Any()).Return(oneChatModel, nil, nil).Times(1)
|
||||
}
|
||||
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
ns := &compose2.NodeSchema{
|
||||
ns := &schema2.NodeSchema{
|
||||
Key: "qa_node_key",
|
||||
Type: entity.NodeTypeQuestionAnswer,
|
||||
Configs: map[string]any{
|
||||
"QuestionTpl": "{{input}}",
|
||||
"AnswerType": qa.AnswerByChoices,
|
||||
"ChoiceType": qa.FixedChoices,
|
||||
"FixedChoices": []string{"{{choice1}}", "{{choice2}}"},
|
||||
"LLMParams": &model.LLMParams{},
|
||||
Configs: &qa.Config{
|
||||
QuestionTpl: "{{input}}",
|
||||
AnswerType: qa.AnswerByChoices,
|
||||
ChoiceType: qa.FixedChoices,
|
||||
FixedChoices: []string{"{{choice1}}", "{{choice2}}"},
|
||||
LLMParams: &model.LLMParams{},
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
Path: compose.FieldPath{"input"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"query"},
|
||||
},
|
||||
},
|
||||
@@ -242,7 +242,7 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
Path: compose.FieldPath{"choice1"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"choice1"},
|
||||
},
|
||||
},
|
||||
@@ -251,7 +251,7 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
Path: compose.FieldPath{"choice2"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"choice2"},
|
||||
},
|
||||
},
|
||||
@@ -259,11 +259,11 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema2.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -287,7 +287,7 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
lambda := &compose2.NodeSchema{
|
||||
lambda := &schema2.NodeSchema{
|
||||
Key: "lambda",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(func(ctx context.Context, in map[string]any) (out map[string]any, err error) {
|
||||
@@ -295,26 +295,26 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
}),
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema2.WorkflowSchema{
|
||||
Nodes: []*schema2.NodeSchema{
|
||||
entryN,
|
||||
ns,
|
||||
exit,
|
||||
exitN,
|
||||
lambda,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema2.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "qa_node_key",
|
||||
},
|
||||
{
|
||||
FromNode: "qa_node_key",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
FromPort: ptr.Of("branch_0"),
|
||||
},
|
||||
{
|
||||
FromNode: "qa_node_key",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
FromPort: ptr.Of("branch_1"),
|
||||
},
|
||||
{
|
||||
@@ -324,11 +324,15 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
},
|
||||
{
|
||||
FromNode: "lambda",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
branches, err := schema2.BuildBranches(ws.Connections)
|
||||
assert.NoError(t, err)
|
||||
ws.Branches = branches
|
||||
|
||||
ws.Init()
|
||||
|
||||
wf, err := compose2.NewWorkflow(context.Background(), ws)
|
||||
@@ -362,28 +366,26 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("answer with dynamic choices", func(t *testing.T) {
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
ns := &compose2.NodeSchema{
|
||||
ns := &schema2.NodeSchema{
|
||||
Key: "qa_node_key",
|
||||
Type: entity.NodeTypeQuestionAnswer,
|
||||
Configs: map[string]any{
|
||||
"QuestionTpl": "{{input}}",
|
||||
"AnswerType": qa.AnswerByChoices,
|
||||
"ChoiceType": qa.DynamicChoices,
|
||||
Configs: &qa.Config{
|
||||
QuestionTpl: "{{input}}",
|
||||
AnswerType: qa.AnswerByChoices,
|
||||
ChoiceType: qa.DynamicChoices,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
Path: compose.FieldPath{"input"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"query"},
|
||||
},
|
||||
},
|
||||
@@ -392,7 +394,7 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
Path: compose.FieldPath{qa.DynamicChoicesKey},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"choices"},
|
||||
},
|
||||
},
|
||||
@@ -400,11 +402,11 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema2.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -428,7 +430,7 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
lambda := &compose2.NodeSchema{
|
||||
lambda := &schema2.NodeSchema{
|
||||
Key: "lambda",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(func(ctx context.Context, in map[string]any) (out map[string]any, err error) {
|
||||
@@ -436,26 +438,26 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
}),
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema2.WorkflowSchema{
|
||||
Nodes: []*schema2.NodeSchema{
|
||||
entryN,
|
||||
ns,
|
||||
exit,
|
||||
exitN,
|
||||
lambda,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema2.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "qa_node_key",
|
||||
},
|
||||
{
|
||||
FromNode: "qa_node_key",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
FromPort: ptr.Of("branch_0"),
|
||||
},
|
||||
{
|
||||
FromNode: "lambda",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
{
|
||||
FromNode: "qa_node_key",
|
||||
@@ -465,6 +467,10 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
branches, err := schema2.BuildBranches(ws.Connections)
|
||||
assert.NoError(t, err)
|
||||
ws.Branches = branches
|
||||
|
||||
ws.Init()
|
||||
|
||||
wf, err := compose2.NewWorkflow(context.Background(), ws)
|
||||
@@ -522,31 +528,29 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
mockModelManager.EXPECT().GetModel(gomock.Any(), gomock.Any()).Return(chatModel, nil, nil).Times(1)
|
||||
}
|
||||
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
ns := &compose2.NodeSchema{
|
||||
ns := &schema2.NodeSchema{
|
||||
Key: "qa_node_key",
|
||||
Type: entity.NodeTypeQuestionAnswer,
|
||||
Configs: map[string]any{
|
||||
"QuestionTpl": "{{input}}",
|
||||
"AnswerType": qa.AnswerDirectly,
|
||||
"ExtractFromAnswer": true,
|
||||
"AdditionalSystemPromptTpl": "{{prompt}}",
|
||||
"MaxAnswerCount": 2,
|
||||
"LLMParams": &model.LLMParams{},
|
||||
Configs: &qa.Config{
|
||||
QuestionTpl: "{{input}}",
|
||||
AnswerType: qa.AnswerDirectly,
|
||||
ExtractFromAnswer: true,
|
||||
AdditionalSystemPromptTpl: "{{prompt}}",
|
||||
MaxAnswerCount: 2,
|
||||
LLMParams: &model.LLMParams{},
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
Path: compose.FieldPath{"input"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"query"},
|
||||
},
|
||||
},
|
||||
@@ -555,7 +559,7 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
Path: compose.FieldPath{"prompt"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"prompt"},
|
||||
},
|
||||
},
|
||||
@@ -573,11 +577,11 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema2.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -610,20 +614,20 @@ func TestQuestionAnswer(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema2.WorkflowSchema{
|
||||
Nodes: []*schema2.NodeSchema{
|
||||
entryN,
|
||||
ns,
|
||||
exit,
|
||||
exitN,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema2.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "qa_node_key",
|
||||
},
|
||||
{
|
||||
FromNode: "qa_node_key",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -26,26 +26,28 @@ import (
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
|
||||
compose2 "github.com/coze-dev/coze-studio/backend/domain/workflow/internal/compose"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/entry"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/exit"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/selector"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/textprocessor"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/nodes/variableaggregator"
|
||||
"github.com/coze-dev/coze-studio/backend/domain/workflow/internal/schema"
|
||||
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
||||
)
|
||||
|
||||
func TestAddSelector(t *testing.T) {
|
||||
// start -> selector, selector.condition1 -> lambda1 -> end, selector.condition2 -> [lambda2, lambda3] -> end, selector default -> end
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
}}
|
||||
entryN := &schema.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -84,7 +86,7 @@ func TestAddSelector(t *testing.T) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
lambdaNode1 := &compose2.NodeSchema{
|
||||
lambdaNode1 := &schema.NodeSchema{
|
||||
Key: "lambda1",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(lambda1),
|
||||
@@ -96,7 +98,7 @@ func TestAddSelector(t *testing.T) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
LambdaNode2 := &compose2.NodeSchema{
|
||||
LambdaNode2 := &schema.NodeSchema{
|
||||
Key: "lambda2",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(lambda2),
|
||||
@@ -108,16 +110,16 @@ func TestAddSelector(t *testing.T) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
lambdaNode3 := &compose2.NodeSchema{
|
||||
lambdaNode3 := &schema.NodeSchema{
|
||||
Key: "lambda3",
|
||||
Type: entity.NodeTypeLambda,
|
||||
Lambda: compose.InvokableLambda(lambda3),
|
||||
}
|
||||
|
||||
ns := &compose2.NodeSchema{
|
||||
ns := &schema.NodeSchema{
|
||||
Key: "selector",
|
||||
Type: entity.NodeTypeSelector,
|
||||
Configs: map[string]any{"Clauses": []*selector.OneClauseSchema{
|
||||
Configs: &selector.Config{Clauses: []*selector.OneClauseSchema{
|
||||
{
|
||||
Single: ptr.Of(selector.OperatorEqual),
|
||||
},
|
||||
@@ -136,7 +138,7 @@ func TestAddSelector(t *testing.T) {
|
||||
Path: compose.FieldPath{"0", selector.LeftKey},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"key1"},
|
||||
},
|
||||
},
|
||||
@@ -151,7 +153,7 @@ func TestAddSelector(t *testing.T) {
|
||||
Path: compose.FieldPath{"1", "0", selector.LeftKey},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"key2"},
|
||||
},
|
||||
},
|
||||
@@ -160,7 +162,7 @@ func TestAddSelector(t *testing.T) {
|
||||
Path: compose.FieldPath{"1", "0", selector.RightKey},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"key3"},
|
||||
},
|
||||
},
|
||||
@@ -169,7 +171,7 @@ func TestAddSelector(t *testing.T) {
|
||||
Path: compose.FieldPath{"1", "1", selector.LeftKey},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"key4"},
|
||||
},
|
||||
},
|
||||
@@ -214,18 +216,18 @@ func TestAddSelector(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema.WorkflowSchema{
|
||||
Nodes: []*schema.NodeSchema{
|
||||
entryN,
|
||||
ns,
|
||||
lambdaNode1,
|
||||
LambdaNode2,
|
||||
lambdaNode3,
|
||||
exit,
|
||||
exitN,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "selector",
|
||||
},
|
||||
{
|
||||
@@ -245,24 +247,28 @@ func TestAddSelector(t *testing.T) {
|
||||
},
|
||||
{
|
||||
FromNode: "selector",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
FromPort: ptr.Of("default"),
|
||||
},
|
||||
{
|
||||
FromNode: "lambda1",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
{
|
||||
FromNode: "lambda2",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
{
|
||||
FromNode: "lambda3",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
branches, err := schema.BuildBranches(ws.Connections)
|
||||
assert.NoError(t, err)
|
||||
ws.Branches = branches
|
||||
|
||||
ws.Init()
|
||||
|
||||
ctx := context.Background()
|
||||
@@ -303,19 +309,17 @@ func TestAddSelector(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestVariableAggregator(t *testing.T) {
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -339,16 +343,16 @@ func TestVariableAggregator(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ns := &compose2.NodeSchema{
|
||||
ns := &schema.NodeSchema{
|
||||
Key: "va",
|
||||
Type: entity.NodeTypeVariableAggregator,
|
||||
Configs: map[string]any{
|
||||
"MergeStrategy": variableaggregator.FirstNotNullValue,
|
||||
"GroupToLen": map[string]int{
|
||||
Configs: &variableaggregator.Config{
|
||||
MergeStrategy: variableaggregator.FirstNotNullValue,
|
||||
GroupLen: map[string]int{
|
||||
"Group1": 1,
|
||||
"Group2": 1,
|
||||
},
|
||||
"GroupOrder": []string{
|
||||
GroupOrder: []string{
|
||||
"Group1",
|
||||
"Group2",
|
||||
},
|
||||
@@ -358,7 +362,7 @@ func TestVariableAggregator(t *testing.T) {
|
||||
Path: compose.FieldPath{"Group1", "0"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"Str1"},
|
||||
},
|
||||
},
|
||||
@@ -367,7 +371,7 @@ func TestVariableAggregator(t *testing.T) {
|
||||
Path: compose.FieldPath{"Group2", "0"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"Int1"},
|
||||
},
|
||||
},
|
||||
@@ -401,20 +405,20 @@ func TestVariableAggregator(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
entry,
|
||||
ws := &schema.WorkflowSchema{
|
||||
Nodes: []*schema.NodeSchema{
|
||||
entryN,
|
||||
ns,
|
||||
exit,
|
||||
exitN,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "va",
|
||||
},
|
||||
{
|
||||
FromNode: "va",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -448,19 +452,17 @@ func TestVariableAggregator(t *testing.T) {
|
||||
|
||||
func TestTextProcessor(t *testing.T) {
|
||||
t.Run("split", func(t *testing.T) {
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -475,19 +477,19 @@ func TestTextProcessor(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ns := &compose2.NodeSchema{
|
||||
ns := &schema.NodeSchema{
|
||||
Key: "tp",
|
||||
Type: entity.NodeTypeTextProcessor,
|
||||
Configs: map[string]any{
|
||||
"Type": textprocessor.SplitText,
|
||||
"Separators": []string{"|"},
|
||||
Configs: &textprocessor.Config{
|
||||
Type: textprocessor.SplitText,
|
||||
Separators: []string{"|"},
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
Path: compose.FieldPath{"String"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"Str"},
|
||||
},
|
||||
},
|
||||
@@ -495,20 +497,20 @@ func TestTextProcessor(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
ws := &schema.WorkflowSchema{
|
||||
Nodes: []*schema.NodeSchema{
|
||||
ns,
|
||||
entry,
|
||||
exit,
|
||||
entryN,
|
||||
exitN,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "tp",
|
||||
},
|
||||
{
|
||||
FromNode: "tp",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -527,19 +529,17 @@ func TestTextProcessor(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("concat", func(t *testing.T) {
|
||||
entry := &compose2.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: map[string]any{
|
||||
"DefaultValues": map[string]any{},
|
||||
},
|
||||
entryN := &schema.NodeSchema{
|
||||
Key: entity.EntryNodeKey,
|
||||
Type: entity.NodeTypeEntry,
|
||||
Configs: &entry.Config{},
|
||||
}
|
||||
|
||||
exit := &compose2.NodeSchema{
|
||||
exitN := &schema.NodeSchema{
|
||||
Key: entity.ExitNodeKey,
|
||||
Type: entity.NodeTypeExit,
|
||||
Configs: map[string]any{
|
||||
"TerminalPlan": vo.ReturnVariables,
|
||||
Configs: &exit.Config{
|
||||
TerminatePlan: vo.ReturnVariables,
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
@@ -554,20 +554,20 @@ func TestTextProcessor(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ns := &compose2.NodeSchema{
|
||||
ns := &schema.NodeSchema{
|
||||
Key: "tp",
|
||||
Type: entity.NodeTypeTextProcessor,
|
||||
Configs: map[string]any{
|
||||
"Type": textprocessor.ConcatText,
|
||||
"Tpl": "{{String1}}_{{String2.f1}}_{{String3.f2[1]}}",
|
||||
"ConcatChar": "\t",
|
||||
Configs: &textprocessor.Config{
|
||||
Type: textprocessor.ConcatText,
|
||||
Tpl: "{{String1}}_{{String2.f1}}_{{String3.f2[1]}}",
|
||||
ConcatChar: "\t",
|
||||
},
|
||||
InputSources: []*vo.FieldInfo{
|
||||
{
|
||||
Path: compose.FieldPath{"String1"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"Str1"},
|
||||
},
|
||||
},
|
||||
@@ -576,7 +576,7 @@ func TestTextProcessor(t *testing.T) {
|
||||
Path: compose.FieldPath{"String2"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"Str2"},
|
||||
},
|
||||
},
|
||||
@@ -585,7 +585,7 @@ func TestTextProcessor(t *testing.T) {
|
||||
Path: compose.FieldPath{"String3"},
|
||||
Source: vo.FieldSource{
|
||||
Ref: &vo.Reference{
|
||||
FromNodeKey: entry.Key,
|
||||
FromNodeKey: entryN.Key,
|
||||
FromPath: compose.FieldPath{"Str3"},
|
||||
},
|
||||
},
|
||||
@@ -593,20 +593,20 @@ func TestTextProcessor(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
ws := &compose2.WorkflowSchema{
|
||||
Nodes: []*compose2.NodeSchema{
|
||||
ws := &schema.WorkflowSchema{
|
||||
Nodes: []*schema.NodeSchema{
|
||||
ns,
|
||||
entry,
|
||||
exit,
|
||||
entryN,
|
||||
exitN,
|
||||
},
|
||||
Connections: []*compose2.Connection{
|
||||
Connections: []*schema.Connection{
|
||||
{
|
||||
FromNode: entry.Key,
|
||||
FromNode: entryN.Key,
|
||||
ToNode: "tp",
|
||||
},
|
||||
{
|
||||
FromNode: "tp",
|
||||
ToNode: exit.Key,
|
||||
ToNode: exitN.Key,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user