mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-18 04:10:51 +08:00
refactor(util): optimize JSON schema processing and keyword removal logic
- Consolidated path-finding logic into a new `findPathsByFields` helper function. - Refactored repetitive loop structures to improve readability and performance. - Added depth-based sorting for deletion paths to ensure proper removal order.
This commit is contained in:
@@ -61,14 +61,20 @@ func cleanJSONSchema(jsonStr string, addPlaceholder bool) string {
|
|||||||
|
|
||||||
// removeKeywords removes all occurrences of specified keywords from the JSON schema.
|
// removeKeywords removes all occurrences of specified keywords from the JSON schema.
|
||||||
func removeKeywords(jsonStr string, keywords []string) string {
|
func removeKeywords(jsonStr string, keywords []string) string {
|
||||||
|
deletePaths := make([]string, 0)
|
||||||
|
pathsByField := findPathsByFields(jsonStr, keywords)
|
||||||
for _, key := range keywords {
|
for _, key := range keywords {
|
||||||
for _, p := range findPaths(jsonStr, key) {
|
for _, p := range pathsByField[key] {
|
||||||
if isPropertyDefinition(trimSuffix(p, "."+key)) {
|
if isPropertyDefinition(trimSuffix(p, "."+key)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
jsonStr, _ = sjson.Delete(jsonStr, p)
|
deletePaths = append(deletePaths, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sortByDepth(deletePaths)
|
||||||
|
for _, p := range deletePaths {
|
||||||
|
jsonStr, _ = sjson.Delete(jsonStr, p)
|
||||||
|
}
|
||||||
return jsonStr
|
return jsonStr
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,8 +241,9 @@ var unsupportedConstraints = []string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func moveConstraintsToDescription(jsonStr string) string {
|
func moveConstraintsToDescription(jsonStr string) string {
|
||||||
|
pathsByField := findPathsByFields(jsonStr, unsupportedConstraints)
|
||||||
for _, key := range unsupportedConstraints {
|
for _, key := range unsupportedConstraints {
|
||||||
for _, p := range findPaths(jsonStr, key) {
|
for _, p := range pathsByField[key] {
|
||||||
val := gjson.Get(jsonStr, p)
|
val := gjson.Get(jsonStr, p)
|
||||||
if !val.Exists() || val.IsObject() || val.IsArray() {
|
if !val.Exists() || val.IsObject() || val.IsArray() {
|
||||||
continue
|
continue
|
||||||
@@ -424,14 +431,21 @@ func removeUnsupportedKeywords(jsonStr string) string {
|
|||||||
"$schema", "$defs", "definitions", "const", "$ref", "additionalProperties",
|
"$schema", "$defs", "definitions", "const", "$ref", "additionalProperties",
|
||||||
"propertyNames", // Gemini doesn't support property name validation
|
"propertyNames", // Gemini doesn't support property name validation
|
||||||
)
|
)
|
||||||
|
|
||||||
|
deletePaths := make([]string, 0)
|
||||||
|
pathsByField := findPathsByFields(jsonStr, keywords)
|
||||||
for _, key := range keywords {
|
for _, key := range keywords {
|
||||||
for _, p := range findPaths(jsonStr, key) {
|
for _, p := range pathsByField[key] {
|
||||||
if isPropertyDefinition(trimSuffix(p, "."+key)) {
|
if isPropertyDefinition(trimSuffix(p, "."+key)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
jsonStr, _ = sjson.Delete(jsonStr, p)
|
deletePaths = append(deletePaths, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sortByDepth(deletePaths)
|
||||||
|
for _, p := range deletePaths {
|
||||||
|
jsonStr, _ = sjson.Delete(jsonStr, p)
|
||||||
|
}
|
||||||
// Remove x-* extension fields (e.g., x-google-enum-descriptions) that are not supported by Gemini API
|
// Remove x-* extension fields (e.g., x-google-enum-descriptions) that are not supported by Gemini API
|
||||||
jsonStr = removeExtensionFields(jsonStr)
|
jsonStr = removeExtensionFields(jsonStr)
|
||||||
return jsonStr
|
return jsonStr
|
||||||
@@ -581,6 +595,42 @@ func findPaths(jsonStr, field string) []string {
|
|||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findPathsByFields(jsonStr string, fields []string) map[string][]string {
|
||||||
|
set := make(map[string]struct{}, len(fields))
|
||||||
|
for _, field := range fields {
|
||||||
|
set[field] = struct{}{}
|
||||||
|
}
|
||||||
|
paths := make(map[string][]string, len(set))
|
||||||
|
walkForFields(gjson.Parse(jsonStr), "", set, paths)
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
|
func walkForFields(value gjson.Result, path string, fields map[string]struct{}, paths map[string][]string) {
|
||||||
|
switch value.Type {
|
||||||
|
case gjson.JSON:
|
||||||
|
value.ForEach(func(key, val gjson.Result) bool {
|
||||||
|
keyStr := key.String()
|
||||||
|
safeKey := escapeGJSONPathKey(keyStr)
|
||||||
|
|
||||||
|
var childPath string
|
||||||
|
if path == "" {
|
||||||
|
childPath = safeKey
|
||||||
|
} else {
|
||||||
|
childPath = path + "." + safeKey
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := fields[keyStr]; ok {
|
||||||
|
paths[keyStr] = append(paths[keyStr], childPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
walkForFields(val, childPath, fields, paths)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
case gjson.String, gjson.Number, gjson.True, gjson.False, gjson.Null:
|
||||||
|
// Terminal types - no further traversal needed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func sortByDepth(paths []string) {
|
func sortByDepth(paths []string) {
|
||||||
sort.Slice(paths, func(i, j int) bool { return len(paths[i]) > len(paths[j]) })
|
sort.Slice(paths, func(i, j int) bool { return len(paths[i]) > len(paths[j]) })
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user