forked from open-webui/open-webui
		
	feat: better annotation
This commit is contained in:
		
							parent
							
								
									a649dc80c0
								
							
						
					
					
						commit
						e48cdf63d9
					
				
					 3 changed files with 152 additions and 15 deletions
				
			
		|  | @ -107,12 +107,8 @@ | ||||||
| 		await sendPrompt(userPrompt, userMessageId, chatId); | 		await sendPrompt(userPrompt, userMessageId, chatId); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	const confirmEditResponseMessage = async (messageId, content) => { | 	const updateChatMessages = async () => { | ||||||
| 		history.messages[messageId].originalContent = history.messages[messageId].content; |  | ||||||
| 		history.messages[messageId].content = content; |  | ||||||
| 
 |  | ||||||
| 		await tick(); | 		await tick(); | ||||||
| 
 |  | ||||||
| 		await updateChatById(localStorage.token, chatId, { | 		await updateChatById(localStorage.token, chatId, { | ||||||
| 			messages: messages, | 			messages: messages, | ||||||
| 			history: history | 			history: history | ||||||
|  | @ -121,15 +117,20 @@ | ||||||
| 		await chats.set(await getChatList(localStorage.token)); | 		await chats.set(await getChatList(localStorage.token)); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	const rateMessage = async (messageId, rating) => { | 	const confirmEditResponseMessage = async (messageId, content) => { | ||||||
| 		history.messages[messageId].rating = rating; | 		history.messages[messageId].originalContent = history.messages[messageId].content; | ||||||
| 		await tick(); | 		history.messages[messageId].content = content; | ||||||
| 		await updateChatById(localStorage.token, chatId, { |  | ||||||
| 			messages: messages, |  | ||||||
| 			history: history |  | ||||||
| 		}); |  | ||||||
| 
 | 
 | ||||||
| 		await chats.set(await getChatList(localStorage.token)); | 		await updateChatMessages(); | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	const rateMessage = async (messageId, rating) => { | ||||||
|  | 		history.messages[messageId].annotation = { | ||||||
|  | 			...history.messages[messageId].annotation, | ||||||
|  | 			rating: rating | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		await updateChatMessages(); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	const showPreviousMessage = async (message) => { | 	const showPreviousMessage = async (message) => { | ||||||
|  | @ -338,6 +339,7 @@ | ||||||
| 								siblings={history.messages[message.parentId]?.childrenIds ?? []} | 								siblings={history.messages[message.parentId]?.childrenIds ?? []} | ||||||
| 								isLastMessage={messageIdx + 1 === messages.length} | 								isLastMessage={messageIdx + 1 === messages.length} | ||||||
| 								{readOnly} | 								{readOnly} | ||||||
|  | 								{updateChatMessages} | ||||||
| 								{confirmEditResponseMessage} | 								{confirmEditResponseMessage} | ||||||
| 								{showPreviousMessage} | 								{showPreviousMessage} | ||||||
| 								{showNextMessage} | 								{showNextMessage} | ||||||
|  |  | ||||||
							
								
								
									
										117
									
								
								src/lib/components/chat/Messages/RateComment.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								src/lib/components/chat/Messages/RateComment.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,117 @@ | ||||||
|  | <script lang="ts"> | ||||||
|  | 	import { toast } from 'svelte-sonner'; | ||||||
|  | 
 | ||||||
|  | 	import { createEventDispatcher, onMount } from 'svelte'; | ||||||
|  | 
 | ||||||
|  | 	const dispatch = createEventDispatcher(); | ||||||
|  | 
 | ||||||
|  | 	export let show = false; | ||||||
|  | 	export let message; | ||||||
|  | 
 | ||||||
|  | 	const LIKE_REASONS = [ | ||||||
|  | 		`Accurate information`, | ||||||
|  | 		`Followed instructions perfectly`, | ||||||
|  | 		`Showcased creativity`, | ||||||
|  | 		`Positive attitude`, | ||||||
|  | 		`Attention to detail`, | ||||||
|  | 		`Thorough explanation`, | ||||||
|  | 		`Other` | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	const DISLIKE_REASONS = [ | ||||||
|  | 		`Don't like the style`, | ||||||
|  | 		`Not factually correct`, | ||||||
|  | 		`Didn't fully follow instructions`, | ||||||
|  | 		`Refused when it shouldn't have`, | ||||||
|  | 		`Being Lazy`, | ||||||
|  | 		`Other` | ||||||
|  | 	]; | ||||||
|  | 
 | ||||||
|  | 	let reasons = []; | ||||||
|  | 	let selectedReason = null; | ||||||
|  | 	let comment = ''; | ||||||
|  | 
 | ||||||
|  | 	$: if (message.annotation.rating === 1) { | ||||||
|  | 		reasons = LIKE_REASONS; | ||||||
|  | 	} else if (message.annotation.rating === -1) { | ||||||
|  | 		reasons = DISLIKE_REASONS; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	onMount(() => { | ||||||
|  | 		selectedReason = message.annotation.reason; | ||||||
|  | 		comment = message.annotation.comment; | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	const submitHandler = () => { | ||||||
|  | 		console.log('submitHandler'); | ||||||
|  | 
 | ||||||
|  | 		message.annotation.reason = selectedReason; | ||||||
|  | 		message.annotation.comment = comment; | ||||||
|  | 
 | ||||||
|  | 		dispatch('submit'); | ||||||
|  | 
 | ||||||
|  | 		toast.success('Thanks for your feedback!'); | ||||||
|  | 		show = false; | ||||||
|  | 	}; | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <div class=" my-2.5 rounded-xl px-4 py-3 border border-gray-850"> | ||||||
|  | 	<div class="flex justify-between items-center"> | ||||||
|  | 		<div class=" text-sm">Tell us more:</div> | ||||||
|  | 
 | ||||||
|  | 		<button | ||||||
|  | 			on:click={() => { | ||||||
|  | 				show = false; | ||||||
|  | 			}} | ||||||
|  | 		> | ||||||
|  | 			<svg | ||||||
|  | 				xmlns="http://www.w3.org/2000/svg" | ||||||
|  | 				fill="none" | ||||||
|  | 				viewBox="0 0 24 24" | ||||||
|  | 				stroke-width="1.5" | ||||||
|  | 				stroke="currentColor" | ||||||
|  | 				class="size-4" | ||||||
|  | 			> | ||||||
|  | 				<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" /> | ||||||
|  | 			</svg> | ||||||
|  | 		</button> | ||||||
|  | 	</div> | ||||||
|  | 
 | ||||||
|  | 	{#if reasons.length > 0} | ||||||
|  | 		<div class="flex flex-wrap gap-2 text-sm mt-2.5"> | ||||||
|  | 			{#each reasons as reason} | ||||||
|  | 				<button | ||||||
|  | 					class="px-3.5 py-1 border dark:border-gray-850 dark:hover:bg-gray-850 {selectedReason === | ||||||
|  | 					reason | ||||||
|  | 						? 'dark:bg-gray-800' | ||||||
|  | 						: ''} transition rounded-lg" | ||||||
|  | 					on:click={() => { | ||||||
|  | 						selectedReason = reason; | ||||||
|  | 					}} | ||||||
|  | 				> | ||||||
|  | 					{reason} | ||||||
|  | 				</button> | ||||||
|  | 			{/each} | ||||||
|  | 		</div> | ||||||
|  | 	{/if} | ||||||
|  | 
 | ||||||
|  | 	<div class="mt-2"> | ||||||
|  | 		<textarea | ||||||
|  | 			bind:value={comment} | ||||||
|  | 			class="w-full text-sm px-1 py-2 bg-transparent outline-none resize-none rounded-xl" | ||||||
|  | 			placeholder="Feel free to add specific details" | ||||||
|  | 			rows="2" | ||||||
|  | 		/> | ||||||
|  | 	</div> | ||||||
|  | 
 | ||||||
|  | 	<div class="mt-2 flex justify-end"> | ||||||
|  | 		<button | ||||||
|  | 			class=" bg-emerald-700 text-sm font-medium rounded-lg px-3.5 py-1.5" | ||||||
|  | 			on:click={() => { | ||||||
|  | 				submitHandler(); | ||||||
|  | 			}} | ||||||
|  | 		> | ||||||
|  | 			Submit | ||||||
|  | 		</button> | ||||||
|  | 	</div> | ||||||
|  | </div> | ||||||
|  | @ -30,6 +30,7 @@ | ||||||
| 	import Image from '$lib/components/common/Image.svelte'; | 	import Image from '$lib/components/common/Image.svelte'; | ||||||
| 	import { WEBUI_BASE_URL } from '$lib/constants'; | 	import { WEBUI_BASE_URL } from '$lib/constants'; | ||||||
| 	import Tooltip from '$lib/components/common/Tooltip.svelte'; | 	import Tooltip from '$lib/components/common/Tooltip.svelte'; | ||||||
|  | 	import RateComment from './RateComment.svelte'; | ||||||
| 
 | 
 | ||||||
| 	export let modelfiles = []; | 	export let modelfiles = []; | ||||||
| 	export let message; | 	export let message; | ||||||
|  | @ -39,6 +40,7 @@ | ||||||
| 
 | 
 | ||||||
| 	export let readOnly = false; | 	export let readOnly = false; | ||||||
| 
 | 
 | ||||||
|  | 	export let updateChatMessages: Function; | ||||||
| 	export let confirmEditResponseMessage: Function; | 	export let confirmEditResponseMessage: Function; | ||||||
| 	export let showPreviousMessage: Function; | 	export let showPreviousMessage: Function; | ||||||
| 	export let showNextMessage: Function; | 	export let showNextMessage: Function; | ||||||
|  | @ -60,6 +62,8 @@ | ||||||
| 	let loadingSpeech = false; | 	let loadingSpeech = false; | ||||||
| 	let generatingImage = false; | 	let generatingImage = false; | ||||||
| 
 | 
 | ||||||
|  | 	let showRateComment = false; | ||||||
|  | 
 | ||||||
| 	$: tokens = marked.lexer(sanitizeResponseContent(message.content)); | 	$: tokens = marked.lexer(sanitizeResponseContent(message.content)); | ||||||
| 
 | 
 | ||||||
| 	const renderer = new marked.Renderer(); | 	const renderer = new marked.Renderer(); | ||||||
|  | @ -536,11 +540,13 @@ | ||||||
| 												<button | 												<button | ||||||
| 													class="{isLastMessage | 													class="{isLastMessage | ||||||
| 														? 'visible' | 														? 'visible' | ||||||
| 														: 'invisible group-hover:visible'} p-1 rounded {message.rating === 1 | 														: 'invisible group-hover:visible'} p-1 rounded {message?.annotation | ||||||
|  | 														?.rating === 1 | ||||||
| 														? 'bg-gray-100 dark:bg-gray-800' | 														? 'bg-gray-100 dark:bg-gray-800' | ||||||
| 														: ''} dark:hover:text-white hover:text-black transition" | 														: ''} dark:hover:text-white hover:text-black transition" | ||||||
| 													on:click={() => { | 													on:click={() => { | ||||||
| 														rateMessage(message.id, 1); | 														rateMessage(message.id, 1); | ||||||
|  | 														showRateComment = true; | ||||||
| 													}} | 													}} | ||||||
| 												> | 												> | ||||||
| 													<svg | 													<svg | ||||||
|  | @ -563,11 +569,13 @@ | ||||||
| 												<button | 												<button | ||||||
| 													class="{isLastMessage | 													class="{isLastMessage | ||||||
| 														? 'visible' | 														? 'visible' | ||||||
| 														: 'invisible group-hover:visible'} p-1 rounded {message.rating === -1 | 														: 'invisible group-hover:visible'} p-1 rounded {message?.annotation | ||||||
|  | 														?.rating === -1 | ||||||
| 														? 'bg-gray-100 dark:bg-gray-800' | 														? 'bg-gray-100 dark:bg-gray-800' | ||||||
| 														: ''} dark:hover:text-white hover:text-black transition" | 														: ''} dark:hover:text-white hover:text-black transition" | ||||||
| 													on:click={() => { | 													on:click={() => { | ||||||
| 														rateMessage(message.id, -1); | 														rateMessage(message.id, -1); | ||||||
|  | 														showRateComment = true; | ||||||
| 													}} | 													}} | ||||||
| 												> | 												> | ||||||
| 													<svg | 													<svg | ||||||
|  | @ -824,6 +832,16 @@ | ||||||
| 										{/if} | 										{/if} | ||||||
| 									</div> | 									</div> | ||||||
| 								{/if} | 								{/if} | ||||||
|  | 
 | ||||||
|  | 								{#if showRateComment} | ||||||
|  | 									<RateComment | ||||||
|  | 										bind:show={showRateComment} | ||||||
|  | 										bind:message | ||||||
|  | 										on:submit={() => { | ||||||
|  | 											updateChatMessages(); | ||||||
|  | 										}} | ||||||
|  | 									/> | ||||||
|  | 								{/if} | ||||||
| 							</div> | 							</div> | ||||||
| 						{/if} | 						{/if} | ||||||
| 					</div> | 					</div> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek