fix: clarify ai runtime errors
This commit is contained in:
@@ -112,7 +112,12 @@ class LLMService:
|
||||
raise ValueError(f'不支持的提供商类型: {provider.provider_type}')
|
||||
self._provider_cache[cache_key] = provider_instance
|
||||
|
||||
return self._provider_cache[cache_key], model.model_name
|
||||
provider_instance = self._provider_cache[cache_key]
|
||||
setattr(provider_instance, 'config_name', provider.name or provider.provider_type)
|
||||
setattr(provider_instance, 'config_id', str(provider.id))
|
||||
setattr(provider_instance, 'config_api_base', provider.api_base or '')
|
||||
|
||||
return provider_instance, model.model_name
|
||||
|
||||
def _get_provider_sync(self, model_id: str, model_data: dict) -> tuple:
|
||||
"""
|
||||
@@ -145,8 +150,71 @@ class LLMService:
|
||||
raise ValueError(f'不支持的提供商类型: {provider_type}')
|
||||
self._provider_cache[cache_key] = provider_instance
|
||||
|
||||
return self._provider_cache[cache_key], model_name
|
||||
provider_instance = self._provider_cache[cache_key]
|
||||
setattr(provider_instance, 'config_name', model_data.get('provider_name') or provider_type)
|
||||
setattr(provider_instance, 'config_id', str(provider_id))
|
||||
setattr(provider_instance, 'config_api_base', api_base or '')
|
||||
|
||||
return provider_instance, model_name
|
||||
|
||||
@staticmethod
|
||||
def _extract_upstream_message(error_text: str) -> str:
|
||||
import re
|
||||
|
||||
for pattern in (
|
||||
r"'message'\s*:\s*'([^']+)'",
|
||||
r'"message"\s*:\s*"([^"]+)"',
|
||||
):
|
||||
match = re.search(pattern, error_text)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return error_text[:240]
|
||||
|
||||
def _format_provider_error(
|
||||
self,
|
||||
exc: Exception,
|
||||
provider: Optional[BaseLLMProvider] = None,
|
||||
model_name: str = '',
|
||||
) -> str:
|
||||
error_text = str(exc)
|
||||
lower_text = error_text.lower()
|
||||
provider_name = (
|
||||
getattr(provider, 'config_name', '')
|
||||
or getattr(provider, 'provider_name', '')
|
||||
or '未知提供商'
|
||||
)
|
||||
model_text = model_name or '未知模型'
|
||||
|
||||
if (
|
||||
'401' in lower_text
|
||||
or 'unauthorized' in lower_text
|
||||
or 'invalid api key' in lower_text
|
||||
or 'incorrect api key' in lower_text
|
||||
or '无效的令牌' in error_text
|
||||
or '鉴权' in error_text
|
||||
):
|
||||
reason = '上游模型鉴权失败,API Key 无效或已过期'
|
||||
elif (
|
||||
'404' in lower_text
|
||||
or 'model_not_found' in lower_text
|
||||
or 'model not found' in lower_text
|
||||
or 'does not exist' in lower_text
|
||||
):
|
||||
reason = '上游模型不存在或当前账号无权访问该模型'
|
||||
elif 'timeout' in lower_text or 'timed out' in lower_text or '超时' in error_text:
|
||||
reason = '上游模型请求超时'
|
||||
elif 'rate limit' in lower_text or '429' in lower_text or 'quota' in lower_text:
|
||||
reason = '上游模型限流或额度不足'
|
||||
else:
|
||||
reason = '上游模型调用失败'
|
||||
|
||||
upstream_message = self._extract_upstream_message(error_text)
|
||||
return (
|
||||
f'{reason}:提供商 {provider_name},模型 {model_text}。'
|
||||
f'请在 AI 平台的模型提供商配置中检查 Base URL、API Key 和模型名称。'
|
||||
f'上游返回:{upstream_message}'
|
||||
)
|
||||
|
||||
def chat_with_provider(
|
||||
self,
|
||||
provider: BaseLLMProvider,
|
||||
@@ -197,7 +265,10 @@ class LLMService:
|
||||
**kwargs
|
||||
)
|
||||
|
||||
return provider.chat(llm_messages, config)
|
||||
try:
|
||||
return provider.chat(llm_messages, config)
|
||||
except Exception as exc:
|
||||
raise RuntimeError(self._format_provider_error(exc, provider, model_name)) from exc
|
||||
|
||||
def _convert_messages(self, messages: List[Dict]) -> List[LLMMessage]:
|
||||
"""转换消息格式,支持 tool 消息"""
|
||||
@@ -263,7 +334,10 @@ class LLMService:
|
||||
**kwargs
|
||||
)
|
||||
|
||||
return await provider.chat_async(llm_messages, config)
|
||||
try:
|
||||
return await provider.chat_async(llm_messages, config)
|
||||
except Exception as exc:
|
||||
raise RuntimeError(self._format_provider_error(exc, provider, model_name)) from exc
|
||||
|
||||
async def chat_stream(
|
||||
self,
|
||||
@@ -315,8 +389,11 @@ class LLMService:
|
||||
**kwargs
|
||||
)
|
||||
|
||||
async for chunk in provider.chat_stream(llm_messages, config):
|
||||
yield chunk
|
||||
try:
|
||||
async for chunk in provider.chat_stream(llm_messages, config):
|
||||
yield chunk
|
||||
except Exception as exc:
|
||||
raise RuntimeError(self._format_provider_error(exc, provider, model_name)) from exc
|
||||
|
||||
def chat_stream_sync(
|
||||
self,
|
||||
@@ -428,8 +505,11 @@ class LLMService:
|
||||
**kwargs
|
||||
)
|
||||
|
||||
for chunk in provider.chat_stream_sync(llm_messages, config):
|
||||
yield chunk
|
||||
try:
|
||||
for chunk in provider.chat_stream_sync(llm_messages, config):
|
||||
yield chunk
|
||||
except Exception as exc:
|
||||
raise RuntimeError(self._format_provider_error(exc, provider, model_name)) from exc
|
||||
|
||||
@staticmethod
|
||||
def get_available_providers() -> List[Dict]:
|
||||
|
||||
Reference in New Issue
Block a user