()
| 3 | import { useIndexContext } from 'renderer/context/IndexContext'; |
| 4 | |
| 5 | const useChat = () => { |
| 6 | const { generateCompletion, prompt } = useAIContext(); |
| 7 | const { vectorSearch, getThreadsAsText, latestThreads } = useIndexContext(); |
| 8 | |
| 9 | const STARTER = useMemo( |
| 10 | () => [ |
| 11 | { |
| 12 | role: 'system', |
| 13 | content: |
| 14 | 'You are a helpful assistant within a digital journaling app called Pile.', |
| 15 | }, |
| 16 | { |
| 17 | role: 'system', |
| 18 | content: |
| 19 | 'The user has provided a description of your personality:' + prompt, |
| 20 | }, |
| 21 | { |
| 22 | role: 'system', |
| 23 | content: `You are about to start a conversation with the user, usually involving reflection or discussion about their thoughts in this journal. For each of their messages, the system will provide a list of relevant journal entries as context to you, be aware of it when you answer and use whatever is relevant and appropriate. You are a wise librarian of my thoughts, providing advice and counsel. You try to keep responses concise and get to the point quickly. Plain-text responses only. You address the user as 'you', you don't need to know their name. You should engage with the user like you're a human. When you mention time, always do it relative to the current time– \nthe date and time at this moment is: ${new Date().toString()}.`, |
| 24 | }, |
| 25 | { |
| 26 | role: 'system', |
| 27 | content: `Here are the 10 latest journal entries from the user: \n\n${latestThreads}`, |
| 28 | }, |
| 29 | { role: 'system', content: 'The user starts the conversation:' }, |
| 30 | ], |
| 31 | [prompt, latestThreads] |
| 32 | ); |
| 33 | |
| 34 | const [messages, setMessages] = useState(STARTER); |
| 35 | |
| 36 | const resetMessages = useCallback(() => setMessages(STARTER), [STARTER]); |
| 37 | |
| 38 | const addMessage = useCallback( |
| 39 | async (message) => { |
| 40 | const lastSystemMessage = messages[messages.length - 1]; |
| 41 | const augmentedMessages = `${lastSystemMessage.content} \n\n${message}`; |
| 42 | const relevantEntries = await vectorSearch(augmentedMessages, 50); |
| 43 | const entryFilePaths = relevantEntries.map((entry) => entry.ref); |
| 44 | const threadsAsText = await getThreadsAsText(entryFilePaths); |
| 45 | |
| 46 | return [ |
| 47 | ...messages, |
| 48 | { |
| 49 | role: 'system', |
| 50 | content: |
| 51 | "Here are some relevant entries from the user's journal related to the user's message:" + |
| 52 | threadsAsText.join('\n'), |
| 53 | }, |
| 54 | { role: 'user', content: message }, |
| 55 | ]; |
| 56 | }, |
| 57 | [messages, vectorSearch, getThreadsAsText] |
| 58 | ); |
| 59 | |
| 60 | const getAIResponse = useCallback( |
| 61 | async (messages, callback = () => {}) => { |
| 62 | setMessages(messages); |
no test coverage detected