Commit 326bd4d9 by Calcium-Ion Committed by GitHub

Merge pull request #1140 from RedwindA/gemini-tool-fix

fix: 完善Gemini渠道对tools中additionalProperties的清理
parents 16f49cfe 7aad5b04
...@@ -297,94 +297,111 @@ func cleanFunctionParameters(params interface{}) interface{} { ...@@ -297,94 +297,111 @@ func cleanFunctionParameters(params interface{}) interface{} {
return nil return nil
} }
paramMap, ok := params.(map[string]interface{}) switch v := params.(type) {
if !ok { case map[string]interface{}:
// Not a map, return as is (e.g., could be an array or primitive) // Create a copy to avoid modifying the original
return params cleanedMap := make(map[string]interface{})
} for k, val := range v {
cleanedMap[k] = val
}
// Create a copy to avoid modifying the original // Remove unsupported root-level fields
cleanedMap := make(map[string]interface{}) delete(cleanedMap, "default")
for k, v := range paramMap { delete(cleanedMap, "exclusiveMaximum")
cleanedMap[k] = v delete(cleanedMap, "exclusiveMinimum")
} delete(cleanedMap, "$schema")
delete(cleanedMap, "additionalProperties")
// Remove unsupported root-level fields // Check and clean 'format' for string types
delete(cleanedMap, "default") if propType, typeExists := cleanedMap["type"].(string); typeExists && propType == "string" {
delete(cleanedMap, "exclusiveMaximum") if formatValue, formatExists := cleanedMap["format"].(string); formatExists {
delete(cleanedMap, "exclusiveMinimum") if formatValue != "enum" && formatValue != "date-time" {
delete(cleanedMap, "$schema") delete(cleanedMap, "format")
delete(cleanedMap, "additionalProperties") }
}
}
// Clean properties // Clean properties
if props, ok := cleanedMap["properties"].(map[string]interface{}); ok && props != nil { if props, ok := cleanedMap["properties"].(map[string]interface{}); ok && props != nil {
cleanedProps := make(map[string]interface{}) cleanedProps := make(map[string]interface{})
for propName, propValue := range props { for propName, propValue := range props {
propMap, ok := propValue.(map[string]interface{}) cleanedProps[propName] = cleanFunctionParameters(propValue)
if !ok {
cleanedProps[propName] = propValue // Keep non-map properties
continue
} }
cleanedMap["properties"] = cleanedProps
}
// Create a copy of the property map // Recursively clean items in arrays
cleanedPropMap := make(map[string]interface{}) if items, ok := cleanedMap["items"].(map[string]interface{}); ok && items != nil {
for k, v := range propMap { cleanedMap["items"] = cleanFunctionParameters(items)
cleanedPropMap[k] = v }
// Also handle items if it's an array of schemas
if itemsArray, ok := cleanedMap["items"].([]interface{}); ok {
cleanedItemsArray := make([]interface{}, len(itemsArray))
for i, item := range itemsArray {
cleanedItemsArray[i] = cleanFunctionParameters(item)
} }
cleanedMap["items"] = cleanedItemsArray
}
// Remove unsupported fields // Recursively clean other schema composition keywords
delete(cleanedPropMap, "default") for _, field := range []string{"allOf", "anyOf", "oneOf"} {
delete(cleanedPropMap, "exclusiveMaximum") if nested, ok := cleanedMap[field].([]interface{}); ok {
delete(cleanedPropMap, "exclusiveMinimum") cleanedNested := make([]interface{}, len(nested))
delete(cleanedPropMap, "$schema") for i, item := range nested {
delete(cleanedPropMap, "additionalProperties") cleanedNested[i] = cleanFunctionParameters(item)
// Check and clean 'format' for string types
if propType, typeExists := cleanedPropMap["type"].(string); typeExists && propType == "string" {
if formatValue, formatExists := cleanedPropMap["format"].(string); formatExists {
if formatValue != "enum" && formatValue != "date-time" {
delete(cleanedPropMap, "format")
}
} }
cleanedMap[field] = cleanedNested
} }
}
// Recursively clean nested properties within this property if it's an object/array // Recursively clean patternProperties
// Check the type before recursing if patternProps, ok := cleanedMap["patternProperties"].(map[string]interface{}); ok {
if propType, typeExists := cleanedPropMap["type"].(string); typeExists && (propType == "object" || propType == "array") { cleanedPatternProps := make(map[string]interface{})
cleanedProps[propName] = cleanFunctionParameters(cleanedPropMap) for pattern, schema := range patternProps {
} else { cleanedPatternProps[pattern] = cleanFunctionParameters(schema)
cleanedProps[propName] = cleanedPropMap // Assign the cleaned map back if not recursing
} }
cleanedMap["patternProperties"] = cleanedPatternProps
}
// Recursively clean definitions
if definitions, ok := cleanedMap["definitions"].(map[string]interface{}); ok {
cleanedDefinitions := make(map[string]interface{})
for defName, defSchema := range definitions {
cleanedDefinitions[defName] = cleanFunctionParameters(defSchema)
}
cleanedMap["definitions"] = cleanedDefinitions
} }
cleanedMap["properties"] = cleanedProps
}
// Recursively clean items in arrays if needed (e.g., type: array, items: { ... }) // Recursively clean $defs (newer JSON Schema draft)
if items, ok := cleanedMap["items"].(map[string]interface{}); ok && items != nil { if defs, ok := cleanedMap["$defs"].(map[string]interface{}); ok {
cleanedMap["items"] = cleanFunctionParameters(items) cleanedDefs := make(map[string]interface{})
} for defName, defSchema := range defs {
// Also handle items if it's an array of schemas cleanedDefs[defName] = cleanFunctionParameters(defSchema)
if itemsArray, ok := cleanedMap["items"].([]interface{}); ok { }
cleanedItemsArray := make([]interface{}, len(itemsArray)) cleanedMap["$defs"] = cleanedDefs
for i, item := range itemsArray {
cleanedItemsArray[i] = cleanFunctionParameters(item)
} }
cleanedMap["items"] = cleanedItemsArray
}
// Recursively clean other schema composition keywords if necessary // Clean conditional keywords
for _, field := range []string{"allOf", "anyOf", "oneOf"} { for _, field := range []string{"if", "then", "else", "not"} {
if nested, ok := cleanedMap[field].([]interface{}); ok { if nested, ok := cleanedMap[field]; ok {
cleanedNested := make([]interface{}, len(nested)) cleanedMap[field] = cleanFunctionParameters(nested)
for i, item := range nested {
cleanedNested[i] = cleanFunctionParameters(item)
} }
cleanedMap[field] = cleanedNested
} }
}
return cleanedMap return cleanedMap
case []interface{}:
// Handle arrays of schemas
cleanedArray := make([]interface{}, len(v))
for i, item := range v {
cleanedArray[i] = cleanFunctionParameters(item)
}
return cleanedArray
default:
// Not a map or array, return as is (e.g., could be a primitive)
return params
}
} }
func removeAdditionalPropertiesWithDepth(schema interface{}, depth int) interface{} { func removeAdditionalPropertiesWithDepth(schema interface{}, depth int) interface{} {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment