@promptbook/components 0.112.0-96 → 0.112.0-98

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esm/index.es.js CHANGED
@@ -42,7 +42,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
42
42
  * @generated
43
43
  * @see https://github.com/webgptorg/promptbook
44
44
  */
45
- const PROMPTBOOK_ENGINE_VERSION = '0.112.0-96';
45
+ const PROMPTBOOK_ENGINE_VERSION = '0.112.0-98';
46
46
  /**
47
47
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
48
48
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -21780,7 +21780,7 @@ function normalizeSanitizedUrlValue(value) {
21780
21780
  return Array.from(value.trim())
21781
21781
  .filter((character) => {
21782
21782
  const characterCode = character.charCodeAt(0);
21783
- return (characterCode > MAX_ASCII_CONTROL_CHARACTER_CODE && characterCode !== ASCII_DELETE_CHARACTER_CODE);
21783
+ return characterCode > MAX_ASCII_CONTROL_CHARACTER_CODE && characterCode !== ASCII_DELETE_CHARACTER_CODE;
21784
21784
  })
21785
21785
  .join('');
21786
21786
  }
@@ -26144,6 +26144,24 @@ const ResetIcon = () => (jsx("svg", { width: "16", height: "16", viewBox: "0 0 2
26144
26144
  */
26145
26145
  const TemplateIcon = ({ size }) => (jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "currentColor", children: jsx("path", { d: "M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z" }) }));
26146
26146
 
26147
+ /**
26148
+ * Builds one normalized filename for a chat export download.
26149
+ *
26150
+ * @param title - Human-readable chat title.
26151
+ * @param fileExtension - Output file extension without a leading dot.
26152
+ * @param date - Export date used in the filename.
26153
+ * @returns Stable filename suitable for browser downloads and HTTP headers.
26154
+ *
26155
+ * @private Internal helper shared by chat export flows.
26156
+ */
26157
+ function createChatExportFilename(title, fileExtension, date = new Date()) {
26158
+ const dateName = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date
26159
+ .getDate()
26160
+ .toString()
26161
+ .padStart(2, '0')}`;
26162
+ return `${normalizeToKebabCase(title)}-${dateName}.${fileExtension}`;
26163
+ }
26164
+
26147
26165
  /**
26148
26166
  * Maximum number of characters shown for a simplified knowledge label.
26149
26167
  *
@@ -28183,7 +28201,7 @@ function getChatSaveFormatDefinitions(formatNames) {
28183
28201
  */
28184
28202
  function ChatActionsBar(props) {
28185
28203
  var _a;
28186
- const { actionsRef, actionsContainer, messages, participants, title, onReset, resetRequiresConfirmation = true, newChatButtonHref, onUseTemplate, extraActions, saveFormats, isSaveButtonEnabled, shouldFadeActions, shouldDisableActions, chatUiTranslations, onButtonClick, } = props;
28204
+ const { actionsRef, actionsContainer, messages, participants, title, onReset, resetRequiresConfirmation = true, newChatButtonHref, onUseTemplate, extraActions, saveFormats, saveFormatHandlers, isSaveButtonEnabled, shouldFadeActions, shouldDisableActions, chatUiTranslations, onButtonClick, } = props;
28187
28205
  const [showSaveMenu, setShowSaveMenu] = useState(false);
28188
28206
  useEffect(() => {
28189
28207
  const handleKeyDown = (event) => {
@@ -28199,21 +28217,26 @@ function ChatActionsBar(props) {
28199
28217
  };
28200
28218
  }, []);
28201
28219
  const handleDownload = useCallback(async (format) => {
28220
+ const customSaveFormatHandler = saveFormatHandlers === null || saveFormatHandlers === void 0 ? void 0 : saveFormatHandlers[format];
28221
+ if (customSaveFormatHandler) {
28222
+ await customSaveFormatHandler({
28223
+ title,
28224
+ messages,
28225
+ participants,
28226
+ });
28227
+ setShowSaveMenu(false);
28228
+ return;
28229
+ }
28202
28230
  const formatDefinition = getChatSaveFormatDefinitions([format])[0];
28203
28231
  if (!formatDefinition) {
28204
28232
  return;
28205
28233
  }
28206
- const date = new Date();
28207
- const dateName = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date
28208
- .getDate()
28209
- .toString()
28210
- .padStart(2, '0')}`;
28211
28234
  const content = await formatDefinition.getContent({ title, messages, participants });
