@autobe/ui 0.22.1 → 0.23.0
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/lib/components/AutoBeChatMain.d.ts +6 -4
- package/lib/components/AutoBeChatMain.js +204 -56
- package/lib/components/AutoBeChatMain.js.map +1 -1
- package/lib/components/AutoBeChatSidebar.d.ts +36 -0
- package/lib/components/AutoBeChatSidebar.js +227 -0
- package/lib/components/AutoBeChatSidebar.js.map +1 -0
- package/lib/components/AutoBeConfigButton.d.ts +15 -0
- package/lib/components/AutoBeConfigButton.js +33 -0
- package/lib/components/AutoBeConfigButton.js.map +1 -0
- package/lib/components/AutoBeConfigModal.d.ts +59 -0
- package/lib/components/AutoBeConfigModal.js +294 -0
- package/lib/components/AutoBeConfigModal.js.map +1 -0
- package/lib/components/AutoBeStatusButton.d.ts +12 -0
- package/lib/components/AutoBeStatusButton.js +29 -0
- package/lib/components/AutoBeStatusButton.js.map +1 -0
- package/lib/components/AutoBeStatusModal.js +35 -15
- package/lib/components/AutoBeStatusModal.js.map +1 -1
- package/lib/components/common/ActionButton.d.ts +16 -0
- package/lib/components/common/ActionButton.js +115 -0
- package/lib/components/common/ActionButton.js.map +1 -0
- package/lib/components/common/ActionButtonGroup.d.ts +13 -0
- package/lib/components/common/ActionButtonGroup.js +37 -0
- package/lib/components/common/ActionButtonGroup.js.map +1 -0
- package/lib/components/common/AutoBeConfigInput.d.ts +24 -0
- package/lib/components/common/AutoBeConfigInput.js +90 -0
- package/lib/components/common/AutoBeConfigInput.js.map +1 -0
- package/lib/components/common/CompactSessionIndicator.d.ts +16 -0
- package/lib/components/common/CompactSessionIndicator.js +46 -0
- package/lib/components/common/CompactSessionIndicator.js.map +1 -0
- package/lib/components/common/CompactSessionList.d.ts +22 -0
- package/lib/components/common/CompactSessionList.js +40 -0
- package/lib/components/common/CompactSessionList.js.map +1 -0
- package/lib/components/common/index.d.ts +6 -0
- package/lib/components/common/index.js +6 -0
- package/lib/components/common/index.js.map +1 -1
- package/lib/components/events/AutoBeEventGroupMovie.d.ts +6 -0
- package/lib/components/events/AutoBeEventGroupMovie.js +11 -0
- package/lib/components/events/AutoBeEventGroupMovie.js.map +1 -0
- package/lib/components/events/AutoBeEventMovie.js +5 -0
- package/lib/components/events/AutoBeEventMovie.js.map +1 -1
- package/lib/components/events/AutoBeValidateEventMovie.js +1 -3
- package/lib/components/events/AutoBeValidateEventMovie.js.map +1 -1
- package/lib/components/events/common/CollapsibleEventGroup.d.ts +1 -1
- package/lib/components/events/groups/ValidateEventGroup.d.ts +1 -1
- package/lib/components/events/utils/eventGrouper.js.map +1 -1
- package/lib/components/index.d.ts +6 -0
- package/lib/components/index.js +7 -0
- package/lib/components/index.js.map +1 -1
- package/lib/components/upload/AutoBeChatUploadBox.js +75 -33
- package/lib/components/upload/AutoBeChatUploadBox.js.map +1 -1
- package/lib/context/AutoBeAgentContext.d.ts +22 -11
- package/lib/context/AutoBeAgentContext.js +127 -11
- package/lib/context/AutoBeAgentContext.js.map +1 -1
- package/lib/context/AutoBeAgentSessionList.d.ts +12 -0
- package/lib/context/AutoBeAgentSessionList.js +37 -0
- package/lib/context/AutoBeAgentSessionList.js.map +1 -0
- package/lib/context/SearchParamsContext.d.ts +10 -0
- package/lib/context/SearchParamsContext.js +29 -0
- package/lib/context/SearchParamsContext.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +4 -0
- package/lib/index.js.map +1 -1
- package/lib/structure/AutoBeListener.d.ts +6 -0
- package/lib/structure/AutoBeListener.js +21 -4
- package/lib/structure/AutoBeListener.js.map +1 -1
- package/lib/structure/IAutoBeAgentSessionStorageStrategy.d.ts +35 -0
- package/lib/structure/IAutoBeAgentSessionStorageStrategy.js +30 -0
- package/lib/structure/IAutoBeAgentSessionStorageStrategy.js.map +1 -0
- package/lib/structure/index.d.ts +1 -0
- package/lib/structure/index.js +1 -0
- package/lib/structure/index.js.map +1 -1
- package/lib/types/config.d.ts +26 -0
- package/lib/types/config.js +14 -0
- package/lib/types/config.js.map +1 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +18 -0
- package/lib/types/index.js.map +1 -0
- package/lib/utils/__tests__/crypto.test.d.ts +1 -0
- package/lib/utils/__tests__/crypto.test.js +222 -0
- package/lib/utils/__tests__/crypto.test.js.map +1 -0
- package/lib/utils/__tests__/storage.test.d.ts +1 -0
- package/lib/utils/__tests__/storage.test.js +174 -0
- package/lib/utils/__tests__/storage.test.js.map +1 -0
- package/lib/utils/crypto.d.ts +18 -0
- package/lib/utils/crypto.js +84 -0
- package/lib/utils/crypto.js.map +1 -0
- package/lib/utils/index.d.ts +2 -0
- package/lib/utils/index.js +2 -0
- package/lib/utils/index.js.map +1 -1
- package/lib/utils/storage.d.ts +29 -0
- package/lib/utils/storage.js +93 -0
- package/lib/utils/storage.js.map +1 -0
- package/package.json +11 -3
- package/src/components/AutoBeChatMain.tsx +329 -131
- package/src/components/AutoBeChatSidebar.tsx +414 -0
- package/src/components/AutoBeConfigButton.tsx +83 -0
- package/src/components/AutoBeConfigModal.tsx +444 -0
- package/src/components/AutoBeStatusButton.tsx +75 -0
- package/src/components/AutoBeStatusModal.tsx +55 -54
- package/src/components/common/ActionButton.tsx +205 -0
- package/src/components/common/ActionButtonGroup.tsx +80 -0
- package/src/components/common/AutoBeConfigInput.tsx +185 -0
- package/src/components/common/CompactSessionIndicator.tsx +73 -0
- package/src/components/common/CompactSessionList.tsx +82 -0
- package/src/components/common/index.ts +6 -0
- package/src/components/events/AutoBeEventGroupMovie.tsx +18 -0
- package/src/components/events/AutoBeEventMovie.tsx +5 -0
- package/src/components/events/AutoBeValidateEventMovie.tsx +7 -9
- package/src/components/events/common/CollapsibleEventGroup.tsx +1 -1
- package/src/components/events/groups/ValidateEventGroup.tsx +1 -1
- package/src/components/events/utils/eventGrouper.tsx +2 -1
- package/src/components/index.ts +6 -0
- package/src/components/upload/AutoBeChatUploadBox.tsx +94 -44
- package/src/context/AutoBeAgentContext.tsx +201 -22
- package/src/context/AutoBeAgentSessionList.tsx +58 -0
- package/src/context/SearchParamsContext.tsx +49 -0
- package/src/index.ts +4 -0
- package/src/structure/AutoBeListener.ts +32 -6
- package/src/structure/IAutoBeAgentSessionStorageStrategy.ts +87 -0
- package/src/structure/index.ts +1 -0
- package/src/types/config.ts +44 -0
- package/src/types/index.ts +1 -0
- package/src/utils/__tests__/crypto.test.ts +286 -0
- package/src/utils/__tests__/storage.test.ts +229 -0
- package/src/utils/crypto.ts +95 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/storage.ts +96 -0
- package/vitest.config.ts +15 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { CSSProperties, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
getEncryptedSessionStorage,
|
|
5
|
+
setEncryptedSessionStorage,
|
|
6
|
+
} from "../utils/storage";
|
|
7
|
+
import AutoBeConfigInput from "./common/AutoBeConfigInput";
|
|
8
|
+
|
|
9
|
+
/** Generic config field definition */
|
|
10
|
+
export interface IConfigField {
|
|
11
|
+
key: string;
|
|
12
|
+
label: string;
|
|
13
|
+
type: "text" | "number" | "checkbox" | "list";
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
default?: string | number | boolean;
|
|
16
|
+
suggestions?: string[];
|
|
17
|
+
required?: boolean;
|
|
18
|
+
min?: number;
|
|
19
|
+
max?: number;
|
|
20
|
+
storageKey: string;
|
|
21
|
+
encrypted?: boolean; // Use sessionStorage with encryption
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface IAutoBeConfigModalProps {
|
|
25
|
+
isOpen: boolean;
|
|
26
|
+
onClose: () => void;
|
|
27
|
+
title?: string;
|
|
28
|
+
fields: IConfigField[];
|
|
29
|
+
onSave?: (config: Record<string, unknown>) => void;
|
|
30
|
+
onReset?: () => void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Generic configuration modal component Receives config field definitions from
|
|
35
|
+
* props for maximum flexibility
|
|
36
|
+
*/
|
|
37
|
+
export const AutoBeConfigModal = (props: IAutoBeConfigModalProps) => {
|
|
38
|
+
// Get stored values for all fields
|
|
39
|
+
const getStoredValue = (field: IConfigField) => {
|
|
40
|
+
if (typeof window === "undefined") {
|
|
41
|
+
if (field.type === "checkbox") return false;
|
|
42
|
+
if (field.type === "number") return 0;
|
|
43
|
+
return "";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const stored = field.encrypted
|
|
47
|
+
? getEncryptedSessionStorage(field.storageKey)
|
|
48
|
+
: localStorage.getItem(field.storageKey);
|
|
49
|
+
|
|
50
|
+
if (stored !== null && stored !== "") {
|
|
51
|
+
if (field.type === "checkbox") {
|
|
52
|
+
return stored === "true";
|
|
53
|
+
}
|
|
54
|
+
if (field.type === "number") {
|
|
55
|
+
return parseInt(stored, 10) || 0;
|
|
56
|
+
}
|
|
57
|
+
return stored;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Return default values based on type
|
|
61
|
+
if (field.type === "checkbox") return false;
|
|
62
|
+
if (field.type === "number") return 0;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Initialize config state from stored values
|
|
66
|
+
const [config, setConfig] = useState<Record<string, unknown>>(() => {
|
|
67
|
+
const initialConfig: Record<string, unknown> = {};
|
|
68
|
+
props.fields.forEach((field) => {
|
|
69
|
+
initialConfig[field.key] =
|
|
70
|
+
getStoredValue(field) ?? field.default ?? undefined;
|
|
71
|
+
});
|
|
72
|
+
return initialConfig;
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const updateConfig = (key: string, value: unknown) => {
|
|
76
|
+
setConfig((prev) => ({ ...prev, [key]: value }));
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const handleSave = () => {
|
|
80
|
+
// Save all config values to their respective storage
|
|
81
|
+
props.fields.forEach((field) => {
|
|
82
|
+
const value = config[field.key];
|
|
83
|
+
const stringValue = String(value);
|
|
84
|
+
|
|
85
|
+
if (field.encrypted) {
|
|
86
|
+
setEncryptedSessionStorage(field.storageKey, stringValue);
|
|
87
|
+
} else {
|
|
88
|
+
localStorage.setItem(field.storageKey, stringValue);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
console.log(config);
|
|
93
|
+
// Call optional external save handler
|
|
94
|
+
props.onSave?.(config);
|
|
95
|
+
props.onClose();
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
if (!props.isOpen) return null;
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
style={{
|
|
103
|
+
position: "fixed",
|
|
104
|
+
top: 0,
|
|
105
|
+
left: 0,
|
|
106
|
+
right: 0,
|
|
107
|
+
bottom: 0,
|
|
108
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
109
|
+
display: "flex",
|
|
110
|
+
alignItems: "center",
|
|
111
|
+
justifyContent: "center",
|
|
112
|
+
zIndex: 1002,
|
|
113
|
+
}}
|
|
114
|
+
onClick={props.onClose}
|
|
115
|
+
>
|
|
116
|
+
<div
|
|
117
|
+
style={{
|
|
118
|
+
backgroundColor: "white",
|
|
119
|
+
borderRadius: "1rem",
|
|
120
|
+
padding: "1.25rem",
|
|
121
|
+
width: "90%",
|
|
122
|
+
maxWidth: "500px",
|
|
123
|
+
maxHeight: "90vh",
|
|
124
|
+
overflow: "visible",
|
|
125
|
+
boxShadow:
|
|
126
|
+
"0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
|
|
127
|
+
}}
|
|
128
|
+
onClick={(e) => e.stopPropagation()}
|
|
129
|
+
>
|
|
130
|
+
{/* Header with title and X button */}
|
|
131
|
+
<div style={{ position: "relative", marginBottom: "1.25rem" }}>
|
|
132
|
+
<h2
|
|
133
|
+
style={{
|
|
134
|
+
margin: "0",
|
|
135
|
+
fontSize: "1.125rem",
|
|
136
|
+
fontWeight: "600",
|
|
137
|
+
color: "#1a1a1a",
|
|
138
|
+
textAlign: "center",
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
141
|
+
{props.title || "Configuration"}
|
|
142
|
+
</h2>
|
|
143
|
+
|
|
144
|
+
{/* X Close Button */}
|
|
145
|
+
<button
|
|
146
|
+
onClick={props.onClose}
|
|
147
|
+
style={{
|
|
148
|
+
position: "absolute",
|
|
149
|
+
top: "50%",
|
|
150
|
+
right: "0",
|
|
151
|
+
transform: "translateY(-50%)",
|
|
152
|
+
background: "none",
|
|
153
|
+
border: "none",
|
|
154
|
+
cursor: "pointer",
|
|
155
|
+
padding: "0.25rem",
|
|
156
|
+
borderRadius: "50%",
|
|
157
|
+
width: "1.75rem",
|
|
158
|
+
height: "1.75rem",
|
|
159
|
+
display: "flex",
|
|
160
|
+
alignItems: "center",
|
|
161
|
+
justifyContent: "center",
|
|
162
|
+
fontSize: "1rem",
|
|
163
|
+
color: "#6b7280",
|
|
164
|
+
transition: "all 0.2s",
|
|
165
|
+
}}
|
|
166
|
+
className="modal-close-button"
|
|
167
|
+
>
|
|
168
|
+
✖️
|
|
169
|
+
</button>
|
|
170
|
+
|
|
171
|
+
<style>
|
|
172
|
+
{`
|
|
173
|
+
.modal-close-button:hover {
|
|
174
|
+
background-color: #f3f4f6 !important;
|
|
175
|
+
color: #374151 !important;
|
|
176
|
+
}
|
|
177
|
+
`}
|
|
178
|
+
</style>
|
|
179
|
+
</div>
|
|
180
|
+
|
|
181
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
|
182
|
+
{props.fields.map((field) => (
|
|
183
|
+
<div key={field.key}>
|
|
184
|
+
{field.type === "checkbox" ? (
|
|
185
|
+
<div style={{ marginBottom: "0.25rem" }}>
|
|
186
|
+
<label
|
|
187
|
+
style={{
|
|
188
|
+
display: "flex",
|
|
189
|
+
alignItems: "center",
|
|
190
|
+
gap: "0.5rem",
|
|
191
|
+
fontSize: "1rem",
|
|
192
|
+
fontWeight: "500",
|
|
193
|
+
color: "#374151",
|
|
194
|
+
marginBottom: "0.5rem",
|
|
195
|
+
}}
|
|
196
|
+
>
|
|
197
|
+
{field.label}
|
|
198
|
+
</label>
|
|
199
|
+
<div
|
|
200
|
+
style={{
|
|
201
|
+
display: "flex",
|
|
202
|
+
alignItems: "center",
|
|
203
|
+
gap: "0.5rem",
|
|
204
|
+
padding: "0.75rem 1rem",
|
|
205
|
+
border: "2px solid #e5e7eb",
|
|
206
|
+
borderRadius: "0.5rem",
|
|
207
|
+
backgroundColor: "#f9fafb",
|
|
208
|
+
transition: "all 0.2s",
|
|
209
|
+
}}
|
|
210
|
+
>
|
|
211
|
+
<input
|
|
212
|
+
type="checkbox"
|
|
213
|
+
checked={Boolean(config[field.key])}
|
|
214
|
+
onChange={(e) =>
|
|
215
|
+
updateConfig(field.key, e.target.checked)
|
|
216
|
+
}
|
|
217
|
+
style={{
|
|
218
|
+
width: "1rem",
|
|
219
|
+
height: "1rem",
|
|
220
|
+
cursor: "pointer",
|
|
221
|
+
}}
|
|
222
|
+
/>
|
|
223
|
+
<span style={{ fontSize: "0.875rem", color: "#6b7280" }}>
|
|
224
|
+
{field.placeholder ||
|
|
225
|
+
`Enable ${field.label.toLowerCase()}`}
|
|
226
|
+
</span>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
) : (
|
|
230
|
+
<AutoBeConfigInput
|
|
231
|
+
label={field.label}
|
|
232
|
+
type={field.type}
|
|
233
|
+
value={String(config[field.key] || field.default || "")}
|
|
234
|
+
onChange={(value) => {
|
|
235
|
+
const finalValue =
|
|
236
|
+
field.type === "number" ? parseInt(value) || 0 : value;
|
|
237
|
+
updateConfig(field.key, finalValue);
|
|
238
|
+
}}
|
|
239
|
+
placeholder={field.placeholder}
|
|
240
|
+
suggestions={field.suggestions?.map((value) => ({ value }))}
|
|
241
|
+
min={field.min}
|
|
242
|
+
max={field.max}
|
|
243
|
+
required={field.required}
|
|
244
|
+
/>
|
|
245
|
+
)}
|
|
246
|
+
</div>
|
|
247
|
+
))}
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
<div
|
|
251
|
+
style={{
|
|
252
|
+
display: "flex",
|
|
253
|
+
gap: "1rem",
|
|
254
|
+
marginTop: "1.25rem",
|
|
255
|
+
justifyContent: "flex-end",
|
|
256
|
+
}}
|
|
257
|
+
>
|
|
258
|
+
<ConfigButton variant="secondary" onClick={props.onClose}>
|
|
259
|
+
Cancel
|
|
260
|
+
</ConfigButton>
|
|
261
|
+
|
|
262
|
+
<ConfigButton variant="primary" onClick={handleSave}>
|
|
263
|
+
Save
|
|
264
|
+
</ConfigButton>
|
|
265
|
+
</div>
|
|
266
|
+
</div>
|
|
267
|
+
</div>
|
|
268
|
+
);
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/** Reusable button component for config modal */
|
|
272
|
+
interface IConfigButtonProps {
|
|
273
|
+
variant: "primary" | "secondary";
|
|
274
|
+
onClick: () => void;
|
|
275
|
+
children: React.ReactNode;
|
|
276
|
+
disabled?: boolean;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const ConfigButton = ({
|
|
280
|
+
variant,
|
|
281
|
+
onClick,
|
|
282
|
+
children,
|
|
283
|
+
disabled,
|
|
284
|
+
}: IConfigButtonProps) => {
|
|
285
|
+
const baseStyles: CSSProperties = {
|
|
286
|
+
padding: "0.5rem 1.25rem",
|
|
287
|
+
fontSize: "0.875rem",
|
|
288
|
+
fontWeight: "500",
|
|
289
|
+
borderRadius: "0.5rem",
|
|
290
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
291
|
+
transition: "all 0.2s",
|
|
292
|
+
border: "none",
|
|
293
|
+
outline: "none",
|
|
294
|
+
opacity: disabled ? 0.5 : 1,
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
const variantStyles: Record<"primary" | "secondary", CSSProperties> = {
|
|
298
|
+
primary: {
|
|
299
|
+
color: "white",
|
|
300
|
+
backgroundColor: "#3b82f6",
|
|
301
|
+
border: "1px solid #3b82f6",
|
|
302
|
+
},
|
|
303
|
+
secondary: {
|
|
304
|
+
color: "#374151",
|
|
305
|
+
backgroundColor: "#f9fafb",
|
|
306
|
+
border: "1px solid #d1d5db",
|
|
307
|
+
},
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
return (
|
|
311
|
+
<>
|
|
312
|
+
<style>
|
|
313
|
+
{`
|
|
314
|
+
.config-button-${variant}:hover:not(:disabled) {
|
|
315
|
+
${
|
|
316
|
+
variant === "primary"
|
|
317
|
+
? "background-color: #2563eb !important; border-color: #2563eb !important;"
|
|
318
|
+
: "background-color: #f3f4f6 !important; border-color: #9ca3af !important;"
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
`}
|
|
322
|
+
</style>
|
|
323
|
+
<button
|
|
324
|
+
className={`config-button-${variant}`}
|
|
325
|
+
style={{
|
|
326
|
+
...baseStyles,
|
|
327
|
+
...variantStyles[variant],
|
|
328
|
+
}}
|
|
329
|
+
onClick={onClick}
|
|
330
|
+
disabled={disabled}
|
|
331
|
+
>
|
|
332
|
+
{children}
|
|
333
|
+
</button>
|
|
334
|
+
</>
|
|
335
|
+
);
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
/** All available AutoBE configuration fields */
|
|
339
|
+
const ALL_CONFIG_FIELDS: Record<string, IConfigField> = {
|
|
340
|
+
locale: {
|
|
341
|
+
key: "locale",
|
|
342
|
+
label: "Language",
|
|
343
|
+
type: "text",
|
|
344
|
+
storageKey: "autobe_locale",
|
|
345
|
+
placeholder: "en",
|
|
346
|
+
suggestions: ["en", "ko", "ja", "zh", "es", "fr", "de"],
|
|
347
|
+
},
|
|
348
|
+
schemaModel: {
|
|
349
|
+
key: "schemaModel",
|
|
350
|
+
label: "Schema Model",
|
|
351
|
+
type: "text",
|
|
352
|
+
storageKey: "autobe_schema_model",
|
|
353
|
+
placeholder: "chatgpt",
|
|
354
|
+
suggestions: ["chatgpt", "claude"],
|
|
355
|
+
},
|
|
356
|
+
aiModel: {
|
|
357
|
+
key: "aiModel",
|
|
358
|
+
label: "AI Model",
|
|
359
|
+
type: "text",
|
|
360
|
+
storageKey: "autobe_ai_model",
|
|
361
|
+
placeholder: "gpt-4.1",
|
|
362
|
+
suggestions: [
|
|
363
|
+
"gpt-4.1",
|
|
364
|
+
"gpt-4",
|
|
365
|
+
"gpt-4-turbo",
|
|
366
|
+
"gpt-3.5-turbo",
|
|
367
|
+
"claude-3-sonnet",
|
|
368
|
+
"claude-3-haiku",
|
|
369
|
+
"claude-3-opus",
|
|
370
|
+
"llama-3.1-70b",
|
|
371
|
+
"deepseek-coder",
|
|
372
|
+
],
|
|
373
|
+
},
|
|
374
|
+
openApiKey: {
|
|
375
|
+
key: "openApiKey",
|
|
376
|
+
label: "OpenAI API Key",
|
|
377
|
+
type: "text",
|
|
378
|
+
storageKey: "autobe_openapi_key_encrypted",
|
|
379
|
+
placeholder: "sk-...",
|
|
380
|
+
encrypted: true,
|
|
381
|
+
required: true,
|
|
382
|
+
},
|
|
383
|
+
baseUrl: {
|
|
384
|
+
key: "baseUrl",
|
|
385
|
+
label: "Base URL",
|
|
386
|
+
type: "text",
|
|
387
|
+
storageKey: "autobe_base_url",
|
|
388
|
+
placeholder: "Leave empty for OpenAI default",
|
|
389
|
+
default: "https://api.openai.com/v1",
|
|
390
|
+
},
|
|
391
|
+
semaphore: {
|
|
392
|
+
key: "semaphore",
|
|
393
|
+
label: "Concurrency Limit",
|
|
394
|
+
type: "number",
|
|
395
|
+
storageKey: "autobe_semaphore",
|
|
396
|
+
placeholder: "16",
|
|
397
|
+
min: 1,
|
|
398
|
+
max: 100,
|
|
399
|
+
},
|
|
400
|
+
supportAudioEnable: {
|
|
401
|
+
key: "supportAudioEnable",
|
|
402
|
+
label: "Audio Support",
|
|
403
|
+
type: "checkbox",
|
|
404
|
+
storageKey: "autobe_support_audio",
|
|
405
|
+
placeholder: "Not STT, just bypass to LLM",
|
|
406
|
+
},
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
/** Available config field keys */
|
|
410
|
+
export type AutoBeConfigKey = keyof typeof ALL_CONFIG_FIELDS;
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Create AutoBE configuration fields with additional keys and optional
|
|
414
|
+
* extensions
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* ```typescript
|
|
418
|
+
* // Get default fields only
|
|
419
|
+
* createAutoBeConfigFields()
|
|
420
|
+
*
|
|
421
|
+
* // Add serverUrl to default fields
|
|
422
|
+
* createAutoBeConfigFields(['serverUrl'])
|
|
423
|
+
*
|
|
424
|
+
* // Add multiple keys to default fields
|
|
425
|
+
* createAutoBeConfigFields(['serverUrl', 'customKey'])
|
|
426
|
+
*
|
|
427
|
+
* // Add keys + custom extensions
|
|
428
|
+
* createAutoBeConfigFields(['serverUrl'], [
|
|
429
|
+
* { key: 'customField', label: 'Custom', type: 'text', storageKey: 'custom' }
|
|
430
|
+
* ])
|
|
431
|
+
* ```;
|
|
432
|
+
*
|
|
433
|
+
* @param additionalKeys - Array of additional config keys to add to default
|
|
434
|
+
* fields
|
|
435
|
+
* @param extensions - Additional custom config fields to append
|
|
436
|
+
* @returns Array of default + additional + extended config fields
|
|
437
|
+
*/
|
|
438
|
+
export const createAutoBeConfigFields = (
|
|
439
|
+
...extensions: IConfigField[]
|
|
440
|
+
): IConfigField[] => {
|
|
441
|
+
return [...Object.values(ALL_CONFIG_FIELDS), ...extensions];
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
export default AutoBeConfigModal;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { overlay } from "overlay-kit";
|
|
2
|
+
import { CSSProperties } from "react";
|
|
3
|
+
|
|
4
|
+
import AutoBeStatusModal from "./AutoBeStatusModal";
|
|
5
|
+
|
|
6
|
+
export interface IAutoBeStatusButtonProps {
|
|
7
|
+
className?: string;
|
|
8
|
+
style?: CSSProperties;
|
|
9
|
+
title?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A floating action button that opens the system status modal Features hover
|
|
14
|
+
* animations and a clean, modern design
|
|
15
|
+
*/
|
|
16
|
+
export const AutoBeStatusButton = (props: IAutoBeStatusButtonProps) => {
|
|
17
|
+
return (
|
|
18
|
+
<button
|
|
19
|
+
onClick={() =>
|
|
20
|
+
overlay.open(({ isOpen, close }) => (
|
|
21
|
+
<AutoBeStatusModal isOpen={isOpen} onClose={close} />
|
|
22
|
+
))
|
|
23
|
+
}
|
|
24
|
+
className={props.className}
|
|
25
|
+
style={{
|
|
26
|
+
background: "#f8f9fa",
|
|
27
|
+
color: "#495057",
|
|
28
|
+
border: "1px solid #dee2e6",
|
|
29
|
+
borderRadius: "50%",
|
|
30
|
+
padding: "0.5rem",
|
|
31
|
+
width: "2rem",
|
|
32
|
+
height: "2rem",
|
|
33
|
+
cursor: "pointer",
|
|
34
|
+
fontSize: "0.85rem",
|
|
35
|
+
fontWeight: "400",
|
|
36
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)",
|
|
37
|
+
transition: "all 0.2s ease",
|
|
38
|
+
display: "flex",
|
|
39
|
+
alignItems: "center",
|
|
40
|
+
justifyContent: "center",
|
|
41
|
+
...props.style,
|
|
42
|
+
}}
|
|
43
|
+
onMouseOver={(e) => {
|
|
44
|
+
e.currentTarget.style.transform = "translateY(-1px)";
|
|
45
|
+
e.currentTarget.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.15)";
|
|
46
|
+
e.currentTarget.style.background = "#e9ecef";
|
|
47
|
+
e.currentTarget.style.borderColor = "#adb5bd";
|
|
48
|
+
}}
|
|
49
|
+
onMouseOut={(e) => {
|
|
50
|
+
e.currentTarget.style.transform = "translateY(0)";
|
|
51
|
+
e.currentTarget.style.boxShadow = "0 2px 4px rgba(0, 0, 0, 0.1)";
|
|
52
|
+
e.currentTarget.style.background = "#f8f9fa";
|
|
53
|
+
e.currentTarget.style.borderColor = "#dee2e6";
|
|
54
|
+
}}
|
|
55
|
+
title={props.title || "View System Status"}
|
|
56
|
+
>
|
|
57
|
+
<svg
|
|
58
|
+
width="14"
|
|
59
|
+
height="14"
|
|
60
|
+
viewBox="0 0 24 24"
|
|
61
|
+
fill="none"
|
|
62
|
+
stroke="currentColor"
|
|
63
|
+
strokeWidth="2"
|
|
64
|
+
strokeLinecap="round"
|
|
65
|
+
strokeLinejoin="round"
|
|
66
|
+
>
|
|
67
|
+
<circle cx="12" cy="12" r="10" />
|
|
68
|
+
<path d="M12 16v-4" />
|
|
69
|
+
<path d="M12 8h.01" />
|
|
70
|
+
</svg>
|
|
71
|
+
</button>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export default AutoBeStatusButton;
|
|
@@ -172,38 +172,38 @@ const SectionTitle = ({ children }: { children: React.ReactNode }) => (
|
|
|
172
172
|
</div>
|
|
173
173
|
);
|
|
174
174
|
|
|
175
|
-
const ConnectionInfo = ({
|
|
176
|
-
|
|
177
|
-
}: {
|
|
178
|
-
|
|
179
|
-
}) => (
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
);
|
|
175
|
+
// const ConnectionInfo = ({
|
|
176
|
+
// header,
|
|
177
|
+
// }: {
|
|
178
|
+
// header: IAutoBePlaygroundHeader<ILlmSchema.Model> | null;
|
|
179
|
+
// }) => (
|
|
180
|
+
// <div>
|
|
181
|
+
// <SectionTitle>Connection Info</SectionTitle>
|
|
182
|
+
// <div
|
|
183
|
+
// style={{
|
|
184
|
+
// background: "linear-gradient(145deg, #ffffff, #f8fafc)",
|
|
185
|
+
// borderRadius: "10px",
|
|
186
|
+
// padding: "1rem",
|
|
187
|
+
// border: "1px solid rgba(148, 163, 184, 0.15)",
|
|
188
|
+
// boxShadow: "0 2px 4px -1px rgba(0, 0, 0, 0.05)",
|
|
189
|
+
// }}
|
|
190
|
+
// >
|
|
191
|
+
// <p
|
|
192
|
+
// style={{
|
|
193
|
+
// margin: 0,
|
|
194
|
+
// fontSize: "0.8rem",
|
|
195
|
+
// color: "#374151",
|
|
196
|
+
// lineHeight: 1.5,
|
|
197
|
+
// }}
|
|
198
|
+
// >
|
|
199
|
+
// <strong>Model:</strong> {header?.model || "N/A"} |{" "}
|
|
200
|
+
// <strong>Vendor:</strong> {header?.vendor.model || "N/A"} |{" "}
|
|
201
|
+
// <strong>Locale:</strong> {header?.locale || "N/A"} |{" "}
|
|
202
|
+
// <strong>Timezone:</strong> {header?.timezone || "N/A"}
|
|
203
|
+
// </p>
|
|
204
|
+
// </div>
|
|
205
|
+
// </div>
|
|
206
|
+
// );
|
|
207
207
|
|
|
208
208
|
const HighlightNumbers = ({
|
|
209
209
|
text,
|
|
@@ -312,27 +312,28 @@ const ProgressCard = ({
|
|
|
312
312
|
</div>
|
|
313
313
|
);
|
|
314
314
|
|
|
315
|
-
const ProgressStatus = ({ state }: { state: AutoBeListenerState }) =>
|
|
316
|
-
|
|
317
|
-
<
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
315
|
+
const ProgressStatus = ({ state }: { state: AutoBeListenerState | null }) =>
|
|
316
|
+
state && (
|
|
317
|
+
<div>
|
|
318
|
+
<SectionTitle>Progress Status</SectionTitle>
|
|
319
|
+
<div
|
|
320
|
+
style={{
|
|
321
|
+
display: "flex",
|
|
322
|
+
flexDirection: "column",
|
|
323
|
+
gap: "0.5rem",
|
|
324
|
+
}}
|
|
325
|
+
>
|
|
326
|
+
{PROGRESS_STEPS.map((step) => (
|
|
327
|
+
<ProgressCard
|
|
328
|
+
key={step.name}
|
|
329
|
+
step={step}
|
|
330
|
+
isCompleted={state[step.name as keyof AutoBeListenerState] !== null}
|
|
331
|
+
results={step.getResults(state)}
|
|
332
|
+
/>
|
|
333
|
+
))}
|
|
334
|
+
</div>
|
|
333
335
|
</div>
|
|
334
|
-
|
|
335
|
-
);
|
|
336
|
+
);
|
|
336
337
|
|
|
337
338
|
const TokenRow = ({
|
|
338
339
|
label,
|
|
@@ -455,7 +456,7 @@ export const AutoBeStatusModal = ({
|
|
|
455
456
|
isOpen,
|
|
456
457
|
onClose,
|
|
457
458
|
}: IAutoBeStatusModalProps) => {
|
|
458
|
-
const { tokenUsage, state
|
|
459
|
+
const { tokenUsage, state } = useAutoBeAgent();
|
|
459
460
|
|
|
460
461
|
useEscapeKey(isOpen, onClose);
|
|
461
462
|
|
|
@@ -470,7 +471,7 @@ export const AutoBeStatusModal = ({
|
|
|
470
471
|
|
|
471
472
|
<div style={MODAL_STYLES.content}>
|
|
472
473
|
<div style={MODAL_STYLES.section}>
|
|
473
|
-
<ConnectionInfo header={header} />
|
|
474
|
+
{/* <ConnectionInfo header={header} /> */}
|
|
474
475
|
<ProgressStatus state={state} />
|
|
475
476
|
<TokenUsage tokenUsage={tokenUsage} />
|
|
476
477
|
</div>
|