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); | ||||
| 	}; | ||||
| 
 | ||||
| 	const confirmEditResponseMessage = async (messageId, content) => { | ||||
| 		history.messages[messageId].originalContent = history.messages[messageId].content; | ||||
| 		history.messages[messageId].content = content; | ||||
| 
 | ||||
| 	const updateChatMessages = async () => { | ||||
| 		await tick(); | ||||
| 
 | ||||
| 		await updateChatById(localStorage.token, chatId, { | ||||
| 			messages: messages, | ||||
| 			history: history | ||||
|  | @ -121,15 +117,20 @@ | |||
| 		await chats.set(await getChatList(localStorage.token)); | ||||
| 	}; | ||||
| 
 | ||||
| 	const rateMessage = async (messageId, rating) => { | ||||
| 		history.messages[messageId].rating = rating; | ||||
| 		await tick(); | ||||
| 		await updateChatById(localStorage.token, chatId, { | ||||
| 			messages: messages, | ||||
| 			history: history | ||||
| 		}); | ||||
| 	const confirmEditResponseMessage = async (messageId, content) => { | ||||
| 		history.messages[messageId].originalContent = history.messages[messageId].content; | ||||
| 		history.messages[messageId].content = content; | ||||
| 
 | ||||
| 		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) => { | ||||
|  | @ -338,6 +339,7 @@ | |||
| 								siblings={history.messages[message.parentId]?.childrenIds ?? []} | ||||
| 								isLastMessage={messageIdx + 1 === messages.length} | ||||
| 								{readOnly} | ||||
| 								{updateChatMessages} | ||||
| 								{confirmEditResponseMessage} | ||||
| 								{showPreviousMessage} | ||||
| 								{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 { WEBUI_BASE_URL } from '$lib/constants'; | ||||
| 	import Tooltip from '$lib/components/common/Tooltip.svelte'; | ||||
| 	import RateComment from './RateComment.svelte'; | ||||
| 
 | ||||
| 	export let modelfiles = []; | ||||
| 	export let message; | ||||
|  | @ -39,6 +40,7 @@ | |||
| 
 | ||||
| 	export let readOnly = false; | ||||
| 
 | ||||
| 	export let updateChatMessages: Function; | ||||
| 	export let confirmEditResponseMessage: Function; | ||||
| 	export let showPreviousMessage: Function; | ||||
| 	export let showNextMessage: Function; | ||||
|  | @ -60,6 +62,8 @@ | |||
| 	let loadingSpeech = false; | ||||
| 	let generatingImage = false; | ||||
| 
 | ||||
| 	let showRateComment = false; | ||||
| 
 | ||||
| 	$: tokens = marked.lexer(sanitizeResponseContent(message.content)); | ||||
| 
 | ||||
| 	const renderer = new marked.Renderer(); | ||||
|  | @ -536,11 +540,13 @@ | |||
| 												<button | ||||
| 													class="{isLastMessage | ||||
| 														? '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' | ||||
| 														: ''} dark:hover:text-white hover:text-black transition" | ||||
| 													on:click={() => { | ||||
| 														rateMessage(message.id, 1); | ||||
| 														showRateComment = true; | ||||
| 													}} | ||||
| 												> | ||||
| 													<svg | ||||
|  | @ -563,11 +569,13 @@ | |||
| 												<button | ||||
| 													class="{isLastMessage | ||||
| 														? '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' | ||||
| 														: ''} dark:hover:text-white hover:text-black transition" | ||||
| 													on:click={() => { | ||||
| 														rateMessage(message.id, -1); | ||||
| 														showRateComment = true; | ||||
| 													}} | ||||
| 												> | ||||
| 													<svg | ||||
|  | @ -824,6 +832,16 @@ | |||
| 										{/if} | ||||
| 									</div> | ||||
| 								{/if} | ||||
| 
 | ||||
| 								{#if showRateComment} | ||||
| 									<RateComment | ||||
| 										bind:show={showRateComment} | ||||
| 										bind:message | ||||
| 										on:submit={() => { | ||||
| 											updateChatMessages(); | ||||
| 										}} | ||||
| 									/> | ||||
| 								{/if} | ||||
| 							</div> | ||||
| 						{/if} | ||||
| 					</div> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy J. Baek
						Timothy J. Baek