feat: 增加 Gemini 安全设置支持

- 新增 `SAFETY_SETTINGS` 配置项,允许用户通过环境变量或数据库配置 Gemini 模型的安全过滤级别。
- 更新后端服务 (`config.py`, `constants.py`, `gemini_routes.py`, `openai_routes.py`, `openai_chat_service.py`, `api_client.py`, `model_service.py`) 以支持和传递 `safety_settings` 参数。
- 在配置编辑器前端 (`config_editor.js`, `config_editor.html`) 添加了用于管理安全设置的用户界面。
- 将模型获取逻辑 (`model_service.py`, `api_client.py`) 改为异步。
- 优化 Service Worker (`service-worker.js`) 的缓存策略为 "cache then network"。

Bump version to 2.1.2
This commit is contained in:
snaily
2025-05-02 22:49:36 +08:00
parent 3480fa3b0f
commit 2225a40bbe
11 changed files with 282 additions and 71 deletions
+4 -9
View File
@@ -46,10 +46,6 @@ async def list_models(
):
"""获取可用的 Gemini 模型列表,并根据配置添加衍生模型(搜索、图像、非思考)。"""
operation_name = "list_gemini_models"
# 注意:此路由的错误处理相对复杂,涉及模型查找和修改,
# 使用通用错误处理可能隐藏部分逻辑错误。暂时保留原有结构,
# 但如果需要更统一的处理,可以将内部逻辑封装并应用 handle_route_errors。
# 这里仅添加日志分隔符。
logger.info("-" * 50 + operation_name + "-" * 50)
logger.info("Handling Gemini models list request")
@@ -59,8 +55,7 @@ async def list_models(
raise HTTPException(status_code=503, detail="No valid API keys available to fetch models.")
logger.info(f"Using API key: {api_key}")
# 假设 get_gemini_models 是同步的,如果不是需要 await
models_data = model_service.get_gemini_models(api_key)
models_data =await model_service.get_gemini_models(api_key)
if not models_data or "models" not in models_data:
raise HTTPException(status_code=500, detail="Failed to fetch base models list.")
@@ -76,7 +71,7 @@ async def list_models(
item["name"] = f"models/{base_name}{suffix}"
display_name = f'{item.get("displayName", base_name)}{display_suffix}'
item["displayName"] = display_name
item["description"] = display_name # 使用 display_name 作为描述
item["description"] = display_name
models_json["models"].append(item)
# 添加衍生模型
@@ -120,7 +115,7 @@ async def generate_content(
logger.debug(f"Request: \n{request.model_dump_json(indent=2)}")
logger.info(f"Using API key: {api_key}")
if not model_service.check_model_support(model_name):
if not await model_service.check_model_support(model_name):
raise HTTPException(status_code=400, detail=f"Model {model_name} is not supported")
response = await chat_service.generate_content(
@@ -150,7 +145,7 @@ async def stream_generate_content(
logger.debug(f"Request: \n{request.model_dump_json(indent=2)}")
logger.info(f"Using API key: {api_key}")
if not model_service.check_model_support(model_name):
if not await model_service.check_model_support(model_name):
raise HTTPException(status_code=400, detail=f"Model {model_name} is not supported")
response_stream = chat_service.stream_generate_content(
+2 -4
View File
@@ -54,9 +54,7 @@ async def list_models(
logger.info("Handling models list request")
api_key = await key_manager.get_first_valid_key()
logger.info(f"Using API key: {api_key}")
# 注意:这里假设 model_service.get_gemini_openai_models 是同步函数
# 如果它是异步的,需要 await
return model_service.get_gemini_openai_models(api_key)
return await model_service.get_gemini_openai_models(api_key)
@router.post("/v1/chat/completions")
@@ -83,7 +81,7 @@ async def chat_completion(
logger.info(f"Using API key: {current_api_key}")
# 检查模型支持性应在错误处理块内,以便捕获并记录错误
if not model_service.check_model_support(request.model):
if not await model_service.check_model_support(request.model):
# 使用 HTTPException,会被 handle_route_errors 捕获并记录
raise HTTPException(
status_code=400, detail=f"Model {request.model} is not supported"