From e32c509cccf298cf56bed0eaefffd96d99299a49 Mon Sep 17 00:00:00 2001 From: Swifty Date: Mon, 13 Oct 2025 09:25:59 +0200 Subject: [PATCH] feat(backend): Simplify caching to just store routes (#11140) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Problem Limits caching to just the main marketplace routes ### Changes 🏗️ - **Simplified store cache implementation** in `backend/server/v2/store/cache.py` - Streamlined caching logic for better maintainability - Reduced complexity while maintaining performance - **Added cache invalidation on store updates** - Implemented cache clearing when new agents are added to the store - Added invalidation logic in admin store routes (`admin_store_routes.py`) - Ensures all pods reflect the latest store state after modifications - **Updated store database operations** in `backend/server/v2/store/db.py` - Modified to work with the new cache structure - **Added cache deletion tests** (`test_cache_delete.py`) - Validates cache invalidation works correctly - Ensures cache consistency across operations ### 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: - [x] Verify store listings are cached correctly - [x] Upload a new agent to the store and confirm cache is invalidated --- .../server/v2/admin/store_admin_routes.py | 11 ++ .../backend/backend/server/v2/store/cache.py | 76 ++++++++ .../backend/backend/server/v2/store/db.py | 21 ++ .../backend/backend/server/v2/store/routes.py | 183 +++--------------- .../server/v2/store/test_cache_delete.py | 138 ++----------- .../frontend/src/app/api/openapi.json | 16 +- 6 files changed, 159 insertions(+), 286 deletions(-) create mode 100644 autogpt_platform/backend/backend/server/v2/store/cache.py diff --git a/autogpt_platform/backend/backend/server/v2/admin/store_admin_routes.py b/autogpt_platform/backend/backend/server/v2/admin/store_admin_routes.py index 6a79eeb219..c611c43f5a 100644 --- a/autogpt_platform/backend/backend/server/v2/admin/store_admin_routes.py +++ b/autogpt_platform/backend/backend/server/v2/admin/store_admin_routes.py @@ -7,6 +7,7 @@ import fastapi import fastapi.responses import prisma.enums +import backend.server.v2.store.cache as store_cache import backend.server.v2.store.db import backend.server.v2.store.model import backend.util.json @@ -86,6 +87,11 @@ async def review_submission( StoreSubmission with updated review information """ try: + already_approved = ( + await backend.server.v2.store.db.check_submission_already_approved( + store_listing_version_id=store_listing_version_id, + ) + ) submission = await backend.server.v2.store.db.review_store_submission( store_listing_version_id=store_listing_version_id, is_approved=request.is_approved, @@ -93,6 +99,11 @@ async def review_submission( internal_comments=request.internal_comments or "", reviewer_id=user_id, ) + + state_changed = already_approved != request.is_approved + # Clear caches when the request is approved as it updates what is shown on the store + if state_changed: + store_cache.clear_all_caches() return submission except Exception as e: logger.exception("Error reviewing submission: %s", e) diff --git a/autogpt_platform/backend/backend/server/v2/store/cache.py b/autogpt_platform/backend/backend/server/v2/store/cache.py new file mode 100644 index 0000000000..8a212d61a4 --- /dev/null +++ b/autogpt_platform/backend/backend/server/v2/store/cache.py @@ -0,0 +1,76 @@ +from autogpt_libs.utils.cache import cached + +import backend.server.v2.store.db + +############################################## +############### Caches ####################### +############################################## + + +def clear_all_caches(): + """Clear all caches.""" + _get_cached_store_agents.cache_clear() + _get_cached_agent_details.cache_clear() + _get_cached_store_creators.cache_clear() + _get_cached_creator_details.cache_clear() + + +# Cache store agents list for 5 minutes +# Different cache entries for different query combinations +@cached(maxsize=5000, ttl_seconds=300) +async def _get_cached_store_agents( + featured: bool, + creator: str | None, + sorted_by: str | None, + search_query: str | None, + category: str | None, + page: int, + page_size: int, +): + """Cached helper to get store agents.""" + return await backend.server.v2.store.db.get_store_agents( + featured=featured, + creators=[creator] if creator else None, + sorted_by=sorted_by, + search_query=search_query, + category=category, + page=page, + page_size=page_size, + ) + + +# Cache individual agent details for 15 minutes +@cached(maxsize=200, ttl_seconds=300) +async def _get_cached_agent_details(username: str, agent_name: str): + """Cached helper to get agent details.""" + return await backend.server.v2.store.db.get_store_agent_details( + username=username, agent_name=agent_name + ) + + +# Cache creators list for 5 minutes +@cached(maxsize=200, ttl_seconds=300) +async def _get_cached_store_creators( + featured: bool, + search_query: str | None, + sorted_by: str | None, + page: int, + page_size: int, +): + """Cached helper to get store creators.""" + return await backend.server.v2.store.db.get_store_creators( + featured=featured, + search_query=search_query, + sorted_by=sorted_by, + page=page, + page_size=page_size, + ) + + +# Cache individual creator details for 5 minutes +@cached(maxsize=100, ttl_seconds=300) +async def _get_cached_creator_details(username: str): + """Cached helper to get creator details.""" + return await backend.server.v2.store.db.get_store_creator_details( + username=username.lower() + ) diff --git a/autogpt_platform/backend/backend/server/v2/store/db.py b/autogpt_platform/backend/backend/server/v2/store/db.py index 63a6ae772b..3c8676bb4d 100644 --- a/autogpt_platform/backend/backend/server/v2/store/db.py +++ b/autogpt_platform/backend/backend/server/v2/store/db.py @@ -1806,6 +1806,27 @@ async def get_admin_listings_with_versions( ) +async def check_submission_already_approved( + store_listing_version_id: str, +) -> bool: + """Check the submission status of a store listing version.""" + try: + store_listing_version = ( + await prisma.models.StoreListingVersion.prisma().find_unique( + where={"id": store_listing_version_id} + ) + ) + if not store_listing_version: + return False + return ( + store_listing_version.submissionStatus + == prisma.enums.SubmissionStatus.APPROVED + ) + except Exception as e: + logger.error(f"Error checking submission status: {e}") + return False + + async def get_agent_as_admin( user_id: str | None, store_listing_version_id: str, diff --git a/autogpt_platform/backend/backend/server/v2/store/routes.py b/autogpt_platform/backend/backend/server/v2/store/routes.py index f39482122e..8ce6c6a545 100644 --- a/autogpt_platform/backend/backend/server/v2/store/routes.py +++ b/autogpt_platform/backend/backend/server/v2/store/routes.py @@ -6,9 +6,9 @@ import urllib.parse import autogpt_libs.auth import fastapi import fastapi.responses -from autogpt_libs.utils.cache import cached import backend.data.graph +import backend.server.v2.store.cache as store_cache import backend.server.v2.store.db import backend.server.v2.store.exceptions import backend.server.v2.store.image_gen @@ -21,117 +21,6 @@ logger = logging.getLogger(__name__) router = fastapi.APIRouter() -############################################## -############### Caches ####################### -############################################## - - -# Cache user profiles for 1 hour per user -@cached(maxsize=1000, ttl_seconds=3600) -async def _get_cached_user_profile(user_id: str): - """Cached helper to get user profile.""" - return await backend.server.v2.store.db.get_user_profile(user_id) - - -# Cache store agents list for 15 minutes -# Different cache entries for different query combinations -@cached(maxsize=5000, ttl_seconds=900) -async def _get_cached_store_agents( - featured: bool, - creator: str | None, - sorted_by: str | None, - search_query: str | None, - category: str | None, - page: int, - page_size: int, -): - """Cached helper to get store agents.""" - return await backend.server.v2.store.db.get_store_agents( - featured=featured, - creators=[creator] if creator else None, - sorted_by=sorted_by, - search_query=search_query, - category=category, - page=page, - page_size=page_size, - ) - - -# Cache individual agent details for 15 minutes -@cached(maxsize=200, ttl_seconds=900) -async def _get_cached_agent_details(username: str, agent_name: str): - """Cached helper to get agent details.""" - return await backend.server.v2.store.db.get_store_agent_details( - username=username, agent_name=agent_name - ) - - -# Cache agent graphs for 1 hour -@cached(maxsize=200, ttl_seconds=3600) -async def _get_cached_agent_graph(store_listing_version_id: str): - """Cached helper to get agent graph.""" - return await backend.server.v2.store.db.get_available_graph( - store_listing_version_id - ) - - -# Cache agent by version for 1 hour -@cached(maxsize=200, ttl_seconds=3600) -async def _get_cached_store_agent_by_version(store_listing_version_id: str): - """Cached helper to get store agent by version ID.""" - return await backend.server.v2.store.db.get_store_agent_by_version_id( - store_listing_version_id - ) - - -# Cache creators list for 1 hour -@cached(maxsize=200, ttl_seconds=3600) -async def _get_cached_store_creators( - featured: bool, - search_query: str | None, - sorted_by: str | None, - page: int, - page_size: int, -): - """Cached helper to get store creators.""" - return await backend.server.v2.store.db.get_store_creators( - featured=featured, - search_query=search_query, - sorted_by=sorted_by, - page=page, - page_size=page_size, - ) - - -# Cache individual creator details for 1 hour -@cached(maxsize=100, ttl_seconds=3600) -async def _get_cached_creator_details(username: str): - """Cached helper to get creator details.""" - return await backend.server.v2.store.db.get_store_creator_details( - username=username.lower() - ) - - -# Cache user's own agents for 5 mins (shorter TTL as this changes more frequently) -@cached(maxsize=500, ttl_seconds=300) -async def _get_cached_my_agents(user_id: str, page: int, page_size: int): - """Cached helper to get user's agents.""" - return await backend.server.v2.store.db.get_my_agents( - user_id, page=page, page_size=page_size - ) - - -# Cache user's submissions for 1 hour (shorter TTL as this changes frequently) -@cached(maxsize=500, ttl_seconds=3600) -async def _get_cached_submissions(user_id: str, page: int, page_size: int): - """Cached helper to get user's submissions.""" - return await backend.server.v2.store.db.get_store_submissions( - user_id=user_id, - page=page, - page_size=page_size, - ) - - ############################################## ############### Profile Endpoints ############ ############################################## @@ -152,7 +41,7 @@ async def get_profile( Cached for 1 hour per user. """ try: - profile = await _get_cached_user_profile(user_id) + profile = await backend.server.v2.store.db.get_user_profile(user_id) if profile is None: return fastapi.responses.JSONResponse( status_code=404, @@ -198,8 +87,6 @@ async def update_or_create_profile( updated_profile = await backend.server.v2.store.db.update_profile( user_id=user_id, profile=profile ) - # Clear the cache for this user after profile update - _get_cached_user_profile.cache_delete(user_id) return updated_profile except Exception as e: logger.exception("Failed to update profile for user %s: %s", user_id, e) @@ -234,7 +121,6 @@ async def get_agents( ): """ Get a paginated list of agents from the store with optional filtering and sorting. - Results are cached for 15 minutes. Args: featured (bool, optional): Filter to only show featured agents. Defaults to False. @@ -270,7 +156,7 @@ async def get_agents( ) try: - agents = await _get_cached_store_agents( + agents = await store_cache._get_cached_store_agents( featured=featured, creator=creator, sorted_by=sorted_by, @@ -300,7 +186,6 @@ async def get_agents( async def get_agent(username: str, agent_name: str): """ This is only used on the AgentDetails Page. - Results are cached for 15 minutes. It returns the store listing agents details. """ @@ -308,7 +193,7 @@ async def get_agent(username: str, agent_name: str): username = urllib.parse.unquote(username).lower() # URL decode the agent name since it comes from the URL path agent_name = urllib.parse.unquote(agent_name).lower() - agent = await _get_cached_agent_details( + agent = await store_cache._get_cached_agent_details( username=username, agent_name=agent_name ) return agent @@ -331,10 +216,11 @@ async def get_agent(username: str, agent_name: str): async def get_graph_meta_by_store_listing_version_id(store_listing_version_id: str): """ Get Agent Graph from Store Listing Version ID. - Results are cached for 1 hour. """ try: - graph = await _get_cached_agent_graph(store_listing_version_id) + graph = await backend.server.v2.store.db.get_available_graph( + store_listing_version_id + ) return graph except Exception: logger.exception("Exception occurred whilst getting agent graph") @@ -354,10 +240,12 @@ async def get_graph_meta_by_store_listing_version_id(store_listing_version_id: s async def get_store_agent(store_listing_version_id: str): """ Get Store Agent Details from Store Listing Version ID. - Results are cached for 1 hour. """ try: - agent = await _get_cached_store_agent_by_version(store_listing_version_id) + agent = await backend.server.v2.store.db.get_store_agent_by_version_id( + store_listing_version_id + ) + return agent except Exception: logger.exception("Exception occurred whilst getting store agent") @@ -435,8 +323,6 @@ async def get_creators( - Home Page Featured Creators - Search Results Page - Results are cached for 1 hour. - --- To support this functionality we need: @@ -455,7 +341,7 @@ async def get_creators( ) try: - creators = await _get_cached_store_creators( + creators = await store_cache._get_cached_store_creators( featured=featured, search_query=search_query, sorted_by=sorted_by, @@ -482,12 +368,11 @@ async def get_creator( ): """ Get the details of a creator. - Results are cached for 1 hour. - Creator Details Page """ try: username = urllib.parse.unquote(username).lower() - creator = await _get_cached_creator_details(username=username) + creator = await store_cache._get_cached_creator_details(username=username) return creator except Exception: logger.exception("Exception occurred whilst getting creator details") @@ -518,10 +403,11 @@ async def get_my_agents( ): """ Get user's own agents. - Results are cached for 5 minutes per user. """ try: - agents = await _get_cached_my_agents(user_id, page=page, page_size=page_size) + agents = await backend.server.v2.store.db.get_my_agents( + user_id, page=page, page_size=page_size + ) return agents except Exception: logger.exception("Exception occurred whilst getting my agents") @@ -558,13 +444,6 @@ async def delete_submission( submission_id=submission_id, ) - # Clear submissions cache for this specific user after deletion - if result: - # Clear user's own agents cache - we don't know all page/size combinations - for page in range(1, 20): - # Clear user's submissions cache for common defaults - _get_cached_submissions.cache_delete(user_id, page=page, page_size=20) - return result except Exception: logger.exception("Exception occurred whilst deleting store submission") @@ -588,7 +467,6 @@ async def get_submissions( ): """ Get a paginated list of store submissions for the authenticated user. - Results are cached for 1 hour per user. Args: user_id (str): ID of the authenticated user @@ -611,8 +489,10 @@ async def get_submissions( status_code=422, detail="Page size must be greater than 0" ) try: - listings = await _get_cached_submissions( - user_id, page=page, page_size=page_size + listings = await backend.server.v2.store.db.get_store_submissions( + user_id=user_id, + page=page, + page_size=page_size, ) return listings except Exception: @@ -666,11 +546,6 @@ async def create_submission( recommended_schedule_cron=submission_request.recommended_schedule_cron, ) - # Clear user's own agents cache - we don't know all page/size combinations - for page in range(1, 20): - # Clear user's submissions cache for common defaults - _get_cached_submissions.cache_delete(user_id, page=page, page_size=20) - return result except Exception: logger.exception("Exception occurred whilst creating store submission") @@ -720,11 +595,6 @@ async def edit_submission( recommended_schedule_cron=submission_request.recommended_schedule_cron, ) - # Clear user's own agents cache - we don't know all page/size combinations - for page in range(1, 20): - # Clear user's submissions cache for common defaults - _get_cached_submissions.cache_delete(user_id, page=page, page_size=20) - return result @@ -917,15 +787,10 @@ async def get_cache_metrics(): ) # Add metrics for each cache - add_cache_metrics("user_profile", _get_cached_user_profile) - add_cache_metrics("store_agents", _get_cached_store_agents) - add_cache_metrics("agent_details", _get_cached_agent_details) - add_cache_metrics("agent_graph", _get_cached_agent_graph) - add_cache_metrics("agent_by_version", _get_cached_store_agent_by_version) - add_cache_metrics("store_creators", _get_cached_store_creators) - add_cache_metrics("creator_details", _get_cached_creator_details) - add_cache_metrics("my_agents", _get_cached_my_agents) - add_cache_metrics("submissions", _get_cached_submissions) + add_cache_metrics("store_agents", store_cache._get_cached_store_agents) + add_cache_metrics("agent_details", store_cache._get_cached_agent_details) + add_cache_metrics("store_creators", store_cache._get_cached_store_creators) + add_cache_metrics("creator_details", store_cache._get_cached_creator_details) # Add metadata/help text at the beginning prometheus_output = [ diff --git a/autogpt_platform/backend/backend/server/v2/store/test_cache_delete.py b/autogpt_platform/backend/backend/server/v2/store/test_cache_delete.py index 12d76c76e4..4111de0ee8 100644 --- a/autogpt_platform/backend/backend/server/v2/store/test_cache_delete.py +++ b/autogpt_platform/backend/backend/server/v2/store/test_cache_delete.py @@ -4,18 +4,12 @@ Test suite for verifying cache_delete functionality in store routes. Tests that specific cache entries can be deleted while preserving others. """ -import datetime from unittest.mock import AsyncMock, patch import pytest -from backend.server.v2.store import routes -from backend.server.v2.store.model import ( - ProfileDetails, - StoreAgent, - StoreAgentDetails, - StoreAgentsResponse, -) +from backend.server.v2.store import cache as store_cache +from backend.server.v2.store.model import StoreAgent, StoreAgentsResponse from backend.util.models import Pagination @@ -54,10 +48,10 @@ class TestCacheDeletion: return_value=mock_response, ) as mock_db: # Clear cache first - routes._get_cached_store_agents.cache_clear() + store_cache._get_cached_store_agents.cache_clear() # First call - should hit database - result1 = await routes._get_cached_store_agents( + result1 = await store_cache._get_cached_store_agents( featured=False, creator=None, sorted_by=None, @@ -70,7 +64,7 @@ class TestCacheDeletion: assert result1.agents[0].agent_name == "Test Agent" # Second call with same params - should use cache - await routes._get_cached_store_agents( + await store_cache._get_cached_store_agents( featured=False, creator=None, sorted_by=None, @@ -82,7 +76,7 @@ class TestCacheDeletion: assert mock_db.call_count == 1 # No additional DB call # Third call with different params - should hit database - await routes._get_cached_store_agents( + await store_cache._get_cached_store_agents( featured=True, # Different param creator=None, sorted_by=None, @@ -94,7 +88,7 @@ class TestCacheDeletion: assert mock_db.call_count == 2 # New DB call # Delete specific cache entry - deleted = routes._get_cached_store_agents.cache_delete( + deleted = store_cache._get_cached_store_agents.cache_delete( featured=False, creator=None, sorted_by=None, @@ -106,7 +100,7 @@ class TestCacheDeletion: assert deleted is True # Entry was deleted # Try to delete non-existent entry - deleted = routes._get_cached_store_agents.cache_delete( + deleted = store_cache._get_cached_store_agents.cache_delete( featured=False, creator="nonexistent", sorted_by=None, @@ -118,7 +112,7 @@ class TestCacheDeletion: assert deleted is False # Entry didn't exist # Call with deleted params - should hit database again - await routes._get_cached_store_agents( + await store_cache._get_cached_store_agents( featured=False, creator=None, sorted_by=None, @@ -130,7 +124,7 @@ class TestCacheDeletion: assert mock_db.call_count == 3 # New DB call after deletion # Call with featured=True - should still be cached - await routes._get_cached_store_agents( + await store_cache._get_cached_store_agents( featured=True, creator=None, sorted_by=None, @@ -141,105 +135,11 @@ class TestCacheDeletion: ) assert mock_db.call_count == 3 # No additional DB call - @pytest.mark.asyncio - async def test_agent_details_cache_delete(self): - """Test that specific agent details cache entries can be deleted.""" - mock_response = StoreAgentDetails( - store_listing_version_id="version1", - slug="test-agent", - agent_name="Test Agent", - agent_video="https://example.com/video.mp4", - agent_image=["https://example.com/image.jpg"], - creator="testuser", - creator_avatar="https://example.com/avatar.jpg", - sub_heading="Test subheading", - description="Test description", - categories=["productivity"], - runs=100, - rating=4.5, - versions=[], - last_updated=datetime.datetime(2024, 1, 1), - ) - - with patch( - "backend.server.v2.store.db.get_store_agent_details", - new_callable=AsyncMock, - return_value=mock_response, - ) as mock_db: - # Clear cache first - routes._get_cached_agent_details.cache_clear() - - # First call - should hit database - await routes._get_cached_agent_details( - username="testuser", agent_name="testagent" - ) - assert mock_db.call_count == 1 - - # Second call - should use cache - await routes._get_cached_agent_details( - username="testuser", agent_name="testagent" - ) - assert mock_db.call_count == 1 # No additional DB call - - # Delete specific entry - deleted = routes._get_cached_agent_details.cache_delete( - username="testuser", agent_name="testagent" - ) - assert deleted is True - - # Call again - should hit database - await routes._get_cached_agent_details( - username="testuser", agent_name="testagent" - ) - assert mock_db.call_count == 2 # New DB call after deletion - - @pytest.mark.asyncio - async def test_user_profile_cache_delete(self): - """Test that user profile cache entries can be deleted.""" - mock_response = ProfileDetails( - name="Test User", - username="testuser", - description="Test profile", - links=["https://example.com"], - ) - - with patch( - "backend.server.v2.store.db.get_user_profile", - new_callable=AsyncMock, - return_value=mock_response, - ) as mock_db: - # Clear cache first - routes._get_cached_user_profile.cache_clear() - - # First call - should hit database - await routes._get_cached_user_profile("user123") - assert mock_db.call_count == 1 - - # Second call - should use cache - await routes._get_cached_user_profile("user123") - assert mock_db.call_count == 1 - - # Different user - should hit database - await routes._get_cached_user_profile("user456") - assert mock_db.call_count == 2 - - # Delete specific user's cache - deleted = routes._get_cached_user_profile.cache_delete("user123") - assert deleted is True - - # user123 should hit database again - await routes._get_cached_user_profile("user123") - assert mock_db.call_count == 3 - - # user456 should still be cached - await routes._get_cached_user_profile("user456") - assert mock_db.call_count == 3 # No additional DB call - @pytest.mark.asyncio async def test_cache_info_after_deletions(self): """Test that cache_info correctly reflects deletions.""" # Clear all caches first - routes._get_cached_store_agents.cache_clear() + store_cache._get_cached_store_agents.cache_clear() mock_response = StoreAgentsResponse( agents=[], @@ -258,7 +158,7 @@ class TestCacheDeletion: ): # Add multiple entries for i in range(5): - await routes._get_cached_store_agents( + await store_cache._get_cached_store_agents( featured=False, creator=f"creator{i}", sorted_by=None, @@ -269,12 +169,12 @@ class TestCacheDeletion: ) # Check cache size - info = routes._get_cached_store_agents.cache_info() + info = store_cache._get_cached_store_agents.cache_info() assert info["size"] == 5 # Delete some entries for i in range(2): - deleted = routes._get_cached_store_agents.cache_delete( + deleted = store_cache._get_cached_store_agents.cache_delete( featured=False, creator=f"creator{i}", sorted_by=None, @@ -286,7 +186,7 @@ class TestCacheDeletion: assert deleted is True # Check cache size after deletion - info = routes._get_cached_store_agents.cache_info() + info = store_cache._get_cached_store_agents.cache_info() assert info["size"] == 3 @pytest.mark.asyncio @@ -307,10 +207,10 @@ class TestCacheDeletion: new_callable=AsyncMock, return_value=mock_response, ) as mock_db: - routes._get_cached_store_agents.cache_clear() + store_cache._get_cached_store_agents.cache_clear() # Test with all parameters - await routes._get_cached_store_agents( + await store_cache._get_cached_store_agents( featured=True, creator="testuser", sorted_by="rating", @@ -322,7 +222,7 @@ class TestCacheDeletion: assert mock_db.call_count == 1 # Delete with exact same parameters - deleted = routes._get_cached_store_agents.cache_delete( + deleted = store_cache._get_cached_store_agents.cache_delete( featured=True, creator="testuser", sorted_by="rating", @@ -334,7 +234,7 @@ class TestCacheDeletion: assert deleted is True # Try to delete with slightly different parameters - deleted = routes._get_cached_store_agents.cache_delete( + deleted = store_cache._get_cached_store_agents.cache_delete( featured=True, creator="testuser", sorted_by="rating", diff --git a/autogpt_platform/frontend/src/app/api/openapi.json b/autogpt_platform/frontend/src/app/api/openapi.json index 744adf0944..39494b1b1f 100644 --- a/autogpt_platform/frontend/src/app/api/openapi.json +++ b/autogpt_platform/frontend/src/app/api/openapi.json @@ -2553,7 +2553,7 @@ "get": { "tags": ["v2", "store", "public"], "summary": "List store agents", - "description": "Get a paginated list of agents from the store with optional filtering and sorting.\nResults are cached for 15 minutes.\n\nArgs:\n featured (bool, optional): Filter to only show featured agents. Defaults to False.\n creator (str | None, optional): Filter agents by creator username. Defaults to None.\n sorted_by (str | None, optional): Sort agents by \"runs\" or \"rating\". Defaults to None.\n search_query (str | None, optional): Search agents by name, subheading and description. Defaults to None.\n category (str | None, optional): Filter agents by category. Defaults to None.\n page (int, optional): Page number for pagination. Defaults to 1.\n page_size (int, optional): Number of agents per page. Defaults to 20.\n\nReturns:\n StoreAgentsResponse: Paginated list of agents matching the filters\n\nRaises:\n HTTPException: If page or page_size are less than 1\n\nUsed for:\n- Home Page Featured Agents\n- Home Page Top Agents\n- Search Results\n- Agent Details - Other Agents By Creator\n- Agent Details - Similar Agents\n- Creator Details - Agents By Creator", + "description": "Get a paginated list of agents from the store with optional filtering and sorting.\n\nArgs:\n featured (bool, optional): Filter to only show featured agents. Defaults to False.\n creator (str | None, optional): Filter agents by creator username. Defaults to None.\n sorted_by (str | None, optional): Sort agents by \"runs\" or \"rating\". Defaults to None.\n search_query (str | None, optional): Search agents by name, subheading and description. Defaults to None.\n category (str | None, optional): Filter agents by category. Defaults to None.\n page (int, optional): Page number for pagination. Defaults to 1.\n page_size (int, optional): Number of agents per page. Defaults to 20.\n\nReturns:\n StoreAgentsResponse: Paginated list of agents matching the filters\n\nRaises:\n HTTPException: If page or page_size are less than 1\n\nUsed for:\n- Home Page Featured Agents\n- Home Page Top Agents\n- Search Results\n- Agent Details - Other Agents By Creator\n- Agent Details - Similar Agents\n- Creator Details - Agents By Creator", "operationId": "getV2List store agents", "parameters": [ { @@ -2639,7 +2639,7 @@ "get": { "tags": ["v2", "store", "public"], "summary": "Get specific agent", - "description": "This is only used on the AgentDetails Page.\nResults are cached for 15 minutes.\n\nIt returns the store listing agents details.", + "description": "This is only used on the AgentDetails Page.\n\nIt returns the store listing agents details.", "operationId": "getV2Get specific agent", "parameters": [ { @@ -2679,7 +2679,7 @@ "get": { "tags": ["v2", "store"], "summary": "Get agent graph", - "description": "Get Agent Graph from Store Listing Version ID.\nResults are cached for 1 hour.", + "description": "Get Agent Graph from Store Listing Version ID.", "operationId": "getV2Get agent graph", "security": [{ "HTTPBearerJWT": [] }], "parameters": [ @@ -2713,7 +2713,7 @@ "get": { "tags": ["v2", "store"], "summary": "Get agent by version", - "description": "Get Store Agent Details from Store Listing Version ID.\nResults are cached for 1 hour.", + "description": "Get Store Agent Details from Store Listing Version ID.", "operationId": "getV2Get agent by version", "security": [{ "HTTPBearerJWT": [] }], "parameters": [ @@ -2803,7 +2803,7 @@ "get": { "tags": ["v2", "store", "public"], "summary": "List store creators", - "description": "This is needed for:\n- Home Page Featured Creators\n- Search Results Page\n\nResults are cached for 1 hour.\n\n---\n\nTo support this functionality we need:\n- featured: bool - to limit the list to just featured agents\n- search_query: str - vector search based on the creators profile description.\n- sorted_by: [agent_rating, agent_runs] -", + "description": "This is needed for:\n- Home Page Featured Creators\n- Search Results Page\n\n---\n\nTo support this functionality we need:\n- featured: bool - to limit the list to just featured agents\n- search_query: str - vector search based on the creators profile description.\n- sorted_by: [agent_rating, agent_runs] -", "operationId": "getV2List store creators", "parameters": [ { @@ -2871,7 +2871,7 @@ "get": { "tags": ["v2", "store", "public"], "summary": "Get creator details", - "description": "Get the details of a creator.\nResults are cached for 1 hour.\n- Creator Details Page", + "description": "Get the details of a creator.\n- Creator Details Page", "operationId": "getV2Get creator details", "parameters": [ { @@ -2905,7 +2905,7 @@ "get": { "tags": ["v2", "store", "private"], "summary": "Get my agents", - "description": "Get user's own agents.\nResults are cached for 5 minutes per user.", + "description": "Get user's own agents.", "operationId": "getV2Get my agents", "security": [{ "HTTPBearerJWT": [] }], "parameters": [ @@ -3000,7 +3000,7 @@ "get": { "tags": ["v2", "store", "private"], "summary": "List my submissions", - "description": "Get a paginated list of store submissions for the authenticated user.\nResults are cached for 1 hour per user.\n\nArgs:\n user_id (str): ID of the authenticated user\n page (int, optional): Page number for pagination. Defaults to 1.\n page_size (int, optional): Number of submissions per page. Defaults to 20.\n\nReturns:\n StoreListingsResponse: Paginated list of store submissions\n\nRaises:\n HTTPException: If page or page_size are less than 1", + "description": "Get a paginated list of store submissions for the authenticated user.\n\nArgs:\n user_id (str): ID of the authenticated user\n page (int, optional): Page number for pagination. Defaults to 1.\n page_size (int, optional): Number of submissions per page. Defaults to 20.\n\nReturns:\n StoreListingsResponse: Paginated list of store submissions\n\nRaises:\n HTTPException: If page or page_size are less than 1", "operationId": "getV2List my submissions", "security": [{ "HTTPBearerJWT": [] }], "parameters": [