From 1aa99887da6efa6a366943c019a5e2ef9147afdb Mon Sep 17 00:00:00 2001 From: LTbinglingfeng Date: Mon, 25 May 2026 23:52:18 +0800 Subject: [PATCH] fix(providers): honor authIndex for OpenAI discovery and connectivity test - useModelDiscovery: openaiCompatibility branch now forwards resolvedAuthIndex into modelsApi.fetchModelsViaApiCall, mirroring the gemini/codex/claude branches. Configs that rely on a backend-resolved auth index without a local plaintext key can now list models. - useConnectivityTest: runOpenAIKey accepts an authIndex fallback when entry.apiKey is empty, sets Authorization: Bearer $TOKEN$ in that case, and forwards authIndex on the /api-call request so the gateway can substitute the upstream token. - useModelDiscovery: reset stale results when baseUrl / apiKey / apiKeyEntries / headers / authIndex change, so reopening the discovery panel after editing fields re-fetches instead of showing the previous endpoint's models. --- .../sheets/forms/useConnectivityTest.ts | 11 ++++++++-- .../sheets/forms/useModelDiscovery.ts | 22 +++++++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/features/providers/sheets/forms/useConnectivityTest.ts b/src/features/providers/sheets/forms/useConnectivityTest.ts index f33eaf0..b09a150 100644 --- a/src/features/providers/sheets/forms/useConnectivityTest.ts +++ b/src/features/providers/sheets/forms/useConnectivityTest.ts @@ -199,7 +199,8 @@ export function useConnectivityTest( } const entry = apiKeyEntries?.[idx]; const entryKey = (entry?.apiKey ?? '').trim(); - if (!entryKey) { + const resolvedAuthIndex = (authIndex ?? '').trim() || undefined; + if (!entryKey && !resolvedAuthIndex) { updateOpenaiStatus(idx, { state: 'error', message: messages.apiKeyRequired, @@ -221,7 +222,11 @@ export function useConnectivityTest( ...parseHeadersText(entry?.headersText ?? ''), }; if (!hasHeader(headerObj, 'authorization')) { - headerObj.Authorization = `Bearer ${entryKey}`; + if (entryKey) { + headerObj.Authorization = `Bearer ${entryKey}`; + } else if (resolvedAuthIndex) { + headerObj.Authorization = 'Bearer $TOKEN$'; + } } updateOpenaiStatus(idx, { state: 'loading', message: '' }); @@ -229,6 +234,7 @@ export function useConnectivityTest( try { const result = await apiCallApi.request( { + authIndex: resolvedAuthIndex, method: 'POST', url: endpoint, header: headerObj, @@ -267,6 +273,7 @@ export function useConnectivityTest( }, [ apiKeyEntries, + authIndex, baseUrl, brand, formHeaders, diff --git a/src/features/providers/sheets/forms/useModelDiscovery.ts b/src/features/providers/sheets/forms/useModelDiscovery.ts index 874b5cb..4d9d98d 100644 --- a/src/features/providers/sheets/forms/useModelDiscovery.ts +++ b/src/features/providers/sheets/forms/useModelDiscovery.ts @@ -1,4 +1,4 @@ -import { useCallback, useState } from 'react'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { modelsApi } from '@/services/api'; import { buildHeaderObject } from '@/utils/headers'; import type { ModelInfo } from '@/utils/models'; @@ -119,7 +119,8 @@ export function useModelDiscovery( next = await modelsApi.fetchModelsViaApiCall( baseUrl, entryKey, - headers + headers, + resolvedAuthIndex ); } catch (firstErr) { // Some OpenAI-compatible endpoints expose /models without auth, or @@ -159,5 +160,22 @@ export function useModelDiscovery( setHasFetched(false); }, []); + const inputSignature = useMemo(() => { + const headerSig = formHeaders + .map((h) => `${h.key}:${h.value}`) + .join('|'); + const entriesSig = (apiKeyEntries ?? []) + .map((e) => `${e.apiKey ?? ''}::${e.headersText ?? ''}`) + .join('|'); + return `${baseUrl}||${apiKey ?? ''}||${fallbackApiKey ?? ''}||${authIndex ?? ''}||${headerSig}||${entriesSig}`; + }, [apiKey, apiKeyEntries, authIndex, baseUrl, fallbackApiKey, formHeaders]); + + const lastSignatureRef = useRef(inputSignature); + useEffect(() => { + if (lastSignatureRef.current === inputSignature) return; + lastSignatureRef.current = inputSignature; + reset(); + }, [inputSignature, reset]); + return { available, loading, error, models, hasFetched, fetch, reset }; }