|
|
@@ -4,6 +4,7 @@ import (
|
|
|
"context"
|
|
|
"encoding/json"
|
|
|
"errors"
|
|
|
+ "fmt"
|
|
|
"strings"
|
|
|
|
|
|
annotations2 "git.ikuban.com/server/kubanapis/kuban/api/annotations"
|
|
|
@@ -70,25 +71,39 @@ func serverAddToolsByMethod(serviceName string, srv any, method protoreflect.Met
|
|
|
if inputOperation != nil {
|
|
|
inputDescription = inputOperation.GetDescription()
|
|
|
}
|
|
|
- propertyOption := []mcp2.PropertyOption{mcp2.Description(inputDescription)}
|
|
|
+ propertyOption := make([]mcp2.PropertyOption, 0)
|
|
|
if inputOperation2 != nil && len(inputOperation2) > 0 && inputOperation2[0] == annotations.FieldBehavior_REQUIRED {
|
|
|
propertyOption = append(propertyOption, mcp2.Required())
|
|
|
}
|
|
|
- switch input.Kind() {
|
|
|
- case protoreflect.StringKind:
|
|
|
- toolOptions = append(toolOptions, mcp2.WithString(string(input.Name()), propertyOption...))
|
|
|
- case protoreflect.BoolKind:
|
|
|
- toolOptions = append(toolOptions, mcp2.WithBoolean(string(input.Name()), propertyOption...))
|
|
|
- case protoreflect.DoubleKind, protoreflect.FloatKind,
|
|
|
- protoreflect.Sfixed64Kind, protoreflect.Sfixed32Kind,
|
|
|
- protoreflect.Fixed64Kind, protoreflect.Fixed32Kind,
|
|
|
- protoreflect.Sint64Kind, protoreflect.Sint32Kind,
|
|
|
- protoreflect.Uint64Kind, protoreflect.Uint32Kind,
|
|
|
- protoreflect.Int64Kind, protoreflect.Int32Kind:
|
|
|
- toolOptions = append(toolOptions, mcp2.WithNumber(string(input.Name()), propertyOption...))
|
|
|
- case protoreflect.MessageKind:
|
|
|
- propertyOption = append(propertyOption, mcp2.Properties(getFiledMessageParamProperties(input.Message())))
|
|
|
+
|
|
|
+ if input.IsList() {
|
|
|
+ propertyOption = append(propertyOption, mcp2.Items(getInputArrayItems(input)))
|
|
|
+ propertyOption = append(propertyOption, mcp2.Description(inputDescription))
|
|
|
+ toolOptions = append(toolOptions, mcp2.WithArray(string(input.Name()), propertyOption...))
|
|
|
+ } else if input.IsMap() {
|
|
|
+ additionalProperties, descriptionSuffix := getInputMapProperties(input)
|
|
|
+ inputDescription = inputDescription + descriptionSuffix
|
|
|
+ propertyOption = append(propertyOption, mcp2.Description(inputDescription))
|
|
|
+ propertyOption = append(propertyOption, mcp2.AdditionalProperties(additionalProperties))
|
|
|
toolOptions = append(toolOptions, mcp2.WithObject(string(input.Name()), propertyOption...))
|
|
|
+ } else {
|
|
|
+ propertyOption = append(propertyOption, mcp2.Description(inputDescription))
|
|
|
+ switch input.Kind() {
|
|
|
+ case protoreflect.StringKind:
|
|
|
+ toolOptions = append(toolOptions, mcp2.WithString(string(input.Name()), propertyOption...))
|
|
|
+ case protoreflect.BoolKind:
|
|
|
+ toolOptions = append(toolOptions, mcp2.WithBoolean(string(input.Name()), propertyOption...))
|
|
|
+ case protoreflect.DoubleKind, protoreflect.FloatKind,
|
|
|
+ protoreflect.Sfixed64Kind, protoreflect.Sfixed32Kind,
|
|
|
+ protoreflect.Fixed64Kind, protoreflect.Fixed32Kind,
|
|
|
+ protoreflect.Sint64Kind, protoreflect.Sint32Kind,
|
|
|
+ protoreflect.Uint64Kind, protoreflect.Uint32Kind,
|
|
|
+ protoreflect.Int64Kind, protoreflect.Int32Kind:
|
|
|
+ toolOptions = append(toolOptions, mcp2.WithNumber(string(input.Name()), propertyOption...))
|
|
|
+ case protoreflect.MessageKind:
|
|
|
+ propertyOption = append(propertyOption, mcp2.Properties(getFiledMessageParamProperties(input.Message(), false)))
|
|
|
+ toolOptions = append(toolOptions, mcp2.WithObject(string(input.Name()), propertyOption...))
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
toolName := serviceName + "_" + string(method.Name())
|
|
|
@@ -133,7 +148,69 @@ func serverAddToolsByMethod(serviceName string, srv any, method protoreflect.Met
|
|
|
return &t, h
|
|
|
}
|
|
|
|
|
|
-func getFiledMessageParamProperties(message protoreflect.MessageDescriptor) map[string]any {
|
|
|
+func getInputArrayItems(input protoreflect.FieldDescriptor) map[string]any {
|
|
|
+ inputMap := make(map[string]any)
|
|
|
+ switch input.Kind() {
|
|
|
+ case protoreflect.StringKind:
|
|
|
+ inputMap["type"] = "string"
|
|
|
+ case protoreflect.BoolKind:
|
|
|
+ inputMap["type"] = "boolean"
|
|
|
+ case protoreflect.DoubleKind, protoreflect.FloatKind,
|
|
|
+ protoreflect.Sfixed64Kind, protoreflect.Sfixed32Kind,
|
|
|
+ protoreflect.Fixed64Kind, protoreflect.Fixed32Kind,
|
|
|
+ protoreflect.Sint64Kind, protoreflect.Sint32Kind,
|
|
|
+ protoreflect.Uint64Kind, protoreflect.Uint32Kind,
|
|
|
+ protoreflect.Int64Kind, protoreflect.Int32Kind:
|
|
|
+ inputMap["type"] = "number"
|
|
|
+ case protoreflect.MessageKind:
|
|
|
+ inputMap["type"] = "object"
|
|
|
+ propertiesMap := getFiledMessageParamProperties(input.Message(), true)
|
|
|
+ inputMap["properties"] = propertiesMap
|
|
|
+ }
|
|
|
+ return inputMap
|
|
|
+}
|
|
|
+
|
|
|
+func getInputMapProperties(input protoreflect.FieldDescriptor) (map[string]any, string) {
|
|
|
+ messageParamMap := make(map[string]any)
|
|
|
+ paramMap := make(map[string]any)
|
|
|
+ switch input.MapValue().Kind() {
|
|
|
+ case protoreflect.StringKind:
|
|
|
+ paramMap["type"] = "string"
|
|
|
+ case protoreflect.BoolKind:
|
|
|
+ paramMap["type"] = "boolean"
|
|
|
+ case protoreflect.DoubleKind, protoreflect.FloatKind,
|
|
|
+ protoreflect.Sfixed64Kind, protoreflect.Sfixed32Kind,
|
|
|
+ protoreflect.Fixed64Kind, protoreflect.Fixed32Kind,
|
|
|
+ protoreflect.Sint64Kind, protoreflect.Sint32Kind,
|
|
|
+ protoreflect.Uint64Kind, protoreflect.Uint32Kind,
|
|
|
+ protoreflect.Int64Kind, protoreflect.Int32Kind:
|
|
|
+ paramMap["type"] = "number"
|
|
|
+ case protoreflect.MessageKind:
|
|
|
+ paramMap["type"] = "object"
|
|
|
+ paramMap["properties"] = getFiledMessageParamProperties(input.Message(), false)
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
+ var keyType string
|
|
|
+ switch input.MapKey().Kind() {
|
|
|
+ case protoreflect.StringKind:
|
|
|
+ keyType = "string"
|
|
|
+ case protoreflect.BoolKind:
|
|
|
+ keyType = "boolean"
|
|
|
+ case protoreflect.DoubleKind, protoreflect.FloatKind,
|
|
|
+ protoreflect.Sfixed64Kind, protoreflect.Sfixed32Kind,
|
|
|
+ protoreflect.Fixed64Kind, protoreflect.Fixed32Kind,
|
|
|
+ protoreflect.Sint64Kind, protoreflect.Sint32Kind,
|
|
|
+ protoreflect.Uint64Kind, protoreflect.Uint32Kind,
|
|
|
+ protoreflect.Int64Kind, protoreflect.Int32Kind:
|
|
|
+ keyType = "number"
|
|
|
+ }
|
|
|
+ descriptionSuffix := fmt.Sprintf("(type of key: %s, type of value: %s)", keyType, paramMap["type"])
|
|
|
+ messageParamMap[string(input.Name())] = paramMap
|
|
|
+ return messageParamMap, descriptionSuffix
|
|
|
+}
|
|
|
+
|
|
|
+func getFiledMessageParamProperties(message protoreflect.MessageDescriptor, needRequired bool) map[string]any {
|
|
|
|
|
|
messageParamMap := make(map[string]any)
|
|
|
|
|
|
@@ -146,21 +223,40 @@ func getFiledMessageParamProperties(message protoreflect.MessageDescriptor) map[
|
|
|
inputDescription = inputOperation.GetDescription()
|
|
|
}
|
|
|
paramMap["description"] = inputDescription
|
|
|
+ if needRequired {
|
|
|
+ inputOperation2, _ := proto.GetExtension(input.Options(), annotations.E_FieldBehavior).([]annotations.FieldBehavior)
|
|
|
+ if inputOperation2 != nil && len(inputOperation2) > 0 && inputOperation2[0] == annotations.FieldBehavior_REQUIRED {
|
|
|
+ paramMap["required"] = true
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- switch input.Kind() {
|
|
|
- case protoreflect.StringKind:
|
|
|
- paramMap["type"] = "string"
|
|
|
- case protoreflect.BoolKind:
|
|
|
- paramMap["type"] = "boolean"
|
|
|
- case protoreflect.DoubleKind, protoreflect.FloatKind,
|
|
|
- protoreflect.Sfixed64Kind, protoreflect.Sfixed32Kind,
|
|
|
- protoreflect.Fixed64Kind, protoreflect.Fixed32Kind,
|
|
|
- protoreflect.Sint64Kind, protoreflect.Sint32Kind,
|
|
|
- protoreflect.Uint64Kind, protoreflect.Uint32Kind,
|
|
|
- protoreflect.Int64Kind, protoreflect.Int32Kind:
|
|
|
- paramMap["type"] = "number"
|
|
|
- default:
|
|
|
- break
|
|
|
+ if input.IsList() {
|
|
|
+ paramMap["type"] = "array"
|
|
|
+ paramMap["items"] = getInputArrayItems(input)
|
|
|
+ } else if input.IsMap() {
|
|
|
+ paramMap["type"] = "object"
|
|
|
+ var descriptionSuffix string
|
|
|
+ paramMap["additionalProperties"], descriptionSuffix = getInputMapProperties(input)
|
|
|
+ paramMap["description"] = inputDescription + descriptionSuffix
|
|
|
+ } else {
|
|
|
+ switch input.Kind() {
|
|
|
+ case protoreflect.StringKind:
|
|
|
+ paramMap["type"] = "string"
|
|
|
+ case protoreflect.BoolKind:
|
|
|
+ paramMap["type"] = "boolean"
|
|
|
+ case protoreflect.DoubleKind, protoreflect.FloatKind,
|
|
|
+ protoreflect.Sfixed64Kind, protoreflect.Sfixed32Kind,
|
|
|
+ protoreflect.Fixed64Kind, protoreflect.Fixed32Kind,
|
|
|
+ protoreflect.Sint64Kind, protoreflect.Sint32Kind,
|
|
|
+ protoreflect.Uint64Kind, protoreflect.Uint32Kind,
|
|
|
+ protoreflect.Int64Kind, protoreflect.Int32Kind:
|
|
|
+ paramMap["type"] = "number"
|
|
|
+ case protoreflect.MessageKind:
|
|
|
+ paramMap["type"] = "object"
|
|
|
+ paramMap["properties"] = getFiledMessageParamProperties(input.Message(), false)
|
|
|
+ default:
|
|
|
+ break
|
|
|
+ }
|
|
|
}
|
|
|
messageParamMap[string(input.Name())] = paramMap
|
|
|
}
|