Stijnus commited on
Commit
af620d0
·
1 Parent(s): 5791daf

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
- import React, { memo, useEffect, useState } from 'react';
 
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 { autoSelectTemplate, isLatestBranch, contextOptimizationEnabled, eventLogs, isLocalModel } = useSettings();
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
- const getLocalStorageBoolean = (key: string, defaultValue: boolean): boolean => {
120
- const value = localStorage.getItem(key);
121
-
122
- if (value === null) {
123
- return defaultValue;
124
- }
125
-
126
- try {
127
- return JSON.parse(value);
128
- } catch {
129
- return defaultValue;
130
- }
131
- };
132
-
133
- const autoSelectTemplateState = getLocalStorageBoolean('autoSelectTemplate', autoSelectTemplate);
134
- const enableLatestBranchState = getLocalStorageBoolean('enableLatestBranch', isLatestBranch);
135
- const contextOptimizationState = getLocalStorageBoolean('contextOptimization', contextOptimizationEnabled);
136
- const eventLogsState = getLocalStorageBoolean('eventLogs', eventLogs);
137
- const experimentalProvidersState = getLocalStorageBoolean('experimentalProviders', isLocalModel);
138
- const promptLibraryState = getLocalStorageBoolean('promptLibrary', false);
139
- const promptIdState = localStorage.getItem('promptId') ?? '';
140
-
141
- const [autoSelectTemplateLocal, setAutoSelectTemplateLocal] = useState(autoSelectTemplateState);
142
- const [enableLatestBranchLocal, setEnableLatestBranchLocal] = useState(enableLatestBranchState);
143
- const [contextOptimizationLocal, setContextOptimizationLocal] = useState(contextOptimizationState);
144
- const [eventLogsLocal, setEventLogsLocal] = useState(eventLogsState);
145
- const [experimentalProvidersLocal, setExperimentalProvidersLocal] = useState(experimentalProvidersState);
146
- const [promptLibraryLocal, setPromptLibraryLocal] = useState(promptLibraryState);
147
- const [promptIdLocal, setPromptIdLocal] = useState(promptIdState);
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: Record<'stable' | 'beta' | 'experimental', FeatureToggle[]> = {
211
  stable: [
 
 
 
 
 
 
 
 
212
  {
213
  id: 'autoSelectTemplate',
214
- title: 'Auto Select Code Template',
215
- description: 'Let Bolt select the best starter template for your project',
216
- icon: 'i-ph:magic-wand',
217
- enabled: autoSelectTemplateLocal,
218
- tooltip: 'Automatically choose the most suitable template based on your project type',
219
  },
220
  {
221
  id: 'contextOptimization',
222
  title: 'Context Optimization',
223
- description: 'Optimize chat context by redacting file contents and using system prompts',
224
- icon: 'i-ph:arrows-in',
225
- enabled: contextOptimizationLocal,
226
- tooltip: 'Improve AI responses by optimizing the context window and system prompts',
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: eventLogsLocal,
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: experimentalProvidersLocal,
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={promptIdLocal}
323
  onChange={(e) => {
324
- setPromptIdLocal(e.target.value);
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
- // Effect to filter and sort providers
66
  useEffect(() => {
67
  const newFilteredProviders = Object.entries(settings.providers || {})
68
- .filter(([key]) => !['Ollama', 'LMStudio', 'OpenAILike'].includes(key)) // Filter out local providers
69
- .map(([key, value]) => {
70
- const provider = value as IProviderConfig;
71
- return {
72
- name: key,
73
- settings: provider.settings,
74
- staticModels: provider.staticModels || [],
75
- getDynamicModels: provider.getDynamicModels,
76
- getApiKeyLink: provider.getApiKeyLink,
77
- labelForGetApiKey: provider.labelForGetApiKey,
78
- icon: provider.icon,
79
- } as IProviderConfig;
80
- });
81
 
82
  const sorted = newFilteredProviders.sort((a, b) => a.name.localeCompare(b.name));
83
- const regular = sorted.filter((p) => !URL_CONFIGURABLE_PROVIDERS.includes(p.name));
84
- const urlConfigurable = sorted.filter((p) => URL_CONFIGURABLE_PROVIDERS.includes(p.name));
85
 
86
- setFilteredProviders([...regular, ...urlConfigurable]);
 
 
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
- setCategoryEnabled(enabled);
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 = (provider: IProviderConfig, enabled: boolean) => {
107
- settings.updateProviderSettings(provider.name, { ...provider.settings, enabled });
 
 
108
 
109
- if (enabled) {
110
- logStore.logProvider(`Provider ${provider.name} enabled`, { provider: provider.name });
111
- toast.success(`${provider.name} enabled`);
112
- } else {
113
- logStore.logProvider(`Provider ${provider.name} disabled`, { provider: provider.name });
114
- toast.success(`${provider.name} disabled`);
115
- }
116
- };
 
 
117
 
118
- const handleUpdateBaseUrl = (provider: IProviderConfig, baseUrl: string) => {
119
- let newBaseUrl: string | undefined = baseUrl;
 
120
 
121
- if (newBaseUrl && newBaseUrl.trim().length === 0) {
122
- newBaseUrl = undefined;
123
- }
124
 
125
- settings.updateProviderSettings(provider.name, { ...provider.settings, baseUrl: newBaseUrl });
126
- logStore.logProvider(`Base URL updated for ${provider.name}`, {
127
- provider: provider.name,
128
- baseUrl: newBaseUrl,
129
- });
130
- toast.success(`${provider.name} base URL updated`);
131
- setEditingProvider(null);
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) as Record<string, IProviderConfig>;
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: IProviderSetting) => {
122
- providersStore.setKey(provider, { settings: config } as IProviderConfig);
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
- isEventLogsEnabled.set(enabled);
133
  logStore.logSystem(`Event logs ${enabled ? 'enabled' : 'disabled'}`);
134
- Cookies.set('isEventLogsEnabled', String(enabled));
135
  }, []);
136
 
137
  const enableLocalModels = useCallback((enabled: boolean) => {
138
- isLocalModelsEnabled.set(enabled);
139
  logStore.logSystem(`Local models ${enabled ? 'enabled' : 'disabled'}`);
140
- Cookies.set('isLocalModelsEnabled', String(enabled));
141
  }, []);
142
 
143
- const setPromptId = useCallback((promptId: string) => {
144
- promptStore.set(promptId);
145
- Cookies.set('promptId', promptId);
146
  }, []);
147
 
148
  const enableLatestBranch = useCallback((enabled: boolean) => {
149
- latestBranchStore.set(enabled);
150
  logStore.logSystem(`Main branch updates ${enabled ? 'enabled' : 'disabled'}`);
151
- Cookies.set('isLatestBranch', String(enabled));
152
  }, []);
153
 
154
  const setAutoSelectTemplate = useCallback((enabled: boolean) => {
155
- autoSelectStarterTemplate.set(enabled);
156
  logStore.logSystem(`Auto select template ${enabled ? 'enabled' : 'disabled'}`);
157
- Cookies.set('autoSelectTemplate', String(enabled));
158
  }, []);
159
 
160
  const enableContextOptimization = useCallback((enabled: boolean) => {
161
- enableContextOptimizationStore.set(enabled);
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
- const initialProviderSettings: ProviderSetting = {};
63
- PROVIDER_LIST.forEach((provider) => {
64
- initialProviderSettings[provider.name] = {
65
- ...provider,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  settings: {
67
- enabled: true,
 
68
  },
69
  };
70
- });
71
 
72
- //TODO: need to create one single map for all these flags
 
73
 
74
- export const providersStore = map<ProviderSetting>(initialProviderSettings);
 
 
 
75
 
76
  export const isDebugMode = atom(false);
77
 
78
- // Initialize event logs from cookie or default to false
79
- const savedEventLogs = Cookies.get('isEventLogsEnabled');
80
- export const isEventLogsEnabled = atom(savedEventLogs === 'true');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
- // Local models settings
83
- export const isLocalModelsEnabled = atom(true);
 
 
 
84
 
85
- // Prompt settings
86
- export const promptStore = atom<string>('default');
 
 
87
 
88
- // Branch settings
89
- export const latestBranchStore = atom(false);
 
 
90
 
91
- // Template settings
92
- export const autoSelectStarterTemplate = atom(false);
 
 
93
 
94
- // Context optimization settings
95
- export const enableContextOptimizationStore = atom(false);
 
 
 
 
 
 
 
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)