28212
28235
  const blob = new Blob([content], { type: formatDefinition.mimeType });
28213
28236
  const url = URL.createObjectURL(blob);
28214
28237
  const link = document.createElement('a');
28215
28238
  link.href = url;
28216
- link.download = `${normalizeToKebabCase(title)}-${dateName}.${formatDefinition.fileExtension}`;
28239
+ link.download = createChatExportFilename(title, formatDefinition.fileExtension);
28217
28240
  document.body.appendChild(link);
28218
28241
  link.click();
28219
28242
  setTimeout(() => {
@@ -28221,7 +28244,7 @@ function ChatActionsBar(props) {
28221
28244
  URL.revokeObjectURL(url);
28222
28245
  }, 100);
28223
28246
  setShowSaveMenu(false);
28224
- }, [messages, participants, title]);
28247
+ }, [messages, participants, saveFormatHandlers, title]);
28225
28248
  const firstMessageFromUser = ((_a = messages[0]) === null || _a === void 0 ? void 0 : _a.sender) === 'USER';
28226
28249
  const actionsAlignmentClass = classNames(styles$5.actions, firstMessageFromUser ? styles$5.left : styles$5.right);
28227
28250
  const newChatButtonLabel = (chatUiTranslations === null || chatUiTranslations === void 0 ? void 0 : chatUiTranslations.newChatButtonLabel) || 'New chat';
