From 4dd11ab427d23365ec0d702cca3874c907d2579f Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 21 Apr 2026 22:40:53 +0800 Subject: [PATCH] fix(usage): support Hermes and OpenClaw in usage query modal Extend getProviderCredentials to read flat settingsConfig fields for Hermes (snake_case base_url / api_key) and OpenClaw (camelCase baseUrl / apiKey), so the "official balance" template auto-selects for matching providers like SiliconFlow. Also refactor the BALANCE and TOKEN_PLAN test paths in handleTest to reuse the precomputed providerCredentials instead of re-reading env.ANTHROPIC_* directly, which previously caused empty key errors for non-Claude apps even when the key was configured. --- src/components/UsageScriptModal.tsx | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/components/UsageScriptModal.tsx b/src/components/UsageScriptModal.tsx index 3acfcaba9..7571933e1 100644 --- a/src/components/UsageScriptModal.tsx +++ b/src/components/UsageScriptModal.tsx @@ -204,6 +204,18 @@ const UsageScriptModal: React.FC = ({ apiKey: env.GEMINI_API_KEY, baseUrl: env.GOOGLE_GEMINI_BASE_URL, }; + } else if (appId === "hermes") { + // Hermes: settingsConfig 顶层扁平(snake_case,对应 config.yaml) + return { + apiKey: (config as any).api_key, + baseUrl: (config as any).base_url, + }; + } else if (appId === "openclaw") { + // OpenClaw: settingsConfig 顶层扁平(camelCase,对应 openclaw.json) + return { + apiKey: (config as any).apiKey, + baseUrl: (config as any).baseUrl, + }; } return { apiKey: undefined, baseUrl: undefined }; } catch (error) { @@ -408,12 +420,8 @@ const UsageScriptModal: React.FC = ({ try { // 官方余额查询模板使用专用 API if (selectedTemplate === TEMPLATE_TYPES.BALANCE) { - const config = provider.settingsConfig as Record; - const baseUrl: string = config?.env?.ANTHROPIC_BASE_URL ?? ""; - const apiKey: string = - config?.env?.ANTHROPIC_AUTH_TOKEN ?? - config?.env?.ANTHROPIC_API_KEY ?? - ""; + const baseUrl = providerCredentials.baseUrl ?? ""; + const apiKey = providerCredentials.apiKey ?? ""; const { subscriptionApi } = await import("@/lib/api/subscription"); const result = await subscriptionApi.getBalance(baseUrl, apiKey); if (result.success && result.data && result.data.length > 0) { @@ -439,12 +447,8 @@ const UsageScriptModal: React.FC = ({ // Coding Plan 模板使用专用 API if (selectedTemplate === TEMPLATE_TYPES.TOKEN_PLAN) { - const config = provider.settingsConfig as Record; - const baseUrl: string = config?.env?.ANTHROPIC_BASE_URL ?? ""; - const apiKey: string = - config?.env?.ANTHROPIC_AUTH_TOKEN ?? - config?.env?.ANTHROPIC_API_KEY ?? - ""; + const baseUrl = providerCredentials.baseUrl ?? ""; + const apiKey = providerCredentials.apiKey ?? ""; const { subscriptionApi } = await import("@/lib/api/subscription"); const quota = await subscriptionApi.getCodingPlanQuota(baseUrl, apiKey); if (quota.success && quota.tiers.length > 0) {