From 3ec8fd912f878cfc874a1a7c8a6a3d642b939fce Mon Sep 17 00:00:00 2001 From: Medyan Date: Thu, 29 Jan 2026 19:32:15 -0500 Subject: [PATCH] Sort by most recent execution time rebase with dev branch --- .../backend/api/features/library/db.py | 69 +++++++++++++++---- .../backend/api/features/library/model.py | 1 + .../api/features/library/routes/agents.py | 2 +- .../backend/backend/data/includes.py | 2 +- 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/autogpt_platform/backend/backend/api/features/library/db.py b/autogpt_platform/backend/backend/api/features/library/db.py index 394f959953..3794b6eba5 100644 --- a/autogpt_platform/backend/backend/api/features/library/db.py +++ b/autogpt_platform/backend/backend/api/features/library/db.py @@ -104,18 +104,63 @@ async def list_library_agents( order_by = {"updatedAt": "desc"} try: - library_agents = await prisma.models.LibraryAgent.prisma().find_many( - where=where_clause, - include=library_agent_include( - user_id, include_nodes=False, include_executions=include_executions - ), - order=order_by, - skip=(page - 1) * page_size, - take=page_size, - ) - agent_count = await prisma.models.LibraryAgent.prisma().count( - where=where_clause - ) + # For LAST_EXECUTED sorting, we need to fetch execution data and sort in Python + # since Prisma doesn't support sorting by nested relations + if sort_by == library_model.LibraryAgentSort.LAST_EXECUTED: + # TODO: This fetches all agents into memory for sorting, which may cause + # performance issues for users with many agents. Prisma doesn't support + # sorting by nested relations, so a dedicated lastExecutedAt column or + # raw SQL query would be needed for database-level pagination. + library_agents = await prisma.models.LibraryAgent.prisma().find_many( + where=where_clause, + include=library_agent_include( + user_id, + include_nodes=False, + include_executions=True, + execution_limit=1, + ), + ) + + def get_sort_key( + agent: prisma.models.LibraryAgent, + ) -> tuple[int, float]: + """ + Returns a tuple for sorting: (has_no_executions, -timestamp). + + Agents WITH executions come first (sorted by most recent execution), + agents WITHOUT executions come last (sorted by creation date). + + Uses updatedAt (not createdAt) because it reflects when the execution + completed or last progressed, showing recently-finished agents first. + """ + graph = agent.AgentGraph + if graph and graph.Executions and len(graph.Executions) > 0: + execution = graph.Executions[0] + timestamp = execution.updatedAt or execution.createdAt + return (0, -timestamp.timestamp()) + return (1, -agent.createdAt.timestamp()) + + library_agents.sort(key=get_sort_key) + + # Apply pagination after sorting + agent_count = len(library_agents) + start_idx = (page - 1) * page_size + end_idx = start_idx + page_size + library_agents = library_agents[start_idx:end_idx] + else: + # Standard sorting via database + library_agents = await prisma.models.LibraryAgent.prisma().find_many( + where=where_clause, + include=library_agent_include( + user_id, include_nodes=False, include_executions=False + ), + order=order_by, + skip=(page - 1) * page_size, + take=page_size, + ) + agent_count = await prisma.models.LibraryAgent.prisma().count( + where=where_clause + ) logger.debug( f"Retrieved {len(library_agents)} library agents for user #{user_id}" diff --git a/autogpt_platform/backend/backend/api/features/library/model.py b/autogpt_platform/backend/backend/api/features/library/model.py index c6bc0e0427..3ba4514115 100644 --- a/autogpt_platform/backend/backend/api/features/library/model.py +++ b/autogpt_platform/backend/backend/api/features/library/model.py @@ -442,6 +442,7 @@ class LibraryAgentSort(str, Enum): CREATED_AT = "createdAt" UPDATED_AT = "updatedAt" + LAST_EXECUTED = "lastExecuted" class LibraryAgentUpdateRequest(pydantic.BaseModel): diff --git a/autogpt_platform/backend/backend/api/features/library/routes/agents.py b/autogpt_platform/backend/backend/api/features/library/routes/agents.py index fa3d1a0f0c..688bbdd672 100644 --- a/autogpt_platform/backend/backend/api/features/library/routes/agents.py +++ b/autogpt_platform/backend/backend/api/features/library/routes/agents.py @@ -28,7 +28,7 @@ async def list_library_agents( None, description="Search term to filter agents" ), sort_by: library_model.LibraryAgentSort = Query( - library_model.LibraryAgentSort.UPDATED_AT, + library_model.LibraryAgentSort.LAST_EXECUTED, description="Criteria to sort results by", ), page: int = Query( diff --git a/autogpt_platform/backend/backend/data/includes.py b/autogpt_platform/backend/backend/data/includes.py index bc3d5c9dd1..9298bf2a75 100644 --- a/autogpt_platform/backend/backend/data/includes.py +++ b/autogpt_platform/backend/backend/data/includes.py @@ -119,7 +119,7 @@ def library_agent_include( if include_executions: agent_graph_include["Executions"] = { "where": {"userId": user_id}, - "order_by": {"createdAt": "desc"}, + "order_by": {"updatedAt": "desc"}, "take": execution_limit, }