fix(stale): scope trace cache and ignore stale discovery

This commit is contained in:
Supra4E8C
2026-02-22 12:46:27 +08:00
Unverified
parent c75aeecec5
commit ecaaa397a3
3 changed files with 40 additions and 3 deletions
+9 -1
View File
@@ -118,6 +118,7 @@ export function AiProvidersCodexEditPage() {
const [modelDiscoverySearch, setModelDiscoverySearch] = useState('');
const [modelDiscoverySelected, setModelDiscoverySelected] = useState<Set<string>>(new Set());
const autoFetchSignatureRef = useRef<string>('');
const modelDiscoveryRequestIdRef = useRef(0);
const hasIndexParam = typeof params.index === 'string';
const editIndex = useMemo(() => parseIndexParam(params.index), [params.index]);
@@ -266,6 +267,7 @@ export function AiProvidersCodexEditPage() {
);
const fetchCodexModelDiscovery = useCallback(async () => {
const requestId = (modelDiscoveryRequestIdRef.current += 1);
setModelDiscoveryFetching(true);
setModelDiscoveryError('');
@@ -280,19 +282,25 @@ export function AiProvidersCodexEditPage() {
hasCustomAuthorization ? undefined : apiKey,
headerObject
);
if (modelDiscoveryRequestIdRef.current !== requestId) return;
setDiscoveredModels(list);
} catch (err: unknown) {
if (modelDiscoveryRequestIdRef.current !== requestId) return;
setDiscoveredModels([]);
const message = getErrorMessage(err);
setModelDiscoveryError(`${t('ai_providers.codex_models_fetch_error')}: ${message}`);
} finally {
setModelDiscoveryFetching(false);
if (modelDiscoveryRequestIdRef.current === requestId) {
setModelDiscoveryFetching(false);
}
}
}, [form.apiKey, form.baseUrl, form.headers, t]);
useEffect(() => {
if (!modelDiscoveryOpen) {
autoFetchSignatureRef.current = '';
modelDiscoveryRequestIdRef.current += 1;
setModelDiscoveryFetching(false);
return;
}
+9 -1
View File
@@ -112,6 +112,7 @@ export function AiProvidersGeminiEditPage() {
const [modelDiscoverySearch, setModelDiscoverySearch] = useState('');
const [modelDiscoverySelected, setModelDiscoverySelected] = useState<Set<string>>(new Set());
const autoFetchSignatureRef = useRef<string>('');
const modelDiscoveryRequestIdRef = useRef(0);
const hasIndexParam = typeof params.index === 'string';
const editIndex = useMemo(() => parseIndexParam(params.index), [params.index]);
@@ -244,6 +245,7 @@ export function AiProvidersGeminiEditPage() {
);
const fetchGeminiModelDiscovery = useCallback(async () => {
const requestId = (modelDiscoveryRequestIdRef.current += 1);
setModelDiscoveryFetching(true);
setModelDiscoveryError('');
const headerObject = buildHeaderObject(form.headers);
@@ -253,8 +255,10 @@ export function AiProvidersGeminiEditPage() {
form.apiKey.trim() || undefined,
headerObject
);
if (modelDiscoveryRequestIdRef.current !== requestId) return;
setDiscoveredModels(list);
} catch (err: unknown) {
if (modelDiscoveryRequestIdRef.current !== requestId) return;
setDiscoveredModels([]);
const message = err instanceof Error ? err.message : typeof err === 'string' ? err : '';
const hasCustomXGoogApiKey = Object.keys(headerObject).some(
@@ -271,13 +275,17 @@ export function AiProvidersGeminiEditPage() {
: '';
setModelDiscoveryError(`${t('ai_providers.gemini_models_fetch_error')}: ${message}${diag}`);
} finally {
setModelDiscoveryFetching(false);
if (modelDiscoveryRequestIdRef.current === requestId) {
setModelDiscoveryFetching(false);
}
}
}, [form.apiKey, form.baseUrl, form.headers, t]);
useEffect(() => {
if (!modelDiscoveryOpen) {
autoFetchSignatureRef.current = '';
modelDiscoveryRequestIdRef.current += 1;
setModelDiscoveryFetching(false);
return;
}
+22 -1
View File
@@ -490,6 +490,9 @@ export function LogsPage() {
const { t } = useTranslation();
const { showNotification, showConfirmation } = useNotificationStore();
const connectionStatus = useAuthStore((state) => state.connectionStatus);
const apiBase = useAuthStore((state) => state.apiBase);
const managementKey = useAuthStore((state) => state.managementKey);
const traceScopeKey = `${apiBase}::${managementKey}`;
const config = useConfigStore((state) => state.config);
const requestLogEnabled = config?.requestLog ?? false;
@@ -529,6 +532,7 @@ export function LogsPage() {
const pendingFullReloadRef = useRef(false);
const traceUsageLoadedAtRef = useRef(0);
const traceAuthLoadedAtRef = useRef(0);
const traceScopeKeyRef = useRef('');
// 保存最新时间戳用于增量获取
const latestTimestampRef = useRef<number>(0);
@@ -754,6 +758,15 @@ export function LogsPage() {
};
const loadTraceUsageDetails = useCallback(async () => {
if (traceScopeKeyRef.current !== traceScopeKey) {
traceScopeKeyRef.current = traceScopeKey;
traceUsageLoadedAtRef.current = 0;
traceAuthLoadedAtRef.current = 0;
setTraceUsageDetails([]);
setTraceAuthFileMap(new Map());
setTraceError('');
}
if (traceLoading) return;
const now = Date.now();
@@ -801,11 +814,18 @@ export function LogsPage() {
} finally {
setTraceLoading(false);
}
}, [t, traceLoading]);
}, [t, traceLoading, traceScopeKey]);
useEffect(() => {
if (connectionStatus === 'connected') {
latestTimestampRef.current = 0;
traceScopeKeyRef.current = traceScopeKey;
traceUsageLoadedAtRef.current = 0;
traceAuthLoadedAtRef.current = 0;
setTraceUsageDetails([]);
setTraceAuthFileMap(new Map());
setTraceLoading(false);
setTraceError('');
loadLogs(false);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -1158,6 +1178,7 @@ export function LogsPage() {
const openTraceModal = (line: ParsedLogLine) => {
if (!isTraceableRequestPath(line.path)) return;
cancelLongPress();
setTraceError('');
setTraceLogLine(line);
void loadTraceUsageDetails();
};