Compare commits

...

2 Commits

Author SHA1 Message Date
openhands
f9b4d31c4a Fix linting errors in feedback query optimization
- Remove console.warn statements to fix no-console linting warnings
- Fix TanStack Query exhaustive-deps error by removing problematic cached data logic
- Maintain the core optimization features while ensuring code quality
2025-07-31 14:27:34 +00:00
openhands
348809f189 Fix duplicate GET requests to feedback/conversation/{id} endpoint 2025-07-30 17:37:42 +00:00
4 changed files with 60 additions and 18 deletions

View File

@@ -153,12 +153,38 @@ class OpenHands {
eventId: number,
): Promise<{ exists: boolean; rating?: number; reason?: string }> {
try {
// Use a cache to prevent duplicate requests for the same data
const cacheKey = `feedback_${conversationId}_${eventId}`;
const cachedData = sessionStorage.getItem(cacheKey);
if (cachedData) {
try {
const parsedData = JSON.parse(cachedData);
// Only use cached data if feedback exists
if (parsedData.exists) {
return parsedData;
}
} catch (e) {
// Invalid JSON in cache, ignore and proceed with request
}
}
const url = `/feedback/conversation/${conversationId}/${eventId}`;
const { data } = await openHands.get<{
exists: boolean;
rating?: number;
reason?: string;
}>(url);
// Cache the response if feedback exists
if (data.exists) {
try {
sessionStorage.setItem(cacheKey, JSON.stringify(data));
} catch (e) {
// Ignore storage errors
}
}
return data;
} catch (error) {
// Error checking if feedback exists

View File

@@ -63,23 +63,18 @@ export function EventMessage({
const { data: config } = useConfig();
// Only fetch feedback data if we're actually going to show the LikertScale
const shouldShowFeedback =
config?.APP_MODE === "saas" &&
(isErrorObservation(event) ? isInLast10Actions : isLastMessage);
const {
data: feedbackData = { exists: false },
isLoading: isCheckingFeedback,
} = useFeedbackExists(event.id);
} = useFeedbackExists(shouldShowFeedback ? event.id : undefined);
const renderLikertScale = () => {
if (config?.APP_MODE !== "saas" || isCheckingFeedback) {
return null;
}
// For error observations, show if in last 10 actions
// For other events, show only if it's the last message
const shouldShow = isErrorObservation(event)
? isInLast10Actions
: isLastMessage;
if (!shouldShow) {
if (!shouldShowFeedback || isCheckingFeedback) {
return null;
}

View File

@@ -2,6 +2,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import OpenHands from "#/api/open-hands";
import { useConversationId } from "#/hooks/use-conversation-id";
import { FeedbackData } from "../query/use-feedback-exists";
type SubmitConversationFeedbackArgs = {
rating: number;
@@ -22,12 +23,28 @@ export const useSubmitConversationFeedback = () => {
eventId,
reason,
),
onSuccess: (_, { eventId }) => {
// Invalidate the feedback existence query to trigger a refetch
onSuccess: (_, { eventId, rating, reason }) => {
if (eventId) {
queryClient.invalidateQueries({
queryKey: ["feedback", "exists", conversationId, eventId],
// Update the cache directly instead of invalidating to prevent refetch
const queryKey = ["feedback", "exists", conversationId, eventId];
// Update the React Query cache
queryClient.setQueryData<FeedbackData>(queryKey, {
exists: true,
rating,
reason,
});
// Also update the sessionStorage cache
try {
const cacheKey = `feedback_${conversationId}_${eventId}`;
sessionStorage.setItem(
cacheKey,
JSON.stringify({ exists: true, rating, reason }),
);
} catch (e) {
// Ignore storage errors
}
}
},
onError: (error) => {

View File

@@ -20,7 +20,11 @@ export const useFeedbackExists = (eventId?: number) => {
return OpenHands.checkFeedbackExists(conversationId, eventId);
},
enabled: !!eventId && config?.APP_MODE === "saas",
staleTime: 1000 * 60 * 5, // 5 minutes
gcTime: 1000 * 60 * 15, // 15 minutes
staleTime: 1000 * 60 * 60, // Increase to 60 minutes since feedback rarely changes
gcTime: 1000 * 60 * 60 * 2, // 2 hours
// Prevent refetching on window focus to reduce duplicate requests
refetchOnWindowFocus: false,
// Prevent refetching on reconnect to reduce duplicate requests
refetchOnReconnect: false,
});
};