@promptbook/components 0.102.0-3 → 0.102.0-4

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
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { useMemo, useState, useRef, useCallback, useEffect } from 'react';
2
+ import { useMemo, useState, useRef, useCallback, useEffect, memo } from 'react';
3
3
  import spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
4
4
  import 'path';
5
5
  import 'crypto';
@@ -21,7 +21,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
21
21
  * @generated
22
22
  * @see https://github.com/webgptorg/promptbook
23
23
  */
24
- const PROMPTBOOK_ENGINE_VERSION = '0.102.0-3';
24
+ const PROMPTBOOK_ENGINE_VERSION = '0.102.0-4';
25
25
  /**
26
26
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
27
27
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -4712,6 +4712,18 @@ function useChatAutoScroll(config = {}) {
4712
4712
  };
4713
4713
  }
4714
4714
 
4715
+ /**
4716
+ * Utility to compute readable text color based on background
4717
+ */
4718
+ function getTextColor(bgColor) {
4719
+ // Simple luminance check for contrast
4720
+ const hex = bgColor.replace('#', '');
4721
+ const r = parseInt(hex.substring(0, 2), 16);
4722
+ const g = parseInt(hex.substring(2, 4), 16);
4723
+ const b = parseInt(hex.substring(4, 6), 16);
4724
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b);
4725
+ return luminance > 186 ? '#222' : '#fff';
4726
+ }
4715
4727
  /**
4716
4728
  * HTML export plugin
4717
4729
  *
@@ -4720,7 +4732,112 @@ function useChatAutoScroll(config = {}) {
4720
4732
  const htmlSaveFormatDefinition = {
4721
4733
  formatName: 'html',
4722
4734
  label: 'HTML',
4723
- getContent: (messages) => `<html><body>${messages.map((m) => `<strong>${m.from}:</strong><br>${m.content}<hr>`).join('')}</body></html>`,
4735
+ getContent: (messages) => spaceTrim(`
4736
+ <!DOCTYPE html>
4737
+ <html lang="en">
4738
+ <head>
4739
+ <meta charset="UTF-8" />
4740
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
4741
+ <title>Chat Export - Promptbook</title>
4742
+ <style>
4743
+ body {
4744
+ font-family: 'Segoe UI', Arial, sans-serif;
4745
+ background: #f7f8fa;
4746
+ margin: 0;
4747
+ padding: 0;
4748
+ }
4749
+ .chat-container {
4750
+ max-width: 600px;
4751
+ margin: 40px auto 20px auto;
4752
+ background: #fff;
4753
+ border-radius: 12px;
4754
+ box-shadow: 0 2px 16px rgba(0,0,0,0.07);
4755
+ padding: 24px 18px 18px 18px;
4756
+ }
4757
+ .chat-message {
4758
+ display: flex;
4759
+ align-items: flex-start;
4760
+ margin-bottom: 18px;
4761
+ border-radius: 10px;
4762
+ padding: 0;
4763
+ }
4764
+ .avatar {
4765
+ width: 38px;
4766
+ height: 38px;
4767
+ border-radius: 50%;
4768
+ background: #ccc;
4769
+ margin-right: 14px;
4770
+ flex-shrink: 0;
4771
+ display: flex;
4772
+ align-items: center;
4773
+ justify-content: center;
4774
+ font-weight: bold;
4775
+ font-size: 18px;
4776
+ color: #fff;
4777
+ box-shadow: 0 1px 4px rgba(0,0,0,0.04);
4778
+ }
4779
+ .bubble {
4780
+ border-radius: 10px;
4781
+ padding: 12px 16px;
4782
+ min-width: 80px;
4783
+ max-width: 100%;
4784
+ word-break: break-word;
4785
+ box-shadow: 0 1px 4px rgba(0,0,0,0.03);
4786
+ font-size: 16px;
4787
+ line-height: 1.6;
4788
+ margin-top: 2px;
4789
+ }
4790
+ .from-label {
4791
+ font-weight: bold;
4792
+ font-size: 15px;
4793
+ margin-bottom: 4px;
4794
+ display: block;
4795
+ opacity: 0.85;
4796
+ }
4797
+ .footer {
4798
+ text-align: center;
4799
+ margin: 32px 0 18px 0;
4800
+ color: #888;
4801
+ font-size: 15px;
4802
+ opacity: 0.85;
4803
+ }
4804
+ .footer a {
4805
+ color: #2b7cff;
4806
+ text-decoration: none;
4807
+ font-weight: bold;
4808
+ }
4809
+ </style>
4810
+ </head>
4811
+ <body>
4812
+ <div class="chat-container">
4813
+ ${messages.map((m) => {
4814
+ // Fallback color map for common participants
4815
+ const participantColors = {
4816
+ USER: '#2b7cff',
4817
+ ASSISTANT: '#ffb300',
4818
+ SYSTEM: '#888',
4819
+ };
4820
+ const bgColor = participantColors[String(m.from)] || '#2b7cff';
4821
+ const textColor = getTextColor(bgColor);
4822
+ return spaceTrim(`
4823
+ <div class="chat-message">
4824
+ <div class="avatar" style="background:${bgColor};color:${getTextColor(bgColor)};">
4825
+ ${String(m.from)[0] || '?'}
4826
+ </div>
4827
+ <div class="bubble" style="background:${bgColor};color:${textColor};">
4828
+ <span class="from-label">${String(m.from)}:</span>
4829
+ ${m.content}
4830
+ </div>
4831
+ </div>
4832
+ `);
4833
+ }).join('')}
4834
+ </div>
4835
+ <div class="footer">
4836
+ Exported from <a href="https://ptbk.io" target="_blank" rel="noopener">Promptbook</a>
4837
+ </div>
4838
+ </body>
4839
+ </html>
4840
+ `),
4724
4841
  mimeType: 'text/html',
4725
4842
  fileExtension: 'html',
4726
4843
  };
@@ -4746,7 +4863,19 @@ const jsonSaveFormatDefinition = {
4746
4863
  const mdSaveFormatDefinition = {
4747
4864
  formatName: 'md',
4748
4865
  label: 'Markdown',
4749
- getContent: (messages) => messages.map((m) => `**${m.from}:**\n\n${m.content}\n`).join('\n---\n'),
4866
+ getContent: (messages) => spaceTrim$1(`
4867
+ ${messages
4868
+ .map((m) => spaceTrim$1(`
4869
+ **${m.from}:**
4870
+
4871
+ > ${m.content.replace(/\n/g, '\n> ')}
4872
+ `))
4873
+ .join('\n\n---\n\n')}
4874
+
4875
+ ---
4876
+
4877
+ _Exported from [Promptbook](https://ptbk.io)_
4878
+ `),
4750
4879
  mimeType: 'text/markdown',
4751
4880
  fileExtension: 'md',
4752
4881
  };
@@ -4764,6 +4893,25 @@ const txtSaveFormatDefinition = {
4764
4893
  fileExtension: 'txt',
4765
4894
  };
4766
4895
 
4896
+ /**
4897
+ * PDF export plugin
4898
+ *
4899
+ * @public exported from `@promptbook/components`
4900
+ */
4901
+ const pdfSaveFormatDefinition = {
4902
+ formatName: 'pdf',
4903
+ label: 'PDF',
4904
+ getContent: (messages) => {
4905
+ htmlSaveFormatDefinition.getContent(messages);
4906
+ // <- TODO: !!!!
4907
+ // PDF conversion should be implemented here (sync or pre-generated)
4908
+ // For now, return a placeholder string
4909
+ return '[PDF chat save not implemented. Integrate a PDF library for conversion.]';
4910
+ },
4911
+ mimeType: 'application/pdf',
4912
+ fileExtension: 'pdf',
4913
+ };
4914
+
4767
4915
  /**
4768
4916
  * Registry of all built-in chat save plugins
4769
4917
  *
@@ -4774,6 +4922,7 @@ const CHAT_SAVE_FORMATS = [
4774
4922
  txtSaveFormatDefinition,
4775
4923
  mdSaveFormatDefinition,
4776
4924
  htmlSaveFormatDefinition,
4925
+ pdfSaveFormatDefinition,
4777
4926
  ];
4778
4927
  /**
4779
4928
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -4951,6 +5100,107 @@ const LOADING_INTERACTIVE_IMAGE = 'Loading...';
4951
5100
 
4952
5101
  // [🚉] Avatar dimensions constant to prevent layout jumps and maintain DRY principle
4953
5102
  const AVATAR_SIZE = 40;
5103
+ const ChatMessageItem = memo(({ message, participant, participants, isLastMessage, onMessage, setExpandedMessageId, isExpanded, currentRating, handleRating, mode, }) => {
5104
+ const avatarSrc = (participant === null || participant === void 0 ? void 0 : participant.avatarSrc) || '';
5105
+ const color = Color.from((participant && participant.color) || '#ccc');
5106
+ const colorOfText = color.then(textColor);
5107
+ const { contentWithoutButtons, buttons } = parseMessageButtons(message.content);
5108
+ const shouldShowButtons = isLastMessage && buttons.length > 0 && onMessage;
5109
+ const [localHoveredRating, setLocalHoveredRating] = useState(0);
5110
+ useEffect(() => {
5111
+ if (!isExpanded) {
5112
+ setLocalHoveredRating(0);
5113
+ }
5114
+ }, [isExpanded]);
5115
+ return (jsxs("div", { className: classNames(chatStyles.chatMessage, (participant === null || participant === void 0 ? void 0 : participant.isMe) && chatStyles.isMe, !message.isComplete && chatStyles.isNotCompleteMessage), onClick: () => {
5116
+ console.group('💬', message.content);
5117
+ console.info('message', message);
5118
+ console.info('participant', participant);
5119
+ console.info('participants', participants);
5120
+ console.info('participant avatarSrc', avatarSrc);
5121
+ console.info('participant color', { color, colorOfText });
5122
+ console.groupEnd();
5123
+ }, children: [avatarSrc && (jsx("div", { className: chatStyles.avatar, children: jsx("img", { width: AVATAR_SIZE, height: AVATAR_SIZE, src: avatarSrc, alt: `Avatar of ${message.from.toString().toLocaleLowerCase()}`, style: {
5124
+ backgroundColor: color.toHex(),
5125
+ width: AVATAR_SIZE,
5126
+ height: AVATAR_SIZE,
5127
+ borderRadius: '50%',
5128
+ objectFit: 'cover',
5129
+ border: '2px solid rgba(125, 125, 125, 0.1)',
5130
+ flexShrink: 0,
5131
+ } }) })), jsxs("div", { className: chatStyles.messageText, style: {
5132
+ backgroundColor: color.toHex(),
5133
+ color: colorOfText.toHex(),
5134
+ }, children: [message.isVoiceCall && (jsx("div", { className: chatStyles.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" }) }) })), message.content === LOADING_INTERACTIVE_IMAGE ? (jsx(Fragment, {})) : (jsx("div", { dangerouslySetInnerHTML: {
5135
+ __html: renderMarkdown(contentWithoutButtons),
5136
+ } })), !message.isComplete && jsx("span", { className: chatStyles.NonCompleteMessageFiller, children: '_'.repeat(70) }), shouldShowButtons && (jsx("div", { className: chatStyles.messageButtons, children: buttons.map((button, buttonIndex) => (jsx("button", { className: chatStyles.messageButton, onClick: (event) => {
5137
+ event.stopPropagation();
5138
+ if (onMessage) {
5139
+ onMessage(button.message);
5140
+ }
5141
+ }, dangerouslySetInnerHTML: {
5142
+ __html: renderMarkdown(button.text),
5143
+ } }, buttonIndex))) })), message.isComplete && (jsx("div", { className: chatStyles.rating, onMouseEnter: () => {
5144
+ setExpandedMessageId(message.id);
5145
+ }, onMouseLeave: () => {
5146
+ setExpandedMessageId(null);
5147
+ setLocalHoveredRating(0);
5148
+ }, children: isExpanded ? ([1, 2, 3, 4, 5].map((star) => (jsx("span", { onClick: () => handleRating(message, star), onMouseEnter: () => setLocalHoveredRating(star), style: {
5149
+ cursor: 'pointer',
5150
+ fontSize: '20px',
5151
+ color: star <= (localHoveredRating || currentRating || 0)
5152
+ ? '#FFD700'
5153
+ : mode === 'LIGHT'
5154
+ ? '#ccc'
5155
+ : '#555',
5156
+ transition: 'color 0.2s',
5157
+ }, children: "\u2B50" }, star)))) : (jsx("span", { onClick: () => handleRating(message, currentRating || 1), style: {
5158
+ cursor: 'pointer',
5159
+ fontSize: '20px',
5160
+ color: currentRating ? '#FFD700' : mode === 'LIGHT' ? '#888' : '#666',
5161
+ transition: 'color 0.2s',
5162
+ }, children: "\u2B50" })) }))] })] }));
5163
+ }, (prev, next) => {
5164
+ var _a, _b, _c, _d;
5165
+ if (prev.message.id !== next.message.id) {
5166
+ return false;
5167
+ }
5168
+ if (prev.message.content !== next.message.content) {
5169
+ return false;
5170
+ }
5171
+ if (((_a = prev.message.isComplete) !== null && _a !== void 0 ? _a : true) !== ((_b = next.message.isComplete) !== null && _b !== void 0 ? _b : true)) {
5172
+ return false;
5173
+ }
5174
+ if (((_c = prev.message.isVoiceCall) !== null && _c !== void 0 ? _c : false) !== ((_d = next.message.isVoiceCall) !== null && _d !== void 0 ? _d : false)) {
5175
+ return false;
5176
+ }
5177
+ if (prev.participant !== next.participant) {
5178
+ return false;
5179
+ }
5180
+ if (prev.participants !== next.participants) {
5181
+ return false;
5182
+ }
5183
+ if (prev.isLastMessage !== next.isLastMessage) {
5184
+ return false;
5185
+ }
5186
+ if (prev.onMessage !== next.onMessage) {
5187
+ return false;
5188
+ }
5189
+ if (prev.setExpandedMessageId !== next.setExpandedMessageId) {
5190
+ return false;
5191
+ }
5192
+ if (prev.isExpanded !== next.isExpanded) {
5193
+ return false;
5194
+ }
5195
+ if (prev.currentRating !== next.currentRating) {
5196
+ return false;
5197
+ }
5198
+ if (prev.handleRating !== next.handleRating) {
5199
+ return false;
5200
+ }
5201
+ return prev.mode === next.mode;
5202
+ });
5203
+ ChatMessageItem.displayName = 'ChatMessageItem';
4954
5204
  /**
4955
5205
  * Renders a chat with messages and input for new messages
4956
5206
  *
@@ -5133,9 +5383,13 @@ function Chat(props) {
5133
5383
  const scrollToBottomCssClassName = useChatCssClassName('scrollToBottom');
5134
5384
  const handleRating = useCallback(async (message, newRating) => {
5135
5385
  setSelectedMessage(message);
5136
- setMessageRatings(new Map(messageRatings.set(message.id, newRating)));
5386
+ setMessageRatings((previousRatings) => {
5387
+ const nextRatings = new Map(previousRatings);
5388
+ nextRatings.set(message.id, newRating);
5389
+ return nextRatings;
5390
+ });
5137
5391
  setRatingModalOpen(true);
5138
- }, [messageRatings]);
5392
+ }, []);
5139
5393
  const submitRating = useCallback(async () => {
5140
5394
  if (!selectedMessage)
5141
5395
  return;
@@ -5248,67 +5502,10 @@ function Chat(props) {
5248
5502
  cursor: 'pointer',
5249
5503
  }, onClick: () => handleDownload(formatDefinition.formatName), children: formatDefinition.label }, formatDefinition.formatName))) }))] })), onUseTemplate && (jsxs("button", { className: classNames(chatStyles.useTemplateButton), onClick: onUseTemplate, children: [jsx("span", { className: chatStyles.resetButtonText, children: "Use this template" }), jsx(TemplateIcon, { size: 16 })] })), extraActions] }), jsx("div", { className: classNames(chatStyles.chatMessages, useChatCssClassName('chatMessages')), ref: chatMessagesRef, onScroll: handleScroll, children: postprocessedMessages.map((message, i) => {
5250
5504
  const participant = participants.find((participant) => participant.name === message.from);
5251
- const avatarSrc = (participant && participant.avatarSrc) || '';
5252
- const color = Color.from((participant && participant.color) || '#ccc');
5253
- const colorOfText = color.then(textColor);
5254
- // Parse buttons from message content
5255
- const { contentWithoutButtons, buttons } = parseMessageButtons(message.content);
5256
- // Only show buttons for the last message
5257
5505
  const isLastMessage = i === postprocessedMessages.length - 1;
5258
- const shouldShowButtons = isLastMessage && buttons.length > 0 && onMessage;
5259
- return (jsxs("div", { className: classNames(chatStyles.chatMessage, (participant === null || participant === void 0 ? void 0 : participant.isMe) && chatStyles.isMe, !message.isComplete && chatStyles.isNotCompleteMessage), onClick: () => {
5260
- console.group('💬', message.content);
5261
- console.info('message', message);
5262
- console.info('participant', participant);
5263
- console.info('participants', participants);
5264
- console.info('participant avatarSrc', avatarSrc);
5265
- console.info('participant color', { color, colorOfText });
5266
- console.groupEnd();
5267
- }, children: [avatarSrc && (jsx("div", { className: chatStyles.avatar, children: jsx("img", { width: AVATAR_SIZE, height: AVATAR_SIZE, src: avatarSrc, alt: `Avatar of ${message.from.toString().toLocaleLowerCase()}`, style: {
5268
- backgroundColor: color.toHex(),
5269
- width: AVATAR_SIZE,
5270
- height: AVATAR_SIZE,
5271
- borderRadius: '50%',
5272
- objectFit: 'cover',
5273
- border: '2px solid rgba(125, 125, 125, 0.1)',
5274
- flexShrink: 0,
5275
- } }) })), jsxs("div", { className: chatStyles.messageText, style: {
5276
- backgroundColor: color.toHex(),
5277
- color: colorOfText.toHex(),
5278
- }, children: [message.isVoiceCall && (jsx("div", { className: chatStyles.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" }) }) })), message.content === LOADING_INTERACTIVE_IMAGE ? (jsx(Fragment, {})) : (jsx("div", { dangerouslySetInnerHTML: {
5279
- __html: renderMarkdown(contentWithoutButtons),
5280
- } })), !message.isComplete && (jsx("span", { className: chatStyles.NonCompleteMessageFiller, children: '_'.repeat(70) })), shouldShowButtons && (jsx("div", { className: chatStyles.messageButtons, children: buttons.map((button, buttonIndex) => (jsx("button", { className: chatStyles.messageButton, onClick: (event) => {
5281
- event.stopPropagation();
5282
- if (onMessage) {
5283
- onMessage(button.message);
5284
- }
5285
- }, dangerouslySetInnerHTML: {
5286
- __html: renderMarkdown(button.text),
5287
- } }, buttonIndex))) })), message.isComplete && (jsx("div", { className: chatStyles.rating, onMouseEnter: () => setExpandedMessageId(message.id), onMouseLeave: () => {
5288
- setExpandedMessageId(null);
5289
- setHoveredRating(0);
5290
- }, children: expandedMessageId === message.id ? ([1, 2, 3, 4, 5].map((star) => (jsx("span", { onClick: () => handleRating(message, star), onMouseEnter: () => setHoveredRating(star), style: {
5291
- cursor: 'pointer',
5292
- fontSize: '20px',
5293
- color: star <=
5294
- (hoveredRating ||
5295
- messageRatings.get(message.id) ||
5296
- 0)
5297
- ? '#FFD700'
5298
- : mode === 'LIGHT'
5299
- ? '#ccc'
5300
- : '#555',
5301
- transition: 'color 0.2s',
5302
- }, children: "\u2B50" }, star)))) : (jsx("span", { onClick: () => handleRating(message, messageRatings.get(message.id) || 1), style: {
5303
- cursor: 'pointer',
5304
- fontSize: '20px',
5305
- color: messageRatings.get(message.id)
5306
- ? '#FFD700'
5307
- : mode === 'LIGHT'
5308
- ? '#888'
5309
- : '#666',
5310
- transition: 'color 0.2s',
5311
- }, children: "\u2B50" })) }))] })] }, message.id));
5506
+ const isExpanded = expandedMessageId === message.id;
5507
+ const currentRating = messageRatings.get(message.id) || 0;
5508
+ return (jsx(ChatMessageItem, { message: message, participant: participant, participants: participants, isLastMessage: isLastMessage, onMessage: onMessage, setExpandedMessageId: setExpandedMessageId, isExpanded: isExpanded, currentRating: currentRating, handleRating: handleRating, mode: mode }, message.id));
5312
5509
  }) }), onMessage && (jsxs("div", { className: classNames(chatStyles.chatInput, useChatCssClassName('chatInput'), isDragOver && chatStyles.dragOver), ...(onFileUpload
5313
5510
  ? {
5314
5511
  onDrop: handleDrop,
@@ -5350,7 +5547,11 @@ function Chat(props) {
5350
5547
  if (e.target === e.currentTarget && isMobile) {
5351
5548
  setRatingModalOpen(false);
5352
5549
  }
5353
- }, children: jsxs("div", { className: chatStyles.ratingModalContent, children: [jsx("h3", { children: "Rate this response" }), jsx("div", { className: chatStyles.stars, children: [1, 2, 3, 4, 5].map((star) => (jsx("span", { onClick: () => setMessageRatings(new Map(messageRatings.set(selectedMessage.id, star))), onMouseEnter: () => setHoveredRating(star), onMouseLeave: () => setHoveredRating(0), style: {
5550
+ }, children: jsxs("div", { className: chatStyles.ratingModalContent, children: [jsx("h3", { children: "Rate this response" }), jsx("div", { className: chatStyles.stars, children: [1, 2, 3, 4, 5].map((star) => (jsx("span", { onClick: () => setMessageRatings((previousRatings) => {
5551
+ const nextRatings = new Map(previousRatings);
5552
+ nextRatings.set(selectedMessage.id, star);
5553
+ return nextRatings;
5554
+ }), onMouseEnter: () => setHoveredRating(star), onMouseLeave: () => setHoveredRating(0), style: {
5354
5555
  cursor: 'pointer',
5355
5556
  fontSize: '24px',
5356
5557
  color: star <= (hoveredRating || messageRatings.get(selectedMessage.id) || 0)
@@ -6001,5 +6202,5 @@ function MockedChat(props) {
6001
6202
  onMessage: isSimulationComplete && chatProps.onMessage ? chatProps.onMessage : undefined }));
6002
6203
  }
6003
6204
 
6004
- export { ArrowIcon, AttachmentIcon, AvatarChip, AvatarChipFromSource, AvatarProfile, AvatarProfileFromSource, BLOCKY_FLOW, BOOK_LANGUAGE_VERSION, BookEditor, CHAT_SAVE_FORMATS, Chat, CloseIcon, DEFAULT_BOOK_FONT_CLASS, FAST_FLOW, LlmChat, MOCKED_CHAT_DELAY_CONFIGS, MockedChat, NORMAL_FLOW, PROMPTBOOK_ENGINE_VERSION, PauseIcon, PlayIcon, RANDOM_FLOW, ResetIcon, SLOW_FLOW, SendIcon, TemplateIcon, getChatSaveFormatDefinitions, htmlSaveFormatDefinition, isMarkdownContent, jsonSaveFormatDefinition, mdSaveFormatDefinition, parseMessageButtons, renderMarkdown, txtSaveFormatDefinition, useChatAutoScroll, useSendMessageToLlmChat };
6205
+ export { ArrowIcon, AttachmentIcon, AvatarChip, AvatarChipFromSource, AvatarProfile, AvatarProfileFromSource, BLOCKY_FLOW, BOOK_LANGUAGE_VERSION, BookEditor, CHAT_SAVE_FORMATS, Chat, CloseIcon, DEFAULT_BOOK_FONT_CLASS, FAST_FLOW, LlmChat, MOCKED_CHAT_DELAY_CONFIGS, MockedChat, NORMAL_FLOW, PROMPTBOOK_ENGINE_VERSION, PauseIcon, PlayIcon, RANDOM_FLOW, ResetIcon, SLOW_FLOW, SendIcon, TemplateIcon, getChatSaveFormatDefinitions, htmlSaveFormatDefinition, isMarkdownContent, jsonSaveFormatDefinition, mdSaveFormatDefinition, parseMessageButtons, pdfSaveFormatDefinition, renderMarkdown, txtSaveFormatDefinition, useChatAutoScroll, useSendMessageToLlmChat };
6005
6206
  //# sourceMappingURL=index.es.js.map