forked from open-webui/open-webui
main #3
5 changed files with 93 additions and 53 deletions
|
@ -271,7 +271,7 @@ export const generateChatCompletion = async (token: string = '', body: object) =
|
||||||
return [res, controller];
|
return [res, controller];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const cancelChatCompletion = async (token: string = '', requestId: string) => {
|
export const cancelOllamaRequest = async (token: string = '', requestId: string) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
const res = await fetch(`${OLLAMA_API_BASE_URL}/cancel/${requestId}`, {
|
const res = await fetch(`${OLLAMA_API_BASE_URL}/cancel/${requestId}`, {
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
deleteModel,
|
deleteModel,
|
||||||
getOllamaUrls,
|
getOllamaUrls,
|
||||||
getOllamaVersion,
|
getOllamaVersion,
|
||||||
pullModel
|
pullModel,
|
||||||
|
cancelOllamaRequest
|
||||||
} from '$lib/apis/ollama';
|
} from '$lib/apis/ollama';
|
||||||
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
|
import { WEBUI_API_BASE_URL, WEBUI_BASE_URL } from '$lib/constants';
|
||||||
import { WEBUI_NAME, models, user } from '$lib/stores';
|
import { WEBUI_NAME, models, user } from '$lib/stores';
|
||||||
|
@ -364,12 +365,24 @@
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
if (line !== '') {
|
if (line !== '') {
|
||||||
let data = JSON.parse(line);
|
let data = JSON.parse(line);
|
||||||
|
console.log(data);
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
throw data.error;
|
throw data.error;
|
||||||
}
|
}
|
||||||
if (data.detail) {
|
if (data.detail) {
|
||||||
throw data.detail;
|
throw data.detail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.id) {
|
||||||
|
modelDownloadStatus[opts.modelName] = {
|
||||||
|
...modelDownloadStatus[opts.modelName],
|
||||||
|
requestId: data.id,
|
||||||
|
reader,
|
||||||
|
done: false
|
||||||
|
};
|
||||||
|
console.log(data);
|
||||||
|
}
|
||||||
|
|
||||||
if (data.status) {
|
if (data.status) {
|
||||||
if (data.digest) {
|
if (data.digest) {
|
||||||
let downloadProgress = 0;
|
let downloadProgress = 0;
|
||||||
|
@ -379,12 +392,17 @@
|
||||||
downloadProgress = 100;
|
downloadProgress = 100;
|
||||||
}
|
}
|
||||||
modelDownloadStatus[opts.modelName] = {
|
modelDownloadStatus[opts.modelName] = {
|
||||||
reader,
|
...modelDownloadStatus[opts.modelName],
|
||||||
pullProgress: downloadProgress,
|
pullProgress: downloadProgress,
|
||||||
digest: data.digest
|
digest: data.digest
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
toast.success(data.status);
|
toast.success(data.status);
|
||||||
|
|
||||||
|
modelDownloadStatus[opts.modelName] = {
|
||||||
|
...modelDownloadStatus[opts.modelName],
|
||||||
|
done: data.status === 'success'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,7 +415,14 @@
|
||||||
opts.callback({ success: false, error, modelName: opts.modelName });
|
opts.callback({ success: false, error, modelName: opts.modelName });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(modelDownloadStatus[opts.modelName]);
|
||||||
|
|
||||||
|
if (modelDownloadStatus[opts.modelName].done) {
|
||||||
opts.callback({ success: true, modelName: opts.modelName });
|
opts.callback({ success: true, modelName: opts.modelName });
|
||||||
|
} else {
|
||||||
|
opts.callback({ success: false, error: 'Download canceled', modelName: opts.modelName });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -467,10 +492,13 @@
|
||||||
ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => false);
|
ollamaVersion = await getOllamaVersion(localStorage.token).catch((error) => false);
|
||||||
liteLLMModelInfo = await getLiteLLMModelInfo(localStorage.token);
|
liteLLMModelInfo = await getLiteLLMModelInfo(localStorage.token);
|
||||||
});
|
});
|
||||||
const deleteModelPull = async (model: string) => {
|
|
||||||
const { reader } = modelDownloadStatus[model];
|
const cancelModelPullHandler = async (model: string) => {
|
||||||
|
const { reader, requestId } = modelDownloadStatus[model];
|
||||||
if (reader) {
|
if (reader) {
|
||||||
await reader.cancel();
|
await reader.cancel();
|
||||||
|
|
||||||
|
await cancelOllamaRequest(localStorage.token, requestId);
|
||||||
delete modelDownloadStatus[model];
|
delete modelDownloadStatus[model];
|
||||||
await deleteModel(localStorage.token, model);
|
await deleteModel(localStorage.token, model);
|
||||||
toast.success(`${model} download has been canceled`);
|
toast.success(`${model} download has been canceled`);
|
||||||
|
@ -606,20 +634,28 @@
|
||||||
|
|
||||||
{#if Object.keys(modelDownloadStatus).length > 0}
|
{#if Object.keys(modelDownloadStatus).length > 0}
|
||||||
{#each Object.keys(modelDownloadStatus) as model}
|
{#each Object.keys(modelDownloadStatus) as model}
|
||||||
|
{#if 'pullProgress' in modelDownloadStatus[model]}
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="font-medium mb-1">{model}</div>
|
<div class="font-medium mb-1">{model}</div>
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="flex flex-row space-x-4 pr-2">
|
<div class="flex flex-row justify-between space-x-4 pr-2">
|
||||||
|
<div class=" flex-1">
|
||||||
<div
|
<div
|
||||||
class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
|
class="dark:bg-gray-600 bg-gray-500 text-xs font-medium text-gray-100 text-center p-0.5 leading-none rounded-full"
|
||||||
style="width: {Math.max(15, modelDownloadStatus[model].pullProgress ?? 0)}%"
|
style="width: {Math.max(
|
||||||
|
15,
|
||||||
|
modelDownloadStatus[model].pullProgress ?? 0
|
||||||
|
)}%"
|
||||||
>
|
>
|
||||||
{modelDownloadStatus[model].pullProgress ?? 0}%
|
{modelDownloadStatus[model].pullProgress ?? 0}%
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Tooltip content="Cancel">
|
||||||
<button
|
<button
|
||||||
class="text-gray-800 dark:text-gray-100"
|
class="text-gray-800 dark:text-gray-100"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
deleteModelPull(model);
|
cancelModelPullHandler(model);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
@ -640,12 +676,16 @@
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
{#if 'digest' in modelDownloadStatus[model]}
|
||||||
<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
|
<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;">
|
||||||
{modelDownloadStatus[model].digest}
|
{modelDownloadStatus[model].digest}
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
} from '$lib/stores';
|
} from '$lib/stores';
|
||||||
import { copyToClipboard, splitStream } from '$lib/utils';
|
import { copyToClipboard, splitStream } from '$lib/utils';
|
||||||
|
|
||||||
import { generateChatCompletion, cancelChatCompletion, generateTitle } from '$lib/apis/ollama';
|
import { generateChatCompletion, cancelOllamaRequest, generateTitle } from '$lib/apis/ollama';
|
||||||
import {
|
import {
|
||||||
addTagById,
|
addTagById,
|
||||||
createNewChat,
|
createNewChat,
|
||||||
|
@ -104,7 +104,7 @@
|
||||||
|
|
||||||
const initNewChat = async () => {
|
const initNewChat = async () => {
|
||||||
if (currentRequestId !== null) {
|
if (currentRequestId !== null) {
|
||||||
await cancelChatCompletion(localStorage.token, currentRequestId);
|
await cancelOllamaRequest(localStorage.token, currentRequestId);
|
||||||
currentRequestId = null;
|
currentRequestId = null;
|
||||||
}
|
}
|
||||||
window.history.replaceState(history.state, '', `/`);
|
window.history.replaceState(history.state, '', `/`);
|
||||||
|
@ -372,7 +372,7 @@
|
||||||
|
|
||||||
if (stopResponseFlag) {
|
if (stopResponseFlag) {
|
||||||
controller.abort('User: Stop Response');
|
controller.abort('User: Stop Response');
|
||||||
await cancelChatCompletion(localStorage.token, currentRequestId);
|
await cancelOllamaRequest(localStorage.token, currentRequestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentRequestId = null;
|
currentRequestId = null;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
} from '$lib/stores';
|
} from '$lib/stores';
|
||||||
import { copyToClipboard, splitStream, convertMessagesToHistory } from '$lib/utils';
|
import { copyToClipboard, splitStream, convertMessagesToHistory } from '$lib/utils';
|
||||||
|
|
||||||
import { generateChatCompletion, generateTitle, cancelChatCompletion } from '$lib/apis/ollama';
|
import { generateChatCompletion, generateTitle, cancelOllamaRequest } from '$lib/apis/ollama';
|
||||||
import {
|
import {
|
||||||
addTagById,
|
addTagById,
|
||||||
createNewChat,
|
createNewChat,
|
||||||
|
@ -382,7 +382,7 @@
|
||||||
|
|
||||||
if (stopResponseFlag) {
|
if (stopResponseFlag) {
|
||||||
controller.abort('User: Stop Response');
|
controller.abort('User: Stop Response');
|
||||||
await cancelChatCompletion(localStorage.token, currentRequestId);
|
await cancelOllamaRequest(localStorage.token, currentRequestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentRequestId = null;
|
currentRequestId = null;
|
||||||
|
@ -843,7 +843,7 @@
|
||||||
shareEnabled={messages.length > 0}
|
shareEnabled={messages.length > 0}
|
||||||
initNewChat={async () => {
|
initNewChat={async () => {
|
||||||
if (currentRequestId !== null) {
|
if (currentRequestId !== null) {
|
||||||
await cancelChatCompletion(localStorage.token, currentRequestId);
|
await cancelOllamaRequest(localStorage.token, currentRequestId);
|
||||||
currentRequestId = null;
|
currentRequestId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
} from '$lib/constants';
|
} from '$lib/constants';
|
||||||
import { WEBUI_NAME, config, user, models, settings } from '$lib/stores';
|
import { WEBUI_NAME, config, user, models, settings } from '$lib/stores';
|
||||||
|
|
||||||
import { cancelChatCompletion, generateChatCompletion } from '$lib/apis/ollama';
|
import { cancelOllamaRequest, generateChatCompletion } from '$lib/apis/ollama';
|
||||||
import { generateOpenAIChatCompletion } from '$lib/apis/openai';
|
import { generateOpenAIChatCompletion } from '$lib/apis/openai';
|
||||||
|
|
||||||
import { splitStream } from '$lib/utils';
|
import { splitStream } from '$lib/utils';
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
|
|
||||||
// const cancelHandler = async () => {
|
// const cancelHandler = async () => {
|
||||||
// if (currentRequestId) {
|
// if (currentRequestId) {
|
||||||
// const res = await cancelChatCompletion(localStorage.token, currentRequestId);
|
// const res = await cancelOllamaRequest(localStorage.token, currentRequestId);
|
||||||
// currentRequestId = null;
|
// currentRequestId = null;
|
||||||
// loading = false;
|
// loading = false;
|
||||||
// }
|
// }
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
const { value, done } = await reader.read();
|
const { value, done } = await reader.read();
|
||||||
if (done || stopResponseFlag) {
|
if (done || stopResponseFlag) {
|
||||||
if (stopResponseFlag) {
|
if (stopResponseFlag) {
|
||||||
await cancelChatCompletion(localStorage.token, currentRequestId);
|
await cancelOllamaRequest(localStorage.token, currentRequestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentRequestId = null;
|
currentRequestId = null;
|
||||||
|
@ -181,7 +181,7 @@
|
||||||
const { value, done } = await reader.read();
|
const { value, done } = await reader.read();
|
||||||
if (done || stopResponseFlag) {
|
if (done || stopResponseFlag) {
|
||||||
if (stopResponseFlag) {
|
if (stopResponseFlag) {
|
||||||
await cancelChatCompletion(localStorage.token, currentRequestId);
|
await cancelOllamaRequest(localStorage.token, currentRequestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentRequestId = null;
|
currentRequestId = null;
|
||||||
|
|
Loading…
Reference in a new issue