Bug Fixes part1
Browse files
app/components/settings/connections/ConnectionsTab.tsx
CHANGED
@@ -311,6 +311,24 @@ export default function ConnectionsTab() {
|
|
311 |
'disabled:opacity-50',
|
312 |
)}
|
313 |
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
</div>
|
315 |
</div>
|
316 |
|
|
|
311 |
'disabled:opacity-50',
|
312 |
)}
|
313 |
/>
|
314 |
+
<div className="mt-2 text-sm text-bolt-elements-textSecondary">
|
315 |
+
<a
|
316 |
+
href={`https://github.com/settings/tokens${connection.tokenType === 'fine-grained' ? '/beta' : '/new'}`}
|
317 |
+
target="_blank"
|
318 |
+
rel="noopener noreferrer"
|
319 |
+
className="text-purple-500 hover:underline inline-flex items-center gap-1"
|
320 |
+
>
|
321 |
+
Get your token
|
322 |
+
<div className="i-ph:arrow-square-out w-10 h-5" />
|
323 |
+
</a>
|
324 |
+
<span className="mx-2">•</span>
|
325 |
+
<span>
|
326 |
+
Required scopes:{' '}
|
327 |
+
{connection.tokenType === 'classic'
|
328 |
+
? 'repo, read:org, read:user'
|
329 |
+
: 'Repository access, Organization access'}
|
330 |
+
</span>
|
331 |
+
</div>
|
332 |
</div>
|
333 |
</div>
|
334 |
|
app/components/settings/features/FeaturesTab.tsx
CHANGED
@@ -1,19 +1,11 @@
|
|
1 |
-
|
|
|
2 |
import { motion } from 'framer-motion';
|
3 |
import { Switch } from '~/components/ui/Switch';
|
4 |
import { useSettings } from '~/lib/hooks/useSettings';
|
5 |
import { classNames } from '~/utils/classNames';
|
6 |
import { toast } from 'react-toastify';
|
7 |
import { PromptLibrary } from '~/lib/common/prompt-library';
|
8 |
-
import {
|
9 |
-
latestBranchStore,
|
10 |
-
autoSelectStarterTemplate,
|
11 |
-
enableContextOptimizationStore,
|
12 |
-
isLocalModelsEnabled,
|
13 |
-
isEventLogsEnabled,
|
14 |
-
promptStore as promptAtom,
|
15 |
-
} from '~/lib/stores/settings';
|
16 |
-
import { logStore } from '~/lib/stores/logs';
|
17 |
|
18 |
interface FeatureToggle {
|
19 |
id: string;
|
@@ -114,133 +106,85 @@ const FeatureSection = memo(
|
|
114 |
);
|
115 |
|
116 |
export default function FeaturesTab() {
|
117 |
-
const {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
|
119 |
-
const
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
useEffect(() => {
|
150 |
-
localStorage.setItem('autoSelectTemplate', JSON.stringify(autoSelectTemplateLocal));
|
151 |
-
localStorage.setItem('enableLatestBranch', JSON.stringify(enableLatestBranchLocal));
|
152 |
-
localStorage.setItem('contextOptimization', JSON.stringify(contextOptimizationLocal));
|
153 |
-
localStorage.setItem('eventLogs', JSON.stringify(eventLogsLocal));
|
154 |
-
localStorage.setItem('experimentalProviders', JSON.stringify(experimentalProvidersLocal));
|
155 |
-
localStorage.setItem('promptLibrary', JSON.stringify(promptLibraryLocal));
|
156 |
-
localStorage.setItem('promptId', promptIdLocal);
|
157 |
-
|
158 |
-
autoSelectStarterTemplate.set(autoSelectTemplateLocal);
|
159 |
-
latestBranchStore.set(enableLatestBranchLocal);
|
160 |
-
enableContextOptimizationStore.set(contextOptimizationLocal);
|
161 |
-
isEventLogsEnabled.set(eventLogsLocal);
|
162 |
-
isLocalModelsEnabled.set(experimentalProvidersLocal);
|
163 |
-
promptAtom.set(promptIdLocal);
|
164 |
-
}, [
|
165 |
-
autoSelectTemplateLocal,
|
166 |
-
enableLatestBranchLocal,
|
167 |
-
contextOptimizationLocal,
|
168 |
-
eventLogsLocal,
|
169 |
-
experimentalProvidersLocal,
|
170 |
-
promptLibraryLocal,
|
171 |
-
promptIdLocal,
|
172 |
-
]);
|
173 |
-
|
174 |
-
const handleToggleFeature = (featureId: string, enabled: boolean) => {
|
175 |
-
logStore.logFeatureToggle(featureId, enabled);
|
176 |
-
|
177 |
-
switch (featureId) {
|
178 |
-
case 'latestBranch':
|
179 |
-
setEnableLatestBranchLocal(enabled);
|
180 |
-
latestBranchStore.set(enabled);
|
181 |
-
toast.success(`Main branch updates ${enabled ? 'enabled' : 'disabled'}`);
|
182 |
-
break;
|
183 |
-
case 'autoSelectTemplate':
|
184 |
-
setAutoSelectTemplateLocal(enabled);
|
185 |
-
autoSelectStarterTemplate.set(enabled);
|
186 |
-
toast.success(`Auto template selection ${enabled ? 'enabled' : 'disabled'}`);
|
187 |
-
break;
|
188 |
-
case 'contextOptimization':
|
189 |
-
setContextOptimizationLocal(enabled);
|
190 |
-
enableContextOptimizationStore.set(enabled);
|
191 |
-
toast.success(`Context optimization ${enabled ? 'enabled' : 'disabled'}`);
|
192 |
-
break;
|
193 |
-
case 'localModels':
|
194 |
-
setExperimentalProvidersLocal(enabled);
|
195 |
-
isLocalModelsEnabled.set(enabled);
|
196 |
-
toast.success(`Experimental providers ${enabled ? 'enabled' : 'disabled'}`);
|
197 |
-
break;
|
198 |
-
case 'eventLogs':
|
199 |
-
setEventLogsLocal(enabled);
|
200 |
-
isEventLogsEnabled.set(enabled);
|
201 |
-
toast.success(`Event logging ${enabled ? 'enabled' : 'disabled'}`);
|
202 |
-
break;
|
203 |
-
case 'promptLibrary':
|
204 |
-
setPromptLibraryLocal(enabled);
|
205 |
-
toast.success(`Prompt Library ${enabled ? 'enabled' : 'disabled'}`);
|
206 |
-
break;
|
207 |
-
}
|
208 |
-
};
|
209 |
|
210 |
-
const features
|
211 |
stable: [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
212 |
{
|
213 |
id: 'autoSelectTemplate',
|
214 |
-
title: 'Auto Select
|
215 |
-
description: '
|
216 |
-
icon: 'i-ph:
|
217 |
-
enabled:
|
218 |
-
tooltip: 'Automatically
|
219 |
},
|
220 |
{
|
221 |
id: 'contextOptimization',
|
222 |
title: 'Context Optimization',
|
223 |
-
description: 'Optimize
|
224 |
-
icon: 'i-ph:
|
225 |
-
enabled:
|
226 |
-
tooltip: '
|
227 |
},
|
228 |
{
|
229 |
id: 'eventLogs',
|
230 |
title: 'Event Logging',
|
231 |
description: 'Enable detailed event logging and history',
|
232 |
icon: 'i-ph:list-bullets',
|
233 |
-
enabled:
|
234 |
tooltip: 'Record detailed logs of system events and user actions',
|
235 |
},
|
236 |
-
{
|
237 |
-
id: 'promptLibrary',
|
238 |
-
title: 'Prompt Library',
|
239 |
-
description: 'Manage your prompt library settings',
|
240 |
-
icon: 'i-ph:library',
|
241 |
-
enabled: promptLibraryLocal,
|
242 |
-
tooltip: 'Enable or disable the prompt library',
|
243 |
-
},
|
244 |
],
|
245 |
beta: [],
|
246 |
experimental: [
|
@@ -249,7 +193,7 @@ export default function FeaturesTab() {
|
|
249 |
title: 'Experimental Providers',
|
250 |
description: 'Enable experimental providers like Ollama, LMStudio, and OpenAILike',
|
251 |
icon: 'i-ph:robot',
|
252 |
-
enabled:
|
253 |
experimental: true,
|
254 |
tooltip: 'Try out new AI providers and models in development',
|
255 |
},
|
@@ -319,9 +263,9 @@ export default function FeaturesTab() {
|
|
319 |
</p>
|
320 |
</div>
|
321 |
<select
|
322 |
-
value={
|
323 |
onChange={(e) => {
|
324 |
-
|
325 |
toast.success('Prompt template updated');
|
326 |
}}
|
327 |
className={classNames(
|
|
|
1 |
+
// Remove unused imports
|
2 |
+
import React, { memo, useCallback } from 'react';
|
3 |
import { motion } from 'framer-motion';
|
4 |
import { Switch } from '~/components/ui/Switch';
|
5 |
import { useSettings } from '~/lib/hooks/useSettings';
|
6 |
import { classNames } from '~/utils/classNames';
|
7 |
import { toast } from 'react-toastify';
|
8 |
import { PromptLibrary } from '~/lib/common/prompt-library';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
interface FeatureToggle {
|
11 |
id: string;
|
|
|
106 |
);
|
107 |
|
108 |
export default function FeaturesTab() {
|
109 |
+
const {
|
110 |
+
autoSelectTemplate,
|
111 |
+
isLatestBranch,
|
112 |
+
contextOptimizationEnabled,
|
113 |
+
eventLogs,
|
114 |
+
isLocalModel,
|
115 |
+
setAutoSelectTemplate,
|
116 |
+
enableLatestBranch,
|
117 |
+
enableContextOptimization,
|
118 |
+
setEventLogs,
|
119 |
+
enableLocalModels,
|
120 |
+
setPromptId,
|
121 |
+
promptId,
|
122 |
+
} = useSettings();
|
123 |
|
124 |
+
const handleToggleFeature = useCallback(
|
125 |
+
(id: string, enabled: boolean) => {
|
126 |
+
switch (id) {
|
127 |
+
case 'latestBranch':
|
128 |
+
enableLatestBranch(enabled);
|
129 |
+
toast.success(`Main branch updates ${enabled ? 'enabled' : 'disabled'}`);
|
130 |
+
break;
|
131 |
+
case 'autoSelectTemplate':
|
132 |
+
setAutoSelectTemplate(enabled);
|
133 |
+
toast.success(`Auto select template ${enabled ? 'enabled' : 'disabled'}`);
|
134 |
+
break;
|
135 |
+
case 'contextOptimization':
|
136 |
+
enableContextOptimization(enabled);
|
137 |
+
toast.success(`Context optimization ${enabled ? 'enabled' : 'disabled'}`);
|
138 |
+
break;
|
139 |
+
case 'eventLogs':
|
140 |
+
setEventLogs(enabled);
|
141 |
+
toast.success(`Event logging ${enabled ? 'enabled' : 'disabled'}`);
|
142 |
+
break;
|
143 |
+
case 'localModels':
|
144 |
+
enableLocalModels(enabled);
|
145 |
+
toast.success(`Experimental providers ${enabled ? 'enabled' : 'disabled'}`);
|
146 |
+
break;
|
147 |
+
default:
|
148 |
+
break;
|
149 |
+
}
|
150 |
+
},
|
151 |
+
[enableLatestBranch, setAutoSelectTemplate, enableContextOptimization, setEventLogs, enableLocalModels],
|
152 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
|
154 |
+
const features = {
|
155 |
stable: [
|
156 |
+
{
|
157 |
+
id: 'latestBranch',
|
158 |
+
title: 'Main Branch Updates',
|
159 |
+
description: 'Get the latest updates from the main branch',
|
160 |
+
icon: 'i-ph:git-branch',
|
161 |
+
enabled: isLatestBranch,
|
162 |
+
tooltip: 'Enable to receive updates from the main development branch',
|
163 |
+
},
|
164 |
{
|
165 |
id: 'autoSelectTemplate',
|
166 |
+
title: 'Auto Select Template',
|
167 |
+
description: 'Automatically select starter template',
|
168 |
+
icon: 'i-ph:selection',
|
169 |
+
enabled: autoSelectTemplate,
|
170 |
+
tooltip: 'Automatically select the most appropriate starter template',
|
171 |
},
|
172 |
{
|
173 |
id: 'contextOptimization',
|
174 |
title: 'Context Optimization',
|
175 |
+
description: 'Optimize context for better responses',
|
176 |
+
icon: 'i-ph:brain',
|
177 |
+
enabled: contextOptimizationEnabled,
|
178 |
+
tooltip: 'Enable context optimization for improved AI responses',
|
179 |
},
|
180 |
{
|
181 |
id: 'eventLogs',
|
182 |
title: 'Event Logging',
|
183 |
description: 'Enable detailed event logging and history',
|
184 |
icon: 'i-ph:list-bullets',
|
185 |
+
enabled: eventLogs,
|
186 |
tooltip: 'Record detailed logs of system events and user actions',
|
187 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
],
|
189 |
beta: [],
|
190 |
experimental: [
|
|
|
193 |
title: 'Experimental Providers',
|
194 |
description: 'Enable experimental providers like Ollama, LMStudio, and OpenAILike',
|
195 |
icon: 'i-ph:robot',
|
196 |
+
enabled: isLocalModel,
|
197 |
experimental: true,
|
198 |
tooltip: 'Try out new AI providers and models in development',
|
199 |
},
|
|
|
263 |
</p>
|
264 |
</div>
|
265 |
<select
|
266 |
+
value={promptId}
|
267 |
onChange={(e) => {
|
268 |
+
setPromptId(e.target.value);
|
269 |
toast.success('Prompt template updated');
|
270 |
}}
|
271 |
className={classNames(
|
app/components/settings/providers/CloudProvidersTab.tsx
CHANGED
@@ -62,74 +62,73 @@ const CloudProvidersTab = () => {
|
|
62 |
const [filteredProviders, setFilteredProviders] = useState<IProviderConfig[]>([]);
|
63 |
const [categoryEnabled, setCategoryEnabled] = useState<boolean>(false);
|
64 |
|
65 |
-
//
|
66 |
useEffect(() => {
|
67 |
const newFilteredProviders = Object.entries(settings.providers || {})
|
68 |
-
.filter(([key]) => !['Ollama', 'LMStudio', 'OpenAILike'].includes(key))
|
69 |
-
.map(([key, value]) => {
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
icon: provider.icon,
|
79 |
-
} as IProviderConfig;
|
80 |
-
});
|
81 |
|
82 |
const sorted = newFilteredProviders.sort((a, b) => a.name.localeCompare(b.name));
|
83 |
-
|
84 |
-
const urlConfigurable = sorted.filter((p) => URL_CONFIGURABLE_PROVIDERS.includes(p.name));
|
85 |
|
86 |
-
|
|
|
|
|
87 |
}, [settings.providers]);
|
88 |
|
89 |
-
// Add effect to update category toggle state based on provider states
|
90 |
-
useEffect(() => {
|
91 |
-
const newCategoryState = filteredProviders.every((p) => p.settings.enabled);
|
92 |
-
setCategoryEnabled(newCategoryState);
|
93 |
-
}, [filteredProviders]);
|
94 |
-
|
95 |
const handleToggleCategory = useCallback(
|
96 |
(enabled: boolean) => {
|
97 |
-
|
98 |
filteredProviders.forEach((provider) => {
|
99 |
settings.updateProviderSettings(provider.name, { ...provider.settings, enabled });
|
100 |
});
|
|
|
|
|
101 |
toast.success(enabled ? 'All cloud providers enabled' : 'All cloud providers disabled');
|
102 |
},
|
103 |
[filteredProviders, settings],
|
104 |
);
|
105 |
|
106 |
-
const handleToggleProvider = (
|
107 |
-
|
|
|
|
|
108 |
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
|
|
|
|
117 |
|
118 |
-
const handleUpdateBaseUrl = (
|
119 |
-
|
|
|
120 |
|
121 |
-
|
122 |
-
newBaseUrl
|
123 |
-
}
|
124 |
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
133 |
|
134 |
return (
|
135 |
<div className="space-y-6">
|
|
|
62 |
const [filteredProviders, setFilteredProviders] = useState<IProviderConfig[]>([]);
|
63 |
const [categoryEnabled, setCategoryEnabled] = useState<boolean>(false);
|
64 |
|
65 |
+
// Load and filter providers
|
66 |
useEffect(() => {
|
67 |
const newFilteredProviders = Object.entries(settings.providers || {})
|
68 |
+
.filter(([key]) => !['Ollama', 'LMStudio', 'OpenAILike'].includes(key))
|
69 |
+
.map(([key, value]) => ({
|
70 |
+
name: key,
|
71 |
+
settings: value.settings,
|
72 |
+
staticModels: value.staticModels || [],
|
73 |
+
getDynamicModels: value.getDynamicModels,
|
74 |
+
getApiKeyLink: value.getApiKeyLink,
|
75 |
+
labelForGetApiKey: value.labelForGetApiKey,
|
76 |
+
icon: value.icon,
|
77 |
+
}));
|
|
|
|
|
|
|
78 |
|
79 |
const sorted = newFilteredProviders.sort((a, b) => a.name.localeCompare(b.name));
|
80 |
+
setFilteredProviders(sorted);
|
|
|
81 |
|
82 |
+
// Update category enabled state
|
83 |
+
const allEnabled = newFilteredProviders.every((p) => p.settings.enabled);
|
84 |
+
setCategoryEnabled(allEnabled);
|
85 |
}, [settings.providers]);
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
const handleToggleCategory = useCallback(
|
88 |
(enabled: boolean) => {
|
89 |
+
// Update all providers
|
90 |
filteredProviders.forEach((provider) => {
|
91 |
settings.updateProviderSettings(provider.name, { ...provider.settings, enabled });
|
92 |
});
|
93 |
+
|
94 |
+
setCategoryEnabled(enabled);
|
95 |
toast.success(enabled ? 'All cloud providers enabled' : 'All cloud providers disabled');
|
96 |
},
|
97 |
[filteredProviders, settings],
|
98 |
);
|
99 |
|
100 |
+
const handleToggleProvider = useCallback(
|
101 |
+
(provider: IProviderConfig, enabled: boolean) => {
|
102 |
+
// Update the provider settings in the store
|
103 |
+
settings.updateProviderSettings(provider.name, { ...provider.settings, enabled });
|
104 |
|
105 |
+
if (enabled) {
|
106 |
+
logStore.logProvider(`Provider ${provider.name} enabled`, { provider: provider.name });
|
107 |
+
toast.success(`${provider.name} enabled`);
|
108 |
+
} else {
|
109 |
+
logStore.logProvider(`Provider ${provider.name} disabled`, { provider: provider.name });
|
110 |
+
toast.success(`${provider.name} disabled`);
|
111 |
+
}
|
112 |
+
},
|
113 |
+
[settings],
|
114 |
+
);
|
115 |
|
116 |
+
const handleUpdateBaseUrl = useCallback(
|
117 |
+
(provider: IProviderConfig, baseUrl: string) => {
|
118 |
+
const newBaseUrl: string | undefined = baseUrl.trim() || undefined;
|
119 |
|
120 |
+
// Update the provider settings in the store
|
121 |
+
settings.updateProviderSettings(provider.name, { ...provider.settings, baseUrl: newBaseUrl });
|
|
|
122 |
|
123 |
+
logStore.logProvider(`Base URL updated for ${provider.name}`, {
|
124 |
+
provider: provider.name,
|
125 |
+
baseUrl: newBaseUrl,
|
126 |
+
});
|
127 |
+
toast.success(`${provider.name} base URL updated`);
|
128 |
+
setEditingProvider(null);
|
129 |
+
},
|
130 |
+
[settings],
|
131 |
+
);
|
132 |
|
133 |
return (
|
134 |
<div className="space-y-6">
|
app/lib/hooks/useSettings.ts
CHANGED
@@ -12,6 +12,13 @@ import {
|
|
12 |
tabConfigurationStore,
|
13 |
updateTabConfiguration as updateTabConfig,
|
14 |
resetTabConfiguration as resetTabConfig,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
} from '~/lib/stores/settings';
|
16 |
import { useCallback, useEffect, useState } from 'react';
|
17 |
import Cookies from 'js-cookie';
|
@@ -64,8 +71,13 @@ export interface UseSettingsReturn {
|
|
64 |
resetTabConfiguration: () => void;
|
65 |
}
|
66 |
|
|
|
|
|
|
|
|
|
|
|
67 |
export function useSettings(): UseSettingsReturn {
|
68 |
-
const providers = useStore(providersStore)
|
69 |
const debug = useStore(isDebugMode);
|
70 |
const eventLogs = useStore(isEventLogsEnabled);
|
71 |
const promptId = useStore(promptStore);
|
@@ -87,16 +99,6 @@ export function useSettings(): UseSettingsReturn {
|
|
87 |
};
|
88 |
});
|
89 |
|
90 |
-
// writing values to cookies on change
|
91 |
-
useEffect(() => {
|
92 |
-
const providers = providersStore.get();
|
93 |
-
const providerSetting: Record<string, IProviderSetting> = {};
|
94 |
-
Object.keys(providers).forEach((provider) => {
|
95 |
-
providerSetting[provider] = providers[provider].settings;
|
96 |
-
});
|
97 |
-
Cookies.set('providers', JSON.stringify(providerSetting));
|
98 |
-
}, [providers]);
|
99 |
-
|
100 |
useEffect(() => {
|
101 |
let active = Object.entries(providers)
|
102 |
.filter(([_key, provider]) => provider.settings.enabled)
|
@@ -118,8 +120,8 @@ export function useSettings(): UseSettingsReturn {
|
|
118 |
});
|
119 |
}, []);
|
120 |
|
121 |
-
const updateProviderSettings = useCallback((provider: string, config:
|
122 |
-
|
123 |
}, []);
|
124 |
|
125 |
const enableDebugMode = useCallback((enabled: boolean) => {
|
@@ -129,38 +131,33 @@ export function useSettings(): UseSettingsReturn {
|
|
129 |
}, []);
|
130 |
|
131 |
const setEventLogs = useCallback((enabled: boolean) => {
|
132 |
-
|
133 |
logStore.logSystem(`Event logs ${enabled ? 'enabled' : 'disabled'}`);
|
134 |
-
Cookies.set('isEventLogsEnabled', String(enabled));
|
135 |
}, []);
|
136 |
|
137 |
const enableLocalModels = useCallback((enabled: boolean) => {
|
138 |
-
|
139 |
logStore.logSystem(`Local models ${enabled ? 'enabled' : 'disabled'}`);
|
140 |
-
Cookies.set('isLocalModelsEnabled', String(enabled));
|
141 |
}, []);
|
142 |
|
143 |
-
const setPromptId = useCallback((
|
144 |
-
|
145 |
-
|
146 |
}, []);
|
147 |
|
148 |
const enableLatestBranch = useCallback((enabled: boolean) => {
|
149 |
-
|
150 |
logStore.logSystem(`Main branch updates ${enabled ? 'enabled' : 'disabled'}`);
|
151 |
-
Cookies.set('isLatestBranch', String(enabled));
|
152 |
}, []);
|
153 |
|
154 |
const setAutoSelectTemplate = useCallback((enabled: boolean) => {
|
155 |
-
|
156 |
logStore.logSystem(`Auto select template ${enabled ? 'enabled' : 'disabled'}`);
|
157 |
-
Cookies.set('autoSelectTemplate', String(enabled));
|
158 |
}, []);
|
159 |
|
160 |
const enableContextOptimization = useCallback((enabled: boolean) => {
|
161 |
-
|
162 |
logStore.logSystem(`Context optimization ${enabled ? 'enabled' : 'disabled'}`);
|
163 |
-
Cookies.set('contextOptimizationEnabled', String(enabled));
|
164 |
}, []);
|
165 |
|
166 |
const setTheme = useCallback(
|
@@ -191,6 +188,18 @@ export function useSettings(): UseSettingsReturn {
|
|
191 |
[saveSettings],
|
192 |
);
|
193 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
194 |
return {
|
195 |
...settings,
|
196 |
providers,
|
|
|
12 |
tabConfigurationStore,
|
13 |
updateTabConfiguration as updateTabConfig,
|
14 |
resetTabConfiguration as resetTabConfig,
|
15 |
+
updateProviderSettings as updateProviderSettingsStore,
|
16 |
+
updateLatestBranch,
|
17 |
+
updateAutoSelectTemplate,
|
18 |
+
updateContextOptimization,
|
19 |
+
updateEventLogs,
|
20 |
+
updateLocalModels,
|
21 |
+
updatePromptId,
|
22 |
} from '~/lib/stores/settings';
|
23 |
import { useCallback, useEffect, useState } from 'react';
|
24 |
import Cookies from 'js-cookie';
|
|
|
71 |
resetTabConfiguration: () => void;
|
72 |
}
|
73 |
|
74 |
+
// Add interface to match ProviderSetting type
|
75 |
+
interface ProviderSettingWithIndex extends IProviderSetting {
|
76 |
+
[key: string]: any;
|
77 |
+
}
|
78 |
+
|
79 |
export function useSettings(): UseSettingsReturn {
|
80 |
+
const providers = useStore(providersStore);
|
81 |
const debug = useStore(isDebugMode);
|
82 |
const eventLogs = useStore(isEventLogsEnabled);
|
83 |
const promptId = useStore(promptStore);
|
|
|
99 |
};
|
100 |
});
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
useEffect(() => {
|
103 |
let active = Object.entries(providers)
|
104 |
.filter(([_key, provider]) => provider.settings.enabled)
|
|
|
120 |
});
|
121 |
}, []);
|
122 |
|
123 |
+
const updateProviderSettings = useCallback((provider: string, config: ProviderSettingWithIndex) => {
|
124 |
+
updateProviderSettingsStore(provider, config);
|
125 |
}, []);
|
126 |
|
127 |
const enableDebugMode = useCallback((enabled: boolean) => {
|
|
|
131 |
}, []);
|
132 |
|
133 |
const setEventLogs = useCallback((enabled: boolean) => {
|
134 |
+
updateEventLogs(enabled);
|
135 |
logStore.logSystem(`Event logs ${enabled ? 'enabled' : 'disabled'}`);
|
|
|
136 |
}, []);
|
137 |
|
138 |
const enableLocalModels = useCallback((enabled: boolean) => {
|
139 |
+
updateLocalModels(enabled);
|
140 |
logStore.logSystem(`Local models ${enabled ? 'enabled' : 'disabled'}`);
|
|
|
141 |
}, []);
|
142 |
|
143 |
+
const setPromptId = useCallback((id: string) => {
|
144 |
+
updatePromptId(id);
|
145 |
+
logStore.logSystem(`Prompt template updated to ${id}`);
|
146 |
}, []);
|
147 |
|
148 |
const enableLatestBranch = useCallback((enabled: boolean) => {
|
149 |
+
updateLatestBranch(enabled);
|
150 |
logStore.logSystem(`Main branch updates ${enabled ? 'enabled' : 'disabled'}`);
|
|
|
151 |
}, []);
|
152 |
|
153 |
const setAutoSelectTemplate = useCallback((enabled: boolean) => {
|
154 |
+
updateAutoSelectTemplate(enabled);
|
155 |
logStore.logSystem(`Auto select template ${enabled ? 'enabled' : 'disabled'}`);
|
|
|
156 |
}, []);
|
157 |
|
158 |
const enableContextOptimization = useCallback((enabled: boolean) => {
|
159 |
+
updateContextOptimization(enabled);
|
160 |
logStore.logSystem(`Context optimization ${enabled ? 'enabled' : 'disabled'}`);
|
|
|
161 |
}, []);
|
162 |
|
163 |
const setTheme = useCallback(
|
|
|
188 |
[saveSettings],
|
189 |
);
|
190 |
|
191 |
+
// Fix the providers cookie sync
|
192 |
+
useEffect(() => {
|
193 |
+
const providers = providersStore.get();
|
194 |
+
const providerSetting: Record<string, { enabled: boolean }> = {};
|
195 |
+
Object.keys(providers).forEach((provider) => {
|
196 |
+
providerSetting[provider] = {
|
197 |
+
enabled: providers[provider].settings.enabled || false, // Add fallback for undefined
|
198 |
+
};
|
199 |
+
});
|
200 |
+
Cookies.set('providers', JSON.stringify(providerSetting));
|
201 |
+
}, [providers]);
|
202 |
+
|
203 |
return {
|
204 |
...settings,
|
205 |
providers,
|
app/lib/stores/settings.ts
CHANGED
@@ -59,40 +59,142 @@ export const shortcutsStore = map<Shortcuts>({
|
|
59 |
},
|
60 |
});
|
61 |
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
settings: {
|
67 |
-
|
|
|
68 |
},
|
69 |
};
|
70 |
-
});
|
71 |
|
72 |
-
//
|
|
|
73 |
|
74 |
-
|
|
|
|
|
|
|
75 |
|
76 |
export const isDebugMode = atom(false);
|
77 |
|
78 |
-
//
|
79 |
-
const
|
80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
|
82 |
-
//
|
83 |
-
export const
|
|
|
|
|
|
|
84 |
|
85 |
-
|
86 |
-
|
|
|
|
|
87 |
|
88 |
-
|
89 |
-
|
|
|
|
|
90 |
|
91 |
-
|
92 |
-
|
|
|
|
|
93 |
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
|
97 |
// Initialize tab configuration from cookie or default
|
98 |
const savedTabConfig = Cookies.get('tabConfiguration');
|
|
|
59 |
},
|
60 |
});
|
61 |
|
62 |
+
// Create a single key for provider settings
|
63 |
+
const PROVIDER_SETTINGS_KEY = 'provider_settings';
|
64 |
+
|
65 |
+
// Initialize provider settings from both localStorage and defaults
|
66 |
+
const getInitialProviderSettings = (): ProviderSetting => {
|
67 |
+
const savedSettings = localStorage.getItem(PROVIDER_SETTINGS_KEY);
|
68 |
+
const initialSettings: ProviderSetting = {};
|
69 |
+
|
70 |
+
// Start with default settings
|
71 |
+
PROVIDER_LIST.forEach((provider) => {
|
72 |
+
initialSettings[provider.name] = {
|
73 |
+
...provider,
|
74 |
+
settings: {
|
75 |
+
enabled: true,
|
76 |
+
},
|
77 |
+
};
|
78 |
+
});
|
79 |
+
|
80 |
+
// Override with saved settings if they exist
|
81 |
+
if (savedSettings) {
|
82 |
+
try {
|
83 |
+
const parsed = JSON.parse(savedSettings);
|
84 |
+
Object.entries(parsed).forEach(([key, value]) => {
|
85 |
+
if (initialSettings[key]) {
|
86 |
+
initialSettings[key].settings = (value as IProviderConfig).settings;
|
87 |
+
}
|
88 |
+
});
|
89 |
+
} catch (error) {
|
90 |
+
console.error('Error parsing saved provider settings:', error);
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
return initialSettings;
|
95 |
+
};
|
96 |
+
|
97 |
+
export const providersStore = map<ProviderSetting>(getInitialProviderSettings());
|
98 |
+
|
99 |
+
// Create a function to update provider settings that handles both store and persistence
|
100 |
+
export const updateProviderSettings = (provider: string, settings: ProviderSetting) => {
|
101 |
+
const currentSettings = providersStore.get();
|
102 |
+
|
103 |
+
// Create new provider config with updated settings
|
104 |
+
const updatedProvider = {
|
105 |
+
...currentSettings[provider],
|
106 |
settings: {
|
107 |
+
...currentSettings[provider].settings,
|
108 |
+
...settings,
|
109 |
},
|
110 |
};
|
|
|
111 |
|
112 |
+
// Update the store with new settings
|
113 |
+
providersStore.setKey(provider, updatedProvider);
|
114 |
|
115 |
+
// Save to localStorage
|
116 |
+
const allSettings = providersStore.get();
|
117 |
+
localStorage.setItem(PROVIDER_SETTINGS_KEY, JSON.stringify(allSettings));
|
118 |
+
};
|
119 |
|
120 |
export const isDebugMode = atom(false);
|
121 |
|
122 |
+
// Define keys for localStorage
|
123 |
+
const SETTINGS_KEYS = {
|
124 |
+
LATEST_BRANCH: 'isLatestBranch',
|
125 |
+
AUTO_SELECT_TEMPLATE: 'autoSelectTemplate',
|
126 |
+
CONTEXT_OPTIMIZATION: 'contextOptimizationEnabled',
|
127 |
+
EVENT_LOGS: 'isEventLogsEnabled',
|
128 |
+
LOCAL_MODELS: 'isLocalModelsEnabled',
|
129 |
+
PROMPT_ID: 'promptId',
|
130 |
+
} as const;
|
131 |
+
|
132 |
+
// Initialize settings from localStorage or defaults
|
133 |
+
const getInitialSettings = () => {
|
134 |
+
const getStoredBoolean = (key: string, defaultValue: boolean): boolean => {
|
135 |
+
const stored = localStorage.getItem(key);
|
136 |
+
|
137 |
+
if (stored === null) {
|
138 |
+
return defaultValue;
|
139 |
+
}
|
140 |
+
|
141 |
+
try {
|
142 |
+
return JSON.parse(stored);
|
143 |
+
} catch {
|
144 |
+
return defaultValue;
|
145 |
+
}
|
146 |
+
};
|
147 |
+
|
148 |
+
return {
|
149 |
+
latestBranch: getStoredBoolean(SETTINGS_KEYS.LATEST_BRANCH, false),
|
150 |
+
autoSelectTemplate: getStoredBoolean(SETTINGS_KEYS.AUTO_SELECT_TEMPLATE, false),
|
151 |
+
contextOptimization: getStoredBoolean(SETTINGS_KEYS.CONTEXT_OPTIMIZATION, false),
|
152 |
+
eventLogs: getStoredBoolean(SETTINGS_KEYS.EVENT_LOGS, true),
|
153 |
+
localModels: getStoredBoolean(SETTINGS_KEYS.LOCAL_MODELS, true),
|
154 |
+
promptId: localStorage.getItem(SETTINGS_KEYS.PROMPT_ID) || 'default',
|
155 |
+
};
|
156 |
+
};
|
157 |
+
|
158 |
+
// Initialize stores with persisted values
|
159 |
+
const initialSettings = getInitialSettings();
|
160 |
+
|
161 |
+
export const latestBranchStore = atom<boolean>(initialSettings.latestBranch);
|
162 |
+
export const autoSelectStarterTemplate = atom<boolean>(initialSettings.autoSelectTemplate);
|
163 |
+
export const enableContextOptimizationStore = atom<boolean>(initialSettings.contextOptimization);
|
164 |
+
export const isEventLogsEnabled = atom<boolean>(initialSettings.eventLogs);
|
165 |
+
export const isLocalModelsEnabled = atom<boolean>(initialSettings.localModels);
|
166 |
+
export const promptStore = atom<string>(initialSettings.promptId);
|
167 |
|
168 |
+
// Helper functions to update settings with persistence
|
169 |
+
export const updateLatestBranch = (enabled: boolean) => {
|
170 |
+
latestBranchStore.set(enabled);
|
171 |
+
localStorage.setItem(SETTINGS_KEYS.LATEST_BRANCH, JSON.stringify(enabled));
|
172 |
+
};
|
173 |
|
174 |
+
export const updateAutoSelectTemplate = (enabled: boolean) => {
|
175 |
+
autoSelectStarterTemplate.set(enabled);
|
176 |
+
localStorage.setItem(SETTINGS_KEYS.AUTO_SELECT_TEMPLATE, JSON.stringify(enabled));
|
177 |
+
};
|
178 |
|
179 |
+
export const updateContextOptimization = (enabled: boolean) => {
|
180 |
+
enableContextOptimizationStore.set(enabled);
|
181 |
+
localStorage.setItem(SETTINGS_KEYS.CONTEXT_OPTIMIZATION, JSON.stringify(enabled));
|
182 |
+
};
|
183 |
|
184 |
+
export const updateEventLogs = (enabled: boolean) => {
|
185 |
+
isEventLogsEnabled.set(enabled);
|
186 |
+
localStorage.setItem(SETTINGS_KEYS.EVENT_LOGS, JSON.stringify(enabled));
|
187 |
+
};
|
188 |
|
189 |
+
export const updateLocalModels = (enabled: boolean) => {
|
190 |
+
isLocalModelsEnabled.set(enabled);
|
191 |
+
localStorage.setItem(SETTINGS_KEYS.LOCAL_MODELS, JSON.stringify(enabled));
|
192 |
+
};
|
193 |
+
|
194 |
+
export const updatePromptId = (id: string) => {
|
195 |
+
promptStore.set(id);
|
196 |
+
localStorage.setItem(SETTINGS_KEYS.PROMPT_ID, id);
|
197 |
+
};
|
198 |
|
199 |
// Initialize tab configuration from cookie or default
|
200 |
const savedTabConfig = Cookies.get('tabConfiguration');
|
scripts/clean.js.zip
DELETED
Binary file (1.04 kB)
|
|