auto-save 2026-05-27 17:24 (~4)

This commit is contained in:
2026-05-27 17:24:16 +08:00
parent 9ab541796b
commit fb939b8fcf
4 changed files with 93 additions and 13 deletions

View File

@@ -103,6 +103,49 @@ const isModelSupported = (model, provider) => {
return model.provider.includes(provider)
}
const normalizeRuntimeSizeOptions = (items = []) => {
if (!Array.isArray(items)) return []
return items
.map(item => {
const key = item?.value || item?.key || item?.id
if (!key) return null
return {
label: item.label || key,
key
}
})
.filter(Boolean)
}
const normalizeRuntimeImageModel = (item) => {
const key = item?.id || item?.model
if (!key) return null
const sizeOptions = normalizeRuntimeSizeOptions(item.size_options)
return {
label: item.label || item.model || key,
key,
provider: ['chatfire'],
sizes: sizeOptions.map(option => option.key),
sizeOptions,
qualities: [{ label: '标准', key: 'standard' }],
defaultParams: {
size: item.default_size || sizeOptions[0]?.key || 'auto',
quality: 'standard',
style: item.provider === 'ark_seedream' ? 'commercial' : 'vivid'
},
available: item.available !== false,
providerName: item.provider,
isRuntime: true
}
}
const mergeModels = (builtInModels, runtimeModels) => {
const byKey = new Map()
builtInModels.forEach(model => byKey.set(model.key, { ...model, isCustom: false }))
runtimeModels.forEach(model => byKey.set(model.key, { ...byKey.get(model.key), ...model, isCustom: false }))
return Array.from(byKey.values())
}
export const useModelStore = defineStore('model', () => {
// ============ Provider 状态 | Provider State ============
@@ -162,6 +205,7 @@ export const useModelStore = defineStore('model', () => {
const customChatModelsByProvider = ref(getStoredJson(STORAGE_KEYS.CUSTOM_CHAT_MODELS_BY_PROVIDER, {}))
const customImageModelsByProvider = ref(getStoredJson(STORAGE_KEYS.CUSTOM_IMAGE_MODELS_BY_PROVIDER, {}))
const customVideoModelsByProvider = ref(getStoredJson(STORAGE_KEYS.CUSTOM_VIDEO_MODELS_BY_PROVIDER, {}))
const runtimeImageModels = ref([])
// 选中的模型
const selectedChatModel = ref(getStored(STORAGE_KEYS.SELECTED_CHAT_MODEL, DEFAULT_CHAT_MODEL))
@@ -211,7 +255,7 @@ export const useModelStore = defineStore('model', () => {
])
const allImageModels = computed(() =>
IMAGE_MODELS.map(m => ({ ...m, isCustom: false }))
mergeModels(IMAGE_MODELS, runtimeImageModels.value)
)
const allVideoModels = computed(() =>
@@ -226,7 +270,7 @@ export const useModelStore = defineStore('model', () => {
)
const availableImageModels = computed(() =>
allImageModels.value.filter(m => isModelSupported(m, currentProvider.value))
allImageModels.value.filter(m => isModelSupported(m, currentProvider.value) && m.available !== false)
)
const availableVideoModels = computed(() =>
@@ -239,7 +283,8 @@ export const useModelStore = defineStore('model', () => {
const allImageModelOptions = computed(() =>
allImageModels.value.map(m => ({
label: m.label,
key: m.key
key: m.key,
disabled: m.available === false
}))
)
@@ -263,7 +308,8 @@ export const useModelStore = defineStore('model', () => {
const imageModelOptions = computed(() =>
availableImageModels.value.map(m => ({
label: m.label,
key: m.key
key: m.key,
disabled: m.available === false
}))
)
@@ -343,6 +389,23 @@ export const useModelStore = defineStore('model', () => {
const getImageModel = (key) => allImageModels.value.find(m => m.key === key)
const getVideoModel = (key) => allVideoModels.value.find(m => m.key === key)
const loadRuntimeModels = async () => {
try {
const response = await fetch('/api/health', { credentials: 'include' })
if (!response.ok) return false
const data = await response.json()
const imageOptions = data?.models?.image_options || []
runtimeImageModels.value = imageOptions
.filter(item => item?.id && item.id !== 'auto')
.map(normalizeRuntimeImageModel)
.filter(Boolean)
return true
} catch (err) {
console.warn('[model store] runtime model load failed', err)
return false
}
}
// ============ Methods: Get API Endpoints ============
// 获取图片端点
@@ -383,7 +446,7 @@ export const useModelStore = defineStore('model', () => {
provider: [provider]
}))
]
const image = IMAGE_MODELS
const image = allImageModels.value
.filter(m => isModelSupported(m, provider))
.map(m => ({ ...m, isCustom: false }))
const video = VIDEO_MODELS
@@ -500,6 +563,7 @@ export const useModelStore = defineStore('model', () => {
allChatModels,
allImageModels,
allVideoModels,
runtimeImageModels,
// Available models filtered by provider
availableChatModels,
@@ -551,6 +615,7 @@ export const useModelStore = defineStore('model', () => {
getChatModel,
getImageModel,
getVideoModel,
loadRuntimeModels,
// Get API endpoints
getImageEndpoint,

View File

@@ -319,6 +319,7 @@ const isApiConfigured = computed(() => !!modelStore.currentApiKey)
// Initialize models on page load | 页面加载时初始化模型
onMounted(() => {
loadAllModels()
modelStore.loadRuntimeModels()
})
// Chat templates | 问答模板