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 (selectedModel.includes('gpt-')) { | 				if (model.includes('gpt-')) { | ||||||
| 		// 			await sendPromptOpenAI(userPrompt, parentId); | 					await sendPromptOpenAI(model, userPrompt, parentId); | ||||||
| 		// 		} else { | 				} else { | ||||||
| 		// 			await sendPromptOllama(userPrompt, parentId); | 					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); | ||||||
| 		} | 		// } | ||||||
| 
 | 
 | ||||||
| 		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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek