@messenger-box/tailwind-ui-inbox 10.0.3-alpha.184 → 10.0.3-alpha.185

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/components/AIAgent/AIAgent.d.ts +2 -0
  3. package/lib/components/AIAgent/AIAgent.d.ts.map +1 -1
  4. package/lib/components/AIAgent/AIAgent.js +232 -89
  5. package/lib/components/AIAgent/AIAgent.js.map +1 -1
  6. package/lib/components/InboxMessage/InputComponent.d.ts +3 -1
  7. package/lib/components/InboxMessage/InputComponent.d.ts.map +1 -1
  8. package/lib/components/InboxMessage/InputComponent.js +6 -2
  9. package/lib/components/InboxMessage/InputComponent.js.map +1 -1
  10. package/lib/components/InboxMessage/RightSidebarAi.d.ts +2 -0
  11. package/lib/components/InboxMessage/RightSidebarAi.d.ts.map +1 -1
  12. package/lib/components/InboxMessage/RightSidebarAi.js.map +1 -1
  13. package/lib/components/ModelConfigPanel.d.ts +4 -0
  14. package/lib/components/ModelConfigPanel.d.ts.map +1 -1
  15. package/lib/components/ModelConfigPanel.js +17 -2
  16. package/lib/components/ModelConfigPanel.js.map +1 -1
  17. package/lib/container/AiLandingInput.d.ts +2 -0
  18. package/lib/container/AiLandingInput.d.ts.map +1 -1
  19. package/lib/container/AiLandingInput.js +4 -0
  20. package/lib/container/AiLandingInput.js.map +1 -1
  21. package/lib/container/Inbox.js +1 -1
  22. package/lib/container/InboxAiMessagesLoader.d.ts +2 -0
  23. package/lib/container/InboxAiMessagesLoader.d.ts.map +1 -1
  24. package/lib/container/InboxAiMessagesLoader.js +5 -1
  25. package/lib/container/InboxAiMessagesLoader.js.map +1 -1
  26. package/lib/container/InboxContainer.d.ts +2 -0
  27. package/lib/container/InboxContainer.d.ts.map +1 -1
  28. package/lib/container/InboxContainer.js.map +1 -1
  29. package/lib/container/InboxWithAiLoader.d.ts +2 -0
  30. package/lib/container/InboxWithAiLoader.d.ts.map +1 -1
  31. package/lib/container/InboxWithAiLoader.js +9 -3
  32. package/lib/container/InboxWithAiLoader.js.map +1 -1
  33. package/lib/container/ServiceInbox.js +1 -1
  34. package/lib/container/ServiceInbox.js.map +1 -1
  35. package/lib/container/TestInboxWithAiLoader.d.ts.map +1 -1
  36. package/lib/container/TestInboxWithAiLoader.js +5 -1
  37. package/lib/container/TestInboxWithAiLoader.js.map +1 -1
  38. package/lib/container/ThreadMessages.js +1 -1
  39. package/lib/container/ThreadMessages.js.map +1 -1
  40. package/lib/container/ThreadMessagesInbox.js +1 -1
  41. package/lib/container/ThreadMessagesInbox.js.map +1 -1
  42. package/lib/container/Threads.js +1 -1
  43. package/lib/container/Threads.js.map +1 -1
  44. package/lib/templates/InboxWithAi.d.ts +2 -0
  45. package/lib/templates/InboxWithAi.d.ts.map +1 -1
  46. package/lib/templates/InboxWithAi.js +24 -5
  47. package/lib/templates/InboxWithAi.js.map +1 -1
  48. package/lib/templates/InboxWithAi.tsx +25 -2
  49. package/package.json +2 -2
  50. package/src/components/AIAgent/AIAgent.tsx +291 -112
  51. package/src/components/InboxMessage/InputComponent.tsx +6 -0
  52. package/src/components/InboxMessage/RightSidebarAi.tsx +2 -0
  53. package/src/components/ModelConfigPanel.tsx +55 -37
  54. package/src/container/AiLandingInput.tsx +6 -0
  55. package/src/container/InboxAiMessagesLoader.tsx +6 -0
  56. package/src/container/InboxContainer.tsx +2 -0
  57. package/src/container/InboxWithAiLoader.tsx +8 -0
  58. package/src/container/TestInboxWithAiLoader.tsx +4 -0
  59. package/src/templates/InboxWithAi.tsx +25 -2
