Fix profile loading issues on new chat

This commit is contained in:
Webifi 2023-06-03 13:15:20 -05:00
parent 80aa0cbb57
commit aa94788573
5 changed files with 53 additions and 14 deletions

View File

@ -1,9 +1,10 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { getProfile } from './Profiles.svelte' import { getProfile } from './Profiles.svelte'
import { cleanSettingValue, setChatSettingValue } from './Storage.svelte' import { addChat, cleanSettingValue, setChatSettingValue } from './Storage.svelte'
import type { Chat, ChatSetting, ChatSettings, SettingPrompt } from './Types.svelte' import type { Chat, ChatSetting, ChatSettings, SettingPrompt } from './Types.svelte'
import { autoGrowInputOnEvent } from './Util.svelte' import { autoGrowInputOnEvent } from './Util.svelte'
import { replace } from 'svelte-spa-router';
export let setting:ChatSetting export let setting:ChatSetting
export let chatSettings:ChatSettings export let chatSettings:ChatSettings
@ -27,14 +28,29 @@
profile: [ profile: [
{ {
prompt: 'Unsaved changes to the current profile will be lost.\n Continue?', prompt: 'Unsaved changes to the current profile will be lost.\n Continue?',
fn: (setting, newVal, oldVal) => { checkPrompt: (setting, newVal, oldVal) => {
return !!chatSettings.isDirty && newVal !== oldVal return !!chatSettings.isDirty && newVal !== oldVal
}, },
passed: false passed: false
}, },
{
prompt: 'Would you like to start a new chat session with this profile?',
checkPrompt: (setting, newVal, oldVal) => {
return newVal !== oldVal
},
onYes: (setting, newVal, oldVal) => {
// start new char session, apply this profile, amd start it
setChatSettingValue(chatId, setting, oldVal)
const profile = getProfile(newVal)
const newChatId = addChat(profile)
replace(`/chat/${newChatId}`)
return true
},
passed: false
},
{ {
prompt: 'Personality change will not correctly apply to existing chat session.\n Continue?', prompt: 'Personality change will not correctly apply to existing chat session.\n Continue?',
fn: (setting, newVal, oldVal) => { checkPrompt: (setting, newVal, oldVal) => {
return chat.sessionStarted && newVal !== originalProfile && return chat.sessionStarted && newVal !== originalProfile &&
(getProfile(newVal).characterName !== chatSettings.characterName) (getProfile(newVal).characterName !== chatSettings.characterName)
}, },
@ -70,7 +86,7 @@
default: default:
setChatSettingValue(chatId, setting, el.value) setChatSettingValue(chatId, setting, el.value)
} }
const newVal = chatSettings[setting.key] const newVal = cleanSettingValue(setting.type, el.checked || el.value)
if (val === newVal) return if (val === newVal) return
try { try {
if ((typeof setting.afterChange === 'function') && setting.afterChange(chatId, setting, chatSettings[setting.key])) { if ((typeof setting.afterChange === 'function') && setting.afterChange(chatId, setting, chatSettings[setting.key])) {
@ -88,16 +104,21 @@
for (let i = 0, l = checks.length; i < l; i++) { for (let i = 0, l = checks.length; i < l; i++) {
const c = checks[i] const c = checks[i]
if (c.passed) continue if (c.passed) continue
if (c.fn(setting, newVal, val)) { if (c.checkPrompt(setting, newVal, val)) {
// eventually this needs to be an async call to a confirmation modal where // eventually this needs to be an async call to a confirmation modal where
// "passed", not really being used here, will be reworked to some other // "passed", not really being used here, will be reworked to some other
// state to deal with inevitable issues once a non-blocking modal is used. // state to deal with inevitable issues once a non-blocking modal is used.
if (window.confirm(c.prompt)) { if (window.confirm(c.prompt)) {
c.passed = true c.passed = true
if (c.onYes && c.onYes(setting, newVal, val)) {
resetSettingCheck(setting.key)
return
}
} else { } else {
// roll-back // roll-back
setChatSettingValue(chatId, setting, val) setChatSettingValue(chatId, setting, val)
// refresh setting modal, if open // refresh setting modal, if open
c.onNo && c.onNo(setting, newVal, val)
refreshSettings() refreshSettings()
resetSettingCheck(setting.key) resetSettingCheck(setting.key)
return return

View File

@ -10,7 +10,10 @@
deleteCustomProfile, deleteCustomProfile,
setGlobalSettingValueByKey, setGlobalSettingValueByKey,
resetChatSettings, resetChatSettings,
checkStateChange checkStateChange,
addChat
} from './Storage.svelte' } from './Storage.svelte'
import { supportedModels, type Chat, type ChatSetting, type ResponseModels, type SettingSelect, type SelectOption } from './Types.svelte' import { supportedModels, type Chat, type ChatSetting, type ResponseModels, type SettingSelect, type SelectOption } from './Types.svelte'
import { sizeTextElements } from './Util.svelte' import { sizeTextElements } from './Util.svelte'
@ -22,12 +25,14 @@
faFloppyDisk, faFloppyDisk,
faThumbtack, faThumbtack,
faDownload, faDownload,
faUpload faUpload,
faSquarePlus
} 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 { afterUpdate } from 'svelte' import { afterUpdate } from 'svelte'
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';
export let chatId:number export let chatId:number
export const show = () => { showSettings() } export const show = () => { showSettings() }
@ -201,6 +206,11 @@
return cname return cname
} }
const startNewChat = () => {
const newChatId = addChat(chatSettings)
replace(`/chat/${newChatId}`)
}
// excludeFromProfile // excludeFromProfile
const deepEqual = (x:any, y:any) => { const deepEqual = (x:any, y:any) => {
@ -244,8 +254,9 @@
<div class="level is-mobile"> <div class="level is-mobile">
<div class="level-left"> <div class="level-left">
<!-- <button class="button is-info" on:click={closeSettings}>Close</button> --> <!-- <button class="button is-info" on:click={closeSettings}>Close</button> -->
<button class="button" class:is-disabled={!chatSettings.isDirty} on:click={saveProfile}>Save Changes</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" 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 is-warning" title="Start new chat with this profile." class:is-disabled={!chatSettings.isDirty} on:click={startNewChat}>New Chat</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}>
@ -266,6 +277,9 @@
<a href={'#'} class="dropdown-item" class:is-disabled={isDefault} on:click|preventDefault={pinDefaultProfile}> <a href={'#'} class="dropdown-item" class:is-disabled={isDefault} on:click|preventDefault={pinDefaultProfile}>
<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" class:is-disabled={isDefault} on:click|preventDefault={startNewChat}>
<span class="menu-icon"><Fa icon={faSquarePlus}/></span> Start New Chat Using Profile
</a>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
<a href={'#'} <a href={'#'}
class="dropdown-item" class="dropdown-item"

View File

@ -45,7 +45,7 @@
></div> ></div>
{:else} {:else}
<div class="level-item"> <div class="level-item">
<a href={'#/chat/new'} class="panel-block" class:is-disabled={!$apiKeyStorage} <a href={'#/chat/new'} class="panel-block" title="Start new chat with default profile" class:is-disabled={!$apiKeyStorage}
><span class="greyscale mr-2"><Fa icon={faSquarePlus} /></span> New chat</a ><span class="greyscale mr-2"><Fa icon={faSquarePlus} /></span> New chat</a
></div> ></div>
{/if} {/if}

View File

@ -22,17 +22,19 @@
return chatId return chatId
} }
export const addChat = (): number => { export const addChat = (profile:ChatSettings|undefined=undefined): number => {
const chats = get(chatsStorage) const chats = get(chatsStorage)
// Find the max chatId // Find the max chatId
const chatId = newChatID() const chatId = newChatID()
profile = JSON.parse(JSON.stringify(profile || getProfile('')))
// Add a new chat // Add a new chat
chats.push({ chats.push({
id: chatId, id: chatId,
name: `Chat ${chatId}`, name: `Chat ${chatId}`,
settings: {} as ChatSettings, settings: profile as any,
messages: [], messages: [],
usage: {} as Record<Model, Usage>, usage: {} as Record<Model, Usage>,
startSession: false, startSession: false,

View File

@ -172,7 +172,9 @@ type SettingBoolean = {
export type SettingPrompt = { export type SettingPrompt = {
prompt: string; prompt: string;
fn: (setting:ChatSetting, newVal:any, oldVal:any)=>boolean; checkPrompt: (setting:ChatSetting, newVal:any, oldVal:any)=>boolean;
onYes?: (setting:ChatSetting, newVal:any, oldVal:any)=>boolean;
onNo?: (setting:ChatSetting, newVal:any, oldVal:any)=>boolean;
passed: boolean; passed: boolean;
}; };