Merge pull request #184 from Webifi/main
Fix choppy streaming, mask UI blocking
This commit is contained in:
		
						commit
						c592cd639b
					
				| 
						 | 
					@ -9,7 +9,12 @@
 | 
				
			||||||
    showSetChatSettings,
 | 
					    showSetChatSettings,
 | 
				
			||||||
    submitExitingPromptsNow,
 | 
					    submitExitingPromptsNow,
 | 
				
			||||||
    continueMessage,
 | 
					    continueMessage,
 | 
				
			||||||
    getMessage
 | 
					    getMessage,
 | 
				
			||||||
 | 
					    currentChatMessages,
 | 
				
			||||||
 | 
					    setCurrentChat,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    currentChatId
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  } from './Storage.svelte'
 | 
					  } from './Storage.svelte'
 | 
				
			||||||
  import {
 | 
					  import {
 | 
				
			||||||
    type Message,
 | 
					    type Message,
 | 
				
			||||||
| 
						 | 
					@ -82,9 +87,9 @@
 | 
				
			||||||
        submitForm(false, true)
 | 
					        submitForm(false, true)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if ($continueMessage) {
 | 
					      if ($continueMessage) {
 | 
				
			||||||
        const message = getMessage(chat, $continueMessage)
 | 
					        const message = getMessage(chatId, $continueMessage)
 | 
				
			||||||
        $continueMessage = ''
 | 
					        $continueMessage = ''
 | 
				
			||||||
        if (message && chat.messages.indexOf(message) === (chat.messages.length - 1)) {
 | 
					        if (message && $currentChatMessages.indexOf(message) === ($currentChatMessages.length - 1)) {
 | 
				
			||||||
          submitForm(lastSubmitRecorded, true, message)
 | 
					          submitForm(lastSubmitRecorded, true, message)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -93,6 +98,7 @@
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  $: onStateChange($checkStateChange, $showSetChatSettings, $submitExitingPromptsNow, $continueMessage)
 | 
					  $: onStateChange($checkStateChange, $showSetChatSettings, $submitExitingPromptsNow, $continueMessage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  setCurrentChat(0)
 | 
				
			||||||
  // Make sure chat object is ready to go
 | 
					  // Make sure chat object is ready to go
 | 
				
			||||||
  updateChatSettings(chatId)
 | 
					  updateChatSettings(chatId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,6 +112,8 @@
 | 
				
			||||||
  onMount(async () => {
 | 
					  onMount(async () => {
 | 
				
			||||||
    if (!chat) return
 | 
					    if (!chat) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setCurrentChat(chatId)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    chatRequest = new ChatRequest()
 | 
					    chatRequest = new ChatRequest()
 | 
				
			||||||
    chatRequest.setChat(chat)
 | 
					    chatRequest.setChat(chat)
 | 
				
			||||||
    // Focus the input on mount
 | 
					    // Focus the input on mount
 | 
				
			||||||
| 
						 | 
					@ -164,9 +172,9 @@
 | 
				
			||||||
  const addNewMessage = () => {
 | 
					  const addNewMessage = () => {
 | 
				
			||||||
    if (chatRequest.updating) return
 | 
					    if (chatRequest.updating) return
 | 
				
			||||||
    let inputMessage: Message
 | 
					    let inputMessage: Message
 | 
				
			||||||
    const lastMessage = chat.messages[chat.messages.length - 1]
 | 
					    const lastMessage = $currentChatMessages[$currentChatMessages.length - 1]
 | 
				
			||||||
    const uuid = uuidv4()
 | 
					    const uuid = uuidv4()
 | 
				
			||||||
    if (chat.messages.length === 0) {
 | 
					    if ($currentChatMessages.length === 0) {
 | 
				
			||||||
      inputMessage = { role: 'system', content: input.value, uuid }
 | 
					      inputMessage = { role: 'system', content: input.value, uuid }
 | 
				
			||||||
    } else if (lastMessage && lastMessage.role === 'user') {
 | 
					    } else if (lastMessage && lastMessage.role === 'user') {
 | 
				
			||||||
      inputMessage = { role: 'assistant', content: input.value, uuid }
 | 
					      inputMessage = { role: 'assistant', content: input.value, uuid }
 | 
				
			||||||
| 
						 | 
					@ -220,8 +228,8 @@
 | 
				
			||||||
        // Compose the input message
 | 
					        // Compose the input message
 | 
				
			||||||
        const inputMessage: Message = { role: 'user', content: input.value, uuid: uuidv4() }
 | 
					        const inputMessage: Message = { role: 'user', content: input.value, uuid: uuidv4() }
 | 
				
			||||||
        addMessage(chatId, inputMessage)
 | 
					        addMessage(chatId, inputMessage)
 | 
				
			||||||
      } else if (!fillMessage && chat.messages.length && chat.messages[chat.messages.length - 1].finish_reason === 'length') {
 | 
					      } else if (!fillMessage && $currentChatMessages.length && $currentChatMessages[$currentChatMessages.length - 1].finish_reason === 'length') {
 | 
				
			||||||
        fillMessage = chat.messages[chat.messages.length - 1]
 | 
					        fillMessage = $currentChatMessages[$currentChatMessages.length - 1]
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
      // Clear the input value
 | 
					      // Clear the input value
 | 
				
			||||||
| 
						 | 
					@ -237,7 +245,7 @@
 | 
				
			||||||
    chatRequest.updatingMessage = ''
 | 
					    chatRequest.updatingMessage = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      const response = await chatRequest.sendRequest(chat.messages, {
 | 
					      const response = await chatRequest.sendRequest($currentChatMessages, {
 | 
				
			||||||
        chat,
 | 
					        chat,
 | 
				
			||||||
        autoAddMessages: true, // Auto-add and update messages in array
 | 
					        autoAddMessages: true, // Auto-add and update messages in array
 | 
				
			||||||
        streaming: chatSettings.stream,
 | 
					        streaming: chatSettings.stream,
 | 
				
			||||||
| 
						 | 
					@ -268,7 +276,7 @@
 | 
				
			||||||
      uuid: uuidv4()
 | 
					      uuid: uuidv4()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const suggestMessages = chat.messages.slice(0, 10) // limit to first 10 messages
 | 
					    const suggestMessages = $currentChatMessages.slice(0, 10) // limit to first 10 messages
 | 
				
			||||||
    suggestMessages.push(suggestMessage)
 | 
					    suggestMessages.push(suggestMessage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const response = await chatRequest.sendRequest(suggestMessages, {
 | 
					    const response = await chatRequest.sendRequest(suggestMessages, {
 | 
				
			||||||
| 
						 | 
					@ -346,9 +354,9 @@
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</nav>
 | 
					</nav>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<Messages messages={chat.messages} chatId={chatId} />
 | 
					<Messages messages={$currentChatMessages} chatId={chatId} chat={chat} />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{#if chatRequest.updating === true}
 | 
					{#if chatRequest.updating === true || $currentChatId === 0}
 | 
				
			||||||
  <article class="message is-success assistant-message">
 | 
					  <article class="message is-success assistant-message">
 | 
				
			||||||
    <div class="message-body content">
 | 
					    <div class="message-body content">
 | 
				
			||||||
      <span class="is-loading" ></span>
 | 
					      <span class="is-loading" ></span>
 | 
				
			||||||
| 
						 | 
					@ -357,7 +365,7 @@
 | 
				
			||||||
  </article>
 | 
					  </article>
 | 
				
			||||||
{/if}
 | 
					{/if}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{#if chat.messages.length === 0 || (chat.messages.length === 1 && chat.messages[0].role === 'system')}
 | 
					{#if $currentChatId !== 0 && ($currentChatMessages.length === 0 || ($currentChatMessages.length === 1 && $currentChatMessages[0].role === 'system'))}
 | 
				
			||||||
  <Prompts bind:input />
 | 
					  <Prompts bind:input />
 | 
				
			||||||
{/if}
 | 
					{/if}
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,12 +3,13 @@
 | 
				
			||||||
    import { mergeProfileFields, prepareSummaryPrompt } from './Profiles.svelte'
 | 
					    import { mergeProfileFields, prepareSummaryPrompt } from './Profiles.svelte'
 | 
				
			||||||
    import { countMessageTokens, countPromptTokens, getModelMaxTokens } from './Stats.svelte'
 | 
					    import { countMessageTokens, countPromptTokens, getModelMaxTokens } from './Stats.svelte'
 | 
				
			||||||
    import type { Chat, ChatCompletionOpts, ChatSettings, Message, Model, Request, RequestImageGeneration } from './Types.svelte'
 | 
					    import type { Chat, ChatCompletionOpts, ChatSettings, Message, Model, Request, RequestImageGeneration } from './Types.svelte'
 | 
				
			||||||
    import { deleteMessage, getChatSettingValueNullDefault, insertMessages, saveChatStore, getApiKey, addError } from './Storage.svelte'
 | 
					    import { deleteMessage, getChatSettingValueNullDefault, insertMessages, getApiKey, addError, currentChatMessages, getMessages, updateMessages } from './Storage.svelte'
 | 
				
			||||||
    import { scrollToBottom, scrollToMessage } from './Util.svelte'
 | 
					    import { scrollToBottom, scrollToMessage } from './Util.svelte'
 | 
				
			||||||
    import { getRequestSettingList, defaultModel } from './Settings.svelte'
 | 
					    import { getRequestSettingList, defaultModel } from './Settings.svelte'
 | 
				
			||||||
    import { EventStreamContentType, fetchEventSource } from '@microsoft/fetch-event-source'
 | 
					    import { EventStreamContentType, fetchEventSource } from '@microsoft/fetch-event-source'
 | 
				
			||||||
    import { getApiBase, getEndpointCompletions, getEndpointGenerations } from './ApiUtil.svelte'
 | 
					    import { getApiBase, getEndpointCompletions, getEndpointGenerations } from './ApiUtil.svelte'
 | 
				
			||||||
    import { v4 as uuidv4 } from 'uuid'
 | 
					    import { v4 as uuidv4 } from 'uuid'
 | 
				
			||||||
 | 
					    import { get } from 'svelte/store'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class ChatRequest {
 | 
					export class ChatRequest {
 | 
				
			||||||
      constructor () {
 | 
					      constructor () {
 | 
				
			||||||
| 
						 | 
					@ -317,7 +318,7 @@ export class ChatRequest {
 | 
				
			||||||
        const maxTokens = getModelMaxTokens(model) // max tokens for model
 | 
					        const maxTokens = getModelMaxTokens(model) // max tokens for model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const continueRequest = async () => {
 | 
					        const continueRequest = async () => {
 | 
				
			||||||
          return await _this.sendRequest(chat.messages, {
 | 
					          return await _this.sendRequest(getMessages(chatId), {
 | 
				
			||||||
            ...opts,
 | 
					            ...opts,
 | 
				
			||||||
            didSummary: true
 | 
					            didSummary: true
 | 
				
			||||||
          }, overrides)
 | 
					          }, overrides)
 | 
				
			||||||
| 
						 | 
					@ -358,7 +359,7 @@ export class ChatRequest {
 | 
				
			||||||
            promptSize = countPromptTokens(top.concat(rw), model) + countPadding
 | 
					            promptSize = countPromptTokens(top.concat(rw), model) + countPadding
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          // Run a new request, now with the rolled messages hidden
 | 
					          // Run a new request, now with the rolled messages hidden
 | 
				
			||||||
          return await _this.sendRequest(chat.messages, {
 | 
					          return await _this.sendRequest(get(currentChatMessages), {
 | 
				
			||||||
            ...opts,
 | 
					            ...opts,
 | 
				
			||||||
            didSummary: true // our "summary" was simply dropping some messages
 | 
					            didSummary: true // our "summary" was simply dropping some messages
 | 
				
			||||||
          }, overrides)
 | 
					          }, overrides)
 | 
				
			||||||
| 
						 | 
					@ -466,11 +467,11 @@ export class ChatRequest {
 | 
				
			||||||
          summaryResponse.summary = summarizedIds
 | 
					          summaryResponse.summary = summarizedIds
 | 
				
			||||||
          // Disable the messages we summarized so they still show in history
 | 
					          // Disable the messages we summarized so they still show in history
 | 
				
			||||||
          rw.forEach((m, i) => { m.summarized = summaryIds })
 | 
					          rw.forEach((m, i) => { m.summarized = summaryIds })
 | 
				
			||||||
          saveChatStore()
 | 
					          updateMessages(chatId)
 | 
				
			||||||
          // Re-run request with summarized prompts
 | 
					          // Re-run request with summarized prompts
 | 
				
			||||||
          _this.updatingMessage = 'Continuing...'
 | 
					          _this.updatingMessage = 'Continuing...'
 | 
				
			||||||
          scrollToBottom(true)
 | 
					          scrollToBottom(true)
 | 
				
			||||||
          return await _this.sendRequest(chat.messages, {
 | 
					          return await _this.sendRequest(get(currentChatMessages), {
 | 
				
			||||||
            ...opts,
 | 
					            ...opts,
 | 
				
			||||||
            didSummary: true
 | 
					            didSummary: true
 | 
				
			||||||
          },
 | 
					          },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
  import Code from './Code.svelte'
 | 
					  import Code from './Code.svelte'
 | 
				
			||||||
  import { afterUpdate, createEventDispatcher, onMount } from 'svelte'
 | 
					  import { afterUpdate, createEventDispatcher, onMount } from 'svelte'
 | 
				
			||||||
  import { deleteMessage, chatsStorage, deleteSummaryMessage, truncateFromMessage, submitExitingPromptsNow, saveChatStore, continueMessage } from './Storage.svelte'
 | 
					  import { deleteMessage, deleteSummaryMessage, truncateFromMessage, submitExitingPromptsNow, continueMessage, updateMessages } from './Storage.svelte'
 | 
				
			||||||
  import { getPrice } from './Stats.svelte'
 | 
					  import { getPrice } from './Stats.svelte'
 | 
				
			||||||
  import SvelteMarkdown from 'svelte-markdown'
 | 
					  import SvelteMarkdown from 'svelte-markdown'
 | 
				
			||||||
  import type { Message, Model, Chat } from './Types.svelte'
 | 
					  import type { Message, Model, Chat } from './Types.svelte'
 | 
				
			||||||
| 
						 | 
					@ -14,9 +14,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let message:Message
 | 
					  export let message:Message
 | 
				
			||||||
  export let chatId:number
 | 
					  export let chatId:number
 | 
				
			||||||
 | 
					  export let chat:Chat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
  $: chat = $chatsStorage.find((chat) => chat.id === chatId) as Chat
 | 
					 | 
				
			||||||
  $: chatSettings = chat.settings
 | 
					  $: chatSettings = chat.settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const isError = message.role === 'error'
 | 
					  const isError = message.role === 'error'
 | 
				
			||||||
| 
						 | 
					@ -49,7 +48,7 @@
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  afterUpdate(() => {
 | 
					  afterUpdate(() => {
 | 
				
			||||||
    if (message.content.slice(-5).includes('```')) refreshCounter++
 | 
					    if (message.streaming && message.content.slice(-5).includes('```')) refreshCounter++
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const edit = () => {
 | 
					  const edit = () => {
 | 
				
			||||||
| 
						 | 
					@ -178,7 +177,7 @@
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    message.suppress = value
 | 
					    message.suppress = value
 | 
				
			||||||
    saveChatStore()
 | 
					    updateMessages(chatId)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const downloadImage = () => {
 | 
					  const downloadImage = () => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,19 +1,19 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
  // Iterate messages
 | 
					  // Iterate messages
 | 
				
			||||||
  import type { Message, Chat } from './Types.svelte'
 | 
					  import type { Message, Chat } from './Types.svelte'
 | 
				
			||||||
  import { chatsStorage, globalStorage } from './Storage.svelte'
 | 
					  import { globalStorage } from './Storage.svelte'
 | 
				
			||||||
  import EditMessage from './EditMessage.svelte'
 | 
					  import EditMessage from './EditMessage.svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let messages : Message[]
 | 
					  export let messages : Message[]
 | 
				
			||||||
  export let chatId: number
 | 
					  export let chatId: number
 | 
				
			||||||
 | 
					  export let chat: Chat
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  $: chat = $chatsStorage.find((chat) => chat.id === chatId) as Chat
 | 
					 | 
				
			||||||
  $: chatSettings = chat.settings
 | 
					  $: chatSettings = chat.settings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{#each messages as message, i}
 | 
					{#each messages as message, i}
 | 
				
			||||||
  {#if !((message.summarized) && $globalStorage.hideSummarized) && !(i === 0 && message.role === 'system' && !chatSettings.useSystemPrompt)}
 | 
					  {#if !((message.summarized) && $globalStorage.hideSummarized) && !(i === 0 && message.role === 'system' && !chatSettings.useSystemPrompt)}
 | 
				
			||||||
  {#key message.uuid}<EditMessage bind:message={message} chatId={chatId} />{/key}
 | 
					  <EditMessage bind:message={message} chatId={chatId} chat={chat} />
 | 
				
			||||||
  {/if}
 | 
					  {/if}
 | 
				
			||||||
{/each}
 | 
					{/each}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@
 | 
				
			||||||
  import { getChatDefaults, getExcludeFromProfile } from './Settings.svelte'
 | 
					  import { getChatDefaults, getExcludeFromProfile } from './Settings.svelte'
 | 
				
			||||||
  import { get, writable } from 'svelte/store'
 | 
					  import { get, writable } from 'svelte/store'
 | 
				
			||||||
  // Profile definitions
 | 
					  // Profile definitions
 | 
				
			||||||
  import { addMessage, clearMessages, deleteMessage, getChat, getChatSettings, getCustomProfiles, getGlobalSettings, newName, resetChatSettings, saveChatStore, setGlobalSettingValueByKey, updateProfile } from './Storage.svelte'
 | 
					  import { addMessage, clearMessages, deleteMessage, getChat, getChatSettings, getCustomProfiles, getGlobalSettings, getMessages, newName, resetChatSettings, saveChatStore, setGlobalSettingValueByKey, setMessages, updateProfile } from './Storage.svelte'
 | 
				
			||||||
  import type { Message, SelectOption, ChatSettings } from './Types.svelte'
 | 
					  import type { Message, SelectOption, ChatSettings } from './Types.svelte'
 | 
				
			||||||
  import { v4 as uuidv4 } from 'uuid'
 | 
					  import { v4 as uuidv4 } from 'uuid'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,15 +90,15 @@ export const prepareSummaryPrompt = (chatId:number, maxTokens:number) => {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const setSystemPrompt = (chatId: number) => {
 | 
					export const setSystemPrompt = (chatId: number) => {
 | 
				
			||||||
    const chat = getChat(chatId)
 | 
					    const messages = getMessages(chatId)
 | 
				
			||||||
    const systemPromptMessage:Message = {
 | 
					    const systemPromptMessage:Message = {
 | 
				
			||||||
      role: 'system',
 | 
					      role: 'system',
 | 
				
			||||||
      content: prepareProfilePrompt(chatId),
 | 
					      content: prepareProfilePrompt(chatId),
 | 
				
			||||||
      uuid: uuidv4()
 | 
					      uuid: uuidv4()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (chat.messages[0]?.role === 'system') deleteMessage(chatId, chat.messages[0].uuid)
 | 
					    if (messages[0]?.role === 'system') deleteMessage(chatId, messages[0].uuid)
 | 
				
			||||||
    chat.messages.unshift(systemPromptMessage)
 | 
					    messages.unshift(systemPromptMessage)
 | 
				
			||||||
    saveChatStore()
 | 
					    setMessages(chatId, messages.filter(m => true))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Restart currently loaded profile
 | 
					// Restart currently loaded profile
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,8 @@
 | 
				
			||||||
  export let submitExitingPromptsNow = writable(false) // for them to go now.  Will not submit anything in the input
 | 
					  export let submitExitingPromptsNow = writable(false) // for them to go now.  Will not submit anything in the input
 | 
				
			||||||
  export let pinMainMenu = writable(false) // Show menu (for mobile use)
 | 
					  export let pinMainMenu = writable(false) // Show menu (for mobile use)
 | 
				
			||||||
  export let continueMessage = writable('') //
 | 
					  export let continueMessage = writable('') //
 | 
				
			||||||
 | 
					  export let currentChatMessages = writable([] as Message[])
 | 
				
			||||||
 | 
					  export let currentChatId = writable(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const chatDefaults = getChatDefaults()
 | 
					  const chatDefaults = getChatDefaults()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -215,70 +217,97 @@
 | 
				
			||||||
    chatsStorage.set(chats)
 | 
					    chatsStorage.set(chats)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export const getMessages = (chatId: number): Message[] => {
 | 
				
			||||||
 | 
					    if (get(currentChatId) === chatId) return get(currentChatMessages)
 | 
				
			||||||
 | 
					    return getChat(chatId).messages
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let setChatTimer: any
 | 
				
			||||||
 | 
					  export const setCurrentChat = (chatId: number) => {
 | 
				
			||||||
 | 
					    clearTimeout(setChatTimer)
 | 
				
			||||||
 | 
					    if (!chatId) {
 | 
				
			||||||
 | 
					      currentChatId.set(0)
 | 
				
			||||||
 | 
					      currentChatMessages.set([])
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    setChatTimer = setTimeout(() => {
 | 
				
			||||||
 | 
					      currentChatId.set(chatId)
 | 
				
			||||||
 | 
					      currentChatMessages.set(getChat(chatId).messages)
 | 
				
			||||||
 | 
					    }, 10)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let setMessagesTimer: any
 | 
				
			||||||
 | 
					  export const setMessages = (chatId: number, messages: Message[]) => {
 | 
				
			||||||
 | 
					    if (get(currentChatId) === chatId) {
 | 
				
			||||||
 | 
					      // update current message cache right away
 | 
				
			||||||
 | 
					      currentChatMessages.set(messages)
 | 
				
			||||||
 | 
					      clearTimeout(setMessagesTimer)
 | 
				
			||||||
 | 
					      // delay expensive all chats update for a bit
 | 
				
			||||||
 | 
					      setMessagesTimer = setTimeout(() => {
 | 
				
			||||||
 | 
					        getChat(chatId).messages = messages
 | 
				
			||||||
 | 
					        saveChatStore()
 | 
				
			||||||
 | 
					      }, 100)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      getChat(chatId).messages = messages
 | 
				
			||||||
 | 
					      saveChatStore()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export const updateMessages = (chatId: number) => {
 | 
				
			||||||
 | 
					    setMessages(chatId, getMessages(chatId))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const addError = (chatId: number, error: string) => {
 | 
					  export const addError = (chatId: number, error: string) => {
 | 
				
			||||||
    addMessage(chatId, { content: error } as Message)
 | 
					    addMessage(chatId, { content: error } as Message)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const addMessage = (chatId: number, message: Message) => {
 | 
					  export const addMessage = (chatId: number, message: Message) => {
 | 
				
			||||||
    const chats = get(chatsStorage)
 | 
					    const messages = getMessages(chatId)
 | 
				
			||||||
    const chat = chats.find((chat) => chat.id === chatId) as Chat
 | 
					 | 
				
			||||||
    if (!message.uuid) message.uuid = uuidv4()
 | 
					    if (!message.uuid) message.uuid = uuidv4()
 | 
				
			||||||
    if (chat.messages.indexOf(message) < 0) {
 | 
					    if (messages.indexOf(message) < 0) {
 | 
				
			||||||
      // Don't have message, add it
 | 
					      // Don't have message, add it
 | 
				
			||||||
      chat.messages.push(message)
 | 
					      messages[messages.length] = message
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    chatsStorage.set(chats)
 | 
					    setMessages(chatId, messages)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const getMessages = (chatId: number):Message[] => {
 | 
					  export const getMessage = (chatId: number, uuid:string):Message|undefined => {
 | 
				
			||||||
    const chats = get(chatsStorage)
 | 
					    return getMessages(chatId).find((m) => m.uuid === uuid)
 | 
				
			||||||
    const chat = chats.find((chat) => chat.id === chatId) as Chat
 | 
					 | 
				
			||||||
    return chat.messages
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  export const getMessage = (chat: Chat, uuid:string):Message|undefined => {
 | 
					 | 
				
			||||||
    return chat.messages.find((m) => m.uuid === uuid)
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const insertMessages = (chatId: number, insertAfter: Message, newMessages: Message[]) => {
 | 
					  export const insertMessages = (chatId: number, insertAfter: Message, newMessages: Message[]) => {
 | 
				
			||||||
    const chats = get(chatsStorage)
 | 
					    const messages = getMessages(chatId)
 | 
				
			||||||
    const chat = chats.find((chat) => chat.id === chatId) as Chat
 | 
					    const index = messages.findIndex((m) => m.uuid === insertAfter.uuid)
 | 
				
			||||||
    const index = chat.messages.findIndex((m) => m.uuid === insertAfter.uuid)
 | 
					 | 
				
			||||||
    if (index === undefined || index < 0) {
 | 
					    if (index === undefined || index < 0) {
 | 
				
			||||||
      console.error("Couldn't insert after message:", insertAfter)
 | 
					      console.error("Couldn't insert after message:", insertAfter)
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    newMessages.forEach(m => { m.uuid = m.uuid || uuidv4() })
 | 
					    newMessages.forEach(m => { m.uuid = m.uuid || uuidv4() })
 | 
				
			||||||
    chat.messages.splice(index + 1, 0, ...newMessages)
 | 
					    messages.splice(index + 1, 0, ...newMessages)
 | 
				
			||||||
    chatsStorage.set(chats)
 | 
					    setMessages(chatId, messages.filter(m => true))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const deleteSummaryMessage = (chatId: number, uuid: string) => {
 | 
					  export const deleteSummaryMessage = (chatId: number, uuid: string) => {
 | 
				
			||||||
    const chats = get(chatsStorage)
 | 
					    const message = getMessage(chatId, uuid)
 | 
				
			||||||
    const chat = chats.find((chat) => chat.id === chatId) as Chat
 | 
					 | 
				
			||||||
    const message = getMessage(chat, uuid)
 | 
					 | 
				
			||||||
    if (message && message.summarized) throw new Error('Unable to delete summarized message')
 | 
					    if (message && message.summarized) throw new Error('Unable to delete summarized message')
 | 
				
			||||||
    if (message && message.summary) { // messages we summarized
 | 
					    if (message && message.summary) { // messages we summarized
 | 
				
			||||||
      message.summary.forEach(sid => {
 | 
					      message.summary.forEach(sid => {
 | 
				
			||||||
        const m = getMessage(chat, sid)
 | 
					        const m = getMessage(chatId, sid)
 | 
				
			||||||
        if (m) {
 | 
					        if (m) {
 | 
				
			||||||
          delete m.summarized // unbind to this summary
 | 
					          delete m.summarized // unbind to this summary
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      delete message.summary
 | 
					      delete message.summary
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    chatsStorage.set(chats)
 | 
					    updateMessages(chatId)
 | 
				
			||||||
    deleteMessage(chatId, uuid)
 | 
					    deleteMessage(chatId, uuid)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const deleteMessage = (chatId: number, uuid: string) => {
 | 
					  export const deleteMessage = (chatId: number, uuid: string) => {
 | 
				
			||||||
    const chats = get(chatsStorage)
 | 
					    const messages = getMessages(chatId)
 | 
				
			||||||
    const chat = chats.find((chat) => chat.id === chatId) as Chat
 | 
					    const index = messages.findIndex((m) => m.uuid === uuid)
 | 
				
			||||||
    const index = chat.messages.findIndex((m) => m.uuid === uuid)
 | 
					    const message = getMessage(chatId, uuid)
 | 
				
			||||||
    const message = getMessage(chat, uuid)
 | 
					 | 
				
			||||||
    if (message?.summarized) throw new Error('Unable to delete summarized message')
 | 
					    if (message?.summarized) throw new Error('Unable to delete summarized message')
 | 
				
			||||||
    if (message?.summary) throw new Error('Unable to directly delete message summary')
 | 
					    if (message?.summary) throw new Error('Unable to directly delete message summary')
 | 
				
			||||||
    // const found = chat.messages.filter((m) => m.uuid === uuid)
 | 
					 | 
				
			||||||
    if (index < 0) {
 | 
					    if (index < 0) {
 | 
				
			||||||
      console.error(`Unable to find and delete message with ID: ${uuid}`)
 | 
					      console.error(`Unable to find and delete message with ID: ${uuid}`)
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
| 
						 | 
					@ -287,8 +316,8 @@
 | 
				
			||||||
      deleteImage(chatId, message.image.id)
 | 
					      deleteImage(chatId, message.image.id)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // console.warn(`Deleting message with ID: ${uuid}`, found, index)
 | 
					    // console.warn(`Deleting message with ID: ${uuid}`, found, index)
 | 
				
			||||||
    chat.messages.splice(index, 1) // remove item
 | 
					    messages.splice(index, 1) // remove item
 | 
				
			||||||
    chatsStorage.set(chats)
 | 
					    setMessages(chatId, messages.filter(m => true))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const clearImages = (chatId: number, messages: Message[]) => {
 | 
					  const clearImages = (chatId: number, messages: Message[]) => {
 | 
				
			||||||
| 
						 | 
					@ -298,38 +327,33 @@
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const truncateFromMessage = (chatId: number, uuid: string) => {
 | 
					  export const truncateFromMessage = (chatId: number, uuid: string) => {
 | 
				
			||||||
    const chats = get(chatsStorage)
 | 
					    const messages = getMessages(chatId)
 | 
				
			||||||
    const chat = chats.find((chat) => chat.id === chatId) as Chat
 | 
					    const index = messages.findIndex((m) => m.uuid === uuid)
 | 
				
			||||||
    const index = chat.messages.findIndex((m) => m.uuid === uuid)
 | 
					    const message = getMessage(chatId, uuid)
 | 
				
			||||||
    const message = getMessage(chat, uuid)
 | 
					 | 
				
			||||||
    if (message && message.summarized) throw new Error('Unable to truncate from a summarized message')
 | 
					    if (message && message.summarized) throw new Error('Unable to truncate from a summarized message')
 | 
				
			||||||
    // const found = chat.messages.filter((m) => m.uuid === uuid)
 | 
					 | 
				
			||||||
    if (index < 0) {
 | 
					    if (index < 0) {
 | 
				
			||||||
      throw new Error(`Unable to find message with ID: ${uuid}`)
 | 
					      throw new Error(`Unable to find message with ID: ${uuid}`)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const truncated = chat.messages.splice(index + 1) // remove every item after
 | 
					    const truncated = messages.splice(index + 1) // remove every item after
 | 
				
			||||||
    clearImages(chatId, truncated)
 | 
					    clearImages(chatId, truncated)
 | 
				
			||||||
    chatsStorage.set(chats)
 | 
					    setMessages(chatId, messages.filter(m => true))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const clearMessages = (chatId: number) => {
 | 
					  export const clearMessages = (chatId: number) => {
 | 
				
			||||||
    const chats = get(chatsStorage)
 | 
					    clearImages(chatId, getMessages(chatId))
 | 
				
			||||||
    const chat = chats.find((chat) => chat.id === chatId) as Chat
 | 
					    setMessages(chatId, [])
 | 
				
			||||||
    clearImages(chatId, chat.messages)
 | 
					 | 
				
			||||||
    chat.messages = []
 | 
					 | 
				
			||||||
    chatsStorage.set(chats)
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const deleteChat = (chatId: number) => {
 | 
					  export const deleteChat = (chatId: number) => {
 | 
				
			||||||
    const chats = get(chatsStorage)
 | 
					    const chats = get(chatsStorage)
 | 
				
			||||||
    const chat = getChat(chatId)
 | 
					    clearImages(chatId, getMessages(chatId) || [])
 | 
				
			||||||
    clearImages(chatId, chat?.messages || [])
 | 
					 | 
				
			||||||
    chatsStorage.set(chats.filter((chat) => chat.id !== chatId))
 | 
					    chatsStorage.set(chats.filter((chat) => chat.id !== chatId))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const updateChatImages = async (chatId: number, chat: Chat) => {
 | 
					  export const updateChatImages = async (chatId: number, chat: Chat) => {
 | 
				
			||||||
    for (let i = 0; i < chat.messages.length; i++) {
 | 
					    const messages = getMessages(chatId)
 | 
				
			||||||
      const m = chat.messages[i]
 | 
					    for (let i = 0; i < messages.length; i++) {
 | 
				
			||||||
 | 
					      const m = messages[i]
 | 
				
			||||||
      if (m.image) m.image = await setImage(chatId, m.image)
 | 
					      if (m.image) m.image = await setImage(chatId, m.image)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue