@solidxai/core-ui 0.1.7-beta.9 → 0.1.7
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/README.md +215 -0
- package/dist/components/auth/SolidLogin.js +1 -1
- package/dist/components/auth/SolidLogin.js.map +1 -1
- package/dist/components/auth/SolidLogin.tsx +2 -2
- package/dist/components/common/GeneralSettings.js +31 -29
- package/dist/components/common/GeneralSettings.js.map +1 -1
- package/dist/components/common/GeneralSettings.tsx +51 -41
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.d.ts +18 -14
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.d.ts.map +1 -1
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.js +130 -26
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.js.map +1 -1
- package/dist/components/common/SolidSettings/LlmSettings/AiModelConfigTab.tsx +319 -80
- package/dist/components/shad-cn-ui/SolidTabs.d.ts +2 -1
- package/dist/components/shad-cn-ui/SolidTabs.d.ts.map +1 -1
- package/dist/components/shad-cn-ui/SolidTabs.js +5 -5
- package/dist/components/shad-cn-ui/SolidTabs.js.map +1 -1
- package/dist/components/shad-cn-ui/SolidTabs.tsx +6 -0
- package/dist/routes/guards/GuestGuard.d.ts.map +1 -1
- package/dist/routes/guards/GuestGuard.js +2 -7
- package/dist/routes/guards/GuestGuard.js.map +1 -1
- package/dist/routes/guards/GuestGuard.tsx +2 -6
- package/package.json +1 -1
|
@@ -1,20 +1,32 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import {
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
SolidButton,
|
|
4
|
+
SolidDialog,
|
|
5
|
+
SolidDialogBody,
|
|
6
|
+
SolidDialogFooter,
|
|
7
|
+
SolidDialogHeader,
|
|
8
|
+
SolidDialogTitle,
|
|
9
|
+
SolidInput,
|
|
10
|
+
SolidSelect,
|
|
11
|
+
SolidSwitch,
|
|
12
|
+
SolidTextarea,
|
|
13
|
+
} from "../../../shad-cn-ui";
|
|
14
|
+
|
|
3
15
|
|
|
4
16
|
export interface ModelBehavior {
|
|
5
17
|
streaming: boolean;
|
|
6
18
|
custom: string;
|
|
7
19
|
}
|
|
8
20
|
|
|
9
|
-
export interface
|
|
10
|
-
|
|
21
|
+
export interface ProviderEntry {
|
|
22
|
+
type: string;
|
|
11
23
|
apiKey: string;
|
|
12
|
-
model: string;
|
|
13
24
|
baseUrl?: string;
|
|
14
25
|
}
|
|
15
26
|
|
|
16
27
|
export interface ModelEntry {
|
|
17
|
-
|
|
28
|
+
providerId: string;
|
|
29
|
+
model: string;
|
|
18
30
|
behavior: ModelBehavior;
|
|
19
31
|
}
|
|
20
32
|
|
|
@@ -23,125 +35,353 @@ export interface SolidAiConfig {
|
|
|
23
35
|
default: ModelEntry;
|
|
24
36
|
fast: ModelEntry;
|
|
25
37
|
};
|
|
26
|
-
providers: Record<string,
|
|
38
|
+
providers: Record<string, ProviderEntry>;
|
|
27
39
|
}
|
|
28
40
|
|
|
29
|
-
interface Props {
|
|
30
|
-
providerKey: string;
|
|
31
|
-
providerConfig: ProviderConfig;
|
|
32
|
-
behavior: ModelBehavior;
|
|
33
|
-
allProviders: Record<string, ProviderConfig>;
|
|
34
|
-
onProviderKeyChange: (newProviderKey: string, config: ProviderConfig) => void;
|
|
35
|
-
onProviderConfigChange: (providerKey: string, config: ProviderConfig) => void;
|
|
36
|
-
onBehaviorChange: (behavior: ModelBehavior) => void;
|
|
37
|
-
}
|
|
38
41
|
|
|
39
|
-
const
|
|
42
|
+
const PROVIDER_TYPE_OPTIONS = [
|
|
40
43
|
{ label: "OpenAI", value: "openai" },
|
|
41
44
|
{ label: "Anthropic", value: "anthropic" },
|
|
42
45
|
{ label: "OpenAI Compatible", value: "openai-compatible" },
|
|
43
46
|
{ label: "Anthropic Compatible", value: "anthropic-compatible" },
|
|
44
47
|
];
|
|
45
48
|
|
|
46
|
-
const
|
|
49
|
+
const COMPATIBLE_TYPES = ["openai-compatible", "anthropic-compatible"];
|
|
47
50
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
const BUILT_IN_TYPES = ["openai", "anthropic"];
|
|
52
|
+
|
|
53
|
+
const DEFAULT_BUILT_IN_PROVIDERS: Record<string, ProviderEntry> = {
|
|
54
|
+
openai: { type: "openai", apiKey: "" },
|
|
55
|
+
anthropic: { type: "anthropic", apiKey: "" },
|
|
53
56
|
};
|
|
54
57
|
|
|
55
|
-
export const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
export const ensureBuiltInProviders = (providers: Record<string, ProviderEntry>): Record<string, ProviderEntry> => ({
|
|
59
|
+
...DEFAULT_BUILT_IN_PROVIDERS,
|
|
60
|
+
...providers,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const cardStyle: React.CSSProperties = {
|
|
64
|
+
border: "1px solid var(--solid-border-color, #e2e8f0)",
|
|
65
|
+
borderRadius: "0.5rem",
|
|
66
|
+
padding: "1.25rem",
|
|
67
|
+
background: "var(--solid-card-bg, var(--solid-surface-bg, transparent))",
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
interface ProviderModalProps {
|
|
72
|
+
visible: boolean;
|
|
73
|
+
onHide: () => void;
|
|
74
|
+
providers: Record<string, ProviderEntry>;
|
|
75
|
+
onProvidersChange: (providers: Record<string, ProviderEntry>) => void;
|
|
76
|
+
editKey?: string | null; // null = add mode, string = edit mode
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const ProviderModal = ({ visible, onHide, providers, onProvidersChange, editKey }: ProviderModalProps) => {
|
|
80
|
+
const isEdit = !!editKey;
|
|
81
|
+
const existingEntry = isEdit ? providers[editKey] : null;
|
|
82
|
+
|
|
83
|
+
const [providerType, setProviderType] = useState(existingEntry?.type ?? "");
|
|
84
|
+
const [providerName, setProviderName] = useState(editKey && !BUILT_IN_TYPES.includes(editKey) ? editKey : "");
|
|
85
|
+
const [providerBaseUrl, setProviderBaseUrl] = useState(existingEntry?.baseUrl ?? "");
|
|
86
|
+
const [providerApiKey, setProviderApiKey] = useState(existingEntry?.apiKey ?? "");
|
|
87
|
+
|
|
88
|
+
const isCompatible = COMPATIBLE_TYPES.includes(providerType);
|
|
89
|
+
|
|
90
|
+
// Reset state when modal opens with new data
|
|
91
|
+
React.useEffect(() => {
|
|
92
|
+
if (visible) {
|
|
93
|
+
const entry = editKey ? providers[editKey] : null;
|
|
94
|
+
setProviderType(entry?.type ?? "");
|
|
95
|
+
setProviderName(editKey && !BUILT_IN_TYPES.includes(editKey) ? editKey : "");
|
|
96
|
+
setProviderBaseUrl(entry?.baseUrl ?? "");
|
|
97
|
+
setProviderApiKey(entry?.apiKey ?? "");
|
|
98
|
+
}
|
|
99
|
+
}, [visible, editKey]);
|
|
100
|
+
|
|
101
|
+
// In add mode, only show compatible types (built-ins are always pre-added)
|
|
102
|
+
// In edit mode, show all types but lock the value
|
|
103
|
+
const typeOptions = isEdit
|
|
104
|
+
? PROVIDER_TYPE_OPTIONS
|
|
105
|
+
: PROVIDER_TYPE_OPTIONS.filter((opt) => COMPATIBLE_TYPES.includes(opt.value));
|
|
106
|
+
|
|
107
|
+
const handleSave = () => {
|
|
108
|
+
if (!providerType) return;
|
|
71
109
|
|
|
72
|
-
|
|
73
|
-
|
|
110
|
+
let key: string;
|
|
111
|
+
const entry: ProviderEntry = { type: providerType, apiKey: providerApiKey };
|
|
112
|
+
|
|
113
|
+
if (isCompatible) {
|
|
114
|
+
if (!providerName.trim()) return;
|
|
115
|
+
key = providerName.trim();
|
|
116
|
+
entry.baseUrl = providerBaseUrl;
|
|
117
|
+
} else {
|
|
118
|
+
key = providerType;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// In add mode, don't overwrite existing
|
|
122
|
+
if (!isEdit && providers[key]) return;
|
|
123
|
+
|
|
124
|
+
const next = { ...providers };
|
|
125
|
+
|
|
126
|
+
// If editing and key changed (shouldn't happen for built-in), remove old
|
|
127
|
+
if (isEdit && editKey !== key) {
|
|
128
|
+
delete next[editKey!];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
next[key] = entry;
|
|
132
|
+
onProvidersChange(next);
|
|
133
|
+
onHide();
|
|
74
134
|
};
|
|
75
135
|
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
136
|
+
const handleRemove = () => {
|
|
137
|
+
if (!editKey) return;
|
|
138
|
+
const next = { ...providers };
|
|
139
|
+
delete next[editKey];
|
|
140
|
+
onProvidersChange(next);
|
|
141
|
+
onHide();
|
|
81
142
|
};
|
|
82
143
|
|
|
144
|
+
const canSave = providerType && (isCompatible ? providerName.trim() : true);
|
|
145
|
+
|
|
83
146
|
return (
|
|
84
|
-
<
|
|
85
|
-
<
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
{isCompatible && (
|
|
99
|
-
<div className="flex flex-column gap-2">
|
|
100
|
-
<label className="form-field-label">Base URL</label>
|
|
101
|
-
<SolidInput
|
|
102
|
-
placeholder="http://localhost:8000"
|
|
103
|
-
value={providerConfig?.baseUrl || ""}
|
|
104
|
-
onChange={(e) => handleConfigUpdate("baseUrl", e.target.value)}
|
|
147
|
+
<SolidDialog open={visible} onOpenChange={(open) => !open && onHide()} style={{ width: "500px" }}>
|
|
148
|
+
<SolidDialogHeader>
|
|
149
|
+
<SolidDialogTitle>
|
|
150
|
+
{isEdit
|
|
151
|
+
? `Edit Provider — ${BUILT_IN_TYPES.includes(editKey!) ? PROVIDER_TYPE_OPTIONS.find((o) => o.value === editKey)?.label : editKey}`
|
|
152
|
+
: "Add Provider"}
|
|
153
|
+
</SolidDialogTitle>
|
|
154
|
+
</SolidDialogHeader>
|
|
155
|
+
<SolidDialogBody>
|
|
156
|
+
<div className="flex flex-column gap-3">
|
|
157
|
+
{!(isEdit && BUILT_IN_TYPES.includes(editKey!)) && (
|
|
158
|
+
<div>
|
|
159
|
+
<label className="form-field-label">Provider Type</label>
|
|
160
|
+
<SolidSelect
|
|
105
161
|
className="w-full"
|
|
162
|
+
value={providerType}
|
|
163
|
+
options={typeOptions}
|
|
164
|
+
onChange={(e) => {
|
|
165
|
+
setProviderType(e.value);
|
|
166
|
+
if (!isEdit) {
|
|
167
|
+
setProviderName("");
|
|
168
|
+
setProviderBaseUrl("");
|
|
169
|
+
}
|
|
170
|
+
}}
|
|
171
|
+
placeholder="Select Provider Type"
|
|
172
|
+
disabled={isEdit}
|
|
106
173
|
/>
|
|
107
174
|
</div>
|
|
108
175
|
)}
|
|
109
|
-
|
|
176
|
+
{isCompatible && (
|
|
177
|
+
<>
|
|
178
|
+
{!isEdit && (
|
|
179
|
+
<div>
|
|
180
|
+
<label className="form-field-label">Name (unique identifier)</label>
|
|
181
|
+
<SolidInput
|
|
182
|
+
placeholder="e.g. openrouter, together-ai"
|
|
183
|
+
value={providerName}
|
|
184
|
+
onChange={(e) => setProviderName(e.target.value)}
|
|
185
|
+
className="w-full"
|
|
186
|
+
/>
|
|
187
|
+
</div>
|
|
188
|
+
)}
|
|
189
|
+
<div>
|
|
190
|
+
<label className="form-field-label">Base URL</label>
|
|
191
|
+
<SolidInput
|
|
192
|
+
placeholder="https://openrouter.ai/api/v1"
|
|
193
|
+
value={providerBaseUrl}
|
|
194
|
+
onChange={(e) => setProviderBaseUrl(e.target.value)}
|
|
195
|
+
className="w-full"
|
|
196
|
+
/>
|
|
197
|
+
</div>
|
|
198
|
+
</>
|
|
199
|
+
)}
|
|
200
|
+
<div>
|
|
110
201
|
<label className="form-field-label">API Key</label>
|
|
111
202
|
<SolidInput
|
|
112
203
|
type="password"
|
|
204
|
+
value={providerApiKey}
|
|
205
|
+
onChange={(e) => setProviderApiKey(e.target.value)}
|
|
206
|
+
className="w-full"
|
|
207
|
+
/>
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
</SolidDialogBody>
|
|
211
|
+
<SolidDialogFooter>
|
|
212
|
+
<div className="flex justify-content-between w-full">
|
|
213
|
+
<div>
|
|
214
|
+
{isEdit && !BUILT_IN_TYPES.includes(editKey!) && (
|
|
215
|
+
<SolidButton variant="ghost" onClick={handleRemove} style={{ color: "var(--solid-danger-color, #ef4444)" }}>
|
|
216
|
+
Remove
|
|
217
|
+
</SolidButton>
|
|
218
|
+
)}
|
|
219
|
+
</div>
|
|
220
|
+
<div className="flex gap-2">
|
|
221
|
+
<SolidButton variant="outline" onClick={onHide}>
|
|
222
|
+
Cancel
|
|
223
|
+
</SolidButton>
|
|
224
|
+
<SolidButton onClick={handleSave} disabled={!canSave}>
|
|
225
|
+
{isEdit ? "Save" : "Add"}
|
|
226
|
+
</SolidButton>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
</SolidDialogFooter>
|
|
230
|
+
</SolidDialog>
|
|
231
|
+
);
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
// --- Providers Tab (List View) ---
|
|
235
|
+
|
|
236
|
+
interface ProvidersTabProps {
|
|
237
|
+
providers: Record<string, ProviderEntry>;
|
|
238
|
+
onProvidersChange: (providers: Record<string, ProviderEntry>) => void;
|
|
239
|
+
showAddModal?: boolean;
|
|
240
|
+
onAddModalClose?: () => void;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export const ProvidersTab = ({ providers, onProvidersChange, showAddModal, onAddModalClose }: ProvidersTabProps) => {
|
|
244
|
+
const [editKey, setEditKey] = useState<string | null>(null);
|
|
245
|
+
const [modalVisible, setModalVisible] = useState(false);
|
|
246
|
+
|
|
247
|
+
// Ensure built-in providers are always present
|
|
248
|
+
const allProviders = ensureBuiltInProviders(providers);
|
|
249
|
+
|
|
250
|
+
// Open modal when parent triggers add
|
|
251
|
+
React.useEffect(() => {
|
|
252
|
+
if (showAddModal) {
|
|
253
|
+
setEditKey(null);
|
|
254
|
+
setModalVisible(true);
|
|
255
|
+
}
|
|
256
|
+
}, [showAddModal]);
|
|
257
|
+
|
|
258
|
+
const providerEntries = Object.entries(allProviders);
|
|
259
|
+
|
|
260
|
+
const handleRowClick = (key: string) => {
|
|
261
|
+
setEditKey(key);
|
|
262
|
+
setModalVisible(true);
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
return (
|
|
266
|
+
<>
|
|
267
|
+
<div className="solid-simple-table">
|
|
268
|
+
<table style={{ width: "100%" }}>
|
|
269
|
+
<thead>
|
|
270
|
+
<tr>
|
|
271
|
+
<th style={{ textAlign: "left", padding: "0.75rem 1rem" }}>Name</th>
|
|
272
|
+
<th style={{ textAlign: "left", padding: "0.75rem 1rem" }}>Type</th>
|
|
273
|
+
<th style={{ textAlign: "left", padding: "0.75rem 1rem" }}>API Key</th>
|
|
274
|
+
<th style={{ textAlign: "left", padding: "0.75rem 1rem" }}>Base URL</th>
|
|
275
|
+
</tr>
|
|
276
|
+
</thead>
|
|
277
|
+
<tbody>
|
|
278
|
+
{providerEntries.length === 0 && (
|
|
279
|
+
<tr>
|
|
280
|
+
<td colSpan={4} style={{ textAlign: "center", padding: "2rem 1rem", opacity: 0.5 }}>
|
|
281
|
+
No providers configured.
|
|
282
|
+
</td>
|
|
283
|
+
</tr>
|
|
284
|
+
)}
|
|
285
|
+
{providerEntries.map(([key, entry]) => {
|
|
286
|
+
const typeLabel = PROVIDER_TYPE_OPTIONS.find((o) => o.value === entry.type)?.label ?? entry.type;
|
|
287
|
+
const isBuiltIn = BUILT_IN_TYPES.includes(key);
|
|
288
|
+
const displayName = isBuiltIn ? typeLabel : key;
|
|
289
|
+
const maskedKey = entry.apiKey ? "\u2022".repeat(Math.min(entry.apiKey.length, 8)) : "-";
|
|
290
|
+
|
|
291
|
+
return (
|
|
292
|
+
<tr
|
|
293
|
+
key={key}
|
|
294
|
+
onClick={() => handleRowClick(key)}
|
|
295
|
+
style={{ cursor: "pointer" }}
|
|
296
|
+
className="solid-table-row-hover"
|
|
297
|
+
>
|
|
298
|
+
<td style={{ padding: "0.75rem 1rem", fontWeight: 500 }}>{displayName}</td>
|
|
299
|
+
<td style={{ padding: "0.75rem 1rem" }}>{typeLabel}</td>
|
|
300
|
+
<td style={{ padding: "0.75rem 1rem" }}>{maskedKey}</td>
|
|
301
|
+
<td style={{ padding: "0.75rem 1rem" }}>{entry.baseUrl || "-"}</td>
|
|
302
|
+
</tr>
|
|
303
|
+
);
|
|
304
|
+
})}
|
|
305
|
+
</tbody>
|
|
306
|
+
</table>
|
|
307
|
+
</div>
|
|
308
|
+
|
|
309
|
+
<ProviderModal
|
|
310
|
+
visible={modalVisible}
|
|
311
|
+
onHide={() => {
|
|
312
|
+
setModalVisible(false);
|
|
313
|
+
setEditKey(null);
|
|
314
|
+
onAddModalClose?.();
|
|
315
|
+
}}
|
|
316
|
+
providers={allProviders}
|
|
317
|
+
onProvidersChange={onProvidersChange}
|
|
318
|
+
editKey={editKey}
|
|
319
|
+
/>
|
|
320
|
+
</>
|
|
321
|
+
);
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
// --- Model Config Tab (used for Intelligent Model & Fast Model) ---
|
|
325
|
+
|
|
326
|
+
interface ModelConfigTabProps {
|
|
327
|
+
modelEntry: ModelEntry;
|
|
328
|
+
providers: Record<string, ProviderEntry>;
|
|
329
|
+
onModelEntryChange: (entry: ModelEntry) => void;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export const ModelConfigTab = ({ modelEntry, providers, onModelEntryChange }: ModelConfigTabProps) => {
|
|
333
|
+
const providerOptions = Object.entries(providers).map(([key, entry]) => {
|
|
334
|
+
const typeLabel = PROVIDER_TYPE_OPTIONS.find((o) => o.value === entry.type)?.label ?? entry.type;
|
|
335
|
+
const label = BUILT_IN_TYPES.includes(key) ? typeLabel : `${key} (${typeLabel})`;
|
|
336
|
+
return { label, value: key };
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
return (
|
|
340
|
+
<div className="flex flex-column gap-4">
|
|
341
|
+
<div style={{ ...cardStyle, width: "50%" }}>
|
|
342
|
+
<p className="solid-settings-subheading">Model Config</p>
|
|
343
|
+
<div className="flex flex-column gap-3 mt-3">
|
|
344
|
+
<div>
|
|
345
|
+
<label className="form-field-label">Provider</label>
|
|
346
|
+
<SolidSelect
|
|
113
347
|
className="w-full"
|
|
114
|
-
value={
|
|
115
|
-
|
|
348
|
+
value={modelEntry.providerId}
|
|
349
|
+
options={providerOptions}
|
|
350
|
+
onChange={(e) => onModelEntryChange({ ...modelEntry, providerId: e.value })}
|
|
351
|
+
placeholder="Select Provider"
|
|
116
352
|
/>
|
|
117
353
|
</div>
|
|
118
|
-
<div
|
|
354
|
+
<div>
|
|
119
355
|
<label className="form-field-label">Model</label>
|
|
120
356
|
<SolidInput
|
|
121
357
|
placeholder="e.g. gpt-4o-mini"
|
|
122
|
-
value={
|
|
123
|
-
onChange={(e) =>
|
|
358
|
+
value={modelEntry.model || ""}
|
|
359
|
+
onChange={(e) => onModelEntryChange({ ...modelEntry, model: e.target.value })}
|
|
124
360
|
className="w-full"
|
|
125
361
|
/>
|
|
126
362
|
</div>
|
|
127
363
|
</div>
|
|
128
364
|
</div>
|
|
129
365
|
|
|
130
|
-
<div style={cardStyle}>
|
|
366
|
+
<div style={{ ...cardStyle, width: "50%" }}>
|
|
131
367
|
<p className="solid-settings-subheading">Behavior</p>
|
|
132
368
|
<div className="flex flex-column gap-3 mt-3">
|
|
133
369
|
<div className="flex align-items-center gap-2">
|
|
134
370
|
<SolidSwitch
|
|
135
|
-
checked={behavior.streaming}
|
|
136
|
-
onChange={(val) =>
|
|
371
|
+
checked={modelEntry.behavior.streaming}
|
|
372
|
+
onChange={(val) =>
|
|
373
|
+
onModelEntryChange({ ...modelEntry, behavior: { ...modelEntry.behavior, streaming: val } })
|
|
374
|
+
}
|
|
137
375
|
/>
|
|
138
376
|
<label className="form-field-label" style={{ marginBottom: 0 }}>Streaming</label>
|
|
139
377
|
</div>
|
|
140
|
-
<div
|
|
378
|
+
<div>
|
|
141
379
|
<label className="form-field-label">Custom Params (JSON)</label>
|
|
142
380
|
<SolidTextarea
|
|
143
|
-
value={behavior.custom}
|
|
144
|
-
onChange={(e) =>
|
|
381
|
+
value={modelEntry.behavior.custom}
|
|
382
|
+
onChange={(e) =>
|
|
383
|
+
onModelEntryChange({ ...modelEntry, behavior: { ...modelEntry.behavior, custom: e.target.value } })
|
|
384
|
+
}
|
|
145
385
|
placeholder='{ "temperature": 0.7, "maxTokens": 1000 }'
|
|
146
386
|
rows={4}
|
|
147
387
|
className="w-full"
|
|
@@ -149,7 +389,6 @@ export const AiModelConfigTab = ({
|
|
|
149
389
|
</div>
|
|
150
390
|
</div>
|
|
151
391
|
</div>
|
|
152
|
-
|
|
153
392
|
</div>
|
|
154
393
|
);
|
|
155
394
|
};
|
|
@@ -13,8 +13,9 @@ type SolidTabGroupProps = {
|
|
|
13
13
|
listClassName?: string;
|
|
14
14
|
panelClassName?: string;
|
|
15
15
|
tabPosition?: "left" | "center" | "right";
|
|
16
|
+
extra?: React.ReactNode;
|
|
16
17
|
};
|
|
17
18
|
export declare function SolidTab(_props: SolidTabProps): null;
|
|
18
|
-
export declare function SolidTabGroup({ tabs, value, onValueChange, className, listClassName, panelClassName, tabPosition, }: SolidTabGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export declare function SolidTabGroup({ tabs, value, onValueChange, className, listClassName, panelClassName, tabPosition, extra, }: SolidTabGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
19
20
|
export {};
|
|
20
21
|
//# sourceMappingURL=SolidTabs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SolidTabs.d.ts","sourceRoot":"","sources":["../../../src/components/shad-cn-ui/SolidTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"SolidTabs.d.ts","sourceRoot":"","sources":["../../../src/components/shad-cn-ui/SolidTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC1C,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB,CAAC;AAMF,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,QAE7C;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,aAAa,EACb,SAAS,EACT,aAAa,EACb,cAAc,EACd,WAAoB,EACpB,KAAK,GACN,EAAE,kBAAkB,2CAqDpB"}
|
|
@@ -10,11 +10,11 @@ export function SolidTab(_props) {
|
|
|
10
10
|
return null;
|
|
11
11
|
}
|
|
12
12
|
export function SolidTabGroup(_a) {
|
|
13
|
-
var tabs = _a.tabs, value = _a.value, onValueChange = _a.onValueChange, className = _a.className, listClassName = _a.listClassName, panelClassName = _a.panelClassName, _b = _a.tabPosition, tabPosition = _b === void 0 ? "left" : _b;
|
|
14
|
-
return (_jsxs("div", { className: cx("solid-notebook", "solid-tabs", "solid-tabs--".concat(tabPosition), className), children: [
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
var tabs = _a.tabs, value = _a.value, onValueChange = _a.onValueChange, className = _a.className, listClassName = _a.listClassName, panelClassName = _a.panelClassName, _b = _a.tabPosition, tabPosition = _b === void 0 ? "left" : _b, extra = _a.extra;
|
|
14
|
+
return (_jsxs("div", { className: cx("solid-notebook", "solid-tabs", "solid-tabs--".concat(tabPosition), className), children: [_jsxs("div", { className: cx("solid-notebook-tablist", "solid-tabs-list", listClassName), role: "tablist", style: extra ? { display: "flex", alignItems: "center", justifyContent: "space-between" } : undefined, children: [_jsx("div", { style: extra ? { display: "flex" } : undefined, children: tabs.map(function (tab) {
|
|
15
|
+
var isActive = tab.value === value;
|
|
16
|
+
return (_jsx("button", { type: "button", role: "tab", "aria-selected": isActive, "aria-controls": "solid-tab-panel-".concat(tab.value), id: "solid-tab-".concat(tab.value), className: cx("solid-notebook-tab-trigger", "solid-tabs-trigger", tab.hasError && "error", isActive && "active", isActive && "is-active"), onClick: function () { return onValueChange(tab.value); }, children: tab.label }, tab.value));
|
|
17
|
+
}) }), extra && _jsx("div", { children: extra })] }), tabs.map(function (tab) {
|
|
18
18
|
var isActive = tab.value === value;
|
|
19
19
|
return (_jsx("div", { role: "tabpanel", id: "solid-tab-panel-".concat(tab.value), "aria-labelledby": "solid-tab-".concat(tab.value), hidden: !isActive, className: cx("solid-notebook-content", "solid-tabs-panel", panelClassName), children: isActive ? tab.content : null }, tab.value));
|
|
20
20
|
})] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SolidTabs.js","sourceRoot":"","sources":["../../../src/components/shad-cn-ui/SolidTabs.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"SolidTabs.js","sourceRoot":"","sources":["../../../src/components/shad-cn-ui/SolidTabs.tsx"],"names":[],"mappings":";AAoBA,SAAS,EAAE;IAAC,eAA2C;SAA3C,UAA2C,EAA3C,qBAA2C,EAA3C,IAA2C;QAA3C,0BAA2C;;IACrD,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAqB;IAC5C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAST;QARnB,IAAI,UAAA,EACJ,KAAK,WAAA,EACL,aAAa,mBAAA,EACb,SAAS,eAAA,EACT,aAAa,mBAAA,EACb,cAAc,oBAAA,EACd,mBAAoB,EAApB,WAAW,mBAAG,MAAM,KAAA,EACpB,KAAK,WAAA;IAEL,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,gBAAgB,EAAE,YAAY,EAAE,sBAAe,WAAW,CAAE,EAAE,SAAS,CAAC,aACzF,eACE,SAAS,EAAE,EAAE,CAAC,wBAAwB,EAAE,iBAAiB,EAAE,aAAa,CAAC,EACzE,IAAI,EAAC,SAAS,EACd,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,SAAS,aAErG,cAAK,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,YAClD,IAAI,CAAC,GAAG,CAAC,UAAC,GAAG;4BACZ,IAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC;4BACrC,OAAO,CACL,iBAEE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,QAAQ,mBACR,0BAAmB,GAAG,CAAC,KAAK,CAAE,EAC7C,EAAE,EAAE,oBAAa,GAAG,CAAC,KAAK,CAAE,EAC5B,SAAS,EAAE,EAAE,CACX,4BAA4B,EAC5B,oBAAoB,EACpB,GAAG,CAAC,QAAQ,IAAI,OAAO,EACvB,QAAQ,IAAI,QAAQ,EACpB,QAAQ,IAAI,WAAW,CACxB,EACD,OAAO,EAAE,cAAM,OAAA,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAxB,CAAwB,YAEtC,GAAG,CAAC,KAAK,IAfL,GAAG,CAAC,KAAK,CAgBP,CACV,CAAC;wBACJ,CAAC,CAAC,GACI,EACL,KAAK,IAAI,wBAAM,KAAK,GAAO,IACxB,EAEL,IAAI,CAAC,GAAG,CAAC,UAAC,GAAG;gBACZ,IAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC;gBACrC,OAAO,CACL,cAEE,IAAI,EAAC,UAAU,EACf,EAAE,EAAE,0BAAmB,GAAG,CAAC,KAAK,CAAE,qBACjB,oBAAa,GAAG,CAAC,KAAK,CAAE,EACzC,MAAM,EAAE,CAAC,QAAQ,EACjB,SAAS,EAAE,EAAE,CAAC,wBAAwB,EAAE,kBAAkB,EAAE,cAAc,CAAC,YAE1E,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAPzB,GAAG,CAAC,KAAK,CAQV,CACP,CAAC;YACJ,CAAC,CAAC,IACE,CACP,CAAC;AACJ,CAAC","sourcesContent":["import React from \"react\";\n\ntype SolidTabProps = {\n value: string;\n label: React.ReactNode;\n content: React.ReactNode;\n hasError?: boolean;\n};\n\ntype SolidTabGroupProps = {\n tabs: SolidTabProps[];\n value: string;\n onValueChange: (value: string) => void;\n className?: string;\n listClassName?: string;\n panelClassName?: string;\n tabPosition?: \"left\" | \"center\" | \"right\";\n extra?: React.ReactNode;\n};\n\nfunction cx(...parts: Array<string | false | undefined>) {\n return parts.filter(Boolean).join(\" \");\n}\n\nexport function SolidTab(_props: SolidTabProps) {\n return null;\n}\n\nexport function SolidTabGroup({\n tabs,\n value,\n onValueChange,\n className,\n listClassName,\n panelClassName,\n tabPosition = \"left\",\n extra,\n}: SolidTabGroupProps) {\n return (\n <div className={cx(\"solid-notebook\", \"solid-tabs\", `solid-tabs--${tabPosition}`, className)}>\n <div\n className={cx(\"solid-notebook-tablist\", \"solid-tabs-list\", listClassName)}\n role=\"tablist\"\n style={extra ? { display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\" } : undefined}\n >\n <div style={extra ? { display: \"flex\" } : undefined}>\n {tabs.map((tab) => {\n const isActive = tab.value === value;\n return (\n <button\n key={tab.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={isActive}\n aria-controls={`solid-tab-panel-${tab.value}`}\n id={`solid-tab-${tab.value}`}\n className={cx(\n \"solid-notebook-tab-trigger\",\n \"solid-tabs-trigger\",\n tab.hasError && \"error\",\n isActive && \"active\",\n isActive && \"is-active\",\n )}\n onClick={() => onValueChange(tab.value)}\n >\n {tab.label}\n </button>\n );\n })}\n </div>\n {extra && <div>{extra}</div>}\n </div>\n\n {tabs.map((tab) => {\n const isActive = tab.value === value;\n return (\n <div\n key={tab.value}\n role=\"tabpanel\"\n id={`solid-tab-panel-${tab.value}`}\n aria-labelledby={`solid-tab-${tab.value}`}\n hidden={!isActive}\n className={cx(\"solid-notebook-content\", \"solid-tabs-panel\", panelClassName)}\n >\n {isActive ? tab.content : null}\n </div>\n );\n })}\n </div>\n );\n}\n"]}
|
|
@@ -15,6 +15,7 @@ type SolidTabGroupProps = {
|
|
|
15
15
|
listClassName?: string;
|
|
16
16
|
panelClassName?: string;
|
|
17
17
|
tabPosition?: "left" | "center" | "right";
|
|
18
|
+
extra?: React.ReactNode;
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
function cx(...parts: Array<string | false | undefined>) {
|
|
@@ -33,13 +34,16 @@ export function SolidTabGroup({
|
|
|
33
34
|
listClassName,
|
|
34
35
|
panelClassName,
|
|
35
36
|
tabPosition = "left",
|
|
37
|
+
extra,
|
|
36
38
|
}: SolidTabGroupProps) {
|
|
37
39
|
return (
|
|
38
40
|
<div className={cx("solid-notebook", "solid-tabs", `solid-tabs--${tabPosition}`, className)}>
|
|
39
41
|
<div
|
|
40
42
|
className={cx("solid-notebook-tablist", "solid-tabs-list", listClassName)}
|
|
41
43
|
role="tablist"
|
|
44
|
+
style={extra ? { display: "flex", alignItems: "center", justifyContent: "space-between" } : undefined}
|
|
42
45
|
>
|
|
46
|
+
<div style={extra ? { display: "flex" } : undefined}>
|
|
43
47
|
{tabs.map((tab) => {
|
|
44
48
|
const isActive = tab.value === value;
|
|
45
49
|
return (
|
|
@@ -63,6 +67,8 @@ export function SolidTabGroup({
|
|
|
63
67
|
</button>
|
|
64
68
|
);
|
|
65
69
|
})}
|
|
70
|
+
</div>
|
|
71
|
+
{extra && <div>{extra}</div>}
|
|
66
72
|
</div>
|
|
67
73
|
|
|
68
74
|
{tabs.map((tab) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GuestGuard.d.ts","sourceRoot":"","sources":["../../../src/routes/guards/GuestGuard.tsx"],"names":[],"mappings":"AAIA,wBAAgB,UAAU,
|
|
1
|
+
{"version":3,"file":"GuestGuard.d.ts","sourceRoot":"","sources":["../../../src/routes/guards/GuestGuard.tsx"],"names":[],"mappings":"AAIA,wBAAgB,UAAU,4CAezB"}
|
|
@@ -6,13 +6,8 @@ export function GuestGuard() {
|
|
|
6
6
|
var status = useSession().status;
|
|
7
7
|
var navigate = useNavigate();
|
|
8
8
|
useEffect(function () {
|
|
9
|
-
if (status === "authenticated") {
|
|
10
|
-
|
|
11
|
-
navigate(-1);
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
navigate("/admin", { replace: true });
|
|
15
|
-
}
|
|
9
|
+
if (status === "authenticated" && location.pathname.startsWith("/auth")) {
|
|
10
|
+
navigate("/admin", { replace: true });
|
|
16
11
|
}
|
|
17
12
|
}, [status, navigate]);
|
|
18
13
|
if (status === "loading" || status === "authenticated") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GuestGuard.js","sourceRoot":"","sources":["../../../src/routes/guards/GuestGuard.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,MAAM,UAAU,UAAU;IAChB,IAAA,MAAM,GAAK,UAAU,EAAE,OAAjB,CAAkB;IAChC,IAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,SAAS,CAAC;QACR,IAAI,MAAM,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"GuestGuard.js","sourceRoot":"","sources":["../../../src/routes/guards/GuestGuard.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,MAAM,UAAU,UAAU;IAChB,IAAA,MAAM,GAAK,UAAU,EAAE,OAAjB,CAAkB;IAChC,IAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,SAAS,CAAC;QACR,IAAI,MAAM,KAAK,eAAe,IAAI,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE;YACvE,QAAQ,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;SACvC;IACH,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEvB,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,eAAe,EAAE;QACtD,OAAO,uCAAqB,CAAC;KAC9B;IAED,OAAO,KAAC,MAAM,KAAG,CAAC;AACpB,CAAC","sourcesContent":["import { useEffect } from \"react\";\nimport { Outlet, useNavigate } from \"react-router-dom\";\nimport { useSession } from \"../../hooks/useSession\";\n\nexport function GuestGuard() {\n const { status } = useSession();\n const navigate = useNavigate();\n\n useEffect(() => {\n if (status === \"authenticated\" && location.pathname.startsWith(\"/auth\")) {\n navigate(\"/admin\", { replace: true });\n }\n }, [status, navigate]);\n\n if (status === \"loading\" || status === \"authenticated\") {\n return <div>Loading...</div>;\n }\n\n return <Outlet />;\n}"]}
|
|
@@ -7,12 +7,8 @@ export function GuestGuard() {
|
|
|
7
7
|
const navigate = useNavigate();
|
|
8
8
|
|
|
9
9
|
useEffect(() => {
|
|
10
|
-
if (status === "authenticated") {
|
|
11
|
-
|
|
12
|
-
navigate(-1);
|
|
13
|
-
} else {
|
|
14
|
-
navigate("/admin", { replace: true });
|
|
15
|
-
}
|
|
10
|
+
if (status === "authenticated" && location.pathname.startsWith("/auth")) {
|
|
11
|
+
navigate("/admin", { replace: true });
|
|
16
12
|
}
|
|
17
13
|
}, [status, navigate]);
|
|
18
14
|
|