@fusioni/client-sdk 1.1.16 → 1.1.18

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/dist/index.esm.js CHANGED
@@ -61,6 +61,7 @@ const en = {
61
61
  emptyState: {
62
62
  title: 'How can I help today?',
63
63
  description: 'Ask a question, share a task, or describe what you need. Fusioni is ready when you are.',
64
+ suggestionsLabel: 'Suggested actions',
64
65
  suggestionOne: 'Ask a question',
65
66
  suggestionTwo: 'Compare options',
66
67
  suggestionThree: 'Get next steps'
@@ -162,6 +163,7 @@ const el = {
162
163
  emptyState: {
163
164
  title: 'Πώς μπορώ να βοηθήσω σήμερα;',
164
165
  description: 'Κάντε μια ερώτηση, μοιραστείτε μια εργασία ή περιγράψτε τι χρειάζεστε. Το Fusioni είναι έτοιμο όταν είστε κι εσείς.',
166
+ suggestionsLabel: 'Προτεινόμενες ενέργειες',
165
167
  suggestionOne: 'Κάντε μια ερώτηση',
166
168
  suggestionTwo: 'Συγκρίνετε επιλογές',
167
169
  suggestionThree: 'Δείτε επόμενα βήματα'
@@ -5369,8 +5371,65 @@ const ImageGallery = ({ images, initialIndex = 0, onClose, theme = 'light', }) =
5369
5371
  }, children: jsx("img", { src: images[gi], alt: "", loading: "lazy", referrerPolicy: "no-referrer" }) })) }) }))] })] }));
5370
5372
  };
5371
5373
 
