feat: add Hermes frontend types, API layer, and hooks (Phase 7)

- Add "hermes" to AppId union type and all exhaustive Record<AppId>
- Add HermesModelConfig, HermesAgentConfig, HermesEnvConfig types
- Add hermes field to VisibleApps, McpApps, ProxyTakeoverStatus
- Create src/lib/api/hermes.ts with Tauri invoke wrappers
- Create src/hooks/useHermes.ts with 5 query + 3 mutation hooks
- Register hermes in APP_IDS, APP_ICON_MAP (violet color scheme)
- Split MCP_SKILLS_APP_IDS into MCP_APP_IDS (includes hermes) and
  SKILLS_APP_IDS (excludes hermes, since Hermes has no Skills support)
- Wire hermes additive-mode into App.tsx (remove/duplicate handlers),
  ProviderList.tsx (live provider ID query + In Config badge),
  mutations.ts (cache invalidation on switch/add/delete)
- Add Hermes checkbox to McpFormModal
- Add basic hermes i18n keys (en/zh/ja)
This commit is contained in:
Jason
2026-04-15 17:41:33 +08:00
parent 576ff53a75
commit a0b585992a
23 changed files with 467 additions and 33 deletions
+13 -2
View File
@@ -25,6 +25,7 @@ import {
useOpenClawLiveProviderIds,
useOpenClawDefaultModel,
} from "@/hooks/useOpenClaw";
import { useHermesLiveProviderIds } from "@/hooks/useHermes";
import { useStreamCheck } from "@/hooks/useStreamCheck";
import { ProviderCard } from "@/components/providers/ProviderCard";
import { ProviderEmptyState } from "@/components/providers/ProviderEmptyState";
@@ -105,7 +106,10 @@ export function ProviderList({
appId === "openclaw",
);
// 判断供应商是否已添加到配置(累加模式应用:OpenCode/OpenClaw
// Hermes: 查询 live 配置中的供应商 ID 列表,用于判断 isInConfig
const { data: hermesLiveIds } = useHermesLiveProviderIds(appId === "hermes");
// 判断供应商是否已添加到配置(累加模式应用:OpenCode/OpenClaw/Hermes
const isProviderInConfig = useCallback(
(providerId: string): boolean => {
if (appId === "opencode") {
@@ -114,9 +118,12 @@ export function ProviderList({
if (appId === "openclaw") {
return openclawLiveIds?.includes(providerId) ?? false;
}
if (appId === "hermes") {
return hermesLiveIds?.includes(providerId) ?? false;
}
return true; // 其他应用始终返回 true
},
[appId, opencodeLiveIds, openclawLiveIds],
[appId, opencodeLiveIds, openclawLiveIds, hermesLiveIds],
);
// OpenClaw: query default model to determine which provider is default
@@ -229,6 +236,10 @@ export function ProviderList({
const count = await providersApi.importOpenClawFromLive();
return count > 0;
}
if (appId === "hermes") {
const count = await providersApi.importHermesFromLive();
return count > 0;
}
return providersApi.importDefault(appId);
},
onSuccess: (imported) => {
@@ -15,6 +15,7 @@ const ENDPOINT_TIMEOUT_SECS: Record<AppId, number> = {
gemini: 8,
opencode: 8,
openclaw: 8,
hermes: 8,
};
interface TestResult {