mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-02 15:52:26 +08:00
refactor: 重构模型测试错误解析逻辑并修复用量统计变量引用
- 将 ModelsTab 和 ModelAliasesTab 中重复的错误解析逻辑提取到 errorParser.ts - 添加 parseTestModelError 函数统一处理测试响应错误 - 为 testModel API 添加 TypeScript 类型定义 (TestModelRequest/TestModelResponse) - 修复 endpoint_checker.py 中 usage_data 变量引用错误
This commit is contained in:
@@ -61,12 +61,34 @@ export async function deleteProvider(providerId: string): Promise<{ message: str
|
|||||||
/**
|
/**
|
||||||
* 测试模型连接性
|
* 测试模型连接性
|
||||||
*/
|
*/
|
||||||
export async function testModel(data: {
|
export interface TestModelRequest {
|
||||||
provider_id: string
|
provider_id: string
|
||||||
model_name: string
|
model_name: string
|
||||||
api_key_id?: string
|
api_key_id?: string
|
||||||
message?: string
|
message?: string
|
||||||
}): Promise<any> {
|
api_format?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TestModelResponse {
|
||||||
|
success: boolean
|
||||||
|
error?: string
|
||||||
|
data?: {
|
||||||
|
response?: {
|
||||||
|
status_code?: number
|
||||||
|
error?: string | { message?: string }
|
||||||
|
choices?: Array<{ message?: { content?: string } }>
|
||||||
|
}
|
||||||
|
content_preview?: string
|
||||||
|
}
|
||||||
|
provider?: {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
display_name: string
|
||||||
|
}
|
||||||
|
model?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function testModel(data: TestModelRequest): Promise<TestModelResponse> {
|
||||||
const response = await client.post('/api/admin/provider-query/test-model', data)
|
const response = await client.post('/api/admin/provider-query/test-model', data)
|
||||||
return response.data
|
return response.data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -518,7 +518,7 @@ function initForm() {
|
|||||||
upstreamModels.value = []
|
upstreamModels.value = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理模型选择变更
|
// 处理模型选择变更
|
||||||
function handleModelChange(value: string) {
|
function handleModelChange(value: string) {
|
||||||
formData.value.modelId = value
|
formData.value.modelId = value
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ import {
|
|||||||
type ProviderModelAlias
|
type ProviderModelAlias
|
||||||
} from '@/api/endpoints'
|
} from '@/api/endpoints'
|
||||||
import { updateModel } from '@/api/endpoints/models'
|
import { updateModel } from '@/api/endpoints/models'
|
||||||
|
import { parseTestModelError } from '@/utils/errorParser'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
provider: any
|
provider: any
|
||||||
@@ -368,8 +369,6 @@ async function testMapping(group: any, mapping: any) {
|
|||||||
apiFormat = group.model.effective_api_format || group.model.api_format
|
apiFormat = group.model.effective_api_format || group.model.api_format
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`测试映射 ${mapping.name},使用 API Format: ${apiFormat}`)
|
|
||||||
|
|
||||||
const result = await testModel({
|
const result = await testModel({
|
||||||
provider_id: props.provider.id,
|
provider_id: props.provider.id,
|
||||||
model_name: mapping.name, // 使用映射名称进行测试
|
model_name: mapping.name, // 使用映射名称进行测试
|
||||||
@@ -388,37 +387,7 @@ async function testMapping(group: any, mapping: any) {
|
|||||||
showSuccess(`流式测试成功,预览: ${result.data.content_preview}`)
|
showSuccess(`流式测试成功,预览: ${result.data.content_preview}`)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 根据不同的错误类型显示更详细的信息
|
showError(`映射测试失败: ${parseTestModelError(result)}`)
|
||||||
let errorMsg = result.error || '测试失败'
|
|
||||||
|
|
||||||
// 检查HTTP状态码错误
|
|
||||||
if (result.data?.response?.status_code) {
|
|
||||||
const status = result.data.response.status_code
|
|
||||||
if (status === 403) {
|
|
||||||
errorMsg = '认证失败: API密钥无效或客户端类型不被允许'
|
|
||||||
} else if (status === 401) {
|
|
||||||
errorMsg = '认证失败: API密钥无效或已过期'
|
|
||||||
} else if (status === 404) {
|
|
||||||
errorMsg = '模型不存在: 请检查模型名称是否正确'
|
|
||||||
} else if (status === 429) {
|
|
||||||
errorMsg = '请求频率过高: 请稍后重试'
|
|
||||||
} else if (status >= 500) {
|
|
||||||
errorMsg = `服务器错误: HTTP ${status}`
|
|
||||||
} else {
|
|
||||||
errorMsg = `请求失败: HTTP ${status}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 尝试从错误响应中提取更多信息
|
|
||||||
if (result.data?.response?.error) {
|
|
||||||
if (typeof result.data.response.error === 'string') {
|
|
||||||
errorMsg = result.data.response.error
|
|
||||||
} else if (result.data.response.error?.message) {
|
|
||||||
errorMsg = result.data.response.error.message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showError(`映射测试失败: ${errorMsg}`)
|
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
const errorMsg = err.response?.data?.detail || err.message || '测试请求失败'
|
const errorMsg = err.response?.data?.detail || err.message || '测试请求失败'
|
||||||
|
|||||||
@@ -226,6 +226,7 @@ import Button from '@/components/ui/button.vue'
|
|||||||
import { useToast } from '@/composables/useToast'
|
import { useToast } from '@/composables/useToast'
|
||||||
import { getProviderModels, testModel, type Model } from '@/api/endpoints'
|
import { getProviderModels, testModel, type Model } from '@/api/endpoints'
|
||||||
import { updateModel } from '@/api/endpoints/models'
|
import { updateModel } from '@/api/endpoints/models'
|
||||||
|
import { parseTestModelError } from '@/utils/errorParser'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
provider: any
|
provider: any
|
||||||
@@ -415,37 +416,7 @@ async function testModelConnection(model: Model) {
|
|||||||
showSuccess(`流式测试成功,预览: ${result.data.content_preview}`)
|
showSuccess(`流式测试成功,预览: ${result.data.content_preview}`)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 根据不同的错误类型显示更详细的信息
|
showError(`模型测试失败: ${parseTestModelError(result)}`)
|
||||||
let errorMsg = result.error || '测试失败'
|
|
||||||
|
|
||||||
// 检查HTTP状态码错误
|
|
||||||
if (result.data?.response?.status_code) {
|
|
||||||
const status = result.data.response.status_code
|
|
||||||
if (status === 403) {
|
|
||||||
errorMsg = '认证失败: API密钥无效或客户端类型不被允许'
|
|
||||||
} else if (status === 401) {
|
|
||||||
errorMsg = '认证失败: API密钥无效或已过期'
|
|
||||||
} else if (status === 404) {
|
|
||||||
errorMsg = '模型不存在: 请检查模型名称是否正确'
|
|
||||||
} else if (status === 429) {
|
|
||||||
errorMsg = '请求频率过高: 请稍后重试'
|
|
||||||
} else if (status >= 500) {
|
|
||||||
errorMsg = `服务器错误: HTTP ${status}`
|
|
||||||
} else {
|
|
||||||
errorMsg = `请求失败: HTTP ${status}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 尝试从错误响应中提取更多信息
|
|
||||||
if (result.data?.response?.error) {
|
|
||||||
if (typeof result.data.response.error === 'string') {
|
|
||||||
errorMsg = result.data.response.error
|
|
||||||
} else if (result.data.response.error?.message) {
|
|
||||||
errorMsg = result.data.response.error.message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showError(`模型测试失败: ${errorMsg}`)
|
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
const errorMsg = err.response?.data?.detail || err.message || '测试请求失败'
|
const errorMsg = err.response?.data?.detail || err.message || '测试请求失败'
|
||||||
|
|||||||
@@ -198,3 +198,49 @@ export function parseApiErrorShort(err: unknown, defaultMessage: string = '操
|
|||||||
const lines = fullError.split('\n')
|
const lines = fullError.split('\n')
|
||||||
return lines[0] || defaultMessage
|
return lines[0] || defaultMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析模型测试响应的错误信息
|
||||||
|
* @param result 测试响应结果
|
||||||
|
* @returns 格式化的错误信息
|
||||||
|
*/
|
||||||
|
export function parseTestModelError(result: {
|
||||||
|
error?: string
|
||||||
|
data?: {
|
||||||
|
response?: {
|
||||||
|
status_code?: number
|
||||||
|
error?: string | { message?: string }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}): string {
|
||||||
|
let errorMsg = result.error || '测试失败'
|
||||||
|
|
||||||
|
// 检查HTTP状态码错误
|
||||||
|
if (result.data?.response?.status_code) {
|
||||||
|
const status = result.data.response.status_code
|
||||||
|
if (status === 403) {
|
||||||
|
errorMsg = '认证失败: API密钥无效或客户端类型不被允许'
|
||||||
|
} else if (status === 401) {
|
||||||
|
errorMsg = '认证失败: API密钥无效或已过期'
|
||||||
|
} else if (status === 404) {
|
||||||
|
errorMsg = '模型不存在: 请检查模型名称是否正确'
|
||||||
|
} else if (status === 429) {
|
||||||
|
errorMsg = '请求频率过高: 请稍后重试'
|
||||||
|
} else if (status >= 500) {
|
||||||
|
errorMsg = `服务器错误: HTTP ${status}`
|
||||||
|
} else {
|
||||||
|
errorMsg = `请求失败: HTTP ${status}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试从错误响应中提取更多信息
|
||||||
|
if (result.data?.response?.error) {
|
||||||
|
if (typeof result.data.response.error === 'string') {
|
||||||
|
errorMsg = result.data.response.error
|
||||||
|
} else if (result.data.response.error?.message) {
|
||||||
|
errorMsg = result.data.response.error.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errorMsg
|
||||||
|
}
|
||||||
|
|||||||
@@ -1243,7 +1243,7 @@ class EndpointCheckOrchestrator:
|
|||||||
api_format=api_format,
|
api_format=api_format,
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info(f"[{request.api_format}] Usage calculated successfully: {usage_data}")
|
logger.info(f"[{request.api_format}] Usage calculated successfully: {result.usage_data}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[{request.api_format}] Failed to calculate usage: {e}")
|
logger.error(f"[{request.api_format}] Failed to calculate usage: {e}")
|
||||||
import traceback
|
import traceback
|
||||||
|
|||||||
Reference in New Issue
Block a user