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)
|
|
|