Skip to content

Commit

Permalink
Merge pull request #38 from nasa-petal/update-save-chats
Browse files Browse the repository at this point in the history
Update Save Chats and Fix Threads Out of Sync
  • Loading branch information
bruffridge authored Feb 22, 2024
2 parents 2954b99 + af8925f commit dd052b2
Show file tree
Hide file tree
Showing 10 changed files with 387 additions and 139 deletions.
150 changes: 73 additions & 77 deletions src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<!-- This is an example for a Svelte browser app, if you are using SvelteKit, please see the following example:
https://codesandbox.io/p/sandbox/deep-chat-sveltekit-fn8h6x -->
<!-- This is an example for a Svelte browser app, if you are using SvelteKit, please see the following example: https://codesandbox.io/p/sandbox/deep-chat-sveltekit-fn8h6x -->

<script>
import { DeepChat } from "deep-chat";
Expand All @@ -8,8 +7,7 @@
import { BIDARA_CONFIG } from './assistant/bidara';
import { funcCalling } from './assistant/bidaraFunctions';
import { setOpenAIKey, setAsst, getKeyAsstAndThread, getBidaraAssistant } from './utils/openaiUtils';
import { setThread, getThread, deleteThreadFromThreads, getNewThread, getThreads, setThreads, setActiveThreadName } from './utils/threadUtils';
import { getStoredActiveThread } from './utils/storageUtils';
import { setThread, getThread, deleteThreadFromThreads, getNewThread, getThreads, setThreads, setActiveThreadName, updateThreadAndThreads, getEmptyThreads } from './utils/threadUtils';
import hljs from "highlight.js";
window.hljs = hljs;
Expand All @@ -21,19 +19,17 @@
let openAIKeySet = false;
let openAIAsstIdSet = false;
let openAIThreadIdSet = false;
let changedToLoggedInView = false;
let keyAsstAndThread = null;
let activeThread = null;
let welcomeRef;
let navbarRef;
let sidebarRef;
let deepChatRef;
let open = false;
let blurred = true;
let threads = getThreads();
let selectedThreadId;
let selectedThreadName = "";
let emptyChat;
let threads;
function onError(error) {
console.log(error);
Expand All @@ -45,19 +41,16 @@
async function initKeyAsstAndThreads() {
keyAsstAndThread = await getKeyAsstAndThread();
activeThread = null;
if (keyAsstAndThread && keyAsstAndThread[0]) {
changedToLoggedInView = true;
threads = getThreads();
selectedThreadName = keyAsstAndThread[2]?.name ? keyAsstAndThread[2].name : "";
selectedThreadId = keyAsstAndThread[2]?.id ? keyAsstAndThread[2].id : "";
if (selectedThreadId) {
setThread({name: selectedThreadName, id: selectedThreadId});
}
activeThread = keyAsstAndThread[2];
if (threads.length <= 0 && selectedThreadName) {
threads = [keyAsstAndThread[2]];
if (!threads || (threads.length <= 0 && activeThread)) {
threads = [activeThread];
setThreads(threads);
}
}
Expand All @@ -74,22 +67,17 @@
openAIAsstIdSet = true;
}
if (!openAIThreadIdSet && message.message._sessionId && message.message._sessionId != await getThread()) {
const newThread = {name: "New Chat", id: message.message._sessionId}
setThread(newThread);
openAIThreadIdSet = true;
}
if (message.message.role === 'user' && emptyChat && emptyChat.id === selectedThreadId) {
emptyChat = null;
if (activeThread) {
activeThread.length = deepChatRef.getMessages().length;
updateThreads();
}
}
async function onComponentRender() {
// save key to localStorage.
// The event occurs before key is set, and again, after key is set.
if (!openAIKeySet && this._activeService.key) {
// if key set through UI, save it to localStorage.
// if key set through UI or in URL variable, save it to localStorage.
setOpenAIKey(this._activeService.key);
openAIKeySet = true;
}
Expand All @@ -106,87 +94,90 @@
if(!openAIKeySet) { // Show login instructions.
welcomeRef.style.display = "block";
navbarRef.style.display = "none";
deepChatRef.style.width = "calc(100vw - 1rem)";
deepChatRef.style.height = "100px";
}
else if (!changedToLoggedInView) { // Hide login instructions after login.
welcomeRef.style.display = "none";
navbarRef.style.display = "block";
deepChatRef.style.width = "100%";
deepChatRef.style.height = "calc(100dvh - 3.1rem)";
await initKeyAsstAndThreads();
changedToLoggedInView = true;
}
setTimeout(()=> blurred = false, 200);
}
async function newThreadAndSwitch() {
if (emptyChat) {
switchActiveThread(emptyChat);
// If the thread is already "new", stay on it
if (activeThread && activeThread.length <= 0) {
if (activeThread.name != "New Chat") {
await renameActiveThread("New Chat");
}
return true;
}
}
const currrent_messages = deepChatRef.getMessages();
// If an empty thead is already created, prevents creating a new one
const emptyThreads = getEmptyThreads();
if (emptyThreads && emptyThreads.length >= 1) {
if (currrent_messages.length <= initialMessages.length) {
return;
}
const emptyThread = emptyThreads[0];
switchActiveThread(emptyThread);
const newThread = await getNewThread();
return true;
}
// force new object so Siderbar rerenders
threads = [ newThread ].concat(threads);
switchActiveThread(newThread);
emptyChat = newThread;
const thread = await getNewThread();
threads.unshift(thread);
setThreads(threads);
await switchActiveThread(thread);
return true;
}
async function deleteThreadAndSwitch(thread) {
const currrent_messages = deepChatRef.getMessages();
if (threads.length <= 1 && currrent_messages.length <= initialMessages.length) {
return false;
}
if (emptyChat && emptyChat.id === thread.id) {
emptyChat = null;
}
threads = deleteThreadFromThreads(thread.id);
activeThread = {};
if (threads && threads.length > 0) {
const current_thread = getStoredActiveThread();
const candidateThread = threads[0];
if (candidateThread && candidateThread !== current_thread) {
switchActiveThread(candidateThread);
}
switchActiveThread(threads[0]);
} else {
newThreadAndSwitch();
await newThreadAndSwitch();
}
return true;
}
async function switchActiveThread(thread) {
if (thread.id === activeThread.id) {
return;
}
blurred = true;
await setThread(thread);
keyAsstAndThread = await getKeyAsstAndThread();
selectedThreadId = keyAsstAndThread[2].id;
selectedThreadName = thread.name;
activeThread = keyAsstAndThread[2];
return true;
}
async function renameActiveThread(name) {
threads = await setActiveThreadName(name);
await setActiveThreadName(name);
threads = getThreads();
activeThread = await getThread();
return true;
}
function updateThreads() {
updateThreadAndThreads(activeThread, threads);
}
</script>

<main>
Expand Down Expand Up @@ -236,23 +227,30 @@
<li>After you send your first message to BIDARA, it will also be available to interact with through the <a href="https://platform.openai.com/assistants" class="underline text-blue-600 hover:text-blue-800 visited:text-purple-600">OpenAI Assistants Playground</a>. This interface is more complex, but also provides more customizability. Just select BIDARA, then click the 'Test' button.</li>
</ul>
</div>
<div id="content-container" class:open>
{#if keyAsstAndThread !== null}
{#if activeThread !== null}
{#key activeThread}
<div bind:this={navbarRef}>
<Navbar bind:this={navbarRef} bind:chat_name={selectedThreadName} bind:sidebar={open} handleRename={renameActiveThread}/>
<Navbar bind:chat_name={activeThread.name} bind:sidebar={open} handleRename={renameActiveThread}/>
</div>
{/key}
{/if}
<div id="content-container" class="flex justify-between" class:open>
{#if activeThread !== null}
{#key activeThread}
<div bind:this={sidebarRef}>
{#key selectedThreadId}
<Sidebar bind:this={sidebarRef} handleChatSelect={switchActiveThread} handleChatDelete={deleteThreadAndSwitch} handleChatNew={newThreadAndSwitch} bind:threads bind:open bind:selectedThreadId/>
{/key}
<Sidebar handleChatSelect={switchActiveThread} handleChatDelete={deleteThreadAndSwitch} handleChatNew={newThreadAndSwitch} bind:threads bind:open bind:selectedThreadId={activeThread.id}/>
</div>
{/key}
{/if}
<div id="chat-container">
<!-- demo/textInput are examples of passing an object directly into a property -->
<!-- initialMessages is an example of passing a state object into a property -->
{#if keyAsstAndThread !== null}
{#key keyAsstAndThread}
<deep-chat
id="chat-element"
bind:this={deepChatRef}
class:blurred
directConnection={{
openAI: {
key: keyAsstAndThread[0],
Expand Down Expand Up @@ -339,7 +337,6 @@
border: "1px solid rgba(0,0,0,0.2)",
top: "-2.55em",
height: "4em",
width: "calc(100% - 6.2em)",
}}
textInput={{
styles: {
Expand Down Expand Up @@ -403,46 +400,45 @@
}}
/>
{/key}
{/if}
</div>
</div>
{/if}
</main>


<style>
#chat-container {
width: 100%;
margin-left: 0;
transition: ease 0.3s;
transition: width 0.3s ease, filter 0.5s ease-out;
}
.open #chat-container {
width: 80%;
margin-left: 20%;
}
@media only screen and (max-width: 1000px) {
@media only screen and (max-width: 1400px) {
.open #chat-container {
width: 70%;
margin-left: 30%;
}
}
@media only screen and (max-width: 900px) {
@media only screen and (max-width: 1000px) {
.open #chat-container {
width: 60%;
margin-left: 40%;
}
}
@media only screen and (max-width: 700px) {
.open #chat-container {
width: 100%;
margin-left: 0;
}
}
.blurred {
filter: blur(2px);
}
main {
font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
display: grid;
Expand Down
4 changes: 2 additions & 2 deletions src/assistant/bidaraFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ export async function ssSearch(params) {

async function genImage(params) {

var imageParams = JSON.parse(params);
let imageParams = JSON.parse(params);

if ("parameters" in imageParams) {
imageParams = imageParams.parameters;
}

var imageDescription = JSON.stringify(imageParams.description) + " Realistic depiction of the object and its environment. Stay true to science, engineering, and biology. DO NOT INCLUDE ANY WORDS OR BRANDING."
let imageDescription = JSON.stringify(imageParams.description) + " Realistic depiction of the object and its environment. Stay true to science, engineering, and biology. DO NOT INCLUDE ANY WORDS OR BRANDING."

const res = await getDalleImageGeneration(imageDescription);

Expand Down
Loading

0 comments on commit dd052b2

Please sign in to comment.