5372
- const MessageList = ({ messages, streamMessages, showThoughts = false, onDeleteMessage, onEditMessage, onConfirmation, enableButtons = true, apiBaseUrl, apiKey, agencyId, currentLanguage = 'en', theme = 'light' }) => {
5374
+ function resolveActionLiteral(action, language) {
5375
+ if (!action.literals?.length) {
5376
+ return undefined;
5377
+ }
5378
+ return (action.literals.find((l) => l.language === language)
5379
+ ?? action.literals.find((l) => l.language === 'en')
5380
+ ?? action.literals[0]);
5381
+ }
5382
+ function toActionSuggestion(action, language) {
5383
+ if (action.enabled === false) {
5384
+ return null;
5385
+ }
5386
+ const literal = resolveActionLiteral(action, language);
5387
+ const label = (literal?.text || action.title || '').trim();
5388
+ const prompt = (literal?.prompt || literal?.text || action.title || '').trim();
5389
+ if (!label) {
5390
+ return null;
5391
+ }
5392
+ return {
5393
+ id: action.id,
5394
+ label,
5395
+ prompt: prompt || label,
5396
+ };
5397
+ }
5398
+ class ActionService {
5399
+ getApiClient() {
5400
+ return getApiClient();
5401
+ }
5402
+ async findEnabledByAgencyId(agencyId) {
5403
+ const apiClient = this.getApiClient();
5404
+ return await apiClient.get('/action/enabled', {
5405
+ params: {
5406
+ agency_id: agencyId,
5407
+ },
5408
+ });
5409
+ }
5410
+ async findByAgencyId(agencyId, page = 0, size = 100) {
5411
+ const apiClient = this.getApiClient();
5412
+ const response = await apiClient.get('/action/list', {
5413
+ params: {
5414
+ agency_id: agencyId,
5415
+ page,
5416
+ size,
5417
+ },
5418
+ });
5419
+ return response?.body ?? [];
5420
+ }
5421
+ }
5422
+ let actionServiceInstance = null;
5423
+ const getActionService = () => {
5424
+ if (!actionServiceInstance) {
5425
+ actionServiceInstance = new ActionService();
5426
+ }
5427
+ return actionServiceInstance;
5428
+ };
5429
+
5430
+ const MessageList = ({ messages, streamMessages, showThoughts = false, onDeleteMessage, onEditMessage, onConfirmation, enableButtons = true, apiBaseUrl, apiKey, agencyId, currentLanguage = 'en', theme = 'light', onSuggestionClick, }) => {
5373
5431
  const { t } = useTranslation(currentLanguage);
5432
+ const [suggestions, setSuggestions] = useState([]);
5374
5433
  const messagesEndRef = useRef(null);
5375
5434
  const scrollContainerRef = useRef(null);
5376
5435
  const editRef = useRef(null);
@@ -5403,6 +5462,51 @@ const MessageList = ({ messages, streamMessages, showThoughts = false, onDeleteM
5403
5462
  useEffect(() => {
5404
5463
  scrollToBottom();
5405
5464
  }, [messages, streamMessages]);
5465
+ useEffect(() => {
5466
+ if (!agencyId) {
5467
+ setSuggestions([]);
5468
+ return;
5469
+ }
5470
+ let cancelled = false;
5471
+ getActionService()
5472
+ .findEnabledByAgencyId(agencyId)
5473
+ .then((actions) => {
5474
+ if (cancelled) {
5475
+ return;
5476
+ }
5477
+ const items = actions
5478
+ .map((action) => toActionSuggestion(action, currentLanguage))
5479
+ .filter((item) => item !== null);
5480
+ setSuggestions(items);
5481
+ })
5482
+ .catch((error) => {
5483
+ console.error('Failed to load action suggestions:', error);
5484
+ if (!cancelled) {
5485
+ setSuggestions([]);
5486
+ }
5487
+ });
5488
+ return () => {
5489
+ cancelled = true;
5490
+ };
5491
+ }, [agencyId, currentLanguage]);
5492
+ const defaultSuggestions = useMemo(() => [
5493
+ {
5494
+ id: 'default-suggestion-1',
5495
+ label: t('chat.emptyState.suggestionOne'),
5496
+ prompt: t('chat.emptyState.suggestionOne'),
5497
+ },
5498
+ {
5499
+ id: 'default-suggestion-2',
5500
+ label: t('chat.emptyState.suggestionTwo'),
5501
+ prompt: t('chat.emptyState.suggestionTwo'),
5502
+ },
5503
+ {
5504
+ id: 'default-suggestion-3',
5505
+ label: t('chat.emptyState.suggestionThree'),
5506
+ prompt: t('chat.emptyState.suggestionThree'),
5507
+ },
5508
+ ], [t, currentLanguage]);
5509
+ const displaySuggestions = suggestions.length > 0 ? suggestions : defaultSuggestions;
5406
5510
  const formatDate = (date) => {
5407
5511
  const now = new Date();
5408
5512
  const diffInMilliseconds = now.getTime() - new Date(date).getTime();
@@ -5464,7 +5568,7 @@ const MessageList = ({ messages, streamMessages, showThoughts = false, onDeleteM
5464
5568
  selection.addRange(range);
5465
5569
  }
5466
5570
  }, [editingMessageId, editingContent]);
5467
- return (jsxs(Fragment, { children: [jsx("div", { className: "fusioni-message-list", ref: scrollContainerRef, children: jsxs("div", { className: "fusioni-messages-container", children: [messages.length === 0 ? (jsx("div", { className: "fusioni-empty-messages", children: jsxs("div", { className: "fusioni-empty-messages-content", children: [jsx("div", { className: "fusioni-empty-icon-frame", "aria-hidden": "true", children: jsx("img", { src: FUSIONI_LOGO_BASE64, alt: "", width: "40", height: "40", className: "fusioni-empty-logo" }) }), jsx("h3", { children: t('chat.emptyState.title') }), jsx("p", { children: t('chat.emptyState.description') }), jsxs("div", { className: "fusioni-empty-suggestions", "aria-hidden": "true", children: [jsx("span", { children: t('chat.emptyState.suggestionOne') }), jsx("span", { children: t('chat.emptyState.suggestionTwo') }), jsx("span", { children: t('chat.emptyState.suggestionThree') })] })] }) })) : (jsx("div", { className: "fusioni-messages", children: messages.map((message, index) => {
5571
+ return (jsxs(Fragment, { children: [jsx("div", { className: "fusioni-message-list", ref: scrollContainerRef, children: jsxs("div", { className: "fusioni-messages-container", children: [messages.length === 0 ? (jsx("div", { className: "fusioni-empty-messages", children: jsxs("div", { className: "fusioni-empty-messages-content", children: [jsx("div", { className: "fusioni-empty-icon-frame", "aria-hidden": "true", children: jsx("img", { src: FUSIONI_LOGO_BASE64, alt: "", width: "60", height: "60", className: "fusioni-empty-logo" }) }), jsx("h3", { children: t('chat.emptyState.title') }), jsx("p", { children: t('chat.emptyState.description') }), jsx("div", { className: "fusioni-empty-suggestions", role: "list", "aria-label": t('chat.emptyState.suggestionsLabel'), children: displaySuggestions.map((suggestion, index) => (jsx("button", { type: "button", className: "fusioni-empty-suggestion-chip", role: "listitem", disabled: !onSuggestionClick, onClick: () => onSuggestionClick?.(suggestion.prompt), children: suggestion.label }, suggestion.id ?? `action-suggestion-${index}`))) })] }) })) : (jsx("div", { className: "fusioni-messages", children: messages.map((message, index) => {
5468
5572
  const isLastMessage = index === messages.length - 1;
5469
5573
  const messageKey = message.id ??
5470
5574
  `msg-fallback-${index}-${message.role}-${message.created instanceof Date ? message.created.getTime() : 0}`;
@@ -6109,6 +6213,7 @@ function useIsMobileLayout() {
6109
6213
  }
6110
6214
 
6111
6215
  const getStoredConversationIdKey = (agencyId) => `fusioni:selectedConversationId:${agencyId}`;
6216
+ const getStoredChatPanelOpenKey = (agencyId) => `fusioni:chatPanelOpen:${agencyId}`;
6112
6217
  const readStoredConversationId = (agencyId) => {
6113
6218
  if (typeof window === 'undefined')
6114
6219
  return null;
@@ -6135,6 +6240,26 @@ const writeStoredConversationId = (agencyId, conversationId) => {
6135
6240
  // Storage can be unavailable in restricted browser contexts.
6136
6241
  }
6137
6242
  };
6243
+ const readStoredChatPanelOpen = (agencyId) => {
6244
+ if (typeof window === 'undefined')
6245
+ return false;
6246
+ try {
6247
+ return window.sessionStorage.getItem(getStoredChatPanelOpenKey(agencyId)) === 'true';
6248
+ }
6249
+ catch {
6250
+ return false;
6251
+ }
6252
+ };
6253
+ const writeStoredChatPanelOpen = (agencyId, isOpen) => {
6254
+ if (typeof window === 'undefined')
6255
+ return;
6256
+ try {
6257
+ window.sessionStorage.setItem(getStoredChatPanelOpenKey(agencyId), String(isOpen));
6258
+ }
6259
+ catch {
6260
+ // Storage can be unavailable in restricted browser contexts.
6261
+ }
6262
+ };
6138
6263
  const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMessageReceived, onConversationCreated, onConversationDeleted, onError }, ref) {
6139
6264
  const [languageOverride, setLanguageOverride] = useState(null);
6140
6265
  const [isOpen, setIsOpen] = useState(false);
@@ -6157,6 +6282,15 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
6157
6282
  // Translation and language management - use merged config or fallback to user config
6158
6283
  const { t, currentLanguage, changeLanguage } = useTranslation(translationDefault);
6159
6284
  const activeAgencyId = mergedConfig?.agencyId || config.agencyId;
6285
+ const updateChatOpen = useCallback((nextIsOpen) => {
6286
+ setIsOpen(nextIsOpen);
6287
+ if (activeAgencyId) {
6288
+ writeStoredChatPanelOpen(activeAgencyId, nextIsOpen);
6289
+ }
6290
+ if (!nextIsOpen) {
6291
+ setIsConversationListOpen(false);
6292
+ }
6293
+ }, [activeAgencyId]);
6160
6294
  const { conversations, currentConversation, messages, streamMessages, setCurrentConversation, setStreamMessages, addMessage, updateMessage, removeMessage, removeOptimisticUserMessages, truncateMessagesAt, addConversation, updateConversation, removeConversation, loadConversations, loadMessages, clearMessages } = useChatState(activeAgencyId);
6161
6295
  const { theme, toggleTheme, setTheme } = useTheme(mergedConfig?.theme || config.theme);
6162
6296
  const isMobileLayout = useIsMobileLayout();
@@ -6238,6 +6372,12 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
6238
6372
  };
6239
6373
  }
6240
6374
  }, [activeAgencyId, loadConversations]);
6375
+ useEffect(() => {
6376
+ if (!activeAgencyId) {
6377
+ return;
6378
+ }
6379
+ setIsOpen(readStoredChatPanelOpen(activeAgencyId));
6380
+ }, [activeAgencyId]);
6241
6381
  // SSE connection for real-time updates - only when a chat panel is open
6242
6382
  useSSE(activeAgencyId, (data) => {
6243
6383
  // Same as fusioni-web chat.component: latest SSE line replaces stream (single loading row updates)
@@ -6252,8 +6392,17 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
6252
6392
  };
6253
6393
  }, []);
6254
6394
  const handleToggleChat = useCallback(() => {
6255
- setIsOpen(prev => !prev);
6256
- }, []);
6395
+ setIsOpen(prev => {
6396
+ const nextIsOpen = !prev;
6397
+ if (activeAgencyId) {
6398
+ writeStoredChatPanelOpen(activeAgencyId, nextIsOpen);
6399
+ }
6400
+ if (!nextIsOpen) {
6401
+ setIsConversationListOpen(false);
6402
+ }
6403
+ return nextIsOpen;
6404
+ });
6405
+ }, [activeAgencyId]);
6257
6406
  const handleToggleConversationList = useCallback(() => {
6258
6407
  setIsConversationListOpen(prev => !prev);
6259
6408
  }, []);
@@ -6687,7 +6836,7 @@ const ChatWidget = forwardRef(function ChatWidget({ config, onMessageSent, onMes
6687
6836
  if (error) {
6688
6837
  return (jsxs("div", { className: "fusioni-chat-error", children: [jsxs("p", { children: [t('common.error'), ": ", error] }), jsx("button", { onClick: () => setError(null), children: t('chat.errors.retry') })] }));
6689
6838
  }
6690
- return (jsxs("div", { className: `fusioni-chat-widget ${theme}`, style: { '--primary-color': mergedConfig.primaryColor || '#6366f1' }, children: [jsx(FloatingButton, { isOpen: isOpen, onClick: handleToggleChat, position: mergedConfig.position || 'bottom-right', primaryColor: mergedConfig.primaryColor, buttonRef: floatingButtonRef, variant: mergedConfig.buttonVariant || 'glass', shouldDisplay: !hasConfigError && (!isMobileLayout || !isOpen) }), isOpen && (jsx(ChatPanel, { isOpen: isOpen, onClose: () => setIsOpen(false), position: mergedConfig.position || 'bottom-right', isFullscreen: isFullscreen, floatingButtonRef: floatingButtonRef, children: jsxs("div", { className: "fusioni-chat-container", children: [mergedConfig.showConversationList !== false && (jsxs(Fragment, { children: [jsx("div", { className: `fusioni-conversation-backdrop ${isConversationListOpen ? 'open' : ''}`, onClick: () => setIsConversationListOpen(false) }), jsx(ConversationList, { conversations: conversations, selectedConversationId: currentConversation?.id || undefined, onSelectConversation: handleSelectConversation, onDeleteConversation: handleDeleteConversation, onCreateConversation: handleCreateConversation, isOpen: isConversationListOpen, currentLanguage: currentLanguage })] })), jsxs("div", { className: "fusioni-chat-main", children: [jsxs("div", { className: "fusioni-chat-main-header", children: [mergedConfig.showConversationList !== false ? (jsxs("button", { type: "button", onClick: handleToggleConversationList, className: `fusioni-conversation-toggle ${isConversationListOpen ? 'open' : ''}`, children: [jsx("svg", { className: "fusioni-conversation-toggle-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M3 12h18M3 6h18M3 18h18" }) }), t('chat.conversations.title')] })) : (jsx("span", { className: "fusioni-chat-main-header-title", children: t('chat.title') })), jsxs("div", { className: "fusioni-header-actions", children: [jsx("button", { type: "button", onClick: handleCreateConversation, disabled: isLoading, className: "fusioni-btn fusioni-btn-icon", title: t('chat.conversations.newConversation'), "aria-label": t('chat.conversations.newConversation'), children: jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: jsx("path", { d: "M12 5V19M5 12H19", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), mergedConfig.showThemeToggle !== false && (jsx("button", { type: "button", onClick: toggleTheme, className: "fusioni-btn fusioni-btn-icon", title: theme === 'dark' ? t('chat.theme.light') : t('chat.theme.dark'), children: theme === 'dark' ? (jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [jsx("circle", { cx: "12", cy: "12", r: "5" }), jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }), jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }), jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }), jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }), jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }), jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }), jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }), jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })] })) : (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) })) })), mergedConfig.showFullscreenToggle !== false && (jsx("button", { type: "button", onClick: handleToggleFullscreen, className: "fusioni-btn fusioni-btn-icon", title: isFullscreen ? t('chat.fullscreen.exit') : t('chat.fullscreen.enter'), children: isFullscreen ? (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M8 3V5M8 3H5M8 3L3 8M16 3V5M16 3H19M16 3L21 8M8 21V19M8 21H5M8 21L3 16M16 21V19M16 21H19M16 21L21 16" }) })) : (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M8 3H5C4.46957 3 3.96086 3.21071 3.58579 3.58579C3.21071 3.96086 3 4.46957 3 5V8M21 8V5C21 4.46957 20.7893 3.96086 20.4142 3.58579C20.0391 3.21071 19.5304 3 19 3H16M16 21H19C19.5304 21 20.0391 20.7893 20.4142 20.4142C20.7893 20.0391 21 19.5304 21 19V16M3 16V19C3 19.5304 3.21071 20.0391 3.58579 20.4142C3.96086 20.7893 4.46957 21 5 21H8" }) })) })), mergedConfig.showLanguageSwitcher !== false && (jsx(LanguageSwitcher, { currentLanguage: currentLanguage, onLanguageChange: handleLanguageChange })), jsx("button", { type: "button", onClick: () => setIsOpen(false), className: "fusioni-btn fusioni-btn-icon fusioni-chat-toolbar-close-mobile", title: t('common.close'), "aria-label": t('common.close'), children: jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: jsx("path", { d: "M18 6L6 18M6 6L18 18", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), currentConversation ? (jsxs(Fragment, { children: [jsx(MessageList, { messages: messages, streamMessages: streamMessages, showThoughts: false, onDeleteMessage: handleDeleteMessage, onEditMessage: handleEditMessage, onConfirmation: handleConfirmation, enableButtons: !isLoading, apiBaseUrl: mergedConfig.apiBaseUrl, apiKey: mergedConfig.accessToken, agencyId: mergedConfig.agencyId, currentLanguage: currentLanguage, theme: theme }), jsx(ChatInput, { onSendMessage: handleSendMessage, onFileUpload: handleFileUpload, disabled: isLoading, placeholder: t('chat.input.placeholder'), enableAudioRecording: mergedConfig.enableAudioRecording !== false, enableFileUpload: mergedConfig.enableFileUpload !== false, maxFileSize: mergedConfig.maxFileSize || 10, allowedFileTypes: mergedConfig.allowedFileTypes || ['image/*'], currentLanguage: currentLanguage })] })) : (jsx("div", { className: "fusioni-chat-welcome", children: jsxs("div", { className: "fusioni-chat-welcome-content", children: [jsx("h3", { children: t('chat.welcome.title') }), jsx("p", { children: t('chat.welcome.description') }), jsx("button", { onClick: handleCreateConversation, disabled: isLoading, className: "fusioni-btn fusioni-btn-primary", children: isLoading ? t('chat.welcome.creating') : t('chat.welcome.startButton') })] }) }))] })] }) })), jsx(ConfirmationDialog, { isOpen: isDeleteDialogOpen, title: t('chat.conversations.deleteConfirm.title'), message: t('chat.conversations.deleteConfirm.message'), confirmText: t('chat.conversations.deleteConfirm.confirm'), cancelText: t('chat.conversations.deleteConfirm.cancel'), onConfirm: confirmDeleteConversation, onCancel: cancelDeleteConversation, currentLanguage: currentLanguage, variant: "danger" }), jsx(ConfirmationDialog, { isOpen: isDeleteMessageDialogOpen, title: t('chat.messages.deleteConfirm.title'), message: t('chat.messages.deleteConfirm.message'), confirmText: t('chat.messages.deleteConfirm.confirm'), cancelText: t('chat.messages.deleteConfirm.cancel'), onConfirm: confirmDeleteMessage, onCancel: cancelDeleteMessage, currentLanguage: currentLanguage, variant: "danger" })] }));
6839
+ return (jsxs("div", { className: `fusioni-chat-widget ${theme}`, style: { '--primary-color': mergedConfig.primaryColor || '#6366f1' }, children: [jsx(FloatingButton, { isOpen: isOpen, onClick: handleToggleChat, position: mergedConfig.position || 'bottom-right', primaryColor: mergedConfig.primaryColor, buttonRef: floatingButtonRef, variant: mergedConfig.buttonVariant || 'glass', shouldDisplay: !hasConfigError && (!isMobileLayout || !isOpen) }), isOpen && (jsx(ChatPanel, { isOpen: isOpen, onClose: () => updateChatOpen(false), position: mergedConfig.position || 'bottom-right', isFullscreen: isFullscreen, floatingButtonRef: floatingButtonRef, children: jsxs("div", { className: "fusioni-chat-container", children: [mergedConfig.showConversationList !== false && (jsxs(Fragment, { children: [jsx("div", { className: `fusioni-conversation-backdrop ${isConversationListOpen ? 'open' : ''}`, onClick: () => setIsConversationListOpen(false) }), jsx(ConversationList, { conversations: conversations, selectedConversationId: currentConversation?.id || undefined, onSelectConversation: handleSelectConversation, onDeleteConversation: handleDeleteConversation, onCreateConversation: handleCreateConversation, isOpen: isConversationListOpen, currentLanguage: currentLanguage })] })), jsxs("div", { className: "fusioni-chat-main", children: [jsxs("div", { className: "fusioni-chat-main-header", children: [mergedConfig.showConversationList !== false ? (jsxs("button", { type: "button", onClick: handleToggleConversationList, className: `fusioni-conversation-toggle ${isConversationListOpen ? 'open' : ''}`, children: [jsx("svg", { className: "fusioni-conversation-toggle-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M3 12h18M3 6h18M3 18h18" }) }), t('chat.conversations.title')] })) : (jsx("span", { className: "fusioni-chat-main-header-title", children: t('chat.title') })), jsxs("div", { className: "fusioni-header-actions", children: [jsx("button", { type: "button", onClick: handleCreateConversation, disabled: isLoading, className: "fusioni-btn fusioni-btn-icon", title: t('chat.conversations.newConversation'), "aria-label": t('chat.conversations.newConversation'), children: jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: jsx("path", { d: "M12 5V19M5 12H19", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), mergedConfig.showThemeToggle !== false && (jsx("button", { type: "button", onClick: toggleTheme, className: "fusioni-btn fusioni-btn-icon", title: theme === 'dark' ? t('chat.theme.light') : t('chat.theme.dark'), children: theme === 'dark' ? (jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [jsx("circle", { cx: "12", cy: "12", r: "5" }), jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }), jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }), jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }), jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }), jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }), jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }), jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }), jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })] })) : (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) })) })), mergedConfig.showFullscreenToggle !== false && (jsx("button", { type: "button", onClick: handleToggleFullscreen, className: "fusioni-btn fusioni-btn-icon", title: isFullscreen ? t('chat.fullscreen.exit') : t('chat.fullscreen.enter'), children: isFullscreen ? (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M8 3V5M8 3H5M8 3L3 8M16 3V5M16 3H19M16 3L21 8M8 21V19M8 21H5M8 21L3 16M16 21V19M16 21H19M16 21L21 16" }) })) : (jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsx("path", { d: "M8 3H5C4.46957 3 3.96086 3.21071 3.58579 3.58579C3.21071 3.96086 3 4.46957 3 5V8M21 8V5C21 4.46957 20.7893 3.96086 20.4142 3.58579C20.0391 3.21071 19.5304 3 19 3H16M16 21H19C19.5304 21 20.0391 20.7893 20.4142 20.4142C20.7893 20.0391 21 19.5304 21 19V16M3 16V19C3 19.5304 3.21071 20.0391 3.58579 20.4142C3.96086 20.7893 4.46957 21 5 21H8" }) })) })), mergedConfig.showLanguageSwitcher !== false && (jsx(LanguageSwitcher, { currentLanguage: currentLanguage, onLanguageChange: handleLanguageChange })), jsx("button", { type: "button", onClick: () => updateChatOpen(false), className: "fusioni-btn fusioni-btn-icon fusioni-chat-toolbar-close-mobile", title: t('common.close'), "aria-label": t('common.close'), children: jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: jsx("path", { d: "M18 6L6 18M6 6L18 18", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), currentConversation ? (jsxs(Fragment, { children: [jsx(MessageList, { messages: messages, streamMessages: streamMessages, showThoughts: false, onDeleteMessage: handleDeleteMessage, onEditMessage: handleEditMessage, onConfirmation: handleConfirmation, enableButtons: !isLoading, apiBaseUrl: mergedConfig.apiBaseUrl, apiKey: mergedConfig.accessToken, agencyId: mergedConfig.agencyId, currentLanguage: currentLanguage, theme: theme, onSuggestionClick: (prompt) => handleSendMessage(prompt) }), jsx(ChatInput, { onSendMessage: handleSendMessage, onFileUpload: handleFileUpload, disabled: isLoading, placeholder: t('chat.input.placeholder'), enableAudioRecording: mergedConfig.enableAudioRecording !== false, enableFileUpload: mergedConfig.enableFileUpload !== false, maxFileSize: mergedConfig.maxFileSize || 10, allowedFileTypes: mergedConfig.allowedFileTypes || ['image/*'], currentLanguage: currentLanguage })] })) : (jsx("div", { className: "fusioni-chat-welcome", children: jsxs("div", { className: "fusioni-chat-welcome-content", children: [jsx("h3", { children: t('chat.welcome.title') }), jsx("p", { children: t('chat.welcome.description') }), jsx("button", { onClick: handleCreateConversation, disabled: isLoading, className: "fusioni-btn fusioni-btn-primary", children: isLoading ? t('chat.welcome.creating') : t('chat.welcome.startButton') })] }) }))] })] }) })), jsx(ConfirmationDialog, { isOpen: isDeleteDialogOpen, title: t('chat.conversations.deleteConfirm.title'), message: t('chat.conversations.deleteConfirm.message'), confirmText: t('chat.conversations.deleteConfirm.confirm'), cancelText: t('chat.conversations.deleteConfirm.cancel'), onConfirm: confirmDeleteConversation, onCancel: cancelDeleteConversation, currentLanguage: currentLanguage, variant: "danger" }), jsx(ConfirmationDialog, { isOpen: isDeleteMessageDialogOpen, title: t('chat.messages.deleteConfirm.title'), message: t('chat.messages.deleteConfirm.message'), confirmText: t('chat.messages.deleteConfirm.confirm'), cancelText: t('chat.messages.deleteConfirm.cancel'), onConfirm: confirmDeleteMessage, onCancel: cancelDeleteMessage, currentLanguage: currentLanguage, variant: "danger" })] }));
6691
6840
  });
6692
6841
  ChatWidget.displayName = 'ChatWidget';
6693
6842
 
@@ -6720,5 +6869,5 @@ const ChatLoader = () => {
6720
6869
  return (jsx("div", { className: "fusioni-chat-loader", children: jsxs("div", { className: "fusioni-loader-content", children: [jsxs("div", { className: "fusioni-loader-dots", children: [jsx("div", { className: "fusioni-loader-dot" }), jsx("div", { className: "fusioni-loader-dot" }), jsx("div", { className: "fusioni-loader-dot" })] }), jsx("span", { className: "fusioni-loader-text", children: "AI is thinking..." })] }) }));
6721
6870
  };
6722
6871
 
6723
- export { ApiClient, AudioRecorder, ChatInput, ChatLoader, ChatPanel, ChatWidget, ConversationList, FileUpload, FloatingButton, ImageGallery, LanguageSwitcher, Map$1 as Map, Message, MessageList, MessageService, PipelineService, Spotlight, UrlPreview, ChatWidget as default, getApiClient, getAvailableLanguages, getConversationService, getMessageService, getPipelineService, getTranslation, initializeApiClient, isValidLanguage, useChatState, useIsMobileLayout, useSSE, useTheme, useTranslation };
6872
+ export { ActionService, ApiClient, AudioRecorder, ChatInput, ChatLoader, ChatPanel, ChatWidget, ConversationList, FileUpload, FloatingButton, ImageGallery, LanguageSwitcher, Map$1 as Map, Message, MessageList, MessageService, PipelineService, Spotlight, UrlPreview, ChatWidget as default, getActionService, getApiClient, getAvailableLanguages, getConversationService, getMessageService, getPipelineService, getTranslation, initializeApiClient, isValidLanguage, resolveActionLiteral, toActionSuggestion, useChatState, useIsMobileLayout, useSSE, useTheme, useTranslation };
6724
6873
  //# sourceMappingURL=index.esm.js.map