refactor: replace jobs proxy with local controller and optimize model loading (#174)

* refactor: replace jobs proxy with local controller and optimize model loading

- Add local jobs controller that directly fetches upstream gateway with
  profile support and 30s timeout, replacing unreliable proxy catch-all
- Upstream errors (non-200) return 502 instead of leaking to frontend
- Switch loadModels() from fetchAvailableModels (slow, fetches all
  provider APIs) to fetchConfigModels (reads config.yaml only)
- Hide logo dance video in sidebar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: resolve TypeScript errors from previous refactor

- Remove unused imports (danceVideo, useTheme) in AppSidebar
- Map ConfigModelsResponse.groups to AvailableModelGroup[] format

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ekko
2026-04-24 09:57:30 +08:00
committed by GitHub
parent 88c7e25f78
commit f8283729ba
5 changed files with 116 additions and 10 deletions
@@ -9,14 +9,9 @@ import ProfileSelector from "./ProfileSelector.vue";
import LanguageSwitch from "./LanguageSwitch.vue";
import ThemeSwitch from "./ThemeSwitch.vue";
import { useSessionSearch } from '@/composables/useSessionSearch'
import danceVideoLight from "@/assets/dance-light.mp4";
import danceVideoDark from "@/assets/dance-dark.mp4";
import { useTheme } from "@/composables/useTheme";
import { changelog } from "@/data/changelog";
const { t } = useI18n();
const { isDark } = useTheme();
const message = useMessage();
const route = useRoute();
const router = useRouter();
@@ -66,7 +61,7 @@ function openChangelog() {
<div class="sidebar-logo" @click="router.push('/hermes/chat')">
<img :src="logoPath" alt="Hermes" class="logo-img" />
<span class="logo-text">Hermes</span>
<video class="logo-dance" :src="isDark ? danceVideoDark : danceVideoLight" autoplay loop muted playsinline />
<!-- <video class="logo-dance" :src="isDark ? danceVideoDark : danceVideoLight" autoplay loop muted playsinline /> -->
</div>
<nav class="sidebar-nav">
+10 -4
View File
@@ -1,6 +1,6 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { checkHealth, fetchAvailableModels, updateDefaultModel, triggerUpdate, type AvailableModelGroup } from '@/api/hermes/system'
import { checkHealth, fetchConfigModels, updateDefaultModel, triggerUpdate, type AvailableModelGroup } from '@/api/hermes/system'
const WEB_UI_VERSION = __APP_VERSION__
@@ -57,10 +57,16 @@ export const useAppStore = defineStore('app', () => {
async function loadModels() {
try {
const res = await fetchAvailableModels()
modelGroups.value = res.groups
const res = await fetchConfigModels()
modelGroups.value = res.groups.map(g => ({
provider: g.provider,
label: g.provider,
base_url: '',
models: g.models.map(m => typeof m === 'string' ? m : m.id),
api_key: '',
}))
selectedModel.value = res.default
selectedProvider.value = res.default_provider || ''
selectedProvider.value = ''
} catch {
// ignore
}