@autobe/ui 0.22.1 → 0.23.1

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 (128) hide show
  1. package/lib/components/AutoBeChatMain.d.ts +6 -4
  2. package/lib/components/AutoBeChatMain.js +204 -56
  3. package/lib/components/AutoBeChatMain.js.map +1 -1
  4. package/lib/components/AutoBeChatSidebar.d.ts +36 -0
  5. package/lib/components/AutoBeChatSidebar.js +227 -0
  6. package/lib/components/AutoBeChatSidebar.js.map +1 -0
  7. package/lib/components/AutoBeConfigButton.d.ts +15 -0
  8. package/lib/components/AutoBeConfigButton.js +33 -0
  9. package/lib/components/AutoBeConfigButton.js.map +1 -0
  10. package/lib/components/AutoBeConfigModal.d.ts +59 -0
  11. package/lib/components/AutoBeConfigModal.js +294 -0
  12. package/lib/components/AutoBeConfigModal.js.map +1 -0
  13. package/lib/components/AutoBeStatusButton.d.ts +12 -0
  14. package/lib/components/AutoBeStatusButton.js +29 -0
  15. package/lib/components/AutoBeStatusButton.js.map +1 -0
  16. package/lib/components/AutoBeStatusModal.js +35 -15
  17. package/lib/components/AutoBeStatusModal.js.map +1 -1
  18. package/lib/components/common/ActionButton.d.ts +16 -0
  19. package/lib/components/common/ActionButton.js +115 -0
  20. package/lib/components/common/ActionButton.js.map +1 -0
  21. package/lib/components/common/ActionButtonGroup.d.ts +13 -0
  22. package/lib/components/common/ActionButtonGroup.js +37 -0
  23. package/lib/components/common/ActionButtonGroup.js.map +1 -0
  24. package/lib/components/common/AutoBeConfigInput.d.ts +24 -0
  25. package/lib/components/common/AutoBeConfigInput.js +90 -0
  26. package/lib/components/common/AutoBeConfigInput.js.map +1 -0
  27. package/lib/components/common/CompactSessionIndicator.d.ts +16 -0
  28. package/lib/components/common/CompactSessionIndicator.js +46 -0
  29. package/lib/components/common/CompactSessionIndicator.js.map +1 -0
  30. package/lib/components/common/CompactSessionList.d.ts +22 -0
  31. package/lib/components/common/CompactSessionList.js +40 -0
  32. package/lib/components/common/CompactSessionList.js.map +1 -0
  33. package/lib/components/common/index.d.ts +6 -0
  34. package/lib/components/common/index.js +6 -0
  35. package/lib/components/common/index.js.map +1 -1
  36. package/lib/components/events/AutoBeEventGroupMovie.d.ts +6 -0
  37. package/lib/components/events/AutoBeEventGroupMovie.js +11 -0
  38. package/lib/components/events/AutoBeEventGroupMovie.js.map +1 -0
  39. package/lib/components/events/AutoBeEventMovie.js +5 -0
  40. package/lib/components/events/AutoBeEventMovie.js.map +1 -1
  41. package/lib/components/events/AutoBeValidateEventMovie.js +1 -3
  42. package/lib/components/events/AutoBeValidateEventMovie.js.map +1 -1
  43. package/lib/components/events/common/CollapsibleEventGroup.d.ts +1 -1
  44. package/lib/components/events/groups/ValidateEventGroup.d.ts +1 -1
  45. package/lib/components/events/utils/eventGrouper.js.map +1 -1
  46. package/lib/components/index.d.ts +6 -0
  47. package/lib/components/index.js +7 -0
  48. package/lib/components/index.js.map +1 -1
  49. package/lib/components/upload/AutoBeChatUploadBox.js +75 -33
  50. package/lib/components/upload/AutoBeChatUploadBox.js.map +1 -1
  51. package/lib/context/AutoBeAgentContext.d.ts +22 -11
  52. package/lib/context/AutoBeAgentContext.js +127 -11
  53. package/lib/context/AutoBeAgentContext.js.map +1 -1
  54. package/lib/context/AutoBeAgentSessionList.d.ts +12 -0
  55. package/lib/context/AutoBeAgentSessionList.js +37 -0
  56. package/lib/context/AutoBeAgentSessionList.js.map +1 -0
  57. package/lib/context/SearchParamsContext.d.ts +10 -0
  58. package/lib/context/SearchParamsContext.js +29 -0
  59. package/lib/context/SearchParamsContext.js.map +1 -0
  60. package/lib/index.d.ts +4 -0
  61. package/lib/index.js +4 -0
  62. package/lib/index.js.map +1 -1
  63. package/lib/structure/AutoBeListener.d.ts +6 -0
  64. package/lib/structure/AutoBeListener.js +21 -4
  65. package/lib/structure/AutoBeListener.js.map +1 -1
  66. package/lib/structure/IAutoBeAgentSessionStorageStrategy.d.ts +35 -0
  67. package/lib/structure/IAutoBeAgentSessionStorageStrategy.js +30 -0
  68. package/lib/structure/IAutoBeAgentSessionStorageStrategy.js.map +1 -0
  69. package/lib/structure/index.d.ts +1 -0
  70. package/lib/structure/index.js +1 -0
  71. package/lib/structure/index.js.map +1 -1
  72. package/lib/types/config.d.ts +26 -0
  73. package/lib/types/config.js +14 -0
  74. package/lib/types/config.js.map +1 -0
  75. package/lib/types/index.d.ts +1 -0
  76. package/lib/types/index.js +18 -0
  77. package/lib/types/index.js.map +1 -0
  78. package/lib/utils/__tests__/crypto.test.d.ts +1 -0
  79. package/lib/utils/__tests__/crypto.test.js +222 -0
  80. package/lib/utils/__tests__/crypto.test.js.map +1 -0
  81. package/lib/utils/__tests__/storage.test.d.ts +1 -0
  82. package/lib/utils/__tests__/storage.test.js +174 -0
  83. package/lib/utils/__tests__/storage.test.js.map +1 -0
  84. package/lib/utils/crypto.d.ts +18 -0
  85. package/lib/utils/crypto.js +84 -0
  86. package/lib/utils/crypto.js.map +1 -0
  87. package/lib/utils/index.d.ts +2 -0
  88. package/lib/utils/index.js +2 -0
  89. package/lib/utils/index.js.map +1 -1
  90. package/lib/utils/storage.d.ts +29 -0
  91. package/lib/utils/storage.js +93 -0
  92. package/lib/utils/storage.js.map +1 -0
  93. package/package.json +11 -3
  94. package/src/components/AutoBeChatMain.tsx +329 -131
  95. package/src/components/AutoBeChatSidebar.tsx +414 -0
  96. package/src/components/AutoBeConfigButton.tsx +83 -0
  97. package/src/components/AutoBeConfigModal.tsx +444 -0
  98. package/src/components/AutoBeStatusButton.tsx +75 -0
  99. package/src/components/AutoBeStatusModal.tsx +55 -54
  100. package/src/components/common/ActionButton.tsx +205 -0
  101. package/src/components/common/ActionButtonGroup.tsx +80 -0
  102. package/src/components/common/AutoBeConfigInput.tsx +185 -0
  103. package/src/components/common/CompactSessionIndicator.tsx +73 -0
  104. package/src/components/common/CompactSessionList.tsx +82 -0
  105. package/src/components/common/index.ts +6 -0
  106. package/src/components/events/AutoBeEventGroupMovie.tsx +18 -0
  107. package/src/components/events/AutoBeEventMovie.tsx +5 -0
  108. package/src/components/events/AutoBeValidateEventMovie.tsx +7 -9
  109. package/src/components/events/common/CollapsibleEventGroup.tsx +1 -1
  110. package/src/components/events/groups/ValidateEventGroup.tsx +1 -1
  111. package/src/components/events/utils/eventGrouper.tsx +2 -1
  112. package/src/components/index.ts +6 -0
  113. package/src/components/upload/AutoBeChatUploadBox.tsx +94 -44
  114. package/src/context/AutoBeAgentContext.tsx +201 -22
  115. package/src/context/AutoBeAgentSessionList.tsx +58 -0
  116. package/src/context/SearchParamsContext.tsx +49 -0
  117. package/src/index.ts +4 -0
  118. package/src/structure/AutoBeListener.ts +32 -6
  119. package/src/structure/IAutoBeAgentSessionStorageStrategy.ts +87 -0
  120. package/src/structure/index.ts +1 -0
  121. package/src/types/config.ts +44 -0
  122. package/src/types/index.ts +1 -0
  123. package/src/utils/__tests__/crypto.test.ts +286 -0
  124. package/src/utils/__tests__/storage.test.ts +229 -0
  125. package/src/utils/crypto.ts +95 -0
  126. package/src/utils/index.ts +2 -0
  127. package/src/utils/storage.ts +96 -0
  128. package/vitest.config.ts +15 -0
@@ -1,26 +1,39 @@
1
1
  import { AutoBeUserMessageContent } from "@autobe/interface";
2
- import { RefObject, useEffect, useRef, useState } from "react";
2
+ import { OverlayProvider, overlay } from "overlay-kit";
3
+ import { RefObject, useEffect, useRef } from "react";
3
4
 
4
- import { AutoBeChatUploadBox, AutoBeEventMovie, IAutoBeUploadConfig } from "..";
5
+ import { AutoBeChatUploadBox, useAutoBeAgentSessionList } from "..";
5
6
  import { useAutoBeAgent } from "../context/AutoBeAgentContext";
6
7
  import { useMediaQuery } from "../hooks";
7
- import AutoBeStatusModal from "./AutoBeStatusModal";
8
+ import {
9
+ DEFAULT_CONFIG,
10
+ IAutoBeConfig,
11
+ IAutoBePartialConfig,
12
+ } from "../types/config";
13
+ import { getEncryptedSessionStorage } from "../utils/storage";
14
+ import AutoBeConfigButton from "./AutoBeConfigButton";
15
+ import AutoBeConfigModal, { IConfigField } from "./AutoBeConfigModal";
16
+ import AutoBeStatusButton from "./AutoBeStatusButton";
17
+ import AutoBeEventGroupMovie from "./events/AutoBeEventGroupMovie";
8
18
 
