diff --git a/src/search/components/input/AskAIResults.tsx b/src/search/components/input/AskAIResults.tsx index 19060614aa24..8f6d4f28b2f4 100644 --- a/src/search/components/input/AskAIResults.tsx +++ b/src/search/components/input/AskAIResults.tsx @@ -76,7 +76,7 @@ export function AskAIResults({ const [conversationId, setConversationId] = useState('') - const handleAICannotAnswer = () => { + const handleAICannotAnswer = (passedConversationId?: string) => { setInitialLoading(false) setResponseLoading(false) setAICouldNotAnswer(true) @@ -87,6 +87,7 @@ export function AskAIResults({ eventGroupId: askAIEventGroupId.current, couldNotAnswer: true, status: 400, + connectedEventId: passedConversationId || conversationId, }) setMessage(cannedResponse) setAnnouncement(cannedResponse) @@ -98,6 +99,7 @@ export function AskAIResults({ message: cannedResponse, sources: [], aiCouldNotAnswer: true, + connectedEventId: passedConversationId || conversationId, }, version, router.locale || 'en', @@ -123,6 +125,7 @@ export function AskAIResults({ if (cachedData) { setMessage(cachedData.message) setReferences(cachedData.sources) + setConversationId(cachedData.connectedEventId || '') setAICouldNotAnswer(cachedData.aiCouldNotAnswer || false) setInitialLoading(false) setResponseLoading(false) @@ -150,10 +153,6 @@ export function AskAIResults({ try { const response = await executeAISearch(router, version, query, debug) - // Serve canned response. A question that cannot be answered was asked - if (response.status === 400) { - return handleAICannotAnswer() - } if (!response.ok) { console.error( `Failed to fetch search results.\nStatus ${response.status}\n${response.statusText}`, @@ -219,7 +218,14 @@ export function AskAIResults({ continue } - if (parsedLine.chunkType === 'SOURCES') { + // A conversation ID will still be sent when a question cannot be answered + if (parsedLine.chunkType === 'CONVERSATION_ID') { + conversationIdBuffer = parsedLine.conversation_id + setConversationId(parsedLine.conversation_id) + } else if (parsedLine.chunkType === 'NO_CONTENT_SIGNAL') { + // Serve canned response. A question that cannot be answered was asked + handleAICannotAnswer(conversationIdBuffer) + } else if (parsedLine.chunkType === 'SOURCES') { if (!isCancelled) { sourcesBuffer = sourcesBuffer.concat(parsedLine.sources) sourcesBuffer = uniqBy(sourcesBuffer, 'url') @@ -230,9 +236,9 @@ export function AskAIResults({ messageBuffer += parsedLine.text setMessage(messageBuffer) } - } else if (parsedLine.chunkType === 'CONVERSATION_ID') { - conversationIdBuffer = parsedLine.conversation_id - setConversationId(parsedLine.conversation_id) + } else if (parsedLine.chunkType === 'INPUT_CONTENT_FILTER') { + // Serve canned response. A spam question was asked + handleAICannotAnswer(conversationIdBuffer) } if (!isCancelled) { setAnnouncement('Copilot Response Loading...') diff --git a/src/search/lib/ai-search-proxy.ts b/src/search/lib/ai-search-proxy.ts index fbb897c2b56e..54d3d28146fb 100644 --- a/src/search/lib/ai-search-proxy.ts +++ b/src/search/lib/ai-search-proxy.ts @@ -80,14 +80,7 @@ export const aiSearchProxy = async (req: Request, res: Response) => { // Handle the upstream response before piping stream.on('response', (upstreamResponse) => { - // When cse-copilot returns a 204, it means the backend received the request - // but was unable to answer the question. So we return a 400 to the client to be handled. - if (upstreamResponse.statusCode === 204) { - statsd.increment('ai-search.unable_to_answer_query', 1, diagnosticTags) - return res - .status(400) - .json({ errors: [{ message: 'Sorry I am unable to answer this question.' }] }) - } else if (upstreamResponse.statusCode !== 200) { + if (upstreamResponse.statusCode !== 200) { const errorMessage = `Upstream server responded with status code ${upstreamResponse.statusCode}` console.error(errorMessage) statsd.increment('ai-search.stream_response_error', 1, diagnosticTags)