mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-02 15:52:26 +08:00
refactor: 将模型测试功能从 ModelsTab 移到 KeyAllowedModelsDialog
This commit is contained in:
@@ -116,6 +116,19 @@
|
|||||||
{{ model.global_model_name }}
|
{{ model.global_model_name }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 测试按钮 -->
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
class="h-7 w-7 shrink-0"
|
||||||
|
title="测试模型连接"
|
||||||
|
:disabled="testingModelName === model.global_model_name"
|
||||||
|
@click.stop="testModelConnection(model)"
|
||||||
|
>
|
||||||
|
<Loader2 v-if="testingModelName === model.global_model_name" class="w-3.5 h-3.5 animate-spin" />
|
||||||
|
<Play v-else class="w-3.5 h-3.5" />
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -148,16 +161,17 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, watch } from 'vue'
|
import { ref, computed, watch } from 'vue'
|
||||||
import { Box, Loader2, Settings2 } from 'lucide-vue-next'
|
import { Box, Loader2, Settings2, Play } from 'lucide-vue-next'
|
||||||
import { Dialog } from '@/components/ui'
|
import { Dialog } from '@/components/ui'
|
||||||
import Button from '@/components/ui/button.vue'
|
import Button from '@/components/ui/button.vue'
|
||||||
import Badge from '@/components/ui/badge.vue'
|
import Badge from '@/components/ui/badge.vue'
|
||||||
import Checkbox from '@/components/ui/checkbox.vue'
|
import Checkbox from '@/components/ui/checkbox.vue'
|
||||||
import { useToast } from '@/composables/useToast'
|
import { useToast } from '@/composables/useToast'
|
||||||
import { parseApiError } from '@/utils/errorParser'
|
import { parseApiError, parseTestModelError } from '@/utils/errorParser'
|
||||||
import {
|
import {
|
||||||
updateEndpointKey,
|
updateEndpointKey,
|
||||||
getProviderAvailableSourceModels,
|
getProviderAvailableSourceModels,
|
||||||
|
testModel,
|
||||||
type EndpointAPIKey,
|
type EndpointAPIKey,
|
||||||
type ProviderAvailableSourceModel
|
type ProviderAvailableSourceModel
|
||||||
} from '@/api/endpoints'
|
} from '@/api/endpoints'
|
||||||
@@ -181,6 +195,7 @@ const loadingModels = ref(false)
|
|||||||
const availableModels = ref<ProviderAvailableSourceModel[]>([])
|
const availableModels = ref<ProviderAvailableSourceModel[]>([])
|
||||||
const selectedModels = ref<string[]>([])
|
const selectedModels = ref<string[]>([])
|
||||||
const initialModels = ref<string[]>([])
|
const initialModels = ref<string[]>([])
|
||||||
|
const testingModelName = ref<string | null>(null)
|
||||||
|
|
||||||
// 监听对话框打开
|
// 监听对话框打开
|
||||||
watch(() => props.open, (open) => {
|
watch(() => props.open, (open) => {
|
||||||
@@ -268,6 +283,32 @@ function clearModels() {
|
|||||||
selectedModels.value = []
|
selectedModels.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 测试模型连接
|
||||||
|
async function testModelConnection(model: ProviderAvailableSourceModel) {
|
||||||
|
if (!props.providerId || !props.apiKey || testingModelName.value) return
|
||||||
|
|
||||||
|
testingModelName.value = model.global_model_name
|
||||||
|
try {
|
||||||
|
const result = await testModel({
|
||||||
|
provider_id: props.providerId,
|
||||||
|
model_name: model.provider_model_name,
|
||||||
|
api_key_id: props.apiKey.id,
|
||||||
|
message: "hello"
|
||||||
|
})
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
success(`模型 "${model.display_name}" 测试成功`)
|
||||||
|
} else {
|
||||||
|
showError(`模型测试失败: ${parseTestModelError(result)}`)
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
const errorMsg = err.response?.data?.detail || err.message || '测试请求失败'
|
||||||
|
showError(`模型测试失败: ${errorMsg}`)
|
||||||
|
} finally {
|
||||||
|
testingModelName.value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function areArraysEqual(a: string[], b: string[]): boolean {
|
function areArraysEqual(a: string[], b: string[]): boolean {
|
||||||
if (a.length !== b.length) return false
|
if (a.length !== b.length) return false
|
||||||
const sortedA = [...a].sort()
|
const sortedA = [...a].sort()
|
||||||
|
|||||||
@@ -156,17 +156,6 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="align-top px-4 py-3">
|
<td class="align-top px-4 py-3">
|
||||||
<div class="flex justify-center gap-1.5">
|
<div class="flex justify-center gap-1.5">
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
class="h-8 w-8"
|
|
||||||
title="测试模型"
|
|
||||||
:disabled="testingModelId === model.id"
|
|
||||||
@click="testModelConnection(model)"
|
|
||||||
>
|
|
||||||
<Loader2 v-if="testingModelId === model.id" class="w-3.5 h-3.5 animate-spin" />
|
|
||||||
<Play v-else class="w-3.5 h-3.5" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
@@ -220,14 +209,13 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import { Box, Edit, Trash2, Layers, Eye, Wrench, Zap, Brain, Power, Copy, Image, Loader2, Play } from 'lucide-vue-next'
|
import { Box, Edit, Trash2, Layers, Eye, Wrench, Zap, Brain, Power, Copy, Image } from 'lucide-vue-next'
|
||||||
import Card from '@/components/ui/card.vue'
|
import Card from '@/components/ui/card.vue'
|
||||||
import Button from '@/components/ui/button.vue'
|
import Button from '@/components/ui/button.vue'
|
||||||
import { useToast } from '@/composables/useToast'
|
import { useToast } from '@/composables/useToast'
|
||||||
import { useClipboard } from '@/composables/useClipboard'
|
import { useClipboard } from '@/composables/useClipboard'
|
||||||
import { getProviderModels, testModel, type Model } from '@/api/endpoints'
|
import { getProviderModels, 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
|
||||||
@@ -246,7 +234,6 @@ const { copyToClipboard } = useClipboard()
|
|||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const models = ref<Model[]>([])
|
const models = ref<Model[]>([])
|
||||||
const togglingModelId = ref<string | null>(null)
|
const togglingModelId = ref<string | null>(null)
|
||||||
const testingModelId = ref<string | null>(null)
|
|
||||||
|
|
||||||
// 按名称排序的模型列表
|
// 按名称排序的模型列表
|
||||||
const sortedModels = computed(() => {
|
const sortedModels = computed(() => {
|
||||||
@@ -390,39 +377,6 @@ async function toggleModelActive(model: Model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 测试模型连接性
|
|
||||||
async function testModelConnection(model: Model) {
|
|
||||||
if (testingModelId.value) return
|
|
||||||
|
|
||||||
testingModelId.value = model.id
|
|
||||||
try {
|
|
||||||
const result = await testModel({
|
|
||||||
provider_id: props.provider.id,
|
|
||||||
model_name: model.provider_model_name,
|
|
||||||
message: "hello"
|
|
||||||
})
|
|
||||||
|
|
||||||
if (result.success) {
|
|
||||||
showSuccess(`模型 "${model.provider_model_name}" 测试成功`)
|
|
||||||
|
|
||||||
// 如果有响应内容,可以显示更多信息
|
|
||||||
if (result.data?.response?.choices?.[0]?.message?.content) {
|
|
||||||
const content = result.data.response.choices[0].message.content
|
|
||||||
showSuccess(`测试成功,响应: ${content.substring(0, 100)}${content.length > 100 ? '...' : ''}`)
|
|
||||||
} else if (result.data?.content_preview) {
|
|
||||||
showSuccess(`流式测试成功,预览: ${result.data.content_preview}`)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
showError(`模型测试失败: ${parseTestModelError(result)}`)
|
|
||||||
}
|
|
||||||
} catch (err: any) {
|
|
||||||
const errorMsg = err.response?.data?.detail || err.message || '测试请求失败'
|
|
||||||
showError(`模型测试失败: ${errorMsg}`)
|
|
||||||
} finally {
|
|
||||||
testingModelId.value = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadModels()
|
loadModels()
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user