9
19
  export interface IAutoBeChatMainProps {
20
+ isUnusedConfig?: boolean;
21
+ isReplay?: boolean;
10
22
  isMobile: boolean;
11
- conversate: (messages: AutoBeUserMessageContent[]) => Promise<void>;
12
23
  setError: (error: Error) => void;
13
- uploadConfig?: IAutoBeUploadConfig;
14
24
  className?: string;
15
25
  style?: React.CSSProperties;
26
+ configFields?: IConfigField[];
27
+
28
+ /** Additional required config fields beyond openApiKey */
29
+ requiredFields?: string[];
16
30
  }
17
31
 
18
32
  export const AutoBeChatMain = (props: IAutoBeChatMainProps) => {
19
33
  const bodyContainerRef = useRef<HTMLDivElement>(null);
20
34
  const scrollAnchorRef = useRef<HTMLDivElement>(null);
21
- const { eventGroups } = useAutoBeAgent();
22
- const [isTokenModalOpen, setIsTokenModalOpen] = useState(false);
23
-
35
+ const { eventGroups, getAutoBeService, connectionStatus } = useAutoBeAgent();
36
+ const { refreshSessionList } = useAutoBeAgentSessionList();
24
37
  const listener: RefObject<AutoBeChatUploadBox.IListener> = useRef({
25
38
  handleDragEnter: () => {},
26
39
  handleDragLeave: () => {},
@@ -28,151 +41,336 @@ export const AutoBeChatMain = (props: IAutoBeChatMainProps) => {
28
41
  handleDragOver: () => {},
29
42
  });
30
43
 
31
- useEffect(() => {
32
- if (eventGroups.length === 0) return;
33
- scrollAnchorRef.current?.scrollIntoView({
34
- behavior: "smooth",
44
+ // Simplified config reader
45
+ const getCurrentConfig = (): IAutoBeConfig => {
46
+ const config: IAutoBePartialConfig = {};
47
+
48
+ props.configFields?.forEach((field) => {
49
+ const value = field.encrypted
50
+ ? getEncryptedSessionStorage(field.storageKey)
51
+ : localStorage.getItem(field.storageKey) || "";
52
+
53
+ if (field.type === "checkbox") {
54
+ config[field.key] = String(value) === "true";
55
+ } else if (field.type === "number") {
56
+ config[field.key] = parseInt(String(value)) || 0;
57
+ } else {
58
+ config[field.key] = String(value);
59
+ }
35
60
  });
36
- }, [bodyContainerRef.current?.scrollHeight]);
61
+
62
+ return { ...DEFAULT_CONFIG, ...config };
63
+ };
64
+
65
+ // Check if required config is available
66
+ const hasRequiredConfig = (): boolean => {
67
+ const config = getCurrentConfig();
68
+
69
+ // Check additional required fields from props
70
+ if (props.requiredFields) {
71
+ for (const field of props.requiredFields) {
72
+ if (!config[field]) {
73
+ return false;
74
+ }
75
+ }
76
+ }
77
+
78
+ return true;
79
+ };
80
+
81
+ // Unified service connection handler
82
+ const conversate = async (
83
+ messages: AutoBeUserMessageContent[],
84
+ ): Promise<void> => {
85
+ // Check if we have required config
86
+ if (props.isUnusedConfig === false && !hasRequiredConfig()) {
87
+ overlay.open(({ isOpen, close }) => (
88
+ <AutoBeConfigModal
89
+ isOpen={isOpen}
90
+ onClose={close}
91
+ title="Server Connection Required"
92
+ fields={props.configFields || []}
93
+ onSave={() => {
94
+ conversate(messages);
95
+ }}
96
+ />
97
+ ));
98
+ }
99
+
100
+ // Connect to service
101
+ try {
102
+ const config = getCurrentConfig();
103
+ const serviceData = await getAutoBeService(config);
104
+ if (messages.length !== 0) {
105
+ await new Promise((resolve) => {
106
+ if (serviceData.listener.getEnable() === true) {
107
+ resolve(void 0);
108
+ }
109
+ serviceData.listener.onEnable(async (value) => {
110
+ if (value === true) {
111
+ resolve(void 0);
112
+ }
113
+ });
114
+ });
115
+ await serviceData.service.conversate(messages);
116
+ }
117
+ if (eventGroups.length === 0) {
118
+ refreshSessionList();
119
+ }
120
+ } catch (error) {
121
+ console.error("Failed to connect:", error);
122
+ props.setError(error as Error);
123
+ }
124
+ };
125
+
126
+ // Auto-scroll when new events arrive
127
+ useEffect(() => {
128
+ if (eventGroups.length > 0) {
129
+ scrollAnchorRef.current?.scrollIntoView({ behavior: "smooth" });
130
+ }
131
+ }, [eventGroups.length]);
132
+
133
+ // Auto-connect if there are existing conversations and config is ready
134
+ useEffect(() => {
135
+ if (props.isReplay === true) {
136
+ conversate([]);
137
+ return;
138
+ }
139
+
140
+ if (
141
+ eventGroups.length > 0 &&
142
+ hasRequiredConfig() &&
143
+ connectionStatus === "disconnected"
144
+ ) {
145
+ conversate([]);
146
+ return;
147
+ }
148
+ }, [connectionStatus, eventGroups.length]);
37
149
 
38
150
  return (
39
- <div
40
- onDragEnter={(e) => listener.current.handleDragEnter(e)}
41
- onDragLeave={(e) => listener.current.handleDragLeave(e)}
42
- onDragOver={(e) => listener.current.handleDragOver(e)}
43
- onDrop={(e) => listener.current.handleDrop(e)}
44
- style={{
45
- position: "relative",
46
- overflowY: "auto",
47
- margin: 0,
48
- flexGrow: 1,
49
- display: "flex",
50
- flexDirection: "column",
51
- ...props.style,
52
- }}
53
- className={props.className}
54
- ref={bodyContainerRef}
55
- >
56
- {/* Token Usage Button - Sticky position in top right */}
151
+ <OverlayProvider>
57
152
  <div
153
+ onDragEnter={(e) => listener.current.handleDragEnter(e)}
154
+ onDragLeave={(e) => listener.current.handleDragLeave(e)}
155
+ onDragOver={(e) => listener.current.handleDragOver(e)}
156
+ onDrop={(e) => listener.current.handleDrop(e)}
58
157
  style={{
59
- position: "sticky",
60
- top: "1rem",
61
- zIndex: 1001,
158
+ position: "relative",
159
+ overflowY: "auto",
160
+ margin: 0,
161
+ flexGrow: 1,
62
162
  display: "flex",
63
- justifyContent: "flex-end",
64
- marginBottom: "-3rem",
65
- paddingRight: "1.5rem",
163
+ flexDirection: "column",
164
+ ...props.style,
66
165
  }}
166
+ className={props.className}
167
+ ref={bodyContainerRef}
67
168
  >
68
- <button
69
- onClick={() => setIsTokenModalOpen(!isTokenModalOpen)}
169
+ {/* Control Buttons & Status - Sticky position in top right */}
170
+ <div
70
171
  style={{
71
- background: "#f8f9fa",
72
- color: "#495057",
73
- border: "1px solid #dee2e6",
74
- borderRadius: "50%",
75
- padding: "0.5rem",
76
- width: "2rem",
77
- height: "2rem",
78
- cursor: "pointer",
79
- fontSize: "0.85rem",
80
- fontWeight: "400",
81
- boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)",
82
- transition: "all 0.2s ease",
172
+ position: "sticky",
173
+ top: "1rem",
174
+ zIndex: 1001,
83
175
  display: "flex",
176
+ justifyContent: "flex-end",
84
177
  alignItems: "center",
85
- justifyContent: "center",
178
+ gap: "0.5rem",
179
+ marginBottom: "-3rem",
180
+ paddingRight: "1.5rem",
86
181
  }}
87
- onMouseOver={(e) => {
88
- e.currentTarget.style.transform = "translateY(-1px)";
89
- e.currentTarget.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.15)";
90
- e.currentTarget.style.background = "#e9ecef";
91
- e.currentTarget.style.borderColor = "#adb5bd";
92
- }}
93
- onMouseOut={(e) => {
94
- e.currentTarget.style.transform = "translateY(0)";
95
- e.currentTarget.style.boxShadow = "0 2px 4px rgba(0, 0, 0, 0.1)";
96
- e.currentTarget.style.background = "#f8f9fa";
97
- e.currentTarget.style.borderColor = "#dee2e6";
98
- }}
99
- title="View System Status"
100
182
  >
101
- <svg
102
- width="14"
103
- height="14"
104
- viewBox="0 0 24 24"
105
- fill="none"
106
- stroke="currentColor"
107
- strokeWidth="2"
108
- strokeLinecap="round"
109
- strokeLinejoin="round"
110
- >
111
- <circle cx="12" cy="12" r="10" />
112
- <path d="M12 16v-4" />
113
- <path d="M12 8h.01" />
114
- </svg>
115
- </button>
116
- </div>
117
- <div
118
- style={{
119
- display: "flex",
120
- flexDirection: "column",
121
- maxWidth: useMediaQuery.WIDTH_MD,
122
- width: "100%",
123
- margin: "0 auto",
124
- }}
125
- >
183
+ {/* Connection Status Indicator */}
184
+ {connectionStatus === "disconnected" && (
185
+ <div
186
+ style={{
187
+ background: "#f8d7da",
188
+ color: "#721c24",
189
+ border: "1px solid #f5c6cb",
190
+ borderRadius: "50px",
191
+ padding: "0.4rem 0.8rem",
192
+ fontSize: "0.8rem",
193
+ fontWeight: "500",
194
+ display: "flex",
195
+ alignItems: "center",
196
+ gap: "0.4rem",
197
+ boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)",
198
+ }}
199
+ >
200
+ <div
201
+ style={{
202
+ width: "6px",
203
+ height: "6px",
204
+ backgroundColor: "#dc3545",
205
+ borderRadius: "50%",
206
+ animation: "pulse 2s infinite",
207
+ }}
208
+ ></div>
209
+ Disconnected
210
+ </div>
211
+ )}
212
+
213
+ {connectionStatus === "connecting" && (
214
+ <div
215
+ style={{
216
+ background: "#fff3cd",
217
+ color: "#856404",
218
+ border: "1px solid #ffeaa7",
219
+ borderRadius: "50px",
220
+ padding: "0.4rem 0.8rem",
221
+ fontSize: "0.8rem",
222
+ fontWeight: "500",
223
+ display: "flex",
224
+ alignItems: "center",
225
+ gap: "0.4rem",
226
+ boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)",
227
+ }}
228
+ >
229
+ <div
230
+ style={{
231
+ width: "6px",
232
+ height: "6px",
233
+ backgroundColor: "#f39c12",
234
+ borderRadius: "50%",
235
+ animation: "pulse 1.5s infinite",
236
+ }}
237
+ ></div>
238
+ Connecting...
239
+ </div>
240
+ )}
241
+
242
+ {connectionStatus === "connected" && (
243
+ <div
244
+ style={{
245
+ background: "#d4edda",
246
+ color: "#155724",
247
+ border: "1px solid #c3e6cb",
248
+ borderRadius: "50px",
249
+ padding: "0.4rem 0.8rem",
250
+ fontSize: "0.8rem",
251
+ fontWeight: "500",
252
+ display: "flex",
253
+ alignItems: "center",
254
+ gap: "0.4rem",
255
+ boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)",
256
+ }}
257
+ >
258
+ <div
259
+ style={{
260
+ width: "6px",
261
+ height: "6px",
262
+ backgroundColor: "#28a745",
263
+ borderRadius: "50%",
264
+ animation: "pulse 1.5s infinite",
265
+ }}
266
+ ></div>
267
+ Connected
268
+ </div>
269
+ )}
270
+
271
+ <style>
272
+ {`
273
+ @keyframes pulse {
274
+ 0%, 100% { opacity: 1; }
275
+ 50% { opacity: 0.5; }
276
+ }
277
+ `}
278
+ </style>
279
+
280
+ {props.isUnusedConfig === false &&
281
+ props.configFields?.length != null &&
282
+ props.configFields.length > 0 && (
283
+ <AutoBeConfigButton fields={props.configFields || []} />
284
+ )}
285
+ <AutoBeStatusButton />
286
+ </div>
126
287
  <div
