Spaces:
Sleeping
Sleeping
File size: 4,786 Bytes
05c5ed5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | "use client";
import { appStore } from "@/app/store";
import useSWR, { SWRConfiguration, useSWRConfig } from "swr";
import { handleErrorWithToast } from "ui/shared-toast";
import { fetcher } from "lib/utils";
import { AgentSummary } from "app-types/agent";
import { authClient } from "auth/client";
interface UseAgentsOptions extends SWRConfiguration {
filters?: ("all" | "mine" | "shared" | "bookmarked")[];
limit?: number;
}
export function useAgents(options: UseAgentsOptions = {}) {
const { filters = ["all"], limit = 50, ...swrOptions } = options;
// Build query string with filters
const filtersParam = filters.join(",");
const queryParams = new URLSearchParams({
filters: filtersParam,
limit: limit.toString(),
});
const {
data: agents = [],
error,
isLoading,
mutate,
} = useSWR<AgentSummary[]>(`/api/agent?${queryParams.toString()}`, fetcher, {
errorRetryCount: 0,
revalidateOnFocus: false,
fallbackData: [],
onError: handleErrorWithToast,
onSuccess: (data) => {
// Update Zustand store for chat mentions
appStore.setState({ agentList: data });
},
...swrOptions,
});
const { data: session } = authClient.useSession();
const currentUserId = session?.user?.id;
// Client-side filtering for additional views
const filterAgents = (filterFn: (agent: AgentSummary) => boolean) => {
return agents.filter(filterFn);
};
return {
agents, // All returned agents based on server filters
myAgents: filterAgents((agent) => agent.userId === currentUserId),
sharedAgents: filterAgents((agent) => agent.userId !== currentUserId),
bookmarkedAgents: filterAgents(
(agent) => agent.userId !== currentUserId && agent.isBookmarked === true,
),
publicAgents: filterAgents((agent) => agent.visibility === "public"),
readonlyAgents: filterAgents((agent) => agent.visibility === "readonly"),
isLoading,
error,
mutate,
// Helper to check if any agents exist of a certain type
hasAgents: (
type: "mine" | "shared" | "bookmarked" | "public" | "readonly",
) => {
switch (type) {
case "mine":
return agents.some((agent) => agent.userId === currentUserId);
case "shared":
return agents.some((agent) => agent.userId !== currentUserId);
case "bookmarked":
return agents.some(
(agent) => agent.userId !== currentUserId && agent.isBookmarked,
);
case "public":
return agents.some((agent) => agent.visibility === "public");
case "readonly":
return agents.some((agent) => agent.visibility === "readonly");
}
},
};
}
// Utility hook to invalidate all agent caches
export function useMutateAgents() {
const { mutate } = useSWRConfig();
return (
updatedAgent?: Partial<AgentSummary> & { id: string },
deleteAgent?: boolean,
) => {
// Update all agent list endpoints (with or without query strings)
mutate(
(key) => {
if (typeof key !== "string") return false;
// Match /api/agent or /api/agent?... but not /api/agent/id
return (
key.startsWith("/api/agent") && !key.match(/\/api\/agent\/[^/?]+/)
);
},
(cachedData: any) => {
if (!cachedData || !Array.isArray(cachedData) || !updatedAgent)
return cachedData;
// Handle agent deletion
if (deleteAgent) {
return cachedData.filter(
(agent: AgentSummary) => agent.id !== updatedAgent?.id,
);
}
// Handle agent update/creation
const existingIndex = cachedData.findIndex(
(agent: AgentSummary) => agent.id === updatedAgent?.id,
);
if (existingIndex >= 0) {
// Update existing agent
const newData = [...cachedData];
newData[existingIndex] = {
...newData[existingIndex],
...updatedAgent,
};
return newData;
} else {
// Add new agent at the beginning
return [updatedAgent, ...cachedData];
}
},
{ revalidate: true },
);
// Also update individual agent caches if we have an agent ID
if (updatedAgent?.id) {
if (deleteAgent) {
// For deleted agents, invalidate the individual cache
mutate(`/api/agent/${updatedAgent.id}`, undefined, {
revalidate: true,
});
} else {
// For updated agents, update the individual cache
mutate(
`/api/agent/${updatedAgent.id}`,
(cachedData: any) => {
if (!cachedData) return cachedData;
return { ...cachedData, ...updatedAgent };
},
{ revalidate: true },
);
}
}
};
}
|