@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.js CHANGED
@@ -65,6 +65,7 @@ const en = {
65
65
  emptyState: {
66
66
  title: 'How can I help today?',
67
67
  description: 'Ask a question, share a task, or describe what you need. Fusioni is ready when you are.',
68
+ suggestionsLabel: 'Suggested actions',
68
69
  suggestionOne: 'Ask a question',
69
70
  suggestionTwo: 'Compare options',
70
71
  suggestionThree: 'Get next steps'
@@ -166,6 +167,7 @@ const el = {
166
167
  emptyState: {
167
168
  title: 'Πώς μπορώ να βοηθήσω σήμερα;',
168
169
  description: 'Κάντε μια ερώτηση, μοιραστείτε μια εργασία ή περιγράψτε τι χρειάζεστε. Το Fusioni είναι έτοιμο όταν είστε κι εσείς.',
170
+ suggestionsLabel: 'Προτεινόμενες ενέργειες',
169
171
  suggestionOne: 'Κάντε μια ερώτηση',
170
172
  suggestionTwo: 'Συγκρίνετε επιλογές',
171
173
  suggestionThree: 'Δείτε επόμενα βήματα'
@@ -5373,8 +5375,65 @@ const ImageGallery = ({ images, initialIndex = 0, onClose, theme = 'light', }) =
5373
5375
  }, children: jsxRuntime.jsx("img", { src: images[gi], alt: "", loading: "lazy", referrerPolicy: "no-referrer" }) })) }) }))] })] }));
5374
5376
  };
5375
5377
 
