fix: delete redundant fields in plugin output data (#469)

This commit is contained in:
lvxinyu-1117
2025-08-04 16:54:30 +08:00
committed by GitHub
parent a44b4e8f7e
commit c7bf6bbdec
8 changed files with 304 additions and 15 deletions

View File

@@ -201,7 +201,7 @@ func (t *pluginService) GetPluginToolsInfo(ctx context.Context, req *crossplugin
)
if toolExample != nil {
requestExample = toolExample.RequestExample
responseExample = toolExample.RequestExample
responseExample = toolExample.ResponseExample
}
response.ToolInfoList[tf.ID] = crossplugin.ToolInfo{
@@ -220,6 +220,63 @@ func (t *pluginService) GetPluginToolsInfo(ctx context.Context, req *crossplugin
return response, nil
}
func (t *pluginService) UnwrapArrayItemFieldsInVariable(v *vo.Variable) error {
if v == nil {
return nil
}
if v.Type == vo.VariableTypeObject {
subVars, ok := v.Schema.([]*vo.Variable)
if !ok {
return nil
}
newSubVars := make([]*vo.Variable, 0, len(subVars))
for _, subVar := range subVars {
if subVar.Name == "[Array Item]" {
if err := t.UnwrapArrayItemFieldsInVariable(subVar); err != nil {
return err
}
// If the array item is an object, append its children
if subVar.Type == vo.VariableTypeObject {
if innerSubVars, ok := subVar.Schema.([]*vo.Variable); ok {
newSubVars = append(newSubVars, innerSubVars...)
}
} else {
// If the array item is a primitive type, clear its name and append it
subVar.Name = ""
newSubVars = append(newSubVars, subVar)
}
} else {
// For other sub-variables, recursively unwrap and append
if err := t.UnwrapArrayItemFieldsInVariable(subVar); err != nil {
return err
}
newSubVars = append(newSubVars, subVar)
}
}
v.Schema = newSubVars
} else if v.Type == vo.VariableTypeList {
if v.Schema != nil {
subVar, ok := v.Schema.(*vo.Variable)
if !ok {
return nil
}
if err := t.UnwrapArrayItemFieldsInVariable(subVar); err != nil {
return err
}
// If the array item definition itself has "[Array Item]" name, clear it
if subVar.Name == "[Array Item]" {
subVar.Name = ""
}
v.Schema = subVar
}
}
return nil
}
func (t *pluginService) GetPluginInvokableTools(ctx context.Context, req *crossplugin.ToolsInvokableRequest) (
_ map[int64]crossplugin.InvokableTool, err error) {
defer func() {
@@ -327,7 +384,7 @@ func (t *pluginService) ExecutePlugin(ctx context.Context, input map[string]any,
}
var output map[string]any
err = sonic.UnmarshalString(r.RawResp, &output)
err = sonic.UnmarshalString(r.TrimmedResp, &output)
if err != nil {
return nil, vo.WrapError(errno.ErrSerializationDeserializationFail, err)
}

View File

@@ -0,0 +1,217 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package plugin
import (
"testing"
"github.com/coze-dev/coze-studio/backend/domain/workflow/entity/vo"
"github.com/stretchr/testify/assert"
)
func TestPluginService_UnwrapArrayItemFieldsInVariable(t *testing.T) {
s := &pluginService{}
t.Run("unwraps a simple array item", func(t *testing.T) {
input := &vo.Variable{
Name: "root",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{
Name: "[Array Item]",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{Name: "field1", Type: vo.VariableTypeString},
{Name: "field2", Type: vo.VariableTypeInteger},
},
},
},
}
expected := &vo.Variable{
Name: "root",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{Name: "field1", Type: vo.VariableTypeString},
{Name: "field2", Type: vo.VariableTypeInteger},
},
}
err := s.UnwrapArrayItemFieldsInVariable(input)
assert.NoError(t, err)
assert.Equal(t, expected, input)
})
t.Run("handles nested array items", func(t *testing.T) {
input := &vo.Variable{
Name: "root",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{
Name: "[Array Item]",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{Name: "field1", Type: vo.VariableTypeString},
{
Name: "[Array Item]",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{Name: "nestedField", Type: vo.VariableTypeBoolean},
},
},
},
},
},
}
expected := &vo.Variable{
Name: "root",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{Name: "field1", Type: vo.VariableTypeString},
{Name: "nestedField", Type: vo.VariableTypeBoolean},
},
}
err := s.UnwrapArrayItemFieldsInVariable(input)
assert.NoError(t, err)
assert.Equal(t, expected, input)
})
t.Run("handles array item within a list", func(t *testing.T) {
input := &vo.Variable{
Name: "rootList",
Type: vo.VariableTypeList,
Schema: &vo.Variable{
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{
Name: "[Array Item]",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{Name: "itemField", Type: vo.VariableTypeString},
},
},
},
},
}
expected := &vo.Variable{
Name: "rootList",
Type: vo.VariableTypeList,
Schema: &vo.Variable{
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{Name: "itemField", Type: vo.VariableTypeString},
},
},
}
err := s.UnwrapArrayItemFieldsInVariable(input)
assert.NoError(t, err)
assert.Equal(t, expected, input)
})
t.Run("does nothing if no array item is present", func(t *testing.T) {
input := &vo.Variable{
Name: "root",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{Name: "field1", Type: vo.VariableTypeString},
{Name: "field2", Type: vo.VariableTypeInteger},
},
}
// Create a copy for comparison as the input will be modified in place.
expected := &vo.Variable{
Name: "root",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{Name: "field1", Type: vo.VariableTypeString},
{Name: "field2", Type: vo.VariableTypeInteger},
},
}
err := s.UnwrapArrayItemFieldsInVariable(input)
assert.NoError(t, err)
assert.Equal(t, expected, input)
})
t.Run("handles primitive type array item in object", func(t *testing.T) {
input := &vo.Variable{
Name: "root",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{
Name: "[Array Item]",
Type: vo.VariableTypeString,
},
{
Name: "anotherField",
Type: vo.VariableTypeInteger,
},
},
}
expected := &vo.Variable{
Name: "root",
Type: vo.VariableTypeObject,
Schema: []*vo.Variable{
{
Name: "",
Type: vo.VariableTypeString,
},
{
Name: "anotherField",
Type: vo.VariableTypeInteger,
},
},
}
err := s.UnwrapArrayItemFieldsInVariable(input)
assert.NoError(t, err)
assert.Equal(t, expected, input)
})
t.Run("handles list of primitives", func(t *testing.T) {
input := &vo.Variable{
Name: "listOfStrings",
Type: vo.VariableTypeList,
Schema: &vo.Variable{
Name: "[Array Item]",
Type: vo.VariableTypeString,
},
}
expected := &vo.Variable{
Name: "listOfStrings",
Type: vo.VariableTypeList,
Schema: &vo.Variable{
Name: "",
Type: vo.VariableTypeString,
},
}
err := s.UnwrapArrayItemFieldsInVariable(input)
assert.NoError(t, err)
assert.Equal(t, expected, input)
})
t.Run("handles nil input", func(t *testing.T) {
err := s.UnwrapArrayItemFieldsInVariable(nil)
assert.NoError(t, err)
})
}