feat(builder, server): Speed up fetching graphs (#7477)

- Let `GET /graphs` return `GraphMeta[]` instead of `string[]` (list of IDs)
- Rename `AutoGPTServerAPI` method `listGraphIDs` -> `listGraphs` and adjust return type
   - Replace all usages of `Graph` with `GraphMeta` in `/monitor`
- Delete `data.graph:get_graph_ids()`
pull/7501/head^2
Reinier van der Leer 2024-07-20 01:28:59 +02:00 committed by GitHub
parent 82fd3166ef
commit 21084c5817
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 19 additions and 36 deletions

View File

@ -24,7 +24,7 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { ChevronDownIcon, ClockIcon, EnterIcon, ExitIcon, Pencil2Icon } from '@radix-ui/react-icons';
import AutoGPTServerAPI, { Graph, GraphMeta, NodeExecutionResult } from '@/lib/autogpt_server_api';
import AutoGPTServerAPI, { GraphMeta, NodeExecutionResult } from '@/lib/autogpt_server_api';
import { cn, exportAsJSONFile, hashString } from '@/lib/utils';
import { Badge } from "@/components/ui/badge";
import { Button, buttonVariants } from "@/components/ui/button";
@ -36,9 +36,9 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@
import { AgentImportForm } from '@/components/agent-import-form';
const Monitor = () => {
const [flows, setFlows] = useState<Graph[]>([]);
const [flows, setFlows] = useState<GraphMeta[]>([]);
const [flowRuns, setFlowRuns] = useState<FlowRun[]>([]);
const [selectedFlow, setSelectedFlow] = useState<Graph | null>(null);
const [selectedFlow, setSelectedFlow] = useState<GraphMeta | null>(null);
const [selectedRun, setSelectedRun] = useState<FlowRun | null>(null);
const api = new AutoGPTServerAPI();
@ -50,16 +50,10 @@ const Monitor = () => {
}, []);
function fetchFlowsAndRuns() {
// Fetch flow IDs
api.listGraphIDs()
.then(flowIDs => {
Promise.all(flowIDs.map(flowID => {
refreshFlowRuns(flowID);
// Fetch flow
return api.getGraph(flowID);
}))
.then(flows => setFlows(flows));
api.listGraphs()
.then(flows => {
setFlows(flows);
flows.map(flow => refreshFlowRuns(flow.id));
});
}
@ -206,10 +200,10 @@ function flowRunFromNodeExecutionResults(
const AgentFlowList = (
{ flows, flowRuns, selectedFlow, onSelectFlow, className }: {
flows: Graph[],
flows: GraphMeta[],
flowRuns?: FlowRun[],
selectedFlow: Graph | null,
onSelectFlow: (f: Graph) => void,
selectedFlow: GraphMeta | null,
onSelectFlow: (f: GraphMeta) => void,
className?: string,
}
) => {
@ -341,7 +335,7 @@ const FlowStatusBadge = ({ status }: { status: "active" | "disabled" | "failing"
);
const FlowRunsList: React.FC<{
flows: Graph[];
flows: GraphMeta[];
runs: FlowRun[];
className?: string;
selectedRun?: FlowRun | null;
@ -400,13 +394,13 @@ const FlowRunStatusBadge: React.FC<{
);
const FlowInfo: React.FC<React.HTMLAttributes<HTMLDivElement> & {
flow: Graph;
flow: GraphMeta;
flowRuns: FlowRun[];
flowVersion?: number | "all";
}> = ({ flow, flowRuns, flowVersion, ...props }) => {
const api = new AutoGPTServerAPI();
const [flowVersions, setFlowVersions] = useState<Graph[] | null>(null);
const [flowVersions, setFlowVersions] = useState<GraphMeta[] | null>(null);
const [selectedVersion, setSelectedFlowVersion] = useState(flowVersion ?? "all");
useEffect(() => {
@ -478,7 +472,7 @@ const FlowInfo: React.FC<React.HTMLAttributes<HTMLDivElement> & {
};
const FlowRunInfo: React.FC<React.HTMLAttributes<HTMLDivElement> & {
flow: Graph;
flow: GraphMeta;
flowRun: FlowRun;
}> = ({ flow, flowRun, ...props }) => {
if (flowRun.graphID != flow.id) {
@ -509,7 +503,7 @@ const FlowRunInfo: React.FC<React.HTMLAttributes<HTMLDivElement> & {
};
const FlowRunsStats: React.FC<{
flows: Graph[],
flows: GraphMeta[],
flowRuns: FlowRun[],
title?: string,
className?: string,
@ -570,7 +564,7 @@ const FlowRunsStats: React.FC<{
const FlowRunsTimeline = (
{ flows, flowRuns, dataMin, className }: {
flows: Graph[],
flows: GraphMeta[],
flowRuns: FlowRun[],
dataMin: "dataMin" | number,
className?: string,

View File

@ -18,7 +18,7 @@ export default class AutoGPTServerAPI {
return await this._get("/blocks");
}
async listGraphIDs(): Promise<string[]> {
async listGraphs(): Promise<GraphMeta[]> {
return this._get("/graphs")
}

View File

@ -123,16 +123,6 @@ async def get_node(node_id: str) -> Node | None:
return Node.from_db(node) if node else None
# TODO: Delete this
async def get_graph_ids() -> list[str]:
return [
graph.id
for graph in await AgentGraph.prisma().find_many(
distinct=["id"], where={"isActive": True}
)
]
async def get_graphs_meta(
filter_by: Literal["active", "template"] | None = "active"
) -> list[GraphMeta]:

View File

@ -393,9 +393,8 @@ class AgentServer(AppService):
return [{name: data} for name, data in obj.execute(data)]
@classmethod
async def get_graphs(cls) -> list[str]:
# TODO: get_graph_ids() -> get_graphs_meta()
return await graph_db.get_graph_ids()
async def get_graphs(cls) -> list[graph_db.GraphMeta]:
return await graph_db.get_graphs_meta(filter_by="active")
@classmethod
async def get_templates(cls) -> list[graph_db.GraphMeta]: