diff --git a/src/components/AssistantSteps.tsx b/src/components/AssistantSteps.tsx index c715a924..748463f6 100644 --- a/src/components/AssistantSteps.tsx +++ b/src/components/AssistantSteps.tsx @@ -37,7 +37,8 @@ const getStepTitle = ( if (step.type === 'reasoning') { return isStreaming && !step.reasoning ? 'Thinking...' : 'Thinking'; } else if (step.type === 'searching') { - return `Searching ${step.searching.length} ${step.searching.length === 1 ? 'query' : 'queries'}`; + const queries = Array.isArray(step.searching) ? step.searching : []; + return `Searching ${queries.length} ${queries.length === 1 ? 'query' : 'queries'}`; } else if (step.type === 'search_results') { return `Found ${step.reading.length} ${step.reading.length === 1 ? 'result' : 'results'}`; } else if (step.type === 'reading') { @@ -160,6 +161,7 @@ const AssistantSteps = ({ )} {step.type === 'searching' && + Array.isArray(step.searching) && step.searching.length > 0 && (
{step.searching.map((query, idx) => ( diff --git a/src/lib/agents/search/api.ts b/src/lib/agents/search/api.ts index 924bc68f..94b70ae9 100644 --- a/src/lib/agents/search/api.ts +++ b/src/lib/agents/search/api.ts @@ -19,6 +19,9 @@ class APISearchAgent { chatHistory: input.chatHistory, followUp: input.followUp, llm: input.config.llm, + }).catch((err) => { + console.error(`Error executing widgets: ${err}`); + return []; }); let searchPromise: Promise | null = null; diff --git a/src/lib/agents/search/researcher/actions/academicSearch.ts b/src/lib/agents/search/researcher/actions/academicSearch.ts index 72e1f4b1..0ae822c7 100644 --- a/src/lib/agents/search/researcher/actions/academicSearch.ts +++ b/src/lib/agents/search/researcher/actions/academicSearch.ts @@ -30,7 +30,7 @@ const academicSearchAction: ResearchAction = { config.classification.classification.skipSearch === false && config.classification.classification.academicSearch === true, execute: async (input, additionalConfig) => { - input.queries = input.queries.slice(0, 3); + input.queries = (Array.isArray(input.queries) ? input.queries : [input.queries]).slice(0, 3); const researchBlock = additionalConfig.session.getBlock( additionalConfig.researchBlockId, diff --git a/src/lib/agents/search/researcher/actions/socialSearch.ts b/src/lib/agents/search/researcher/actions/socialSearch.ts index 16468ab4..e22d5b79 100644 --- a/src/lib/agents/search/researcher/actions/socialSearch.ts +++ b/src/lib/agents/search/researcher/actions/socialSearch.ts @@ -30,7 +30,7 @@ const socialSearchAction: ResearchAction = { config.classification.classification.skipSearch === false && config.classification.classification.discussionSearch === true, execute: async (input, additionalConfig) => { - input.queries = input.queries.slice(0, 3); + input.queries = (Array.isArray(input.queries) ? input.queries : [input.queries]).slice(0, 3); const researchBlock = additionalConfig.session.getBlock( additionalConfig.researchBlockId, diff --git a/src/lib/agents/search/researcher/actions/webSearch.ts b/src/lib/agents/search/researcher/actions/webSearch.ts index 4d60b79f..d1785e2b 100644 --- a/src/lib/agents/search/researcher/actions/webSearch.ts +++ b/src/lib/agents/search/researcher/actions/webSearch.ts @@ -85,7 +85,7 @@ const webSearchAction: ResearchAction = { config.sources.includes('web') && config.classification.classification.skipSearch === false, execute: async (input, additionalConfig) => { - input.queries = input.queries.slice(0, 3); + input.queries = (Array.isArray(input.queries) ? input.queries : [input.queries]).slice(0, 3); const researchBlock = additionalConfig.session.getBlock( additionalConfig.researchBlockId, diff --git a/src/lib/searxng.ts b/src/lib/searxng.ts index a0bcd835..87767e09 100644 --- a/src/lib/searxng.ts +++ b/src/lib/searxng.ts @@ -38,11 +38,30 @@ export const searchSearxng = async ( }); } - const res = await fetch(url); - const data = await res.json(); + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 10000); - const results: SearxngSearchResult[] = data.results; - const suggestions: string[] = data.suggestions; + try { + const res = await fetch(url, { + signal: controller.signal, + }); - return { results, suggestions }; + if (!res.ok) { + throw new Error(`SearXNG error: ${res.statusText}`); + } + + const data = await res.json(); + + const results: SearxngSearchResult[] = data.results; + const suggestions: string[] = data.suggestions; + + return { results, suggestions }; + } catch (err: any) { + if (err.name === 'AbortError') { + throw new Error('SearXNG search timed out'); + } + throw err; + } finally { + clearTimeout(timeoutId); + } };