forked from open-webui/open-webui
		
	feat: enable api_base_url edit from ui
This commit is contained in:
		
							parent
							
								
									00b5b38ac9
								
							
						
					
					
						commit
						b6a780e7c7
					
				
					 5 changed files with 167 additions and 28 deletions
				
			
		
							
								
								
									
										77
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										77
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							|  | @ -21,6 +21,7 @@ | |||
| 				"@sveltejs/adapter-auto": "^2.0.0", | ||||
| 				"@sveltejs/adapter-static": "^2.0.3", | ||||
| 				"@sveltejs/kit": "^1.20.4", | ||||
| 				"@tailwindcss/typography": "^0.5.10", | ||||
| 				"@typescript-eslint/eslint-plugin": "^6.0.0", | ||||
| 				"@typescript-eslint/parser": "^6.0.0", | ||||
| 				"autoprefixer": "^10.4.16", | ||||
|  | @ -838,6 +839,34 @@ | |||
| 				"vite": "^4.0.0" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@tailwindcss/typography": { | ||||
| 			"version": "0.5.10", | ||||
| 			"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.10.tgz", | ||||
| 			"integrity": "sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==", | ||||
| 			"dev": true, | ||||
| 			"dependencies": { | ||||
| 				"lodash.castarray": "^4.4.0", | ||||
| 				"lodash.isplainobject": "^4.0.6", | ||||
| 				"lodash.merge": "^4.6.2", | ||||
| 				"postcss-selector-parser": "6.0.10" | ||||
| 			}, | ||||
| 			"peerDependencies": { | ||||
| 				"tailwindcss": ">=3.0.0 || insiders" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { | ||||
| 			"version": "6.0.10", | ||||
| 			"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", | ||||
| 			"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", | ||||
| 			"dev": true, | ||||
| 			"dependencies": { | ||||
| 				"cssesc": "^3.0.0", | ||||
| 				"util-deprecate": "^1.0.2" | ||||
| 			}, | ||||
| 			"engines": { | ||||
| 				"node": ">=4" | ||||
| 			} | ||||
| 		}, | ||||
| 		"node_modules/@types/cookie": { | ||||
| 			"version": "0.5.2", | ||||
| 			"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.2.tgz", | ||||
|  | @ -2603,6 +2632,18 @@ | |||
| 			"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", | ||||
| 			"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" | ||||
| 		}, | ||||
| 		"node_modules/lodash.castarray": { | ||||
| 			"version": "4.4.0", | ||||
| 			"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", | ||||
| 			"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"node_modules/lodash.isplainobject": { | ||||
| 			"version": "4.0.6", | ||||
| 			"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", | ||||
| 			"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"node_modules/lodash.merge": { | ||||
| 			"version": "4.6.2", | ||||
| 			"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", | ||||
|  | @ -4670,6 +4711,30 @@ | |||
| 				"debug": "^4.3.4" | ||||
| 			} | ||||
| 		}, | ||||
| 		"@tailwindcss/typography": { | ||||
| 			"version": "0.5.10", | ||||
| 			"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.10.tgz", | ||||
| 			"integrity": "sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==", | ||||
| 			"dev": true, | ||||
| 			"requires": { | ||||
| 				"lodash.castarray": "^4.4.0", | ||||
| 				"lodash.isplainobject": "^4.0.6", | ||||
| 				"lodash.merge": "^4.6.2", | ||||
| 				"postcss-selector-parser": "6.0.10" | ||||
| 			}, | ||||
| 			"dependencies": { | ||||
| 				"postcss-selector-parser": { | ||||
| 					"version": "6.0.10", | ||||
| 					"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", | ||||
| 					"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", | ||||
| 					"dev": true, | ||||
| 					"requires": { | ||||
| 						"cssesc": "^3.0.0", | ||||
| 						"util-deprecate": "^1.0.2" | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		}, | ||||
| 		"@types/cookie": { | ||||
| 			"version": "0.5.2", | ||||
| 			"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.2.tgz", | ||||
|  | @ -5909,6 +5974,18 @@ | |||
| 			"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", | ||||
| 			"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" | ||||
| 		}, | ||||
| 		"lodash.castarray": { | ||||
| 			"version": "4.4.0", | ||||
| 			"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", | ||||
| 			"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"lodash.isplainobject": { | ||||
| 			"version": "4.0.6", | ||||
| 			"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", | ||||
| 			"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", | ||||
| 			"dev": true | ||||
| 		}, | ||||
| 		"lodash.merge": { | ||||
| 			"version": "4.6.2", | ||||
| 			"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ | |||
| 		"@sveltejs/adapter-auto": "^2.0.0", | ||||
| 		"@sveltejs/adapter-static": "^2.0.3", | ||||
| 		"@sveltejs/kit": "^1.20.4", | ||||
| 		"@tailwindcss/typography": "^0.5.10", | ||||
| 		"@typescript-eslint/eslint-plugin": "^6.0.0", | ||||
| 		"@typescript-eslint/parser": "^6.0.0", | ||||
| 		"autoprefixer": "^10.4.16", | ||||
|  |  | |||
|  | @ -1,13 +1,14 @@ | |||
| <script lang="ts"> | ||||
| 	import Modal from '../common/Modal.svelte'; | ||||
| 
 | ||||
| 	import { API_BASE_URL } from '$lib/constants'; | ||||
| 	import { API_BASE_URL as BUILD_TIME_API_BASE_URL } from '$lib/constants'; | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 
 | ||||
| 	export let show = false; | ||||
| 	export let saveSettings: Function; | ||||
| 	export let getModelTags: Function; | ||||
| 
 | ||||
| 	let API_BASE_URL = BUILD_TIME_API_BASE_URL; | ||||
| 	let system = ''; | ||||
| 	let temperature = 0.8; | ||||
| 
 | ||||
|  | @ -33,6 +34,14 @@ | |||
| 		}); | ||||
| 	}; | ||||
| 
 | ||||
| 	const checkOllamaConnection = async () => { | ||||
| 		const res = await getModelTags(API_BASE_URL); | ||||
| 
 | ||||
| 		if (res) { | ||||
| 			toast.success('Server connection verified'); | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	const pullModelHandler = async () => { | ||||
| 		const res = await fetch(`${API_BASE_URL}/pull`, { | ||||
| 			method: 'POST', | ||||
|  | @ -139,6 +148,7 @@ | |||
| 
 | ||||
| 	$: if (show) { | ||||
| 		let settings = JSON.parse(localStorage.getItem('settings') ?? '{}'); | ||||
| 		API_BASE_URL = settings.API_BASE_URL ?? BUILD_TIME_API_BASE_URL; | ||||
| 		system = settings.system ?? ''; | ||||
| 		temperature = settings.temperature ?? 0.8; | ||||
| 	} | ||||
|  | @ -227,6 +237,50 @@ | |||
| 			<div class="flex-1 md:min-h-[300px]"> | ||||
| 				{#if selectedMenu === 'general'} | ||||
| 					<div class="flex flex-col space-y-3"> | ||||
| 						<div> | ||||
| 							<div class=" mb-2.5 text-sm font-medium">Ollama Server URL</div> | ||||
| 							<div class="flex w-full"> | ||||
| 								<div class="flex-1 mr-2"> | ||||
| 									<input | ||||
| 										class="w-full rounded py-2 px-4 text-sm text-gray-300 bg-gray-800 outline-none" | ||||
| 										placeholder="Enter URL (e.g. http://localhost:11434/api)" | ||||
| 										bind:value={API_BASE_URL} | ||||
| 									/> | ||||
| 								</div> | ||||
| 								<button | ||||
| 									class="px-3 bg-gray-600 hover:bg-gray-700 rounded transition" | ||||
| 									on:click={() => { | ||||
| 										checkOllamaConnection(); | ||||
| 									}} | ||||
| 								> | ||||
| 									<svg | ||||
| 										xmlns="http://www.w3.org/2000/svg" | ||||
| 										viewBox="0 0 20 20" | ||||
| 										fill="currentColor" | ||||
| 										class="w-4 h-4" | ||||
| 									> | ||||
| 										<path | ||||
| 											fill-rule="evenodd" | ||||
| 											d="M15.312 11.424a5.5 5.5 0 01-9.201 2.466l-.312-.311h2.433a.75.75 0 000-1.5H3.989a.75.75 0 00-.75.75v4.242a.75.75 0 001.5 0v-2.43l.31.31a7 7 0 0011.712-3.138.75.75 0 00-1.449-.39zm1.23-3.723a.75.75 0 00.219-.53V2.929a.75.75 0 00-1.5 0V5.36l-.31-.31A7 7 0 003.239 8.188a.75.75 0 101.448.389A5.5 5.5 0 0113.89 6.11l.311.31h-2.432a.75.75 0 000 1.5h4.243a.75.75 0 00.53-.219z" | ||||
| 											clip-rule="evenodd" | ||||
| 										/> | ||||
| 									</svg> | ||||
| 								</button> | ||||
| 							</div> | ||||
| 
 | ||||
| 							<div class="mt-2 text-xs text-gray-500"> | ||||
| 								Trouble accessing Ollama? <a | ||||
| 									class=" text-gray-300 font-medium" | ||||
| 									href="https://github.com/ollama-webui/ollama-webui#troubleshooting" | ||||
| 									target="_blank" | ||||
| 								> | ||||
| 									Click here for help. | ||||
| 								</a> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 
 | ||||
| 						<hr class=" border-gray-700" /> | ||||
| 
 | ||||
| 						<div> | ||||
| 							<div class=" mb-2.5 text-sm font-medium">System Prompt</div> | ||||
| 							<textarea | ||||
|  | @ -260,6 +314,7 @@ | |||
| 								class=" px-4 py-2 bg-emerald-600 hover:bg-emerald-700 transition rounded" | ||||
| 								on:click={() => { | ||||
| 									saveSettings( | ||||
| 										API_BASE_URL === '' ? BUILD_TIME_API_BASE_URL : API_BASE_URL, | ||||
| 										system != '' ? system : null, | ||||
| 										temperature != 0.8 ? temperature : null | ||||
| 									); | ||||
|  | @ -305,11 +360,11 @@ | |||
| 							</div> | ||||
| 
 | ||||
| 							<div class="mt-2 text-xs text-gray-500"> | ||||
| 								To access the available model names for downloading, click <a | ||||
| 								To access the available model names for downloading, <a | ||||
| 									class=" text-gray-300 font-medium" | ||||
| 									href="https://ollama.ai/library" | ||||
| 									target="_blank">here</a | ||||
| 								>. | ||||
| 									target="_blank">click here.</a | ||||
| 								> | ||||
| 							</div> | ||||
| 
 | ||||
| 							{#if pullProgress !== ''} | ||||
|  |  | |||
|  | @ -6,13 +6,14 @@ | |||
| 	import fileSaver from 'file-saver'; | ||||
| 	const { saveAs } = fileSaver; | ||||
| 	import hljs from 'highlight.js'; | ||||
| 	import 'highlight.js/styles/dark.min.css'; | ||||
| 	import { API_BASE_URL } from '$lib/constants'; | ||||
| 	import 'highlight.js/styles/github-dark.min.css'; | ||||
| 	import { API_BASE_URL as BUILD_TIME_API_BASE_URL } from '$lib/constants'; | ||||
| 	import { onMount, tick } from 'svelte'; | ||||
| 
 | ||||
| 	import Navbar from '$lib/components/layout/Navbar.svelte'; | ||||
| 	import SettingsModal from '$lib/components/chat/SettingsModal.svelte'; | ||||
| 
 | ||||
| 	let API_BASE_URL = BUILD_TIME_API_BASE_URL; | ||||
| 	let suggestions = ''; // $page.url.searchParams.get('suggestions'); | ||||
| 
 | ||||
| 	let models = []; | ||||
|  | @ -31,21 +32,19 @@ | |||
| 	let messages = []; | ||||
| 
 | ||||
| 	onMount(async () => { | ||||
| 		let settings = JSON.parse(localStorage.getItem('settings') ?? '{}'); | ||||
| 
 | ||||
| 		API_BASE_URL = settings.API_BASE_URL ?? BUILD_TIME_API_BASE_URL; | ||||
| 		console.log(API_BASE_URL); | ||||
| 		system = settings.system ?? null; | ||||
| 		temperature = settings.temperature ?? null; | ||||
| 
 | ||||
| 		await getModelTags(); | ||||
| 
 | ||||
| 		let settings = localStorage.getItem('settings'); | ||||
| 		if (settings) { | ||||
| 			settings = JSON.parse(settings); | ||||
| 			console.log(settings); | ||||
| 
 | ||||
| 			selectedModel = | ||||
| 				settings.model && models.map((model) => model.name).includes(settings.model) | ||||
| 					? settings.model | ||||
| 					: ''; | ||||
| 			system = settings.system ?? null; | ||||
| 			temperature = settings.temperature ?? null; | ||||
| 		} | ||||
| 		selectedModel = | ||||
| 			settings.model && models.map((model) => model.name).includes(settings.model) | ||||
| 				? settings.model | ||||
| 				: ''; | ||||
| 
 | ||||
| 		db = await openDB('Chats', 1, { | ||||
| 			upgrade(db) { | ||||
|  | @ -133,21 +132,23 @@ | |||
| 		toast.success('Default model updated'); | ||||
| 	}; | ||||
| 
 | ||||
| 	const saveSettings = (_system, _temperature) => { | ||||
| 	const saveSettings = async (_api_base_url, _system, _temperature) => { | ||||
| 		API_BASE_URL = _api_base_url; | ||||
| 		system = _system; | ||||
| 		temperature = _temperature; | ||||
| 
 | ||||
| 		let settings = localStorage.getItem('settings') ?? '{}'; | ||||
| 		if (settings) { | ||||
| 			settings = JSON.parse(settings); | ||||
| 
 | ||||
| 			settings.API_BASE_URL = API_BASE_URL; | ||||
| 			settings.system = system; | ||||
| 			settings.temperature = temperature; | ||||
| 			localStorage.setItem('settings', JSON.stringify(settings)); | ||||
| 		} | ||||
| 
 | ||||
| 		console.log(settings); | ||||
| 
 | ||||
| 		console.log('saved'); | ||||
| 		await getModelTags(); | ||||
| 	}; | ||||
| 
 | ||||
| 	const createNewChat = () => { | ||||
|  | @ -163,7 +164,10 @@ | |||
| 				settings = JSON.parse(settings); | ||||
| 				console.log(settings); | ||||
| 
 | ||||
| 				selectedModel = settings.model ?? selectedModel; | ||||
| 				selectedModel = | ||||
| 					settings.model && models.map((model) => model.name).includes(settings.model) | ||||
| 						? settings.model | ||||
| 						: ''; | ||||
| 				system = settings.system ?? system; | ||||
| 				temperature = settings.temperature ?? temperature; | ||||
| 			} | ||||
|  | @ -219,8 +223,8 @@ | |||
| 	// Ollama functions | ||||
| 	////////////////////////// | ||||
| 
 | ||||
| 	const getModelTags = async () => { | ||||
| 		const res = await fetch(`${API_BASE_URL}/tags`, { | ||||
| 	const getModelTags = async (url = null) => { | ||||
| 		const res = await fetch(`${url === null ? API_BASE_URL : url}/tags`, { | ||||
| 			method: 'GET', | ||||
| 			headers: { | ||||
| 				Accept: 'application/json', | ||||
|  | @ -233,11 +237,13 @@ | |||
| 			}) | ||||
| 			.catch((error) => { | ||||
| 				console.log(error); | ||||
| 				return { models: [] }; | ||||
| 				toast.error('Server connection failed'); | ||||
| 				return null; | ||||
| 			}); | ||||
| 
 | ||||
| 		console.log(res); | ||||
| 		models = res.models ?? []; | ||||
| 		models = res?.models ?? []; | ||||
| 		return res; | ||||
| 	}; | ||||
| 
 | ||||
| 	const submitPrompt = async (user_prompt) => { | ||||
|  | @ -609,7 +615,7 @@ | |||
| 												</div> | ||||
| 											</div> | ||||
| 										{:else} | ||||
| 											<div class="markdown-body whitespace-pre-line"> | ||||
| 											<div class="whitespace-pre-line"> | ||||
| 												{@html marked.parse(message.content)} | ||||
| 											</div> | ||||
| 										{/if} | ||||
|  |  | |||
|  | @ -20,5 +20,5 @@ export default { | |||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 	plugins: [] | ||||
| 	plugins: [require('@tailwindcss/typography')] | ||||
| }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek