refac: message status history

This commit is contained in:
Timothy J. Baek 2024-06-10 11:40:58 -07:00
parent 34f04c53fc
commit a75b68c19c
4 changed files with 89 additions and 27 deletions

View File

@ -515,11 +515,13 @@
const getWebSearchResults = async (model: string, parentId: string, responseId: string) => { const getWebSearchResults = async (model: string, parentId: string, responseId: string) => {
const responseMessage = history.messages[responseId]; const responseMessage = history.messages[responseId];
responseMessage.status = { responseMessage.statusHistory = [
{
done: false, done: false,
action: 'web_search', action: 'web_search',
description: $i18n.t('Generating search query') description: $i18n.t('Generating search query')
}; }
];
messages = messages; messages = messages;
const prompt = history.messages[parentId].content; const prompt = history.messages[parentId].content;
@ -532,19 +534,21 @@
if (!searchQuery) { if (!searchQuery) {
toast.warning($i18n.t('No search query generated')); toast.warning($i18n.t('No search query generated'));
responseMessage.status = { responseMessage.statusHistory.push({
...responseMessage.status,
done: true, done: true,
error: true, error: true,
action: 'web_search',
description: 'No search query generated' description: 'No search query generated'
}; });
messages = messages; messages = messages;
} }
responseMessage.status = { responseMessage.statusHistory.push({
...responseMessage.status, done: false,
description: $i18n.t("Searching the web for '{{searchQuery}}'", { searchQuery }) action: 'web_search',
}; description: $i18n.t(`Searching "{{searchQuery}}"`, { searchQuery })
});
messages = messages; messages = messages;
const results = await runWebSearch(localStorage.token, searchQuery).catch((error) => { const results = await runWebSearch(localStorage.token, searchQuery).catch((error) => {
@ -555,12 +559,13 @@
}); });
if (results) { if (results) {
responseMessage.status = { responseMessage.statusHistory.push({
...responseMessage.status,
done: true, done: true,
action: 'web_search',
description: $i18n.t('Searched {{count}} sites', { count: results.filenames.length }), description: $i18n.t('Searched {{count}} sites', { count: results.filenames.length }),
query: searchQuery,
urls: results.filenames urls: results.filenames
}; });
if (responseMessage?.files ?? undefined === undefined) { if (responseMessage?.files ?? undefined === undefined) {
responseMessage.files = []; responseMessage.files = [];
@ -575,12 +580,12 @@
messages = messages; messages = messages;
} else { } else {
responseMessage.status = { responseMessage.statusHistory.push({
...responseMessage.status,
done: true, done: true,
error: true, error: true,
action: 'web_search',
description: 'No search results found' description: 'No search results found'
}; });
messages = messages; messages = messages;
} }
}; };

View File

@ -420,26 +420,29 @@
class="prose chat-{message.role} w-full max-w-full dark:prose-invert prose-headings:my-0 prose-headings:-mb-4 prose-p:m-0 prose-p:-mb-6 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-img:my-0 prose-ul:-my-4 prose-ol:-my-4 prose-li:-my-3 prose-ul:-mb-6 prose-ol:-mb-8 prose-ol:p-0 prose-li:-mb-4 whitespace-pre-line" class="prose chat-{message.role} w-full max-w-full dark:prose-invert prose-headings:my-0 prose-headings:-mb-4 prose-p:m-0 prose-p:-mb-6 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-img:my-0 prose-ul:-my-4 prose-ol:-my-4 prose-li:-my-3 prose-ul:-mb-6 prose-ol:-mb-8 prose-ol:p-0 prose-li:-mb-4 whitespace-pre-line"
> >
<div> <div>
{#if message?.status} {#if (message?.statusHistory ?? [...(message?.status ? [message?.status] : [])]).length > 0}
{@const status = (
message?.statusHistory ?? [...(message?.status ? [message?.status] : [])]
).at(-1)}
<div class="flex items-center gap-2 pt-1 pb-1"> <div class="flex items-center gap-2 pt-1 pb-1">
{#if message?.status?.done === false} {#if status.done === false}
<div class=""> <div class="">
<Spinner className="size-4" /> <Spinner className="size-4" />
</div> </div>
{/if} {/if}
{#if message?.status?.action === 'web_search' && message?.status?.urls} {#if status?.action === 'web_search' && status?.urls}
<WebSearchResults urls={message?.status?.urls}> <WebSearchResults {status}>
<div class="flex flex-col justify-center -space-y-0.5"> <div class="flex flex-col justify-center -space-y-0.5">
<div class="text-base line-clamp-1 text-wrap"> <div class="text-base line-clamp-1 text-wrap">
{message.status.description} {status?.description}
</div> </div>
</div> </div>
</WebSearchResults> </WebSearchResults>
{:else} {:else}
<div class="flex flex-col justify-center -space-y-0.5"> <div class="flex flex-col justify-center -space-y-0.5">
<div class=" text-gray-500 dark:text-gray-500 text-base line-clamp-1 text-wrap"> <div class=" text-gray-500 dark:text-gray-500 text-base line-clamp-1 text-wrap">
{message.status.description} {status?.description}
</div> </div>
</div> </div>
{/if} {/if}

View File

@ -1,10 +1,11 @@
<script lang="ts"> <script lang="ts">
import ChevronDown from '$lib/components/icons/ChevronDown.svelte'; import ChevronDown from '$lib/components/icons/ChevronDown.svelte';
import ChevronUp from '$lib/components/icons/ChevronUp.svelte'; import ChevronUp from '$lib/components/icons/ChevronUp.svelte';
import MagnifyingGlass from '$lib/components/icons/MagnifyingGlass.svelte';
import { Collapsible } from 'bits-ui'; import { Collapsible } from 'bits-ui';
import { slide } from 'svelte/transition'; import { slide } from 'svelte/transition';
export let urls = []; export let status = { urls: [], query: '' };
let state = false; let state = false;
</script> </script>
@ -27,11 +28,45 @@
class=" text-sm border border-gray-300/30 dark:border-gray-700/50 rounded-xl" class=" text-sm border border-gray-300/30 dark:border-gray-700/50 rounded-xl"
transition={slide} transition={slide}
> >
{#each urls as url, urlIdx} {#if status?.query}
<a
href="https://www.google.com/search?q={status.query}"
target="_blank"
class="flex w-full items-center p-3 px-4 border-b border-gray-300/30 dark:border-gray-700/50 group/item justify-between font-normal text-gray-800 dark:text-gray-300 no-underline"
>
<div class="flex gap-2 items-center">
<MagnifyingGlass />
<div class=" line-clamp-1">
{status.query}
</div>
</div>
<div
class=" ml-1 text-white dark:text-gray-900 group-hover/item:text-gray-600 dark:group-hover/item:text-white transition"
>
<!-- -->
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="size-4"
>
<path
fill-rule="evenodd"
d="M4.22 11.78a.75.75 0 0 1 0-1.06L9.44 5.5H5.75a.75.75 0 0 1 0-1.5h5.5a.75.75 0 0 1 .75.75v5.5a.75.75 0 0 1-1.5 0V6.56l-5.22 5.22a.75.75 0 0 1-1.06 0Z"
clip-rule="evenodd"
/>
</svg>
</div>
</a>
{/if}
{#each status.urls as url, urlIdx}
<a <a
href={url} href={url}
target="_blank" target="_blank"
class="flex w-full items-center p-3 px-4 {urlIdx === urls.length - 1 class="flex w-full items-center p-3 px-4 {urlIdx === status.urls.length - 1
? '' ? ''
: 'border-b border-gray-300/30 dark:border-gray-700/50'} group/item justify-between font-normal text-gray-800 dark:text-gray-300" : 'border-b border-gray-300/30 dark:border-gray-700/50'} group/item justify-between font-normal text-gray-800 dark:text-gray-300"
> >

View File

@ -0,0 +1,19 @@
<script lang="ts">
export let className = 'size-4';
export let strokeWidth = '2';
</script>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width={strokeWidth}
stroke="currentColor"
class={className}
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"
/>
</svg>