From de26322e18d85095199d0710464f15b54f5f40d7 Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Sat, 17 Jan 2026 02:52:30 +1000 Subject: [PATCH] fix: exclude existing collection tools from search results - Pass excludeIds param to search API to filter out already-added tools - Increase search limit to 50 (was 10) for large packages - Increase max API limit to 100 (was 50) - Add notIn filter to database query for efficient exclusion --- apps/web/src/app/api/tools/search/route.ts | 8 +++++++- .../src/components/collections/AddToolSearch.tsx | 15 +++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/apps/web/src/app/api/tools/search/route.ts b/apps/web/src/app/api/tools/search/route.ts index f7f68a3..b620549 100644 --- a/apps/web/src/app/api/tools/search/route.ts +++ b/apps/web/src/app/api/tools/search/route.ts @@ -93,7 +93,11 @@ export async function GET(request: NextRequest) { // Accept both 'q' and 'query' parameters for flexibility const query = searchParams.get('q') || searchParams.get('query') || ''; const category = searchParams.get('category'); - const limit = Math.min(Number.parseInt(searchParams.get('limit') || '10'), 50); + const limit = Math.min(Number.parseInt(searchParams.get('limit') || '10'), 100); + + // Parse excludeIds to filter out tools already in user's collection + const excludeIdsParam = searchParams.get('excludeIds'); + const excludeIds = excludeIdsParam ? excludeIdsParam.split(',').filter(Boolean) : []; // Get recent messages for context (passed as JSON in 'messages' param) // Wrap in try-catch to handle malformed JSON gracefully @@ -121,6 +125,8 @@ export async function GET(request: NextRequest) { // Build database filter - pre-filter at DB level to reduce in-memory processing // Use OR conditions to find tools that match ANY search token const dbFilter = { + // Exclude tools already in collection (if provided) + ...(excludeIds.length > 0 && { id: { notIn: excludeIds } }), ...(category && { package: { category } }), ...(hasSearchQuery && { OR: [ diff --git a/apps/web/src/components/collections/AddToolSearch.tsx b/apps/web/src/components/collections/AddToolSearch.tsx index b1b1244..285db58 100644 --- a/apps/web/src/components/collections/AddToolSearch.tsx +++ b/apps/web/src/components/collections/AddToolSearch.tsx @@ -58,9 +58,16 @@ export function AddToolSearch({ setError(null); try { - const response = await fetch( - `/api/tools/search?q=${encodeURIComponent(searchQuery)}&limit=10` - ); + // Build URL with excludeIds to avoid returning tools already in collection + const params = new URLSearchParams({ + q: searchQuery, + limit: '50', // Higher limit to handle large packages like @tpmjs/tools-unsandbox (59 tools) + }); + // Pass existing tool IDs so server can exclude them + if (existingToolIds.length > 0) { + params.set('excludeIds', existingToolIds.join(',')); + } + const response = await fetch(`/api/tools/search?${params.toString()}`); const data = await response.json(); if (data.success && data.results?.tools) { @@ -76,7 +83,7 @@ export function AddToolSearch({ } finally { setIsSearching(false); } - }, []); + }, [existingToolIds]); // Handle query changes with debounce useEffect(() => {