mirror of
https://github.com/snailyp/gemini-balance.git
synced 2026-09-07 00:36:36 +08:00
feat: add JSON Schema cleaning function to remove unsupported fields in Gemini API
This commit is contained in:
@@ -28,6 +28,33 @@ def _has_image_parts(contents: List[Dict[str, Any]]) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_json_schema_properties(obj: Any) -> Any:
|
||||||
|
"""清理JSON Schema中Gemini API不支持的字段"""
|
||||||
|
if not isinstance(obj, dict):
|
||||||
|
return obj
|
||||||
|
|
||||||
|
# Gemini API不支持的JSON Schema字段
|
||||||
|
unsupported_fields = {
|
||||||
|
"exclusiveMaximum", "exclusiveMinimum", "const", "examples",
|
||||||
|
"contentEncoding", "contentMediaType", "if", "then", "else",
|
||||||
|
"allOf", "anyOf", "oneOf", "not", "definitions", "$schema",
|
||||||
|
"$id", "$ref", "$comment", "readOnly", "writeOnly"
|
||||||
|
}
|
||||||
|
|
||||||
|
cleaned = {}
|
||||||
|
for key, value in obj.items():
|
||||||
|
if key in unsupported_fields:
|
||||||
|
continue
|
||||||
|
if isinstance(value, dict):
|
||||||
|
cleaned[key] = _clean_json_schema_properties(value)
|
||||||
|
elif isinstance(value, list):
|
||||||
|
cleaned[key] = [_clean_json_schema_properties(item) for item in value]
|
||||||
|
else:
|
||||||
|
cleaned[key] = value
|
||||||
|
|
||||||
|
return cleaned
|
||||||
|
|
||||||
|
|
||||||
def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||||
"""构建工具"""
|
"""构建工具"""
|
||||||
|
|
||||||
@@ -40,7 +67,15 @@ def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|||||||
for k, v in item.items():
|
for k, v in item.items():
|
||||||
if k == "functionDeclarations" and v and isinstance(v, list):
|
if k == "functionDeclarations" and v and isinstance(v, list):
|
||||||
functions = record.get("functionDeclarations", [])
|
functions = record.get("functionDeclarations", [])
|
||||||
functions.extend(v)
|
# 清理每个函数声明中的不支持字段
|
||||||
|
cleaned_functions = []
|
||||||
|
for func in v:
|
||||||
|
if isinstance(func, dict):
|
||||||
|
cleaned_func = _clean_json_schema_properties(func)
|
||||||
|
cleaned_functions.append(cleaned_func)
|
||||||
|
else:
|
||||||
|
cleaned_functions.append(func)
|
||||||
|
functions.extend(cleaned_functions)
|
||||||
record["functionDeclarations"] = functions
|
record["functionDeclarations"] = functions
|
||||||
else:
|
else:
|
||||||
record[k] = v
|
record[k] = v
|
||||||
|
|||||||
@@ -26,16 +26,43 @@ from app.service.key.key_manager import KeyManager
|
|||||||
logger = get_openai_logger()
|
logger = get_openai_logger()
|
||||||
|
|
||||||
|
|
||||||
def _has_media_parts(contents: List[Dict[str, Any]]) -> bool:
|
def _has_media_parts(messages: List[Dict[str, Any]]) -> bool:
|
||||||
"""判断消息是否包含图片、音频或视频部分 (inline_data)"""
|
"""判断消息是否包含多媒体部分"""
|
||||||
for content in contents:
|
for message in messages:
|
||||||
if content and "parts" in content and isinstance(content["parts"], list):
|
if "parts" in message:
|
||||||
for part in content["parts"]:
|
for part in message["parts"]:
|
||||||
if isinstance(part, dict) and "inline_data" in part:
|
if "image_url" in part or "inline_data" in part:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_json_schema_properties(obj: Any) -> Any:
|
||||||
|
"""清理JSON Schema中Gemini API不支持的字段"""
|
||||||
|
if not isinstance(obj, dict):
|
||||||
|
return obj
|
||||||
|
|
||||||
|
# Gemini API不支持的JSON Schema字段
|
||||||
|
unsupported_fields = {
|
||||||
|
"exclusiveMaximum", "exclusiveMinimum", "const", "examples",
|
||||||
|
"contentEncoding", "contentMediaType", "if", "then", "else",
|
||||||
|
"allOf", "anyOf", "oneOf", "not", "definitions", "$schema",
|
||||||
|
"$id", "$ref", "$comment", "readOnly", "writeOnly"
|
||||||
|
}
|
||||||
|
|
||||||
|
cleaned = {}
|
||||||
|
for key, value in obj.items():
|
||||||
|
if key in unsupported_fields:
|
||||||
|
continue
|
||||||
|
if isinstance(value, dict):
|
||||||
|
cleaned[key] = _clean_json_schema_properties(value)
|
||||||
|
elif isinstance(value, list):
|
||||||
|
cleaned[key] = [_clean_json_schema_properties(item) for item in value]
|
||||||
|
else:
|
||||||
|
cleaned[key] = value
|
||||||
|
|
||||||
|
return cleaned
|
||||||
|
|
||||||
|
|
||||||
def _build_tools(
|
def _build_tools(
|
||||||
request: ChatRequest, messages: List[Dict[str, Any]]
|
request: ChatRequest, messages: List[Dict[str, Any]]
|
||||||
) -> List[Dict[str, Any]]:
|
) -> List[Dict[str, Any]]:
|
||||||
@@ -76,6 +103,8 @@ def _build_tools(
|
|||||||
):
|
):
|
||||||
function.pop("parameters", None)
|
function.pop("parameters", None)
|
||||||
|
|
||||||
|
# 清理函数中的不支持字段
|
||||||
|
function = _clean_json_schema_properties(function)
|
||||||
function_declarations.append(function)
|
function_declarations.append(function)
|
||||||
|
|
||||||
if function_declarations:
|
if function_declarations:
|
||||||
|
|||||||
@@ -28,6 +28,33 @@ def _has_image_parts(contents: List[Dict[str, Any]]) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _clean_json_schema_properties(obj: Any) -> Any:
|
||||||
|
"""清理JSON Schema中Gemini API不支持的字段"""
|
||||||
|
if not isinstance(obj, dict):
|
||||||
|
return obj
|
||||||
|
|
||||||
|
# Gemini API不支持的JSON Schema字段
|
||||||
|
unsupported_fields = {
|
||||||
|
"exclusiveMaximum", "exclusiveMinimum", "const", "examples",
|
||||||
|
"contentEncoding", "contentMediaType", "if", "then", "else",
|
||||||
|
"allOf", "anyOf", "oneOf", "not", "definitions", "$schema",
|
||||||
|
"$id", "$ref", "$comment", "readOnly", "writeOnly"
|
||||||
|
}
|
||||||
|
|
||||||
|
cleaned = {}
|
||||||
|
for key, value in obj.items():
|
||||||
|
if key in unsupported_fields:
|
||||||
|
continue
|
||||||
|
if isinstance(value, dict):
|
||||||
|
cleaned[key] = _clean_json_schema_properties(value)
|
||||||
|
elif isinstance(value, list):
|
||||||
|
cleaned[key] = [_clean_json_schema_properties(item) for item in value]
|
||||||
|
else:
|
||||||
|
cleaned[key] = value
|
||||||
|
|
||||||
|
return cleaned
|
||||||
|
|
||||||
|
|
||||||
def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
||||||
"""构建工具"""
|
"""构建工具"""
|
||||||
|
|
||||||
@@ -40,7 +67,15 @@ def _build_tools(model: str, payload: Dict[str, Any]) -> List[Dict[str, Any]]:
|
|||||||
for k, v in item.items():
|
for k, v in item.items():
|
||||||
if k == "functionDeclarations" and v and isinstance(v, list):
|
if k == "functionDeclarations" and v and isinstance(v, list):
|
||||||
functions = record.get("functionDeclarations", [])
|
functions = record.get("functionDeclarations", [])
|
||||||
functions.extend(v)
|
# 清理每个函数声明中的不支持字段
|
||||||
|
cleaned_functions = []
|
||||||
|
for func in v:
|
||||||
|
if isinstance(func, dict):
|
||||||
|
cleaned_func = _clean_json_schema_properties(func)
|
||||||
|
cleaned_functions.append(cleaned_func)
|
||||||
|
else:
|
||||||
|
cleaned_functions.append(func)
|
||||||
|
functions.extend(cleaned_functions)
|
||||||
record["functionDeclarations"] = functions
|
record["functionDeclarations"] = functions
|
||||||
else:
|
else:
|
||||||
record[k] = v
|
record[k] = v
|
||||||
|
|||||||
Reference in New Issue
Block a user