forked from open-webui/open-webui
		
	feat: modelfile builder linked to api
This commit is contained in:
		
							parent
							
								
									b391c92036
								
							
						
					
					
						commit
						2fba5ed38e
					
				
					 1 changed files with 100 additions and 22 deletions
				
			
		|  | @ -1,13 +1,24 @@ | ||||||
| <script> | <script> | ||||||
| 	import { toast } from 'svelte-french-toast'; | 	import { toast } from 'svelte-french-toast'; | ||||||
| 	import { goto } from '$app/navigation'; | 	import { goto } from '$app/navigation'; | ||||||
|  | 	import { OLLAMA_API_BASE_URL } from '$lib/constants'; | ||||||
|  | 	import { settings, db, user, config } from '$lib/stores'; | ||||||
|  | 
 | ||||||
| 	import Advanced from '$lib/components/chat/Settings/Advanced.svelte'; | 	import Advanced from '$lib/components/chat/Settings/Advanced.svelte'; | ||||||
|  | 	import { splitStream } from '$lib/utils'; | ||||||
| 
 | 
 | ||||||
| 	let loading = false; | 	let loading = false; | ||||||
| 
 | 
 | ||||||
| 	let filesInputElement; | 	let filesInputElement; | ||||||
| 	let inputFiles; | 	let inputFiles; | ||||||
| 	let imageUrl = null; | 	let imageUrl = null; | ||||||
|  | 	let digest = ''; | ||||||
|  | 	let pullProgress = null; | ||||||
|  | 	let success = false; | ||||||
|  | 
 | ||||||
|  | 	// /////////// | ||||||
|  | 	// Modelfile | ||||||
|  | 	// /////////// | ||||||
| 
 | 
 | ||||||