127
288
  style={{
128
- padding: "2rem",
129
- gap: 16,
130
289
  display: "flex",
131
290
  flexDirection: "column",
291
+ maxWidth: useMediaQuery.WIDTH_MD,
292
+ width: "100%",
293
+ margin: "0 auto",
132
294
  }}
133
295
  >
134
- {eventGroups.map((e, index) => (
135
- <AutoBeEventMovie
136
- key={index}
137
- events={e.events}
138
- last={index === eventGroups.length - 1}
139
- />
140
- ))}
296
+ <div
297
+ style={{
298
+ padding: "2rem",
299
+ gap: 16,
300
+ display: "flex",
301
+ flexDirection: "column",
302
+ }}
303
+ >
304
+ {connectionStatus === "disconnected" && (
305
+ <div
306
+ style={{
307
+ display: "flex",
308
+ flexDirection: "column",
309
+ justifyContent: "center",
310
+ alignItems: "center",
311
+ padding: "3rem",
312
+ color: "#666",
313
+ textAlign: "center",
314
+ gap: "1rem",
315
+ }}
316
+ >
317
+ <div style={{ fontSize: "3rem" }}>⚙️</div>
318
+ <div style={{ fontSize: "1.25rem", fontWeight: "600" }}>
319
+ Configuration Required
320
+ </div>
321
+ <div
322
+ style={{
323
+ fontSize: "1rem",
324
+ maxWidth: "400px",
325
+ lineHeight: "1.5",
326
+ }}
327
+ >
328
+ Please click the settings button ⚙️ to configure your server
329
+ connection and API credentials, or start typing to begin
330
+ setup.
331
+ </div>
332
+ </div>
333
+ )}
334
+
335
+ {connectionStatus === "connected" && (
336
+ <AutoBeEventGroupMovie eventGroups={eventGroups} />
337
+ )}
338
+ </div>
141
339
  </div>
