refactor: Components imports/exports structure & documentation
This commit is contained in:
parent
b7d1de68c3
commit
c631e26a3f
|
|
@ -2,7 +2,7 @@
|
|||
import { Square } from '@lucide/svelte';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import {
|
||||
ChatFormActionFileAttachments,
|
||||
ChatFormActionAttachmentsDropdown,
|
||||
ChatFormActionRecord,
|
||||
ChatFormActionSubmit,
|
||||
DialogMcpServersSettings,
|
||||
|
|
@ -169,7 +169,7 @@
|
|||
|
||||
<div class="flex w-full items-center gap-3 {className}" style="container-type: inline-size">
|
||||
<div class="mr-auto flex items-center gap-2">
|
||||
<ChatFormActionFileAttachments
|
||||
<ChatFormActionAttachmentsDropdown
|
||||
{disabled}
|
||||
{hasAudioModality}
|
||||
{hasVisionModality}
|
||||
|
|
|
|||
|
|
@ -1,28 +1,4 @@
|
|||
<script lang="ts">
|
||||
/**
|
||||
* ChatMessageAgenticContent - Chronological display of agentic flow output
|
||||
*
|
||||
* This component renders assistant messages containing agentic workflow markers,
|
||||
* displaying tool calls and reasoning blocks as interactive collapsible sections.
|
||||
*
|
||||
* Features:
|
||||
* - Parses content with tool call markers (<<<AGENTIC_TOOL_CALL>>>, etc.)
|
||||
* - Displays reasoning blocks (<<<REASONING>>>, etc.)
|
||||
* - Shows tool execution states: streaming, pending, completed
|
||||
* - Collapsible blocks with user-configurable default states
|
||||
* - Real-time streaming support with loading indicators
|
||||
*
|
||||
* @component
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ChatMessageAgenticContent
|
||||
* content={message.content}
|
||||
* message={message}
|
||||
* isStreaming={true}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
|
||||
import {
|
||||
CollapsibleContentBlock,
|
||||
MarkdownContent,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { Trash2, Pencil, MoreHorizontal, Download, Loader2, Square } from '@lucide/svelte';
|
||||
import { ActionDropdown } from '$lib/components/app';
|
||||
import { DropdownMenuActions } from '$lib/components/app';
|
||||
import * as Tooltip from '$lib/components/ui/tooltip';
|
||||
import { getAllLoadingChats } from '$lib/stores/chat.svelte';
|
||||
import { conversationsStore } from '$lib/stores/conversations.svelte';
|
||||
|
|
@ -128,7 +128,7 @@
|
|||
|
||||
{#if renderActionsDropdown}
|
||||
<div class="actions flex items-center">
|
||||
<ActionDropdown
|
||||
<DropdownMenuActions
|
||||
triggerIcon={MoreHorizontal}
|
||||
triggerTooltip="More actions"
|
||||
bind:open={dropdownOpen}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,715 @@
|
|||
/**
|
||||
*
|
||||
* ATTACHMENTS
|
||||
*
|
||||
* Components for displaying and managing file attachments in chat messages.
|
||||
* Supports two operational modes:
|
||||
* - **Readonly mode**: For displaying stored attachments in sent messages (DatabaseMessageExtra[])
|
||||
* - **Editable mode**: For managing pending uploads in the input form (ChatUploadedFile[])
|
||||
*
|
||||
* The attachment system uses `getAttachmentDisplayItems()` utility to normalize both
|
||||
* data sources into a unified display format, enabling consistent rendering regardless
|
||||
* of the attachment origin.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **ChatAttachmentsList** - Unified display for file attachments in chat
|
||||
*
|
||||
* Central component for rendering file attachments in both ChatMessage (readonly)
|
||||
* and ChatForm (editable) contexts.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Delegates rendering to specialized thumbnail components based on attachment type
|
||||
* - Manages scroll state and navigation arrows for horizontal overflow
|
||||
* - Integrates with DialogChatAttachmentPreview for full-size viewing
|
||||
* - Validates vision modality support via `activeModelId` prop
|
||||
*
|
||||
* **Features:**
|
||||
* - Horizontal scroll with smooth navigation arrows
|
||||
* - Image thumbnails with lazy loading and error fallback
|
||||
* - File type icons for non-image files (PDF, text, audio, etc.)
|
||||
* - MCP prompt attachments with expandable content preview
|
||||
* - Click-to-preview with full-size dialog and download option
|
||||
* - "View All" button when `limitToSingleRow` is enabled and content overflows
|
||||
* - Vision modality validation to warn about unsupported image uploads
|
||||
* - Customizable thumbnail dimensions via `imageHeight`/`imageWidth` props
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <!-- Readonly mode (in ChatMessage) -->
|
||||
* <ChatAttachmentsList attachments={message.extra} readonly />
|
||||
*
|
||||
* <!-- Editable mode (in ChatForm) -->
|
||||
* <ChatAttachmentsList
|
||||
* bind:uploadedFiles
|
||||
* onFileRemove={(id) => removeFile(id)}
|
||||
* limitToSingleRow
|
||||
* activeModelId={selectedModel}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as ChatAttachmentsList } from './ChatAttachments/ChatAttachmentsList.svelte';
|
||||
|
||||
/**
|
||||
* Displays MCP Prompt attachment with expandable content preview.
|
||||
* Shows server name, prompt name, and allows expanding to view full prompt arguments
|
||||
* and content. Used when user selects a prompt from ChatFormPromptPicker.
|
||||
*/
|
||||
export { default as ChatAttachmentMcpPrompt } from './ChatAttachments/ChatAttachmentMcpPrompt.svelte';
|
||||
|
||||
/**
|
||||
* Full-size attachment preview component for dialog display. Handles different file types:
|
||||
* images (full-size display), text files (syntax highlighted), PDFs (text extraction or image preview),
|
||||
* audio (placeholder with download), and generic files (download option).
|
||||
*/
|
||||
export { default as ChatAttachmentPreview } from './ChatAttachments/ChatAttachmentPreview.svelte';
|
||||
|
||||
/**
|
||||
* Thumbnail for non-image file attachments. Displays file type icon based on extension,
|
||||
* file name (truncated), and file size.
|
||||
* Handles text files, PDFs, audio, and other document types.
|
||||
*/
|
||||
export { default as ChatAttachmentThumbnailFile } from './ChatAttachments/ChatAttachmentThumbnailFile.svelte';
|
||||
|
||||
/**
|
||||
* Thumbnail for image attachments with lazy loading and error fallback.
|
||||
* Displays image preview with configurable dimensions. Falls back to placeholder
|
||||
* on load error.
|
||||
*/
|
||||
export { default as ChatAttachmentThumbnailImage } from './ChatAttachments/ChatAttachmentThumbnailImage.svelte';
|
||||
|
||||
/**
|
||||
* Grid view of all attachments for "View All" dialog. Displays all attachments
|
||||
* in a responsive grid layout when there are too many to show inline.
|
||||
* Triggered by "+X more" button in ChatAttachmentsList.
|
||||
*/
|
||||
export { default as ChatAttachmentsViewAll } from './ChatAttachments/ChatAttachmentsViewAll.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* FORM
|
||||
*
|
||||
* Components for the chat input area. The form handles user input, file attachments,
|
||||
* audio recording, and MCP prompt selection. It integrates with multiple stores:
|
||||
* - `chatStore` for message submission and generation control
|
||||
* - `modelsStore` for model selection and validation
|
||||
* - `mcpStore` for MCP prompt browsing and loading
|
||||
*
|
||||
* The form exposes a public API for programmatic control from parent components
|
||||
* (focus, height reset, model selector, validation).
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **ChatForm** - Main chat input component with rich features
|
||||
*
|
||||
* The primary input interface for composing and sending chat messages.
|
||||
* Orchestrates text input, file attachments, audio recording, and MCP prompts.
|
||||
* Used by ChatScreenForm and ChatMessageEditForm for both new conversations and message editing.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Composes ChatFormTextarea, ChatFormActions, and ChatFormPromptPicker
|
||||
* - Manages file upload state via `uploadedFiles` bindable prop
|
||||
* - Integrates with ModelsSelector for model selection in router mode
|
||||
* - Communicates with parent via callbacks (onSubmit, onFilesAdd, onStop, etc.)
|
||||
*
|
||||
* **Input Handling:**
|
||||
* - IME-safe Enter key handling (waits for composition end)
|
||||
* - Shift+Enter for newline, Enter for submit
|
||||
* - Paste handler for files and long text (> {pasteLongTextToFileLen} chars → file conversion)
|
||||
* - Keyboard shortcut `/` triggers MCP prompt picker
|
||||
*
|
||||
* **Features:**
|
||||
* - Auto-resizing textarea with placeholder
|
||||
* - File upload via button dropdown (images/text/PDF), drag-drop, or paste
|
||||
* - Audio recording with WAV conversion (when model supports audio)
|
||||
* - MCP prompt picker with search and argument forms
|
||||
* - Model selector integration (router mode)
|
||||
* - Loading state with stop button, disabled state for errors
|
||||
*
|
||||
* **Exported API:**
|
||||
* - `focus()` - Focus the textarea programmatically
|
||||
* - `resetTextareaHeight()` - Reset textarea to default height after submit
|
||||
* - `openModelSelector()` - Open model selection dropdown
|
||||
* - `checkModelSelected(): boolean` - Validate model selection, show error if none
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ChatForm
|
||||
* bind:this={chatFormRef}
|
||||
* bind:value={message}
|
||||
* bind:uploadedFiles
|
||||
* {isLoading}
|
||||
* onSubmit={handleSubmit}
|
||||
* onFilesAdd={processFiles}
|
||||
* onStop={handleStop}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as ChatForm } from './ChatForm/ChatForm.svelte';
|
||||
|
||||
/**
|
||||
* Dropdown button for file attachment selection. Opens a menu with options for
|
||||
* Images, Text Files, and PDF Files. Each option filters the file picker to
|
||||
* appropriate types. Images option is disabled when model lacks vision modality.
|
||||
*/
|
||||
export { default as ChatFormActionAttachmentsDropdown } from './ChatForm/ChatFormActions/ChatFormActionAttachmentsDropdown.svelte';
|
||||
|
||||
/**
|
||||
* Audio recording button with real-time recording indicator. Records audio
|
||||
* and converts to WAV format for upload. Only visible when the active model
|
||||
* supports audio modality and setting for automatic audio input is enabled. Shows recording duration while active.
|
||||
*/
|
||||
export { default as ChatFormActionRecord } from './ChatForm/ChatFormActions/ChatFormActionRecord.svelte';
|
||||
|
||||
/**
|
||||
* Container for chat form action buttons. Arranges file attachment, audio record,
|
||||
* and submit/stop buttons in a horizontal layout. Handles conditional visibility
|
||||
* based on model capabilities and loading state.
|
||||
*/
|
||||
export { default as ChatFormActions } from './ChatForm/ChatFormActions/ChatFormActions.svelte';
|
||||
|
||||
/**
|
||||
* Submit/stop button with loading state. Shows send icon normally, transforms
|
||||
* to stop icon during generation. Disabled when input is empty or form is disabled.
|
||||
* Triggers onSubmit or onStop callbacks based on current state.
|
||||
*/
|
||||
export { default as ChatFormActionSubmit } from './ChatForm/ChatFormActions/ChatFormActionSubmit.svelte';
|
||||
|
||||
/**
|
||||
* Hidden file input element for programmatic file selection.
|
||||
*/
|
||||
export { default as ChatFormFileInputInvisible } from './ChatForm/ChatFormFileInputInvisible.svelte';
|
||||
|
||||
/**
|
||||
* Helper text display below chat.
|
||||
*/
|
||||
export { default as ChatFormHelperText } from './ChatForm/ChatFormHelperText.svelte';
|
||||
|
||||
/**
|
||||
* Auto-resizing textarea with IME composition support. Automatically adjusts
|
||||
* height based on content. Handles IME input correctly (waits for composition
|
||||
* end before processing Enter key). Exposes focus() and resetHeight() methods.
|
||||
*/
|
||||
export { default as ChatFormTextarea } from './ChatForm/ChatFormTextarea.svelte';
|
||||
|
||||
/**
|
||||
* **ChatFormPromptPicker** - MCP prompt selection interface
|
||||
*
|
||||
* Floating picker for browsing and selecting MCP Server Prompts.
|
||||
* Triggered by typing `/` in the chat input or choosing `MCP Prompt` option in ChatFormActionAttachmentsDropdown.
|
||||
* Loads prompts from connected MCP servers and allows users to select and configure them.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Fetches available prompts from mcpStore
|
||||
* - Manages selection state and keyboard navigation internally
|
||||
* - Delegates argument input to ChatFormPromptPickerArgumentForm
|
||||
* - Communicates prompt loading lifecycle via callbacks
|
||||
*
|
||||
* **Prompt Loading Flow:**
|
||||
* 1. User selects prompt → `onPromptLoadStart` called with placeholder ID
|
||||
* 2. Prompt content fetched from MCP server asynchronously
|
||||
* 3. On success → `onPromptLoadComplete` with full prompt data
|
||||
* 4. On failure → `onPromptLoadError` with error details
|
||||
*
|
||||
* **Features:**
|
||||
* - Search/filter prompts by name across all connected servers
|
||||
* - Keyboard navigation (↑/↓ to navigate, Enter to select, Esc to close)
|
||||
* - Argument input forms for prompts with required parameters
|
||||
* - Autocomplete suggestions for argument values
|
||||
* - Loading states with skeleton placeholders
|
||||
* - Server information header per prompt for visual identification
|
||||
*
|
||||
* **Exported API:**
|
||||
* - `handleKeydown(event): boolean` - Process keyboard events, returns true if handled
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ChatFormPromptPicker
|
||||
* bind:this={pickerRef}
|
||||
* isOpen={showPicker}
|
||||
* searchQuery={promptQuery}
|
||||
* onClose={() => showPicker = false}
|
||||
* onPromptLoadStart={(id, info) => addPlaceholder(id, info)}
|
||||
* onPromptLoadComplete={(id, result) => replacePlaceholder(id, result)}
|
||||
* onPromptLoadError={(id, error) => handleError(id, error)}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as ChatFormPromptPicker } from './ChatForm/ChatFormPromptPicker/ChatFormPromptPicker.svelte';
|
||||
|
||||
/**
|
||||
* Form for entering MCP prompt arguments. Displays input fields for each
|
||||
* required argument defined by the prompt. Validates input and submits
|
||||
* when all required fields are filled. Shows argument descriptions as hints.
|
||||
*/
|
||||
export { default as ChatFormPromptPickerArgumentForm } from './ChatForm/ChatFormPromptPicker/ChatFormPromptPickerArgumentForm.svelte';
|
||||
|
||||
/**
|
||||
* Single argument input field with autocomplete suggestions. Fetches suggestions
|
||||
* from MCP server based on argument type. Supports keyboard navigation through
|
||||
* suggestions list. Used within ChatFormPromptPickerArgumentForm.
|
||||
*/
|
||||
export { default as ChatFormPromptPickerArgumentInput } from './ChatForm/ChatFormPromptPicker/ChatFormPromptPickerArgumentInput.svelte';
|
||||
|
||||
/**
|
||||
* Header for prompt picker with search input and close button. Contains the
|
||||
* search field for filtering prompts and X button to dismiss the picker.
|
||||
* Search input is auto-focused when picker opens.
|
||||
*/
|
||||
export { default as ChatFormPromptPickerHeader } from './ChatForm/ChatFormPromptPicker/ChatFormPromptPickerHeader.svelte';
|
||||
|
||||
/**
|
||||
* Scrollable list of available MCP prompts. Renders ChatFormPromptPickerListItem
|
||||
* for each prompt, grouped by server. Handles empty state when no prompts match
|
||||
* search query. Manages scroll position for keyboard navigation.
|
||||
*/
|
||||
export { default as ChatFormPromptPickerList } from './ChatForm/ChatFormPromptPicker/ChatFormPromptPickerList.svelte';
|
||||
|
||||
/**
|
||||
* Single prompt item in the picker list. Displays server avatar, prompt name,
|
||||
* and description. Highlights on hover/keyboard focus. Triggers selection
|
||||
* callback on click or Enter key.
|
||||
*/
|
||||
export { default as ChatFormPromptPickerListItem } from './ChatForm/ChatFormPromptPicker/ChatFormPromptPickerListItem.svelte';
|
||||
|
||||
/**
|
||||
* Skeleton loading placeholder for prompt picker items. Displays animated
|
||||
* placeholder while prompts are being fetched from MCP servers.
|
||||
* Matches dimensions of ChatFormPromptPickerListItem.
|
||||
*/
|
||||
export { default as ChatFormPromptPickerListItemSkeleton } from './ChatForm/ChatFormPromptPicker/ChatFormPromptPickerListItemSkeleton.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* MESSAGES
|
||||
*
|
||||
* Components for displaying chat messages. The message system supports:
|
||||
* - **Conversation branching**: Messages can have siblings (alternative versions)
|
||||
* created by editing or regenerating. Users can navigate between branches.
|
||||
* - **Role-based rendering**: Different layouts for user, assistant, and system messages
|
||||
* - **Streaming support**: Real-time display of assistant responses as they generate
|
||||
* - **Agentic workflows**: Special rendering for tool calls and reasoning blocks
|
||||
*
|
||||
* The branching system uses `getMessageSiblings()` utility to compute sibling info
|
||||
* for each message based on the full conversation tree stored in the database.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **ChatMessages** - Message list container with branching support
|
||||
*
|
||||
* Container component that renders the list of messages in a conversation.
|
||||
* Computes sibling information for each message to enable branch navigation.
|
||||
* Integrates with conversationsStore for message operations.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Fetches all conversation messages to compute sibling relationships
|
||||
* - Filters system messages based on user config (`showSystemMessage`)
|
||||
* - Delegates rendering to ChatMessage for each message
|
||||
* - Propagates all message operations to chatStore via callbacks
|
||||
*
|
||||
* **Branching Logic:**
|
||||
* - Uses `getMessageSiblings()` to find all messages with same parent
|
||||
* - Computes `siblingInfo: { currentIndex, totalSiblings, siblingIds }`
|
||||
* - Enables navigation between alternative message versions
|
||||
*
|
||||
* **Message Operations (delegated to chatStore):**
|
||||
* - Edit with branching: Creates new message branch, preserves original
|
||||
* - Edit with replacement: Modifies message in place
|
||||
* - Regenerate: Creates new assistant response as sibling
|
||||
* - Delete: Removes message and all descendants (cascade)
|
||||
* - Continue: Appends to incomplete assistant message
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ChatMessages
|
||||
* messages={activeMessages()}
|
||||
* onUserAction={resetAutoScroll}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as ChatMessages } from './ChatMessages/ChatMessages.svelte';
|
||||
|
||||
/**
|
||||
* **ChatMessage** - Single message display with actions
|
||||
*
|
||||
* Renders a single chat message with role-specific styling and full action
|
||||
* support. Delegates to specialized components based on message role:
|
||||
* ChatMessageUser, ChatMessageAssistant, or ChatMessageSystem.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Routes to role-specific component based on `message.type`
|
||||
* - Manages edit mode state and inline editing UI
|
||||
* - Handles action callbacks (copy, edit, delete, regenerate)
|
||||
* - Displays branching controls when message has siblings
|
||||
*
|
||||
* **User Messages:**
|
||||
* - Shows attachments via ChatAttachmentsList
|
||||
* - Displays MCP prompts if present
|
||||
* - Edit creates new branch or preserves responses
|
||||
*
|
||||
* **Assistant Messages:**
|
||||
* - Renders content via MarkdownContent or ChatMessageAgenticContent
|
||||
* - Shows model info badge (when enabled)
|
||||
* - Regenerate creates sibling with optional model override
|
||||
* - Continue action for incomplete responses
|
||||
*
|
||||
* **Features:**
|
||||
* - Inline editing with file attachments support
|
||||
* - Copy formatted content to clipboard
|
||||
* - Delete with confirmation (shows cascade delete count)
|
||||
* - Branching controls for sibling navigation
|
||||
* - Statistics display (tokens, timing)
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ChatMessage
|
||||
* {message}
|
||||
* {siblingInfo}
|
||||
* onEditWithBranching={handleEdit}
|
||||
* onRegenerateWithBranching={handleRegenerate}
|
||||
* onNavigateToSibling={handleNavigate}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as ChatMessage } from './ChatMessages/ChatMessage.svelte';
|
||||
|
||||
/**
|
||||
* **ChatMessageAgenticContent** - Agentic workflow output display
|
||||
*
|
||||
* Specialized renderer for assistant messages containing agentic workflow markers.
|
||||
* Parses structured content and displays tool calls and reasoning blocks as
|
||||
* interactive collapsible sections with real-time streaming support.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses `parseAgenticContent()` from `$lib/utils/agentic` to parse markers
|
||||
* - Renders sections as CollapsibleContentBlock components
|
||||
* - Handles streaming state for progressive content display
|
||||
* - Falls back to MarkdownContent for plain text sections
|
||||
*
|
||||
* **Marker Format:**
|
||||
* - Tool calls: in constants/agentic.ts (AGENTIC_TAGS)
|
||||
* - Reasoning: in constants/agentic.ts (REASONING_TAGS)
|
||||
* - Partial markers handled gracefully during streaming
|
||||
*
|
||||
* **Execution States:**
|
||||
* - **Streaming**: Animated spinner, block expanded, auto-scroll enabled
|
||||
* - **Pending**: Waiting indicator for queued tool calls
|
||||
* - **Completed**: Static display, block collapsed by default
|
||||
*
|
||||
* **Features:**
|
||||
* - JSON arguments syntax highlighting via SyntaxHighlightedCode
|
||||
* - Tool results display with formatting
|
||||
* - Plain text sections between markers rendered as markdown
|
||||
* - Smart collapse defaults (expanded while streaming, collapsed when done)
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ChatMessageAgenticContent
|
||||
* content={message.content}
|
||||
* {message}
|
||||
* isStreaming={isGenerating}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as ChatMessageAgenticContent } from './ChatMessages/ChatMessageAgenticContent.svelte';
|
||||
|
||||
/**
|
||||
* Action buttons toolbar for messages. Displays copy, edit, delete, and regenerate
|
||||
* buttons based on message role. Includes branching controls when message has siblings.
|
||||
* Shows delete confirmation dialog with cascade delete count. Handles raw output toggle
|
||||
* for assistant messages.
|
||||
*/
|
||||
export { default as ChatMessageActions } from './ChatMessages/ChatMessageActions.svelte';
|
||||
|
||||
/**
|
||||
* Navigation controls for message siblings (conversation branches). Displays
|
||||
* prev/next arrows with current position counter (e.g., "2/5"). Enables users
|
||||
* to navigate between alternative versions of a message created by editing
|
||||
* or regenerating. Uses `conversationsStore.navigateToSibling()` for navigation.
|
||||
*/
|
||||
export { default as ChatMessageBranchingControls } from './ChatMessages/ChatMessageBranchingControls.svelte';
|
||||
|
||||
/**
|
||||
* Statistics display for assistant messages. Shows token counts (prompt/completion),
|
||||
* generation timing, tokens per second, and model name (when enabled in settings).
|
||||
* Data sourced from message.timings stored during generation.
|
||||
*/
|
||||
export { default as ChatMessageStatistics } from './ChatMessages/ChatMessageStatistics.svelte';
|
||||
|
||||
/**
|
||||
* MCP prompt display in user messages. Shows when user selected an MCP prompt
|
||||
* via ChatFormPromptPicker. Displays server name, prompt name, and expandable
|
||||
* content preview. Stored in message.extra as DatabaseMessageExtraMcpPrompt.
|
||||
*/
|
||||
export { default as ChatMessageMcpPrompt } from './ChatMessages/ChatMessageMcpPrompt.svelte';
|
||||
|
||||
/**
|
||||
* Formatted content display for MCP prompt messages. Renders the full prompt
|
||||
* content with arguments in a readable format. Used within ChatMessageMcpPrompt
|
||||
* for the expanded view.
|
||||
*/
|
||||
export { default as ChatMessageMcpPromptContent } from './ChatMessages/ChatMessageMcpPromptContent.svelte';
|
||||
|
||||
/**
|
||||
* System message display component. Renders system messages with distinct styling.
|
||||
* Visibility controlled by `showSystemMessage` config setting.
|
||||
*/
|
||||
export { default as ChatMessageSystem } from './ChatMessages/ChatMessageSystem.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* SCREEN
|
||||
*
|
||||
* Top-level chat interface components. ChatScreen is the main container that
|
||||
* orchestrates all chat functionality. It integrates with multiple stores:
|
||||
* - `chatStore` for message operations and generation control
|
||||
* - `conversationsStore` for conversation management
|
||||
* - `serverStore` for server connection state
|
||||
* - `modelsStore` for model capabilities (vision, audio modalities)
|
||||
*
|
||||
* The screen handles the complete chat lifecycle from empty state to active
|
||||
* conversation with streaming responses.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **ChatScreen** - Main chat interface container
|
||||
*
|
||||
* Top-level component that orchestrates the entire chat interface. Manages
|
||||
* messages display, input form, file handling, auto-scroll, error dialogs,
|
||||
* and server state. Used as the main content area in chat routes.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Composes ChatMessages, ChatScreenForm, ChatScreenHeader, and dialogs
|
||||
* - Manages auto-scroll via `createAutoScrollController()` hook
|
||||
* - Handles file upload pipeline (validation → processing → state update)
|
||||
* - Integrates with serverStore for loading/error/warning states
|
||||
* - Tracks active model for modality validation (vision, audio)
|
||||
*
|
||||
* **File Upload Pipeline:**
|
||||
* 1. Files received via drag-drop, paste, or file picker
|
||||
* 2. Validated against supported types (`isFileTypeSupported()`)
|
||||
* 3. Filtered by model modalities (`filterFilesByModalities()`)
|
||||
* 4. Empty files detected and reported via DialogEmptyFileAlert
|
||||
* 5. Valid files processed to ChatUploadedFile[] format
|
||||
* 6. Unsupported files shown in error dialog with reasons
|
||||
*
|
||||
* **State Management:**
|
||||
* - `isEmpty`: Shows centered welcome UI when no conversation active
|
||||
* - `isCurrentConversationLoading`: Tracks generation state for current chat
|
||||
* - `activeModelId`: Determines available modalities for file validation
|
||||
* - `uploadedFiles`: Pending file attachments for next message
|
||||
*
|
||||
* **Features:**
|
||||
* - Messages display with smart auto-scroll (pauses on user scroll up)
|
||||
* - File drag-drop with visual overlay indicator
|
||||
* - File validation with detailed error messages
|
||||
* - Error dialog management (chat errors, model unavailable)
|
||||
* - Server loading/error/warning states with appropriate UI
|
||||
* - Conversation deletion with confirmation dialog
|
||||
* - Processing info display (tokens/sec, timing) during generation
|
||||
* - Keyboard shortcuts (Ctrl+Shift+Backspace to delete conversation)
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <!-- In chat route -->
|
||||
* <ChatScreen showCenteredEmpty={true} />
|
||||
*
|
||||
* <!-- In conversation route -->
|
||||
* <ChatScreen showCenteredEmpty={false} />
|
||||
* ```
|
||||
*/
|
||||
export { default as ChatScreen } from './ChatScreen/ChatScreen.svelte';
|
||||
|
||||
/**
|
||||
* Chat form wrapper within ChatScreen. Positions the ChatForm component at the
|
||||
* bottom of the screen with proper padding and max-width constraints. Handles
|
||||
* the visual container styling for the input area.
|
||||
*/
|
||||
export { default as ChatScreenForm } from './ChatScreen/ChatScreenForm.svelte';
|
||||
|
||||
/**
|
||||
* Header bar for chat screen. Displays conversation title (or "New Chat"),
|
||||
* model selector (in router mode), and action buttons (delete conversation).
|
||||
* Sticky positioned at the top of the chat area.
|
||||
*/
|
||||
export { default as ChatScreenHeader } from './ChatScreen/ChatScreenHeader.svelte';
|
||||
|
||||
/**
|
||||
* Processing info display during generation. Shows real-time statistics:
|
||||
* tokens per second, prompt/completion token counts, and elapsed time.
|
||||
* Data sourced from slotsService polling during active generation.
|
||||
* Only visible when `isCurrentConversationLoading` is true.
|
||||
*/
|
||||
export { default as ChatScreenProcessingInfo } from './ChatScreen/ChatScreenProcessingInfo.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* SETTINGS
|
||||
*
|
||||
* Application settings components. Settings are persisted to localStorage via
|
||||
* the config store and synchronized with server `/props` endpoint for sampling
|
||||
* parameters. The settings panel uses a tabbed interface with mobile-responsive
|
||||
* horizontal scrolling tabs.
|
||||
*
|
||||
* **Parameter Sync System:**
|
||||
* Sampling parameters (temperature, top_p, etc.) can come from three sources:
|
||||
* 1. **Server Props**: Default values from `/props` endpoint
|
||||
* 2. **User Custom**: Values explicitly set by user (overrides server)
|
||||
* 3. **App Default**: Fallback when server props unavailable
|
||||
*
|
||||
* The `ChatSettingsParameterSourceIndicator` badge shows which source is active.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **ChatSettings** - Application settings panel
|
||||
*
|
||||
* Comprehensive settings interface with categorized sections. Manages all
|
||||
* user preferences and sampling parameters. Integrates with config store
|
||||
* for persistence and ParameterSyncService for server synchronization.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses tabbed navigation with category sections
|
||||
* - Maintains local form state, commits on save
|
||||
* - Tracks user overrides vs server defaults for sampling params
|
||||
* - Exposes reset() method for dialog close without save
|
||||
*
|
||||
* **Categories:**
|
||||
* - **General**: API key, system message, show system messages toggle
|
||||
* - **Display**: Theme selection, message actions visibility, model info badge
|
||||
* - **Sampling**: Temperature, top_p, top_k, min_p, repeat_penalty, etc.
|
||||
* - **Penalties**: Frequency penalty, presence penalty, repeat last N
|
||||
* - **Import/Export**: Conversation backup and restore
|
||||
* - **MCP**: MCP server management (opens DialogMcpServersSettings)
|
||||
* - **Developer**: Debug options, disable auto-scroll
|
||||
*
|
||||
* **Parameter Sync:**
|
||||
* - Fetches defaults from server `/props` endpoint
|
||||
* - Shows source indicator badge (Custom/Server Props/Default)
|
||||
* - Real-time badge updates as user types
|
||||
* - Tracks which parameters user has explicitly overridden
|
||||
*
|
||||
* **Features:**
|
||||
* - Mobile-responsive layout with horizontal scrolling tabs
|
||||
* - Form validation with error messages
|
||||
* - Secure API key storage (masked input)
|
||||
* - Import/export conversations as JSON
|
||||
* - Reset to defaults option per parameter
|
||||
*
|
||||
* **Exported API:**
|
||||
* - `reset()` - Reset form fields to currently saved values (for cancel action)
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ChatSettings
|
||||
* bind:this={settingsRef}
|
||||
* onSave={() => dialogOpen = false}
|
||||
* onCancel={() => { settingsRef.reset(); dialogOpen = false; }}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as ChatSettings } from './ChatSettings/ChatSettings.svelte';
|
||||
|
||||
/**
|
||||
* Footer with save/cancel buttons for settings panel. Positioned at bottom
|
||||
* of settings dialog. Save button commits form state to config store,
|
||||
* cancel button triggers reset and close.
|
||||
*/
|
||||
export { default as ChatSettingsFooter } from './ChatSettings/ChatSettingsFooter.svelte';
|
||||
|
||||
/**
|
||||
* Form fields renderer for individual settings. Generates appropriate input
|
||||
* components based on field type (text, number, select, checkbox, textarea).
|
||||
* Handles validation, help text display, and parameter source indicators.
|
||||
*/
|
||||
export { default as ChatSettingsFields } from './ChatSettings/ChatSettingsFields.svelte';
|
||||
|
||||
/**
|
||||
* Import/export tab content for conversation data management. Provides buttons
|
||||
* to export all conversations as JSON file and import from JSON file.
|
||||
* Handles file download/upload and data validation.
|
||||
*/
|
||||
export { default as ChatSettingsImportExportTab } from './ChatSettings/ChatSettingsImportExportTab.svelte';
|
||||
|
||||
/**
|
||||
* Badge indicating parameter source for sampling settings. Shows one of:
|
||||
* - **Custom**: User has explicitly set this value (orange badge)
|
||||
* - **Server Props**: Using default from `/props` endpoint (blue badge)
|
||||
* - **Default**: Using app default, server props unavailable (gray badge)
|
||||
* Updates in real-time as user types to show immediate feedback.
|
||||
*/
|
||||
export { default as ChatSettingsParameterSourceIndicator } from './ChatSettings/ChatSettingsParameterSourceIndicator.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* SIDEBAR
|
||||
*
|
||||
* The sidebar integrates with ShadCN's sidebar component system
|
||||
* for consistent styling and mobile responsiveness.
|
||||
* Conversations are loaded from conversationsStore and displayed in reverse
|
||||
* chronological order (most recent first).
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **ChatSidebar** - Chat Sidebar with actions menu and conversation list
|
||||
*
|
||||
* Collapsible sidebar displaying conversation history with search and
|
||||
* management actions. Integrates with ShadCN sidebar component for
|
||||
* consistent styling and mobile responsiveness.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses ShadCN Sidebar.* components for structure
|
||||
* - Fetches conversations from conversationsStore
|
||||
* - Manages search state and filtered results locally
|
||||
* - Handles conversation CRUD operations via conversationsStore
|
||||
*
|
||||
* **Navigation:**
|
||||
* - Click conversation to navigate to `/chat/[id]`
|
||||
* - New chat button navigates to `/` (root)
|
||||
* - Active conversation highlighted based on route params
|
||||
*
|
||||
* **Conversation Management:**
|
||||
* - Right-click or menu button for context menu
|
||||
* - Rename: Opens inline edit dialog
|
||||
* - Delete: Shows confirmation with conversation preview
|
||||
* - Delete All: Removes all conversations with confirmation
|
||||
*
|
||||
* **Features:**
|
||||
* - Search/filter conversations by title
|
||||
* - Conversation list with message previews (first message truncated)
|
||||
* - Active conversation highlighting
|
||||
* - Mobile-responsive collapse/expand via ShadCN sidebar
|
||||
* - New chat button in header
|
||||
* - Settings button opens DialogChatSettings
|
||||
*
|
||||
* **Exported API:**
|
||||
* - `handleMobileSidebarItemClick()` - Close sidebar on mobile after item selection
|
||||
* - `activateSearchMode()` - Focus search input programmatically
|
||||
* - `editActiveConversation()` - Open rename dialog for current conversation
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ChatSidebar bind:this={sidebarRef} />
|
||||
* ```
|
||||
*/
|
||||
export { default as ChatSidebar } from './ChatSidebar/ChatSidebar.svelte';
|
||||
|
||||
/**
|
||||
* Single conversation item in sidebar. Displays conversation title (truncated),
|
||||
* last message preview, and timestamp. Shows context menu on right-click with
|
||||
* rename and delete options. Highlights when active (matches current route).
|
||||
* Handles click to navigate and keyboard accessibility.
|
||||
*/
|
||||
export { default as ChatSidebarConversationItem } from './ChatSidebar/ChatSidebarConversationItem.svelte';
|
||||
|
||||
/**
|
||||
* Search input for filtering conversations in sidebar. Filters conversation
|
||||
* list by title as user types. Shows clear button when query is not empty.
|
||||
* Integrated into sidebar header with proper styling.
|
||||
*/
|
||||
export { default as ChatSidebarSearch } from './ChatSidebar/ChatSidebarSearch.svelte';
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import * as Dialog from '$lib/components/ui/dialog';
|
||||
import { McpLogo, McpSettingsSection } from '$lib/components/app';
|
||||
import { McpLogo, McpServersSettings } from '$lib/components/app';
|
||||
import { mcpStore } from '$lib/stores/mcp.svelte';
|
||||
import { mcpClient } from '$lib/clients/mcp.client';
|
||||
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
</div>
|
||||
|
||||
<div class="flex-1 overflow-y-auto px-4 py-6">
|
||||
<McpSettingsSection />
|
||||
<McpServersSettings />
|
||||
</div>
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,407 @@
|
|||
/**
|
||||
*
|
||||
* DIALOGS
|
||||
*
|
||||
* Modal dialog components for the chat application.
|
||||
*
|
||||
* All dialogs use ShadCN Dialog or AlertDialog components for consistent
|
||||
* styling, accessibility, and animation. They integrate with application
|
||||
* stores for state management and data access.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* SETTINGS DIALOGS
|
||||
*
|
||||
* Dialogs for application and server configuration.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **DialogChatSettings** - Settings dialog wrapper
|
||||
*
|
||||
* Modal dialog containing ChatSettings component with proper
|
||||
* open/close state management and automatic form reset on open.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Wraps ChatSettings component in ShadCN Dialog
|
||||
* - Manages open/close state via bindable `open` prop
|
||||
* - Resets form state when dialog opens to discard unsaved changes
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogChatSettings bind:open={showSettings} />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogChatSettings } from './DialogChatSettings.svelte';
|
||||
|
||||
/**
|
||||
* **DialogMcpServersSettings** - MCP servers configuration dialog
|
||||
*
|
||||
* Full-screen dialog for managing MCP Server
|
||||
* connections with add/edit/delete capabilities and health monitoring.
|
||||
* Opened from McpActiveServerAvatars or ChatFormActionAttachentsDropdown.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses ShadCN Dialog
|
||||
* - Integrates with mcpStore for server CRUD operations
|
||||
* - Manages connection state and health checks
|
||||
*
|
||||
* **Features:**
|
||||
* - Add new MCP servers by URL with validation
|
||||
* - Edit existing server configuration (URL, headers)
|
||||
* - Delete servers with confirmation dialog
|
||||
* - Health check status indicators (connected/disconnected/error)
|
||||
* - Connection logs display for debugging
|
||||
* - Tools list per server showing available capabilities
|
||||
* - Enable/disable servers per conversation
|
||||
* - Custom HTTP headers support
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogMcpServersSettings bind:open={showMcpSettings} />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogMcpServersSettings } from './DialogMcpServersSettings.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* CONFIRMATION DIALOGS
|
||||
*
|
||||
* Dialogs for user action confirmations. Use AlertDialog for blocking
|
||||
* confirmations that require explicit user decision before proceeding.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **DialogConfirmation** - Generic confirmation dialog
|
||||
*
|
||||
* Reusable confirmation dialog with customizable title, description,
|
||||
* and action buttons. Supports destructive action styling and custom icons.
|
||||
* Used for delete confirmations, irreversible actions, and important decisions.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses ShadCN AlertDialog
|
||||
* - Supports variant styling (default, destructive)
|
||||
* - Customizable button labels and callbacks
|
||||
*
|
||||
* **Features:**
|
||||
* - Customizable title and description text
|
||||
* - Destructive variant with red styling for dangerous actions
|
||||
* - Custom icon support in header
|
||||
* - Cancel and confirm button callbacks
|
||||
* - Keyboard accessible (Escape to cancel, Enter to confirm)
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogConfirmation
|
||||
* bind:open={showDelete}
|
||||
* title="Delete conversation?"
|
||||
* description="This action cannot be undone."
|
||||
* variant="destructive"
|
||||
* onConfirm={handleDelete}
|
||||
* onCancel={() => showDelete = false}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogConfirmation } from './DialogConfirmation.svelte';
|
||||
|
||||
/**
|
||||
* **DialogConversationTitleUpdate** - Conversation rename confirmation
|
||||
*
|
||||
* Confirmation dialog shown when editing the first user message in a conversation.
|
||||
* Asks user whether to update the conversation title to match the new message content.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses ShadCN AlertDialog
|
||||
* - Shows current vs proposed title comparison
|
||||
* - Triggered by ChatMessages when first message is edited
|
||||
*
|
||||
* **Features:**
|
||||
* - Side-by-side display of current and new title
|
||||
* - "Keep Current Title" and "Update Title" action buttons
|
||||
* - Styled title previews in muted background boxes
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogConversationTitleUpdate
|
||||
* bind:open={showTitleUpdate}
|
||||
* currentTitle={conversation.name}
|
||||
* newTitle={truncatedMessageContent}
|
||||
* onConfirm={updateTitle}
|
||||
* onCancel={() => showTitleUpdate = false}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogConversationTitleUpdate } from './DialogConversationTitleUpdate.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* ATTACHMENT DIALOGS
|
||||
*
|
||||
* Dialogs for viewing and managing file attachments. Support both
|
||||
* uploaded files (pending) and stored attachments (in messages).
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **DialogChatAttachmentPreview** - Full-size attachment preview
|
||||
*
|
||||
* Modal dialog for viewing file attachments at full size. Supports different
|
||||
* file types with appropriate preview modes: images, text files, PDFs, and audio.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Wraps ChatAttachmentPreview component in ShadCN Dialog
|
||||
* - Accepts either uploaded file or stored attachment as data source
|
||||
* - Resets preview state when dialog opens
|
||||
*
|
||||
* **Features:**
|
||||
* - Full-size image display with proper scaling
|
||||
* - Text file content with syntax highlighting
|
||||
* - PDF preview with text/image view toggle
|
||||
* - Audio file placeholder with download option
|
||||
* - File name and size display in header
|
||||
* - Download button for all file types
|
||||
* - Vision modality check for image attachments
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <!-- Preview uploaded file -->
|
||||
* <DialogChatAttachmentPreview
|
||||
* bind:open={showPreview}
|
||||
* uploadedFile={selectedFile}
|
||||
* activeModelId={currentModel}
|
||||
* />
|
||||
*
|
||||
* <!-- Preview stored attachment -->
|
||||
* <DialogChatAttachmentPreview
|
||||
* bind:open={showPreview}
|
||||
* attachment={selectedAttachment}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogChatAttachmentPreview } from './DialogChatAttachmentPreview.svelte';
|
||||
|
||||
/**
|
||||
* **DialogChatAttachmentsViewAll** - Grid view of all attachments
|
||||
*
|
||||
* Dialog showing all attachments in a responsive grid layout. Triggered by
|
||||
* "+X more" button in ChatAttachmentsList when there are too many attachments
|
||||
* to display inline.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Wraps ChatAttachmentsViewAll component in ShadCN Dialog
|
||||
* - Supports both readonly (message view) and editable (form) modes
|
||||
* - Displays total attachment count in header
|
||||
*
|
||||
* **Features:**
|
||||
* - Responsive grid layout for all attachments
|
||||
* - Thumbnail previews with click-to-expand
|
||||
* - Remove button in editable mode
|
||||
* - Configurable thumbnail dimensions
|
||||
* - Vision modality validation for images
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogChatAttachmentsViewAll
|
||||
* bind:open={showAllAttachments}
|
||||
* attachments={message.extra}
|
||||
* readonly
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogChatAttachmentsViewAll } from './DialogChatAttachmentsViewAll.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* ERROR & ALERT DIALOGS
|
||||
*
|
||||
* Dialogs for displaying errors, warnings, and alerts to users.
|
||||
* Provide context about what went wrong and recovery options.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **DialogChatError** - Chat/generation error display
|
||||
*
|
||||
* Alert dialog for displaying chat and generation errors with context
|
||||
* information. Supports different error types with appropriate styling
|
||||
* and messaging.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses ShadCN AlertDialog for modal display
|
||||
* - Differentiates between timeout and server errors
|
||||
* - Shows context info when available (token counts)
|
||||
*
|
||||
* **Error Types:**
|
||||
* - **timeout**: TCP timeout with timer icon, red destructive styling
|
||||
* - **server**: Server error with warning icon, amber warning styling
|
||||
*
|
||||
* **Features:**
|
||||
* - Type-specific icons (TimerOff for timeout, AlertTriangle for server)
|
||||
* - Error message display in styled badge
|
||||
* - Context info showing prompt tokens and context size
|
||||
* - Close button to dismiss
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogChatError
|
||||
* bind:open={showError}
|
||||
* type="server"
|
||||
* message={errorMessage}
|
||||
* contextInfo={{ n_prompt_tokens: 1024, n_ctx: 4096 }}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogChatError } from './DialogChatError.svelte';
|
||||
|
||||
/**
|
||||
* **DialogEmptyFileAlert** - Empty file upload warning
|
||||
*
|
||||
* Alert dialog shown when user attempts to upload empty files. Lists the
|
||||
* empty files that were detected and removed from attachments, with
|
||||
* explanation of why empty files cannot be processed.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses ShadCN AlertDialog for modal display
|
||||
* - Receives list of empty file names from ChatScreen
|
||||
* - Triggered during file upload validation
|
||||
*
|
||||
* **Features:**
|
||||
* - FileX icon indicating file error
|
||||
* - List of empty file names in monospace font
|
||||
* - Explanation of what happened and why
|
||||
* - Single "Got it" dismiss button
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogEmptyFileAlert
|
||||
* bind:open={showEmptyAlert}
|
||||
* emptyFiles={['empty.txt', 'blank.md']}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogEmptyFileAlert } from './DialogEmptyFileAlert.svelte';
|
||||
|
||||
/**
|
||||
* **DialogModelNotAvailable** - Model unavailable error
|
||||
*
|
||||
* Alert dialog shown when the requested model (from URL params or selection)
|
||||
* is not available on the server. Displays the requested model name and
|
||||
* offers selection from available models.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses ShadCN AlertDialog for modal display
|
||||
* - Integrates with SvelteKit navigation for model switching
|
||||
* - Receives available models list from modelsStore
|
||||
*
|
||||
* **Features:**
|
||||
* - Warning icon with amber styling
|
||||
* - Requested model name display in styled badge
|
||||
* - Scrollable list of available models
|
||||
* - Click model to navigate with updated URL params
|
||||
* - Cancel button to dismiss without selection
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogModelNotAvailable
|
||||
* bind:open={showModelError}
|
||||
* modelName={requestedModel}
|
||||
* availableModels={modelsList}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogModelNotAvailable } from './DialogModelNotAvailable.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* DATA MANAGEMENT DIALOGS
|
||||
*
|
||||
* Dialogs for managing conversation data, including import/export
|
||||
* and selection operations.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **DialogConversationSelection** - Conversation picker for import/export
|
||||
*
|
||||
* Dialog for selecting conversations during import or export operations.
|
||||
* Displays list of conversations with checkboxes for multi-selection.
|
||||
* Used by ChatSettingsImportExportTab for data management.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Wraps ConversationSelection component in ShadCN Dialog
|
||||
* - Supports export mode (select from local) and import mode (select from file)
|
||||
* - Resets selection state when dialog opens
|
||||
* - High z-index to appear above settings dialog
|
||||
*
|
||||
* **Features:**
|
||||
* - Multi-select with checkboxes
|
||||
* - Conversation title and message count display
|
||||
* - Select all / deselect all controls
|
||||
* - Mode-specific descriptions (export vs import)
|
||||
* - Cancel and confirm callbacks with selected conversations
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogConversationSelection
|
||||
* bind:open={showExportSelection}
|
||||
* conversations={allConversations}
|
||||
* messageCountMap={messageCounts}
|
||||
* mode="export"
|
||||
* onConfirm={handleExport}
|
||||
* onCancel={() => showExportSelection = false}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogConversationSelection } from './DialogConversationSelection.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* MODEL INFORMATION DIALOGS
|
||||
*
|
||||
* Dialogs for displaying model and server information.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **DialogModelInformation** - Model details display
|
||||
*
|
||||
* Dialog showing comprehensive information about the currently loaded model
|
||||
* and server configuration. Displays model metadata, capabilities, and
|
||||
* server settings in a structured table format.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses ShadCN Dialog with wide layout for table display
|
||||
* - Fetches data from serverStore (props) and modelsStore (metadata)
|
||||
* - Auto-fetches models when dialog opens if not loaded
|
||||
*
|
||||
* **Information Displayed:**
|
||||
* - **Model**: Name with copy button
|
||||
* - **File Path**: Full path to model file with copy button
|
||||
* - **Context Size**: Current context window size
|
||||
* - **Training Context**: Original training context (if available)
|
||||
* - **Model Size**: File size in human-readable format
|
||||
* - **Parameters**: Parameter count (e.g., "7B", "70B")
|
||||
* - **Embedding Size**: Embedding dimension
|
||||
* - **Vocabulary Size**: Token vocabulary size
|
||||
* - **Vocabulary Type**: Tokenizer type (BPE, etc.)
|
||||
* - **Parallel Slots**: Number of concurrent request slots
|
||||
* - **Modalities**: Supported input types (text, vision, audio)
|
||||
* - **Build Info**: Server build information
|
||||
* - **Chat Template**: Full Jinja template in scrollable code block
|
||||
*
|
||||
* **Features:**
|
||||
* - Copy buttons for model name and path
|
||||
* - Modality badges with icons
|
||||
* - Responsive table layout with container queries
|
||||
* - Loading state while fetching model info
|
||||
* - Scrollable chat template display
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DialogModelInformation bind:open={showModelInfo} />
|
||||
* ```
|
||||
*/
|
||||
export { default as DialogModelInformation } from './DialogModelInformation.svelte';
|
||||
|
|
@ -1,101 +1,6 @@
|
|||
// Chat
|
||||
|
||||
export { default as ChatAttachmentMcpPrompt } from './chat/ChatAttachments/ChatAttachmentMcpPrompt.svelte';
|
||||
export { default as ChatAttachmentPreview } from './chat/ChatAttachments/ChatAttachmentPreview.svelte';
|
||||
export { default as ChatAttachmentThumbnailFile } from './chat/ChatAttachments/ChatAttachmentThumbnailFile.svelte';
|
||||
export { default as ChatAttachmentThumbnailImage } from './chat/ChatAttachments/ChatAttachmentThumbnailImage.svelte';
|
||||
export { default as ChatAttachmentsList } from './chat/ChatAttachments/ChatAttachmentsList.svelte';
|
||||
export { default as ChatAttachmentsViewAll } from './chat/ChatAttachments/ChatAttachmentsViewAll.svelte';
|
||||
|
||||
export { default as ChatForm } from './chat/ChatForm/ChatForm.svelte';
|
||||
export { default as ChatFormActionFileAttachments } from './chat/ChatForm/ChatFormActions/ChatFormActionFileAttachments.svelte';
|
||||
export { default as ChatFormActionRecord } from './chat/ChatForm/ChatFormActions/ChatFormActionRecord.svelte';
|
||||
export { default as ChatFormActions } from './chat/ChatForm/ChatFormActions/ChatFormActions.svelte';
|
||||
export { default as ChatFormActionSubmit } from './chat/ChatForm/ChatFormActions/ChatFormActionSubmit.svelte';
|
||||
export { default as ChatFormFileInputInvisible } from './chat/ChatForm/ChatFormFileInputInvisible.svelte';
|
||||
export { default as ChatFormHelperText } from './chat/ChatForm/ChatFormHelperText.svelte';
|
||||
export { default as ChatFormPromptPicker } from './chat/ChatForm/ChatFormPromptPicker/ChatFormPromptPicker.svelte';
|
||||
export { default as ChatFormPromptPickerArgumentForm } from './chat/ChatForm/ChatFormPromptPicker/ChatFormPromptPickerArgumentForm.svelte';
|
||||
export { default as ChatFormPromptPickerArgumentInput } from './chat/ChatForm/ChatFormPromptPicker/ChatFormPromptPickerArgumentInput.svelte';
|
||||
export { default as ChatFormPromptPickerHeader } from './chat/ChatForm/ChatFormPromptPicker/ChatFormPromptPickerHeader.svelte';
|
||||
export { default as ChatFormPromptPickerList } from './chat/ChatForm/ChatFormPromptPicker/ChatFormPromptPickerList.svelte';
|
||||
export { default as ChatFormPromptPickerListItem } from './chat/ChatForm/ChatFormPromptPicker/ChatFormPromptPickerListItem.svelte';
|
||||
export { default as ChatFormPromptPickerListItemSkeleton } from './chat/ChatForm/ChatFormPromptPicker/ChatFormPromptPickerListItemSkeleton.svelte';
|
||||
export { default as ChatFormTextarea } from './chat/ChatForm/ChatFormTextarea.svelte';
|
||||
|
||||
export { default as ChatMessage } from './chat/ChatMessages/ChatMessage.svelte';
|
||||
export { default as ChatMessageActions } from './chat/ChatMessages/ChatMessageActions.svelte';
|
||||
export { default as ChatMessageAgenticContent } from './chat/ChatMessages/ChatMessageAgenticContent.svelte';
|
||||
export { default as ChatMessageBranchingControls } from './chat/ChatMessages/ChatMessageBranchingControls.svelte';
|
||||
export { default as ChatMessageStatistics } from './chat/ChatMessages/ChatMessageStatistics.svelte';
|
||||
export { default as ChatMessageMcpPrompt } from './chat/ChatMessages/ChatMessageMcpPrompt.svelte';
|
||||
export { default as ChatMessageMcpPromptContent } from './chat/ChatMessages/ChatMessageMcpPromptContent.svelte';
|
||||
export { default as ChatMessageSystem } from './chat/ChatMessages/ChatMessageSystem.svelte';
|
||||
export { default as ChatMessages } from './chat/ChatMessages/ChatMessages.svelte';
|
||||
export { default as CollapsibleContentBlock } from './chat/ChatMessages/CollapsibleContentBlock.svelte';
|
||||
export { default as MessageBranchingControls } from './chat/ChatMessages/ChatMessageBranchingControls.svelte';
|
||||
|
||||
export { default as ChatScreen } from './chat/ChatScreen/ChatScreen.svelte';
|
||||
export { default as ChatScreenForm } from './chat/ChatScreen/ChatScreenForm.svelte';
|
||||
|
||||
export { default as ChatScreenHeader } from './chat/ChatScreen/ChatScreenHeader.svelte';
|
||||
export { default as ChatScreenProcessingInfo } from './chat/ChatScreen/ChatScreenProcessingInfo.svelte';
|
||||
|
||||
export { default as ChatSettings } from './chat/ChatSettings/ChatSettings.svelte';
|
||||
export { default as ChatSettingsFooter } from './chat/ChatSettings/ChatSettingsFooter.svelte';
|
||||
export { default as ChatSettingsFields } from './chat/ChatSettings/ChatSettingsFields.svelte';
|
||||
export { default as ChatSettingsImportExportTab } from './chat/ChatSettings/ChatSettingsImportExportTab.svelte';
|
||||
export { default as ChatSettingsParameterSourceIndicator } from './chat/ChatSettings/ChatSettingsParameterSourceIndicator.svelte';
|
||||
|
||||
export { default as ChatSidebar } from './chat/ChatSidebar/ChatSidebar.svelte';
|
||||
export { default as ChatSidebarConversationItem } from './chat/ChatSidebar/ChatSidebarConversationItem.svelte';
|
||||
export { default as ChatSidebarSearch } from './chat/ChatSidebar/ChatSidebarSearch.svelte';
|
||||
|
||||
// Dialogs
|
||||
|
||||
export { default as DialogChatAttachmentPreview } from './dialogs/DialogChatAttachmentPreview.svelte';
|
||||
export { default as DialogChatAttachmentsViewAll } from './dialogs/DialogChatAttachmentsViewAll.svelte';
|
||||
export { default as DialogChatError } from './dialogs/DialogChatError.svelte';
|
||||
export { default as DialogChatSettings } from './dialogs/DialogChatSettings.svelte';
|
||||
export { default as DialogConfirmation } from './dialogs/DialogConfirmation.svelte';
|
||||
export { default as DialogConversationSelection } from './dialogs/DialogConversationSelection.svelte';
|
||||
export { default as DialogConversationTitleUpdate } from './dialogs/DialogConversationTitleUpdate.svelte';
|
||||
export { default as DialogEmptyFileAlert } from './dialogs/DialogEmptyFileAlert.svelte';
|
||||
export { default as DialogMcpServersSettings } from './dialogs/DialogMcpServersSettings.svelte';
|
||||
export { default as DialogModelInformation } from './dialogs/DialogModelInformation.svelte';
|
||||
export { default as DialogModelNotAvailable } from './dialogs/DialogModelNotAvailable.svelte';
|
||||
|
||||
// Miscellanous
|
||||
|
||||
export { default as ActionButton } from './misc/ActionButton.svelte';
|
||||
export { default as ActionDropdown } from './misc/ActionDropdown.svelte';
|
||||
export { default as BadgeChatStatistic } from './misc/BadgeChatStatistic.svelte';
|
||||
export { default as BadgeInfo } from './misc/BadgeInfo.svelte';
|
||||
export { default as BadgeModality } from './misc/BadgeModality.svelte';
|
||||
export { default as ConversationSelection } from './misc/ConversationSelection.svelte';
|
||||
export { default as CopyToClipboardIcon } from './misc/CopyToClipboardIcon.svelte';
|
||||
export { default as KeyboardShortcutInfo } from './misc/KeyboardShortcutInfo.svelte';
|
||||
export { default as KeyValuePairs } from './misc/KeyValuePairs.svelte';
|
||||
export { default as MarkdownContent } from './misc/MarkdownContent.svelte';
|
||||
export { default as RemoveButton } from './misc/RemoveButton.svelte';
|
||||
export { default as SearchInput } from './misc/SearchInput.svelte';
|
||||
export { default as SearchableDropdownMenu } from './misc/SearchableDropdownMenu.svelte';
|
||||
export { default as SyntaxHighlightedCode } from './misc/SyntaxHighlightedCode.svelte';
|
||||
export { default as TruncatedText } from './misc/TruncatedText.svelte';
|
||||
|
||||
// Models
|
||||
|
||||
export { default as ModelBadge } from './models/ModelBadge.svelte';
|
||||
export { default as ModelsSelector } from './models/ModelsSelector.svelte';
|
||||
|
||||
// MCP
|
||||
|
||||
export { default as McpActiveServersAvatars } from './mcp/McpActiveServersAvatars.svelte';
|
||||
export { default as McpLogo } from './mcp/McpLogo.svelte';
|
||||
export { default as McpSettingsSection } from './mcp/McpSettingsSection.svelte';
|
||||
|
||||
// Server
|
||||
|
||||
export { default as ServerStatus } from './server/ServerStatus.svelte';
|
||||
export { default as ServerErrorSplash } from './server/ServerErrorSplash.svelte';
|
||||
export { default as ServerLoadingSplash } from './server/ServerLoadingSplash.svelte';
|
||||
export * from './chat';
|
||||
export * from './dialogs';
|
||||
export * from './mcp';
|
||||
export * from './misc';
|
||||
export * from './models';
|
||||
export * from './server';
|
||||
|
|
|
|||
|
|
@ -6,13 +6,15 @@
|
|||
import { HealthCheckStatus } from '$lib/enums';
|
||||
import { mcpStore } from '$lib/stores/mcp.svelte';
|
||||
import { mcpClient } from '$lib/clients/mcp.client';
|
||||
import McpServerCardHeader from './McpServerCardHeader.svelte';
|
||||
import McpServerCardActions from './McpServerCardActions.svelte';
|
||||
import McpServerCardToolsList from './McpServerCardToolsList.svelte';
|
||||
import McpServerCardEditForm from './McpServerCardEditForm.svelte';
|
||||
import McpServerCardDeleteDialog from './McpServerCardDeleteDialog.svelte';
|
||||
import McpServerInfo from './McpServerInfo.svelte';
|
||||
import McpConnectionLogs from './McpConnectionLogs.svelte';
|
||||
import {
|
||||
McpServerCardActions,
|
||||
McpServerCardDeleteDialog,
|
||||
McpServerCardEditForm,
|
||||
McpServerCardHeader,
|
||||
McpServerCardToolsList,
|
||||
McpConnectionLogs,
|
||||
McpServerInfo
|
||||
} from '$lib/components/app/mcp';
|
||||
|
||||
interface Props {
|
||||
server: MCPServerSettingsEntry;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import type { MCPServerInfo, MCPCapabilitiesInfo } from '$lib/types';
|
||||
import { MCPTransportType } from '$lib/enums';
|
||||
import { Badge } from '$lib/components/ui/badge';
|
||||
import McpCapabilitiesBadges from './McpCapabilitiesBadges.svelte';
|
||||
import { McpCapabilitiesBadges } from '$lib/components/app/mcp';
|
||||
|
||||
interface Props {
|
||||
displayName: string;
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
export { default as McpServerCard } from './McpServerCard.svelte';
|
||||
export { default as McpServerCardHeader } from './McpServerCardHeader.svelte';
|
||||
export { default as McpServerCardActions } from './McpServerCardActions.svelte';
|
||||
export { default as McpServerCardToolsList } from './McpServerCardToolsList.svelte';
|
||||
export { default as McpServerCardEditForm } from './McpServerCardEditForm.svelte';
|
||||
export { default as McpServerCardDeleteDialog } from './McpServerCardDeleteDialog.svelte';
|
||||
export { default as McpServerInfo } from './McpServerInfo.svelte';
|
||||
export { default as McpCapabilitiesBadges } from './McpCapabilitiesBadges.svelte';
|
||||
export { default as McpConnectionLogs } from './McpConnectionLogs.svelte';
|
||||
|
|
@ -5,8 +5,7 @@
|
|||
import { getFaviconUrl } from '$lib/utils';
|
||||
import { mcpStore } from '$lib/stores/mcp.svelte';
|
||||
import { conversationsStore } from '$lib/stores/conversations.svelte';
|
||||
import { McpServerCard } from '$lib/components/app/mcp/McpServerCard';
|
||||
import McpServerForm from './McpServerForm.svelte';
|
||||
import { McpServerCard, McpServerForm } from '$lib/components/app/mcp';
|
||||
import { Skeleton } from '$lib/components/ui/skeleton';
|
||||
let servers = $derived(mcpStore.getServersSorted());
|
||||
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/**
|
||||
*
|
||||
* MCP (Model Context Protocol)
|
||||
*
|
||||
* Components for managing MCP server connections and displaying server status.
|
||||
* MCP enables agentic workflows by connecting to external tool servers.
|
||||
*
|
||||
* The MCP system integrates with:
|
||||
* - `mcpStore` for server CRUD operations and health checks
|
||||
* - `conversationsStore` for per-conversation server enable/disable
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **McpServersSettings** - MCP servers configuration section
|
||||
*
|
||||
* Settings section for configuring MCP server connections.
|
||||
* Displays server cards with status, tools, and management actions.
|
||||
* Used within DialogMcpServersSettings.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Manages add server form state locally
|
||||
* - Delegates server display to McpServerCard components
|
||||
* - Integrates with mcpStore for server operations
|
||||
* - Shows skeleton loading states during health checks
|
||||
*
|
||||
* **Features:**
|
||||
* - Add new MCP servers by URL with validation
|
||||
* - Server cards with connection status indicators
|
||||
* - Health check status (connected/disconnected/error)
|
||||
* - Tools list per server showing available capabilities
|
||||
* - Enable/disable toggle per conversation
|
||||
* - Edit/delete server actions
|
||||
* - Skeleton loading states during connection
|
||||
* - Empty state with helpful message
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <McpServersSettings />
|
||||
* ```
|
||||
*/
|
||||
export { default as McpServersSettings } from './McpServersSettings.svelte';
|
||||
|
||||
/**
|
||||
* **McpActiveServersAvatars** - Active MCP servers indicator
|
||||
*
|
||||
* Compact avatar row showing favicons of active MCP servers.
|
||||
* Displays up to 3 server icons with "+N" counter for additional servers.
|
||||
* Clickable to open MCP settings dialog.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Filters servers by enabled status and health check
|
||||
* - Fetches favicons from server URLs
|
||||
* - Integrates with conversationsStore for per-chat server state
|
||||
*
|
||||
* **Features:**
|
||||
* - Overlapping favicon avatars (max 3 visible)
|
||||
* - "+N" counter for additional servers
|
||||
* - Click handler for settings navigation
|
||||
* - Disabled state support
|
||||
* - Only shows healthy, enabled servers
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <McpActiveServersAvatars
|
||||
* onSettingsClick={() => showMcpSettings = true}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as McpActiveServersAvatars } from './McpActiveServersAvatars.svelte';
|
||||
|
||||
/**
|
||||
* **McpCapabilitiesBadges** - Server capabilities display
|
||||
*
|
||||
* Displays MCP server capabilities as colored badges.
|
||||
* Shows which features the server supports (tools, resources, prompts, etc.).
|
||||
*
|
||||
* **Features:**
|
||||
* - Tools badge (green) - server provides callable tools
|
||||
* - Resources badge (blue) - server provides data resources
|
||||
* - Prompts badge (purple) - server provides prompt templates
|
||||
* - Logging badge (orange) - server supports logging
|
||||
* - Completions badge (cyan) - server provides completions
|
||||
* - Tasks badge (pink) - server supports task management
|
||||
*/
|
||||
export { default as McpCapabilitiesBadges } from './McpCapabilitiesBadges.svelte';
|
||||
|
||||
/**
|
||||
* **McpConnectionLogs** - Connection log viewer
|
||||
*
|
||||
* Collapsible panel showing MCP server connection logs.
|
||||
* Displays timestamped log entries with level-based styling.
|
||||
*
|
||||
* **Features:**
|
||||
* - Collapsible log list with entry count
|
||||
* - Connection time display in milliseconds
|
||||
* - Log level icons and color coding
|
||||
* - Scrollable log container with max height
|
||||
* - Monospace font for log readability
|
||||
*/
|
||||
export { default as McpConnectionLogs } from './McpConnectionLogs.svelte';
|
||||
|
||||
/**
|
||||
* **McpServerForm** - Server URL and headers input form
|
||||
*
|
||||
* Reusable form for entering MCP server connection details.
|
||||
* Used in both add new server and edit server flows.
|
||||
*
|
||||
* **Features:**
|
||||
* - URL input with validation error display
|
||||
* - Custom headers key-value pairs editor
|
||||
* - Controlled component with change callbacks
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <McpServerForm
|
||||
* url={serverUrl}
|
||||
* headers={serverHeaders}
|
||||
* onUrlChange={(v) => serverUrl = v}
|
||||
* onHeadersChange={(v) => serverHeaders = v}
|
||||
* urlError={validationError}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as McpServerForm } from './McpServerForm.svelte';
|
||||
|
||||
/**
|
||||
* MCP protocol logo SVG component. Renders the official MCP icon
|
||||
* with customizable size via class and style props.
|
||||
*/
|
||||
export { default as McpLogo } from './McpLogo.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* SERVER CARD
|
||||
*
|
||||
* Components for displaying individual MCP server status and controls.
|
||||
* McpServerCard is the main component, with sub-components for specific sections.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **McpServerCard** - Individual server display card
|
||||
*
|
||||
* Main component for displaying a single MCP server with all its details.
|
||||
* Manages edit mode, delete confirmation, and health check actions.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Composes header, tools list, logs, and actions sub-components
|
||||
* - Manages local edit/delete state
|
||||
* - Reads health state from mcpStore
|
||||
* - Triggers health checks via mcpClient
|
||||
*
|
||||
* **Features:**
|
||||
* - Server header with favicon, name, version, and toggle
|
||||
* - Capabilities badges display
|
||||
* - Tools list with descriptions
|
||||
* - Connection logs viewer
|
||||
* - Edit form for URL and headers
|
||||
* - Delete confirmation dialog
|
||||
* - Skeleton loading states
|
||||
*/
|
||||
export { default as McpServerCard } from './McpServerCard/McpServerCard.svelte';
|
||||
|
||||
/** Server card header with favicon, name, version badge, and enable toggle. */
|
||||
export { default as McpServerCardHeader } from './McpServerCard/McpServerCardHeader.svelte';
|
||||
|
||||
/** Action buttons row: edit, refresh, delete. */
|
||||
export { default as McpServerCardActions } from './McpServerCard/McpServerCardActions.svelte';
|
||||
|
||||
/** Collapsible tools list showing available server tools with descriptions. */
|
||||
export { default as McpServerCardToolsList } from './McpServerCard/McpServerCardToolsList.svelte';
|
||||
|
||||
/** Inline edit form for server URL and custom headers. */
|
||||
export { default as McpServerCardEditForm } from './McpServerCard/McpServerCardEditForm.svelte';
|
||||
|
||||
/** Delete confirmation dialog with server name display. */
|
||||
export { default as McpServerCardDeleteDialog } from './McpServerCard/McpServerCardDeleteDialog.svelte';
|
||||
|
||||
/**
|
||||
* **McpServerInfo** - Server instructions display
|
||||
*
|
||||
* Collapsible panel showing server-provided instructions.
|
||||
* Displays guidance text from the MCP server for users.
|
||||
*/
|
||||
export { default as McpServerInfo } from './McpServerInfo.svelte';
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
/**
|
||||
*
|
||||
* MISC
|
||||
*
|
||||
* Reusable utility components used across the application.
|
||||
* Includes content rendering, UI primitives, and helper components.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* CONTENT RENDERING
|
||||
*
|
||||
* Components for rendering rich content: markdown, code, and previews.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **MarkdownContent** - Rich markdown renderer
|
||||
*
|
||||
* Renders markdown content with syntax highlighting, LaTeX math,
|
||||
* tables, links, and code blocks. Optimized for streaming with
|
||||
* incremental block-based rendering.
|
||||
*
|
||||
* **Features:**
|
||||
* - GFM (GitHub Flavored Markdown): tables, task lists, strikethrough
|
||||
* - LaTeX math via KaTeX (`$inline$` and `$$block$$`)
|
||||
* - Syntax highlighting (highlight.js) with language detection
|
||||
* - Code copy buttons with click feedback
|
||||
* - External links open in new tab with security attrs
|
||||
* - Image attachment resolution from message extras
|
||||
* - Dark/light theme support (auto-switching)
|
||||
* - Streaming-optimized incremental rendering
|
||||
* - Code preview dialog for large blocks
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <MarkdownContent content={message.content} {message} />
|
||||
* ```
|
||||
*/
|
||||
export { default as MarkdownContent } from './MarkdownContent.svelte';
|
||||
|
||||
/**
|
||||
* **SyntaxHighlightedCode** - Code syntax highlighting
|
||||
*
|
||||
* Renders code with syntax highlighting using highlight.js.
|
||||
* Supports theme switching and scrollable containers.
|
||||
*
|
||||
* **Features:**
|
||||
* - Auto language detection with fallback
|
||||
* - Dark/light theme auto-switching
|
||||
* - Scrollable container with configurable max dimensions
|
||||
* - Monospace font styling
|
||||
* - Preserves whitespace and formatting
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <SyntaxHighlightedCode code={jsonString} language="json" />
|
||||
* ```
|
||||
*/
|
||||
export { default as SyntaxHighlightedCode } from './SyntaxHighlightedCode.svelte';
|
||||
|
||||
/**
|
||||
* **CodePreviewDialog** - Full-screen code preview
|
||||
*
|
||||
* Full-screen dialog for previewing HTML/code in an isolated iframe.
|
||||
* Used by MarkdownContent for previewing rendered HTML blocks.
|
||||
*
|
||||
* **Features:**
|
||||
* - Full viewport iframe preview
|
||||
* - Sandboxed execution (allow-scripts only)
|
||||
* - Close button with mix-blend-difference for visibility
|
||||
* - Clears content when closed for security
|
||||
*/
|
||||
export { default as CodePreviewDialog } from './CodePreviewDialog.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* COLLAPSIBLE & EXPANDABLE
|
||||
*
|
||||
* Components for showing/hiding content sections.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **CollapsibleContentBlock** - Expandable content card
|
||||
*
|
||||
* Reusable collapsible card with header, icon, and auto-scroll.
|
||||
* Used for tool calls and reasoning blocks in chat messages.
|
||||
*
|
||||
* **Features:**
|
||||
* - Collapsible content with smooth animation
|
||||
* - Custom icon and title display
|
||||
* - Optional subtitle/status text
|
||||
* - Auto-scroll during streaming (pauses on user scroll)
|
||||
* - Configurable max height with overflow scroll
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <CollapsibleContentBlock
|
||||
* bind:open
|
||||
* icon={BrainIcon}
|
||||
* title="Thinking..."
|
||||
* isStreaming={true}
|
||||
* >
|
||||
* {reasoningContent}
|
||||
* </CollapsibleContentBlock>
|
||||
* ```
|
||||
*/
|
||||
export { default as CollapsibleContentBlock } from './CollapsibleContentBlock.svelte';
|
||||
|
||||
/**
|
||||
* **TruncatedText** - Text with ellipsis and tooltip
|
||||
*
|
||||
* Displays text with automatic truncation and full content in tooltip.
|
||||
* Useful for long names or paths in constrained spaces.
|
||||
*/
|
||||
export { default as TruncatedText } from './TruncatedText.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* DROPDOWNS & MENUS
|
||||
*
|
||||
* Components for dropdown menus and action selection.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **DropdownMenuSearchable** - Filterable dropdown menu
|
||||
*
|
||||
* Generic dropdown with search input for filtering options.
|
||||
* Uses Svelte snippets for flexible content rendering.
|
||||
*
|
||||
* **Features:**
|
||||
* - Search/filter input with clear on close
|
||||
* - Keyboard navigation support
|
||||
* - Custom trigger, content, and footer via snippets
|
||||
* - Empty state message
|
||||
* - Disabled state
|
||||
* - Configurable alignment and width
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DropdownMenuSearchable
|
||||
* bind:open
|
||||
* bind:searchValue
|
||||
* placeholder="Search..."
|
||||
* isEmpty={filteredItems.length === 0}
|
||||
* >
|
||||
* {#snippet trigger()}<Button>Select</Button>{/snippet}
|
||||
* {#snippet children()}{#each items as item}<Item {item} />{/each}{/snippet}
|
||||
* </DropdownMenuSearchable>
|
||||
* ```
|
||||
*/
|
||||
export { default as DropdownMenuSearchable } from './DropdownMenuSearchable.svelte';
|
||||
|
||||
/**
|
||||
* **DropdownMenuActions** - Multi-action dropdown menu
|
||||
*
|
||||
* Dropdown menu for multiple action options with icons and shortcuts.
|
||||
* Supports destructive variants and keyboard shortcut hints.
|
||||
*
|
||||
* **Features:**
|
||||
* - Configurable trigger icon with tooltip
|
||||
* - Action items with icons and labels
|
||||
* - Destructive variant styling
|
||||
* - Keyboard shortcut display
|
||||
* - Separator support between groups
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <DropdownMenuActions
|
||||
* triggerIcon={MoreHorizontal}
|
||||
* triggerTooltip="More actions"
|
||||
* actions={[
|
||||
* { icon: Edit, label: 'Edit', onclick: handleEdit },
|
||||
* { icon: Trash, label: 'Delete', onclick: handleDelete, variant: 'destructive' }
|
||||
* ]}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as DropdownMenuActions } from './DropdownMenuActions.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* BUTTONS & ACTIONS
|
||||
*
|
||||
* Small interactive components for user actions.
|
||||
*
|
||||
*/
|
||||
|
||||
/** Styled button for action triggers with icon support. */
|
||||
export { default as ActionButton } from './ActionButton.svelte';
|
||||
|
||||
/** Copy-to-clipboard button with success feedback. */
|
||||
export { default as CopyToClipboardIcon } from './CopyToClipboardIcon.svelte';
|
||||
|
||||
/** Remove/delete button with X icon. */
|
||||
export { default as RemoveButton } from './RemoveButton.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* BADGES & INDICATORS
|
||||
*
|
||||
* Small visual indicators for status and metadata.
|
||||
*
|
||||
*/
|
||||
|
||||
/** Badge displaying chat statistics (tokens, timing). */
|
||||
export { default as BadgeChatStatistic } from './BadgeChatStatistic.svelte';
|
||||
|
||||
/** Generic info badge with optional tooltip and click handler. */
|
||||
export { default as BadgeInfo } from './BadgeInfo.svelte';
|
||||
|
||||
/** Badge indicating model modality (vision, audio, tools). */
|
||||
export { default as BadgeModality } from './BadgeModality.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* FORMS & INPUTS
|
||||
*
|
||||
* Form-related utility components.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **SearchInput** - Search field with clear button
|
||||
*
|
||||
* Input field optimized for search with clear button and keyboard handling.
|
||||
* Supports placeholder, autofocus, and change callbacks.
|
||||
*/
|
||||
export { default as SearchInput } from './SearchInput.svelte';
|
||||
|
||||
/**
|
||||
* **KeyValuePairs** - Editable key-value list
|
||||
*
|
||||
* Dynamic list of key-value pairs with add/remove functionality.
|
||||
* Used for HTTP headers, metadata, and configuration.
|
||||
*
|
||||
* **Features:**
|
||||
* - Add new pairs with button
|
||||
* - Remove individual pairs
|
||||
* - Customizable placeholders and labels
|
||||
* - Empty state message
|
||||
* - Auto-resize value textarea
|
||||
*/
|
||||
export { default as KeyValuePairs } from './KeyValuePairs.svelte';
|
||||
|
||||
/**
|
||||
* **ConversationSelection** - Multi-select conversation picker
|
||||
*
|
||||
* List of conversations with checkboxes for multi-selection.
|
||||
* Used in import/export dialogs for selecting conversations.
|
||||
*
|
||||
* **Features:**
|
||||
* - Search/filter conversations by name
|
||||
* - Select all / deselect all controls
|
||||
* - Shift-click for range selection
|
||||
* - Message count display per conversation
|
||||
* - Mode-specific UI (export vs import)
|
||||
*/
|
||||
export { default as ConversationSelection } from './ConversationSelection.svelte';
|
||||
|
||||
/**
|
||||
*
|
||||
* KEYBOARD & SHORTCUTS
|
||||
*
|
||||
* Components for displaying keyboard shortcuts.
|
||||
*
|
||||
*/
|
||||
|
||||
/** Display for keyboard shortcut hints (e.g., "⌘ + Enter"). */
|
||||
export { default as KeyboardShortcutInfo } from './KeyboardShortcutInfo.svelte';
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
import { isRouterMode } from '$lib/stores/server.svelte';
|
||||
import {
|
||||
DialogModelInformation,
|
||||
SearchableDropdownMenu,
|
||||
DropdownMenuSearchable,
|
||||
TruncatedText
|
||||
} from '$lib/components/app';
|
||||
import type { ModelOption } from '$lib/types/models';
|
||||
|
|
@ -261,7 +261,7 @@
|
|||
{@const selectedOption = getDisplayOption()}
|
||||
|
||||
{#if isRouter}
|
||||
<SearchableDropdownMenu
|
||||
<DropdownMenuSearchable
|
||||
bind:open={isOpen}
|
||||
onOpenChange={handleOpenChange}
|
||||
bind:searchValue={searchTerm}
|
||||
|
|
@ -392,7 +392,7 @@
|
|||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</SearchableDropdownMenu>
|
||||
</DropdownMenuSearchable>
|
||||
{:else}
|
||||
<button
|
||||
class={cn(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
*
|
||||
* MODELS
|
||||
*
|
||||
* Components for model selection and display. Supports two server modes:
|
||||
* - **Single model mode**: Server runs with one model, selector shows model info
|
||||
* - **Router mode**: Server runs with multiple models, selector enables switching
|
||||
*
|
||||
* Integrates with modelsStore for model data and serverStore for mode detection.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **ModelsSelector** - Model selection dropdown
|
||||
*
|
||||
* Dropdown for selecting AI models with status indicators,
|
||||
* search, and model information display. Adapts UI based on server mode.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Uses DropdownMenuSearchable for model list
|
||||
* - Integrates with modelsStore for model options and selection
|
||||
* - Detects router vs single mode from serverStore
|
||||
* - Opens DialogModelInformation for model details
|
||||
*
|
||||
* **Features:**
|
||||
* - Searchable model list with keyboard navigation
|
||||
* - Model status indicators (loading/ready/error/updating)
|
||||
* - Model capabilities badges (vision, tools, etc.)
|
||||
* - Current/active model highlighting
|
||||
* - Model information dialog on info button click
|
||||
* - Router mode: shows all available models with status
|
||||
* - Single mode: shows current model name only
|
||||
* - Loading/updating skeleton states
|
||||
* - Global selection support for form integration
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ModelsSelector
|
||||
* currentModel={conversation.modelId}
|
||||
* onModelChange={(id, name) => updateModel(id)}
|
||||
* useGlobalSelection
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as ModelsSelector } from './ModelsSelector.svelte';
|
||||
|
||||
/**
|
||||
* **ModelBadge** - Model name display badge
|
||||
*
|
||||
* Compact badge showing current model name with package icon.
|
||||
* Only visible in single model mode. Supports tooltip and copy functionality.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Reads model name from modelsStore or prop
|
||||
* - Checks server mode from serverStore
|
||||
* - Uses BadgeInfo for consistent styling
|
||||
*
|
||||
* **Features:**
|
||||
* - Optional copy to clipboard button
|
||||
* - Optional tooltip with model details
|
||||
* - Click handler for model info dialog
|
||||
* - Only renders in model mode (not router)
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ModelBadge
|
||||
* onclick={() => showModelInfo = true}
|
||||
* showTooltip
|
||||
* showCopyIcon
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as ModelBadge } from './ModelBadge.svelte';
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/**
|
||||
*
|
||||
* SERVER
|
||||
*
|
||||
* Components for displaying server connection state and handling
|
||||
* connection errors. Integrates with serverStore for state management.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* **ServerStatus** - Server connection status indicator
|
||||
*
|
||||
* Compact status display showing connection state, model name,
|
||||
* and context size. Used in headers and loading screens.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Reads state from serverStore (props, loading, error)
|
||||
* - Displays model name from modelsStore
|
||||
*
|
||||
* **Features:**
|
||||
* - Status dot: green (connected), yellow (connecting), red (error), gray (unknown)
|
||||
* - Status text label
|
||||
* - Model name badge with icon
|
||||
* - Context size badge
|
||||
* - Optional error action button
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ServerStatus showActions />
|
||||
* ```
|
||||
*/
|
||||
export { default as ServerStatus } from './ServerStatus.svelte';
|
||||
|
||||
/**
|
||||
* **ServerErrorSplash** - Full-screen connection error display
|
||||
*
|
||||
* Blocking error screen shown when server connection fails.
|
||||
* Provides retry options and API key input for authentication errors.
|
||||
*
|
||||
* **Architecture:**
|
||||
* - Detects access denied errors for API key flow
|
||||
* - Validates API key against server before saving
|
||||
* - Integrates with settingsStore for API key persistence
|
||||
*
|
||||
* **Features:**
|
||||
* - Error message display with icon
|
||||
* - Retry connection button with loading state
|
||||
* - API key input for authentication errors
|
||||
* - API key validation with success/error feedback
|
||||
* - Troubleshooting section with server start commands
|
||||
* - Animated transitions for UI elements
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ServerErrorSplash
|
||||
* error={serverError}
|
||||
* onRetry={handleRetry}
|
||||
* showTroubleshooting
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export { default as ServerErrorSplash } from './ServerErrorSplash.svelte';
|
||||
|
||||
/**
|
||||
* **ServerLoadingSplash** - Full-screen loading display
|
||||
*
|
||||
* Shown during initial server connection. Displays loading animation
|
||||
* with ServerStatus component for real-time connection state.
|
||||
*
|
||||
* **Features:**
|
||||
* - Animated server icon
|
||||
* - Customizable loading message
|
||||
* - Embedded ServerStatus for live updates
|
||||
*
|
||||
* @example
|
||||
* ```svelte
|
||||
* <ServerLoadingSplash message="Connecting to server..." />
|
||||
* ```
|
||||
*/
|
||||
export { default as ServerLoadingSplash } from './ServerLoadingSplash.svelte';
|
||||
|
|
@ -24,84 +24,64 @@ type ReasoningSegment = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Strips partial marker from text content
|
||||
*
|
||||
* Removes incomplete agentic markers (e.g., "<<<", "<<<AGENTIC") that may appear
|
||||
* at the end of streaming content.
|
||||
*
|
||||
* @param text - The text content to process
|
||||
* @returns Text with partial markers removed
|
||||
*/
|
||||
function stripPartialMarker(text: string): string {
|
||||
const partialMarkerMatch = text.match(AGENTIC_REGEX.PARTIAL_MARKER);
|
||||
if (partialMarkerMatch) {
|
||||
return text.slice(0, partialMarkerMatch.index).trim();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits raw content into segments based on reasoning blocks
|
||||
*
|
||||
* Identifies and extracts reasoning content wrapped in REASONING_TAGS.START/END markers,
|
||||
* separating it from regular text content. Handles both complete and incomplete
|
||||
* (streaming) reasoning blocks.
|
||||
*
|
||||
* Parses agentic content into structured sections
|
||||
*
|
||||
* Main parsing function that processes content containing:
|
||||
* - Tool calls (completed, pending, or streaming)
|
||||
* - Reasoning blocks (completed or streaming)
|
||||
* - Regular text content
|
||||
*
|
||||
* The parser handles chronological display of agentic flow output, maintaining
|
||||
* the order of operations and properly identifying different states of tool calls
|
||||
* and reasoning blocks during streaming.
|
||||
*
|
||||
* @param rawContent - The raw content string to parse
|
||||
* @returns Array of reasoning segments with their types and content
|
||||
* @returns Array of structured agentic sections ready for display
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const content = "Some text <<<AGENTIC_TOOL_CALL>>>tool_name...";
|
||||
* const sections = parseAgenticContent(content);
|
||||
* // Returns: [{ type: 'text', content: 'Some text' }, { type: 'tool_call_streaming', ... }]
|
||||
* ```
|
||||
*/
|
||||
function splitReasoningSegments(rawContent: string): ReasoningSegment[] {
|
||||
export function parseAgenticContent(rawContent: string): AgenticSection[] {
|
||||
if (!rawContent) return [];
|
||||
|
||||
const segments: ReasoningSegment[] = [];
|
||||
let cursor = 0;
|
||||
const segments = splitReasoningSegments(rawContent);
|
||||
const sections: AgenticSection[] = [];
|
||||
|
||||
while (cursor < rawContent.length) {
|
||||
const startIndex = rawContent.indexOf(REASONING_TAGS.START, cursor);
|
||||
if (startIndex === -1) {
|
||||
const remainingText = rawContent.slice(cursor);
|
||||
if (remainingText) {
|
||||
segments.push({ type: AgenticSectionType.TEXT, content: remainingText });
|
||||
for (const segment of segments) {
|
||||
if (segment.type === 'text') {
|
||||
sections.push(...parseToolCallContent(segment.content));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (segment.type === 'reasoning') {
|
||||
if (segment.content.trim()) {
|
||||
sections.push({ type: AgenticSectionType.REASONING, content: segment.content });
|
||||
}
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startIndex > cursor) {
|
||||
const textBefore = rawContent.slice(cursor, startIndex);
|
||||
if (textBefore) {
|
||||
segments.push({ type: AgenticSectionType.TEXT, content: textBefore });
|
||||
}
|
||||
}
|
||||
|
||||
const contentStart = startIndex + REASONING_TAGS.START.length;
|
||||
const endIndex = rawContent.indexOf(REASONING_TAGS.END, contentStart);
|
||||
|
||||
if (endIndex === -1) {
|
||||
const pendingContent = rawContent.slice(contentStart);
|
||||
segments.push({
|
||||
type: AgenticSectionType.REASONING_PENDING,
|
||||
content: stripPartialMarker(pendingContent)
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
const reasoningContent = rawContent.slice(contentStart, endIndex);
|
||||
segments.push({ type: AgenticSectionType.REASONING, content: reasoningContent });
|
||||
cursor = endIndex + REASONING_TAGS.END.length;
|
||||
sections.push({
|
||||
type: AgenticSectionType.REASONING_PENDING,
|
||||
content: segment.content
|
||||
});
|
||||
}
|
||||
|
||||
return segments;
|
||||
return sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses content containing tool call markers
|
||||
*
|
||||
*
|
||||
* Identifies and extracts tool calls from content, handling:
|
||||
* - Completed tool calls with name, arguments, and results
|
||||
* - Pending tool calls (execution in progress)
|
||||
* - Streaming tool calls (arguments being received)
|
||||
* - Early-stage tool calls (just started)
|
||||
*
|
||||
*
|
||||
* @param rawContent - The raw content string to parse
|
||||
* @returns Array of agentic sections representing tool calls and text
|
||||
*/
|
||||
|
|
@ -221,51 +201,71 @@ function parseToolCallContent(rawContent: string): AgenticSection[] {
|
|||
}
|
||||
|
||||
/**
|
||||
* Parses agentic content into structured sections
|
||||
*
|
||||
* Main parsing function that processes content containing:
|
||||
* - Tool calls (completed, pending, or streaming)
|
||||
* - Reasoning blocks (completed or streaming)
|
||||
* - Regular text content
|
||||
*
|
||||
* The parser handles chronological display of agentic flow output, maintaining
|
||||
* the order of operations and properly identifying different states of tool calls
|
||||
* and reasoning blocks during streaming.
|
||||
*
|
||||
* @param rawContent - The raw content string to parse
|
||||
* @returns Array of structured agentic sections ready for display
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const content = "Some text <<<AGENTIC_TOOL_CALL>>>tool_name...";
|
||||
* const sections = parseAgenticContent(content);
|
||||
* // Returns: [{ type: 'text', content: 'Some text' }, { type: 'tool_call_streaming', ... }]
|
||||
* ```
|
||||
* Strips partial marker from text content
|
||||
*
|
||||
* Removes incomplete agentic markers (e.g., "<<<", "<<<AGENTIC") that may appear
|
||||
* at the end of streaming content.
|
||||
*
|
||||
* @param text - The text content to process
|
||||
* @returns Text with partial markers removed
|
||||
*/
|
||||
export function parseAgenticContent(rawContent: string): AgenticSection[] {
|
||||
function stripPartialMarker(text: string): string {
|
||||
const partialMarkerMatch = text.match(AGENTIC_REGEX.PARTIAL_MARKER);
|
||||
if (partialMarkerMatch) {
|
||||
return text.slice(0, partialMarkerMatch.index).trim();
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits raw content into segments based on reasoning blocks
|
||||
*
|
||||
* Identifies and extracts reasoning content wrapped in REASONING_TAGS.START/END markers,
|
||||
* separating it from regular text content. Handles both complete and incomplete
|
||||
* (streaming) reasoning blocks.
|
||||
*
|
||||
* @param rawContent - The raw content string to parse
|
||||
* @returns Array of reasoning segments with their types and content
|
||||
*/
|
||||
function splitReasoningSegments(rawContent: string): ReasoningSegment[] {
|
||||
if (!rawContent) return [];
|
||||
|
||||
const segments = splitReasoningSegments(rawContent);
|
||||
const sections: AgenticSection[] = [];
|
||||
const segments: ReasoningSegment[] = [];
|
||||
let cursor = 0;
|
||||
|
||||
for (const segment of segments) {
|
||||
if (segment.type === 'text') {
|
||||
sections.push(...parseToolCallContent(segment.content));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (segment.type === 'reasoning') {
|
||||
if (segment.content.trim()) {
|
||||
sections.push({ type: AgenticSectionType.REASONING, content: segment.content });
|
||||
while (cursor < rawContent.length) {
|
||||
const startIndex = rawContent.indexOf(REASONING_TAGS.START, cursor);
|
||||
if (startIndex === -1) {
|
||||
const remainingText = rawContent.slice(cursor);
|
||||
if (remainingText) {
|
||||
segments.push({ type: AgenticSectionType.TEXT, content: remainingText });
|
||||
}
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
sections.push({
|
||||
type: AgenticSectionType.REASONING_PENDING,
|
||||
content: segment.content
|
||||
});
|
||||
if (startIndex > cursor) {
|
||||
const textBefore = rawContent.slice(cursor, startIndex);
|
||||
if (textBefore) {
|
||||
segments.push({ type: AgenticSectionType.TEXT, content: textBefore });
|
||||
}
|
||||
}
|
||||
|
||||
const contentStart = startIndex + REASONING_TAGS.START.length;
|
||||
const endIndex = rawContent.indexOf(REASONING_TAGS.END, contentStart);
|
||||
|
||||
if (endIndex === -1) {
|
||||
const pendingContent = rawContent.slice(contentStart);
|
||||
segments.push({
|
||||
type: AgenticSectionType.REASONING_PENDING,
|
||||
content: stripPartialMarker(pendingContent)
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
const reasoningContent = rawContent.slice(contentStart, endIndex);
|
||||
segments.push({ type: AgenticSectionType.REASONING, content: reasoningContent });
|
||||
cursor = endIndex + REASONING_TAGS.END.length;
|
||||
}
|
||||
|
||||
return sections;
|
||||
return segments;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue