Use modals instead of window.alert & confirm
This commit is contained in:
		
							parent
							
								
									db6e5898df
								
							
						
					
					
						commit
						5853b9e451
					
				| 
						 | 
					@ -17,11 +17,13 @@
 | 
				
			||||||
    faEye,
 | 
					    faEye,
 | 
				
			||||||
    faEyeSlash
 | 
					    faEyeSlash
 | 
				
			||||||
  } from '@fortawesome/free-solid-svg-icons/index'
 | 
					  } from '@fortawesome/free-solid-svg-icons/index'
 | 
				
			||||||
  import { apiKeyStorage, addChatFromJSON, chatsStorage, checkStateChange, clearChats, clearMessages, copyChat, globalStorage, setGlobalSettingValueByKey, showSetChatSettings, pinMainMenu } from './Storage.svelte'
 | 
					  import { apiKeyStorage, addChatFromJSON, chatsStorage, checkStateChange, clearChats, clearMessages, copyChat, globalStorage, setGlobalSettingValueByKey, showSetChatSettings, pinMainMenu, getChat, deleteChat } from './Storage.svelte'
 | 
				
			||||||
  import { exportAsMarkdown, exportChatAsJSON } from './Export.svelte'
 | 
					  import { exportAsMarkdown, exportChatAsJSON } from './Export.svelte'
 | 
				
			||||||
  import { restartProfile } from './Profiles.svelte'
 | 
					  import { restartProfile } from './Profiles.svelte'
 | 
				
			||||||
  import { replace } from 'svelte-spa-router'
 | 
					  import { replace } from 'svelte-spa-router'
 | 
				
			||||||
  import { clickOutside } from 'svelte-use-click-outside'
 | 
					  import { clickOutside } from 'svelte-use-click-outside'
 | 
				
			||||||
 | 
					  import { openModal } from 'svelte-modals'
 | 
				
			||||||
 | 
					  import PromptConfirm from './PromptConfirm.svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let chatId
 | 
					  export let chatId
 | 
				
			||||||
  export const show = (showHide:boolean = true) => {
 | 
					  export const show = (showHide:boolean = true) => {
 | 
				
			||||||
| 
						 | 
					@ -29,6 +31,8 @@
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  export let style: string = 'is-right'
 | 
					  export let style: string = 'is-right'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  $: sortedChats = $chatsStorage.sort((a, b) => b.id - a.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let showChatMenu = false
 | 
					  let showChatMenu = false
 | 
				
			||||||
  let chatFileInput
 | 
					  let chatFileInput
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,20 +47,45 @@
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const deleteChat = () => {
 | 
					  const delChat = () => {
 | 
				
			||||||
    close()
 | 
					    close()
 | 
				
			||||||
    if (window.confirm('Are you sure you want to delete this chat?')) {
 | 
					    openModal(PromptConfirm, {
 | 
				
			||||||
      replace('/').then(() => {
 | 
					      title: 'Delete Chat',
 | 
				
			||||||
        chatsStorage.update((chats) => chats.filter((chat) => chat.id !== chatId))
 | 
					      message: 'Are you sure you want to delete this chat?',
 | 
				
			||||||
      })
 | 
					      class: 'is-warning',
 | 
				
			||||||
 | 
					      confirmButtonClass: 'is-warning',
 | 
				
			||||||
 | 
					      confirmButton: 'Delete Chat',
 | 
				
			||||||
 | 
					      onConfirm: () => {
 | 
				
			||||||
 | 
					        const thisChat = getChat(chatId)
 | 
				
			||||||
 | 
					        const thisIndex = sortedChats.indexOf(thisChat)
 | 
				
			||||||
 | 
					        const prevChat = sortedChats[thisIndex - 1]
 | 
				
			||||||
 | 
					        const nextChat = sortedChats[thisIndex + 1]
 | 
				
			||||||
 | 
					        const newChat = nextChat || prevChat
 | 
				
			||||||
 | 
					        if (!newChat) {
 | 
				
			||||||
 | 
					          // No other chats, clear all and go to home
 | 
				
			||||||
 | 
					          replace('/').then(() => { deleteChat(chatId) })
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          // Delete the current chat and go to the max chatId
 | 
				
			||||||
 | 
					          replace(`/chat/${newChat.id}`).then(() => { deleteChat(chatId) })
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      onCancel: () => {}
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const confirmClearChats = () => {
 | 
					  const confirmClearChats = () => {
 | 
				
			||||||
    close()
 | 
					    close()
 | 
				
			||||||
    if (window.confirm('Are you sure you want to delete ALL of your chats?')) {
 | 
					    openModal(PromptConfirm, {
 | 
				
			||||||
 | 
					      title: 'Delete ALL Chat',
 | 
				
			||||||
 | 
					      message: 'Are you sure you want to delete ALL of your chats?',
 | 
				
			||||||
 | 
					      class: 'is-danger',
 | 
				
			||||||
 | 
					      confirmButtonClass: 'is-danger',
 | 
				
			||||||
 | 
					      confirmButton: 'Delete ALL',
 | 
				
			||||||
 | 
					      onConfirm: () => {
 | 
				
			||||||
        clearChats()
 | 
					        clearChats()
 | 
				
			||||||
    }
 | 
					      },
 | 
				
			||||||
 | 
					      onCancel: () => {}
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const close = () => {
 | 
					  const close = () => {
 | 
				
			||||||
| 
						 | 
					@ -116,7 +145,7 @@
 | 
				
			||||||
        <span class="menu-icon"><Fa icon={faFileExport}/></span> Export Chat Markdown
 | 
					        <span class="menu-icon"><Fa icon={faFileExport}/></span> Export Chat Markdown
 | 
				
			||||||
      </a>
 | 
					      </a>
 | 
				
			||||||
      <hr class="dropdown-divider">
 | 
					      <hr class="dropdown-divider">
 | 
				
			||||||
      <a href={'#'} class="dropdown-item" class:is-disabled={!chatId} on:click|preventDefault={() => { if (chatId) close(); deleteChat() }}>
 | 
					      <a href={'#'} class="dropdown-item" class:is-disabled={!chatId} on:click|preventDefault={() => { if (chatId) close(); delChat() }}>
 | 
				
			||||||
        <span class="menu-icon"><Fa icon={faTrash}/></span> Delete Chat
 | 
					        <span class="menu-icon"><Fa icon={faTrash}/></span> Delete Chat
 | 
				
			||||||
      </a>
 | 
					      </a>
 | 
				
			||||||
      <a href={'#'} class="dropdown-item" on:click|preventDefault={() => { if (chatId) confirmClearChats() }}>
 | 
					      <a href={'#'} class="dropdown-item" on:click|preventDefault={() => { if (chatId) confirmClearChats() }}>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,11 +3,12 @@
 | 
				
			||||||
  // import { getProfile } from './Profiles.svelte'
 | 
					  // import { getProfile } from './Profiles.svelte'
 | 
				
			||||||
  import { cleanSettingValue, setChatSettingValue } from './Storage.svelte'
 | 
					  import { cleanSettingValue, setChatSettingValue } from './Storage.svelte'
 | 
				
			||||||
  import type { Chat, ChatSetting, ChatSettings, ControlAction, FieldControl, SettingPrompt } from './Types.svelte'
 | 
					  import type { Chat, ChatSetting, ChatSettings, ControlAction, FieldControl, SettingPrompt } from './Types.svelte'
 | 
				
			||||||
  import { autoGrowInputOnEvent } from './Util.svelte'
 | 
					  import { autoGrowInputOnEvent, errorNotice } from './Util.svelte'
 | 
				
			||||||
  // import { replace } from 'svelte-spa-router'
 | 
					  // import { replace } from 'svelte-spa-router'
 | 
				
			||||||
  import Fa from 'svelte-fa/src/fa.svelte'
 | 
					  import Fa from 'svelte-fa/src/fa.svelte'
 | 
				
			||||||
  import { openModal } from 'svelte-modals'
 | 
					  import { openModal } from 'svelte-modals'
 | 
				
			||||||
  import PromptConfirm from './PromptConfirm.svelte'
 | 
					  import PromptConfirm from './PromptConfirm.svelte'
 | 
				
			||||||
 | 
					  import PromptNotice from './PromptNotice.svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let setting:ChatSetting
 | 
					  export let setting:ChatSetting
 | 
				
			||||||
  export let chatSettings:ChatSettings
 | 
					  export let chatSettings:ChatSettings
 | 
				
			||||||
| 
						 | 
					@ -87,7 +88,7 @@
 | 
				
			||||||
        (typeof setting.beforeChange === 'function') && setting.beforeChange(chatId, setting, el.checked || el.value) &&
 | 
					        (typeof setting.beforeChange === 'function') && setting.beforeChange(chatId, setting, el.checked || el.value) &&
 | 
				
			||||||
          refreshSettings()
 | 
					          refreshSettings()
 | 
				
			||||||
      } catch (e) {
 | 
					      } catch (e) {
 | 
				
			||||||
        window.alert('Unable to change:\n' + e.message)
 | 
					        openModal(PromptNotice, errorNotice('Unable to change:', e))
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      switch (setting.type) {
 | 
					      switch (setting.type) {
 | 
				
			||||||
        case 'boolean':
 | 
					        case 'boolean':
 | 
				
			||||||
| 
						 | 
					@ -106,7 +107,7 @@
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } catch (e) {
 | 
					      } catch (e) {
 | 
				
			||||||
        setChatSettingValue(chatId, setting, val)
 | 
					        setChatSettingValue(chatId, setting, val)
 | 
				
			||||||
        window.alert('Unable to change:\n' + e.message)
 | 
					        openModal(PromptNotice, errorNotice('Unable to change:', e))
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      dispatch('change', setting)
 | 
					      dispatch('change', setting)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  } from './Storage.svelte'
 | 
					  } from './Storage.svelte'
 | 
				
			||||||
  import { supportedModels, type Chat, type ChatSetting, type ResponseModels, type SettingSelect, type SelectOption, type ChatSettings } from './Types.svelte'
 | 
					  import { supportedModels, type Chat, type ChatSetting, type ResponseModels, type SettingSelect, type SelectOption, type ChatSettings } from './Types.svelte'
 | 
				
			||||||
  import { sizeTextElements } from './Util.svelte'
 | 
					  import { errorNotice, sizeTextElements } from './Util.svelte'
 | 
				
			||||||
  import Fa from 'svelte-fa/src/fa.svelte'
 | 
					  import Fa from 'svelte-fa/src/fa.svelte'
 | 
				
			||||||
  import {
 | 
					  import {
 | 
				
			||||||
    faTrash,
 | 
					    faTrash,
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,8 @@
 | 
				
			||||||
  import ChatSettingField from './ChatSettingField.svelte'
 | 
					  import ChatSettingField from './ChatSettingField.svelte'
 | 
				
			||||||
  import { getModelMaxTokens } from './Stats.svelte'
 | 
					  import { getModelMaxTokens } from './Stats.svelte'
 | 
				
			||||||
  import { replace } from 'svelte-spa-router'
 | 
					  import { replace } from 'svelte-spa-router'
 | 
				
			||||||
 | 
					  import { openModal } from 'svelte-modals'
 | 
				
			||||||
 | 
					  import PromptNotice from './PromptNotice.svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let chatId:number
 | 
					  export let chatId:number
 | 
				
			||||||
  export const show = () => { showSettings() }
 | 
					  export const show = () => { showSettings() }
 | 
				
			||||||
| 
						 | 
					@ -101,7 +103,7 @@
 | 
				
			||||||
      applyProfile(chatId, clone.profile)
 | 
					      applyProfile(chatId, clone.profile)
 | 
				
			||||||
      refreshSettings()
 | 
					      refreshSettings()
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
      window.alert('Error cloning profile: \n' + e.message)
 | 
					      openModal(PromptNotice, errorNotice('Error cloning profile:', e))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -115,7 +117,7 @@
 | 
				
			||||||
      applyProfile(chatId, chat.settings.profile as any)
 | 
					      applyProfile(chatId, chat.settings.profile as any)
 | 
				
			||||||
      refreshSettings()
 | 
					      refreshSettings()
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
      window.alert('Error deleting profile: \n' + e.message)
 | 
					      openModal(PromptNotice, errorNotice('Error deleting profile:', e))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -138,7 +140,7 @@
 | 
				
			||||||
        saveCustomProfile(profile)
 | 
					        saveCustomProfile(profile)
 | 
				
			||||||
        refreshSettings()
 | 
					        refreshSettings()
 | 
				
			||||||
      } catch (e) {
 | 
					      } catch (e) {
 | 
				
			||||||
        window.alert('Unable to import profile: \n' + e.message)
 | 
					        openModal(PromptNotice, errorNotice('Unable to import profile:', e))
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -201,7 +203,7 @@
 | 
				
			||||||
      saveCustomProfile(chat.settings)
 | 
					      saveCustomProfile(chat.settings)
 | 
				
			||||||
      refreshSettings()
 | 
					      refreshSettings()
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
      window.alert('Error saving profile: \n' + e.message)
 | 
					      openModal(PromptNotice, errorNotice('Error saving profile:', e))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,10 @@
 | 
				
			||||||
  import type { Message, Model, Chat } from './Types.svelte'
 | 
					  import type { Message, Model, Chat } from './Types.svelte'
 | 
				
			||||||
  import Fa from 'svelte-fa/src/fa.svelte'
 | 
					  import Fa from 'svelte-fa/src/fa.svelte'
 | 
				
			||||||
  import { faTrash, faDiagramPredecessor, faDiagramNext, faCircleCheck, faPaperPlane, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons/index'
 | 
					  import { faTrash, faDiagramPredecessor, faDiagramNext, faCircleCheck, faPaperPlane, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons/index'
 | 
				
			||||||
  import { scrollIntoViewWithOffset } from './Util.svelte'
 | 
					  import { errorNotice, scrollIntoViewWithOffset } from './Util.svelte'
 | 
				
			||||||
 | 
					  import { openModal } from 'svelte-modals'
 | 
				
			||||||
 | 
					  import PromptConfirm from './PromptConfirm.svelte'
 | 
				
			||||||
 | 
					  import PromptNotice from './PromptNotice.svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let message:Message
 | 
					  export let message:Message
 | 
				
			||||||
  export let chatId:number
 | 
					  export let chatId:number
 | 
				
			||||||
| 
						 | 
					@ -115,24 +118,33 @@
 | 
				
			||||||
    waitingForDeleteConfirm = 0
 | 
					    waitingForDeleteConfirm = 0
 | 
				
			||||||
    if (message.summarized) {
 | 
					    if (message.summarized) {
 | 
				
			||||||
      // is in a summary, so we're summarized
 | 
					      // is in a summary, so we're summarized
 | 
				
			||||||
      window.alert('Sorry, you can\'t delete a summarized message')
 | 
					      openModal(PromptNotice, errorNotice('Sorry, you can\'t delete a summarized message'))
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (message.summary) {
 | 
					    if (message.summary) {
 | 
				
			||||||
      // We're linked to messages we're a summary of
 | 
					      // We're linked to messages we're a summary of
 | 
				
			||||||
      if (window.confirm('Are you sure you want to delete this summary?\nYour session may be too long to submit again after you do.')) {
 | 
					      openModal(PromptConfirm, {
 | 
				
			||||||
 | 
					        title: 'Delete Summary',
 | 
				
			||||||
 | 
					        message: '<p>Are you sure you want to delete this summary?</p><p>Your session may be too long to submit again after you do.</p>',
 | 
				
			||||||
 | 
					        asHtml: true,
 | 
				
			||||||
 | 
					        class: 'is-warning',
 | 
				
			||||||
 | 
					        confirmButtonClass: 'is-warning',
 | 
				
			||||||
 | 
					        confirmButton: 'Delete Summary',
 | 
				
			||||||
 | 
					        onConfirm: () => {
 | 
				
			||||||
          try {
 | 
					          try {
 | 
				
			||||||
            deleteSummaryMessage(chatId, message.uuid)
 | 
					            deleteSummaryMessage(chatId, message.uuid)
 | 
				
			||||||
          } catch (e) {
 | 
					          } catch (e) {
 | 
				
			||||||
          window.alert('Unable to delete summary:\n' + e.message)
 | 
					            openModal(PromptNotice, errorNotice('Unable to delete summary:', e))
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        onCancel: () => {}
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        deleteMessage(chatId, message.uuid)
 | 
					        deleteMessage(chatId, message.uuid)
 | 
				
			||||||
      } catch (e) {
 | 
					      } catch (e) {
 | 
				
			||||||
      window.alert('Unable to delete:\n' + e.message)
 | 
					        openModal(PromptNotice, errorNotice('Unable to delete:', e))
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -150,21 +162,21 @@
 | 
				
			||||||
    waitingForTruncateConfirm = 0
 | 
					    waitingForTruncateConfirm = 0
 | 
				
			||||||
    if (message.summarized) {
 | 
					    if (message.summarized) {
 | 
				
			||||||
      // is in a summary, so we're summarized
 | 
					      // is in a summary, so we're summarized
 | 
				
			||||||
      window.alert('Sorry, you can\'t truncate a summarized message')
 | 
					      openModal(PromptNotice, errorNotice('Sorry, you can\'t truncate a summarized message'))
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      truncateFromMessage(chatId, message.uuid)
 | 
					      truncateFromMessage(chatId, message.uuid)
 | 
				
			||||||
      $submitExitingPromptsNow = true
 | 
					      $submitExitingPromptsNow = true
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
      window.alert('Unable to delete:\n' + e.message)
 | 
					      openModal(PromptNotice, errorNotice('Unable to delete:', e))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const setSuppress = (value:boolean) => {
 | 
					  const setSuppress = (value:boolean) => {
 | 
				
			||||||
    if (message.summarized) {
 | 
					    if (message.summarized) {
 | 
				
			||||||
      // is in a summary, so we're summarized
 | 
					      // is in a summary, so we're summarized
 | 
				
			||||||
      window.alert('Sorry, you can\'t suppress a summarized message')
 | 
					      openModal(PromptNotice, errorNotice('Sorry, you can\'t suppress a summarized message'))
 | 
				
			||||||
      return
 | 
					      return
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    message.suppress = value
 | 
					    message.suppress = value
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,50 @@
 | 
				
			||||||
 | 
					<script lang="ts">
 | 
				
			||||||
 | 
					  import { closeModal } from 'svelte-modals'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export let isOpen:boolean
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export let title:string
 | 
				
			||||||
 | 
					  export let message:string
 | 
				
			||||||
 | 
					  export let asHtml:boolean = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export let onConfirm:()=>boolean|void
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export let confirmButton:string = 'Okay'
 | 
				
			||||||
 | 
					  export let confirmButtonClass:string = 'is-info'
 | 
				
			||||||
 | 
					  let classes:string = ''
 | 
				
			||||||
 | 
					  export { classes as class }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const doConfirm = () => {
 | 
				
			||||||
 | 
					    if (!onConfirm || !onConfirm()) closeModal()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{#if isOpen}
 | 
				
			||||||
 | 
					<div class="modal is-active" on:modal-esc={doConfirm}>
 | 
				
			||||||
 | 
					  <!-- svelte-ignore a11y-click-events-have-key-events -->
 | 
				
			||||||
 | 
					  <div class="modal-background" on:click={doConfirm} />
 | 
				
			||||||
 | 
					  <div class="modal-content nomax">
 | 
				
			||||||
 | 
					    <article class="message {classes}">
 | 
				
			||||||
 | 
					      <div class="message-header">
 | 
				
			||||||
 | 
					        <p>{title}</p>
 | 
				
			||||||
 | 
					        <button class="delete" aria-label="close" type="button" on:click={doConfirm}></button>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="message-body">
 | 
				
			||||||
 | 
					        {#if asHtml}{@html message}{:else}{message}{/if}
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <div class="message-footer">
 | 
				
			||||||
 | 
					        <div class="level is-mobile">
 | 
				
			||||||
 | 
					          <div class="level-right">
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div class="level-right">
 | 
				
			||||||
 | 
					            <div class="level-item">
 | 
				
			||||||
 | 
					              <button class="button {confirmButtonClass}" type="button" on:click={doConfirm} >{confirmButton}</button>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>     
 | 
				
			||||||
 | 
					    </article>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					{/if}
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ import {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} from './Types.svelte'
 | 
					} from './Types.svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const defaultModel:Model = 'gpt-3.5-turbo-0301'
 | 
					export const defaultModel:Model = 'gpt-3.5-turbo'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const getChatSettingList = (): ChatSetting[] => {
 | 
					export const getChatSettingList = (): ChatSetting[] => {
 | 
				
			||||||
      return chatSettingsList
 | 
					      return chatSettingsList
 | 
				
			||||||
| 
						 | 
					@ -86,6 +86,8 @@ const defaults:ChatSettings = {
 | 
				
			||||||
  systemPrompt: '',
 | 
					  systemPrompt: '',
 | 
				
			||||||
  autoStartSession: false,
 | 
					  autoStartSession: false,
 | 
				
			||||||
  trainingPrompts: [],
 | 
					  trainingPrompts: [],
 | 
				
			||||||
 | 
					  // useResponseAlteration: false,
 | 
				
			||||||
 | 
					  // responseAlterations: [],
 | 
				
			||||||
  isDirty: false
 | 
					  isDirty: false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,8 +131,7 @@ const profileSetting: ChatSetting & SettingSelect = {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Settings that will not be part of the API request
 | 
					// Settings that will not be part of the API request
 | 
				
			||||||
const nonRequestSettings: ChatSetting[] = [
 | 
					const systemPromptSettings: ChatSetting[] = [
 | 
				
			||||||
      profileSetting,
 | 
					 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        key: 'profileName',
 | 
					        key: 'profileName',
 | 
				
			||||||
        name: 'Profile Name',
 | 
					        name: 'Profile Name',
 | 
				
			||||||
| 
						 | 
					@ -181,7 +182,10 @@ const nonRequestSettings: ChatSetting[] = [
 | 
				
			||||||
        title: 'If possible, auto-start the chat session, sending a system prompt to get an initial response.',
 | 
					        title: 'If possible, auto-start the chat session, sending a system prompt to get an initial response.',
 | 
				
			||||||
        type: 'boolean',
 | 
					        type: 'boolean',
 | 
				
			||||||
        hide: (chatId) => !getChatSettings(chatId).useSystemPrompt
 | 
					        hide: (chatId) => !getChatSettings(chatId).useSystemPrompt
 | 
				
			||||||
      },
 | 
					      }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const summarySettings: ChatSetting[] = [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        key: 'useSummarization',
 | 
					        key: 'useSummarization',
 | 
				
			||||||
        name: 'Enable Continuous Chat',
 | 
					        name: 'Enable Continuous Chat',
 | 
				
			||||||
| 
						 | 
					@ -242,6 +246,54 @@ const nonRequestSettings: ChatSetting[] = [
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// const responseAlterationSettings: ChatSetting[] = [
 | 
				
			||||||
 | 
					//       {
 | 
				
			||||||
 | 
					//         key: 'useResponseAlteration',
 | 
				
			||||||
 | 
					//         name: 'Alter Responses',
 | 
				
			||||||
 | 
					//         header: 'Automatic Response Alteration',
 | 
				
			||||||
 | 
					//         headerClass: 'is-info',
 | 
				
			||||||
 | 
					//         title: 'When an undesired response is encountered, try to alter it in effort to improve future responses.',
 | 
				
			||||||
 | 
					//         type: 'boolean',
 | 
				
			||||||
 | 
					//         hide: () => true
 | 
				
			||||||
 | 
					//       },
 | 
				
			||||||
 | 
					//       {
 | 
				
			||||||
 | 
					//         key: 'responseAlterations',
 | 
				
			||||||
 | 
					//         name: 'Alterations',
 | 
				
			||||||
 | 
					//         title: 'Add find/replace or re-prompts.',
 | 
				
			||||||
 | 
					//         header: 'Profile / Presets',
 | 
				
			||||||
 | 
					//         headerClass: 'is-info',
 | 
				
			||||||
 | 
					//         settings: [
 | 
				
			||||||
 | 
					//           {
 | 
				
			||||||
 | 
					//             key: 'type',
 | 
				
			||||||
 | 
					//             type: 'select',
 | 
				
			||||||
 | 
					//             name: 'Alteration Type',
 | 
				
			||||||
 | 
					//             default: 'replace',
 | 
				
			||||||
 | 
					//             options: [{
 | 
				
			||||||
 | 
					//               value: 'replace',
 | 
				
			||||||
 | 
					//               text: 'Regexp Find / Replace'
 | 
				
			||||||
 | 
					//             }, {
 | 
				
			||||||
 | 
					//               value: 'prompt',
 | 
				
			||||||
 | 
					//               text: 'Re-prompt with Instructions'
 | 
				
			||||||
 | 
					//             }]
 | 
				
			||||||
 | 
					//           },
 | 
				
			||||||
 | 
					//           {
 | 
				
			||||||
 | 
					//             key: 'match',
 | 
				
			||||||
 | 
					//             type: 'text',
 | 
				
			||||||
 | 
					//             name: 'Match Expression',
 | 
				
			||||||
 | 
					//             title: 'Regular expression used to match '
 | 
				
			||||||
 | 
					//           },
 | 
				
			||||||
 | 
					//           {
 | 
				
			||||||
 | 
					//             key: 'replace',
 | 
				
			||||||
 | 
					//             type: 'text',
 | 
				
			||||||
 | 
					//             name: 'Alteration',
 | 
				
			||||||
 | 
					//             title: 'Regexp Replacement or Re-prompt'
 | 
				
			||||||
 | 
					//           }
 | 
				
			||||||
 | 
					//         ],
 | 
				
			||||||
 | 
					//         type: 'subset',
 | 
				
			||||||
 | 
					//         hide: (chatId) => !getChatSettings(chatId).useResponseAlteration!
 | 
				
			||||||
 | 
					//       }
 | 
				
			||||||
 | 
					// ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const modelSetting: ChatSetting & SettingSelect = {
 | 
					const modelSetting: ChatSetting & SettingSelect = {
 | 
				
			||||||
      key: 'model',
 | 
					      key: 'model',
 | 
				
			||||||
      name: 'Model',
 | 
					      name: 'Model',
 | 
				
			||||||
| 
						 | 
					@ -255,7 +307,10 @@ const modelSetting: ChatSetting & SettingSelect = {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const chatSettingsList: ChatSetting[] = [
 | 
					const chatSettingsList: ChatSetting[] = [
 | 
				
			||||||
      ...nonRequestSettings,
 | 
					      profileSetting,
 | 
				
			||||||
 | 
					      ...systemPromptSettings,
 | 
				
			||||||
 | 
					      ...summarySettings,
 | 
				
			||||||
 | 
					      // ...responseAlterationSettings,
 | 
				
			||||||
      modelSetting,
 | 
					      modelSetting,
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        key: 'temperature',
 | 
					        key: 'temperature',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,9 @@
 | 
				
			||||||
  import { getChatSettingObjectByKey, getGlobalSettingObjectByKey, getChatDefaults, getExcludeFromProfile } from './Settings.svelte'
 | 
					  import { getChatSettingObjectByKey, getGlobalSettingObjectByKey, getChatDefaults, getExcludeFromProfile } from './Settings.svelte'
 | 
				
			||||||
  import { v4 as uuidv4 } from 'uuid'
 | 
					  import { v4 as uuidv4 } from 'uuid'
 | 
				
			||||||
  import { getProfile, getProfiles, isStaticProfile, newNameForProfile, restartProfile } from './Profiles.svelte'
 | 
					  import { getProfile, getProfiles, isStaticProfile, newNameForProfile, restartProfile } from './Profiles.svelte'
 | 
				
			||||||
 | 
					  import { openModal } from 'svelte-modals'
 | 
				
			||||||
 | 
					  import PromptNotice from './PromptNotice.svelte'
 | 
				
			||||||
 | 
					  import { errorNotice } from './Util.svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const chatsStorage = persisted('chats', [] as Chat[])
 | 
					  export const chatsStorage = persisted('chats', [] as Chat[])
 | 
				
			||||||
  export const globalStorage = persisted('global', {} as GlobalSettings)
 | 
					  export const globalStorage = persisted('global', {} as GlobalSettings)
 | 
				
			||||||
| 
						 | 
					@ -56,11 +59,11 @@
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      chat = JSON.parse(json) as Chat
 | 
					      chat = JSON.parse(json) as Chat
 | 
				
			||||||
      if (!chat.settings || !chat.messages || isNaN(chat.id)) {
 | 
					      if (!chat.settings || !chat.messages || isNaN(chat.id)) {
 | 
				
			||||||
        window.alert('Not valid Chat JSON')
 | 
					        openModal(PromptNotice, errorNotice('Not valid Chat JSON'))
 | 
				
			||||||
        return 0
 | 
					        return 0
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } catch (err) {
 | 
					    } catch (err) {
 | 
				
			||||||
      window.alert("Can't parse file JSON")
 | 
					      openModal(PromptNotice, errorNotice("Can't parse file JSON"))
 | 
				
			||||||
      return 0
 | 
					      return 0
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,12 @@
 | 
				
			||||||
    suppress?: boolean;
 | 
					    suppress?: boolean;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export type ResponseAlteration = {
 | 
				
			||||||
 | 
					    type: 'prompt' | 'replace';
 | 
				
			||||||
 | 
					    match: string;
 | 
				
			||||||
 | 
					    replace: string;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export type Request = {
 | 
					  export type Request = {
 | 
				
			||||||
    model?: Model;
 | 
					    model?: Model;
 | 
				
			||||||
    messages?: Message[];
 | 
					    messages?: Message[];
 | 
				
			||||||
| 
						 | 
					@ -59,6 +65,8 @@
 | 
				
			||||||
    systemPrompt: string;
 | 
					    systemPrompt: string;
 | 
				
			||||||
    autoStartSession: boolean;
 | 
					    autoStartSession: boolean;
 | 
				
			||||||
    trainingPrompts?: Message[];
 | 
					    trainingPrompts?: Message[];
 | 
				
			||||||
 | 
					    useResponseAlteration?: boolean;
 | 
				
			||||||
 | 
					    responseAlterations?: ResponseAlteration[];
 | 
				
			||||||
    isDirty?: boolean;
 | 
					    isDirty?: boolean;
 | 
				
			||||||
  } & Request;
 | 
					  } & Request;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -157,6 +165,11 @@ type SettingBoolean = {
 | 
				
			||||||
    getAction: (chatId:number, setting:any, value:any) => ControlAction;
 | 
					    getAction: (chatId:number, setting:any, value:any) => ControlAction;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export type SubSetting = {
 | 
				
			||||||
 | 
					    type: 'subset';
 | 
				
			||||||
 | 
					    settings: any[];
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  export type ChatSetting = {
 | 
					  export type ChatSetting = {
 | 
				
			||||||
    key: keyof ChatSettings;
 | 
					    key: keyof ChatSettings;
 | 
				
			||||||
    name: string;
 | 
					    name: string;
 | 
				
			||||||
| 
						 | 
					@ -171,7 +184,8 @@ type SettingBoolean = {
 | 
				
			||||||
    fieldControls?: FieldControl[];
 | 
					    fieldControls?: FieldControl[];
 | 
				
			||||||
    beforeChange?: (chatId:number, setting:ChatSetting, value:any) => boolean;
 | 
					    beforeChange?: (chatId:number, setting:ChatSetting, value:any) => boolean;
 | 
				
			||||||
    afterChange?: (chatId:number, setting:ChatSetting, value:any) => boolean;
 | 
					    afterChange?: (chatId:number, setting:ChatSetting, value:any) => boolean;
 | 
				
			||||||
  } & (SettingNumber | SettingSelect | SettingBoolean | SettingText | SettingTextArea | SettingOther);
 | 
					  } & (SettingNumber | SettingSelect | SettingBoolean | SettingText | SettingTextArea | SettingOther | SubSetting);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export type GlobalSetting = {
 | 
					  export type GlobalSetting = {
 | 
				
			||||||
    key: keyof GlobalSettings;
 | 
					    key: keyof GlobalSettings;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,4 +52,14 @@
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export const errorNotice = (message:string, error:Error|undefined = undefined):any => {
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      title: 'Error',
 | 
				
			||||||
 | 
					      class: 'is-danger',
 | 
				
			||||||
 | 
					      message: message + (error ? '<br>' + error.message : ''),
 | 
				
			||||||
 | 
					      asHtml: true,
 | 
				
			||||||
 | 
					      onConfirm: () => {}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</script> 
 | 
					</script> 
 | 
				
			||||||
		Loading…
	
		Reference in New Issue