diff --git a/src/app/api/autocomplete/route.ts b/src/app/api/autocomplete/route.ts new file mode 100644 index 0000000..2bb28fc --- /dev/null +++ b/src/app/api/autocomplete/route.ts @@ -0,0 +1,79 @@ +import { NextResponse } from 'next/server'; +import { getSearxngApiEndpoint } from '@/lib/config'; + +/** + * Proxies autocomplete requests to SearXNG + */ +export async function GET(request: Request) { + try { + // Get the query parameter from the request URL + const { searchParams } = new URL(request.url); + const query = searchParams.get('q'); + + // Check if query exists + if (!query) { + return new NextResponse(JSON.stringify([query || '', []]), { + headers: { + 'Content-Type': 'application/x-suggestions+json', + }, + }); + } + + // Get the SearXNG API endpoint + const searxngUrl = getSearxngApiEndpoint(); + + if (!searxngUrl) { + console.error('SearXNG API endpoint not configured'); + return new NextResponse(JSON.stringify([query, []]), { + headers: { + 'Content-Type': 'application/x-suggestions+json', + }, + }); + } + + // Format the URL (remove trailing slashes) + const formattedSearxngUrl = searxngUrl.replace(/\/+$/, ''); + const autocompleteUrl = `${formattedSearxngUrl}/autocompleter?q=${encodeURIComponent(query)}`; + + // Make the request to SearXNG + const response = await fetch(autocompleteUrl, { + method: 'POST', // The example XML used POST method + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + signal: AbortSignal.timeout(3000), // 3 second timeout + }); + + if (!response.ok) { + console.error( + `SearXNG autocompleter returned status: ${response.status}`, + ); + return new NextResponse(JSON.stringify([query, []]), { + headers: { + 'Content-Type': 'application/x-suggestions+json', + }, + }); + } + + // Get the JSON response from SearXNG + const suggestions = await response.json(); + + // Return the suggestions in the expected format + console.log('SearXNG autocompleter response:', suggestions); + return new NextResponse(JSON.stringify(suggestions), { + headers: { + 'Content-Type': 'application/x-suggestions+json', + }, + }); + } catch (error) { + console.error('Error proxying to SearXNG autocompleter:', error); + + // Return an empty suggestion list on error + const query = new URL(request.url).searchParams.get('q') || ''; + return new NextResponse(JSON.stringify([query, []]), { + headers: { + 'Content-Type': 'application/x-suggestions+json', + }, + }); + } +} diff --git a/src/app/api/opensearch/route.ts b/src/app/api/opensearch/route.ts index f49535d..49abec1 100644 --- a/src/app/api/opensearch/route.ts +++ b/src/app/api/opensearch/route.ts @@ -13,6 +13,7 @@ function generateOpenSearchResponse(origin: string): NextResponse { UTF-8 ${origin}/favicon.ico + `; diff --git a/src/components/SearchImages.tsx b/src/components/SearchImages.tsx index c729a60..92bce94 100644 --- a/src/components/SearchImages.tsx +++ b/src/components/SearchImages.tsx @@ -32,9 +32,11 @@ const SearchImages = ({ const handleShowMore = () => { // If we're already showing all images, don't do anything if (images && displayLimit >= images.length) return; - + // Otherwise, increase the display limit by 10, or show all images - setDisplayLimit(prev => images ? Math.min(prev + 10, images.length) : prev); + setDisplayLimit((prev) => + images ? Math.min(prev + 10, images.length) : prev, + ); }; useEffect(() => { @@ -92,7 +94,6 @@ const SearchImages = ({ if (onImagesLoaded && images.length > 0) { onImagesLoaded(images.length); } - } catch (error) { console.error('Error fetching images:', error); } finally { @@ -101,7 +102,6 @@ const SearchImages = ({ }; fetchImages(); - }, [query, messageId, chatHistory, onImagesLoaded]); return ( @@ -118,7 +118,10 @@ const SearchImages = ({ )} {images !== null && images.length > 0 && ( <> -
+
{images.slice(0, displayLimit).map((image, i) => ( { @@ -142,8 +145,10 @@ const SearchImages = ({ onClick={handleShowMore} className="px-4 py-2 bg-light-secondary dark:bg-dark-secondary hover:bg-light-200 dark:hover:bg-dark-200 text-black/70 dark:text-white/70 hover:text-black dark:hover:text-white rounded-md transition duration-200 flex items-center space-x-2" > - Show More Images - ({displayLimit} of {images.length}) + Show More Images + + ({displayLimit} of {images.length}) +
)} diff --git a/src/components/SearchVideos.tsx b/src/components/SearchVideos.tsx index b8fd26f..34f32cd 100644 --- a/src/components/SearchVideos.tsx +++ b/src/components/SearchVideos.tsx @@ -48,9 +48,11 @@ const Searchvideos = ({ const handleShowMore = () => { // If we're already showing all videos, don't do anything if (videos && displayLimit >= videos.length) return; - + // Otherwise, increase the display limit by 10, or show all videos - setDisplayLimit(prev => videos ? Math.min(prev + 10, videos.length) : prev); + setDisplayLimit((prev) => + videos ? Math.min(prev + 10, videos.length) : prev, + ); }; useEffect(() => { @@ -118,7 +120,6 @@ const Searchvideos = ({ }; fetchVideos(); - }, [query, messageId, chatHistory, onVideosLoaded]); return ( @@ -135,7 +136,10 @@ const Searchvideos = ({ )} {videos !== null && videos.length > 0 && ( <> -
+
{videos.slice(0, displayLimit).map((video, i) => (
{ @@ -167,8 +171,10 @@ const Searchvideos = ({ onClick={handleShowMore} className="px-4 py-2 bg-light-secondary dark:bg-dark-secondary hover:bg-light-200 dark:hover:bg-dark-200 text-black/70 dark:text-white/70 hover:text-black dark:hover:text-white rounded-md transition duration-200 flex items-center space-x-2" > - Show More Videos - ({displayLimit} of {videos.length}) + Show More Videos + + ({displayLimit} of {videos.length}) +
)} diff --git a/src/lib/search/index.ts b/src/lib/search/index.ts index b5ea9bf..36bc60e 100644 --- a/src/lib/search/index.ts +++ b/src/lib/search/index.ts @@ -64,6 +64,6 @@ export const searchHandlers: Record = { rerankThreshold: 0.3, searchWeb: true, summarizer: false, - additionalSearchCriteria: "site:reddit.com", + additionalSearchCriteria: 'site:reddit.com', }), }; diff --git a/src/lib/search/metaSearchAgent.ts b/src/lib/search/metaSearchAgent.ts index c9025af..77adfff 100644 --- a/src/lib/search/metaSearchAgent.ts +++ b/src/lib/search/metaSearchAgent.ts @@ -207,7 +207,6 @@ class MetaSearchAgent implements MetaSearchAgentType { return { query: question, docs: docs }; } else { - if (this.config.additionalSearchCriteria) { question = `${question} ${this.config.additionalSearchCriteria}`; } @@ -249,7 +248,6 @@ class MetaSearchAgent implements MetaSearchAgentType { optimizationMode: 'speed' | 'balanced' | 'quality', systemInstructions: string, ) { - return RunnableSequence.from([ RunnableMap.from({ systemInstructions: () => systemInstructions,