mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-09 07:08:09 -05:00
fix(frontend): Fix return type and usage of api.listLibraryAgents() (#9498)
- Follow-up to #9258 The front end is fetching `/library/agents` -> `LibraryAgent[]` but using the result as `GraphMeta[]`. This breaks a bunch of things. ### Changes 🏗️ Frontend: - Add `LibraryAgent` type for `api.listLibraryAgents()` - Amend all broken usages of `LibraryAgent` objects - Introduce branded typing for `LibraryAgent.id` and `GraphMeta.id` to disallow mixing them. This prevents incorrect use in the future, and reduces the chance of this frontend issue accumulating interest on existing open PRs. Backend: - Add a migration to create `LibraryAgent` objects for all existing `AgentGraphs` ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: <!-- Put your test plan here: --> - [x] Check that all existing agents are listed in the agents list on `/monitoring` (check against DB or `GET /api/graphs`) - [x] Check that all views of `/monitoring` work - [x] Try to run an agent and check its status
This commit is contained in:
committed by
GitHub
parent
dcbbe11c53
commit
d1832ce10b
@@ -0,0 +1,33 @@
|
||||
-- Create LibraryAgents for all AgentGraphs in their owners' library, skipping existing entries
|
||||
INSERT INTO "LibraryAgent" (
|
||||
"id",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"userId",
|
||||
"agentId",
|
||||
"agentVersion",
|
||||
"useGraphIsActiveVersion",
|
||||
"isFavorite",
|
||||
"isCreatedByUser",
|
||||
"isArchived",
|
||||
"isDeleted")
|
||||
SELECT
|
||||
gen_random_uuid(), --> id
|
||||
ag."createdAt", --> createdAt
|
||||
ag."createdAt", --> updatedAt
|
||||
ag."userId", --> userId
|
||||
ag."id", --> agentId
|
||||
ag."version", --> agentVersion
|
||||
true, --> useGraphIsActiveVersion
|
||||
false, --> isFavorite
|
||||
true, --> isCreatedByUser
|
||||
false, --> isArchived
|
||||
false --> isDeleted
|
||||
FROM "AgentGraph" AS ag
|
||||
WHERE ag."isActive" = true
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM "LibraryAgent" AS la
|
||||
WHERE la."userId" = ag."userId"
|
||||
AND la."agentId" = ag."id"
|
||||
);
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { GraphID } from "@/lib/autogpt-server-api/types";
|
||||
import FlowEditor from "@/components/Flow";
|
||||
|
||||
export default function Home() {
|
||||
@@ -9,7 +10,7 @@ export default function Home() {
|
||||
return (
|
||||
<FlowEditor
|
||||
className="flow-container"
|
||||
flowID={query.get("flowID") ?? undefined}
|
||||
flowID={query.get("flowID") as GraphID | null ?? undefined}
|
||||
flowVersion={query.get("flowVersion") ?? undefined}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
"use client";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { GraphExecution, Schedule, GraphMeta } from "@/lib/autogpt-server-api";
|
||||
import {
|
||||
GraphExecution,
|
||||
Schedule,
|
||||
LibraryAgent,
|
||||
} from "@/lib/autogpt-server-api";
|
||||
|
||||
import { Card } from "@/components/ui/card";
|
||||
import {
|
||||
@@ -15,10 +19,10 @@ import { SchedulesTable } from "@/components/monitor/scheduleTable";
|
||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
|
||||
const Monitor = () => {
|
||||
const [flows, setFlows] = useState<GraphMeta[]>([]);
|
||||
const [flows, setFlows] = useState<LibraryAgent[]>([]);
|
||||
const [executions, setExecutions] = useState<GraphExecution[]>([]);
|
||||
const [schedules, setSchedules] = useState<Schedule[]>([]);
|
||||
const [selectedFlow, setSelectedFlow] = useState<GraphMeta | null>(null);
|
||||
const [selectedFlow, setSelectedFlow] = useState<LibraryAgent | null>(null);
|
||||
const [selectedRun, setSelectedRun] = useState<GraphExecution | null>(null);
|
||||
const [sortColumn, setSortColumn] = useState<keyof Schedule>("id");
|
||||
const [sortDirection, setSortDirection] = useState<"asc" | "desc">("asc");
|
||||
@@ -83,7 +87,7 @@ const Monitor = () => {
|
||||
selectedFlow={selectedFlow}
|
||||
onSelectFlow={(f) => {
|
||||
setSelectedRun(null);
|
||||
setSelectedFlow(f.id == selectedFlow?.id ? null : (f as GraphMeta));
|
||||
setSelectedFlow(f.id == selectedFlow?.id ? null : f);
|
||||
}}
|
||||
/>
|
||||
<FlowRunsList
|
||||
@@ -91,7 +95,7 @@ const Monitor = () => {
|
||||
flows={flows}
|
||||
executions={[
|
||||
...(selectedFlow
|
||||
? executions.filter((v) => v.graph_id == selectedFlow.id)
|
||||
? executions.filter((v) => v.graph_id == selectedFlow.agent_id)
|
||||
: executions),
|
||||
].sort((a, b) => Number(b.started_at) - Number(a.started_at))}
|
||||
selectedRun={selectedRun}
|
||||
@@ -102,7 +106,8 @@ const Monitor = () => {
|
||||
{(selectedRun && (
|
||||
<FlowRunInfo
|
||||
flow={
|
||||
selectedFlow || flows.find((f) => f.id == selectedRun.graph_id)!
|
||||
selectedFlow ||
|
||||
flows.find((f) => f.agent_id == selectedRun.graph_id)!
|
||||
}
|
||||
execution={selectedRun}
|
||||
className={column3}
|
||||
@@ -111,7 +116,9 @@ const Monitor = () => {
|
||||
(selectedFlow && (
|
||||
<FlowInfo
|
||||
flow={selectedFlow}
|
||||
executions={executions.filter((e) => e.graph_id == selectedFlow.id)}
|
||||
executions={executions.filter(
|
||||
(e) => e.graph_id == selectedFlow.agent_id,
|
||||
)}
|
||||
className={column3}
|
||||
refresh={() => {
|
||||
fetchAgents();
|
||||
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
import "@xyflow/react/dist/style.css";
|
||||
import { CustomNode } from "./CustomNode";
|
||||
import "./flow.css";
|
||||
import { BlockUIType, formatEdgeID } from "@/lib/autogpt-server-api";
|
||||
import { BlockUIType, formatEdgeID, GraphID } from "@/lib/autogpt-server-api";
|
||||
import { getTypeColor, findNewlyAddedBlockCoordinates } from "@/lib/utils";
|
||||
import { history } from "./history";
|
||||
import { CustomEdge } from "./CustomEdge";
|
||||
@@ -69,7 +69,7 @@ export type NodeDimension = {
|
||||
export const FlowContext = createContext<FlowContextType | null>(null);
|
||||
|
||||
const FlowEditor: React.FC<{
|
||||
flowID?: string;
|
||||
flowID?: GraphID;
|
||||
flowVersion?: string;
|
||||
className?: string;
|
||||
}> = ({ flowID, flowVersion, className }) => {
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import BackendAPI, {
|
||||
GraphExecution,
|
||||
GraphMeta,
|
||||
} from "@/lib/autogpt-server-api";
|
||||
import React, { useMemo } from "react";
|
||||
import { GraphExecution, LibraryAgent } from "@/lib/autogpt-server-api";
|
||||
import React from "react";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { TextRenderer } from "@/components/ui/render";
|
||||
@@ -39,10 +36,10 @@ export const AgentFlowList = ({
|
||||
onSelectFlow,
|
||||
className,
|
||||
}: {
|
||||
flows: GraphMeta[];
|
||||
flows: LibraryAgent[];
|
||||
executions?: GraphExecution[];
|
||||
selectedFlow: GraphMeta | null;
|
||||
onSelectFlow: (f: GraphMeta) => void;
|
||||
selectedFlow: LibraryAgent | null;
|
||||
onSelectFlow: (f: LibraryAgent) => void;
|
||||
className?: string;
|
||||
}) => {
|
||||
return (
|
||||
@@ -112,7 +109,7 @@ export const AgentFlowList = ({
|
||||
lastRun: GraphExecution | null = null;
|
||||
if (executions) {
|
||||
const _flowRuns = executions.filter(
|
||||
(r) => r.graph_id == flow.id,
|
||||
(r) => r.graph_id == flow.agent_id,
|
||||
);
|
||||
runCount = _flowRuns.length;
|
||||
lastRun =
|
||||
|
||||
@@ -2,10 +2,10 @@ import React, { useEffect, useState, useCallback } from "react";
|
||||
import {
|
||||
GraphExecution,
|
||||
Graph,
|
||||
GraphMeta,
|
||||
safeCopyGraph,
|
||||
BlockUIType,
|
||||
BlockIORootSchema,
|
||||
LibraryAgent,
|
||||
} from "@/lib/autogpt-server-api";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
@@ -39,7 +39,7 @@ import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
|
||||
export const FlowInfo: React.FC<
|
||||
React.HTMLAttributes<HTMLDivElement> & {
|
||||
flow: GraphMeta;
|
||||
flow: LibraryAgent;
|
||||
executions: GraphExecution[];
|
||||
flowVersion?: number | "all";
|
||||
refresh: () => void;
|
||||
@@ -65,7 +65,7 @@ export const FlowInfo: React.FC<
|
||||
setNodes,
|
||||
edges,
|
||||
setEdges,
|
||||
} = useAgentGraph(flow.id, flow.version, undefined, false);
|
||||
} = useAgentGraph(flow.agent_id, flow.agent_version, undefined, false);
|
||||
|
||||
const api = useBackendAPI();
|
||||
const { toast } = useToast();
|
||||
@@ -76,7 +76,8 @@ export const FlowInfo: React.FC<
|
||||
);
|
||||
const selectedFlowVersion: Graph | undefined = flowVersions?.find(
|
||||
(v) =>
|
||||
v.version == (selectedVersion == "all" ? flow.version : selectedVersion),
|
||||
v.version ==
|
||||
(selectedVersion == "all" ? flow.agent_version : selectedVersion),
|
||||
);
|
||||
|
||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||
@@ -139,8 +140,10 @@ export const FlowInfo: React.FC<
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
api.getGraphAllVersions(flow.id).then((result) => setFlowVersions(result));
|
||||
}, [flow.id, api]);
|
||||
api
|
||||
.getGraphAllVersions(flow.agent_id)
|
||||
.then((result) => setFlowVersions(result));
|
||||
}, [flow.agent_id, api]);
|
||||
|
||||
const openRunnerInput = () => setIsRunnerInputOpen(true);
|
||||
|
||||
@@ -181,7 +184,8 @@ export const FlowInfo: React.FC<
|
||||
<CardHeader className="flex-row justify-between space-x-3 space-y-0">
|
||||
<div>
|
||||
<CardTitle>
|
||||
{flow.name} <span className="font-light">v{flow.version}</span>
|
||||
{flow.name}{" "}
|
||||
<span className="font-light">v{flow.agent_version}</span>
|
||||
</CardTitle>
|
||||
</div>
|
||||
<div className="flex items-start space-x-2">
|
||||
@@ -224,7 +228,7 @@ export const FlowInfo: React.FC<
|
||||
)}
|
||||
<Link
|
||||
className={buttonVariants({ variant: "default" })}
|
||||
href={`/build?flowID=${flow.id}&flowVersion=${flow.version}`}
|
||||
href={`/build?flowID=${flow.agent_id}&flowVersion=${flow.agent_version}`}
|
||||
>
|
||||
<Pencil2Icon className="mr-2" />
|
||||
Open in Builder
|
||||
@@ -268,10 +272,10 @@ export const FlowInfo: React.FC<
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<FlowRunsStats
|
||||
flows={[selectedFlowVersion ?? flow]}
|
||||
flows={[flow]}
|
||||
executions={executions.filter(
|
||||
(execution) =>
|
||||
execution.graph_id == flow.id &&
|
||||
execution.graph_id == flow.agent_id &&
|
||||
(selectedVersion == "all" ||
|
||||
execution.graph_version == selectedVersion),
|
||||
)}
|
||||
@@ -296,7 +300,7 @@ export const FlowInfo: React.FC<
|
||||
<Button
|
||||
variant="destructive"
|
||||
onClick={() => {
|
||||
api.deleteGraph(flow.id).then(() => {
|
||||
api.deleteGraph(flow.agent_id).then(() => {
|
||||
setIsDeleteModalOpen(false);
|
||||
refresh();
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import {
|
||||
GraphExecution,
|
||||
GraphMeta,
|
||||
LibraryAgent,
|
||||
NodeExecutionResult,
|
||||
SpecialBlockID,
|
||||
} from "@/lib/autogpt-server-api";
|
||||
@@ -17,7 +17,7 @@ import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
|
||||
export const FlowRunInfo: React.FC<
|
||||
React.HTMLAttributes<HTMLDivElement> & {
|
||||
flow: GraphMeta;
|
||||
flow: LibraryAgent;
|
||||
execution: GraphExecution;
|
||||
}
|
||||
> = ({ flow, execution, ...props }) => {
|
||||
@@ -27,7 +27,7 @@ export const FlowRunInfo: React.FC<
|
||||
|
||||
const fetchBlockResults = useCallback(async () => {
|
||||
const executionResults = await api.getGraphExecutionInfo(
|
||||
flow.id,
|
||||
flow.agent_id,
|
||||
execution.execution_id,
|
||||
);
|
||||
|
||||
@@ -70,7 +70,7 @@ export const FlowRunInfo: React.FC<
|
||||
result: result.output_data?.output || undefined,
|
||||
})),
|
||||
);
|
||||
}, [api, flow.id, execution.execution_id]);
|
||||
}, [api, flow.agent_id, execution.execution_id]);
|
||||
|
||||
// Fetch graph and execution data
|
||||
useEffect(() => {
|
||||
@@ -78,15 +78,15 @@ export const FlowRunInfo: React.FC<
|
||||
fetchBlockResults();
|
||||
}, [isOutputOpen, fetchBlockResults]);
|
||||
|
||||
if (execution.graph_id != flow.id) {
|
||||
if (execution.graph_id != flow.agent_id) {
|
||||
throw new Error(
|
||||
`FlowRunInfo can't be used with non-matching execution.graph_id and flow.id`,
|
||||
);
|
||||
}
|
||||
|
||||
const handleStopRun = useCallback(() => {
|
||||
api.stopGraphExecution(flow.id, execution.execution_id);
|
||||
}, [api, flow.id, execution.execution_id]);
|
||||
api.stopGraphExecution(flow.agent_id, execution.execution_id);
|
||||
}, [api, flow.agent_id, execution.execution_id]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -107,17 +107,19 @@ export const FlowRunInfo: React.FC<
|
||||
<Button onClick={() => setIsOutputOpen(true)} variant="outline">
|
||||
<ExitIcon className="mr-2" /> View Outputs
|
||||
</Button>
|
||||
<Link
|
||||
className={buttonVariants({ variant: "default" })}
|
||||
href={`/build?flowID=${flow.id}&flowVersion=${execution.graph_version}&flowExecutionID=${execution.execution_id}`}
|
||||
>
|
||||
<Pencil2Icon className="mr-2" /> Open in Builder
|
||||
</Link>
|
||||
{flow.is_created_by_user && (
|
||||
<Link
|
||||
className={buttonVariants({ variant: "default" })}
|
||||
href={`/build?flowID=${execution.graph_id}&flowVersion=${execution.graph_version}&flowExecutionID=${execution.execution_id}`}
|
||||
>
|
||||
<Pencil2Icon className="mr-2" /> Open in Builder
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p className="hidden">
|
||||
<strong>Agent ID:</strong> <code>{flow.id}</code>
|
||||
<strong>Agent ID:</strong> <code>{flow.agent_id}</code>
|
||||
</p>
|
||||
<p className="hidden">
|
||||
<strong>Run ID:</strong> <code>{execution.execution_id}</code>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { GraphExecution, GraphMeta } from "@/lib/autogpt-server-api";
|
||||
import { GraphExecution, LibraryAgent } from "@/lib/autogpt-server-api";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
Table,
|
||||
@@ -14,7 +14,7 @@ import { FlowRunStatusBadge } from "@/components/monitor/FlowRunStatusBadge";
|
||||
import { TextRenderer } from "../ui/render";
|
||||
|
||||
export const FlowRunsList: React.FC<{
|
||||
flows: GraphMeta[];
|
||||
flows: LibraryAgent[];
|
||||
executions: GraphExecution[];
|
||||
className?: string;
|
||||
selectedRun?: GraphExecution | null;
|
||||
@@ -51,7 +51,9 @@ export const FlowRunsList: React.FC<{
|
||||
>
|
||||
<TableCell>
|
||||
<TextRenderer
|
||||
value={flows.find((f) => f.id == execution.graph_id)?.name}
|
||||
value={
|
||||
flows.find((f) => f.agent_id == execution.graph_id)?.name
|
||||
}
|
||||
truncateLengthLimit={30}
|
||||
/>
|
||||
</TableCell>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from "react";
|
||||
import { GraphExecution, GraphMeta } from "@/lib/autogpt-server-api";
|
||||
import { GraphExecution, LibraryAgent } from "@/lib/autogpt-server-api";
|
||||
import { CardTitle } from "@/components/ui/card";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
@@ -11,7 +11,7 @@ import { Calendar } from "@/components/ui/calendar";
|
||||
import { FlowRunsTimeline } from "@/components/monitor/FlowRunsTimeline";
|
||||
|
||||
export const FlowRunsStatus: React.FC<{
|
||||
flows: GraphMeta[];
|
||||
flows: LibraryAgent[];
|
||||
executions: GraphExecution[];
|
||||
title?: string;
|
||||
className?: string;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { GraphExecution, GraphMeta } from "@/lib/autogpt-server-api";
|
||||
import { GraphExecution, LibraryAgent } from "@/lib/autogpt-server-api";
|
||||
import {
|
||||
ComposedChart,
|
||||
DefaultLegendContentProps,
|
||||
@@ -22,7 +22,7 @@ export const FlowRunsTimeline = ({
|
||||
dataMin,
|
||||
className,
|
||||
}: {
|
||||
flows: GraphMeta[];
|
||||
flows: LibraryAgent[];
|
||||
executions: GraphExecution[];
|
||||
dataMin: "dataMin" | number;
|
||||
className?: string;
|
||||
@@ -62,7 +62,7 @@ export const FlowRunsTimeline = ({
|
||||
if (payload && payload.length) {
|
||||
const data: GraphExecution & { time: number; _duration: number } =
|
||||
payload[0].payload;
|
||||
const flow = flows.find((f) => f.id === data.graph_id);
|
||||
const flow = flows.find((f) => f.agent_id === data.graph_id);
|
||||
return (
|
||||
<Card className="p-2 text-xs leading-normal">
|
||||
<p>
|
||||
@@ -94,7 +94,7 @@ export const FlowRunsTimeline = ({
|
||||
<Scatter
|
||||
key={flow.id}
|
||||
data={executions
|
||||
.filter((e) => e.graph_id == flow.id)
|
||||
.filter((e) => e.graph_id == flow.agent_id)
|
||||
.map((e) => ({
|
||||
...e,
|
||||
time: e.started_at + e.total_run_time * 1000,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Schedule } from "@/lib/autogpt-server-api";
|
||||
import { LibraryAgent, Schedule } from "@/lib/autogpt-server-api";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card } from "@/components/ui/card";
|
||||
import {
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { GraphMeta } from "@/lib/autogpt-server-api";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
@@ -36,7 +35,7 @@ import { Label } from "../ui/label";
|
||||
|
||||
interface SchedulesTableProps {
|
||||
schedules: Schedule[];
|
||||
agents: GraphMeta[];
|
||||
agents: LibraryAgent[];
|
||||
onRemoveSchedule: (scheduleId: string, enabled: boolean) => void;
|
||||
sortColumn: keyof Schedule;
|
||||
sortDirection: "asc" | "desc";
|
||||
@@ -54,12 +53,12 @@ export const SchedulesTable = ({
|
||||
const { toast } = useToast();
|
||||
const router = useRouter();
|
||||
const cron_manager = new CronExpressionManager();
|
||||
const [selectedAgent, setSelectedAgent] = useState<string>("");
|
||||
const [selectedVersion, setSelectedVersion] = useState<number>(0);
|
||||
const [selectedAgent, setSelectedAgent] = useState<string>(""); // Library Agent ID
|
||||
const [selectedVersion, setSelectedVersion] = useState<number>(0); // Graph version
|
||||
const [maxVersion, setMaxVersion] = useState<number>(0);
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [selectedFilter, setSelectedFilter] = useState<string>("");
|
||||
const [selectedFilter, setSelectedFilter] = useState<string>(""); // Graph ID
|
||||
|
||||
const filteredAndSortedSchedules = [...schedules]
|
||||
.filter(
|
||||
@@ -91,8 +90,8 @@ export const SchedulesTable = ({
|
||||
const handleAgentSelect = (agentId: string) => {
|
||||
setSelectedAgent(agentId);
|
||||
const agent = agents.find((a) => a.id === agentId);
|
||||
setMaxVersion(agent!.version);
|
||||
setSelectedVersion(agent!.version);
|
||||
setMaxVersion(agent!.agent_version);
|
||||
setSelectedVersion(agent!.agent_version);
|
||||
};
|
||||
|
||||
const handleVersionSelect = (version: string) => {
|
||||
@@ -117,10 +116,11 @@ export const SchedulesTable = ({
|
||||
return;
|
||||
}
|
||||
setIsLoading(true);
|
||||
const agent = agents.find((a) => a.id == selectedAgent)!;
|
||||
try {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
router.push(
|
||||
`/build?flowID=${selectedAgent}&flowVersion=${selectedVersion}&open_scheduling=true`,
|
||||
`/build?flowID=${agent.agent_id}&flowVersion=${agent.agent_version}&open_scheduling=true`,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Navigation error:", error);
|
||||
@@ -184,7 +184,7 @@ export const SchedulesTable = ({
|
||||
</SelectTrigger>
|
||||
<SelectContent className="text-xs">
|
||||
{agents.map((agent) => (
|
||||
<SelectItem key={agent.id} value={agent.id}>
|
||||
<SelectItem key={agent.id} value={agent.agent_id}>
|
||||
{agent.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
@@ -237,8 +237,8 @@ export const SchedulesTable = ({
|
||||
filteredAndSortedSchedules.map((schedule) => (
|
||||
<TableRow key={schedule.id}>
|
||||
<TableCell className="font-medium">
|
||||
{agents.find((a) => a.id === schedule.graph_id)?.name ||
|
||||
schedule.graph_id}
|
||||
{agents.find((a) => a.agent_id === schedule.graph_id)
|
||||
?.name || schedule.graph_id}
|
||||
</TableCell>
|
||||
<TableCell>{schedule.graph_version}</TableCell>
|
||||
<TableCell>
|
||||
|
||||
@@ -6,6 +6,7 @@ import BackendAPI, {
|
||||
BlockUIType,
|
||||
formatEdgeID,
|
||||
Graph,
|
||||
GraphID,
|
||||
NodeExecutionResult,
|
||||
} from "@/lib/autogpt-server-api";
|
||||
import {
|
||||
@@ -26,7 +27,7 @@ import { default as NextLink } from "next/link";
|
||||
const ajv = new Ajv({ strict: false, allErrors: true });
|
||||
|
||||
export default function useAgentGraph(
|
||||
flowID?: string,
|
||||
flowID?: GraphID,
|
||||
flowVersion?: number,
|
||||
flowExecutionID?: string,
|
||||
passDataToBeads?: boolean,
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
GraphCreatable,
|
||||
GraphMeta,
|
||||
GraphUpdateable,
|
||||
LibraryAgent,
|
||||
MyAgentsResponse,
|
||||
NodeExecutionResult,
|
||||
ProfileDetails,
|
||||
@@ -450,7 +451,7 @@ export default class BackendAPI {
|
||||
/////////// V2 LIBRARY API //////////////
|
||||
/////////////////////////////////////////
|
||||
|
||||
async listLibraryAgents(): Promise<GraphMeta[]> {
|
||||
async listLibraryAgents(): Promise<LibraryAgent[]> {
|
||||
return this._get("/library/agents");
|
||||
}
|
||||
|
||||
|
||||
@@ -224,12 +224,12 @@ export type GraphExecution = {
|
||||
duration: number;
|
||||
total_run_time: number;
|
||||
status: "QUEUED" | "RUNNING" | "COMPLETED" | "TERMINATED" | "FAILED";
|
||||
graph_id: string;
|
||||
graph_id: GraphID;
|
||||
graph_version: number;
|
||||
};
|
||||
|
||||
export type GraphMeta = {
|
||||
id: string;
|
||||
id: GraphID;
|
||||
version: number;
|
||||
is_active: boolean;
|
||||
name: string;
|
||||
@@ -238,6 +238,8 @@ export type GraphMeta = {
|
||||
output_schema: BlockIOObjectSubSchema;
|
||||
};
|
||||
|
||||
export type GraphID = Brand<string, "GraphID">;
|
||||
|
||||
/* Mirror of backend/data/graph.py:Graph */
|
||||
export type Graph = GraphMeta & {
|
||||
nodes: Array<Node>;
|
||||
@@ -259,7 +261,7 @@ export type GraphCreatable = Omit<GraphUpdateable, "id"> & { id?: string };
|
||||
|
||||
/* Mirror of backend/data/execution.py:ExecutionResult */
|
||||
export type NodeExecutionResult = {
|
||||
graph_id: string;
|
||||
graph_id: GraphID;
|
||||
graph_version: number;
|
||||
graph_exec_id: string;
|
||||
node_exec_id: string;
|
||||
@@ -280,6 +282,24 @@ export type NodeExecutionResult = {
|
||||
end_time?: Date;
|
||||
};
|
||||
|
||||
/* Mirror of backend/server/v2/library/model.py:LibraryAgent */
|
||||
export type LibraryAgent = {
|
||||
id: LibraryAgentID;
|
||||
agent_id: GraphID;
|
||||
agent_version: number;
|
||||
preset_id: string | null;
|
||||
updated_at: Date;
|
||||
name: string;
|
||||
description: string;
|
||||
input_schema: BlockIOObjectSubSchema;
|
||||
output_schema: BlockIOObjectSubSchema;
|
||||
is_favorite: boolean;
|
||||
is_created_by_user: boolean;
|
||||
is_latest_version: boolean;
|
||||
};
|
||||
|
||||
export type LibraryAgentID = Brand<string, "LibraryAgentID">;
|
||||
|
||||
/* Mirror of backend/server/integrations/router.py:CredentialsMetaResponse */
|
||||
export type CredentialsMetaResponse = {
|
||||
id: string;
|
||||
@@ -503,7 +523,7 @@ export type Schedule = {
|
||||
name: string;
|
||||
cron: string;
|
||||
user_id: string;
|
||||
graph_id: string;
|
||||
graph_id: GraphID;
|
||||
graph_version: number;
|
||||
input_data: { [key: string]: any };
|
||||
next_run_time: string;
|
||||
@@ -511,7 +531,7 @@ export type Schedule = {
|
||||
|
||||
export type ScheduleCreatable = {
|
||||
cron: string;
|
||||
graph_id: string;
|
||||
graph_id: GraphID;
|
||||
graph_version: number;
|
||||
input_data: { [key: string]: any };
|
||||
};
|
||||
@@ -580,7 +600,7 @@ export interface CreditTransaction {
|
||||
amount: number;
|
||||
balance: number;
|
||||
description: string;
|
||||
usage_graph_id: string;
|
||||
usage_graph_id: GraphID;
|
||||
usage_execution_id: string;
|
||||
usage_node_count: number;
|
||||
usage_starting_time: Date;
|
||||
@@ -602,3 +622,10 @@ export interface RefundRequest {
|
||||
created_at: Date;
|
||||
updated_at: Date;
|
||||
}
|
||||
|
||||
/* *** UTILITIES *** */
|
||||
|
||||
/** Use branded types for IDs -> deny mixing IDs between different object classes */
|
||||
export type Brand<T, Brand extends string> = T & {
|
||||
readonly [B in Brand as `__${B}_brand`]: never;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user