mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-06 07:56:52 +08:00
Merge remote-tracking branch 'origin/v2' into v2
This commit is contained in:
@@ -48,7 +48,7 @@ class LlmProviderAuthStartRequest(BaseModel):
|
|||||||
method: str
|
method: str
|
||||||
|
|
||||||
|
|
||||||
def _sanitize_llm_test_error(message: str, api_key: Optional[str] = None) -> str:
|
def _sanitize_llm_error(message: str, api_key: Optional[str] = None) -> str:
|
||||||
"""
|
"""
|
||||||
清理错误信息中的敏感字段,避免回显密钥。
|
清理错误信息中的敏感字段,避免回显密钥。
|
||||||
"""
|
"""
|
||||||
@@ -70,11 +70,14 @@ def _sanitize_llm_test_error(message: str, api_key: Optional[str] = None) -> str
|
|||||||
)
|
)
|
||||||
|
|
||||||
normalized_message = sanitized.lower().replace("_", "").replace(" ", "")
|
normalized_message = sanitized.lower().replace("_", "").replace(" ", "")
|
||||||
if "str" in normalized_message and "modeldump" in normalized_message:
|
if "str" in normalized_message and (
|
||||||
|
"modeldump" in normalized_message
|
||||||
|
or "setprivateattributes" in normalized_message
|
||||||
|
):
|
||||||
return (
|
return (
|
||||||
"服务返回内容不是兼容的模型响应,"
|
"服务返回内容不是兼容的模型响应,请检查基础地址是否填写为 "
|
||||||
"请检查基础地址是否填写为 API Base URL,不要填写网页地址或完整的 "
|
"API Base URL,如果服务要求 /v1 等版本路径,请包含在基础地址中,"
|
||||||
"chat/completions 路径"
|
"不要填写网页地址或完整的 chat/completions 路径"
|
||||||
)
|
)
|
||||||
return sanitized
|
return sanitized
|
||||||
|
|
||||||
@@ -113,7 +116,10 @@ async def get_llm_models(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
return schemas.Response(success=False, message=str(err))
|
return schemas.Response(
|
||||||
|
success=False,
|
||||||
|
message=_sanitize_llm_error(str(err), api_key),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/providers", summary="获取LLM提供商目录", response_model=schemas.Response)
|
@router.get("/providers", summary="获取LLM提供商目录", response_model=schemas.Response)
|
||||||
@@ -312,5 +318,5 @@ async def llm_test(
|
|||||||
except Exception as err:
|
except Exception as err:
|
||||||
return schemas.Response(
|
return schemas.Response(
|
||||||
success=False,
|
success=False,
|
||||||
message=_sanitize_llm_test_error(str(err), payload.api_key),
|
message=_sanitize_llm_error(str(err), payload.api_key),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -24,3 +24,54 @@ def test_llm_test_maps_internal_model_dump_error_to_base_url_hint():
|
|||||||
assert "基础地址" in resp.message
|
assert "基础地址" in resp.message
|
||||||
assert "API Base URL" in resp.message
|
assert "API Base URL" in resp.message
|
||||||
assert "model_dump" not in resp.message
|
assert "model_dump" not in resp.message
|
||||||
|
|
||||||
|
|
||||||
|
def test_llm_test_maps_internal_private_attribute_error_to_base_url_hint():
|
||||||
|
"""LLM 测试遇到 SDK 内部属性错误时应提示检查基础地址。"""
|
||||||
|
with patch.object(llm_endpoint.settings, "AI_AGENT_ENABLE", True), patch.object(
|
||||||
|
llm_endpoint.settings, "LLM_PROVIDER", "openai"
|
||||||
|
), patch.object(llm_endpoint.settings, "LLM_MODEL", "gpt-4o-mini"), patch.object(
|
||||||
|
llm_endpoint.settings, "LLM_API_KEY", "sk-test"
|
||||||
|
), patch.object(
|
||||||
|
llm_endpoint.LLMHelper,
|
||||||
|
"test_current_settings",
|
||||||
|
AsyncMock(
|
||||||
|
side_effect=AttributeError(
|
||||||
|
"'str' object has no attribute '_set_private_attributes'"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
create=True,
|
||||||
|
):
|
||||||
|
resp = asyncio.run(llm_endpoint.llm_test(_="token"))
|
||||||
|
|
||||||
|
assert not resp.success
|
||||||
|
assert "基础地址" in resp.message
|
||||||
|
assert "API Base URL" in resp.message
|
||||||
|
assert "_set_private_attributes" not in resp.message
|
||||||
|
|
||||||
|
|
||||||
|
def test_llm_models_maps_internal_private_attribute_error_to_base_url_hint():
|
||||||
|
"""LLM 模型列表遇到 SDK 内部属性错误时应提示检查基础地址。"""
|
||||||
|
with patch.object(
|
||||||
|
llm_endpoint.LLMHelper,
|
||||||
|
"get_models",
|
||||||
|
AsyncMock(
|
||||||
|
side_effect=AttributeError(
|
||||||
|
"'str' object has no attribute '_set_private_attributes'"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
create=True,
|
||||||
|
):
|
||||||
|
resp = asyncio.run(
|
||||||
|
llm_endpoint.get_llm_models(
|
||||||
|
provider="openai",
|
||||||
|
api_key="sk-test",
|
||||||
|
base_url="https://example.com",
|
||||||
|
_="token",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assert not resp.success
|
||||||
|
assert "基础地址" in resp.message
|
||||||
|
assert "API Base URL" in resp.message
|
||||||
|
assert "_set_private_attributes" not in resp.message
|
||||||
|
|||||||
Reference in New Issue
Block a user