mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-08 20:20:19 +08:00
fix(routing): filter providers by selected model
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { DEFAULT_ROUTING_POLICY_MODEL } from '../utils/routingPolicy'
|
||||
import { buildRoutingProviderSummaryQuery } from '../utils/providerQuery'
|
||||
|
||||
describe('routing provider query', () => {
|
||||
it('filters provider sorting by the selected GlobalModel ID', () => {
|
||||
expect(buildRoutingProviderSummaryQuery(
|
||||
'claude-fable-5-1',
|
||||
'global-claude-fable-5-1',
|
||||
'provider',
|
||||
)).toEqual({
|
||||
page: 1,
|
||||
page_size: 9999,
|
||||
model_id: 'global-claude-fable-5-1',
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps unified sorting and key sorting unfiltered', () => {
|
||||
const expected = { page: 1, page_size: 9999 }
|
||||
|
||||
expect(buildRoutingProviderSummaryQuery(DEFAULT_ROUTING_POLICY_MODEL, undefined, 'provider'))
|
||||
.toEqual(expected)
|
||||
expect(buildRoutingProviderSummaryQuery('claude-fable-5-1', 'global-claude-fable-5-1', 'global_key'))
|
||||
.toEqual(expected)
|
||||
})
|
||||
|
||||
it('does not fall back to all providers before a model ID is available', () => {
|
||||
expect(buildRoutingProviderSummaryQuery('claude-fable-5-1', undefined, 'provider')).toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -324,6 +324,7 @@ import {
|
||||
type RoutingPriorityMode,
|
||||
type RoutingSchedulingMode,
|
||||
} from '../utils/routingPolicy'
|
||||
import { buildRoutingProviderSummaryQuery } from '../utils/providerQuery'
|
||||
|
||||
interface ProviderPriorityRow {
|
||||
id: string
|
||||
@@ -367,6 +368,7 @@ interface GlobalKeySource {
|
||||
const props = defineProps<{
|
||||
config: RoutingGroupConfig
|
||||
model?: string
|
||||
modelId?: string
|
||||
priorityMode?: RoutingPriorityMode
|
||||
schedulingMode?: RoutingSchedulingMode
|
||||
showPriorityMode?: boolean
|
||||
@@ -398,6 +400,7 @@ const draggedKeyId = ref<string | null>(null)
|
||||
const dragOverKeyId = ref<string | null>(null)
|
||||
const providerMultiSelectEnabled = ref(false)
|
||||
const selectedProviderIds = ref<Set<string>>(new Set())
|
||||
let providerLoadRequestId = 0
|
||||
|
||||
const config = computed(() => normalizeRoutingGroupConfig(props.config))
|
||||
const targetModel = computed(() => props.model?.trim() || DEFAULT_ROUTING_POLICY_MODEL)
|
||||
@@ -505,6 +508,12 @@ watch(effectivePriorityMode, mode => {
|
||||
providerMultiSelectEnabled.value = false
|
||||
selectedProviderIds.value = new Set()
|
||||
}
|
||||
void loadProviders()
|
||||
})
|
||||
|
||||
// 父组件异步解析全局模型 ID 后,重新加载对应模型的提供商列表。
|
||||
watch([targetModel, () => props.modelId], () => {
|
||||
void loadProviders()
|
||||
})
|
||||
|
||||
watch(providerRows, rows => {
|
||||
@@ -561,16 +570,31 @@ function updateSchedulingMode(mode: RoutingSchedulingMode): void {
|
||||
}
|
||||
|
||||
async function loadProviders(): Promise<void> {
|
||||
const requestId = ++providerLoadRequestId
|
||||
loadingProviders.value = true
|
||||
loadError.value = null
|
||||
try {
|
||||
const response = await getProvidersSummary({ page: 1, page_size: 9999 })
|
||||
const query = buildRoutingProviderSummaryQuery(
|
||||
targetModel.value,
|
||||
props.modelId,
|
||||
effectivePriorityMode.value,
|
||||
)
|
||||
if (!query) {
|
||||
providers.value = []
|
||||
return
|
||||
}
|
||||
|
||||
const response = await getProvidersSummary(query)
|
||||
if (requestId !== providerLoadRequestId) return
|
||||
providers.value = response.items
|
||||
} catch (err) {
|
||||
if (requestId !== providerLoadRequestId) return
|
||||
loadError.value = parseApiError(err, '加载 Provider 失败')
|
||||
providers.value = []
|
||||
} finally {
|
||||
loadingProviders.value = false
|
||||
if (requestId === providerLoadRequestId) {
|
||||
loadingProviders.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { ProviderSummaryQuery } from '@/api/endpoints/providers'
|
||||
|
||||
import {
|
||||
DEFAULT_ROUTING_POLICY_MODEL,
|
||||
type RoutingPriorityMode,
|
||||
} from './routingPolicy'
|
||||
|
||||
const PROVIDER_SUMMARY_PAGE_SIZE = 9999
|
||||
|
||||
/**
|
||||
* 构造路由排序编辑器的提供商查询参数。
|
||||
* 按模型配置时必须使用 GlobalModel ID 过滤,避免把模型名称误当成 ID;统一调度和
|
||||
* Key 排序仍需要完整的提供商集合。
|
||||
*/
|
||||
export function buildRoutingProviderSummaryQuery(
|
||||
model: string | undefined,
|
||||
modelId: string | undefined,
|
||||
priorityMode: RoutingPriorityMode,
|
||||
): ProviderSummaryQuery | null {
|
||||
const query: ProviderSummaryQuery = {
|
||||
page: 1,
|
||||
page_size: PROVIDER_SUMMARY_PAGE_SIZE,
|
||||
}
|
||||
const isModelScoped = (model?.trim() || DEFAULT_ROUTING_POLICY_MODEL)
|
||||
!== DEFAULT_ROUTING_POLICY_MODEL
|
||||
|
||||
if (!isModelScoped || priorityMode !== 'provider') {
|
||||
return query
|
||||
}
|
||||
|
||||
const normalizedModelId = modelId?.trim()
|
||||
// 模型 ID 尚未由父组件解析出来时,不能回退到全量列表,否则会短暂显示错误的提供商。
|
||||
if (!normalizedModelId) return null
|
||||
|
||||
return {
|
||||
...query,
|
||||
model_id: normalizedModelId,
|
||||
}
|
||||
}
|
||||
@@ -745,6 +745,7 @@
|
||||
<RoutingPriorityPolicyEditor
|
||||
:config="activeConfigForReading"
|
||||
:model="activePerModelPolicy.model"
|
||||
:model-id="globalModelIdFor(activePerModelPolicy.model)"
|
||||
:priority-mode="modelPriorityMode(activePerModelPolicy.model)"
|
||||
:scheduling-mode="modelSchedulingMode(activePerModelPolicy.model)"
|
||||
:show-priority-mode="false"
|
||||
@@ -1458,6 +1459,11 @@ function globalModelLabel(modelName: string): string {
|
||||
return `${model.display_name} (${model.name})`
|
||||
}
|
||||
|
||||
function globalModelIdFor(modelName: string): string | undefined {
|
||||
const normalizedName = modelName.trim()
|
||||
return globalModels.value.find(item => item.name.trim() === normalizedName)?.id
|
||||
}
|
||||
|
||||
function replaceGroup(group: RoutingGroupRecord, select = true): void {
|
||||
const normalized = normalizeRecord(group)
|
||||
const index = groups.value.findIndex(item => item.id === normalized.id)
|
||||
|
||||
Reference in New Issue
Block a user