562261d13f
- Profile-aware proxy: inject API key from profile-specific .env, route requests via X-Hermes-Profile header - Remove auth.json dependency: built-in providers use .env, custom providers use config.yaml - Add allProviders field to available-models response with all hardcoded provider catalogs - Add Models tab in Settings for editing provider API keys (built-in → .env, custom → config.yaml) - Add PUT /api/config/providers/:poolKey for updating provider credentials - ProviderFormModal uses backend allProviders for preset dropdown - Gateway log format support: parse both agent and gateway log formats - Add webui server.log to log viewer with log rotation at 3MB - Fix provider delete loading state and OAuth provider cleanup - Setup script: require Node.js 23+, auto-upgrade if version too low Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
82 lines
2.1 KiB
TypeScript
82 lines
2.1 KiB
TypeScript
import { defineStore } from 'pinia'
|
|
import { ref, computed } from 'vue'
|
|
import * as systemApi from '@/api/hermes/system'
|
|
import type { AvailableModelGroup, CustomProvider } from '@/api/hermes/system'
|
|
import { useAppStore } from './app'
|
|
|
|
export const useModelsStore = defineStore('models', () => {
|
|
const providers = ref<AvailableModelGroup[]>([])
|
|
const allProviders = ref<AvailableModelGroup[]>([])
|
|
const defaultModel = ref('')
|
|
const loading = ref(false)
|
|
|
|
const customProviders = computed(() =>
|
|
providers.value.filter(g => g.provider.startsWith('custom:')),
|
|
)
|
|
|
|
const builtinProviders = computed(() =>
|
|
providers.value.filter(g => !g.provider.startsWith('custom:')),
|
|
)
|
|
|
|
const allModels = computed(() =>
|
|
providers.value.flatMap(g =>
|
|
g.models.map(m => ({
|
|
id: m,
|
|
provider: g.provider,
|
|
label: g.label,
|
|
base_url: g.base_url,
|
|
isDefault: m === defaultModel.value,
|
|
})),
|
|
),
|
|
)
|
|
|
|
async function fetchProviders() {
|
|
loading.value = true
|
|
try {
|
|
const res = await systemApi.fetchAvailableModels()
|
|
providers.value = res.groups
|
|
allProviders.value = res.allProviders
|
|
defaultModel.value = res.default
|
|
} catch (err) {
|
|
console.error('Failed to fetch providers:', err)
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function setDefaultModel(modelId: string, provider: string) {
|
|
await systemApi.updateDefaultModel({ default: modelId, provider })
|
|
defaultModel.value = modelId
|
|
const appStore = useAppStore()
|
|
appStore.loadModels()
|
|
}
|
|
|
|
async function addProvider(data: CustomProvider) {
|
|
await systemApi.addCustomProvider(data)
|
|
await fetchProviders()
|
|
const appStore = useAppStore()
|
|
appStore.loadModels()
|
|
}
|
|
|
|
async function removeProvider(name: string) {
|
|
await systemApi.removeCustomProvider(name)
|
|
await fetchProviders()
|
|
const appStore = useAppStore()
|
|
appStore.loadModels()
|
|
}
|
|
|
|
return {
|
|
providers,
|
|
allProviders,
|
|
defaultModel,
|
|
loading,
|
|
customProviders,
|
|
builtinProviders,
|
|
allModels,
|
|
fetchProviders,
|
|
setDefaultModel,
|
|
addProvider,
|
|
removeProvider,
|
|
}
|
|
})
|