142
- </div>
143
340
 
144
- {/*
145
- * Prompt input area
146
- * this flexGrow: 1 means that the prompt input area will take up the remaining space
147
- * so that the upload box will be at the bottom of the screen
148
- */}
149
- <div
150
- style={{ flexGrow: 1, minHeight: "1rem" }}
151
- ref={scrollAnchorRef}
152
- ></div>
153
- <div
154
- style={{
155
- position: "sticky",
156
- bottom: 16,
157
- left: 0,
158
- right: 0,
159
- zIndex: 1000,
160
- }}
161
- >
162
- <AutoBeChatUploadBox
163
- listener={listener}
164
- uploadConfig={props.uploadConfig}
165
- conversate={props.conversate}
166
- setError={props.setError}
167
- />
341
+ {/*
342
+ * Prompt input area
343
+ * this flexGrow: 1 means that the prompt input area will take up the remaining space
344
+ * so that the upload box will be at the bottom of the screen
345
+ */}
346
+ <div
347
+ style={{ flexGrow: 1, minHeight: "1rem" }}
348
+ ref={scrollAnchorRef}
349
+ ></div>
350
+ <div
351
+ style={{
352
+ position: "sticky",
353
+ bottom: 16,
354
+ left: 0,
355
+ right: 0,
356
+ zIndex: 1000,
357
+ }}
358
+ >
359
+ <AutoBeChatUploadBox
360
+ listener={listener}
361
+ uploadConfig={
362
+ getCurrentConfig().supportAudioEnable
363
+ ? {
364
+ supportAudio: true,
365
+ }
366
+ : undefined
367
+ }
368
+ conversate={conversate}
369
+ setError={props.setError}
370
+ />
371
+ </div>
168
372
  </div>
169
-
170
- {/* System Status Modal */}
171
- <AutoBeStatusModal
172
- isOpen={isTokenModalOpen}
173
- onClose={() => setIsTokenModalOpen(false)}
174
- />
175
- </div>
373
+ </OverlayProvider>
176
374
  );
177
375
  };
178
376
  export default AutoBeChatMain;