This commit is contained in:
Webifi 2023-05-28 01:21:06 -05:00
parent b201f03b67
commit b1acf6806a
4 changed files with 53 additions and 53 deletions

View File

@ -17,7 +17,7 @@
updateChatSettings, updateChatSettings,
resetChatSettings, resetChatSettings,
setChatSettingValue, setChatSettingValue,
addChatFromJSON, addChatFromJSON
} from './Storage.svelte' } from './Storage.svelte'
import { getChatSettingObjectByKey, getChatSettingList, getRequestSettingList } from './Settings.svelte' import { getChatSettingObjectByKey, getChatSettingList, getRequestSettingList } from './Settings.svelte'
import { import {
@ -29,8 +29,7 @@
type SettingSelect, type SettingSelect,
type Chat, type Chat,
type SelectOption, type SelectOption,
supportedModels, supportedModels
type ChatSettings
} from './Types.svelte' } from './Types.svelte'
import Prompts from './Prompts.svelte' import Prompts from './Prompts.svelte'
import Messages from './Messages.svelte' import Messages from './Messages.svelte'
@ -54,7 +53,7 @@
faDownload, faDownload,
faUpload, faUpload,
faEraser, faEraser,
faRotateRight, faRotateRight
} from '@fortawesome/free-solid-svg-icons/index' } from '@fortawesome/free-solid-svg-icons/index'
import { encode } from 'gpt-tokenizer' import { encode } from 'gpt-tokenizer'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
@ -532,10 +531,10 @@
const el = (event.target as HTMLInputElement) const el = (event.target as HTMLInputElement)
const doSet = () => { const doSet = () => {
try { try {
(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) {
alert('Unable to change:\n' + e.message) window.alert('Unable to change:\n' + e.message)
} }
switch (setting.type) { switch (setting.type) {
case 'boolean': case 'boolean':
@ -546,15 +545,15 @@
setChatSettingValue(chatId, setting, el.value) setChatSettingValue(chatId, setting, el.value)
} }
try { try {
(typeof setting.afterChange === 'function') && setting.afterChange(chatId, setting, chatSettings[setting.key]) (typeof setting.afterChange === 'function') && setting.afterChange(chatId, setting, chatSettings[setting.key]) &&
&& refreshSettings() refreshSettings()
} catch (e) { } catch (e) {
setChatSettingValue(chatId, setting, val) setChatSettingValue(chatId, setting, val)
alert('Unable to change:\n' + e.message) window.alert('Unable to change:\n' + e.message)
} }
} }
if (setting.key === 'profile' && chatSettings.sessionStarted if (setting.key === 'profile' && chatSettings.sessionStarted &&
&& (getProfile(el.value).characterName !== chatSettings.characterName)) { (getProfile(el.value).characterName !== chatSettings.characterName)) {
const val = chatSettings[setting.key] const val = chatSettings[setting.key]
if (window.confirm('Personality change will not correctly apply to existing chat session.\n Continue?')) { if (window.confirm('Personality change will not correctly apply to existing chat session.\n Continue?')) {
doSet() doSet()
@ -584,7 +583,7 @@
saveCustomProfile(chat.settings) saveCustomProfile(chat.settings)
refreshSettings() refreshSettings()
} catch (e) { } catch (e) {
alert('Error saving profile: \n' + e.message) window.alert('Error saving profile: \n' + e.message)
} }
} }
@ -614,7 +613,7 @@
updateProfileSelectOptions() updateProfileSelectOptions()
showSettingsModal && showSettingsModal++ showSettingsModal && showSettingsModal++
} catch (e) { } catch (e) {
alert('Error cloning profile: \n' + e.message) window.alert('Error cloning profile: \n' + e.message)
} }
} }
@ -629,7 +628,7 @@
updateProfileSelectOptions() updateProfileSelectOptions()
showSettings() showSettings()
} catch (e) { } catch (e) {
alert('Error deleting profile: \n' + e.message) window.alert('Error deleting profile: \n' + e.message)
} }
} }
@ -652,7 +651,7 @@
updateProfileSelectOptions() updateProfileSelectOptions()
showSettingsModal && showSettingsModal++ showSettingsModal && showSettingsModal++
} catch (e) { } catch (e) {
alert('Unable to import profile: \n' + e.message) window.alert('Unable to import profile: \n' + e.message)
} }
} }
} }
@ -684,7 +683,7 @@
<div class="level-right"> <div class="level-right">
<div class="level-item"> <div class="level-item">
<div class="dropdown is-right" class:is-active={showChatMenu} use:clickOutside={()=>{showChatMenu=false}}> <div class="dropdown is-right" class:is-active={showChatMenu} use:clickOutside={() => { showChatMenu = false }}>
<div class="dropdown-trigger"> <div class="dropdown-trigger">
<button class="button" aria-haspopup="true" <button class="button" aria-haspopup="true"
aria-controls="dropdown-menu3" aria-controls="dropdown-menu3"
@ -695,11 +694,11 @@
</div> </div>
<div class="dropdown-menu" id="dropdown-menu3" role="menu"> <div class="dropdown-menu" id="dropdown-menu3" role="menu">
<div class="dropdown-content"> <div class="dropdown-content">
<a href={'#'} class="dropdown-item" on:click|preventDefault={() => { showChatMenu = false;showSettings() }}> <a href={'#'} class="dropdown-item" on:click|preventDefault={() => { showChatMenu = false; showSettings() }}>
<span><Fa icon={faGear}/></span> Settings <span><Fa icon={faGear}/></span> Settings
</a> </a>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
<a href={'#'} class="dropdown-item" on:click|preventDefault={() => { showChatMenu = false;copyChat(chatId) }}> <a href={'#'} class="dropdown-item" on:click|preventDefault={() => { showChatMenu = false; copyChat(chatId) }}>
<span><Fa icon={faClone}/></span> Clone Chat <span><Fa icon={faClone}/></span> Clone Chat
</a> </a>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
@ -713,14 +712,14 @@
<span><Fa icon={faUpload}/></span> Load Chat <span><Fa icon={faUpload}/></span> Load Chat
</a> </a>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
<a href={'#'} class="dropdown-item" on:click|preventDefault={()=>{applyProfile(chatId, '', true);closeSettings()}}> <a href={'#'} class="dropdown-item" on:click|preventDefault={() => { applyProfile(chatId, '', true); closeSettings() }}>
<span><Fa icon={faRotateRight}/></span> Restart Chat <span><Fa icon={faRotateRight}/></span> Restart Chat
</a> </a>
<a href={'#'} class="dropdown-item" on:click|preventDefault={()=>{showChatMenu = false;clearMessages(chatId)}}> <a href={'#'} class="dropdown-item" on:click|preventDefault={() => { showChatMenu = false; clearMessages(chatId) }}>
<span><Fa icon={faEraser}/></span> Clear Chat Messages <span><Fa icon={faEraser}/></span> Clear Chat Messages
</a> </a>
<hr class="dropdown-divider"> <hr class="dropdown-divider">
<a href={'#'} class="dropdown-item" on:click|preventDefault={()=>{showChatMenu = false;deleteChat()}}> <a href={'#'} class="dropdown-item" on:click|preventDefault={() => { showChatMenu = false; deleteChat() }}>
<span><Fa icon={faTrash}/></span> Delete Chat <span><Fa icon={faTrash}/></span> Delete Chat
</a> </a>
</div> </div>

View File

@ -1,8 +1,7 @@
<script context="module" lang="ts"> <script context="module" lang="ts">
import copy from 'copy-to-clipboard';
import { getChatDefaults, getExcludeFromProfile } from './Settings.svelte' import { getChatDefaults, getExcludeFromProfile } from './Settings.svelte'
// Profile definitions // Profile definitions
import { addMessage, clearMessages, getChatSettings, getCustomProfiles, getGlobalSettings, getMessages, resetChatSettings, setChatSettingValue, setChatSettingValueByKey, setGlobalSettingValueByKey } from './Storage.svelte' import { addMessage, clearMessages, getChatSettings, getCustomProfiles, getGlobalSettings, resetChatSettings, setChatSettingValueByKey, setGlobalSettingValueByKey } 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'
@ -37,11 +36,11 @@ export const getProfileSelect = ():SelectOption[] => {
export const getProfile = (key:string):ChatSettings => { export const getProfile = (key:string):ChatSettings => {
const allProfiles = getProfiles() const allProfiles = getProfiles()
const profile = allProfiles[key] || const profile = allProfiles[key] ||
allProfiles[getGlobalSettings().defaultProfile||''] || allProfiles[getGlobalSettings().defaultProfile || ''] ||
profiles[defaultProfile] || profiles[defaultProfile] ||
profiles[Object.keys(profiles)[0]] profiles[Object.keys(profiles)[0]]
const clone = JSON.parse(JSON.stringify(profile)) // Always return a copy const clone = JSON.parse(JSON.stringify(profile)) // Always return a copy
Object.keys(getExcludeFromProfile()).forEach(k=>{ Object.keys(getExcludeFromProfile()).forEach(k => {
delete clone[k] delete clone[k]
}) })
return clone return clone

View File

@ -1,6 +1,6 @@
<script context="module" lang="ts"> <script context="module" lang="ts">
import { applyProfile } from './Profiles.svelte' import { applyProfile } from './Profiles.svelte'
import { getChatSettings } from './Storage.svelte'; import { getChatSettings } from './Storage.svelte'
import { encode } from 'gpt-tokenizer' import { encode } from 'gpt-tokenizer'
// Setting definitions // Setting definitions
@ -59,7 +59,7 @@ const gptDefaults: Request = Object.freeze({
presence_penalty: 0, presence_penalty: 0,
frequency_penalty: 0, frequency_penalty: 0,
logit_bias: null, logit_bias: null,
user: undefined, user: undefined
}) })
// Core set of defaults // Core set of defaults
@ -82,14 +82,14 @@ const defaults:ChatSettings = Object.freeze({
// There are chat session state variables, and really don't belong here // There are chat session state variables, and really don't belong here
// But it was easier to just put them here. // But it was easier to just put them here.
startSession: false, // Should the session start automatically startSession: false, // Should the session start automatically
sessionStarted: false, // Has the session started (user made a first request) sessionStarted: false // Has the session started (user made a first request)
}) })
const excludeFromProfile = { const excludeFromProfile = {
messages: true, messages: true,
startSession: true, startSession: true,
sessionStarted: true, sessionStarted: true,
user: true, user: true
} }
const profileSetting: ChatSetting & SettingSelect = { const profileSetting: ChatSetting & SettingSelect = {
@ -103,7 +103,7 @@ const profileSetting: ChatSetting & SettingSelect = {
afterChange: (chatId, setting) => { afterChange: (chatId, setting) => {
applyProfile(chatId, '', !getChatSettings(chatId).sessionStarted) applyProfile(chatId, '', !getChatSettings(chatId).sessionStarted)
return true // Signal we should refresh the setting modal return true // Signal we should refresh the setting modal
}, }
} }
// Settings that will not be part of the API request // Settings that will not be part of the API request
@ -113,14 +113,14 @@ const nonRequestSettings: ChatSetting[] = [
key: 'profileName', key: 'profileName',
name: 'Profile Name', name: 'Profile Name',
title: 'How this profile is displayed in the select list.', title: 'How this profile is displayed in the select list.',
type: 'text', type: 'text'
// hide: (chatId) => { return !getChatSettingValueByKey(chatId, 'useSystemPrompt') } // hide: (chatId) => { return !getChatSettingValueByKey(chatId, 'useSystemPrompt') }
}, },
{ {
key: 'profileDescription', key: 'profileDescription',
name: 'Description', name: 'Description',
title: 'How this profile is displayed in the select list.', title: 'How this profile is displayed in the select list.',
type: 'textarea', type: 'textarea'
// hide: (chatId) => { return !getChatSettingValueByKey(chatId, 'useSystemPrompt') } // hide: (chatId) => { return !getChatSettingValueByKey(chatId, 'useSystemPrompt') }
}, },
{ {
@ -129,14 +129,14 @@ const nonRequestSettings: ChatSetting[] = [
title: 'Send a "System" prompt as the first prompt.', title: 'Send a "System" prompt as the first prompt.',
header: 'System Prompt', header: 'System Prompt',
headerClass: 'is-info', headerClass: 'is-info',
type: 'boolean', type: 'boolean'
}, },
{ {
key: 'characterName', key: 'characterName',
name: 'Character Name', name: 'Character Name',
title: 'What the personality of this profile will be called.', title: 'What the personality of this profile will be called.',
type: 'text', type: 'text',
hide: (chatId) => !getChatSettings(chatId).useSystemPrompt, hide: (chatId) => !getChatSettings(chatId).useSystemPrompt
}, },
{ {
key: 'systemPrompt', key: 'systemPrompt',
@ -173,7 +173,7 @@ const nonRequestSettings: ChatSetting[] = [
header: 'Continuous Chat - Summarization', header: 'Continuous Chat - Summarization',
headerClass: 'is-info', headerClass: 'is-info',
title: 'When out of token space, summarize past tokens and keep going.', title: 'When out of token space, summarize past tokens and keep going.',
type: 'boolean', type: 'boolean'
}, },
{ {
key: 'summaryThreshold', key: 'summaryThreshold',
@ -235,7 +235,7 @@ const modelSetting: ChatSetting & SettingSelect = {
headerClass: 'is-warning', headerClass: 'is-warning',
options: [], options: [],
type: 'select', type: 'select',
forceApi: true, // Need to make sure we send this forceApi: true // Need to make sure we send this
} }
const chatSettingsList: ChatSetting[] = [ const chatSettingsList: ChatSetting[] = [
@ -307,7 +307,7 @@ const chatSettingsList: ChatSetting[] = [
key: 'logit_bias', key: 'logit_bias',
name: 'Logit Bias', name: 'Logit Bias',
title: 'Allows you to adjust bias of tokens used in completion.', title: 'Allows you to adjust bias of tokens used in completion.',
header: `Logit Bias. See <a target="_blank" href="https://help.openai.com/en/articles/5247780-using-logit-bias-to-define-token-probability">this article</a> for more details.`, header: 'Logit Bias. See <a target="_blank" href="https://help.openai.com/en/articles/5247780-using-logit-bias-to-define-token-probability">this article</a> for more details.',
type: 'other', type: 'other',
hide: () => true, hide: () => true,
// transform to JSON for request, first converting word->weight pairs to token(s)->weight. // transform to JSON for request, first converting word->weight pairs to token(s)->weight.
@ -318,13 +318,13 @@ const chatSettingsList: ChatSetting[] = [
apiTransform: (chatId, setting, val:Record<string, number>) => { apiTransform: (chatId, setting, val:Record<string, number>) => {
console.log('logit_bias', val, getChatSettings(chatId).logit_bias) console.log('logit_bias', val, getChatSettings(chatId).logit_bias)
if (!val) return null if (!val) return null
const tokenized:Record<number, number> = Object.entries(val).reduce((a,[k,v])=>{ const tokenized:Record<number, number> = Object.entries(val).reduce((a, [k, v]) => {
const tokens:number[] = encode(k) const tokens:number[] = encode(k)
tokens.forEach(t => {a[t] = v}) tokens.forEach(t => { a[t] = v })
return a return a
}, {} as Record<number, number>) }, {} as Record<number, number>)
return tokenized return tokenized
}, }
}, },
// Enable? // Enable?
{ {
@ -332,7 +332,7 @@ const chatSettingsList: ChatSetting[] = [
name: 'User?', name: 'User?',
title: 'Name of user?', title: 'Name of user?',
type: 'text', type: 'text',
hide: () => true, hide: () => true
} }
] ]

View File

@ -33,7 +33,7 @@
}) })
chatsStorage.set(chats) chatsStorage.set(chats)
// Apply defaults and prepare it to start // Apply defaults and prepare it to start
applyProfile(chatId,'', true) applyProfile(chatId, '', true)
return chatId return chatId
} }
@ -70,7 +70,7 @@
if (!chat.settings) { if (!chat.settings) {
chat.settings = {} as ChatSettings chat.settings = {} as ChatSettings
} }
Object.entries(getChatDefaults()).forEach(([k,v]) => { Object.entries(getChatDefaults()).forEach(([k, v]) => {
const val = chat.settings[k] const val = chat.settings[k]
chat.settings[k] = (val === undefined || val === null ? v : chat.settings[k]) as any chat.settings[k] = (val === undefined || val === null ? v : chat.settings[k]) as any
}) })
@ -89,11 +89,11 @@
const exclude = getExcludeFromProfile() const exclude = getExcludeFromProfile()
if (resetAll) { if (resetAll) {
// Reset to base defaults first, then apply profile // Reset to base defaults first, then apply profile
Object.entries(getChatDefaults()).forEach(([k,v]) => { Object.entries(getChatDefaults()).forEach(([k, v]) => {
chat.settings[k] = v chat.settings[k] = v
}) })
} }
Object.entries(profile).forEach(([k,v]) => { Object.entries(profile).forEach(([k, v]) => {
if (exclude[k]) return if (exclude[k]) return
chat.settings[k] = v chat.settings[k] = v
}) })
@ -187,7 +187,7 @@
// Add a new chat // Add a new chat
chats.push(chatCopy) chats.push(chatCopy)
// chatsStorage // chatsStorage
chatsStorage.set(chats) chatsStorage.set(chats)
} }
@ -211,11 +211,13 @@
if (setting) return setChatSettingValue(chatId, setting, value) if (setting) return setChatSettingValue(chatId, setting, value)
if (!(key in chatDefaults)) throw new Error('Invalid chat setting: ' + key) if (!(key in chatDefaults)) throw new Error('Invalid chat setting: ' + key)
const d = chatDefaults[key] const d = chatDefaults[key]
if (d === null || d === undefined) throw new Error('Unable to determine setting type for "' if (d === null || d === undefined) {
+ key +' from default of "' + d + '"') throw new Error('Unable to determine setting type for "' +
key + ' from default of "' + d + '"')
}
const chats = get(chatsStorage) const chats = get(chatsStorage)
const chat = chats.find((chat) => chat.id === chatId) as Chat const chat = chats.find((chat) => chat.id === chatId) as Chat
let settings = chat.settings as any const settings = chat.settings as any
settings[key] = cleanSettingValue(typeof d, value) settings[key] = cleanSettingValue(typeof d, value)
} }
@ -296,8 +298,8 @@
if (!profile.characterName || profile.characterName.length < 3) { if (!profile.characterName || profile.characterName.length < 3) {
throw new Error('Your profile\'s character needs a valid name.') throw new Error('Your profile\'s character needs a valid name.')
} }
const clone =JSON.parse(JSON.stringify(profile)) // Always store a copy const clone = JSON.parse(JSON.stringify(profile)) // Always store a copy
Object.keys(getExcludeFromProfile()).forEach(k=>{ Object.keys(getExcludeFromProfile()).forEach(k => {
delete clone[k] delete clone[k]
}) })
profiles[profile.profile as string] = clone profiles[profile.profile as string] = clone