forked from open-webui/open-webui
		
	chore: refac
This commit is contained in:
		
							parent
							
								
									f30d16a3fd
								
							
						
					
					
						commit
						cc49e0d10f
					
				
					 11 changed files with 239 additions and 397 deletions
				
			
		|  | @ -31,7 +31,7 @@ export const createNewChat = async (token: string, chat: object) => { | |||
| 	return res; | ||||
| }; | ||||
| 
 | ||||
| export const getChatlist = async (token: string = '') => { | ||||
| export const getChatList = async (token: string = '') => { | ||||
| 	let error = null; | ||||
| 
 | ||||
| 	const res = await fetch(`${WEBUI_API_BASE_URL}/chats/`, { | ||||
|  |  | |||
|  | @ -69,3 +69,68 @@ export const getOllamaModels = async ( | |||
| 
 | ||||
| 	return res?.models ?? []; | ||||
| }; | ||||
| 
 | ||||
| export const generateTitle = async ( | ||||
| 	base_url: string = OLLAMA_API_BASE_URL, | ||||
| 	token: string = '', | ||||
| 	model: string, | ||||
| 	prompt: string | ||||
| ) => { | ||||
| 	let error = null; | ||||
| 
 | ||||
| 	const res = await fetch(`${base_url}/generate`, { | ||||
| 		method: 'POST', | ||||
| 		headers: { | ||||
| 			'Content-Type': 'text/event-stream', | ||||
| 			Authorization: `Bearer ${token}` | ||||
| 		}, | ||||
| 		body: JSON.stringify({ | ||||
| 			model: model, | ||||
| 			prompt: `Generate a brief 3-5 word title for this question, excluding the term 'title.' Then, please reply with only the title: ${prompt}`, | ||||
| 			stream: false | ||||
| 		}) | ||||
| 	}) | ||||
| 		.then(async (res) => { | ||||
| 			if (!res.ok) throw await res.json(); | ||||
| 			return res.json(); | ||||
| 		}) | ||||
| 		.catch((err) => { | ||||
| 			console.log(err); | ||||
| 			if ('detail' in err) { | ||||
| 				error = err.detail; | ||||
| 			} | ||||
| 			return null; | ||||
| 		}); | ||||
| 
 | ||||
| 	if (error) { | ||||
| 		throw error; | ||||
| 	} | ||||
| 
 | ||||
| 	return res?.response ?? 'New Chat'; | ||||
| }; | ||||
| 
 | ||||
| export const generateChatCompletion = async ( | ||||
| 	base_url: string = OLLAMA_API_BASE_URL, | ||||
| 	token: string = '', | ||||
| 	body: object | ||||
| ) => { | ||||
| 	let error = null; | ||||
| 
 | ||||
| 	const res = await fetch(`${base_url}/chat`, { | ||||
| 		method: 'POST', | ||||
| 		headers: { | ||||
| 			'Content-Type': 'text/event-stream', | ||||
| 			Authorization: `Bearer ${token}` | ||||
| 		}, | ||||
| 		body: JSON.stringify(body) | ||||
| 	}).catch((err) => { | ||||
| 		error = err; | ||||
| 		return null; | ||||
| 	}); | ||||
| 
 | ||||
| 	if (error) { | ||||
| 		throw error; | ||||
| 	} | ||||
| 
 | ||||
| 	return res; | ||||
| }; | ||||
|  |  | |||
|  | @ -27,8 +27,6 @@ export const getOpenAIModels = async ( | |||
| 
 | ||||
| 	let models = Array.isArray(res) ? res : res?.data ?? null; | ||||
| 
 | ||||
| 	console.log(models); | ||||
| 
 | ||||
| 	return models | ||||
| 		.map((model) => ({ name: model.id, external: true })) | ||||
| 		.filter((model) => (base_url.includes('openai') ? model.name.includes('gpt') : true)); | ||||
|  |  | |||
|  | @ -8,10 +8,11 @@ | |||
| 	import auto_render from 'katex/dist/contrib/auto-render.mjs'; | ||||
| 	import 'katex/dist/katex.min.css'; | ||||
| 
 | ||||
| 	import { config, db, modelfiles, settings, user } from '$lib/stores'; | ||||
| 	import { chats, config, db, modelfiles, settings, user } from '$lib/stores'; | ||||
| 	import { tick } from 'svelte'; | ||||
| 
 | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 	import { getChatList, updateChatById } from '$lib/apis/chats'; | ||||
| 
 | ||||
| 	export let chatId = ''; | ||||
| 	export let sendPrompt: Function; | ||||
|  | @ -262,10 +263,12 @@ | |||
| 			return message; | ||||
| 		}); | ||||
| 
 | ||||
| 		$db.updateChatById(chatId, { | ||||
| 		await updateChatById(localStorage.token, chatId, { | ||||
| 			messages: messages, | ||||
| 			history: history | ||||
| 		}); | ||||
| 
 | ||||
| 		await chats.set(await getChatList(localStorage.token)); | ||||
| 	}; | ||||
| 
 | ||||
| 	const showPreviousMessage = async (message) => { | ||||
|  |  | |||
|  | @ -1,7 +1,5 @@ | |||
| <script lang="ts"> | ||||
| 	import { v4 as uuidv4 } from 'uuid'; | ||||
| 
 | ||||
| 	import { goto } from '$app/navigation'; | ||||
| 	import { getChatById } from '$lib/apis/chats'; | ||||
| 	import { chatId, db, modelfiles } from '$lib/stores'; | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 
 | ||||
|  | @ -10,10 +8,10 @@ | |||
| 	export let shareEnabled: boolean = false; | ||||
| 
 | ||||
| 	const shareChat = async () => { | ||||
| 		const chat = (await $db.getChatById($chatId)).chat; | ||||
| 		const chat = (await getChatById(localStorage.token, $chatId)).chat; | ||||
| 		console.log('share', chat); | ||||
| 		toast.success('Redirecting you to OllamaHub'); | ||||
| 
 | ||||
| 		toast.success('Redirecting you to OllamaHub'); | ||||
| 		const url = 'https://ollamahub.com'; | ||||
| 		// const url = 'http://localhost:5173'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ | |||
| 	import { page } from '$app/stores'; | ||||
| 	import { user, db, chats, showSettings, chatId } from '$lib/stores'; | ||||
| 	import { onMount } from 'svelte'; | ||||
| 	import { deleteChatById, getChatList, updateChatById } from '$lib/apis/chats'; | ||||
| 
 | ||||
| 	let show = false; | ||||
| 	let navElement; | ||||
|  | @ -31,7 +32,7 @@ | |||
| 			show = true; | ||||
| 		} | ||||
| 
 | ||||
| 		await chats.set(await $db.getChats()); | ||||
| 		await chats.set(await getChatList(localStorage.token)); | ||||
| 	}); | ||||
| 
 | ||||
| 	const loadChat = async (id) => { | ||||
|  | @ -39,42 +40,46 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	const editChatTitle = async (id, _title) => { | ||||
| 		await $db.updateChatById(id, { | ||||
| 		title = _title; | ||||
| 
 | ||||
| 		await updateChatById(localStorage.token, id, { | ||||
| 			title: _title | ||||
| 		}); | ||||
| 		title = _title; | ||||
| 		await chats.set(await getChatList(localStorage.token)); | ||||
| 	}; | ||||
| 
 | ||||
| 	const deleteChat = async (id) => { | ||||
| 		goto('/'); | ||||
| 		$db.deleteChatById(id); | ||||
| 
 | ||||
| 		await deleteChatById(localStorage.token, id); | ||||
| 		await chats.set(await getChatList(localStorage.token)); | ||||
| 	}; | ||||
| 
 | ||||
| 	const deleteChatHistory = async () => { | ||||
| 		await $db.deleteAllChat(); | ||||
| 	}; | ||||
| 	// const deleteChatHistory = async () => { | ||||
| 	// 	await $db.deleteAllChat(); | ||||
| 	// }; | ||||
| 
 | ||||
| 	const importChats = async (chatHistory) => { | ||||
| 		await $db.importChats(chatHistory); | ||||
| 	}; | ||||
| 	// const importChats = async (chatHistory) => { | ||||
| 	// 	await $db.importChats(chatHistory); | ||||
| 	// }; | ||||
| 
 | ||||
| 	const exportChats = async () => { | ||||
| 		let blob = new Blob([JSON.stringify(await $db.exportChats())], { type: 'application/json' }); | ||||
| 		saveAs(blob, `chat-export-${Date.now()}.json`); | ||||
| 	}; | ||||
| 	// const exportChats = async () => { | ||||
| 	// 	let blob = new Blob([JSON.stringify(await $db.exportChats())], { type: 'application/json' }); | ||||
| 	// 	saveAs(blob, `chat-export-${Date.now()}.json`); | ||||
| 	// }; | ||||
| 
 | ||||
| 	$: if (importFiles) { | ||||
| 		console.log(importFiles); | ||||
| 	// $: if (importFiles) { | ||||
| 	// 	console.log(importFiles); | ||||
| 
 | ||||
| 		let reader = new FileReader(); | ||||
| 		reader.onload = (event) => { | ||||
| 			let chats = JSON.parse(event.target.result); | ||||
| 			console.log(chats); | ||||
| 			importChats(chats); | ||||
| 		}; | ||||
| 	// 	let reader = new FileReader(); | ||||
| 	// 	reader.onload = (event) => { | ||||
| 	// 		let chats = JSON.parse(event.target.result); | ||||
| 	// 		console.log(chats); | ||||
| 	// 		importChats(chats); | ||||
| 	// 	}; | ||||
| 
 | ||||
| 		reader.readAsText(importFiles[0]); | ||||
| 	} | ||||
| 	// 	reader.readAsText(importFiles[0]); | ||||
| 	// } | ||||
| </script> | ||||
| 
 | ||||
| <div | ||||
|  |  | |||
|  | @ -13,6 +13,8 @@ export const WEBUI_API_BASE_URL = `${WEBUI_BASE_URL}/api/v1`; | |||
| 
 | ||||
| export const WEB_UI_VERSION = 'v1.0.0-alpha-static'; | ||||
| 
 | ||||
| export const REQUIRED_OLLAMA_VERSION = '0.1.16'; | ||||
| 
 | ||||
| // Source: https://kit.svelte.dev/docs/modules#$env-static-public
 | ||||
| // This feature, akin to $env/static/private, exclusively incorporates environment variables
 | ||||
| // that are prefixed with config.kit.env.publicPrefix (usually set to PUBLIC_).
 | ||||
|  |  | |||
|  | @ -66,9 +66,9 @@ export const getGravatarURL = (email) => { | |||
| 	return `https://www.gravatar.com/avatar/${hash}`; | ||||
| }; | ||||
| 
 | ||||
| const copyToClipboard = (text) => { | ||||
| export const copyToClipboard = (text) => { | ||||
| 	if (!navigator.clipboard) { | ||||
| 		var textArea = document.createElement('textarea'); | ||||
| 		const textArea = document.createElement('textarea'); | ||||
| 		textArea.value = text; | ||||
| 
 | ||||
| 		// Avoid scrolling to bottom
 | ||||
|  | @ -81,8 +81,8 @@ const copyToClipboard = (text) => { | |||
| 		textArea.select(); | ||||
| 
 | ||||
| 		try { | ||||
| 			var successful = document.execCommand('copy'); | ||||
| 			var msg = successful ? 'successful' : 'unsuccessful'; | ||||
| 			const successful = document.execCommand('copy'); | ||||
| 			const msg = successful ? 'successful' : 'unsuccessful'; | ||||
| 			console.log('Fallback: Copying text command was ' + msg); | ||||
| 		} catch (err) { | ||||
| 			console.error('Fallback: Oops, unable to copy', err); | ||||
|  |  | |||
|  | @ -1,37 +1,18 @@ | |||
| <script lang="ts"> | ||||
| 	import { v4 as uuidv4 } from 'uuid'; | ||||
| 	import { openDB, deleteDB } from 'idb'; | ||||
| 	import { onMount, tick } from 'svelte'; | ||||
| 	import { goto } from '$app/navigation'; | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 
 | ||||
| 	import { | ||||
| 		config, | ||||
| 		info, | ||||
| 		user, | ||||
| 		showSettings, | ||||
| 		settings, | ||||
| 		models, | ||||
| 		db, | ||||
| 		chats, | ||||
| 		chatId, | ||||
| 		modelfiles | ||||
| 	} from '$lib/stores'; | ||||
| 	import { info, user, showSettings, settings, models, modelfiles } from '$lib/stores'; | ||||
| 
 | ||||
| 	import { OLLAMA_API_BASE_URL, REQUIRED_OLLAMA_VERSION, WEBUI_API_BASE_URL } from '$lib/constants'; | ||||
| 	import { getOllamaModels, getOllamaVersion } from '$lib/apis/ollama'; | ||||
| 	import { getOpenAIModels } from '$lib/apis/openai'; | ||||
| 
 | ||||
| 	import SettingsModal from '$lib/components/chat/SettingsModal.svelte'; | ||||
| 	import Sidebar from '$lib/components/layout/Sidebar.svelte'; | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 	import { OLLAMA_API_BASE_URL, WEBUI_API_BASE_URL } from '$lib/constants'; | ||||
| 	import { getOllamaModels, getOllamaVersion } from '$lib/apis/ollama'; | ||||
| 	import { getOpenAIModels } from '$lib/apis/openai'; | ||||
| 	import { | ||||
| 		createNewChat, | ||||
| 		deleteChatById, | ||||
| 		getChatById, | ||||
| 		getChatlist, | ||||
| 		updateChatById | ||||
| 	} from '$lib/apis/chats'; | ||||
| 
 | ||||
| 	let requiredOllamaVersion = '0.1.16'; | ||||
| 	let loaded = false; | ||||
| 
 | ||||
| 	const getModels = async () => { | ||||
|  | @ -55,92 +36,19 @@ | |||
| 		return models; | ||||
| 	}; | ||||
| 
 | ||||
| 	const getDB = async () => { | ||||
| 		const DB = await openDB('Chats', 1, { | ||||
| 			upgrade(db) { | ||||
| 				const store = db.createObjectStore('chats', { | ||||
| 					keyPath: 'id', | ||||
| 					autoIncrement: true | ||||
| 				}); | ||||
| 				store.createIndex('timestamp', 'timestamp'); | ||||
| 			} | ||||
| 		}); | ||||
| 
 | ||||
| 		return { | ||||
| 			db: DB, | ||||
| 			getChatById: async function (id) { | ||||
| 				const chat = await getChatById(localStorage.token, id); | ||||
| 				return chat; | ||||
| 			}, | ||||
| 			getChats: async function () { | ||||
| 				const chats = await getChatlist(localStorage.token); | ||||
| 				return chats; | ||||
| 			}, | ||||
| 			createNewChat: async function (_chat) { | ||||
| 				const chat = await createNewChat(localStorage.token, { ..._chat, timestamp: Date.now() }); | ||||
| 				console.log(chat); | ||||
| 				await chats.set(await this.getChats()); | ||||
| 
 | ||||
| 				return chat; | ||||
| 			}, | ||||
| 
 | ||||
| 			addChat: async function (chat) { | ||||
| 				await this.db.put('chats', { | ||||
| 					...chat | ||||
| 				}); | ||||
| 			}, | ||||
| 
 | ||||
| 			updateChatById: async function (id, updated) { | ||||
| 				const chat = await updateChatById(localStorage.token, id, { | ||||
| 					...updated, | ||||
| 					timestamp: Date.now() | ||||
| 				}); | ||||
| 				await chats.set(await this.getChats()); | ||||
| 				return chat; | ||||
| 			}, | ||||
| 			deleteChatById: async function (id) { | ||||
| 				if ($chatId === id) { | ||||
| 					goto('/'); | ||||
| 					await chatId.set(uuidv4()); | ||||
| 				} | ||||
| 
 | ||||
| 				await deleteChatById(localStorage.token, id); | ||||
| 				await chats.set(await this.getChats()); | ||||
| 			}, | ||||
| 
 | ||||
| 			deleteAllChat: async function () { | ||||
| 				const tx = this.db.transaction('chats', 'readwrite'); | ||||
| 				await Promise.all([tx.store.clear(), tx.done]); | ||||
| 				await chats.set(await this.getChats()); | ||||
| 			}, | ||||
| 			exportChats: async function () { | ||||
| 				let chats = await this.db.getAllFromIndex('chats', 'timestamp'); | ||||
| 				chats = chats.map((item, idx) => chats[chats.length - 1 - idx]); | ||||
| 				return chats; | ||||
| 			}, | ||||
| 			importChats: async function (_chats) { | ||||
| 				for (const chat of _chats) { | ||||
| 					console.log(chat); | ||||
| 					await this.addChat(chat); | ||||
| 				} | ||||
| 				await chats.set(await this.getChats()); | ||||
| 			} | ||||
| 		}; | ||||
| 	}; | ||||
| 
 | ||||
| 	const setOllamaVersion = async () => { | ||||
| 		const version = await getOllamaVersion( | ||||
| 			$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL, | ||||
| 			localStorage.token | ||||
| 		).catch((error) => { | ||||
| 			toast.error(error); | ||||
| 			return '0'; | ||||
| 		}); | ||||
| 
 | ||||
| 	const setOllamaVersion = async (version: string = '') => { | ||||
| 		if (version === '') { | ||||
| 			version = await getOllamaVersion( | ||||
| 				$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL, | ||||
| 				localStorage.token | ||||
| 			).catch((error) => { | ||||
| 				return '0'; | ||||
| 			}); | ||||
| 		} | ||||
| 		await info.set({ ...$info, ollama: { version: version } }); | ||||
| 
 | ||||
| 		if ( | ||||
| 			version.localeCompare(requiredOllamaVersion, undefined, { | ||||
| 			version.localeCompare(REQUIRED_OLLAMA_VERSION, undefined, { | ||||
| 				numeric: true, | ||||
| 				sensitivity: 'case', | ||||
| 				caseFirst: 'upper' | ||||
|  | @ -151,19 +59,18 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	onMount(async () => { | ||||
| 		if ($config && $user === undefined) { | ||||
| 		if ($user === undefined) { | ||||
| 			await goto('/auth'); | ||||
| 		} | ||||
| 
 | ||||
| 		await settings.set(JSON.parse(localStorage.getItem('settings') ?? '{}')); | ||||
| 		await models.set(await getModels()); | ||||
| 
 | ||||
| 		await modelfiles.set(JSON.parse(localStorage.getItem('modelfiles') ?? '[]')); | ||||
| 
 | ||||
| 		modelfiles.subscribe(async () => {}); | ||||
| 		modelfiles.subscribe(async () => { | ||||
| 			// should fetch models | ||||
| 		}); | ||||
| 
 | ||||
| 		let _db = await getDB(); | ||||
| 		await db.set(_db); | ||||
| 		await setOllamaVersion(); | ||||
| 
 | ||||
| 		await tick(); | ||||
|  | @ -214,7 +121,7 @@ | |||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		{:else if ($info?.ollama?.version ?? '0').localeCompare( requiredOllamaVersion, undefined, { numeric: true, sensitivity: 'case', caseFirst: 'upper' } ) < 0} | ||||
| 		{:else if ($info?.ollama?.version ?? '0').localeCompare( REQUIRED_OLLAMA_VERSION, undefined, { numeric: true, sensitivity: 'case', caseFirst: 'upper' } ) < 0} | ||||
| 			<div class="absolute w-full h-full flex z-50"> | ||||
| 				<div | ||||
| 					class="absolute rounded-xl w-full h-full backdrop-blur bg-gray-900/60 flex justify-center" | ||||
|  | @ -231,15 +138,15 @@ | |||
| 								/>We've detected either a connection hiccup or observed that you're using an older | ||||
| 								version. Ensure you're on the latest Ollama version | ||||
| 								<br class=" hidden sm:flex" />(version | ||||
| 								<span class=" dark:text-white font-medium">{requiredOllamaVersion} or higher</span>) | ||||
| 								or check your connection. | ||||
| 								<span class=" dark:text-white font-medium">{REQUIRED_OLLAMA_VERSION} or higher</span | ||||
| 								>) or check your connection. | ||||
| 							</div> | ||||
| 
 | ||||
| 							<div class=" mt-6 mx-auto relative group w-fit"> | ||||
| 								<button | ||||
| 									class="relative z-20 flex px-5 py-2 rounded-full bg-gray-100 hover:bg-gray-200 transition font-medium text-sm" | ||||
| 									on:click={async () => { | ||||
| 										await setOllamaVersion(await getOllamaVersion()); | ||||
| 										await setOllamaVersion(); | ||||
| 									}} | ||||
| 								> | ||||
| 									Check Again | ||||
|  | @ -248,7 +155,7 @@ | |||
| 								<button | ||||
| 									class="text-xs text-center w-full mt-2 text-gray-400 underline" | ||||
| 									on:click={async () => { | ||||
| 										await setOllamaVersion(requiredOllamaVersion); | ||||
| 										await setOllamaVersion(REQUIRED_OLLAMA_VERSION); | ||||
| 									}}>Close</button | ||||
| 								> | ||||
| 							</div> | ||||
|  |  | |||
|  | @ -2,23 +2,27 @@ | |||
| 	import { v4 as uuidv4 } from 'uuid'; | ||||
| 	import toast from 'svelte-french-toast'; | ||||
| 
 | ||||
| 	import { onDestroy, onMount, tick } from 'svelte'; | ||||
| 	import { onMount, tick } from 'svelte'; | ||||
| 	import { goto } from '$app/navigation'; | ||||
| 	import { page } from '$app/stores'; | ||||
| 
 | ||||
| 	import { config, models, modelfiles, user, settings, db, chats, chatId } from '$lib/stores'; | ||||
| 	import { models, modelfiles, user, settings, db, chats, chatId } from '$lib/stores'; | ||||
| 	import { OLLAMA_API_BASE_URL } from '$lib/constants'; | ||||
| 	import { splitStream } from '$lib/utils'; | ||||
| 
 | ||||
| 	import { generateChatCompletion, generateTitle } from '$lib/apis/ollama'; | ||||
| 	import { copyToClipboard, splitStream } from '$lib/utils'; | ||||
| 
 | ||||
| 	import MessageInput from '$lib/components/chat/MessageInput.svelte'; | ||||
| 	import Messages from '$lib/components/chat/Messages.svelte'; | ||||
| 	import ModelSelector from '$lib/components/chat/ModelSelector.svelte'; | ||||
| 	import Navbar from '$lib/components/layout/Navbar.svelte'; | ||||
| 	import { createNewChat, getChatList, updateChatById } from '$lib/apis/chats'; | ||||
| 
 | ||||
| 	let stopResponseFlag = false; | ||||
| 	let autoScroll = true; | ||||
| 
 | ||||
| 	let selectedModels = ['']; | ||||
| 
 | ||||
| 	let selectedModelfile = null; | ||||
| 	$: selectedModelfile = | ||||
| 		selectedModels.length === 1 && | ||||
|  | @ -83,41 +87,6 @@ | |||
| 		}); | ||||
| 	}; | ||||
| 
 | ||||
| 	const copyToClipboard = (text) => { | ||||
| 		if (!navigator.clipboard) { | ||||
| 			var textArea = document.createElement('textarea'); | ||||
| 			textArea.value = text; | ||||
| 
 | ||||
| 			// Avoid scrolling to bottom | ||||
| 			textArea.style.top = '0'; | ||||
| 			textArea.style.left = '0'; | ||||
| 			textArea.style.position = 'fixed'; | ||||
| 
 | ||||
| 			document.body.appendChild(textArea); | ||||
| 			textArea.focus(); | ||||
| 			textArea.select(); | ||||
| 
 | ||||
| 			try { | ||||
| 				var successful = document.execCommand('copy'); | ||||
| 				var msg = successful ? 'successful' : 'unsuccessful'; | ||||
| 				console.log('Fallback: Copying text command was ' + msg); | ||||
| 			} catch (err) { | ||||
| 				console.error('Fallback: Oops, unable to copy', err); | ||||
| 			} | ||||
| 
 | ||||
| 			document.body.removeChild(textArea); | ||||
| 			return; | ||||
| 		} | ||||
| 		navigator.clipboard.writeText(text).then( | ||||
| 			function () { | ||||
| 				console.log('Async: Copying to clipboard was successful!'); | ||||
| 			}, | ||||
| 			function (err) { | ||||
| 				console.error('Async: Could not copy text: ', err); | ||||
| 			} | ||||
| 		); | ||||
| 	}; | ||||
| 
 | ||||
| 	////////////////////////// | ||||
| 	// Ollama functions | ||||
| 	////////////////////////// | ||||
|  | @ -135,11 +104,11 @@ | |||
| 			}) | ||||
| 		); | ||||
| 
 | ||||
| 		await chats.set(await $db.getChats()); | ||||
| 		await chats.set(await getChatList(localStorage.token)); | ||||
| 	}; | ||||
| 
 | ||||
| 	const sendPromptOllama = async (model, userPrompt, parentId, _chatId) => { | ||||
| 		console.log('sendPromptOllama'); | ||||
| 		// Create response message | ||||
| 		let responseMessageId = uuidv4(); | ||||
| 		let responseMessage = { | ||||
| 			parentId: parentId, | ||||
|  | @ -150,8 +119,11 @@ | |||
| 			model: model | ||||
| 		}; | ||||
| 
 | ||||
| 		// Add message to history and Set currentId to messageId | ||||
| 		history.messages[responseMessageId] = responseMessage; | ||||
| 		history.currentId = responseMessageId; | ||||
| 
 | ||||
| 		// Append messageId to childrenIds of parent message | ||||
| 		if (parentId !== null) { | ||||
| 			history.messages[parentId].childrenIds = [ | ||||
| 				...history.messages[parentId].childrenIds, | ||||
|  | @ -159,17 +131,16 @@ | |||
| 			]; | ||||
| 		} | ||||
| 
 | ||||
| 		// Wait until history/message have been updated | ||||
| 		await tick(); | ||||
| 
 | ||||
| 		// Scroll down | ||||
| 		window.scrollTo({ top: document.body.scrollHeight }); | ||||
| 
 | ||||
| 		const res = await fetch(`${$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL}/chat`, { | ||||
| 			method: 'POST', | ||||
| 			headers: { | ||||
| 				'Content-Type': 'text/event-stream', | ||||
| 				...($settings.authHeader && { Authorization: $settings.authHeader }), | ||||
| 				...($user && { Authorization: `Bearer ${localStorage.token}` }) | ||||
| 			}, | ||||
| 			body: JSON.stringify({ | ||||
| 		const res = await generateChatCompletion( | ||||
| 			$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL, | ||||
| 			localStorage.token, | ||||
| 			{ | ||||
| 				model: model, | ||||
| 				messages: [ | ||||
| 					$settings.system | ||||
|  | @ -191,20 +162,11 @@ | |||
| 						}) | ||||
| 					})), | ||||
| 				options: { | ||||
| 					seed: $settings.seed ?? undefined, | ||||
| 					temperature: $settings.temperature ?? undefined, | ||||
| 					repeat_penalty: $settings.repeat_penalty ?? undefined, | ||||
| 					top_k: $settings.top_k ?? undefined, | ||||
| 					top_p: $settings.top_p ?? undefined, | ||||
| 					num_ctx: $settings.num_ctx ?? undefined, | ||||
| 					...($settings.options ?? {}) | ||||
| 				}, | ||||
| 				format: $settings.requestFormat ?? undefined | ||||
| 			}) | ||||
| 		}).catch((err) => { | ||||
| 			console.log(err); | ||||
| 			return null; | ||||
| 		}); | ||||
| 			} | ||||
| 		); | ||||
| 
 | ||||
| 		if (res && res.ok) { | ||||
| 			const reader = res.body | ||||
|  | @ -296,23 +258,11 @@ | |||
| 			} | ||||
| 
 | ||||
| 			if ($chatId == _chatId) { | ||||
| 				chat = await $db.updateChatById(_chatId, { | ||||
| 					...chat.chat, | ||||
| 					title: title === '' ? 'New Chat' : title, | ||||
| 					models: selectedModels, | ||||
| 					system: $settings.system ?? undefined, | ||||
| 					options: { | ||||
| 						seed: $settings.seed ?? undefined, | ||||
| 						temperature: $settings.temperature ?? undefined, | ||||
| 						repeat_penalty: $settings.repeat_penalty ?? undefined, | ||||
| 						top_k: $settings.top_k ?? undefined, | ||||
| 						top_p: $settings.top_p ?? undefined, | ||||
| 						num_ctx: $settings.num_ctx ?? undefined, | ||||
| 						...($settings.options ?? {}) | ||||
| 					}, | ||||
| 				chat = await updateChatById(localStorage.token, _chatId, { | ||||
| 					messages: messages, | ||||
| 					history: history | ||||
| 				}); | ||||
| 				await chats.set(await getChatList(localStorage.token)); | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (res !== null) { | ||||
|  | @ -338,6 +288,7 @@ | |||
| 
 | ||||
| 		stopResponseFlag = false; | ||||
| 		await tick(); | ||||
| 
 | ||||
| 		if (autoScroll) { | ||||
| 			window.scrollTo({ top: document.body.scrollHeight }); | ||||
| 		} | ||||
|  | @ -483,23 +434,11 @@ | |||
| 					} | ||||
| 
 | ||||
| 					if ($chatId == _chatId) { | ||||
| 						chat = await $db.updateChatById(_chatId, { | ||||
| 							...chat.chat, | ||||
| 							title: title === '' ? 'New Chat' : title, | ||||
| 							models: selectedModels, | ||||
| 							system: $settings.system ?? undefined, | ||||
| 							options: { | ||||
| 								seed: $settings.seed ?? undefined, | ||||
| 								temperature: $settings.temperature ?? undefined, | ||||
| 								repeat_penalty: $settings.repeat_penalty ?? undefined, | ||||
| 								top_k: $settings.top_k ?? undefined, | ||||
| 								top_p: $settings.top_p ?? undefined, | ||||
| 								num_ctx: $settings.num_ctx ?? undefined, | ||||
| 								...($settings.options ?? {}) | ||||
| 							}, | ||||
| 						chat = await updateChatById(localStorage.token, _chatId, { | ||||
| 							messages: messages, | ||||
| 							history: history | ||||
| 						}); | ||||
| 						await chats.set(await getChatList(localStorage.token)); | ||||
| 					} | ||||
| 				} else { | ||||
| 					if (res !== null) { | ||||
|  | @ -549,10 +488,13 @@ | |||
| 		if (selectedModels.includes('')) { | ||||
| 			toast.error('Model not selected'); | ||||
| 		} else if (messages.length != 0 && messages.at(-1).done != true) { | ||||
| 			// Response not done | ||||
| 			console.log('wait'); | ||||
| 		} else { | ||||
| 			// Reset chat message textarea height | ||||
| 			document.getElementById('chat-textarea').style.height = ''; | ||||
| 
 | ||||
| 			// Create user message | ||||
| 			let userMessageId = uuidv4(); | ||||
| 			let userMessage = { | ||||
| 				id: userMessageId, | ||||
|  | @ -563,47 +505,42 @@ | |||
| 				files: files.length > 0 ? files : undefined | ||||
| 			}; | ||||
| 
 | ||||
| 			// Add message to history and Set currentId to messageId | ||||
| 			history.messages[userMessageId] = userMessage; | ||||
| 			history.currentId = userMessageId; | ||||
| 
 | ||||
| 			// Append messageId to childrenIds of parent message | ||||
| 			if (messages.length !== 0) { | ||||
| 				history.messages[messages.at(-1).id].childrenIds.push(userMessageId); | ||||
| 			} | ||||
| 
 | ||||
| 			history.messages[userMessageId] = userMessage; | ||||
| 			history.currentId = userMessageId; | ||||
| 
 | ||||
| 			// Wait until history/message have been updated | ||||
| 			await tick(); | ||||
| 
 | ||||
| 			// Create new chat if only one message in messages | ||||
| 			if (messages.length == 1) { | ||||
| 				chat = await $db.createNewChat({ | ||||
| 				chat = await createNewChat(localStorage.token, { | ||||
| 					id: $chatId, | ||||
| 					title: 'New Chat', | ||||
| 					models: selectedModels, | ||||
| 					system: $settings.system ?? undefined, | ||||
| 					options: { | ||||
| 						seed: $settings.seed ?? undefined, | ||||
| 						temperature: $settings.temperature ?? undefined, | ||||
| 						repeat_penalty: $settings.repeat_penalty ?? undefined, | ||||
| 						top_k: $settings.top_k ?? undefined, | ||||
| 						top_p: $settings.top_p ?? undefined, | ||||
| 						num_ctx: $settings.num_ctx ?? undefined, | ||||
| 						...($settings.options ?? {}) | ||||
| 					}, | ||||
| 					messages: messages, | ||||
| 					history: history | ||||
| 					history: history, | ||||
| 					timestamp: Date.now() | ||||
| 				}); | ||||
| 
 | ||||
| 				console.log(chat); | ||||
| 
 | ||||
| 				await chats.set(await getChatList(localStorage.token)); | ||||
| 				await chatId.set(chat.id); | ||||
| 				await tick(); | ||||
| 			} | ||||
| 
 | ||||
| 			// Reset chat input textarea | ||||
| 			prompt = ''; | ||||
| 			files = []; | ||||
| 
 | ||||
| 			setTimeout(() => { | ||||
| 				window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); | ||||
| 			}, 50); | ||||
| 
 | ||||
| 			// Send prompt | ||||
| 			await sendPrompt(userPrompt, userMessageId); | ||||
| 		} | ||||
| 	}; | ||||
|  | @ -614,9 +551,7 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	const regenerateResponse = async () => { | ||||
| 		const _chatId = JSON.parse(JSON.stringify($chatId)); | ||||
| 		console.log('regenerateResponse', _chatId); | ||||
| 
 | ||||
| 		console.log('regenerateResponse'); | ||||
| 		if (messages.length != 0 && messages.at(-1).done == true) { | ||||
| 			messages.splice(messages.length - 1, 1); | ||||
| 			messages = messages; | ||||
|  | @ -624,40 +559,21 @@ | |||
| 			let userMessage = messages.at(-1); | ||||
| 			let userPrompt = userMessage.content; | ||||
| 
 | ||||
| 			await sendPrompt(userPrompt, userMessage.id, _chatId); | ||||
| 			await sendPrompt(userPrompt, userMessage.id); | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	const generateChatTitle = async (_chatId, userPrompt) => { | ||||
| 		if ($settings.titleAutoGenerate ?? true) { | ||||
| 			console.log('generateChatTitle'); | ||||
| 			const title = await generateTitle( | ||||
| 				$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL, | ||||
| 				localStorage.token, | ||||
| 				selectedModels[0], | ||||
| 				userPrompt | ||||
| 			); | ||||
| 
 | ||||
| 			const res = await fetch(`${$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL}/generate`, { | ||||
| 				method: 'POST', | ||||
| 				headers: { | ||||
| 					'Content-Type': 'text/event-stream', | ||||
| 					...($user && { Authorization: `Bearer ${localStorage.token}` }) | ||||
| 				}, | ||||
| 				body: JSON.stringify({ | ||||
| 					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}`, | ||||
| 					stream: false | ||||
| 				}) | ||||
| 			}) | ||||
| 				.then(async (res) => { | ||||
| 					if (!res.ok) throw await res.json(); | ||||
| 					return res.json(); | ||||
| 				}) | ||||
| 				.catch((error) => { | ||||
| 					if ('detail' in error) { | ||||
| 						toast.error(error.detail); | ||||
| 					} | ||||
| 					console.log(error); | ||||
| 					return null; | ||||
| 				}); | ||||
| 
 | ||||
| 			if (res) { | ||||
| 				await setChatTitle(_chatId, res.response === '' ? 'New Chat' : res.response); | ||||
| 			if (title) { | ||||
| 				await setChatTitle(_chatId, title); | ||||
| 			} | ||||
| 		} else { | ||||
| 			await setChatTitle(_chatId, `${userPrompt}`); | ||||
|  | @ -665,10 +581,12 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	const setChatTitle = async (_chatId, _title) => { | ||||
| 		chat = await $db.updateChatById(_chatId, { ...chat.chat, title: _title }); | ||||
| 		if (_chatId === $chatId) { | ||||
| 			title = _title; | ||||
| 		} | ||||
| 
 | ||||
| 		chat = await updateChatById(localStorage.token, _chatId, { title: _title }); | ||||
| 		await chats.set(await getChatList(localStorage.token)); | ||||
| 	}; | ||||
| </script> | ||||
| 
 | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ | |||
| 	import ModelSelector from '$lib/components/chat/ModelSelector.svelte'; | ||||
| 	import Navbar from '$lib/components/layout/Navbar.svelte'; | ||||
| 	import { page } from '$app/stores'; | ||||
| 	import { createNewChat, getChatById, getChatList } from '$lib/apis/chats'; | ||||
| 
 | ||||
| 	let loaded = false; | ||||
| 	let stopResponseFlag = false; | ||||
|  | @ -70,7 +71,7 @@ | |||
| 
 | ||||
| 	const loadChat = async () => { | ||||
| 		await chatId.set($page.params.id); | ||||
| 		chat = await $db.getChatById($chatId); | ||||
| 		chat = await getChatById(localStorage.token, $chatId); | ||||
| 
 | ||||
| 		const chatContent = chat.chat; | ||||
| 
 | ||||
|  | @ -159,11 +160,11 @@ | |||
| 			}) | ||||
| 		); | ||||
| 
 | ||||
| 		await chats.set(await $db.getChats()); | ||||
| 		await chats.set(await getChatList(localStorage.token)); | ||||
| 	}; | ||||
| 
 | ||||
| 	const sendPromptOllama = async (model, userPrompt, parentId, _chatId) => { | ||||
| 		console.log('sendPromptOllama'); | ||||
| 		// Create response message | ||||
| 		let responseMessageId = uuidv4(); | ||||
| 		let responseMessage = { | ||||
| 			parentId: parentId, | ||||
|  | @ -174,8 +175,11 @@ | |||
| 			model: model | ||||
| 		}; | ||||
| 
 | ||||
| 		// Add message to history and Set currentId to messageId | ||||
| 		history.messages[responseMessageId] = responseMessage; | ||||
| 		history.currentId = responseMessageId; | ||||
| 
 | ||||
| 		// Append messageId to childrenIds of parent message | ||||
| 		if (parentId !== null) { | ||||
| 			history.messages[parentId].childrenIds = [ | ||||
| 				...history.messages[parentId].childrenIds, | ||||
|  | @ -183,17 +187,16 @@ | |||
| 			]; | ||||
| 		} | ||||
| 
 | ||||
| 		// Wait until history/message have been updated | ||||
| 		await tick(); | ||||
| 
 | ||||
| 		// Scroll down | ||||
| 		window.scrollTo({ top: document.body.scrollHeight }); | ||||
| 
 | ||||
| 		const res = await fetch(`${$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL}/chat`, { | ||||
| 			method: 'POST', | ||||
| 			headers: { | ||||
| 				'Content-Type': 'text/event-stream', | ||||
| 				...($settings.authHeader && { Authorization: $settings.authHeader }), | ||||
| 				...($user && { Authorization: `Bearer ${localStorage.token}` }) | ||||
| 			}, | ||||
| 			body: JSON.stringify({ | ||||
| 		const res = await generateChatCompletion( | ||||
| 			$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL, | ||||
| 			localStorage.token, | ||||
| 			{ | ||||
| 				model: model, | ||||
| 				messages: [ | ||||
| 					$settings.system | ||||
|  | @ -215,20 +218,11 @@ | |||
| 						}) | ||||
| 					})), | ||||
| 				options: { | ||||
| 					seed: $settings.seed ?? undefined, | ||||
| 					temperature: $settings.temperature ?? undefined, | ||||
| 					repeat_penalty: $settings.repeat_penalty ?? undefined, | ||||
| 					top_k: $settings.top_k ?? undefined, | ||||
| 					top_p: $settings.top_p ?? undefined, | ||||
| 					num_ctx: $settings.num_ctx ?? undefined, | ||||
| 					...($settings.options ?? {}) | ||||
| 				}, | ||||
| 				format: $settings.requestFormat ?? undefined | ||||
| 			}) | ||||
| 		}).catch((err) => { | ||||
| 			console.log(err); | ||||
| 			return null; | ||||
| 		}); | ||||
| 			} | ||||
| 		); | ||||
| 
 | ||||
| 		if (res && res.ok) { | ||||
| 			const reader = res.body | ||||
|  | @ -320,23 +314,11 @@ | |||
| 			} | ||||
| 
 | ||||
| 			if ($chatId == _chatId) { | ||||
| 				chat = await $db.updateChatById(_chatId, { | ||||
| 					...chat.chat, | ||||
| 					title: title === '' ? 'New Chat' : title, | ||||
| 					models: selectedModels, | ||||
| 					system: $settings.system ?? undefined, | ||||
| 					options: { | ||||
| 						seed: $settings.seed ?? undefined, | ||||
| 						temperature: $settings.temperature ?? undefined, | ||||
| 						repeat_penalty: $settings.repeat_penalty ?? undefined, | ||||
| 						top_k: $settings.top_k ?? undefined, | ||||
| 						top_p: $settings.top_p ?? undefined, | ||||
| 						num_ctx: $settings.num_ctx ?? undefined, | ||||
| 						...($settings.options ?? {}) | ||||
| 					}, | ||||
| 				chat = await updateChatById(localStorage.token, _chatId, { | ||||
| 					messages: messages, | ||||
| 					history: history | ||||
| 				}); | ||||
| 				await chats.set(await getChatList(localStorage.token)); | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (res !== null) { | ||||
|  | @ -362,6 +344,7 @@ | |||
| 
 | ||||
| 		stopResponseFlag = false; | ||||
| 		await tick(); | ||||
| 
 | ||||
| 		if (autoScroll) { | ||||
| 			window.scrollTo({ top: document.body.scrollHeight }); | ||||
| 		} | ||||
|  | @ -507,23 +490,11 @@ | |||
| 					} | ||||
| 
 | ||||
| 					if ($chatId == _chatId) { | ||||
| 						chat = await $db.updateChatById(_chatId, { | ||||
| 							...chat.chat, | ||||
| 							title: title === '' ? 'New Chat' : title, | ||||
| 							models: selectedModels, | ||||
| 							system: $settings.system ?? undefined, | ||||
| 							options: { | ||||
| 								seed: $settings.seed ?? undefined, | ||||
| 								temperature: $settings.temperature ?? undefined, | ||||
| 								repeat_penalty: $settings.repeat_penalty ?? undefined, | ||||
| 								top_k: $settings.top_k ?? undefined, | ||||
| 								top_p: $settings.top_p ?? undefined, | ||||
| 								num_ctx: $settings.num_ctx ?? undefined, | ||||
| 								...($settings.options ?? {}) | ||||
| 							}, | ||||
| 						chat = await updateChatById(localStorage.token, _chatId, { | ||||
| 							messages: messages, | ||||
| 							history: history | ||||
| 						}); | ||||
| 						await chats.set(await getChatList(localStorage.token)); | ||||
| 					} | ||||
| 				} else { | ||||
| 					if (res !== null) { | ||||
|  | @ -573,10 +544,13 @@ | |||
| 		if (selectedModels.includes('')) { | ||||
| 			toast.error('Model not selected'); | ||||
| 		} else if (messages.length != 0 && messages.at(-1).done != true) { | ||||
| 			// Response not done | ||||
| 			console.log('wait'); | ||||
| 		} else { | ||||
| 			// Reset chat message textarea height | ||||
| 			document.getElementById('chat-textarea').style.height = ''; | ||||
| 
 | ||||
| 			// Create user message | ||||
| 			let userMessageId = uuidv4(); | ||||
| 			let userMessage = { | ||||
| 				id: userMessageId, | ||||
|  | @ -587,47 +561,42 @@ | |||
| 				files: files.length > 0 ? files : undefined | ||||
| 			}; | ||||
| 
 | ||||
| 			// Add message to history and Set currentId to messageId | ||||
| 			history.messages[userMessageId] = userMessage; | ||||
| 			history.currentId = userMessageId; | ||||
| 
 | ||||
| 			// Append messageId to childrenIds of parent message | ||||
| 			if (messages.length !== 0) { | ||||
| 				history.messages[messages.at(-1).id].childrenIds.push(userMessageId); | ||||
| 			} | ||||
| 
 | ||||
| 			history.messages[userMessageId] = userMessage; | ||||
| 			history.currentId = userMessageId; | ||||
| 
 | ||||
| 			// Wait until history/message have been updated | ||||
| 			await tick(); | ||||
| 
 | ||||
| 			// Create new chat if only one message in messages | ||||
| 			if (messages.length == 1) { | ||||
| 				chat = await $db.createNewChat({ | ||||
| 				chat = await createNewChat(localStorage.token, { | ||||
| 					id: $chatId, | ||||
| 					title: 'New Chat', | ||||
| 					models: selectedModels, | ||||
| 					system: $settings.system ?? undefined, | ||||
| 					options: { | ||||
| 						seed: $settings.seed ?? undefined, | ||||
| 						temperature: $settings.temperature ?? undefined, | ||||
| 						repeat_penalty: $settings.repeat_penalty ?? undefined, | ||||
| 						top_k: $settings.top_k ?? undefined, | ||||
| 						top_p: $settings.top_p ?? undefined, | ||||
| 						num_ctx: $settings.num_ctx ?? undefined, | ||||
| 						...($settings.options ?? {}) | ||||
| 					}, | ||||
| 					messages: messages, | ||||
| 					history: history | ||||
| 					history: history, | ||||
| 					timestamp: Date.now() | ||||
| 				}); | ||||
| 
 | ||||
| 				console.log(chat); | ||||
| 
 | ||||
| 				await chats.set(await getChatList(localStorage.token)); | ||||
| 				await chatId.set(chat.id); | ||||
| 				await tick(); | ||||
| 			} | ||||
| 
 | ||||
| 			// Reset chat input textarea | ||||
| 			prompt = ''; | ||||
| 			files = []; | ||||
| 
 | ||||
| 			setTimeout(() => { | ||||
| 				window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); | ||||
| 			}, 50); | ||||
| 
 | ||||
| 			// Send prompt | ||||
| 			await sendPrompt(userPrompt, userMessageId); | ||||
| 		} | ||||
| 	}; | ||||
|  | @ -638,9 +607,7 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	const regenerateResponse = async () => { | ||||
| 		const _chatId = JSON.parse(JSON.stringify($chatId)); | ||||
| 		console.log('regenerateResponse', _chatId); | ||||
| 
 | ||||
| 		console.log('regenerateResponse'); | ||||
| 		if (messages.length != 0 && messages.at(-1).done == true) { | ||||
| 			messages.splice(messages.length - 1, 1); | ||||
| 			messages = messages; | ||||
|  | @ -648,41 +615,21 @@ | |||
| 			let userMessage = messages.at(-1); | ||||
| 			let userPrompt = userMessage.content; | ||||
| 
 | ||||
| 			await sendPrompt(userPrompt, userMessage.id, _chatId); | ||||
| 			await sendPrompt(userPrompt, userMessage.id); | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	const generateChatTitle = async (_chatId, userPrompt) => { | ||||
| 		if ($settings.titleAutoGenerate ?? true) { | ||||
| 			console.log('generateChatTitle'); | ||||
| 			const title = await generateTitle( | ||||
| 				$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL, | ||||
| 				localStorage.token, | ||||
| 				selectedModels[0], | ||||
| 				userPrompt | ||||
| 			); | ||||
| 
 | ||||
| 			const res = await fetch(`${$settings?.API_BASE_URL ?? OLLAMA_API_BASE_URL}/generate`, { | ||||
| 				method: 'POST', | ||||
| 				headers: { | ||||
| 					'Content-Type': 'text/event-stream', | ||||
| 					...($settings.authHeader && { Authorization: $settings.authHeader }), | ||||
| 					...($user && { Authorization: `Bearer ${localStorage.token}` }) | ||||
| 				}, | ||||
| 				body: JSON.stringify({ | ||||
| 					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}`, | ||||
| 					stream: false | ||||
| 				}) | ||||
| 			}) | ||||
| 				.then(async (res) => { | ||||
| 					if (!res.ok) throw await res.json(); | ||||
| 					return res.json(); | ||||
| 				}) | ||||
| 				.catch((error) => { | ||||
| 					if ('detail' in error) { | ||||
| 						toast.error(error.detail); | ||||
| 					} | ||||
| 					console.log(error); | ||||
| 					return null; | ||||
| 				}); | ||||
| 
 | ||||
| 			if (res) { | ||||
| 				await setChatTitle(_chatId, res.response === '' ? 'New Chat' : res.response); | ||||
| 			if (title) { | ||||
| 				await setChatTitle(_chatId, title); | ||||
| 			} | ||||
| 		} else { | ||||
| 			await setChatTitle(_chatId, `${userPrompt}`); | ||||
|  | @ -690,13 +637,12 @@ | |||
| 	}; | ||||
| 
 | ||||
| 	const setChatTitle = async (_chatId, _title) => { | ||||
| 		chat = await $db.updateChatById(_chatId, { | ||||
| 			...chat.chat, | ||||
| 			title: _title | ||||
| 		}); | ||||
| 		if (_chatId === $chatId) { | ||||
| 			title = _title; | ||||
| 		} | ||||
| 
 | ||||
| 		chat = await updateChatById(localStorage.token, _chatId, { title: _title }); | ||||
| 		await chats.set(await getChatList(localStorage.token)); | ||||
| 	}; | ||||
| </script> | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek