diff --git a/autogpt_platform/backend/backend/api/features/chat/tools/agent_search.py b/autogpt_platform/backend/backend/api/features/chat/tools/agent_search.py index 61cdba1ef9..ec7b88f6b2 100644 --- a/autogpt_platform/backend/backend/api/features/chat/tools/agent_search.py +++ b/autogpt_platform/backend/backend/api/features/chat/tools/agent_search.py @@ -25,12 +25,20 @@ _UUID_PATTERN = re.compile( re.IGNORECASE, ) +# Keywords that should be treated as "list all" rather than a literal search +_LIST_ALL_KEYWORDS = frozenset({"all", "*", "everything", "any", ""}) + def _is_uuid(text: str) -> bool: """Check if text is a valid UUID v4.""" return bool(_UUID_PATTERN.match(text.strip())) +def _is_list_all_query(query: str) -> bool: + """Check if query should list all agents rather than search.""" + return query.lower().strip() in _LIST_ALL_KEYWORDS + + async def _get_library_agent_by_id(user_id: str, agent_id: str) -> AgentInfo | None: """Fetch a library agent by ID (library agent ID or graph_id). @@ -110,7 +118,8 @@ async def search_agents( Search for agents in marketplace or user library. Args: - query: Search query string + query: Search query string. For library searches, empty or special keywords + like "all" will list all agents without filtering. source: "marketplace" or "library" session_id: Chat session ID user_id: User ID (required for library search) @@ -118,7 +127,8 @@ async def search_agents( Returns: AgentsFoundResponse, NoResultsResponse, or ErrorResponse """ - if not query: + # For marketplace, we always need a search term + if source == "marketplace" and not query: return ErrorResponse( message="Please provide a search query", session_id=session_id ) @@ -129,6 +139,9 @@ async def search_agents( session_id=session_id, ) + # For library searches, treat special keywords as "list all" + list_all = source == "library" and _is_list_all_query(query) + agents: list[AgentInfo] = [] try: if source == "marketplace": @@ -158,10 +171,14 @@ async def search_agents( logger.info(f"Found agent by direct ID lookup: {agent.name}") if not agents: - logger.info(f"Searching user library for: {query}") + search_term = None if list_all else query + logger.info( + f"{'Listing all agents in' if list_all else 'Searching'} " + f"user library{'' if list_all else f' for: {query}'}" + ) results = await library_db.list_library_agents( user_id=user_id, # type: ignore[arg-type] - search_term=query, + search_term=search_term, page_size=10, ) for agent in results.agents: @@ -205,21 +222,34 @@ async def search_agents( "Check your library at /library", ] ) - no_results_msg = ( - f"No agents found matching '{query}'. Let the user know they can try different keywords or browse the marketplace. Also let them know you can create a custom agent for them based on their needs." - if source == "marketplace" - else f"No agents matching '{query}' found in your library. Let the user know you can create a custom agent for them based on their needs." - ) + if source == "marketplace": + no_results_msg = ( + f"No agents found matching '{query}'. Let the user know they can " + "try different keywords or browse the marketplace. Also let them " + "know you can create a custom agent for them based on their needs." + ) + elif list_all: + no_results_msg = ( + "The user's library is empty. Let them know they can browse the " + "marketplace to find agents, or you can create a custom agent " + "for them based on their needs." + ) + else: + no_results_msg = ( + f"No agents matching '{query}' found in your library. Let the user " + "know you can create a custom agent for them based on their needs." + ) return NoResultsResponse( message=no_results_msg, session_id=session_id, suggestions=suggestions ) - title = f"Found {len(agents)} agent{'s' if len(agents) != 1 else ''} " - title += ( - f"for '{query}'" - if source == "marketplace" - else f"in your library for '{query}'" - ) + agent_count_str = f"{len(agents)} agent{'s' if len(agents) != 1 else ''}" + if source == "marketplace": + title = f"Found {agent_count_str} for '{query}'" + elif list_all: + title = f"Found {agent_count_str} in your library" + else: + title = f"Found {agent_count_str} in your library for '{query}'" message = ( "Now you have found some options for the user to choose from. " diff --git a/autogpt_platform/backend/backend/api/features/chat/tools/find_library_agent.py b/autogpt_platform/backend/backend/api/features/chat/tools/find_library_agent.py index 108fba75ae..5062b3f4a2 100644 --- a/autogpt_platform/backend/backend/api/features/chat/tools/find_library_agent.py +++ b/autogpt_platform/backend/backend/api/features/chat/tools/find_library_agent.py @@ -21,7 +21,8 @@ class FindLibraryAgentTool(BaseTool): return ( "Search for agents in the user's library. Use this to find agents " "the user has already added to their library, including agents they " - "created or added from the marketplace." + "created or added from the marketplace. " + "Omit the query parameter or leave it empty to list all agents." ) @property @@ -31,10 +32,13 @@ class FindLibraryAgentTool(BaseTool): "properties": { "query": { "type": "string", - "description": "Search query to find agents by name or description.", + "description": ( + "Optional search query to filter agents by name or description. " + "Leave empty or omit to list all agents in the library." + ), }, }, - "required": ["query"], + "required": [], } @property