| 	let title = ''; | 	let title = ''; | ||||||
| 	let desc = ''; | 	let desc = ''; | ||||||
|  | @ -54,8 +65,6 @@ ${options.top_p !== '' ? `PARAMETER top_p ${options.top_p}` : ''} | ||||||
| ${options.tfs_z !== '' ? `PARAMETER tfs_z ${options.tfs_z}` : ''} | ${options.tfs_z !== '' ? `PARAMETER tfs_z ${options.tfs_z}` : ''} | ||||||
| ${options.num_ctx !== '' ? `PARAMETER num_ctx ${options.num_ctx}` : ''} | ${options.num_ctx !== '' ? `PARAMETER num_ctx ${options.num_ctx}` : ''} | ||||||
| SYSTEM """${system}"""`.replace(/^\s*\n/gm, ''); | SYSTEM """${system}"""`.replace(/^\s*\n/gm, ''); | ||||||
| 	} else { |  | ||||||
| 		// content = ''; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	let suggestions = [ | 	let suggestions = [ | ||||||
|  | @ -91,31 +100,75 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, ''); | ||||||
| 			content !== '' && | 			content !== '' && | ||||||
| 			Object.keys(categories).filter((category) => categories[category]).length > 0 | 			Object.keys(categories).filter((category) => categories[category]).length > 0 | ||||||
| 		) { | 		) { | ||||||
| 			const res = await fetch(`/api/create`, { | 			const res = await fetch(`${$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL}/create`, { | ||||||
| 				method: 'POST', | 				method: 'POST', | ||||||
| 				headers: { | 				headers: { | ||||||
| 					'Content-Type': 'application/json' | 					'Content-Type': 'text/event-stream', | ||||||
|  | 					...($settings.authHeader && { Authorization: $settings.authHeader }), | ||||||
|  | 					...($user && { Authorization: `Bearer ${localStorage.token}` }) | ||||||
| 				}, | 				}, | ||||||
| 				body: JSON.stringify({ | 				body: JSON.stringify({ | ||||||
| 					title: title, | 					name: title.replace(/\s+/g, '-').toLowerCase(), | ||||||
| 					desc: desc, | 					modelfile: content | ||||||
| 					content: content, |  | ||||||
| 					imageUrl: imageUrl, |  | ||||||
| 					categories: Object.keys(categories).filter((category) => categories[category]) |  | ||||||
| 				}) | 				}) | ||||||
| 			}) | 			}); | ||||||
| 				.then(async (res) => { |  | ||||||
| 					if (!res.ok) throw await res.json(); |  | ||||||
| 					return res.json(); |  | ||||||
| 				}) |  | ||||||
| 				.catch((error) => { |  | ||||||
| 					console.log(error); |  | ||||||
| 					return null; |  | ||||||
| 				}); |  | ||||||
| 
 | 
 | ||||||
| 			if (res?.status ?? false) { | 			if (res) { | ||||||
| 				toast.success(`Success! Your model file is now available.`); | 				const reader = res.body | ||||||
| 				await goto(`/models/${res.id}`); | 					.pipeThrough(new TextDecoderStream()) | ||||||
|  | 					.pipeThrough(splitStream('\n')) | ||||||
|  | 					.getReader(); | ||||||
|  | 
 | ||||||
|  | 				while (true) { | ||||||
|  | 					const { value, done } = await reader.read(); | ||||||
|  | 					if (done) break; | ||||||
|  | 
 | ||||||
|  | 					try { | ||||||
|  | 						let lines = value.split('\n'); | ||||||
|  | 
 | ||||||
|  | 						for (const line of lines) { | ||||||
|  | 							if (line !== '') { | ||||||
|  | 								console.log(line); | ||||||
|  | 								let data = JSON.parse(line); | ||||||
|  | 								console.log(data); | ||||||
|  | 
 | ||||||
|  | 								if (data.error) { | ||||||
|  | 									throw data.error; | ||||||
|  | 								} | ||||||
|  | 								if (data.detail) { | ||||||
|  | 									throw data.detail; | ||||||
|  | 								} | ||||||
|  | 
 | ||||||
|  | 								if (data.status) { | ||||||
|  | 									if ( | ||||||
|  | 										!data.digest && | ||||||
|  | 										!data.status.includes('writing') && | ||||||
|  | 										!data.status.includes('sha256') | ||||||
|  | 									) { | ||||||
|  | 										toast.success(data.status); | ||||||
|  | 
 | ||||||
|  | 										if (data.status === 'success') { | ||||||
|  | 											success = true; | ||||||
|  | 										} | ||||||
|  | 									} else { | ||||||
|  | 										if (data.digest) { | ||||||
|  | 											digest = data.digest; | ||||||
|  | 
 | ||||||
|  | 											if (data.completed) { | ||||||
|  | 												pullProgress = Math.round((data.completed / data.total) * 1000) / 10; | ||||||
|  | 											} else { | ||||||
|  | 												pullProgress = 100; | ||||||
|  | 											} | ||||||
|  | 										} | ||||||
|  | 									} | ||||||
|  | 								} | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} catch (error) { | ||||||
|  | 						console.log(error); | ||||||
|  | 						toast.error(error); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		loading = false; | 		loading = false; | ||||||
|  | @ -331,9 +384,17 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, ''); | ||||||
| 									required | 									required | ||||||
| 								/> | 								/> | ||||||
| 							</div> | 							</div> | ||||||
|  | 
 | ||||||
|  | 							<div class="mt-1 text-xs text-gray-400 dark:text-gray-500"> | ||||||
|  | 								To access the available model names for downloading, <a | ||||||
|  | 									class=" text-gray-500 dark:text-gray-300 font-medium" | ||||||
|  | 									href="https://ollama.ai/library" | ||||||
|  | 									target="_blank">click here.</a | ||||||
|  | 								> | ||||||
|  | 							</div> | ||||||
| 						</div> | 						</div> | ||||||
| 
 | 
 | ||||||
| 						<div class="my-2"> | 						<div class="my-1"> | ||||||
| 							<div class=" text-xs font-semibold mb-2">System Prompt</div> | 							<div class=" text-xs font-semibold mb-2">System Prompt</div> | ||||||
| 
 | 
 | ||||||
| 							<div> | 							<div> | ||||||
|  | @ -459,6 +520,23 @@ SYSTEM """${system}"""`.replace(/^\s*\n/gm, ''); | ||||||
| 					</div> | 					</div> | ||||||
| 				</div> | 				</div> | ||||||
| 
 | 
 | ||||||
|  | 				{#if pullProgress !== null} | ||||||
|  | 					<div class="my-2"> | ||||||
|  | 						<div class=" text-sm font-semibold mb-2">Pull Progress</div> | ||||||
|  | 						<div class="w-full rounded-full dark:bg-gray-800"> | ||||||
|  | 							<div | ||||||
|  | 								class="dark:bg-gray-600 text-xs font-medium text-blue-100 text-center p-0.5 leading-none rounded-full" | ||||||
|  | 								style="width: {Math.max(15, pullProgress ?? 0)}%" | ||||||
|  | 							> | ||||||
|  | 								{pullProgress ?? 0}% | ||||||
|  | 							</div> | ||||||
|  | 						</div> | ||||||
|  | 						<div class="mt-1 text-xs dark:text-gray-500" style="font-size: 0.5rem;"> | ||||||
|  | 							{digest} | ||||||
|  | 						</div> | ||||||
|  | 					</div> | ||||||
|  | 				{/if} | ||||||
|  | 
 | ||||||
| 				<div class="my-2 flex justify-end"> | 				<div class="my-2 flex justify-end"> | ||||||
| 					<button | 					<button | ||||||
| 						class=" text-sm px-3 py-2 transition rounded-xl {loading | 						class=" text-sm px-3 py-2 transition rounded-xl {loading | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek