Merge pull request #160 from Webifi/main
Force short suggested names; rename from chat menu; hidden prompt prefix
This commit is contained in:
		
						commit
						284589b6f3
					
				
							
								
								
									
										17
									
								
								src/app.scss
								
								
								
								
							
							
						
						
									
										17
									
								
								src/app.scss
								
								
								
								
							| 
						 | 
					@ -231,16 +231,16 @@ $modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.menu-list {
 | 
					.menu-list {
 | 
				
			||||||
  a:hover {
 | 
					  a:hover {
 | 
				
			||||||
    .delete-button {
 | 
					    .delete-button, .edit-button {
 | 
				
			||||||
      display: block !important;
 | 
					      display: block !important;
 | 
				
			||||||
      background-color: initial;
 | 
					      background-color: initial;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  .delete-button {
 | 
					  .delete-button, .edit-button {
 | 
				
			||||||
    opacity: .8;
 | 
					    opacity: .8;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  .delete-button:hover {
 | 
					  .delete-button:hover, .edit-button {
 | 
				
			||||||
    opacity: 1;
 | 
					    opacity: 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -321,6 +321,17 @@ $modal-background-background-color-dark: rgba($dark, 0.86) !default; // remove t
 | 
				
			||||||
  z-index: 200;
 | 
					  z-index: 200;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.chat-menu-item .edit-button {
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  right: 2em;
 | 
				
			||||||
 | 
					  z-index: 200;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.chat-name-editor {
 | 
				
			||||||
 | 
					  margin: .5em;
 | 
				
			||||||
 | 
					  padding:.1em;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Overrides for main layout  */
 | 
					/* Overrides for main layout  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.side-bar-column {
 | 
					.side-bar-column {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@
 | 
				
			||||||
  } 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'
 | 
				
			||||||
  import { prepareSummaryPrompt, restartProfile } from './Profiles.svelte'
 | 
					  import { mergeProfileFields, prepareSummaryPrompt, restartProfile } from './Profiles.svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  import { afterUpdate, onMount, onDestroy } from 'svelte'
 | 
					  import { afterUpdate, onMount, onDestroy } from 'svelte'
 | 
				
			||||||
  import Fa from 'svelte-fa/src/fa.svelte'
 | 
					  import Fa from 'svelte-fa/src/fa.svelte'
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,7 @@
 | 
				
			||||||
    faLightbulb,
 | 
					    faLightbulb,
 | 
				
			||||||
    faCommentSlash
 | 
					    faCommentSlash
 | 
				
			||||||
  } 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'
 | 
				
			||||||
  import { countPromptTokens, getModelMaxTokens, getPrice } from './Stats.svelte'
 | 
					  import { countPromptTokens, getModelMaxTokens, getPrice } from './Stats.svelte'
 | 
				
			||||||
  import { autoGrowInputOnEvent, scrollToMessage, sizeTextElements } from './Util.svelte'
 | 
					  import { autoGrowInputOnEvent, scrollToMessage, sizeTextElements } from './Util.svelte'
 | 
				
			||||||
| 
						 | 
					@ -184,10 +184,17 @@
 | 
				
			||||||
    let filtered = messages.filter(messageFilter)
 | 
					    let filtered = messages.filter(messageFilter)
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    // Get an estimate of the total prompt size we're sending
 | 
					    // Get an estimate of the total prompt size we're sending
 | 
				
			||||||
    const promptTokenCount:number = countPromptTokens(filtered, model)
 | 
					    let promptTokenCount:number = countPromptTokens(filtered, model)
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    let summarySize = chatSettings.summarySize
 | 
					    let summarySize = chatSettings.summarySize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const hiddenPromptPrefix = mergeProfileFields(chatSettings, chatSettings.hiddenPromptPrefix).trim()
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    if (hiddenPromptPrefix && filtered.length && filtered[filtered.length - 1].role === 'user') {
 | 
				
			||||||
 | 
					      // update estimate with hiddenPromptPrefix token count
 | 
				
			||||||
 | 
					      promptTokenCount += encode(hiddenPromptPrefix + '\n\n').length
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // console.log('Estimated',promptTokenCount,'prompt token for this request')
 | 
					    // console.log('Estimated',promptTokenCount,'prompt token for this request')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (chatSettings.continuousChat && !opts.didSummary &&
 | 
					    if (chatSettings.continuousChat && !opts.didSummary &&
 | 
				
			||||||
| 
						 | 
					@ -340,10 +347,21 @@
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const messagePayload = filtered.map((m, i) => {
 | 
				
			||||||
 | 
					      const r = { role: m.role, content: m.content }
 | 
				
			||||||
 | 
					      if (i === filtered.length - 1 && m.role === 'user' && hiddenPromptPrefix && !opts.summaryRequest) {
 | 
				
			||||||
 | 
					        // If the last prompt is a user prompt, and we have a hiddenPromptPrefix, inject it
 | 
				
			||||||
 | 
					        r.content = hiddenPromptPrefix + '\n\n' + m.content
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return r
 | 
				
			||||||
 | 
					    }) as Message[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Update token count with actual
 | 
				
			||||||
 | 
					    promptTokenCount = countPromptTokens(messagePayload, model)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      const request: Request = {
 | 
					      const request: Request = {
 | 
				
			||||||
        messages: filtered.map(m => { return { role: m.role, content: m.content } }) as Message[],
 | 
					        messages: messagePayload,
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Provide the settings by mapping the settingsMap to key/value pairs
 | 
					        // Provide the settings by mapping the settingsMap to key/value pairs
 | 
				
			||||||
        ...getRequestSettingList().reduce((acc, setting) => {
 | 
					        ...getRequestSettingList().reduce((acc, setting) => {
 | 
				
			||||||
          const key = setting.key
 | 
					          const key = setting.key
 | 
				
			||||||
| 
						 | 
					@ -351,16 +369,15 @@
 | 
				
			||||||
          if (typeof setting.apiTransform === 'function') {
 | 
					          if (typeof setting.apiTransform === 'function') {
 | 
				
			||||||
            value = setting.apiTransform(chatId, setting, value)
 | 
					            value = setting.apiTransform(chatId, setting, value)
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          if (opts.summaryRequest && opts.maxTokens) {
 | 
					          if (opts.maxTokens) {
 | 
				
			||||||
            // requesting summary. do overrides
 | 
					            if (key === 'max_tokens') value = opts.maxTokens // only as large as requested
 | 
				
			||||||
            if (key === 'max_tokens') value = opts.maxTokens // only as large as we need for summary
 | 
					 | 
				
			||||||
            if (key === 'n') value = 1 // never more than one completion for summary
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          if (opts.streaming) {
 | 
					          if (opts.streaming || opts.summaryRequest) {
 | 
				
			||||||
            /*
 | 
					            /*
 | 
				
			||||||
            Streaming goes insane with more than one completion.
 | 
					            Streaming goes insane with more than one completion.
 | 
				
			||||||
            Doesn't seem like there's any way to separate the jumbled mess of deltas for the
 | 
					            Doesn't seem like there's any way to separate the jumbled mess of deltas for the
 | 
				
			||||||
            different completions.
 | 
					            different completions.
 | 
				
			||||||
 | 
					            Summary should only have one completion
 | 
				
			||||||
            */
 | 
					            */
 | 
				
			||||||
            if (key === 'n') value = 1
 | 
					            if (key === 'n') value = 1
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
| 
						 | 
					@ -391,7 +408,11 @@
 | 
				
			||||||
        let errorResponse
 | 
					        let errorResponse
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
          const errObj = await response.json()
 | 
					          const errObj = await response.json()
 | 
				
			||||||
          errorResponse = errObj?.error?.code || 'Unexpected Response'
 | 
					          errorResponse = errObj?.error?.code
 | 
				
			||||||
 | 
					          if (!errorResponse && response.choices && response.choices[0]) {
 | 
				
			||||||
 | 
					            errorResponse = response.choices[0]?.message?.content
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          errorResponse = errorResponse || 'Unexpected Response'
 | 
				
			||||||
        } catch (e) {
 | 
					        } catch (e) {
 | 
				
			||||||
          errorResponse = 'Unknown Response'
 | 
					          errorResponse = 'Unknown Response'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -555,7 +576,7 @@
 | 
				
			||||||
  const suggestName = async (): Promise<void> => {
 | 
					  const suggestName = async (): Promise<void> => {
 | 
				
			||||||
    const suggestMessage: Message = {
 | 
					    const suggestMessage: Message = {
 | 
				
			||||||
      role: 'user',
 | 
					      role: 'user',
 | 
				
			||||||
      content: "Can you give me a 5 word summary of this conversation's topic?",
 | 
					      content: "Using appropriate language, please give a 5 word summary of this conversation's topic.",
 | 
				
			||||||
      uuid: uuidv4()
 | 
					      uuid: uuidv4()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -565,7 +586,9 @@
 | 
				
			||||||
    const response = await sendRequest(suggestMessages, {
 | 
					    const response = await sendRequest(suggestMessages, {
 | 
				
			||||||
      chat,
 | 
					      chat,
 | 
				
			||||||
      autoAddMessages: false,
 | 
					      autoAddMessages: false,
 | 
				
			||||||
      streaming: false
 | 
					      streaming: false,
 | 
				
			||||||
 | 
					      summaryRequest: true,
 | 
				
			||||||
 | 
					      maxTokens: 10
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    await response.promiseToFinish()
 | 
					    await response.promiseToFinish()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -577,10 +600,10 @@
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      response.getMessages().forEach(m => {
 | 
					      response.getMessages().forEach(m => {
 | 
				
			||||||
        chat.name = m.content
 | 
					        const name = m.content.split(/\s+/).slice(0, 8).join(' ').trim()
 | 
				
			||||||
 | 
					        if (name) chat.name = name
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      saveChatStore()
 | 
					      saveChatStore()
 | 
				
			||||||
      $checkStateChange++
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,19 +1,52 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
  import { replace } from 'svelte-spa-router'
 | 
					  import { replace } from 'svelte-spa-router'
 | 
				
			||||||
  import type { Chat } from './Types.svelte'
 | 
					  import type { Chat } from './Types.svelte'
 | 
				
			||||||
  import { apiKeyStorage, deleteChat, pinMainMenu } from './Storage.svelte'
 | 
					  import { apiKeyStorage, deleteChat, pinMainMenu, saveChatStore } from './Storage.svelte'
 | 
				
			||||||
  import Fa from 'svelte-fa/src/fa.svelte'
 | 
					  import Fa from 'svelte-fa/src/fa.svelte'
 | 
				
			||||||
  import { faTrash, faCircleCheck } from '@fortawesome/free-solid-svg-icons/index'
 | 
					  import { faTrash, faCircleCheck, faPencil } from '@fortawesome/free-solid-svg-icons/index'
 | 
				
			||||||
  import { faMessage } from '@fortawesome/free-regular-svg-icons/index'
 | 
					  import { faMessage } from '@fortawesome/free-regular-svg-icons/index'
 | 
				
			||||||
 | 
					  import { onMount } from 'svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export let chat:Chat
 | 
					  export let chat:Chat
 | 
				
			||||||
  export let activeChatId:number|undefined
 | 
					  export let activeChatId:number|undefined
 | 
				
			||||||
  export let prevChat:Chat|undefined
 | 
					  export let prevChat:Chat|undefined
 | 
				
			||||||
  export let nextChat:Chat|undefined
 | 
					  export let nextChat:Chat|undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let editing:boolean = false
 | 
				
			||||||
 | 
					  let original:string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let waitingForConfirm:any = 0
 | 
					  let waitingForConfirm:any = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function delChat () {
 | 
					  onMount(async () => {
 | 
				
			||||||
 | 
					    if (!chat.name) {
 | 
				
			||||||
 | 
					      chat.name = `Chat ${chat.id}`
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const keydown = (event:KeyboardEvent) => {
 | 
				
			||||||
 | 
					    if (event.key === 'Escape') {
 | 
				
			||||||
 | 
					      event.stopPropagation()
 | 
				
			||||||
 | 
					      event.preventDefault()
 | 
				
			||||||
 | 
					      chat.name = original
 | 
				
			||||||
 | 
					      editing = false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (event.key === 'Tab' || event.key === 'Enter') {
 | 
				
			||||||
 | 
					      event.stopPropagation()
 | 
				
			||||||
 | 
					      event.preventDefault()
 | 
				
			||||||
 | 
					      update()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const update = () => {
 | 
				
			||||||
 | 
					    editing = false
 | 
				
			||||||
 | 
					    if (!chat.name) {
 | 
				
			||||||
 | 
					      chat.name = original
 | 
				
			||||||
 | 
					      return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    saveChatStore()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const delChat = () => {
 | 
				
			||||||
    if (!waitingForConfirm) {
 | 
					    if (!waitingForConfirm) {
 | 
				
			||||||
      // wait a second for another click to avoid accidental deletes
 | 
					      // wait a second for another click to avoid accidental deletes
 | 
				
			||||||
      waitingForConfirm = setTimeout(() => { waitingForConfirm = 0 }, 1000)
 | 
					      waitingForConfirm = setTimeout(() => { waitingForConfirm = 0 }, 1000)
 | 
				
			||||||
| 
						 | 
					@ -35,15 +68,33 @@
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const edit = () => {
 | 
				
			||||||
 | 
					    original = chat.name
 | 
				
			||||||
 | 
					    editing = true
 | 
				
			||||||
 | 
					    setTimeout(() => {
 | 
				
			||||||
 | 
					      const el = document.getElementById(`chat-menu-item-${chat.id}`)
 | 
				
			||||||
 | 
					      el && el.focus()
 | 
				
			||||||
 | 
					    }, 0)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<li>
 | 
					<li>
 | 
				
			||||||
  <a class="chat-menu-item" href={`#/chat/${chat.id}`} on:click={() => { $pinMainMenu = false }} class:is-waiting={waitingForConfirm} class:is-disabled={!$apiKeyStorage} class:is-active={activeChatId === chat.id}>
 | 
					  {#if editing}
 | 
				
			||||||
 | 
					    <div id="chat-menu-item-{chat.id}" class="chat-name-editor" on:keydown={keydown} contenteditable bind:innerText={chat.name} on:blur={update} />
 | 
				
			||||||
 | 
					  {:else}
 | 
				
			||||||
 | 
					  <a 
 | 
				
			||||||
 | 
					    href={`#/chat/${chat.id}`}
 | 
				
			||||||
 | 
					    class="chat-menu-item"
 | 
				
			||||||
 | 
					    class:is-waiting={waitingForConfirm} class:is-disabled={!$apiKeyStorage} class:is-active={activeChatId === chat.id}
 | 
				
			||||||
 | 
					    on:click={() => { $pinMainMenu = false }} >
 | 
				
			||||||
    {#if waitingForConfirm}
 | 
					    {#if waitingForConfirm}
 | 
				
			||||||
    <a class="is-pulled-right is-hidden px-1 py-0 has-text-weight-bold delete-button" href={'$'} on:click|preventDefault={() => delChat()}><Fa icon={faCircleCheck} /></a>
 | 
					    <a class="is-pulled-right is-hidden px-1 py-0 has-text-weight-bold delete-button" href={'$'} on:click|preventDefault={() => delChat()}><Fa icon={faCircleCheck} /></a>
 | 
				
			||||||
    {:else}
 | 
					    {:else}
 | 
				
			||||||
 | 
					    <a class="is-pulled-right is-hidden px-1 py-0 has-text-weight-bold edit-button" href={'$'} on:click|preventDefault={() => edit()}><Fa icon={faPencil} /></a>
 | 
				
			||||||
    <a class="is-pulled-right is-hidden px-1 py-0 has-text-weight-bold delete-button" href={'$'} on:click|preventDefault={() => delChat()}><Fa icon={faTrash} /></a>
 | 
					    <a class="is-pulled-right is-hidden px-1 py-0 has-text-weight-bold delete-button" href={'$'} on:click|preventDefault={() => delChat()}><Fa icon={faTrash} /></a>
 | 
				
			||||||
    {/if}
 | 
					    {/if}
 | 
				
			||||||
    <span class="chat-item-name"><Fa class="mr-2 chat-icon" size="xs" icon="{faMessage}"/>{chat.name || `Chat ${chat.id}`}</span>
 | 
					    <span class="chat-item-name"><Fa class="mr-2 chat-icon" size="xs" icon="{faMessage}"/>{chat.name || `Chat ${chat.id}`}</span>
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
					  {/if}
 | 
				
			||||||
</li>
 | 
					</li>
 | 
				
			||||||
| 
						 | 
					@ -70,22 +70,25 @@ export const getProfile = (key:string, forReset:boolean = false):ChatSettings =>
 | 
				
			||||||
    return clone
 | 
					    return clone
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const mergeProfileFields = (settings: ChatSettings, content: string|undefined, maxWords: number|undefined = undefined): string => {
 | 
				
			||||||
 | 
					    if (!content?.toString) return ''
 | 
				
			||||||
 | 
					    content = (content + '').replaceAll('[[CHARACTER_NAME]]', settings.characterName || 'ChatGPT')
 | 
				
			||||||
 | 
					    if (maxWords) content = (content + '').replaceAll('[[MAX_WORDS]]', maxWords.toString())
 | 
				
			||||||
 | 
					    return content
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const prepareProfilePrompt = (chatId:number) => {
 | 
					export const prepareProfilePrompt = (chatId:number) => {
 | 
				
			||||||
    const settings = getChatSettings(chatId)
 | 
					    const settings = getChatSettings(chatId)
 | 
				
			||||||
    const characterName = settings.characterName
 | 
					    return mergeProfileFields(settings, settings.systemPrompt).trim()
 | 
				
			||||||
    const currentProfilePrompt = settings.systemPrompt
 | 
					 | 
				
			||||||
    return currentProfilePrompt.replaceAll('[[CHARACTER_NAME]]', characterName)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const prepareSummaryPrompt = (chatId:number, promptsSize:number, maxTokens:number|undefined = undefined) => {
 | 
					export const prepareSummaryPrompt = (chatId:number, promptsSize:number, maxTokens:number|undefined = undefined) => {
 | 
				
			||||||
    const settings = getChatSettings(chatId)
 | 
					    const settings = getChatSettings(chatId)
 | 
				
			||||||
    const characterName = settings.characterName || 'ChatGPT'
 | 
					 | 
				
			||||||
    maxTokens = maxTokens || settings.summarySize
 | 
					    maxTokens = maxTokens || settings.summarySize
 | 
				
			||||||
    maxTokens = Math.min(Math.floor(promptsSize / 4), maxTokens) // Make sure we're shrinking by at least a 4th
 | 
					    maxTokens = Math.min(Math.floor(promptsSize / 4), maxTokens) // Make sure we're shrinking by at least a 4th
 | 
				
			||||||
    const currentSummaryPrompt = settings.summaryPrompt
 | 
					    const currentSummaryPrompt = settings.summaryPrompt
 | 
				
			||||||
    return currentSummaryPrompt
 | 
					    // ~.75 words per token.  May need to reduce
 | 
				
			||||||
      .replaceAll('[[CHARACTER_NAME]]', characterName)
 | 
					    return mergeProfileFields(settings, currentSummaryPrompt, Math.floor(maxTokens * 0.75)).trim()
 | 
				
			||||||
      .replaceAll('[[MAX_WORDS]]', Math.floor(maxTokens * 0.75).toString()) // ~.75 words per token.  May need to reduce
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Restart currently loaded profile
 | 
					// Restart currently loaded profile
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,6 +84,7 @@ const defaults:ChatSettings = {
 | 
				
			||||||
  systemPrompt: '',
 | 
					  systemPrompt: '',
 | 
				
			||||||
  autoStartSession: false,
 | 
					  autoStartSession: false,
 | 
				
			||||||
  trainingPrompts: [],
 | 
					  trainingPrompts: [],
 | 
				
			||||||
 | 
					  hiddenPromptPrefix: '',
 | 
				
			||||||
  // useResponseAlteration: false,
 | 
					  // useResponseAlteration: false,
 | 
				
			||||||
  // responseAlterations: [],
 | 
					  // responseAlterations: [],
 | 
				
			||||||
  isDirty: false
 | 
					  isDirty: false
 | 
				
			||||||
| 
						 | 
					@ -167,6 +168,14 @@ const systemPromptSettings: ChatSetting[] = [
 | 
				
			||||||
        type: 'textarea',
 | 
					        type: 'textarea',
 | 
				
			||||||
        hide: (chatId) => !getChatSettings(chatId).useSystemPrompt
 | 
					        hide: (chatId) => !getChatSettings(chatId).useSystemPrompt
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        key: 'hiddenPromptPrefix',
 | 
				
			||||||
 | 
					        name: 'Hidden Prompt Prefix',
 | 
				
			||||||
 | 
					        title: 'A prompt that will be silently injected before every user prompt.',
 | 
				
			||||||
 | 
					        placeholder: 'Enter user prompt prefix here.  You can remind ChatGPT how to act.',
 | 
				
			||||||
 | 
					        type: 'textarea',
 | 
				
			||||||
 | 
					        hide: (chatId) => !getChatSettings(chatId).useSystemPrompt
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        key: 'trainingPrompts',
 | 
					        key: 'trainingPrompts',
 | 
				
			||||||
        name: 'Training Prompts',
 | 
					        name: 'Training Prompts',
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,6 @@
 | 
				
			||||||
    profileName: string,
 | 
					    profileName: string,
 | 
				
			||||||
    profileDescription: string,
 | 
					    profileDescription: string,
 | 
				
			||||||
    continuousChat: (''|'fifo'|'summary');
 | 
					    continuousChat: (''|'fifo'|'summary');
 | 
				
			||||||
    // useSummarization: boolean;
 | 
					 | 
				
			||||||
    summaryThreshold: number;
 | 
					    summaryThreshold: number;
 | 
				
			||||||
    summarySize: number;
 | 
					    summarySize: number;
 | 
				
			||||||
    pinTop: number;
 | 
					    pinTop: number;
 | 
				
			||||||
| 
						 | 
					@ -67,6 +66,7 @@
 | 
				
			||||||
    useSystemPrompt: boolean;
 | 
					    useSystemPrompt: boolean;
 | 
				
			||||||
    systemPrompt: string;
 | 
					    systemPrompt: string;
 | 
				
			||||||
    autoStartSession: boolean;
 | 
					    autoStartSession: boolean;
 | 
				
			||||||
 | 
					    hiddenPromptPrefix: string;
 | 
				
			||||||
    trainingPrompts?: Message[];
 | 
					    trainingPrompts?: Message[];
 | 
				
			||||||
    useResponseAlteration?: boolean;
 | 
					    useResponseAlteration?: boolean;
 | 
				
			||||||
    responseAlterations?: ResponseAlteration[];
 | 
					    responseAlterations?: ResponseAlteration[];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue