diff --git a/autogpt_platform/backend/backend/data/execution.py b/autogpt_platform/backend/backend/data/execution.py index bd6d79d47e..ddab2b185b 100644 --- a/autogpt_platform/backend/backend/data/execution.py +++ b/autogpt_platform/backend/backend/data/execution.py @@ -1,11 +1,10 @@ from collections import defaultdict from datetime import datetime, timezone from multiprocessing import Manager -from typing import Any, AsyncGenerator, Generator, Generic, Optional, Type, TypeVar +from typing import Any, AsyncGenerator, Generator, Generic, Type, TypeVar from prisma import Json from prisma.enums import AgentExecutionStatus -from prisma.errors import PrismaError from prisma.models import ( AgentGraphExecution, AgentNodeExecution, @@ -331,28 +330,14 @@ async def update_execution_status( return ExecutionResult.from_db(res) -async def get_execution( - execution_id: str, user_id: str -) -> Optional[AgentNodeExecution]: - """ - Get an execution by ID. Returns None if not found. - - Args: - execution_id: The ID of the execution to retrieve - - Returns: - The execution if found, None otherwise - """ - try: - execution = await AgentNodeExecution.prisma().find_unique( - where={ - "id": execution_id, - "userId": user_id, - } +async def delete_execution(graph_exec_id: str, user_id: str) -> None: + delete_count = await AgentGraphExecution.prisma().delete_many( + where={"id": graph_exec_id, "userId": user_id} + ) + if delete_count < 1: + raise DatabaseError( + f"Could not delete graph execution #{graph_exec_id}: not found" ) - return execution - except PrismaError: - return None async def get_execution_results(graph_exec_id: str) -> list[ExecutionResult]: diff --git a/autogpt_platform/backend/backend/data/graph.py b/autogpt_platform/backend/backend/data/graph.py index 25d574204b..7d3bcddf83 100644 --- a/autogpt_platform/backend/backend/data/graph.py +++ b/autogpt_platform/backend/backend/data/graph.py @@ -591,6 +591,7 @@ async def get_graphs( return graph_models +# TODO: move execution stuff to .execution async def get_graphs_executions(user_id: str) -> list[GraphExecutionMeta]: executions = await AgentGraphExecution.prisma().find_many( where={"userId": user_id}, diff --git a/autogpt_platform/backend/backend/server/routers/v1.py b/autogpt_platform/backend/backend/server/routers/v1.py index 5e0eeea0ec..c649d9f6c2 100644 --- a/autogpt_platform/backend/backend/server/routers/v1.py +++ b/autogpt_platform/backend/backend/server/routers/v1.py @@ -10,12 +10,14 @@ from autogpt_libs.auth.middleware import auth_middleware from autogpt_libs.feature_flag.client import feature_flag from autogpt_libs.utils.cache import thread_cached from fastapi import APIRouter, Body, Depends, HTTPException, Request, Response +from starlette.status import HTTP_204_NO_CONTENT from typing_extensions import Optional, TypedDict import backend.data.block import backend.server.integrations.router import backend.server.routers.analytics import backend.server.v2.library.db as library_db +from backend.data import execution as execution_db from backend.data import graph as graph_db from backend.data.api_key import ( APIKeyError, @@ -630,6 +632,19 @@ async def get_graph_execution( return result +@v1_router.delete( + path="/executions/{graph_exec_id}", + tags=["graphs"], + dependencies=[Depends(auth_middleware)], + status_code=HTTP_204_NO_CONTENT, +) +async def delete_graph_execution( + graph_exec_id: str, + user_id: Annotated[str, Depends(get_user_id)], +) -> None: + await execution_db.delete_execution(graph_exec_id=graph_exec_id, user_id=user_id) + + ######################################################## ##################### Schedules ######################## ######################################################## diff --git a/autogpt_platform/frontend/src/app/library/agents/[id]/page.tsx b/autogpt_platform/frontend/src/app/library/agents/[id]/page.tsx index 5435b88a5c..018fb97087 100644 --- a/autogpt_platform/frontend/src/app/library/agents/[id]/page.tsx +++ b/autogpt_platform/frontend/src/app/library/agents/[id]/page.tsx @@ -98,20 +98,30 @@ export default function AgentRunsPage(): React.ReactElement { fetchSchedules(); }, [fetchSchedules]); - const removeSchedule = useCallback( - async (scheduleId: string) => { - const removedSchedule = await api.deleteSchedule(scheduleId); - setSchedules(schedules.filter((s) => s.id !== removedSchedule.id)); - }, - [schedules, api], - ); - /* TODO: use websockets instead of polling - https://github.com/Significant-Gravitas/AutoGPT/issues/8782 */ useEffect(() => { const intervalId = setInterval(() => fetchAgents(), 5000); return () => clearInterval(intervalId); }, [fetchAgents, agent]); + // =========================== ACTIONS ============================ + + const deleteRun = useCallback( + async (graphExecID: string) => { + await api.deleteGraphExecution(graphExecID); + setAgentRuns(agentRuns.filter((r) => r.execution_id !== graphExecID)); + }, + [agentRuns, api], + ); + + const deleteSchedule = useCallback( + async (scheduleID: string) => { + const removedSchedule = await api.deleteSchedule(scheduleID); + setSchedules(schedules.filter((s) => s.id !== removedSchedule.id)); + }, + [schedules, api], + ); + const agentActions: { label: string; callback: () => void }[] = useMemo( () => [ { @@ -139,7 +149,9 @@ export default function AgentRunsPage(): React.ReactElement { selectedView={selectedView} onSelectRun={selectRun} onSelectSchedule={selectSchedule} - onDraftNewRun={openRunDraftView} + onSelectDraftNewRun={openRunDraftView} + onDeleteRun={(id) => deleteRun(id)} + onDeleteSchedule={(id) => deleteSchedule(id)} />
void;
onSelectSchedule: (schedule: Schedule) => void;
- onDraftNewRun: () => void;
+ onSelectDraftNewRun: () => void;
+ onDeleteSchedule: (id: string) => void;
className?: string;
}
@@ -34,7 +35,9 @@ export default function AgentRunsSelectorList({
selectedView,
onSelectRun,
onSelectSchedule,
- onDraftNewRun,
+ onSelectDraftNewRun,
+ onDeleteRun,
+ onDeleteSchedule,
className,
}: AgentRunsSelectorListProps): React.ReactElement {
const [activeListTab, setActiveListTab] = useState<"runs" | "scheduled">(
@@ -51,7 +54,7 @@ export default function AgentRunsSelectorList({
? "agpt-card-selected text-accent"
: "")
}
- onClick={onDraftNewRun}
+ onClick={onSelectDraftNewRun}
>