Add truncated completion joining
This commit is contained in:
		
							parent
							
								
									d768f4b355
								
							
						
					
					
						commit
						c3172eb4aa
					
				
							
								
								
									
										18
									
								
								src/app.scss
								
								
								
								
							
							
						
						
									
										18
									
								
								src/app.scss
								
								
								
								
							| 
						 | 
					@ -622,6 +622,24 @@ aside.menu.main-menu .menu-expanse {
 | 
				
			||||||
  animation: cursor-blink 1s steps(2) infinite;
 | 
					  animation: cursor-blink 1s steps(2) infinite;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.message:last-of-type.incomplete .message-display p:last-of-type::after {
 | 
				
			||||||
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  content: '...';
 | 
				
			||||||
 | 
					  margin-left: 4px;
 | 
				
			||||||
 | 
					  font-weight: bold;
 | 
				
			||||||
 | 
					  animation: cursor-blink 1s steps(2) infinite;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.message.incomplete .tool-drawer .msg-incomplete {
 | 
				
			||||||
 | 
					  display: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.message:last-of-type.incomplete .tool-drawer .msg-incomplete {
 | 
				
			||||||
 | 
					  display: block;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.modal {
 | 
					.modal {
 | 
				
			||||||
  z-index:100;
 | 
					  z-index:100;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,17 +11,16 @@
 | 
				
			||||||
    checkStateChange,
 | 
					    checkStateChange,
 | 
				
			||||||
    showSetChatSettings,
 | 
					    showSetChatSettings,
 | 
				
			||||||
    submitExitingPromptsNow,
 | 
					    submitExitingPromptsNow,
 | 
				
			||||||
    deleteMessage
 | 
					    deleteMessage,
 | 
				
			||||||
 | 
					    continueMessage,
 | 
				
			||||||
 | 
					    getMessage
 | 
				
			||||||
  } from './Storage.svelte'
 | 
					  } from './Storage.svelte'
 | 
				
			||||||
  import { getRequestSettingList, defaultModel } from './Settings.svelte'
 | 
					  import { getRequestSettingList, defaultModel } from './Settings.svelte'
 | 
				
			||||||
  import {
 | 
					  import {
 | 
				
			||||||
    type Request,
 | 
					    type Request,
 | 
				
			||||||
    type Message,
 | 
					    type Message,
 | 
				
			||||||
    type Chat,
 | 
					    type Chat,
 | 
				
			||||||
    type ChatCompletionOpts,
 | 
					    type ChatCompletionOpts
 | 
				
			||||||
 | 
					 | 
				
			||||||
    type Usage
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  } 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'
 | 
				
			||||||
| 
						 | 
					@ -36,9 +35,7 @@
 | 
				
			||||||
    faPenToSquare,
 | 
					    faPenToSquare,
 | 
				
			||||||
    faMicrophone,
 | 
					    faMicrophone,
 | 
				
			||||||
    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'
 | 
				
			||||||
| 
						 | 
					@ -62,6 +59,7 @@
 | 
				
			||||||
  let input: HTMLTextAreaElement
 | 
					  let input: HTMLTextAreaElement
 | 
				
			||||||
  let recognition: any = null
 | 
					  let recognition: any = null
 | 
				
			||||||
  let recording = false
 | 
					  let recording = false
 | 
				
			||||||
 | 
					  let lastSubmitRecorded = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  $: chat = $chatsStorage.find((chat) => chat.id === chatId) as Chat
 | 
					  $: chat = $chatsStorage.find((chat) => chat.id === chatId) as Chat
 | 
				
			||||||
  $: chatSettings = chat.settings
 | 
					  $: chatSettings = chat.settings
 | 
				
			||||||
| 
						 | 
					@ -88,10 +86,17 @@
 | 
				
			||||||
        $submitExitingPromptsNow = false
 | 
					        $submitExitingPromptsNow = false
 | 
				
			||||||
        submitForm(false, true)
 | 
					        submitForm(false, true)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      if ($continueMessage) {
 | 
				
			||||||
 | 
					        const message = getMessage(chat, $continueMessage)
 | 
				
			||||||
 | 
					        $continueMessage = ''
 | 
				
			||||||
 | 
					        if (message && chat.messages.indexOf(message) === (chat.messages.length - 1)) {
 | 
				
			||||||
 | 
					          submitForm(lastSubmitRecorded, true, message)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  $: onStateChange($checkStateChange, $showSetChatSettings, $submitExitingPromptsNow)
 | 
					  $: onStateChange($checkStateChange, $showSetChatSettings, $submitExitingPromptsNow, $continueMessage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Make sure chat object is ready to go
 | 
					  // Make sure chat object is ready to go
 | 
				
			||||||
  updateChatSettings(chatId)
 | 
					  updateChatSettings(chatId)
 | 
				
			||||||
| 
						 | 
					@ -263,9 +268,6 @@
 | 
				
			||||||
            streaming: opts.streaming,
 | 
					            streaming: opts.streaming,
 | 
				
			||||||
            summary: []
 | 
					            summary: []
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          summaryResponse.usage = {
 | 
					 | 
				
			||||||
            prompt_tokens: 0
 | 
					 | 
				
			||||||
          } as Usage
 | 
					 | 
				
			||||||
          summaryResponse.model = model
 | 
					          summaryResponse.model = model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          // Insert summary prompt
 | 
					          // Insert summary prompt
 | 
				
			||||||
| 
						 | 
					@ -433,6 +435,7 @@
 | 
				
			||||||
        scrollToBottom()
 | 
					        scrollToBottom()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } catch (e) {
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					      console.error(e)
 | 
				
			||||||
      updating = false
 | 
					      updating = false
 | 
				
			||||||
      updatingMessage = ''
 | 
					      updatingMessage = ''
 | 
				
			||||||
      chatResponse.updateFromError(e.message)
 | 
					      chatResponse.updateFromError(e.message)
 | 
				
			||||||
| 
						 | 
					@ -477,10 +480,12 @@
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const submitForm = async (recorded: boolean = false, skipInput: boolean = false): Promise<void> => {
 | 
					  const submitForm = async (recorded: boolean = false, skipInput: boolean = false, fillMessage: Message|undefined = undefined): Promise<void> => {
 | 
				
			||||||
    // Compose the system prompt message if there are no messages yet - disabled for now
 | 
					    // Compose the system prompt message if there are no messages yet - disabled for now
 | 
				
			||||||
    if (updating) return
 | 
					    if (updating) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lastSubmitRecorded = recorded
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
    if (!skipInput) {
 | 
					    if (!skipInput) {
 | 
				
			||||||
      chat.sessionStarted = true
 | 
					      chat.sessionStarted = true
 | 
				
			||||||
      saveChatStore()
 | 
					      saveChatStore()
 | 
				
			||||||
| 
						 | 
					@ -488,8 +493,12 @@
 | 
				
			||||||
        // Compose the input message
 | 
					        // Compose the input message
 | 
				
			||||||
        const inputMessage: Message = { role: 'user', content: input.value, uuid: uuidv4() }
 | 
					        const inputMessage: Message = { role: 'user', content: input.value, uuid: uuidv4() }
 | 
				
			||||||
        addMessage(chatId, inputMessage)
 | 
					        addMessage(chatId, inputMessage)
 | 
				
			||||||
 | 
					      } else if (!fillMessage && chat.messages.length && chat.messages[chat.messages.length - 1].finish_reason === 'length') {
 | 
				
			||||||
 | 
					        fillMessage = chat.messages[chat.messages.length - 1]
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (fillMessage && fillMessage.content) fillMessage.content += ' ' // add a space
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Clear the input value
 | 
					      // Clear the input value
 | 
				
			||||||
      input.value = ''
 | 
					      input.value = ''
 | 
				
			||||||
      input.blur()
 | 
					      input.blur()
 | 
				
			||||||
| 
						 | 
					@ -503,6 +512,7 @@
 | 
				
			||||||
      chat,
 | 
					      chat,
 | 
				
			||||||
      autoAddMessages: true, // Auto-add and update messages in array
 | 
					      autoAddMessages: true, // Auto-add and update messages in array
 | 
				
			||||||
      streaming: chatSettings.stream,
 | 
					      streaming: chatSettings.stream,
 | 
				
			||||||
 | 
					      fillMessage,
 | 
				
			||||||
      onMessageChange: (messages) => {
 | 
					      onMessageChange: (messages) => {
 | 
				
			||||||
        scrollToBottom(true)
 | 
					        scrollToBottom(true)
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
<script context="module" lang="ts">
 | 
					<script context="module" lang="ts">
 | 
				
			||||||
// TODO: Integrate API calls
 | 
					// TODO: Integrate API calls
 | 
				
			||||||
import { addMessage, saveChatStore, updateRunningTotal } from './Storage.svelte'
 | 
					import { addMessage, saveChatStore, subtractRunningTotal, updateRunningTotal } from './Storage.svelte'
 | 
				
			||||||
import type { Chat, ChatCompletionOpts, Message, Response, Usage } from './Types.svelte'
 | 
					import type { Chat, ChatCompletionOpts, Message, Response, Usage } from './Types.svelte'
 | 
				
			||||||
import { encode } from 'gpt-tokenizer'
 | 
					import { encode } from 'gpt-tokenizer'
 | 
				
			||||||
import { v4 as uuidv4 } from 'uuid'
 | 
					import { v4 as uuidv4 } from 'uuid'
 | 
				
			||||||
| 
						 | 
					@ -10,10 +10,17 @@ export class ChatCompletionResponse {
 | 
				
			||||||
    this.opts = opts
 | 
					    this.opts = opts
 | 
				
			||||||
    this.chat = opts.chat
 | 
					    this.chat = opts.chat
 | 
				
			||||||
    this.messages = []
 | 
					    this.messages = []
 | 
				
			||||||
    if (opts.fillMessage) this.messages.push(opts.fillMessage)
 | 
					    if (opts.fillMessage) {
 | 
				
			||||||
 | 
					      this.messages.push(opts.fillMessage)
 | 
				
			||||||
 | 
					      this.offsetTotals = JSON.parse(JSON.stringify(opts.fillMessage.usage))
 | 
				
			||||||
 | 
					      this.isFill = true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    if (opts.onMessageChange) this.messageChangeListeners.push(opts.onMessageChange)
 | 
					    if (opts.onMessageChange) this.messageChangeListeners.push(opts.onMessageChange)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private offsetTotals: Usage
 | 
				
			||||||
 | 
					  private isFill: boolean = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private opts: ChatCompletionOpts
 | 
					  private opts: ChatCompletionOpts
 | 
				
			||||||
  private chat: Chat
 | 
					  private chat: Chat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,11 +46,30 @@ export class ChatCompletionResponse {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateFromSyncResponse (response: Response) {
 | 
					  updateFromSyncResponse (response: Response) {
 | 
				
			||||||
    response.choices.forEach((choice, i) => {
 | 
					    response.choices.forEach((choice, i) => {
 | 
				
			||||||
      const message = this.messages[i] || choice.message
 | 
					      const exitingMessage = this.messages[i]
 | 
				
			||||||
 | 
					      const message = exitingMessage || choice.message
 | 
				
			||||||
 | 
					      if (exitingMessage) {
 | 
				
			||||||
 | 
					        if (this.isFill && choice.message.content.match(/^'(t|ll|ve|m|d|re)[^a-z]/i)) {
 | 
				
			||||||
 | 
					          // deal with merging contractions since we've added an extra space to your fill message
 | 
				
			||||||
 | 
					          message.content.replace(/ $/, '')
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.isFill = false
 | 
				
			||||||
 | 
					        message.content += choice.message.content
 | 
				
			||||||
 | 
					        message.usage = message.usage || {
 | 
				
			||||||
 | 
					          prompt_tokens: 0,
 | 
				
			||||||
 | 
					          completion_tokens: 0,
 | 
				
			||||||
 | 
					          total_tokens: 0
 | 
				
			||||||
 | 
					        } as Usage
 | 
				
			||||||
 | 
					        message.usage.completion_tokens += response.usage.completion_tokens
 | 
				
			||||||
 | 
					        message.usage.prompt_tokens += response.usage.prompt_tokens
 | 
				
			||||||
 | 
					        message.usage.total_tokens += response.usage.total_tokens
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
        message.content = choice.message.content
 | 
					        message.content = choice.message.content
 | 
				
			||||||
        message.usage = response.usage
 | 
					        message.usage = response.usage
 | 
				
			||||||
      message.model = response.model
 | 
					      }
 | 
				
			||||||
 | 
					      message.finish_reason = choice.finish_reason
 | 
				
			||||||
      message.role = choice.message.role
 | 
					      message.role = choice.message.role
 | 
				
			||||||
 | 
					      message.model = response.model
 | 
				
			||||||
      this.messages[i] = message
 | 
					      this.messages[i] = message
 | 
				
			||||||
      if (this.opts.autoAddMessages) addMessage(this.chat.id, message)
 | 
					      if (this.opts.autoAddMessages) addMessage(this.chat.id, message)
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
| 
						 | 
					@ -60,7 +86,14 @@ export class ChatCompletionResponse {
 | 
				
			||||||
        uuid: uuidv4()
 | 
					        uuid: uuidv4()
 | 
				
			||||||
      } as Message
 | 
					      } as Message
 | 
				
			||||||
      choice.delta?.role && (message.role = choice.delta.role)
 | 
					      choice.delta?.role && (message.role = choice.delta.role)
 | 
				
			||||||
      choice.delta?.content && (message.content += choice.delta.content)
 | 
					      if (choice.delta?.content) {
 | 
				
			||||||
 | 
					        if (this.isFill && choice.delta.content.match(/^'(t|ll|ve|m|d|re)[^a-z]/i)) {
 | 
				
			||||||
 | 
					          // deal with merging contractions since we've added an extra space to your fill message
 | 
				
			||||||
 | 
					          message.content.replace(/([a-z]) $/i, '$1')
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.isFill = false
 | 
				
			||||||
 | 
					        message.content += choice.delta.content
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      completionTokenCount += encode(message.content).length
 | 
					      completionTokenCount += encode(message.content).length
 | 
				
			||||||
      message.usage = response.usage || {
 | 
					      message.usage = response.usage || {
 | 
				
			||||||
        prompt_tokens: this.promptTokenCount
 | 
					        prompt_tokens: this.promptTokenCount
 | 
				
			||||||
| 
						 | 
					@ -135,6 +168,10 @@ export class ChatCompletionResponse {
 | 
				
			||||||
    saveChatStore()
 | 
					    saveChatStore()
 | 
				
			||||||
    const message = this.messages[0]
 | 
					    const message = this.messages[0]
 | 
				
			||||||
    if (message) {
 | 
					    if (message) {
 | 
				
			||||||
 | 
					      if (this.offsetTotals) {
 | 
				
			||||||
 | 
					        // Need to subtract some previous message totals before we add new combined message totals
 | 
				
			||||||
 | 
					        subtractRunningTotal(this.chat.id, this.offsetTotals, this.chat.settings.model as any)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      updateRunningTotal(this.chat.id, message.usage as any, message.model as any)
 | 
					      updateRunningTotal(this.chat.id, message.usage as any, message.model as any)
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      // If no messages it's probably because of an error or user initiated abort.
 | 
					      // If no messages it's probably because of an error or user initiated abort.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,12 @@
 | 
				
			||||||
<script lang="ts">
 | 
					<script lang="ts">
 | 
				
			||||||
  import Code from './Code.svelte'
 | 
					  import Code from './Code.svelte'
 | 
				
			||||||
  import { createEventDispatcher, onMount } from 'svelte'
 | 
					  import { createEventDispatcher, onMount } from 'svelte'
 | 
				
			||||||
  import { deleteMessage, chatsStorage, deleteSummaryMessage, truncateFromMessage, submitExitingPromptsNow, saveChatStore } from './Storage.svelte'
 | 
					  import { deleteMessage, chatsStorage, deleteSummaryMessage, truncateFromMessage, submitExitingPromptsNow, saveChatStore, continueMessage } from './Storage.svelte'
 | 
				
			||||||
  import { getPrice } from './Stats.svelte'
 | 
					  import { getPrice } from './Stats.svelte'
 | 
				
			||||||
  import SvelteMarkdown from 'svelte-markdown'
 | 
					  import SvelteMarkdown from 'svelte-markdown'
 | 
				
			||||||
  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, faEllipsis } from '@fortawesome/free-solid-svg-icons/index'
 | 
				
			||||||
  import { errorNotice, scrollToMessage } from './Util.svelte'
 | 
					  import { errorNotice, scrollToMessage } from './Util.svelte'
 | 
				
			||||||
  import { openModal } from 'svelte-modals'
 | 
					  import { openModal } from 'svelte-modals'
 | 
				
			||||||
  import PromptConfirm from './PromptConfirm.svelte'
 | 
					  import PromptConfirm from './PromptConfirm.svelte'
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,11 @@
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const continueIncomplete = () => {
 | 
				
			||||||
 | 
					    editing = false
 | 
				
			||||||
 | 
					    $continueMessage = message.uuid
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const exit = () => {
 | 
					  const exit = () => {
 | 
				
			||||||
    doChange()
 | 
					    doChange()
 | 
				
			||||||
    editing = false
 | 
					    editing = false
 | 
				
			||||||
| 
						 | 
					@ -179,6 +184,7 @@
 | 
				
			||||||
  class:suppress={message.suppress} 
 | 
					  class:suppress={message.suppress} 
 | 
				
			||||||
  class:editing={editing}
 | 
					  class:editing={editing}
 | 
				
			||||||
  class:streaming={message.streaming}
 | 
					  class:streaming={message.streaming}
 | 
				
			||||||
 | 
					  class:incomplete={message.finish_reason === 'length'}
 | 
				
			||||||
>
 | 
					>
 | 
				
			||||||
  <div class="message-body content">
 | 
					  <div class="message-body content">
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -216,6 +222,18 @@
 | 
				
			||||||
  <div class="tool-drawer-mask"></div>
 | 
					  <div class="tool-drawer-mask"></div>
 | 
				
			||||||
  <div class="tool-drawer">
 | 
					  <div class="tool-drawer">
 | 
				
			||||||
    <div class="button-pack">
 | 
					    <div class="button-pack">
 | 
				
			||||||
 | 
					      {#if message.finish_reason === 'length'}
 | 
				
			||||||
 | 
					      <a
 | 
				
			||||||
 | 
					        href={'#'}
 | 
				
			||||||
 | 
					        title="Continue "
 | 
				
			||||||
 | 
					        class="msg-incomplete button is-small"
 | 
				
			||||||
 | 
					        on:click|preventDefault={() => {
 | 
				
			||||||
 | 
					          continueIncomplete()
 | 
				
			||||||
 | 
					        }}
 | 
				
			||||||
 | 
					      >
 | 
				
			||||||
 | 
					      <span class="icon"><Fa icon={faEllipsis} /></span>
 | 
				
			||||||
 | 
					      </a>
 | 
				
			||||||
 | 
					      {/if}
 | 
				
			||||||
      {#if message.summarized}
 | 
					      {#if message.summarized}
 | 
				
			||||||
      <a
 | 
					      <a
 | 
				
			||||||
        href={'#'}
 | 
					        href={'#'}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,6 +14,7 @@
 | 
				
			||||||
  export let showSetChatSettings = writable(false) //
 | 
					  export let showSetChatSettings = writable(false) //
 | 
				
			||||||
  export let submitExitingPromptsNow = writable(false) // for them to go now.  Will not submit anything in the input
 | 
					  export let submitExitingPromptsNow = writable(false) // for them to go now.  Will not submit anything in the input
 | 
				
			||||||
  export let pinMainMenu = writable(false) // Show menu (for mobile use)
 | 
					  export let pinMainMenu = writable(false) // Show menu (for mobile use)
 | 
				
			||||||
 | 
					  export let continueMessage = writable('') //
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const chatDefaults = getChatDefaults()
 | 
					  const chatDefaults = getChatDefaults()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -160,6 +161,24 @@
 | 
				
			||||||
    chatsStorage.set(chats)
 | 
					    chatsStorage.set(chats)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export const subtractRunningTotal = (chatId: number, usage: Usage, model:Model) => {
 | 
				
			||||||
 | 
					    const chats = get(chatsStorage)
 | 
				
			||||||
 | 
					    const chat = chats.find((chat) => chat.id === chatId) as Chat
 | 
				
			||||||
 | 
					    let total:Usage = chat.usage[model]
 | 
				
			||||||
 | 
					    if (!total) {
 | 
				
			||||||
 | 
					      total = {
 | 
				
			||||||
 | 
					        prompt_tokens: 0,
 | 
				
			||||||
 | 
					        completion_tokens: 0,
 | 
				
			||||||
 | 
					        total_tokens: 0
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      chat.usage[model] = total
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    total.completion_tokens -= usage.completion_tokens
 | 
				
			||||||
 | 
					    total.prompt_tokens -= usage.prompt_tokens
 | 
				
			||||||
 | 
					    total.total_tokens -= usage.total_tokens
 | 
				
			||||||
 | 
					    chatsStorage.set(chats)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  export const addMessage = (chatId: number, message: Message) => {
 | 
					  export const addMessage = (chatId: number, message: Message) => {
 | 
				
			||||||
    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
 | 
				
			||||||
| 
						 | 
					@ -177,7 +196,7 @@
 | 
				
			||||||
    return chat.messages
 | 
					    return chat.messages
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const getMessage = (chat: Chat, uuid:string):Message|undefined => {
 | 
					  export const getMessage = (chat: Chat, uuid:string):Message|undefined => {
 | 
				
			||||||
    return chat.messages.find((m) => m.uuid === uuid)
 | 
					    return chat.messages.find((m) => m.uuid === uuid)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -394,9 +413,14 @@
 | 
				
			||||||
      profile.profile = uuidv4()
 | 
					      profile.profile = uuidv4()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const clone = JSON.parse(JSON.stringify(profile)) // Always store a copy
 | 
					    const clone = JSON.parse(JSON.stringify(profile)) // Always store a copy
 | 
				
			||||||
 | 
					    // pull excluded
 | 
				
			||||||
    Object.keys(getExcludeFromProfile()).forEach(k => {
 | 
					    Object.keys(getExcludeFromProfile()).forEach(k => {
 | 
				
			||||||
      delete clone[k]
 | 
					      delete clone[k]
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					    // pull defaults
 | 
				
			||||||
 | 
					    // Object.entries(getChatDefaults()).forEach(([k, v]) => {
 | 
				
			||||||
 | 
					    //   if (clone[k] === v || (v === undefined && clone[k] === null)) delete clone[k]
 | 
				
			||||||
 | 
					    // })
 | 
				
			||||||
    profiles[profile.profile as string] = clone
 | 
					    profiles[profile.profile as string] = clone
 | 
				
			||||||
    globalStorage.set(store)
 | 
					    globalStorage.set(store)
 | 
				
			||||||
    profile.isDirty = false
 | 
					    profile.isDirty = false
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue