fix: ongoing chat stop issue

This commit is contained in:
Timothy Jaeryang Baek
2025-04-12 20:51:02 -07:00
parent fa61065c1e
commit f3fe82da80
6 changed files with 179 additions and 104 deletions

View File

@@ -260,6 +260,38 @@ export const stopTask = async (token: string, id: string) => {
return res;
};
export const getTaskIdsByChatId = async (token: string, chat_id: string) => {
let error = null;
const res = await fetch(`${WEBUI_BASE_URL}/api/tasks/chat/${chat_id}`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(token && { authorization: `Bearer ${token}` })
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.catch((err) => {
console.log(err);
if ('detail' in err) {
error = err.detail;
} else {
error = err;
}
return null;
});
if (error) {
throw error;
}
return res;
};
export const getToolServerData = async (token: string, url: string) => {
let error = null;

View File

@@ -74,7 +74,8 @@
generateQueries,
chatAction,
generateMoACompletion,
stopTask
stopTask,
getTaskIdsByChatId
} from '$lib/apis';
import { getTools } from '$lib/apis/tools';
@@ -825,7 +826,14 @@
}
}
taskIds = chat?.task_ids ?? null;
const taskRes = await getTaskIdsByChatId(localStorage.token, $chatId).catch((error) => {
return null;
});
if (taskRes) {
taskIds = taskRes.task_ids;
}
await tick();
return true;
@@ -1721,7 +1729,6 @@
taskIds = null;
const responseMessage = history.messages[history.currentId];
// Set all response messages to done
for (const messageId of history.messages[responseMessage.parentId].childrenIds) {
history.messages[messageId].done = true;
@@ -2014,6 +2021,7 @@
<div class=" pb-[1rem]">
<MessageInput
{history}
{taskIds}
{selectedModels}
bind:files
bind:prompt

View File

@@ -71,6 +71,7 @@
$: selectedModelIds = atSelectedModel !== undefined ? [atSelectedModel.id] : selectedModels;
export let history;
export let taskIds = null;
export let prompt = '';
export let files = [];
@@ -1237,99 +1238,7 @@
</Tooltip>
{/if}
{#if !history.currentId || history.messages[history.currentId]?.done == true}
{#if prompt === '' && files.length === 0}
<div class=" flex items-center">
<Tooltip content={$i18n.t('Call')}>
<button
class=" bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full p-1.5 self-center"
type="button"
on:click={async () => {
if (selectedModels.length > 1) {
toast.error($i18n.t('Select only one model to call'));
return;
}
if ($config.audio.stt.engine === 'web') {
toast.error(
$i18n.t(
'Call feature is not supported when using Web STT engine'
)
);
return;
}
// check if user has access to getUserMedia
try {
let stream = await navigator.mediaDevices.getUserMedia({
audio: true
});
// If the user grants the permission, proceed to show the call overlay
if (stream) {
const tracks = stream.getTracks();
tracks.forEach((track) => track.stop());
}
stream = null;
if ($settings.audio?.tts?.engine === 'browser-kokoro') {
// If the user has not initialized the TTS worker, initialize it
if (!$TTSWorker) {
await TTSWorker.set(
new KokoroWorker({
dtype: $settings.audio?.tts?.engineConfig?.dtype ?? 'fp32'
})
);
await $TTSWorker.init();
}
}
showCallOverlay.set(true);
showControls.set(true);
} catch (err) {
// If the user denies the permission or an error occurs, show an error message
toast.error(
$i18n.t('Permission denied when accessing media devices')
);
}
}}
aria-label="Call"
>
<Headphone className="size-5" />
</button>
</Tooltip>
</div>
{:else}
<div class=" flex items-center">
<Tooltip content={$i18n.t('Send message')}>
<button
id="send-message-button"
class="{!(prompt === '' && files.length === 0)
? 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 '
: 'text-white bg-gray-200 dark:text-gray-900 dark:bg-gray-700 disabled'} transition rounded-full p-1.5 self-center"
type="submit"
disabled={prompt === '' && files.length === 0}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="size-5"
>
<path
fill-rule="evenodd"
d="M8 14a.75.75 0 0 1-.75-.75V4.56L4.03 7.78a.75.75 0 0 1-1.06-1.06l4.5-4.5a.75.75 0 0 1 1.06 0l4.5 4.5a.75.75 0 0 1-1.06 1.06L8.75 4.56v8.69A.75.75 0 0 1 8 14Z"
clip-rule="evenodd"
/>
</svg>
</button>
</Tooltip>
</div>
{/if}
{:else}
{#if taskIds && taskIds.length > 0}
<div class=" flex items-center">
<Tooltip content={$i18n.t('Stop')}>
<button
@@ -1353,6 +1262,94 @@
</button>
</Tooltip>
</div>
{:else if prompt === '' && files.length === 0}
<div class=" flex items-center">
<Tooltip content={$i18n.t('Call')}>
<button
class=" bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full p-1.5 self-center"
type="button"
on:click={async () => {
if (selectedModels.length > 1) {
toast.error($i18n.t('Select only one model to call'));
return;
}
if ($config.audio.stt.engine === 'web') {
toast.error(
$i18n.t('Call feature is not supported when using Web STT engine')
);
return;
}
// check if user has access to getUserMedia
try {
let stream = await navigator.mediaDevices.getUserMedia({
audio: true
});
// If the user grants the permission, proceed to show the call overlay
if (stream) {
const tracks = stream.getTracks();
tracks.forEach((track) => track.stop());
}
stream = null;
if ($settings.audio?.tts?.engine === 'browser-kokoro') {
// If the user has not initialized the TTS worker, initialize it
if (!$TTSWorker) {
await TTSWorker.set(
new KokoroWorker({
dtype: $settings.audio?.tts?.engineConfig?.dtype ?? 'fp32'
})
);
await $TTSWorker.init();
}
}
showCallOverlay.set(true);
showControls.set(true);
} catch (err) {
// If the user denies the permission or an error occurs, show an error message
toast.error(
$i18n.t('Permission denied when accessing media devices')
);
}
}}
aria-label="Call"
>
<Headphone className="size-5" />
</button>
</Tooltip>
</div>
{:else}
<div class=" flex items-center">
<Tooltip content={$i18n.t('Send message')}>
<button
id="send-message-button"
class="{!(prompt === '' && files.length === 0)
? 'bg-black text-white hover:bg-gray-900 dark:bg-white dark:text-black dark:hover:bg-gray-100 '
: 'text-white bg-gray-200 dark:text-gray-900 dark:bg-gray-700 disabled'} transition rounded-full p-1.5 self-center"
type="submit"
disabled={prompt === '' && files.length === 0}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="size-5"
>
<path
fill-rule="evenodd"
d="M8 14a.75.75 0 0 1-.75-.75V4.56L4.03 7.78a.75.75 0 0 1-1.06-1.06l4.5-4.5a.75.75 0 0 1 1.06 0l4.5 4.5a.75.75 0 0 1-1.06 1.06L8.75 4.56v8.69A.75.75 0 0 1 8 14Z"
clip-rule="evenodd"
/>
</svg>
</button>
</Tooltip>
</div>
{/if}
</div>
</div>