@@ -22,6 +22,8 @@ export interface ModelToolbarProps {
22
22
  showProjectSettings?: boolean;
23
23
  isShowMeta?: boolean;
24
24
  showModeSelector?: boolean;
25
+ showStopButton?: boolean;
26
+ onStop?: () => void;
25
27
  }
26
28
 
27
29
  const providerIcons: Record<ModelConfig['provider'], string> = {
@@ -376,6 +378,8 @@ export interface ModelToolbarProps {
376
378
  showProjectSettings?: boolean;
377
379
  isShowMeta?: boolean;
378
380
  showModeSelector?: boolean;
381
+ showStopButton?: boolean;
382
+ onStop?: () => void;
379
383
  }
380
384
 
381
385
  type MetadataFieldKey = keyof NonNullable<PersistentModelConfig['metadata']>;
@@ -463,6 +467,8 @@ export const ModelToolbar: React.FC<ModelToolbarProps> = ({
463
467
  showProjectSettings = true,
464
468
  isShowMeta = false,
465
469
  showModeSelector = false,
470
+ showStopButton = false,
471
+ onStop,
466
472
  }) => {
467
473
  const [showModelDropdown, setShowModelDropdown] = useState(false);
468
474
  const [showToolbarModelDropdown, setShowToolbarModelDropdown] = useState(false);
@@ -830,44 +836,56 @@ export const ModelToolbar: React.FC<ModelToolbarProps> = ({
830
836
  </div>
831
837
  </UploadImageButton>
832
838
 
833
- {/* Send Button */}
834
- <button
835
- className={`flex items-center justify-center w-7 h-7 sm:w-7 sm:h-7 rounded-lg border transition-colors shrink-0 ${
836
- canSend && !sending
837
- ? 'border-blue-500 bg-blue-500 hover:bg-blue-600 text-white'
838
- : 'border-gray-300 bg-gray-100 text-gray-400 cursor-not-allowed'
839
- }`}
840
- onClick={onSend}
841
- disabled={!canSend || sending}
842
- type="button"
843
- >
844
- {sending ? (
845
- <svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
846
- <circle
847
- className="opacity-25"
848
- cx="12"
849
- cy="12"
850
- r="10"
851
- stroke="currentColor"
852
- strokeWidth="4"
853
- ></circle>
854
- <path
855
- className="opacity-75"
856
- fill="currentColor"
857
- d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
858
- ></path>
859
- </svg>
860
- ) : (
861
- <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
862
- <path
863
- strokeLinecap="round"
864
- strokeLinejoin="round"
865
- strokeWidth={2}
866
- d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"
867
- />
839
+ {/* Send/Stop Button */}
840
+ {showStopButton ? (
841
+ <button
842
+ className="flex items-center justify-center w-7 h-7 sm:w-7 sm:h-7 rounded-lg border border-red-500 bg-red-500 hover:bg-red-600 text-white transition-colors shrink-0"
843
+ onClick={onStop}
844
+ type="button"
845
+ >
846
+ <svg className="w-3 h-3" fill="currentColor" viewBox="0 0 24 24">
847
+ <circle cx="12" cy="12" r="8" fill="white" />
868
848
  </svg>
869
- )}
870
- </button>
849
+ </button>
850
+ ) : (
851
+ <button
852
+ className={`flex items-center justify-center w-7 h-7 sm:w-7 sm:h-7 rounded-lg border transition-colors shrink-0 ${
853
+ canSend && !sending
854
+ ? 'border-blue-500 bg-blue-500 hover:bg-blue-600 text-white'
855
+ : 'border-gray-300 bg-gray-100 text-gray-400 cursor-not-allowed'
856
+ }`}
857
+ onClick={onSend}
858
+ disabled={!canSend || sending}
859
+ type="button"
860
+ >
861
+ {sending ? (
862
+ <svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
863
+ <circle
864
+ className="opacity-25"
865
+ cx="12"
866
+ cy="12"
867
+ r="10"
868
+ stroke="currentColor"
869
+ strokeWidth="4"
870
+ ></circle>
871
+ <path
872
+ className="opacity-75"
873
+ fill="currentColor"
874
+ d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
875
+ ></path>
876
+ </svg>
877
+ ) : (
878
+ <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
879
+ <path
880
+ strokeLinecap="round"
881
+ strokeLinejoin="round"
882
+ strokeWidth={2}
883
+ d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"
884
+ />
885
+ </svg>
886
+ )}
887
+ </button>
888
+ )}
871
889
  </div>
872
890
 
873
891
  {/* Settings Modal - Only API Key and Model + IDs */}
@@ -17,6 +17,8 @@ type AiLandingInputProps = {
17
17
  showModelToolbarProjectSettings?: boolean;
18
18
  isShowMeta?: boolean;
19
19
  showModeSelector?: boolean;
20
+ showStopButton?: boolean;
21
+ onStop?: () => void;
20
22
  [key: string]: any;
21
23
  };
22
24
 
@@ -24,6 +26,8 @@ const AiLandingInput: React.FC<AiLandingInputProps> = ({
24
26
  showModelToolbarProjectSettings = false,
25
27
  isShowMeta = false,
26
28
  showModeSelector = false,
29
+ showStopButton = false,
30
+ onStop = () => {},
27
31
  ...props
28
32
  }) => {
29
33
  const { orgName } = useParams();
@@ -160,6 +164,8 @@ const AiLandingInput: React.FC<AiLandingInputProps> = ({
160
164
  showModelToolbarProjectSettings={showModelToolbarProjectSettings}
161
165
  isShowMeta={isShowMeta}
162
166
  showModeSelector={showModeSelector}
167
+ showStopButton={showStopButton}
168
+ onStop={onStop}
163
169
  {...props}
164
170
  />
165
171
  {/* <div className="text-center text-sm text-gray-400">
@@ -21,6 +21,8 @@ interface InboxWithAiLoaderOutletProps {
21
21
  selectedPost?: any;
22
22
  setSelectedPost?: (post: any) => void;
23
23
  sendMessageInput?: (message: string, files: File[]) => Promise<void>;
24
+ showStopButton?: boolean;
25
+ onStop?: () => void;
24
26
  [key: string]: any; // Allow other props to be passed through to Inbox
25
27
  }
26
28
 
@@ -36,6 +38,8 @@ const InboxWithAiLoaderOutlet = (props: InboxWithAiLoaderOutletProps) => {
36
38
  sendMessageInput,
37
39
  isShowOnlyInbox,
38
40
  showModeSelector,
41
+ showStopButton = false,
42
+ onStop = () => {},
39
43
  } = useOutletContext() as any;
40
44
  const urlParams = location?.search ? new URLSearchParams(location.search) : null;
41
45
  const { id: pathChannelId } = useParams();
@@ -58,6 +62,8 @@ const InboxWithAiLoaderOutlet = (props: InboxWithAiLoaderOutletProps) => {
58
62
  isShowOnlyInbox={isShowOnlyInbox}
59
63
  showModeSelector={showModeSelector}
60
64
  showDateSeparators={props?.showDateSeparators || false}
65
+ showStopButton={showStopButton}
66
+ onStop={onStop}
61
67
  {...props}
62
68
  />
63
69
  );
@@ -13,6 +13,8 @@ interface InboxContainerProps {
13
13
  showModeSelector?: boolean;
14
14
  showContextTab?: boolean;
15
15
  ContextTabComponent?: React.ComponentType<{ context: any; selectedPost?: any }>;
16
+ showStopButton?: boolean;
17
+ onStop?: () => void;
16
18
  [key: string]: any;
17
19
  }
18
20
 
@@ -46,6 +46,8 @@ interface InboxWithAiLoaderProps {
46
46
  showModeSelector?: boolean;
47
47
  showContextTab?: boolean;
48
48
  ContextTabComponent?: React.ComponentType<{ context: any; selectedPost?: any }>;
49
+ showStopButton?: boolean;
50
+ onStop?: () => void;
49
51
  [key: string]: any;
50
52
  }
51
53
 
@@ -60,6 +62,8 @@ const InboxWithAiLoader = (props: InboxWithAiLoaderProps) => {
60
62
  showContextTab = true,
61
63
  ContextTabComponent = null,
62
64
  inboxTitle = 'Chat',
65
+ showStopButton = false,
66
+ onStop = () => {},
63
67
  } = props;
64
68
  const { orgName, channelRole: channelRoleParam } = useParams();
65
69
  const location = useLocation();
@@ -76,6 +80,8 @@ const InboxWithAiLoader = (props: InboxWithAiLoaderProps) => {
76
80
  showContextTab: showContextTab,
77
81
  ContextTabComponent: ContextTabComponent,
78
82
  inboxTitle: inboxTitle || 'Chat',
83
+ showStopButton: showStopButton,
84
+ onStop: onStop,
79
85
  }),
80
86
  [props, orgName, pathPrefix],
81
87
  );
@@ -96,6 +102,8 @@ const InboxWithAiLoader = (props: InboxWithAiLoaderProps) => {
96
102
  showModelToolbarProjectSettings={showModelToolbarProjectSettings}
97
103
  isShowMeta={isShowMeta}
98
104
  showModeSelector={showModeSelector}
105
+ showStopButton={showStopButton}
106
+ onStop={onStop}
99
107
  />
100
108
  );
101
109
  }
@@ -80,6 +80,10 @@ const TestInboxWithAiLoaderOutlet = () => {
80
80
  showContextTab={false}
81
81
  showModeSelector={true}
82
82
  inboxTitle="Chat"
83
+ showStopButton={true}
84
+ onStop={() => {
85
+ console.log('🛑 onStop called');
86
+ }}
83
87
  />
84
88
  );
85
89
  };
@@ -35,6 +35,8 @@ export interface InboxProps {
35
35
  inboxTitle?: string;
36
36
  showModeSelector?: boolean;
37
37
  showContextTab?: boolean;
38
+ showStopButton?: boolean;
39
+ onStop?: () => void;
38
40
  ContextTabComponent?: React.ComponentType<{ context: any; selectedPost?: any }>;
39
41
  }
40
42
 
@@ -169,16 +171,29 @@ const InboxWithAiInternal = (props: InboxProps) => {
169
171
  setIsCreatingSandbox(true);
170
172
  setError(null);
171
173
 
172
- props.handleRecreateSandbox?.(messageId);
174
+ props?.handleRecreateSandbox?.(messageId);
173
175
  } catch (err) {
174
176
  console.error('Error recreating sandbox:', err);
175
177
  setError(err instanceof Error ? err.message : 'Failed to recreate sandbox');
176
178
  setIsCreatingSandbox(false);
177
179
  }
178
180
  },
179
- [channelId],
181
+ [channelId, props?.handleRecreateSandbox],
180
182
  );
181
183
 
184
+ const handleStop = useCallback(async () => {
185
+ try {
186
+ setIsCreatingSandbox(true);
187
+ setError(null);
188
+
189
+ props?.onStop?.();
190
+ } catch (err) {
191
+ console.error('Error stopping:', err);
192
+ setError(err instanceof Error ? err.message : 'Failed to recreate sandbox');
193
+ setIsCreatingSandbox(false);
194
+ }
195
+ }, [props?.onStop]);
196
+
182
197
  // Handle refresh sandbox
183
198
  const handleRefreshSandbox = useCallback(() => {
184
199
  if (selectedPost) {
@@ -424,6 +439,8 @@ const InboxWithAiInternal = (props: InboxProps) => {
424
439
  sendMessageInput={sendMessageInput}
425
440
  isShowOnlyInbox={isShowOnlyInbox}
426
441
  showModeSelector={props?.showModeSelector}
442
+ showStopButton={props?.showStopButton}
443
+ onStop={handleStop}
427
444
  />
428
445
  ) : (
429
446
  <EmptyState />
@@ -459,6 +476,8 @@ const InboxWithAiInternal = (props: InboxProps) => {
459
476
  handleRecreateSandbox={props?.handleRecreateSandbox || null}
460
477
  isMinimized={isMinimized}
461
478
  ContextTabComponent={props?.ContextTabComponent ?? DefaultContextTab}
479
+ showStopButton={props?.showStopButton}
480
+ onStop={handleStop}
462
481
  {...props}
463
482
  />
464
483
  </div>
@@ -481,6 +500,8 @@ const ContentComponent = React.memo((props: any) => {
481
500
  sendMessageInput,
482
501
  isShowOnlyInbox,
483
502
  showModeSelector,
503
+ showStopButton,
504
+ onStop,
484
505
  } = props;
485
506
 
486
507
  return (
@@ -503,6 +524,8 @@ const ContentComponent = React.memo((props: any) => {
503
524
  sendMessageInput={sendMessageInput}
504
525
  isShowOnlyInbox={isShowOnlyInbox}
505
526
  showModeSelector={showModeSelector}
527
+ showStopButton={showStopButton}
528
+ onStop={onStop}
506
529
  />
507
530
  </>
508
531
  )}