diff --git a/docs/features/prompt-repository/playground.mdx b/docs/features/prompt-repository/playground.mdx index 34107d04c3..caffea4080 100644 --- a/docs/features/prompt-repository/playground.mdx +++ b/docs/features/prompt-repository/playground.mdx @@ -12,7 +12,7 @@ The **Playground** in Bifrost is an interactive workspace for building, testing, ## How it Works -The playground is built around three core concepts: **prompts, sessions, and versions**. +The playground is built around four core concepts: **Prompts, Sessions, and Versions**. ### Folders @@ -130,7 +130,7 @@ Configure the provider, model, and parameters from the settings panel on the rig -Click **Run** or press `Cmd + enter` / `Ctrl + enter`. +Click **Run** or press `Cmd + S` / `Ctrl + S`. Optionally, if you do not want to execute the prompt and only want to add a message to history, use the **+ Add** button. diff --git a/ui/components/prompts/components/messagesView/assistantMessageView.tsx b/ui/components/prompts/components/messagesView/assistantMessageView.tsx index 57b58ed721..9577386d19 100644 --- a/ui/components/prompts/components/messagesView/assistantMessageView.tsx +++ b/ui/components/prompts/components/messagesView/assistantMessageView.tsx @@ -8,6 +8,18 @@ import MessageRoleSwitcher from "./messageRoleSwitcher"; import { isJson } from "@/lib/utils/validation"; import { CodeEditor } from "@/components/ui/codeEditor"; +/** + * Renders the assistant message UI including role switcher, usage tooltip, edit/delete controls, and editable or view-only content. + * + * The component allows inline editing of plain text or JSON content (JSON edits are buffered and committed on blur), toggling role, and removing the message. Clicking outside the component exits edit mode. + * + * @param message - The message model to display and edit; updates are emitted via `onChange` as the message's serialized form. + * @param disabled - When true, disables editing, role changes, and delete action. + * @param isStreaming - When true, shows streaming state (loading indicator) and prevents entering edit mode. + * @param onChange - Called when the message is modified; receives the message's serialized representation. + * @param onRemove - Optional callback invoked when the delete action is triggered. + * @returns The rendered assistant message element. + */ export function AssistantMessageView({ message, disabled, diff --git a/ui/components/prompts/components/messagesView/attachmentViews.tsx b/ui/components/prompts/components/messagesView/attachmentViews.tsx index f678dd64a5..05b76a3d09 100644 --- a/ui/components/prompts/components/messagesView/attachmentViews.tsx +++ b/ui/components/prompts/components/messagesView/attachmentViews.tsx @@ -1,6 +1,18 @@ import { MessageContent } from "@/lib/message"; import { Mic, FileIcon, XIcon } from "lucide-react"; +/** + * Renders a compact badge for a single attachment with an inline remove control. + * + * Displays different visuals based on the attachment type: + * - image_url with a valid URL: a thumbnail and the label "Image" + * - input_audio: a microphone icon and the audio format in uppercase or "Audio" + * - other: a file icon and the filename or "File" + * + * @param attachment - The attachment to display; its `type` determines the badge content. + * @param onRemove - Callback invoked when the badge's remove button is clicked. + * @returns The rendered attachment badge element. + */ export function AttachmentBadge({ attachment, onRemove }: { attachment: MessageContent; onRemove: () => void }) { const isImage = attachment.type === "image_url"; const isAudio = attachment.type === "input_audio"; @@ -34,6 +46,21 @@ export function AttachmentBadge({ attachment, onRemove }: { attachment: MessageC ); } +/** + * Renders a compact list of attachment previews (images, audio controls, or file rows). + * + * Renders each attachment according to its type: + * - image_url with a URL: an image thumbnail + * - input_audio: an HTML audio control built from base64 data + * - file: a row with a file icon, filename, and optional file type + * + * When `editable` is true and `onRemoveAttachment` is provided, a remove button is shown for each attachment and invokes the callback with the attachment's index when clicked. + * + * @param attachments - The attachments to render. + * @param editable - If true, show per-attachment remove controls. + * @param onRemoveAttachment - Callback invoked with the attachment index when a remove control is clicked. + * @returns A JSX element containing the rendered attachments, or `null` when `attachments` is empty. + */ export function AttachmentDisplay({ attachments, editable, diff --git a/ui/components/prompts/components/messagesView/errorMessageView.tsx b/ui/components/prompts/components/messagesView/errorMessageView.tsx index 01c626d384..3e53a27430 100644 --- a/ui/components/prompts/components/messagesView/errorMessageView.tsx +++ b/ui/components/prompts/components/messagesView/errorMessageView.tsx @@ -1,6 +1,14 @@ import { Message } from "@/lib/message"; import { AlertCircle, XIcon } from "lucide-react"; +/** + * Render a styled error message block with an optional delete control. + * + * @param message - The message object whose `content` is displayed inside the error block. + * @param disabled - When true, the remove button is not rendered. + * @param onRemove - Callback invoked when the delete button is clicked. + * @returns The React element that displays the error message view. + */ export default function ErrorMessageView({ message, disabled, onRemove }: { message: Message; disabled?: boolean; onRemove?: () => void }) { return (
diff --git a/ui/components/prompts/components/messagesView/messageRoleSwitcher.tsx b/ui/components/prompts/components/messagesView/messageRoleSwitcher.tsx index 0d697aab88..48aff12e8c 100644 --- a/ui/components/prompts/components/messagesView/messageRoleSwitcher.tsx +++ b/ui/components/prompts/components/messagesView/messageRoleSwitcher.tsx @@ -9,6 +9,15 @@ const AVAILABLE_ROLES = [ { value: "tool", label: "Tool" }, ] as const; +/** + * Render a dropdown that lets the user switch the current message role. + * + * @param role - The currently selected role value shown in the trigger + * @param disabled - If true, disables interaction with the trigger + * @param onRoleChange - Callback invoked with the newly selected role value + * @param restrictedRoles - Optional list of role values that should be excluded from the menu + * @returns A JSX element rendering the role selection dropdown + */ export default function MessageRoleSwitcher({ role, disabled, diff --git a/ui/components/prompts/components/messagesView/rootMessageView.tsx b/ui/components/prompts/components/messagesView/rootMessageView.tsx index 21b95b323d..0a1eacb16a 100644 --- a/ui/components/prompts/components/messagesView/rootMessageView.tsx +++ b/ui/components/prompts/components/messagesView/rootMessageView.tsx @@ -8,6 +8,11 @@ import ToolResultMessageView from "./toolCallResultView"; import ToolCallMessageView from "./toolCallView"; import ErrorMessageView from "./errorMessageView"; +/** + * Render and manage the chat messages list, mapping each message to its appropriate view, handling edits, removals, variable recomputation, and automatic scrolling during streaming. + * + * @returns A React element that renders the messages list and provides handlers for message changes, removals, tool submissions, and variable updates. + */ export function MessagesView() { const { messages, setMessages: onUpdateMessages, setVariables, isStreaming, supportsVision, handleSubmitToolResult } = usePromptContext(); const messagesEndRef = useRef(null); diff --git a/ui/components/prompts/components/messagesView/systemMessageView.tsx b/ui/components/prompts/components/messagesView/systemMessageView.tsx index 3d4d584af1..6f632bc16c 100644 --- a/ui/components/prompts/components/messagesView/systemMessageView.tsx +++ b/ui/components/prompts/components/messagesView/systemMessageView.tsx @@ -9,6 +9,15 @@ import MessageRoleSwitcher from "./messageRoleSwitcher"; import { RichTextarea } from "@/components/ui/custom/richTextarea"; import { JINJA_VAR_HIGHLIGHT_PATTERNS, JINJA_VAR_REGEX } from "@/lib/message/constant"; +/** + * Renders an editable system message block that supports role switching, rich-text editing, JSON editing with buffered changes, Jinja variable highlighting, and optional removal. + * + * @param message - The message model to display and edit. + * @param disabled - When true, disables interactions and makes the view read-only. + * @param onChange - Called with the message's serialized representation when the message is modified (role or content). + * @param onRemove - Optional callback invoked when the message should be removed. + * @returns The rendered system message JSX element. + */ export function SystemMessageView({ message, disabled, diff --git a/ui/components/prompts/components/messagesView/toolCallResultView.tsx b/ui/components/prompts/components/messagesView/toolCallResultView.tsx index 8042d33d03..e0dd3bd66d 100644 --- a/ui/components/prompts/components/messagesView/toolCallResultView.tsx +++ b/ui/components/prompts/components/messagesView/toolCallResultView.tsx @@ -6,6 +6,20 @@ import { PencilIcon, XIcon } from "lucide-react"; import { useEffect, useMemo, useRef, useState } from "react"; import MessageRoleSwitcher from "./messageRoleSwitcher"; +/** + * Renders an editable view for a tool result message that supports role switching, inline text editing, JSON-aware editing, and removal. + * + * The component presents the message role selector, optional tool call id, edit/delete actions, and a content area that: + * - shows a textarea for freeform editing when in edit mode, + * - shows a JSON-aware code editor (with edits buffered and flushed on blur) when the content is valid JSON, + * - shows a read-only monospaced display when content is plain text, + * - shows a placeholder when content is empty. + * + * @param message - The Message instance to display and edit; updates emitted via `onChange` are serialized from clones of this message. + * @param disabled - When true, disables interactive controls and makes editors read-only. + * @param onChange - Called with the message's serialized form whenever the message is modified (role, content edits, or flushed JSON buffer). + * @param onRemove - Optional callback invoked when the user requests deletion of the message. + */ export default function ToolResultMessageView({ message, disabled, diff --git a/ui/components/prompts/components/messagesView/toolCallView.tsx b/ui/components/prompts/components/messagesView/toolCallView.tsx index 5f47103cb0..65de0d4a8a 100644 --- a/ui/components/prompts/components/messagesView/toolCallView.tsx +++ b/ui/components/prompts/components/messagesView/toolCallView.tsx @@ -7,6 +7,20 @@ import { Wrench, XIcon } from "lucide-react"; import { useRef, useState } from "react"; import MessageRoleSwitcher from "./messageRoleSwitcher"; +/** + * Renders a UI for viewing and editing tool-call entries on a message, including optional argument editing and submitting tool responses. + * + * The component displays each tool call's name, id, and arguments (JSON arguments open in an editable code editor). JSON edits are buffered locally and only committed to `onChange` when the editor loses focus or when the message role changes. The component also exposes controls for switching the message role, deleting the message, and entering/submitting a response for individual tool calls. + * + * @param message - Message instance containing zero or more toolCalls to render; edits are serialized via `onChange`. + * @param disabled - When true, disables interactive controls and makes editors read-only. + * @param onChange - Called with the message's serialized form after committed edits (e.g., buffered JSON arguments flushed or role changed). + * @param onRemove - If provided, called when the delete button is clicked. + * @param onSubmitToolResult - If provided, called with (toolCallId, content) when a user submits a response for a tool call. + * @param respondedToolCallIds - Optional set of toolCall ids that have already received responses; tool calls in this set hide the response UI. + * + * @returns The rendered React element for the tool-call message view. + */ export default function ToolCallMessageView({ message, disabled, diff --git a/ui/components/prompts/components/messagesView/userMessageView.tsx b/ui/components/prompts/components/messagesView/userMessageView.tsx index f090f62bc1..fc8da8965f 100644 --- a/ui/components/prompts/components/messagesView/userMessageView.tsx +++ b/ui/components/prompts/components/messagesView/userMessageView.tsx @@ -11,6 +11,16 @@ import { AttachmentDisplay } from "./attachmentViews"; import { isJson } from "@/lib/utils/validation"; import { CodeEditor } from "@/components/ui/codeEditor"; +/** + * Render an interactive user message block that supports viewing and editing content, role switching, file attachments (via picker or drag-and-drop), and special handling for JSON and Jinja-variable content. + * + * @param message - The message model to render and edit; its updates are emitted via `onChange`. + * @param disabled - When true, disables editing and attachment interactions. + * @param supportsVision - When true, enables attaching files (images, audio, documents) and drag-and-drop attachments. + * @param onChange - Called with the message's serialized form whenever the message is modified (content, role, or attachments). + * @param onRemove - Optional callback invoked when the message's delete action is triggered. + * @returns The JSX element that renders the user message view and its interactive controls. + */ export function UserMessageView({ message, disabled, diff --git a/ui/components/prompts/fragments/sidebar.tsx b/ui/components/prompts/fragments/sidebar.tsx index f9b9d930aa..8f3dc6f053 100644 --- a/ui/components/prompts/fragments/sidebar.tsx +++ b/ui/components/prompts/fragments/sidebar.tsx @@ -28,6 +28,13 @@ import { usePathname } from "next/navigation"; import { DragDropProvider, useDraggable, useDroppable } from "@dnd-kit/react"; import { usePromptContext } from "../context"; +/** + * Renders the prompt-manager sidebar including search, folder hierarchy, root prompts, and drag-and-drop reorganization. + * + * The sidebar supports creating, renaming, and deleting folders and prompts (when permitted), selecting prompts, auto-expanding the folder that contains the selected prompt, filtering by search query, and dragging prompts between folders or to the root. Visual drag-over feedback and permission gating for create/update/delete actions are applied. + * + * @returns The sidebar React element containing the search input, folder list, root prompt drop zone, and drag-and-drop provider. + */ export function PromptSidebar() { const { folders, @@ -272,6 +279,19 @@ interface RootDropZoneProps { canDelete: boolean; } +/** + * Renders the droppable root area that lists and hosts draggable root-level prompts. + * + * @param isDragOver - Whether a draggable item is currently over the root drop zone (applies drag-over styling). + * @param rootPrompts - Array of prompts that belong at the root (no folder). + * @param selectedPromptId - ID of the currently selected prompt, used to mark its item as selected. + * @param onSelectPrompt - Callback invoked with a prompt ID when a prompt is selected. + * @param onEditPrompt - Callback invoked with a prompt when the prompt's edit action is triggered. + * @param onDeletePrompt - Callback invoked with a prompt when the prompt's delete action is triggered. + * @param canUpdate - Whether prompts are movable/editable (enables dragging). + * @param canDelete - Whether prompts may be deleted (controls delete action visibility). + * @returns The JSX element for the root drop zone containing draggable prompt items. + */ function RootDropZone({ isDragOver, rootPrompts, @@ -320,6 +340,26 @@ interface DroppableFolderProps { canDelete: boolean; } +/** + * Renders a droppable folder header with optional action menu and its list of prompts. + * + * @param folder - Folder metadata (id, name, etc.) + * @param prompts - Prompts that belong to this folder + * @param isExpanded - Whether the folder is expanded to show its prompts + * @param isDragOver - Whether a draggable item is currently over this folder (affects visual state) + * @param selectedPromptId - ID of the currently selected prompt, used to highlight an item + * @param onToggle - Callback invoked to toggle the folder's expanded state + * @param onSelectPrompt - Callback invoked with a prompt ID when a prompt is selected + * @param onEdit - Callback invoked to start editing the folder + * @param onDelete - Callback invoked to start deleting the folder + * @param onCreatePrompt - Callback invoked to create a new prompt inside this folder + * @param onEditPrompt - Callback invoked with a prompt to start editing that prompt + * @param onDeletePrompt - Callback invoked with a prompt to start deleting that prompt + * @param canCreate - Whether the current user may create prompts in this folder + * @param canUpdate - Whether the current user may move/rename prompts or edit the folder + * @param canDelete - Whether the current user may delete prompts or the folder + * @returns A JSX element containing the folder row and, when expanded, its nested prompt items + */ function DroppableFolder({ folder, prompts, @@ -455,6 +495,20 @@ interface DraggablePromptItemProps { canDelete: boolean; } +/** + * Renders a draggable prompt list item that shows the prompt name, selection/drag states, and an actions menu when permitted. + * + * Displays a file icon and truncated prompt name, applies visual styles for selection and dragging, prevents selection while dragging, and exposes rename/delete actions via a dropdown when `canUpdate` or `canDelete` are true. + * + * @param prompt - The prompt object to render. + * @param isSelected - Whether this prompt is currently selected; used for styling. + * @param onSelect - Callback invoked when the item is clicked (not invoked if the item is being dragged). + * @param onEdit - Callback invoked to start editing/renaming the prompt. + * @param onDelete - Callback invoked to delete the prompt. + * @param canUpdate - When true, enables dragging and shows the rename action. + * @param canDelete - When true, shows the delete action. + * @returns The rendered prompt item JSX element. + */ function DraggablePromptItem({ prompt, isSelected, onSelect, onEdit, onDelete, canUpdate, canDelete }: DraggablePromptItemProps) { const { ref, isDragging } = useDraggable({ id: `prompt-${prompt.id}`, disabled: !canUpdate }); const showActions = canUpdate || canDelete;