diff --git a/internal/agent/component/string_transform.go b/internal/agent/component/string_transform.go index 33d9426704..94a72284cf 100644 --- a/internal/agent/component/string_transform.go +++ b/internal/agent/component/string_transform.go @@ -181,6 +181,61 @@ func (s *StringTransformComponent) Inputs() map[string]string { return out } +func (s *StringTransformComponent) GetInputForm() map[string]any { + if s.param.Method == "split" { + return map[string]any{ + "line": map[string]any{ + "name": "String", + "type": "line", + }, + } + } + out := make(map[string]any) + for k, o := range getInputElementsFromText(s.param.Script) { + name, _ := o["name"].(string) + if name == "" { + name = k + } + out[k] = map[string]any{ + "name": name, + "type": "line", + } + } + if len(out) == 0 { + return nil + } + return out +} + +func getInputElementsFromText(txt string) map[string]map[string]any { + res := make(map[string]map[string]any) + for _, match := range runtime.VarRefPattern.FindAllStringSubmatch(txt, -1) { + if len(match) < 2 { + continue + } + exp := match[1] + if _, ok := res[exp]; ok { + continue + } + cpnID, varName := "", exp + if at := strings.Index(exp, "@"); at > 0 { + cpnID = exp[:at] + varName = exp[at+1:] + } + name := exp + if cpnID != "" { + name = cpnID + "@" + varName + } + res[exp] = map[string]any{ + "name": name, + "value": nil, + "_retrieval": nil, + "_cpn_id": cpnID, + } + } + return res +} + // Outputs returns the transformed payload. func (s *StringTransformComponent) Outputs() map[string]string { return map[string]string{ diff --git a/internal/agent/component/string_transform_test.go b/internal/agent/component/string_transform_test.go index 7c55e6e752..43cc039e39 100644 --- a/internal/agent/component/string_transform_test.go +++ b/internal/agent/component/string_transform_test.go @@ -173,3 +173,77 @@ func TestStringTransform_Registered(t *testing.T) { t.Errorf("Name()=%q, want StringTransform", c.Name()) } } + +func TestStringTransform_GetInputFormSplit(t *testing.T) { + c, err := NewStringTransformComponent(map[string]any{ + "method": "split", + "delimiters": []string{","}, + }) + if err != nil { + t.Fatalf("NewStringTransformComponent: %v", err) + } + + got := c.(*StringTransformComponent).GetInputForm() + want := map[string]any{ + "line": map[string]any{ + "name": "String", + "type": "line", + }, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("GetInputForm split = %#v, want %#v", got, want) + } +} + +func TestStringTransform_GetInputFormMerge(t *testing.T) { + c, err := NewStringTransformComponent(map[string]any{ + "method": "merge", + "delimiters": []string{","}, + "script": "{{sys.query}} - {{CodeExec:Run@result}} - {{sys.query}}", + }) + if err != nil { + t.Fatalf("NewStringTransformComponent: %v", err) + } + + got := c.(*StringTransformComponent).GetInputForm() + want := map[string]any{ + "sys.query": map[string]any{ + "name": "sys.query", + "type": "line", + }, + "CodeExec:Run@result": map[string]any{ + "name": "CodeExec:Run@result", + "type": "line", + }, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("GetInputForm merge = %#v, want %#v", got, want) + } +} + +func TestGetInputElementsFromText(t *testing.T) { + got := getInputElementsFromText("{{ sys.query }} {{env.foo}} {{Node_1@answer.text}} {{sys.query}}") + want := map[string]map[string]any{ + "sys.query": { + "name": "sys.query", + "value": nil, + "_retrieval": nil, + "_cpn_id": "", + }, + "env.foo": { + "name": "env.foo", + "value": nil, + "_retrieval": nil, + "_cpn_id": "", + }, + "Node_1@answer.text": { + "name": "Node_1@answer.text", + "value": nil, + "_retrieval": nil, + "_cpn_id": "Node_1", + }, + } + if !reflect.DeepEqual(got, want) { + t.Errorf("getInputElementsFromText = %#v, want %#v", got, want) + } +}