@@ -40014,7 +40037,7 @@ function hasChatActions(postprocessedMessages, { onReset, newChatButtonHref, onU
40014
40037
  * @public exported from `@promptbook/components`
40015
40038
  */
40016
40039
  function Chat(props) {
40017
- const { title = 'Chat', messages, onChange, onMessage, onActionButton, onQuickMessageButton, onReplyToMessage, onCancelReply, onReset, resetRequiresConfirmation = true, newChatButtonHref, onFeedback, feedbackMode = 'stars', feedbackTranslations, timingTranslations, onFileUpload, chatLocale, speechRecognition, placeholderMessageContent, defaultMessage, enterBehavior, resolveEnterBehavior, children, className, style, isAiTextHumanizedAndPromptbookified = true, isVoiceCalling = false, isFocusedOnLoad, participants = [], canReplyToMessage, replyingToMessage, extraActions, actionsContainer, saveFormats, isSaveButtonEnabled = true, isCopyButtonEnabled = true, buttonColor: buttonColorRaw, onUseTemplate, onCreateAgent, toolTitles, teammates, teamAgentProfiles, layout, visualMode = 'ARTICLE_MODE', theme = 'LIGHT', effectConfigs, soundSystem, speechRecognitionLanguage, isSpeechPlaybackEnabled = true, elevenLabsVoiceId, chatUiTranslations, } = props;
40040
+ const { title = 'Chat', messages, onChange, onMessage, onActionButton, onQuickMessageButton, onReplyToMessage, onCancelReply, onReset, resetRequiresConfirmation = true, newChatButtonHref, onFeedback, feedbackMode = 'stars', feedbackTranslations, timingTranslations, onFileUpload, chatLocale, speechRecognition, placeholderMessageContent, defaultMessage, enterBehavior, resolveEnterBehavior, children, className, style, isAiTextHumanizedAndPromptbookified = true, isVoiceCalling = false, isFocusedOnLoad, participants = [], canReplyToMessage, replyingToMessage, extraActions, actionsContainer, saveFormats, saveFormatHandlers, isSaveButtonEnabled = true, isCopyButtonEnabled = true, buttonColor: buttonColorRaw, onUseTemplate, onCreateAgent, toolTitles, teammates, teamAgentProfiles, layout, visualMode = 'ARTICLE_MODE', theme = 'LIGHT', effectConfigs, soundSystem, speechRecognitionLanguage, isSpeechPlaybackEnabled = true, elevenLabsVoiceId, chatUiTranslations, } = props;
40018
40041
  const buttonColor = useMemo(() => Color.from(buttonColorRaw || '#0066cc'), [buttonColorRaw]);
40019
40042
  const agentParticipant = useMemo(() => participants.find((participant) => participant.name === 'AGENT'), [participants]);
40020
40043
  const postprocessedMessages = useChatPostprocessedMessages({
@@ -40059,7 +40082,7 @@ function Chat(props) {
40059
40082
  useChatCompleteNotification(messages, soundSystem);
40060
40083
  return (jsxs(Fragment, { children: [feedbackStatus && (jsx("div", { className: classNames(styles$5.feedbackStatus, feedbackStatus.variant === 'success'
40061
40084
  ? styles$5.feedbackStatusSuccess
40062
- : styles$5.feedbackStatusError), "aria-live": "polite", role: "status", children: feedbackStatus.message })), effectConfigs && effectConfigs.length > 0 && (jsx(ChatEffectsSystem, { messages: postprocessedMessages, effectConfigs: effectConfigs, soundSystem: soundSystem })), jsx("div", { className: classNames(className, styles$5.Chat, layout === 'STANDALONE' && styles$5.standaloneVisual, layout === 'FULL_PAGE' && styles$5.fullPageVisual, isConstrainedArticleMode && styles$5.constrainedArticleVisual, getChatCssClassName('Chat'), chatCssClassNames.chat), "data-chat-theme": mode.toLowerCase(), style, children: jsxs("div", { className: classNames(className, styles$5.chatMainFlow, getChatCssClassName('chatMainFlow'), chatCssClassNames.chatMainFlow), children: [children && jsx("div", { className: classNames(styles$5.chatChildren), children: children }), shouldShowScrollToBottom && (jsx("div", { className: styles$5.scrollToBottomContainer, children: jsxs("div", { className: styles$5.scrollToBottomWrapper, children: [jsx(SolidArrowButton, { "data-button-type": "custom", direction: "down", iconSize: 33, className: classNames(styles$5.scrollToBottom, scrollToBottomCssClassName), onClick: handleButtonClick(() => scrollToBottom()), "aria-label": ariaLabel, title: ariaLabel }), badgeLabel && (jsx("span", { className: styles$5.scrollToBottomBadge, "aria-live": "polite", role: "status", children: badgeLabel }))] }) })), isVoiceCalling && (jsx("div", { className: styles$5.voiceCallIndicatorBar, children: jsxs("div", { className: styles$5.voiceCallIndicator, children: [jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }), jsx("span", { children: "Voice call active" }), jsx("div", { className: styles$5.voiceCallPulse })] }) })), jsx(ChatActionsBar, { actionsRef: actionsRef, actionsContainer: actionsContainer, messages: postprocessedMessages, participants: participants, title: title, onReset: onReset, resetRequiresConfirmation: resetRequiresConfirmation, newChatButtonHref: newChatButtonHref, onUseTemplate: onUseTemplate, extraActions: extraActions, saveFormats: saveFormats, isSaveButtonEnabled: isSaveButtonEnabled, shouldFadeActions: shouldFadeActions, shouldDisableActions: shouldDisableActions, chatUiTranslations: chatUiTranslations, onButtonClick: handleButtonClick }), jsx(ChatMessageList, { messages: postprocessedMessages, participants: participants, expandedMessageId: expandedMessageId, messageRatings: messageRatings, setExpandedMessageId: setExpandedMessageId, handleRating: handleRating, mode: mode, isCopyButtonEnabled: isCopyButtonEnabled, isFeedbackEnabled: isFeedbackEnabled, feedbackMode: feedbackMode, feedbackTranslations: feedbackTranslations, timingTranslations: timingTranslations, chatLocale: chatLocale, onCopy: handleCopy, onMessage: onMessage, onActionButton: onActionButton, onQuickMessageButton: onQuickMessageButton, onReplyToMessage: onReplyToMessage, canReplyToMessage: canReplyToMessage, onCreateAgent: onCreateAgent, toolTitles: toolTitles, teammates: teammates, teamAgentProfiles: teamAgentProfiles, visualMode: visualMode, soundSystem: soundSystem, onToolCallClick: openToolCall, onCitationClick: openCitation, setChatMessagesElement: setChatMessagesElement, onScroll: handleChatScroll, isSpeechPlaybackEnabled: isSpeechPlaybackEnabled, elevenLabsVoiceId: elevenLabsVoiceId, chatUiTranslations: chatUiTranslations, chatMessagesClassName: classNames(isConstrainedArticleMode && styles$5.articleModeChatMessages, getChatCssClassName('chatMessages'), chatCssClassNames.chatMessages), hasActions: hasActions }), onMessage && (jsx(ChatInputArea, { onMessage: onMessage, onChange: onChange, onFileUpload: onFileUpload, speechRecognition: speechRecognition, speechRecognitionLanguage: speechRecognitionLanguage, replyingToMessage: replyingToMessage, onCancelReply: onCancelReply, defaultMessage: defaultMessage, enterBehavior: enterBehavior, resolveEnterBehavior: resolveEnterBehavior, placeholderMessageContent: placeholderMessageContent || (chatUiTranslations === null || chatUiTranslations === void 0 ? void 0 : chatUiTranslations.inputPlaceholder), isFocusedOnLoad: isFocusedOnLoad, isMobile: isMobile, isVoiceCalling: isVoiceCalling, participants: participants, buttonColor: buttonColor, soundSystem: soundSystem, onButtonClick: handleButtonClick, chatUiTranslations: chatUiTranslations, chatInputClassName: classNames(isConstrainedArticleMode && styles$5.articleModeChatInput, getChatCssClassName('chatInput'), chatCssClassNames.chatInput) }))] }) }), jsx(ChatToolCallModal, { isOpen: toolCallModalOpen, toolCall: selectedToolCall, toolCallIdentity: selectedToolCallIdentity, onClose: closeToolCallModal, toolTitles: toolTitles, agentParticipant: agentParticipant, buttonColor: buttonColor, teamAgentProfiles: teamAgentProfiles, chatUiTranslations: chatUiTranslations, locale: chatLocale, availableTools: selectedMessageAvailableTools, mode: mode }), jsx(ChatCitationModal, { isOpen: citationModalOpen, citation: selectedCitation, participants: participants, soundSystem: soundSystem, onClose: closeCitationModal }), jsx(ChatRatingModal, { isOpen: ratingModalOpen, selectedMessage: selectedMessage, postprocessedMessages: postprocessedMessages, messages: messages, hoveredRating: hoveredRating, messageRatings: messageRatings, textRating: textRating, feedbackMode: feedbackMode, feedbackTranslations: feedbackTranslations, mode: mode, isMobile: isMobile, onClose: () => setRatingModalOpen(false), setHoveredRating: setHoveredRating, setMessageRatings: setMessageRatings, setSelectedMessage: setSelectedMessage, setTextRating: setTextRating, submitRating: submitRating })] }));
40085
+ : styles$5.feedbackStatusError), "aria-live": "polite", role: "status", children: feedbackStatus.message })), effectConfigs && effectConfigs.length > 0 && (jsx(ChatEffectsSystem, { messages: postprocessedMessages, effectConfigs: effectConfigs, soundSystem: soundSystem })), jsx("div", { className: classNames(className, styles$5.Chat, layout === 'STANDALONE' && styles$5.standaloneVisual, layout === 'FULL_PAGE' && styles$5.fullPageVisual, isConstrainedArticleMode && styles$5.constrainedArticleVisual, getChatCssClassName('Chat'), chatCssClassNames.chat), "data-chat-theme": mode.toLowerCase(), style, children: jsxs("div", { className: classNames(className, styles$5.chatMainFlow, getChatCssClassName('chatMainFlow'), chatCssClassNames.chatMainFlow), children: [children && jsx("div", { className: classNames(styles$5.chatChildren), children: children }), shouldShowScrollToBottom && (jsx("div", { className: styles$5.scrollToBottomContainer, children: jsxs("div", { className: styles$5.scrollToBottomWrapper, children: [jsx(SolidArrowButton, { "data-button-type": "custom", direction: "down", iconSize: 33, className: classNames(styles$5.scrollToBottom, scrollToBottomCssClassName), onClick: handleButtonClick(() => scrollToBottom()), "aria-label": ariaLabel, title: ariaLabel }), badgeLabel && (jsx("span", { className: styles$5.scrollToBottomBadge, "aria-live": "polite", role: "status", children: badgeLabel }))] }) })), isVoiceCalling && (jsx("div", { className: styles$5.voiceCallIndicatorBar, children: jsxs("div", { className: styles$5.voiceCallIndicator, children: [jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "currentColor", children: jsx("path", { d: "M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z" }) }), jsx("span", { children: "Voice call active" }), jsx("div", { className: styles$5.voiceCallPulse })] }) })), jsx(ChatActionsBar, { actionsRef: actionsRef, actionsContainer: actionsContainer, messages: postprocessedMessages, participants: participants, title: title, onReset: onReset, resetRequiresConfirmation: resetRequiresConfirmation, newChatButtonHref: newChatButtonHref, onUseTemplate: onUseTemplate, extraActions: extraActions, saveFormats: saveFormats, saveFormatHandlers: saveFormatHandlers, isSaveButtonEnabled: isSaveButtonEnabled, shouldFadeActions: shouldFadeActions, shouldDisableActions: shouldDisableActions, chatUiTranslations: chatUiTranslations, onButtonClick: handleButtonClick }), jsx(ChatMessageList, { messages: postprocessedMessages, participants: participants, expandedMessageId: expandedMessageId, messageRatings: messageRatings, setExpandedMessageId: setExpandedMessageId, handleRating: handleRating, mode: mode, isCopyButtonEnabled: isCopyButtonEnabled, isFeedbackEnabled: isFeedbackEnabled, feedbackMode: feedbackMode, feedbackTranslations: feedbackTranslations, timingTranslations: timingTranslations, chatLocale: chatLocale, onCopy: handleCopy, onMessage: onMessage, onActionButton: onActionButton, onQuickMessageButton: onQuickMessageButton, onReplyToMessage: onReplyToMessage, canReplyToMessage: canReplyToMessage, onCreateAgent: onCreateAgent, toolTitles: toolTitles, teammates: teammates, teamAgentProfiles: teamAgentProfiles, visualMode: visualMode, soundSystem: soundSystem, onToolCallClick: openToolCall, onCitationClick: openCitation, setChatMessagesElement: setChatMessagesElement, onScroll: handleChatScroll, isSpeechPlaybackEnabled: isSpeechPlaybackEnabled, elevenLabsVoiceId: elevenLabsVoiceId, chatUiTranslations: chatUiTranslations, chatMessagesClassName: classNames(isConstrainedArticleMode && styles$5.articleModeChatMessages, getChatCssClassName('chatMessages'), chatCssClassNames.chatMessages), hasActions: hasActions }), onMessage && (jsx(ChatInputArea, { onMessage: onMessage, onChange: onChange, onFileUpload: onFileUpload, speechRecognition: speechRecognition, speechRecognitionLanguage: speechRecognitionLanguage, replyingToMessage: replyingToMessage, onCancelReply: onCancelReply, defaultMessage: defaultMessage, enterBehavior: enterBehavior, resolveEnterBehavior: resolveEnterBehavior, placeholderMessageContent: placeholderMessageContent || (chatUiTranslations === null || chatUiTranslations === void 0 ? void 0 : chatUiTranslations.inputPlaceholder), isFocusedOnLoad: isFocusedOnLoad, isMobile: isMobile, isVoiceCalling: isVoiceCalling, participants: participants, buttonColor: buttonColor, soundSystem: soundSystem, onButtonClick: handleButtonClick, chatUiTranslations: chatUiTranslations, chatInputClassName: classNames(isConstrainedArticleMode && styles$5.articleModeChatInput, getChatCssClassName('chatInput'), chatCssClassNames.chatInput) }))] }) }), jsx(ChatToolCallModal, { isOpen: toolCallModalOpen, toolCall: selectedToolCall, toolCallIdentity: selectedToolCallIdentity, onClose: closeToolCallModal, toolTitles: toolTitles, agentParticipant: agentParticipant, buttonColor: buttonColor, teamAgentProfiles: teamAgentProfiles, chatUiTranslations: chatUiTranslations, locale: chatLocale, availableTools: selectedMessageAvailableTools, mode: mode }), jsx(ChatCitationModal, { isOpen: citationModalOpen, citation: selectedCitation, participants: participants, soundSystem: soundSystem, onClose: closeCitationModal }), jsx(ChatRatingModal, { isOpen: ratingModalOpen, selectedMessage: selectedMessage, postprocessedMessages: postprocessedMessages, messages: messages, hoveredRating: hoveredRating, messageRatings: messageRatings, textRating: textRating, feedbackMode: feedbackMode, feedbackTranslations: feedbackTranslations, mode: mode, isMobile: isMobile, onClose: () => setRatingModalOpen(false), setHoveredRating: setHoveredRating, setMessageRatings: setMessageRatings, setSelectedMessage: setSelectedMessage, setTextRating: setTextRating, submitRating: submitRating })] }));
40063
40086
  }
40064
40087
 
40065
40088
  /**