5376
- const MessageList = ({ messages, streamMessages, showThoughts = false, onDeleteMessage, onEditMessage, onConfirmation, enableButtons = true, apiBaseUrl, apiKey, agencyId, currentLanguage = 'en', theme = 'light' }) => {
5378
+ function resolveActionLiteral(action, language) {
5379
+ if (!action.literals?.length) {
5380
+ return undefined;
5381
+ }
5382
+ return (action.literals.find((l) => l.language === language)
5383
+ ?? action.literals.find((l) => l.language === 'en')
5384
+ ?? action.literals[0]);
5385
+ }
5386
+ function toActionSuggestion(action, language) {
5387
+ if (action.enabled === false) {
5388
+ return null;
5389
+ }
5390
+ const literal = resolveActionLiteral(action, language);
5391
+ const label = (literal?.text || action.title || '').trim();
5392
+ const prompt = (literal?.prompt || literal?.text || action.title || '').trim();
5393
+ if (!label) {
5394
+ return null;
5395
+ }
5396
+ return {
5397
+ id: action.id,
5398
+ label,
5399
+ prompt: prompt || label,
5400
+ };
5401
+ }
5402
+ class ActionService {
5403
+ getApiClient() {
5404
+ return getApiClient();
5405
+ }
5406
+ async findEnabledByAgencyId(agencyId) {
5407
+ const apiClient = this.getApiClient();
5408
+ return await apiClient.get('/action/enabled', {
5409
+ params: {
5410
+ agency_id: agencyId,
5411
+ },
5412
+ });
5413
+ }
5414
+ async findByAgencyId(agencyId, page = 0, size = 100) {
5415
+ const apiClient = this.getApiClient();
5416
+ const response = await apiClient.get('/action/list', {
5417
+ params: {
5418
+ agency_id: agencyId,
5419
+ page,
5420
+ size,
5421
+ },
5422
+ });
5423
+ return response?.body ?? [];
5424
+ }
5425
+ }
5426
+ let actionServiceInstance = null;
5427
+ const getActionService = () => {
5428
+ if (!actionServiceInstance) {
5429
+ actionServiceInstance = new ActionService();
5430
+ }
5431
+ return actionServiceInstance;
5432
+ };
5433
+
5434
+ const MessageList = ({ messages, streamMessages, showThoughts = false, onDeleteMessage, onEditMessage, onConfirmation, enableButtons = true, apiBaseUrl, apiKey, agencyId, currentLanguage = 'en', theme = 'light', onSuggestionClick, }) => {
5377
5435
  const { t } = useTranslation(currentLanguage);
5436
+ const [suggestions, setSuggestions] = react.useState([]);
5378
5437
  const messagesEndRef = react.useRef(null);
5379
5438
  const scrollContainerRef = react.useRef(null);
5380
5439
  const editRef = react.useRef(null);
@@ -5407,6 +5466,51 @@ const MessageList = ({ messages, streamMessages, showThoughts = false, onDeleteM
5407
5466
  react.useEffect(() => {
5408
5467
  scrollToBottom();
5409
5468
  }, [messages, streamMessages]);
5469
+ react.useEffect(() => {
5470
+ if (!agencyId) {
5471
+ setSuggestions([]);
5472
+ return;
5473
+ }
5474
+ let cancelled = false;
5475
+ getActionService()
5476
+ .findEnabledByAgencyId(agencyId)
5477
+ .then((actions) => {
5478
+ if (cancelled) {
5479
+ return;
5480
+ }
5481
+ const items = actions
5482
+ .map((action) => toActionSuggestion(action, currentLanguage))
5483
+ .filter((item) => item !== null);
5484
+ setSuggestions(items);
5485
+ })
5486
+ .catch((error) => {
5487
+ console.error('Failed to load action suggestions:', error);
5488
+ if (!cancelled) {
5489
+ setSuggestions([]);
5490
+ }
5491
+ });
5492
+ return () => {
5493
+ cancelled = true;
5494
+ };
5495
+ }, [agencyId, currentLanguage]);
5496
+ const defaultSuggestions = react.useMemo(() => [
5497
+ {
5498
+ id: 'default-suggestion-1',
5499
+ label: t('chat.emptyState.suggestionOne'),
5500
+ prompt: t('chat.emptyState.suggestionOne'),
5501
+ },
5502
+ {
5503
+ id: 'default-suggestion-2',
5504
+ label: t('chat.emptyState.suggestionTwo'),
5505
+ prompt: t('chat.emptyState.suggestionTwo'),
5506
+ },
5507
+ {
5508
+ id: 'default-suggestion-3',
5509
+ label: t('chat.emptyState.suggestionThree'),
5510
+ prompt: t('chat.emptyState.suggestionThree'),
5511
+ },
5512
+ ], [t, currentLanguage]);
5513
+ const displaySuggestions = suggestions.length > 0 ? suggestions : defaultSuggestions;
5410
5514
  const formatDate = (date) => {
5411
5515
  const now = new Date();
5412
5516
  const diffInMilliseconds = now.getTime() - new Date(date).getTime();
@@ -5468,7 +5572,7 @@ const MessageList = ({ messages, streamMessages, showThoughts = false, onDeleteM
5468
5572
  selection.addRange(range);
5469
5573
  }
5470
5574
  }, [editingMessageId, editingContent]);
5471
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: "fusioni-message-list", ref: scrollContainerRef, children: jsxRuntime.jsxs("div", { className: "fusioni-messages-container", children: [messages.length === 0 ? (jsxRuntime.jsx("div", { className: "fusioni-empty-messages", children: jsxRuntime.jsxs("div", { className: "fusioni-empty-messages-content", children: [jsxRuntime.jsx("div", { className: "fusioni-empty-icon-frame", "aria-hidden": "true", children: jsxRuntime.jsx("img", { src: FUSIONI_LOGO_BASE64, alt: "", width: "40", height: "40", className: "fusioni-empty-logo" }) }), jsxRuntime.jsx("h3", { children: t('chat.emptyState.title') }), jsxRuntime.jsx("p", { children: t('chat.emptyState.description') }), jsxRuntime.jsxs("div", { className: "fusioni-empty-suggestions", "aria-hidden": "true", children: [jsxRuntime.jsx("span", { children: t('chat.emptyState.suggestionOne') }), jsxRuntime.jsx("span", { children: t('chat.emptyState.suggestionTwo') }), jsxRuntime.jsx("span", { children: t('chat.emptyState.suggestionThree') })] })] }) })) : (jsxRuntime.jsx("div", { className: "fusioni-messages", children: messages.map((message, index) => {
5575
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: "fusioni-message-list", ref: scrollContainerRef, children: jsxRuntime.jsxs("div", { className: "fusioni-messages-container", children: [messages.length === 0 ? (jsxRuntime.jsx("div", { className: "fusioni-empty-messages", children: jsxRuntime.jsxs("div", { className: "fusioni-empty-messages-content", children: [jsxRuntime.jsx("div", { className: "fusioni-empty-icon-frame", "aria-hidden": "true", children: jsxRuntime.jsx("img", { src: FUSIONI_LOGO_BASE64, alt: "", width: "60", height: "60", className: "fusioni-empty-logo" }) }), jsxRuntime.jsx("h3", { children: t('chat.emptyState.title') }), jsxRuntime.jsx("p", { children: t('chat.emptyState.description') }), jsxRuntime.jsx("div", { className: "fusioni-empty-suggestions", role: "list", "aria-label": t('chat.emptyState.suggestionsLabel'), children: displaySuggestions.map((suggestion, index) => (jsxRuntime.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}`))) })] }) })) : (jsxRuntime.jsx("div", { className: "fusioni-messages", children: messages.map((message, index) => {
5472
5576
  const isLastMessage = index === messages.length - 1;
5473
5577
  const messageKey = message.id ??
5474
5578
  `msg-fallback-${index}-${message.role}-${message.created instanceof Date ? message.created.getTime() : 0}`;
@@ -6113,6 +6217,7 @@ function useIsMobileLayout() {
6113
6217
  }
6114
6218
 
6115
6219
  const getStoredConversationIdKey = (agencyId) => `fusioni:selectedConversationId:${agencyId}`;
6220
+ const getStoredChatPanelOpenKey = (agencyId) => `fusioni:chatPanelOpen:${agencyId}`;
6116
6221
  const readStoredConversationId = (agencyId) => {
6117
6222
  if (typeof window === 'undefined')
6118
6223
  return null;
@@ -6139,6 +6244,26 @@ const writeStoredConversationId = (agencyId, conversationId) => {
6139
6244
  // Storage can be unavailable in restricted browser contexts.
6140
6245
  }
6141
6246
  };
6247
+ const readStoredChatPanelOpen = (agencyId) => {
6248
+ if (typeof window === 'undefined')
6249
+ return false;
6250
+ try {
6251
+ return window.sessionStorage.getItem(getStoredChatPanelOpenKey(agencyId)) === 'true';
6252
+ }
6253
+ catch {
6254
+ return false;
6255
+ }
6256
+ };
6257
+ const writeStoredChatPanelOpen = (agencyId, isOpen) => {
6258
+ if (typeof window === 'undefined')
6259
+ return;
6260
+ try {
6261
+ window.sessionStorage.setItem(getStoredChatPanelOpenKey(agencyId), String(isOpen));
6262
+ }
6263
+ catch {
6264
+ // Storage can be unavailable in restricted browser contexts.
6265
+ }
6266
+ };
6142
6267
  const ChatWidget = react.forwardRef(function ChatWidget({ config, onMessageSent, onMessageReceived, onConversationCreated, onConversationDeleted, onError }, ref) {
6143
6268
  const [languageOverride, setLanguageOverride] = react.useState(null);
6144
6269
  const [isOpen, setIsOpen] = react.useState(false);
@@ -6161,6 +6286,15 @@ const ChatWidget = react.forwardRef(function ChatWidget({ config, onMessageSent,
6161
6286
  // Translation and language management - use merged config or fallback to user config
6162
6287
  const { t, currentLanguage, changeLanguage } = useTranslation(translationDefault);
6163
6288
  const activeAgencyId = mergedConfig?.agencyId || config.agencyId;
6289
+ const updateChatOpen = react.useCallback((nextIsOpen) => {
6290
+ setIsOpen(nextIsOpen);
6291
+ if (activeAgencyId) {
6292
+ writeStoredChatPanelOpen(activeAgencyId, nextIsOpen);
6293
+ }
6294
+ if (!nextIsOpen) {
6295
+ setIsConversationListOpen(false);
6296
+ }
6297
+ }, [activeAgencyId]);
6164
6298
  const { conversations, currentConversation, messages, streamMessages, setCurrentConversation, setStreamMessages, addMessage, updateMessage, removeMessage, removeOptimisticUserMessages, truncateMessagesAt, addConversation, updateConversation, removeConversation, loadConversations, loadMessages, clearMessages } = useChatState(activeAgencyId);
6165
6299
  const { theme, toggleTheme, setTheme } = useTheme(mergedConfig?.theme || config.theme);
6166
6300
  const isMobileLayout = useIsMobileLayout();
@@ -6242,6 +6376,12 @@ const ChatWidget = react.forwardRef(function ChatWidget({ config, onMessageSent,
6242
6376
  };
6243
6377
  }
6244
6378
  }, [activeAgencyId, loadConversations]);
6379
+ react.useEffect(() => {
6380
+ if (!activeAgencyId) {
6381
+ return;
6382
+ }
6383
+ setIsOpen(readStoredChatPanelOpen(activeAgencyId));
6384
+ }, [activeAgencyId]);
6245
6385
  // SSE connection for real-time updates - only when a chat panel is open
6246
6386
  useSSE(activeAgencyId, (data) => {
6247
6387
  // Same as fusioni-web chat.component: latest SSE line replaces stream (single loading row updates)
@@ -6256,8 +6396,17 @@ const ChatWidget = react.forwardRef(function ChatWidget({ config, onMessageSent,
6256
6396
  };
6257
6397
  }, []);
6258
6398
  const handleToggleChat = react.useCallback(() => {
6259
- setIsOpen(prev => !prev);
6260
- }, []);
6399
+ setIsOpen(prev => {
6400
+ const nextIsOpen = !prev;
6401
+ if (activeAgencyId) {
6402
+ writeStoredChatPanelOpen(activeAgencyId, nextIsOpen);
6403
+ }
6404
+ if (!nextIsOpen) {
6405
+ setIsConversationListOpen(false);
6406
+ }
6407
+ return nextIsOpen;
6408
+ });
6409
+ }, [activeAgencyId]);
6261
6410
  const handleToggleConversationList = react.useCallback(() => {
6262
6411
  setIsConversationListOpen(prev => !prev);
6263
6412
  }, []);
@@ -6691,7 +6840,7 @@ const ChatWidget = react.forwardRef(function ChatWidget({ config, onMessageSent,
6691
6840
  if (error) {
6692
6841
  return (jsxRuntime.jsxs("div", { className: "fusioni-chat-error", children: [jsxRuntime.jsxs("p", { children: [t('common.error'), ": ", error] }), jsxRuntime.jsx("button", { onClick: () => setError(null), children: t('chat.errors.retry') })] }));
6693
6842
  }
6694
- return (jsxRuntime.jsxs("div", { className: `fusioni-chat-widget ${theme}`, style: { '--primary-color': mergedConfig.primaryColor || '#6366f1' }, children: [jsxRuntime.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 && (jsxRuntime.jsx(ChatPanel, { isOpen: isOpen, onClose: () => setIsOpen(false), position: mergedConfig.position || 'bottom-right', isFullscreen: isFullscreen, floatingButtonRef: floatingButtonRef, children: jsxRuntime.jsxs("div", { className: "fusioni-chat-container", children: [mergedConfig.showConversationList !== false && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: `fusioni-conversation-backdrop ${isConversationListOpen ? 'open' : ''}`, onClick: () => setIsConversationListOpen(false) }), jsxRuntime.jsx(ConversationList, { conversations: conversations, selectedConversationId: currentConversation?.id || undefined, onSelectConversation: handleSelectConversation, onDeleteConversation: handleDeleteConversation, onCreateConversation: handleCreateConversation, isOpen: isConversationListOpen, currentLanguage: currentLanguage })] })), jsxRuntime.jsxs("div", { className: "fusioni-chat-main", children: [jsxRuntime.jsxs("div", { className: "fusioni-chat-main-header", children: [mergedConfig.showConversationList !== false ? (jsxRuntime.jsxs("button", { type: "button", onClick: handleToggleConversationList, className: `fusioni-conversation-toggle ${isConversationListOpen ? 'open' : ''}`, children: [jsxRuntime.jsx("svg", { className: "fusioni-conversation-toggle-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntime.jsx("path", { d: "M3 12h18M3 6h18M3 18h18" }) }), t('chat.conversations.title')] })) : (jsxRuntime.jsx("span", { className: "fusioni-chat-main-header-title", children: t('chat.title') })), jsxRuntime.jsxs("div", { className: "fusioni-header-actions", children: [jsxRuntime.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: jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M12 5V19M5 12H19", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), mergedConfig.showThemeToggle !== false && (jsxRuntime.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' ? (jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "5" }), jsxRuntime.jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }), jsxRuntime.jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }), jsxRuntime.jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }), jsxRuntime.jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }), jsxRuntime.jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }), jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }), jsxRuntime.jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }), jsxRuntime.jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })] })) : (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntime.jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) })) })), mergedConfig.showFullscreenToggle !== false && (jsxRuntime.jsx("button", { type: "button", onClick: handleToggleFullscreen, className: "fusioni-btn fusioni-btn-icon", title: isFullscreen ? t('chat.fullscreen.exit') : t('chat.fullscreen.enter'), children: isFullscreen ? (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntime.jsx("path", { d: "M8 3V5M8 3H5M8 3L3 8M16 3V5M16 3H19M16 3L21 8M8 21V19M8 21H5M8 21L3 16M16 21V19M16 21H19M16 21L21 16" }) })) : (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntime.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 && (jsxRuntime.jsx(LanguageSwitcher, { currentLanguage: currentLanguage, onLanguageChange: handleLanguageChange })), jsxRuntime.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: jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6L18 18", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), currentConversation ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.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 }), jsxRuntime.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 })] })) : (jsxRuntime.jsx("div", { className: "fusioni-chat-welcome", children: jsxRuntime.jsxs("div", { className: "fusioni-chat-welcome-content", children: [jsxRuntime.jsx("h3", { children: t('chat.welcome.title') }), jsxRuntime.jsx("p", { children: t('chat.welcome.description') }), jsxRuntime.jsx("button", { onClick: handleCreateConversation, disabled: isLoading, className: "fusioni-btn fusioni-btn-primary", children: isLoading ? t('chat.welcome.creating') : t('chat.welcome.startButton') })] }) }))] })] }) })), jsxRuntime.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" }), jsxRuntime.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" })] }));
6843
+ return (jsxRuntime.jsxs("div", { className: `fusioni-chat-widget ${theme}`, style: { '--primary-color': mergedConfig.primaryColor || '#6366f1' }, children: [jsxRuntime.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 && (jsxRuntime.jsx(ChatPanel, { isOpen: isOpen, onClose: () => updateChatOpen(false), position: mergedConfig.position || 'bottom-right', isFullscreen: isFullscreen, floatingButtonRef: floatingButtonRef, children: jsxRuntime.jsxs("div", { className: "fusioni-chat-container", children: [mergedConfig.showConversationList !== false && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: `fusioni-conversation-backdrop ${isConversationListOpen ? 'open' : ''}`, onClick: () => setIsConversationListOpen(false) }), jsxRuntime.jsx(ConversationList, { conversations: conversations, selectedConversationId: currentConversation?.id || undefined, onSelectConversation: handleSelectConversation, onDeleteConversation: handleDeleteConversation, onCreateConversation: handleCreateConversation, isOpen: isConversationListOpen, currentLanguage: currentLanguage })] })), jsxRuntime.jsxs("div", { className: "fusioni-chat-main", children: [jsxRuntime.jsxs("div", { className: "fusioni-chat-main-header", children: [mergedConfig.showConversationList !== false ? (jsxRuntime.jsxs("button", { type: "button", onClick: handleToggleConversationList, className: `fusioni-conversation-toggle ${isConversationListOpen ? 'open' : ''}`, children: [jsxRuntime.jsx("svg", { className: "fusioni-conversation-toggle-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntime.jsx("path", { d: "M3 12h18M3 6h18M3 18h18" }) }), t('chat.conversations.title')] })) : (jsxRuntime.jsx("span", { className: "fusioni-chat-main-header-title", children: t('chat.title') })), jsxRuntime.jsxs("div", { className: "fusioni-header-actions", children: [jsxRuntime.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: jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M12 5V19M5 12H19", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }), mergedConfig.showThemeToggle !== false && (jsxRuntime.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' ? (jsxRuntime.jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "5" }), jsxRuntime.jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }), jsxRuntime.jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }), jsxRuntime.jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }), jsxRuntime.jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }), jsxRuntime.jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }), jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }), jsxRuntime.jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }), jsxRuntime.jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })] })) : (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntime.jsx("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) })) })), mergedConfig.showFullscreenToggle !== false && (jsxRuntime.jsx("button", { type: "button", onClick: handleToggleFullscreen, className: "fusioni-btn fusioni-btn-icon", title: isFullscreen ? t('chat.fullscreen.exit') : t('chat.fullscreen.enter'), children: isFullscreen ? (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntime.jsx("path", { d: "M8 3V5M8 3H5M8 3L3 8M16 3V5M16 3H19M16 3L21 8M8 21V19M8 21H5M8 21L3 16M16 21V19M16 21H19M16 21L21 16" }) })) : (jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: jsxRuntime.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 && (jsxRuntime.jsx(LanguageSwitcher, { currentLanguage: currentLanguage, onLanguageChange: handleLanguageChange })), jsxRuntime.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: jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M18 6L6 18M6 6L18 18", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] }), currentConversation ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.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) }), jsxRuntime.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 })] })) : (jsxRuntime.jsx("div", { className: "fusioni-chat-welcome", children: jsxRuntime.jsxs("div", { className: "fusioni-chat-welcome-content", children: [jsxRuntime.jsx("h3", { children: t('chat.welcome.title') }), jsxRuntime.jsx("p", { children: t('chat.welcome.description') }), jsxRuntime.jsx("button", { onClick: handleCreateConversation, disabled: isLoading, className: "fusioni-btn fusioni-btn-primary", children: isLoading ? t('chat.welcome.creating') : t('chat.welcome.startButton') })] }) }))] })] }) })), jsxRuntime.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" }), jsxRuntime.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" })] }));
6695
6844
  });
6696
6845
  ChatWidget.displayName = 'ChatWidget';
6697
6846
 
@@ -6724,6 +6873,7 @@ const ChatLoader = () => {
6724
6873
  return (jsxRuntime.jsx("div", { className: "fusioni-chat-loader", children: jsxRuntime.jsxs("div", { className: "fusioni-loader-content", children: [jsxRuntime.jsxs("div", { className: "fusioni-loader-dots", children: [jsxRuntime.jsx("div", { className: "fusioni-loader-dot" }), jsxRuntime.jsx("div", { className: "fusioni-loader-dot" }), jsxRuntime.jsx("div", { className: "fusioni-loader-dot" })] }), jsxRuntime.jsx("span", { className: "fusioni-loader-text", children: "AI is thinking..." })] }) }));
6725
6874
  };
6726
6875
 
6876
+ exports.ActionService = ActionService;
6727
6877
  exports.ApiClient = ApiClient;
6728
6878
  exports.AudioRecorder = AudioRecorder;
6729
6879
  exports.ChatInput = ChatInput;
@@ -6743,6 +6893,7 @@ exports.PipelineService = PipelineService;
6743
6893
  exports.Spotlight = Spotlight;
6744
6894
  exports.UrlPreview = UrlPreview;
6745
6895
  exports.default = ChatWidget;
6896
+ exports.getActionService = getActionService;
6746
6897
  exports.getApiClient = getApiClient;
6747
6898
  exports.getAvailableLanguages = getAvailableLanguages;
6748
6899
  exports.getConversationService = getConversationService;
@@ -6751,6 +6902,8 @@ exports.getPipelineService = getPipelineService;
6751
6902
  exports.getTranslation = getTranslation;
6752
6903
  exports.initializeApiClient = initializeApiClient;
6753
6904
  exports.isValidLanguage = isValidLanguage;
6905
+ exports.resolveActionLiteral = resolveActionLiteral;
6906
+ exports.toActionSuggestion = toActionSuggestion;
6754
6907
  exports.useChatState = useChatState;
6755
6908
  exports.useIsMobileLayout = useIsMobileLayout;
6756
6909
  exports.useSSE = useSSE;