diff --git a/tools/server/webui/src/lib/agentic/openai-sse-client.ts b/tools/server/webui/src/lib/clients/openai-sse.ts similarity index 98% rename from tools/server/webui/src/lib/agentic/openai-sse-client.ts rename to tools/server/webui/src/lib/clients/openai-sse.ts index 8f9c2b8ac5..2de9533d1d 100644 --- a/tools/server/webui/src/lib/agentic/openai-sse-client.ts +++ b/tools/server/webui/src/lib/clients/openai-sse.ts @@ -5,7 +5,7 @@ import type { } from '$lib/types/api'; import type { ChatMessagePromptProgress, ChatMessageTimings } from '$lib/types/chat'; import { mergeToolCallDeltas, extractModelName } from '$lib/utils/chat-stream'; -import type { AgenticChatCompletionRequest } from './types'; +import type { AgenticChatCompletionRequest } from '$lib/types/agentic'; export type OpenAISseCallbacks = { onChunk?: (chunk: string) => void; diff --git a/tools/server/webui/src/lib/components/app/chat/ChatMessages/AgenticContent.svelte b/tools/server/webui/src/lib/components/app/chat/ChatMessages/AgenticContent.svelte index cb55c12327..f1f8b2362d 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatMessages/AgenticContent.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatMessages/AgenticContent.svelte @@ -14,7 +14,7 @@ } from '$lib/components/app'; import { config } from '$lib/stores/settings.svelte'; import { Wrench, Loader2 } from '@lucide/svelte'; - import { AgenticSectionType } from '$lib/types/agentic'; + import { AgenticSectionType } from '$lib/enums'; import { AGENTIC_TAGS, AGENTIC_REGEX } from '$lib/constants/agentic'; import { formatJsonPretty } from '$lib/utils/formatters'; @@ -38,16 +38,20 @@ const showToolCallInProgress = $derived(config().showToolCallInProgress as boolean); - function isExpanded(index: number, isPending: boolean): boolean { - if (showToolCallInProgress && isPending) { - return true; - } + function getDefaultExpanded(isPending: boolean): boolean { + return showToolCallInProgress && isPending; + } - return expandedStates[index] ?? showToolCallInProgress; + function isExpanded(index: number, isPending: boolean): boolean { + if (expandedStates[index] !== undefined) { + return expandedStates[index]; + } + return getDefaultExpanded(isPending); } function toggleExpanded(index: number, isPending: boolean) { - expandedStates[index] = !isExpanded(index, isPending); + const currentState = isExpanded(index, isPending); + expandedStates[index] = !currentState; } function parseAgenticContent(rawContent: string): AgenticSection[] { diff --git a/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessage.svelte b/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessage.svelte index 3ded592344..47bb81a6a7 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessage.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessage.svelte @@ -10,6 +10,7 @@ import { DatabaseService } from '$lib/services'; import { config } from '$lib/stores/settings.svelte'; import { SYSTEM_MESSAGE_PLACEHOLDER } from '$lib/constants/ui'; + import { MessageRole } from '$lib/enums'; import { copyToClipboard, isIMEComposing, formatMessageForClipboard } from '$lib/utils'; import ChatMessageAssistant from './ChatMessageAssistant.svelte'; import ChatMessageUser from './ChatMessageUser.svelte'; @@ -70,7 +71,7 @@ let textareaElement: HTMLTextAreaElement | undefined = $state(); let thinkingContent = $derived.by(() => { - if (message.role === 'assistant') { + if (message.role === MessageRole.ASSISTANT) { const trimmedThinking = message.thinking?.trim(); return trimmedThinking ? trimmedThinking : null; @@ -92,7 +93,7 @@ isEditing = false; // If canceling a new system message with placeholder content, remove it without deleting children - if (message.role === 'system') { + if (message.role === MessageRole.SYSTEM) { const conversationDeleted = await removeSystemPromptPlaceholder(message.id); if (conversationDeleted) { @@ -136,7 +137,7 @@ isEditing = true; // Clear temporary placeholder content for system messages editedContent = - message.role === 'system' && message.content === SYSTEM_MESSAGE_PLACEHOLDER + message.role === MessageRole.SYSTEM && message.content === SYSTEM_MESSAGE_PLACEHOLDER ? '' : message.content; textareaElement?.focus(); @@ -179,7 +180,7 @@ } async function handleSaveEdit() { - if (message.role === 'system') { + if (message.role === MessageRole.SYSTEM) { // System messages: update in place without branching const newContent = editedContent.trim(); @@ -198,7 +199,7 @@ if (index !== -1) { conversationsStore.updateMessageAtIndex(index, { content: newContent }); } - } else if (message.role === 'user') { + } else if (message.role === MessageRole.USER) { const finalExtras = await getMergedExtras(); onEditWithBranching?.(message, editedContent.trim(), finalExtras); } else { @@ -213,7 +214,7 @@ } async function handleSaveEditOnly() { - if (message.role === 'user') { + if (message.role === MessageRole.USER) { // For user messages, trim to avoid accidental whitespace const finalExtras = await getMergedExtras(); onEditUserMessagePreserveResponses?.(message, editedContent.trim(), finalExtras); @@ -240,7 +241,7 @@ } -{#if message.role === 'system'} +{#if message.role === MessageRole.SYSTEM} -{:else if message.role === 'user'} +{:else if message.role === MessageRole.USER} {/if} - {#if role === 'assistant' && onRegenerate} + {#if role === MessageRole.ASSISTANT && onRegenerate} onRegenerate()} /> {/if} - {#if role === 'assistant' && onContinue} + {#if role === MessageRole.ASSISTANT && onContinue} {/if} diff --git a/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageAssistant.svelte b/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageAssistant.svelte index f5c9a37bef..d36ea5aaa7 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageAssistant.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageAssistant.svelte @@ -17,6 +17,7 @@ import { Button } from '$lib/components/ui/button'; import { Checkbox } from '$lib/components/ui/checkbox'; import { INPUT_CLASSES } from '$lib/constants/css-classes'; + import { MessageRole } from '$lib/enums'; import Label from '$lib/components/ui/label/label.svelte'; import { config } from '$lib/stores/settings.svelte'; import { conversationsStore } from '$lib/stores/conversations.svelte'; @@ -245,7 +246,7 @@ {#if message.timestamp && !isEditing} {/if} diff --git a/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageUser.svelte b/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageUser.svelte index 0bf8cde390..5c301eb8b2 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageUser.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatMessages/ChatMessageUser.svelte @@ -4,6 +4,7 @@ import { config } from '$lib/stores/settings.svelte'; import ChatMessageActions from './ChatMessageActions.svelte'; import ChatMessageEditForm from './ChatMessageEditForm.svelte'; + import { MessageRole } from '$lib/enums'; interface Props { class?: string; @@ -156,7 +157,7 @@ {onShowDeleteDialogChange} {siblingInfo} {showDeleteDialog} - role="user" + role={MessageRole.USER} /> {/if} diff --git a/tools/server/webui/src/lib/components/app/dialogs/DialogMcpServersSettings.svelte b/tools/server/webui/src/lib/components/app/dialogs/DialogMcpServersSettings.svelte index 504c882d0f..5620417891 100644 --- a/tools/server/webui/src/lib/components/app/dialogs/DialogMcpServersSettings.svelte +++ b/tools/server/webui/src/lib/components/app/dialogs/DialogMcpServersSettings.svelte @@ -1,9 +1,8 @@