import { SearchMatches, Message, } from '@memori.ai/memori-api-client/dist/types'; import { useCallback, useEffect, useState } from 'react'; import memoriApiClient from '@memori.ai/memori-api-client'; import Drawer from '../ui/Drawer'; import Spin from '../ui/Spin'; import Expandable from '../ui/Expandable'; import toast from 'react-hot-toast'; import { getErrori18nKey } from '../../helpers/error'; import { useTranslation } from 'react-i18next'; import Snippet from '../Snippet/Snippet'; import MediaWidget from '../MediaWidget/MediaWidget'; import Card from '../ui/Card'; export interface Props { sessionID: string; message: Message; initialMatches?: SearchMatches[]; visible?: boolean; closeDrawer: () => void; client?: ReturnType; _TEST_loading?: boolean; } const addQuestionMark = (question: string) => question.endsWith('?') ? question : `${question}?`; const WhyThisAnswer = ({ message, sessionID, visible = true, initialMatches = [], closeDrawer, client, _TEST_loading = false, }: Props) => { const { t } = useTranslation(); const searchMemory = client?.search.searchMemory; const [matches, setMatches] = useState(initialMatches); const [loading, setLoading] = useState(_TEST_loading); /** * Fetch matching memories */ const fetchMemories = useCallback(async () => { setLoading(true); if (_TEST_loading || !searchMemory) return; try { const { matches, ...response } = await searchMemory(sessionID, { searchType: 'Semantic', numberOfResults: 3, text: message.questionAnswered, date: message.date, placeName: message.placeName, placeLatitude: message.placeLatitude, placeLongitude: message.placeLongitude, placeUncertaintyKm: message.placeUncertaintyKm, contextVars: message.contextVars, tag: message.tag, memoryTags: message.memoryTags, }); if (response.resultCode !== 0) { console.error(response); toast.error(t(getErrori18nKey(response.resultCode))); } else { setMatches(matches ?? []); } } catch (err) { console.error('WHYTHISANSWER/FETCH', err); setMatches(initialMatches ?? []); } setLoading(false); }, [message, sessionID]); useEffect(() => { fetchMemories(); }, [fetchMemories, message, sessionID]); return ( closeDrawer()} title={t('whyThisAnswer')} >

{t('whyThisAnswerHelper')}

{message.questionAnswered && (

{t('question') || 'Question'}:{' '} {message.questionAnswered}

)} {!loading && matches.length === 0 && (

{t('nothingFound')}

)} {loading && matches.length === 0 && (
)} {matches.length > 0 && (
    {matches.map(m => (
  • {m.confidenceLevel}

    {addQuestionMark(m.memory.title ?? '')}

    {m.memory.titleVariants ?.map(t => addQuestionMark(t)) ?.join(' | ')}

    {(m.memory.receiverName || m.memory.receiverTag) && (

    {t('receiverLabel')}: {m.memory.receiverTag}{' '} {m.memory.receiverName}

    )}
    {m.memory.contextVars && (
    {Object.entries(m.memory.contextVars || {}).map( ([key, value]) => ( {key}: {value?.toString() || '✔️'} ) )}
    )} {m.memory.answers?.map((a, i) => (

    {a.text}

    ))} m.mimeType === 'text/html' )} /> {m.memory.media ?.filter(m => m.mimeType === 'text/plain') ?.map(m => ( ))}
  • ))}
)}
); }; export default WhyThisAnswer;