From d58783b11c1ed66c0ab6d26919ac3eb8f4edebbb Mon Sep 17 00:00:00 2001 From: mrh997 Date: Thu, 14 Aug 2025 17:24:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(plugin):=20supports=20using=20json=20marsh?= =?UTF-8?q?al=20to=20correct=20string=20types=20by=20=E2=80=A6=20(#758)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin/internal/encoder/req_encode.go | 34 +++++++++++-------- backend/domain/plugin/service/exec_tool.go | 8 ++--- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/backend/domain/plugin/internal/encoder/req_encode.go b/backend/domain/plugin/internal/encoder/req_encode.go index cf2cb7c7..1a7e1525 100644 --- a/backend/domain/plugin/internal/encoder/req_encode.go +++ b/backend/domain/plugin/internal/encoder/req_encode.go @@ -263,28 +263,28 @@ func MustString(value any) string { } } -func TryFixValueType(paramName string, schemaRef *openapi3.SchemaRef, value any) (any, error) { +func TryCorrectValueType(paramName string, schemaRef *openapi3.SchemaRef, value any) (any, error) { if value == nil { return "", fmt.Errorf("value of '%s' is nil", paramName) } switch schemaRef.Value.Type { case openapi3.TypeString: - return tryString(value) + return tryCorrectString(value) case openapi3.TypeNumber: - return tryFloat64(value) + return tryCorrectFloat64(value) case openapi3.TypeInteger: - return tryInt64(value) + return tryCorrectInt64(value) case openapi3.TypeBoolean: - return tryBool(value) + return tryCorrectBool(value) case openapi3.TypeArray: arrVal, ok := value.([]any) if !ok { - return nil, fmt.Errorf("[TryFixValueType] value '%s' is not array", paramName) + return nil, fmt.Errorf("[TryCorrectValueType] value '%s' is not array", paramName) } for i, v := range arrVal { - _v, err := TryFixValueType(paramName, schemaRef.Value.Items, v) + _v, err := TryCorrectValueType(paramName, schemaRef.Value.Items, v) if err != nil { return nil, err } @@ -296,7 +296,7 @@ func TryFixValueType(paramName string, schemaRef *openapi3.SchemaRef, value any) case openapi3.TypeObject: mapVal, ok := value.(map[string]any) if !ok { - return nil, fmt.Errorf("[TryFixValueType] value '%s' is not object", paramName) + return nil, fmt.Errorf("[TryCorrectValueType] value '%s' is not object", paramName) } for k, v := range mapVal { @@ -305,7 +305,7 @@ func TryFixValueType(paramName string, schemaRef *openapi3.SchemaRef, value any) continue } - _v, err := TryFixValueType(k, p, v) + _v, err := TryCorrectValueType(k, p, v) if err != nil { return nil, err } @@ -315,11 +315,11 @@ func TryFixValueType(paramName string, schemaRef *openapi3.SchemaRef, value any) return mapVal, nil default: - return nil, fmt.Errorf("[TryFixValueType] unsupported schema type '%s'", schemaRef.Value.Type) + return nil, fmt.Errorf("[TryCorrectValueType] unsupported schema type '%s'", schemaRef.Value.Type) } } -func tryString(value any) (string, error) { +func tryCorrectString(value any) (string, error) { switch val := value.(type) { case string: return val, nil @@ -331,11 +331,15 @@ func tryString(value any) (string, error) { case json.Number: return val.String(), nil default: - return "", fmt.Errorf("cannot convert type from '%T' to string", val) + b, err := sonic.MarshalString(value) + if err != nil { + return "", fmt.Errorf("tryCorrectString failed, err=%w", err) + } + return b, nil } } -func tryInt64(value any) (int64, error) { +func tryCorrectInt64(value any) (int64, error) { switch val := value.(type) { case string: vi64, _ := strconv.ParseInt(val, 10, 64) @@ -352,7 +356,7 @@ func tryInt64(value any) (int64, error) { } } -func tryBool(value any) (bool, error) { +func tryCorrectBool(value any) (bool, error) { switch val := value.(type) { case string: return strconv.ParseBool(val) @@ -363,7 +367,7 @@ func tryBool(value any) (bool, error) { } } -func tryFloat64(value any) (float64, error) { +func tryCorrectFloat64(value any) (float64, error) { switch val := value.(type) { case string: return strconv.ParseFloat(val, 64) diff --git a/backend/domain/plugin/service/exec_tool.go b/backend/domain/plugin/service/exec_tool.go index e1dd6cac..f1b71c5e 100644 --- a/backend/domain/plugin/service/exec_tool.go +++ b/backend/domain/plugin/service/exec_tool.go @@ -1100,15 +1100,15 @@ func (t *toolExecutor) processWithInvalidRespProcessStrategyOfReturnErr(_ contex processor = func(paramName string, paramVal any, schemaVal *openapi3.Schema) (any, error) { switch schemaVal.Type { case openapi3.TypeObject: - newParamValMap := map[string]any{} paramValMap, ok := paramVal.(map[string]any) if !ok { return nil, errorx.New(errno.ErrPluginExecuteToolFailed, errorx.KVf(errno.PluginMsgKey, "expected '%s' to be of type 'object', but got '%T'", paramName, paramVal)) } + newParamValMap := map[string]any{} for paramName_, paramVal_ := range paramValMap { - paramSchema_, ok := schemaVal.Properties[paramName] + paramSchema_, ok := schemaVal.Properties[paramName_] if !ok || t.disabledParam(paramSchema_.Value) { // Only the object field can be disabled, and the top level of request and response must be the object structure continue } @@ -1122,13 +1122,13 @@ func (t *toolExecutor) processWithInvalidRespProcessStrategyOfReturnErr(_ contex return newParamValMap, nil case openapi3.TypeArray: - newParamValSlice := []any{} paramValSlice, ok := paramVal.([]any) if !ok { return nil, errorx.New(errno.ErrPluginExecuteToolFailed, errorx.KVf(errno.PluginMsgKey, "expected '%s' to be of type 'array', but got '%T'", paramName, paramVal)) } + newParamValSlice := []any{} for _, paramVal_ := range paramValSlice { newParamVal, err := processor(paramName, paramVal_, schemaVal.Items.Value) if err != nil { @@ -1426,7 +1426,7 @@ func (t *toolExecutor) buildRequestBody(ctx context.Context, op *model.Openapi3O continue } - _value, err := encoder.TryFixValueType(paramName, prop, value) + _value, err := encoder.TryCorrectValueType(paramName, prop, value) if err != nil { return nil, "", err }