forked from open-webui/open-webui
feat: many models support
This commit is contained in:
parent
5dff474438
commit
4b4fbf62e4
1 changed files with 63 additions and 44 deletions
|
@ -20,7 +20,8 @@
|
||||||
let API_BASE_URL = BUILD_TIME_API_BASE_URL;
|
let API_BASE_URL = BUILD_TIME_API_BASE_URL;
|
||||||
let db;
|
let db;
|
||||||
|
|
||||||
let selectedModel = '';
|
// let selectedModel = '';
|
||||||
|
let selectedModels = [''];
|
||||||
let settings = {
|
let settings = {
|
||||||
system: null,
|
system: null,
|
||||||
temperature: null
|
temperature: null
|
||||||
|
@ -293,10 +294,12 @@
|
||||||
await getModelTags();
|
await getModelTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedModel =
|
// selectedModel =
|
||||||
settings.model && models.map((model) => model.name).includes(settings.model)
|
// settings.model && models.map((model) => model.name).includes(settings.model)
|
||||||
? settings.model
|
// ? settings.model
|
||||||
: '';
|
// : '';
|
||||||
|
|
||||||
|
selectedModels = settings.models ?? [''];
|
||||||
|
|
||||||
console.log(chatId);
|
console.log(chatId);
|
||||||
}
|
}
|
||||||
|
@ -317,7 +320,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveDefaultModel = () => {
|
const saveDefaultModel = () => {
|
||||||
settings.model = selectedModel;
|
settings.models = selectedModels;
|
||||||
localStorage.setItem('settings', JSON.stringify(settings));
|
localStorage.setItem('settings', JSON.stringify(settings));
|
||||||
toast.success('Default model updated');
|
toast.success('Default model updated');
|
||||||
};
|
};
|
||||||
|
@ -334,7 +337,7 @@
|
||||||
const chat = await db.get('chats', id);
|
const chat = await db.get('chats', id);
|
||||||
console.log(chat);
|
console.log(chat);
|
||||||
if (chatId !== chat.id) {
|
if (chatId !== chat.id) {
|
||||||
if ('history' in chat) {
|
if ('history' in chat && chat.history !== undefined) {
|
||||||
history = chat.history;
|
history = chat.history;
|
||||||
} else {
|
} else {
|
||||||
let _history = {
|
let _history = {
|
||||||
|
@ -369,11 +372,16 @@
|
||||||
history = _history;
|
history = _history;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('models' in chat) {
|
||||||
|
selectedModels = chat.models ?? selectedModels;
|
||||||
|
} else {
|
||||||
|
selectedModels = [chat.model ?? ''];
|
||||||
|
}
|
||||||
|
|
||||||
console.log(history);
|
console.log(history);
|
||||||
|
|
||||||
title = chat.title;
|
title = chat.title;
|
||||||
chatId = chat.id;
|
chatId = chat.id;
|
||||||
selectedModel = chat.model ?? selectedModel;
|
|
||||||
settings.system = chat.system ?? settings.system;
|
settings.system = chat.system ?? settings.system;
|
||||||
settings.temperature = chat.temperature ?? settings.temperature;
|
settings.temperature = chat.temperature ?? settings.temperature;
|
||||||
autoScroll = true;
|
autoScroll = true;
|
||||||
|
@ -499,7 +507,7 @@
|
||||||
await db.put('chats', {
|
await db.put('chats', {
|
||||||
id: chatId,
|
id: chatId,
|
||||||
title: title === '' ? 'New Chat' : title,
|
title: title === '' ? 'New Chat' : title,
|
||||||
model: selectedModel,
|
models: selectedModels,
|
||||||
system: settings.system,
|
system: settings.system,
|
||||||
options: {
|
options: {
|
||||||
temperature: settings.temperature
|
temperature: settings.temperature
|
||||||
|
@ -668,26 +676,26 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendPrompt = async (userPrompt, parentId) => {
|
const sendPrompt = async (userPrompt, parentId) => {
|
||||||
// await Promise.all(
|
await Promise.all(
|
||||||
// selectedModels.map((model) => {
|
selectedModels.map(async (model) => {
|
||||||
|
if (model.includes('gpt-')) {
|
||||||
|
await sendPromptOpenAI(model, userPrompt, parentId);
|
||||||
|
} else {
|
||||||
|
await sendPromptOllama(model, userPrompt, parentId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// if (selectedModel.includes('gpt-')) {
|
// if (selectedModel.includes('gpt-')) {
|
||||||
// await sendPromptOpenAI(userPrompt, parentId);
|
// await sendPromptOpenAI(userPrompt, parentId);
|
||||||
// } else {
|
// } else {
|
||||||
// await sendPromptOllama(userPrompt, parentId);
|
// await sendPromptOllama(userPrompt, parentId);
|
||||||
// }
|
// }
|
||||||
// })
|
|
||||||
// );
|
|
||||||
|
|
||||||
if (selectedModel.includes('gpt-')) {
|
|
||||||
await sendPromptOpenAI(userPrompt, parentId);
|
|
||||||
} else {
|
|
||||||
await sendPromptOllama(userPrompt, parentId);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(history);
|
console.log(history);
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendPromptOllama = async (userPrompt, parentId) => {
|
const sendPromptOllama = async (model, userPrompt, parentId) => {
|
||||||
let responseMessageId = uuidv4();
|
let responseMessageId = uuidv4();
|
||||||
|
|
||||||
let responseMessage = {
|
let responseMessage = {
|
||||||
|
@ -695,7 +703,8 @@
|
||||||
id: responseMessageId,
|
id: responseMessageId,
|
||||||
childrenIds: [],
|
childrenIds: [],
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: ''
|
content: '',
|
||||||
|
model: model
|
||||||
};
|
};
|
||||||
|
|
||||||
history.messages[responseMessageId] = responseMessage;
|
history.messages[responseMessageId] = responseMessage;
|
||||||
|
@ -715,7 +724,7 @@
|
||||||
'Content-Type': 'text/event-stream'
|
'Content-Type': 'text/event-stream'
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
model: selectedModel,
|
model: model,
|
||||||
prompt: userPrompt,
|
prompt: userPrompt,
|
||||||
system: settings.system ?? undefined,
|
system: settings.system ?? undefined,
|
||||||
options: {
|
options: {
|
||||||
|
@ -788,7 +797,7 @@
|
||||||
await db.put('chats', {
|
await db.put('chats', {
|
||||||
id: chatId,
|
id: chatId,
|
||||||
title: title === '' ? 'New Chat' : title,
|
title: title === '' ? 'New Chat' : title,
|
||||||
model: selectedModel,
|
models: selectedModels,
|
||||||
system: settings.system,
|
system: settings.system,
|
||||||
options: {
|
options: {
|
||||||
temperature: settings.temperature
|
temperature: settings.temperature
|
||||||
|
@ -810,7 +819,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendPromptOpenAI = async (userPrompt, parentId) => {
|
const sendPromptOpenAI = async (model, userPrompt, parentId) => {
|
||||||
if (settings.OPENAI_API_KEY) {
|
if (settings.OPENAI_API_KEY) {
|
||||||
if (models) {
|
if (models) {
|
||||||
let responseMessageId = uuidv4();
|
let responseMessageId = uuidv4();
|
||||||
|
@ -820,7 +829,8 @@
|
||||||
id: responseMessageId,
|
id: responseMessageId,
|
||||||
childrenIds: [],
|
childrenIds: [],
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: ''
|
content: '',
|
||||||
|
model: model
|
||||||
};
|
};
|
||||||
|
|
||||||
history.messages[responseMessageId] = responseMessage;
|
history.messages[responseMessageId] = responseMessage;
|
||||||
|
@ -841,7 +851,7 @@
|
||||||
Authorization: `Bearer ${settings.OPENAI_API_KEY}`
|
Authorization: `Bearer ${settings.OPENAI_API_KEY}`
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
model: selectedModel,
|
model: model,
|
||||||
stream: true,
|
stream: true,
|
||||||
messages: [
|
messages: [
|
||||||
settings.system
|
settings.system
|
||||||
|
@ -909,7 +919,8 @@
|
||||||
await db.put('chats', {
|
await db.put('chats', {
|
||||||
id: chatId,
|
id: chatId,
|
||||||
title: title === '' ? 'New Chat' : title,
|
title: title === '' ? 'New Chat' : title,
|
||||||
model: selectedModel,
|
models: selectedModels,
|
||||||
|
|
||||||
system: settings.system,
|
system: settings.system,
|
||||||
options: {
|
options: {
|
||||||
temperature: settings.temperature
|
temperature: settings.temperature
|
||||||
|
@ -941,7 +952,7 @@
|
||||||
const submitPrompt = async (userPrompt) => {
|
const submitPrompt = async (userPrompt) => {
|
||||||
console.log('submitPrompt');
|
console.log('submitPrompt');
|
||||||
|
|
||||||
if (selectedModel === '') {
|
if (selectedModels.includes('')) {
|
||||||
toast.error('Model not selected');
|
toast.error('Model not selected');
|
||||||
} else if (messages.length != 0 && messages.at(-1).done != true) {
|
} else if (messages.length != 0 && messages.at(-1).done != true) {
|
||||||
console.log('wait');
|
console.log('wait');
|
||||||
|
@ -970,7 +981,7 @@
|
||||||
if (messages.length == 0) {
|
if (messages.length == 0) {
|
||||||
await db.put('chats', {
|
await db.put('chats', {
|
||||||
id: chatId,
|
id: chatId,
|
||||||
model: selectedModel,
|
models: selectedModels,
|
||||||
system: settings.system,
|
system: settings.system,
|
||||||
options: {
|
options: {
|
||||||
temperature: settings.temperature
|
temperature: settings.temperature
|
||||||
|
@ -1022,7 +1033,7 @@
|
||||||
'Content-Type': 'text/event-stream'
|
'Content-Type': 'text/event-stream'
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
model: selectedModel,
|
model: selectedModels[0],
|
||||||
prompt: `Generate a brief 3-5 word title for this question, excluding the term 'title.' Then, please reply with only the title: ${userPrompt}`,
|
prompt: `Generate a brief 3-5 word title for this question, excluding the term 'title.' Then, please reply with only the title: ${userPrompt}`,
|
||||||
stream: false
|
stream: false
|
||||||
})
|
})
|
||||||
|
@ -1079,7 +1090,7 @@
|
||||||
<div class="min-h-screen w-full flex justify-center">
|
<div class="min-h-screen w-full flex justify-center">
|
||||||
<div class=" py-2.5 flex flex-col justify-between w-full">
|
<div class=" py-2.5 flex flex-col justify-between w-full">
|
||||||
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 mt-14">
|
<div class="max-w-2xl mx-auto w-full px-3 md:px-0 mt-14">
|
||||||
<div class="flex justify-between my-2 text-sm">
|
<!-- <div class="flex justify-between my-2 text-sm">
|
||||||
<select
|
<select
|
||||||
id="models"
|
id="models"
|
||||||
class="outline-none bg-transparent text-lg font-semibold rounded-lg block w-full placeholder-gray-800"
|
class="outline-none bg-transparent text-lg font-semibold rounded-lg block w-full placeholder-gray-800"
|
||||||
|
@ -1122,9 +1133,9 @@
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<!-- <div class="flex flex-col">
|
<div class="flex flex-col my-2">
|
||||||
{#each selectedModels as selectedModel, selectedModelIdx}
|
{#each selectedModels as selectedModel, selectedModelIdx}
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<select
|
<select
|
||||||
|
@ -1144,15 +1155,15 @@
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
{#if selectedModelIdx === selectedModels.length - 1}
|
{#if selectedModelIdx === 0}
|
||||||
<button
|
<button
|
||||||
class=" self-center {selectedModelIdx === 0
|
class=" self-center {selectedModelIdx === 0
|
||||||
? 'mr-3'
|
? 'mr-3'
|
||||||
: 'mr-7'} disabled:text-gray-600 disabled:hover:text-gray-600"
|
: 'mr-7'} disabled:text-gray-600 disabled:hover:text-gray-600"
|
||||||
disabled={selectedModels.length === 3}
|
disabled={selectedModels.length === 3 || messages.length != 0}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
if (selectedModels.length < 3) {
|
if (selectedModels.length < 3) {
|
||||||
selectedModels = ['', ...selectedModels];
|
selectedModels = [...selectedModels, ''];
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -1169,9 +1180,11 @@
|
||||||
</button>
|
</button>
|
||||||
{:else}
|
{:else}
|
||||||
<button
|
<button
|
||||||
class=" self-center dark:hover:text-gray-300 {selectedModelIdx === 0
|
class=" self-center dark:hover:text-gray-300 disabled:text-gray-600 disabled:hover:text-gray-600 {selectedModelIdx ===
|
||||||
|
0
|
||||||
? 'mr-3'
|
? 'mr-3'
|
||||||
: 'mr-7'}"
|
: 'mr-7'}"
|
||||||
|
disabled={messages.length != 0}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
selectedModels.splice(selectedModelIdx, 1);
|
selectedModels.splice(selectedModelIdx, 1);
|
||||||
selectedModels = selectedModels;
|
selectedModels = selectedModels;
|
||||||
|
@ -1220,7 +1233,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div> -->
|
</div>
|
||||||
|
|
||||||
<div class="text-left mt-1.5 text-xs text-gray-500">
|
<div class="text-left mt-1.5 text-xs text-gray-500">
|
||||||
<button on:click={saveDefaultModel}> Set as default</button>
|
<button on:click={saveDefaultModel}> Set as default</button>
|
||||||
|
@ -1255,7 +1268,13 @@
|
||||||
|
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class=" self-center font-bold mb-0.5">
|
<div class=" self-center font-bold mb-0.5">
|
||||||
{message.role === 'user' ? 'You' : 'Ollama'}
|
{#if message.role === 'user'}
|
||||||
|
You
|
||||||
|
{:else}
|
||||||
|
Ollama <span class=" text-gray-500 text-sm font-medium"
|
||||||
|
>{message.model ? ` ${message.model}` : ''}</span
|
||||||
|
>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if message.role !== 'user' && message.content === ''}
|
{#if message.role !== 'user' && message.content === ''}
|
||||||
|
@ -1622,7 +1641,7 @@
|
||||||
<Suggestions {submitPrompt} />
|
<Suggestions {submitPrompt} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if autoScroll === false}
|
{#if autoScroll === false && messages.length > 0}
|
||||||
<div class=" flex justify-center mb-4">
|
<div class=" flex justify-center mb-4">
|
||||||
<button
|
<button
|
||||||
class=" bg-white/20 p-1.5 rounded-full"
|
class=" bg-white/20 p-1.5 rounded-full"
|
||||||
|
|
Loading…
Reference in a new issue