Merge pull request #183 from Webifi/main

Add "apply prompt" option, clarify the "new chat" buttons in settings, fix potential memory leak
This commit is contained in:
Niek van der Maas 2023-06-15 22:24:05 +02:00 committed by GitHub
commit 9f232adc24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 23 deletions

View File

@ -47,7 +47,6 @@ export class ChatRequest {
count = count || 1 count = count || 1
_this.updating = true _this.updating = true
_this.updatingMessage = 'Generating Image...' _this.updatingMessage = 'Generating Image...'
const signal = _this.controller.signal
const size = this.chat.settings.imageGenerationSize const size = this.chat.settings.imageGenerationSize
const request: RequestImageGeneration = { const request: RequestImageGeneration = {
prompt, prompt,
@ -55,6 +54,16 @@ export class ChatRequest {
size, size,
n: count n: count
} }
// fetchEventSource doesn't seem to throw on abort,
// so we deal with it ourselves
_this.controller = new AbortController()
const signal = _this.controller.signal
const abortListener = (e:Event) => {
chatResponse.updateFromError('User aborted request.')
signal.removeEventListener('abort', abortListener)
}
signal.addEventListener('abort', abortListener)
// Create request
const fetchOptions = { const fetchOptions = {
method: 'POST', method: 'POST',
headers: { headers: {
@ -180,7 +189,15 @@ export class ChatRequest {
// (streaming doesn't return counts, so we need to do it client side) // (streaming doesn't return counts, so we need to do it client side)
chatResponse.setPromptTokenCount(promptTokenCount) chatResponse.setPromptTokenCount(promptTokenCount)
// fetchEventSource doesn't seem to throw on abort,
// so we deal with it ourselves
_this.controller = new AbortController()
const signal = _this.controller.signal const signal = _this.controller.signal
const abortListener = (e:Event) => {
chatResponse.updateFromError('User aborted request.')
signal.removeEventListener('abort', abortListener)
}
signal.addEventListener('abort', abortListener)
const fetchOptions = { const fetchOptions = {
method: 'POST', method: 'POST',
@ -192,15 +209,6 @@ export class ChatRequest {
signal signal
} }
// fetchEventSource doesn't seem to throw on abort,
// so we deal with it ourselves
const abortListener = (e:Event) => {
_this.controller = new AbortController()
chatResponse.updateFromError('User aborted request.')
signal.removeEventListener('abort', abortListener)
}
signal.addEventListener('abort', abortListener)
if (opts.streaming) { if (opts.streaming) {
/** /**
* Streaming request/response * Streaming request/response

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { applyProfile, getDefaultProfileKey, getProfile, getProfileSelect } from './Profiles.svelte' import { applyProfile, getDefaultProfileKey, getProfile, getProfileSelect, setSystemPrompt } from './Profiles.svelte'
import { getChatDefaults, getChatSettingList, getChatSettingObjectByKey, getExcludeFromProfile } from './Settings.svelte' import { getChatDefaults, getChatSettingList, getChatSettingObjectByKey, getExcludeFromProfile } from './Settings.svelte'
import { import {
saveChatStore, saveChatStore,
@ -25,9 +25,8 @@
faDownload, faDownload,
faUpload, faUpload,
faSquarePlus, faSquarePlus,
faRotateLeft,
faRotateLeft faCheckCircle
} from '@fortawesome/free-solid-svg-icons/index' } from '@fortawesome/free-solid-svg-icons/index'
import { exportProfileAsJSON } from './Export.svelte' import { exportProfileAsJSON } from './Export.svelte'
import { onMount, afterUpdate } from 'svelte' import { onMount, afterUpdate } from 'svelte'
@ -271,6 +270,12 @@
chatSettings.isDirty = !deepEqual(profile, chatSettings) chatSettings.isDirty = !deepEqual(profile, chatSettings)
} }
const applyToChat = () => {
if (chatSettings.useSystemPrompt) {
setSystemPrompt(chatId)
}
}
</script> </script>
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
@ -295,7 +300,7 @@
<!-- <button class="button is-info" on:click={closeSettings}>Close</button> --> <!-- <button class="button is-info" on:click={closeSettings}>Close</button> -->
<button class="button" title="Save changes to this profile." class:is-disabled={!chatSettings.isDirty} on:click={saveProfile}>Save</button> <button class="button" title="Save changes to this profile." class:is-disabled={!chatSettings.isDirty} on:click={saveProfile}>Save</button>
<button class="button is-warning" title="Throw away changes to this profile." class:is-disabled={!chatSettings.isDirty} on:click={clearSettings}>Reset</button> <button class="button is-warning" title="Throw away changes to this profile." class:is-disabled={!chatSettings.isDirty} on:click={clearSettings}>Reset</button>
<button class="button" title="Start new chat with this profile." on:click={startNewChat}>New Chat</button> <button class="button" title="Start new chat with this profile." on:click={startNewChat}>New Chat <span class="is-hidden-mobile">&nbsp;from Current</span></button>
</div> </div>
<div class="level-right"> <div class="level-right">
<div class="dropdown is-right is-up" class:is-active={showProfileMenu}> <div class="dropdown is-right is-up" class:is-active={showProfileMenu}>
@ -320,7 +325,10 @@
<span class="menu-icon"><Fa icon={faThumbtack}/></span> Set as Default Profile <span class="menu-icon"><Fa icon={faThumbtack}/></span> Set as Default Profile
</a> </a>
<a href={'#'} class="dropdown-item" on:click|preventDefault={startNewChat}> <a href={'#'} class="dropdown-item" on:click|preventDefault={startNewChat}>
<span class="menu-icon"><Fa icon={faSquarePlus}/></span> Start New Chat Using Profile <span class="menu-icon"><Fa icon={faSquarePlus}/></span> Start New Chat from Current
</a>
<a href={'#'} class="dropdown-item" on:click|preventDefault={applyToChat}>
<span class="menu-icon"><Fa icon={faCheckCircle}/></span> Apply Prompts to Current Chat
</a> </a>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
<a href={'#'} <a href={'#'}

View File

@ -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, getChat, getChatSettings, getCustomProfiles, getGlobalSettings, newName, resetChatSettings, saveChatStore, setGlobalSettingValueByKey, updateProfile } from './Storage.svelte' import { addMessage, clearMessages, deleteMessage, getChat, getChatSettings, getCustomProfiles, getGlobalSettings, newName, resetChatSettings, saveChatStore, setGlobalSettingValueByKey, 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'
@ -89,6 +89,18 @@ export const prepareSummaryPrompt = (chatId:number, maxTokens:number) => {
return mergeProfileFields(settings, currentSummaryPrompt, Math.floor(maxTokens * 0.75)).trim() return mergeProfileFields(settings, currentSummaryPrompt, Math.floor(maxTokens * 0.75)).trim()
} }
export const setSystemPrompt = (chatId: number) => {
const chat = getChat(chatId)
const systemPromptMessage:Message = {
role: 'system',
content: prepareProfilePrompt(chatId),
uuid: uuidv4()
}
if (chat.messages[0]?.role === 'system') deleteMessage(chatId, chat.messages[0].uuid)
chat.messages.unshift(systemPromptMessage)
saveChatStore()
}
// Restart currently loaded profile // Restart currently loaded profile
export const restartProfile = (chatId:number, noApply:boolean = false) => { export const restartProfile = (chatId:number, noApply:boolean = false) => {
const settings = getChatSettings(chatId) const settings = getChatSettings(chatId)
@ -96,12 +108,7 @@ export const restartProfile = (chatId:number, noApply:boolean = false) => {
// Clear current messages // Clear current messages
clearMessages(chatId) clearMessages(chatId)
// Add the system prompt // Add the system prompt
const systemPromptMessage:Message = { setSystemPrompt(chatId)
role: 'system',
content: prepareProfilePrompt(chatId),
uuid: uuidv4()
}
addMessage(chatId, systemPromptMessage)
// Add trainingPrompts, if any // Add trainingPrompts, if any
if (settings.trainingPrompts) { if (settings.trainingPrompts) {