Skip to content

Commit 247d732

Browse files
natagh23claude
andcommitted
fix(prompts): bound version-history refetch cost to actual changes
useInfiniteQuery refetches every already-loaded page sequentially on any trigger, and the Diff/Deploy menus can load many pages for large prompts — so the prior refetchInterval/refetchOnWindowFocus multiplied request volume by however many pages a session had loaded. Drop those from the infinite query and instead poll the cheap prompt object (version_count) on the same interval, invalidating the versions list only when that count actually changes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent 9562adf commit 247d732

3 files changed

Lines changed: 42 additions & 4 deletions

File tree

apps/opik-frontend/src/api/prompts/usePromptVersionsByIdInfinite.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type UsePromptVersionsByIdInfiniteParams = {
1818
type UsePromptVersionsByIdInfiniteOptions = {
1919
enabled?: boolean;
2020
refetchInterval?: number;
21+
refetchOnWindowFocus?: boolean;
2122
};
2223

2324
export default function usePromptVersionsByIdInfinite(

apps/opik-frontend/src/v2/pages/PromptPage/PromptPage.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,13 @@ const PromptPage: React.FunctionComponent = () => {
2727

2828
const promptId = usePromptIdFromURL();
2929

30-
const { data: prompt } = usePromptById({ promptId }, { enabled: !!promptId });
30+
// Cheap poll so the (unbounded) paginated version list can detect other
31+
// users' changes without itself refetching every loaded page on a timer —
32+
// see usePromptVersionHistory's version_count watcher.
33+
const { data: prompt } = usePromptById(
34+
{ promptId },
35+
{ enabled: !!promptId, refetchInterval: 30000 },
36+
);
3137
const promptName = prompt?.name || "";
3238
const setBreadcrumbParam = useBreadcrumbsStore((state) => state.setParam);
3339

apps/opik-frontend/src/v2/pages/PromptPage/PromptTab/usePromptVersionHistory.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { useEffect, useMemo, useState } from "react";
2-
import { keepPreviousData } from "@tanstack/react-query";
1+
import { useEffect, useMemo, useRef, useState } from "react";
2+
import { keepPreviousData, useQueryClient } from "@tanstack/react-query";
33
import { StringParam, useQueryParam } from "use-query-params";
44
import {
55
PromptVersion,
@@ -25,6 +25,8 @@ export default function usePromptVersionHistory(
2525
StringParam,
2626
);
2727

28+
const queryClient = useQueryClient();
29+
2830
const {
2931
data,
3032
isLoading: isVersionsLoading,
@@ -40,10 +42,39 @@ export default function usePromptVersionHistory(
4042
},
4143
{
4244
enabled: !!prompt?.id,
43-
refetchInterval: 30000,
45+
// No refetchInterval/refetchOnWindowFocus here: useInfiniteQuery
46+
// refetches every already-loaded page sequentially, and the Diff/Deploy
47+
// menus deliberately load every page for large prompts — polling or
48+
// refocus-refetching that unconditionally would multiply request volume
49+
// by however many pages got loaded that session. Instead, the cheap
50+
// `prompt` query below polls `version_count` and this list only
51+
// refetches (own mutations aside) when that actually changes.
4452
},
4553
);
4654

55+
// `prompt` is polled (see PromptPage) so `version_count` changing is a
56+
// cheap signal that some version was added/removed elsewhere — only then
57+
// do we pay for the expensive full-history refetch.
58+
const versionCountRef = useRef(prompt?.version_count);
59+
useEffect(() => {
60+
if (
61+
prompt?.id &&
62+
prompt.version_count !== undefined &&
63+
versionCountRef.current !== undefined &&
64+
prompt.version_count !== versionCountRef.current
65+
) {
66+
queryClient.invalidateQueries({
67+
predicate: (query) =>
68+
query.queryKey[0] === "prompt-versions" &&
69+
typeof query.queryKey[1] === "object" &&
70+
query.queryKey[1] !== null &&
71+
"promptId" in query.queryKey[1] &&
72+
query.queryKey[1].promptId === prompt.id,
73+
});
74+
}
75+
versionCountRef.current = prompt?.version_count;
76+
}, [prompt?.id, prompt?.version_count, queryClient]);
77+
4778
const versions = useMemo(
4879
() =>
4980
data?.pages.flatMap((p) => p.content) as

0 commit comments

Comments
 (0)