Bug Fixes part1
This commit is contained in:
@@ -311,6 +311,24 @@ export default function ConnectionsTab() {
|
||||
'disabled:opacity-50',
|
||||
)}
|
||||
/>
|
||||
<div className="mt-2 text-sm text-bolt-elements-textSecondary">
|
||||
<a
|
||||
href={`https://github.com/settings/tokens${connection.tokenType === 'fine-grained' ? '/beta' : '/new'}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-purple-500 hover:underline inline-flex items-center gap-1"
|
||||
>
|
||||
Get your token
|
||||
<div className="i-ph:arrow-square-out w-10 h-5" />
|
||||
</a>
|
||||
<span className="mx-2">•</span>
|
||||
<span>
|
||||
Required scopes:{' '}
|
||||
{connection.tokenType === 'classic'
|
||||
? 'repo, read:org, read:user'
|
||||
: 'Repository access, Organization access'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,19 +1,11 @@
|
||||
import React, { memo, useEffect, useState } from 'react';
|
||||
// Remove unused imports
|
||||
import React, { memo, useCallback } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { Switch } from '~/components/ui/Switch';
|
||||
import { useSettings } from '~/lib/hooks/useSettings';
|
||||
import { classNames } from '~/utils/classNames';
|
||||
import { toast } from 'react-toastify';
|
||||
import { PromptLibrary } from '~/lib/common/prompt-library';
|
||||
import {
|
||||
latestBranchStore,
|
||||
autoSelectStarterTemplate,
|
||||
enableContextOptimizationStore,
|
||||
isLocalModelsEnabled,
|
||||
isEventLogsEnabled,
|
||||
promptStore as promptAtom,
|
||||
} from '~/lib/stores/settings';
|
||||
import { logStore } from '~/lib/stores/logs';
|
||||
|
||||
interface FeatureToggle {
|
||||
id: string;
|
||||
@@ -114,133 +106,85 @@ const FeatureSection = memo(
|
||||
);
|
||||
|
||||
export default function FeaturesTab() {
|
||||
const { autoSelectTemplate, isLatestBranch, contextOptimizationEnabled, eventLogs, isLocalModel } = useSettings();
|
||||
const {
|
||||
autoSelectTemplate,
|
||||
isLatestBranch,
|
||||
contextOptimizationEnabled,
|
||||
eventLogs,
|
||||
isLocalModel,
|
||||
setAutoSelectTemplate,
|
||||
enableLatestBranch,
|
||||
enableContextOptimization,
|
||||
setEventLogs,
|
||||
enableLocalModels,
|
||||
setPromptId,
|
||||
promptId,
|
||||
} = useSettings();
|
||||
|
||||
const getLocalStorageBoolean = (key: string, defaultValue: boolean): boolean => {
|
||||
const value = localStorage.getItem(key);
|
||||
const handleToggleFeature = useCallback(
|
||||
(id: string, enabled: boolean) => {
|
||||
switch (id) {
|
||||
case 'latestBranch':
|
||||
enableLatestBranch(enabled);
|
||||
toast.success(`Main branch updates ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
case 'autoSelectTemplate':
|
||||
setAutoSelectTemplate(enabled);
|
||||
toast.success(`Auto select template ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
case 'contextOptimization':
|
||||
enableContextOptimization(enabled);
|
||||
toast.success(`Context optimization ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
case 'eventLogs':
|
||||
setEventLogs(enabled);
|
||||
toast.success(`Event logging ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
case 'localModels':
|
||||
enableLocalModels(enabled);
|
||||
toast.success(`Experimental providers ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
[enableLatestBranch, setAutoSelectTemplate, enableContextOptimization, setEventLogs, enableLocalModels],
|
||||
);
|
||||
|
||||
if (value === null) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
} catch {
|
||||
return defaultValue;
|
||||
}
|
||||
};
|
||||
|
||||
const autoSelectTemplateState = getLocalStorageBoolean('autoSelectTemplate', autoSelectTemplate);
|
||||
const enableLatestBranchState = getLocalStorageBoolean('enableLatestBranch', isLatestBranch);
|
||||
const contextOptimizationState = getLocalStorageBoolean('contextOptimization', contextOptimizationEnabled);
|
||||
const eventLogsState = getLocalStorageBoolean('eventLogs', eventLogs);
|
||||
const experimentalProvidersState = getLocalStorageBoolean('experimentalProviders', isLocalModel);
|
||||
const promptLibraryState = getLocalStorageBoolean('promptLibrary', false);
|
||||
const promptIdState = localStorage.getItem('promptId') ?? '';
|
||||
|
||||
const [autoSelectTemplateLocal, setAutoSelectTemplateLocal] = useState(autoSelectTemplateState);
|
||||
const [enableLatestBranchLocal, setEnableLatestBranchLocal] = useState(enableLatestBranchState);
|
||||
const [contextOptimizationLocal, setContextOptimizationLocal] = useState(contextOptimizationState);
|
||||
const [eventLogsLocal, setEventLogsLocal] = useState(eventLogsState);
|
||||
const [experimentalProvidersLocal, setExperimentalProvidersLocal] = useState(experimentalProvidersState);
|
||||
const [promptLibraryLocal, setPromptLibraryLocal] = useState(promptLibraryState);
|
||||
const [promptIdLocal, setPromptIdLocal] = useState(promptIdState);
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem('autoSelectTemplate', JSON.stringify(autoSelectTemplateLocal));
|
||||
localStorage.setItem('enableLatestBranch', JSON.stringify(enableLatestBranchLocal));
|
||||
localStorage.setItem('contextOptimization', JSON.stringify(contextOptimizationLocal));
|
||||
localStorage.setItem('eventLogs', JSON.stringify(eventLogsLocal));
|
||||
localStorage.setItem('experimentalProviders', JSON.stringify(experimentalProvidersLocal));
|
||||
localStorage.setItem('promptLibrary', JSON.stringify(promptLibraryLocal));
|
||||
localStorage.setItem('promptId', promptIdLocal);
|
||||
|
||||
autoSelectStarterTemplate.set(autoSelectTemplateLocal);
|
||||
latestBranchStore.set(enableLatestBranchLocal);
|
||||
enableContextOptimizationStore.set(contextOptimizationLocal);
|
||||
isEventLogsEnabled.set(eventLogsLocal);
|
||||
isLocalModelsEnabled.set(experimentalProvidersLocal);
|
||||
promptAtom.set(promptIdLocal);
|
||||
}, [
|
||||
autoSelectTemplateLocal,
|
||||
enableLatestBranchLocal,
|
||||
contextOptimizationLocal,
|
||||
eventLogsLocal,
|
||||
experimentalProvidersLocal,
|
||||
promptLibraryLocal,
|
||||
promptIdLocal,
|
||||
]);
|
||||
|
||||
const handleToggleFeature = (featureId: string, enabled: boolean) => {
|
||||
logStore.logFeatureToggle(featureId, enabled);
|
||||
|
||||
switch (featureId) {
|
||||
case 'latestBranch':
|
||||
setEnableLatestBranchLocal(enabled);
|
||||
latestBranchStore.set(enabled);
|
||||
toast.success(`Main branch updates ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
case 'autoSelectTemplate':
|
||||
setAutoSelectTemplateLocal(enabled);
|
||||
autoSelectStarterTemplate.set(enabled);
|
||||
toast.success(`Auto template selection ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
case 'contextOptimization':
|
||||
setContextOptimizationLocal(enabled);
|
||||
enableContextOptimizationStore.set(enabled);
|
||||
toast.success(`Context optimization ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
case 'localModels':
|
||||
setExperimentalProvidersLocal(enabled);
|
||||
isLocalModelsEnabled.set(enabled);
|
||||
toast.success(`Experimental providers ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
case 'eventLogs':
|
||||
setEventLogsLocal(enabled);
|
||||
isEventLogsEnabled.set(enabled);
|
||||
toast.success(`Event logging ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
case 'promptLibrary':
|
||||
setPromptLibraryLocal(enabled);
|
||||
toast.success(`Prompt Library ${enabled ? 'enabled' : 'disabled'}`);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const features: Record<'stable' | 'beta' | 'experimental', FeatureToggle[]> = {
|
||||
const features = {
|
||||
stable: [
|
||||
{
|
||||
id: 'latestBranch',
|
||||
title: 'Main Branch Updates',
|
||||
description: 'Get the latest updates from the main branch',
|
||||
icon: 'i-ph:git-branch',
|
||||
enabled: isLatestBranch,
|
||||
tooltip: 'Enable to receive updates from the main development branch',
|
||||
},
|
||||
{
|
||||
id: 'autoSelectTemplate',
|
||||
title: 'Auto Select Code Template',
|
||||
description: 'Let Bolt select the best starter template for your project',
|
||||
icon: 'i-ph:magic-wand',
|
||||
enabled: autoSelectTemplateLocal,
|
||||
tooltip: 'Automatically choose the most suitable template based on your project type',
|
||||
title: 'Auto Select Template',
|
||||
description: 'Automatically select starter template',
|
||||
icon: 'i-ph:selection',
|
||||
enabled: autoSelectTemplate,
|
||||
tooltip: 'Automatically select the most appropriate starter template',
|
||||
},
|
||||
{
|
||||
id: 'contextOptimization',
|
||||
title: 'Context Optimization',
|
||||
description: 'Optimize chat context by redacting file contents and using system prompts',
|
||||
icon: 'i-ph:arrows-in',
|
||||
enabled: contextOptimizationLocal,
|
||||
tooltip: 'Improve AI responses by optimizing the context window and system prompts',
|
||||
description: 'Optimize context for better responses',
|
||||
icon: 'i-ph:brain',
|
||||
enabled: contextOptimizationEnabled,
|
||||
tooltip: 'Enable context optimization for improved AI responses',
|
||||
},
|
||||
{
|
||||
id: 'eventLogs',
|
||||
title: 'Event Logging',
|
||||
description: 'Enable detailed event logging and history',
|
||||
icon: 'i-ph:list-bullets',
|
||||
enabled: eventLogsLocal,
|
||||
enabled: eventLogs,
|
||||
tooltip: 'Record detailed logs of system events and user actions',
|
||||
},
|
||||
{
|
||||
id: 'promptLibrary',
|
||||
title: 'Prompt Library',
|
||||
description: 'Manage your prompt library settings',
|
||||
icon: 'i-ph:library',
|
||||
enabled: promptLibraryLocal,
|
||||
tooltip: 'Enable or disable the prompt library',
|
||||
},
|
||||
],
|
||||
beta: [],
|
||||
experimental: [
|
||||
@@ -249,7 +193,7 @@ export default function FeaturesTab() {
|
||||
title: 'Experimental Providers',
|
||||
description: 'Enable experimental providers like Ollama, LMStudio, and OpenAILike',
|
||||
icon: 'i-ph:robot',
|
||||
enabled: experimentalProvidersLocal,
|
||||
enabled: isLocalModel,
|
||||
experimental: true,
|
||||
tooltip: 'Try out new AI providers and models in development',
|
||||
},
|
||||
@@ -319,9 +263,9 @@ export default function FeaturesTab() {
|
||||
</p>
|
||||
</div>
|
||||
<select
|
||||
value={promptIdLocal}
|
||||
value={promptId}
|
||||
onChange={(e) => {
|
||||
setPromptIdLocal(e.target.value);
|
||||
setPromptId(e.target.value);
|
||||
toast.success('Prompt template updated');
|
||||
}}
|
||||
className={classNames(
|
||||
|
||||
@@ -62,74 +62,73 @@ const CloudProvidersTab = () => {
|
||||
const [filteredProviders, setFilteredProviders] = useState<IProviderConfig[]>([]);
|
||||
const [categoryEnabled, setCategoryEnabled] = useState<boolean>(false);
|
||||
|
||||
// Effect to filter and sort providers
|
||||
// Load and filter providers
|
||||
useEffect(() => {
|
||||
const newFilteredProviders = Object.entries(settings.providers || {})
|
||||
.filter(([key]) => !['Ollama', 'LMStudio', 'OpenAILike'].includes(key)) // Filter out local providers
|
||||
.map(([key, value]) => {
|
||||
const provider = value as IProviderConfig;
|
||||
return {
|
||||
name: key,
|
||||
settings: provider.settings,
|
||||
staticModels: provider.staticModels || [],
|
||||
getDynamicModels: provider.getDynamicModels,
|
||||
getApiKeyLink: provider.getApiKeyLink,
|
||||
labelForGetApiKey: provider.labelForGetApiKey,
|
||||
icon: provider.icon,
|
||||
} as IProviderConfig;
|
||||
});
|
||||
.filter(([key]) => !['Ollama', 'LMStudio', 'OpenAILike'].includes(key))
|
||||
.map(([key, value]) => ({
|
||||
name: key,
|
||||
settings: value.settings,
|
||||
staticModels: value.staticModels || [],
|
||||
getDynamicModels: value.getDynamicModels,
|
||||
getApiKeyLink: value.getApiKeyLink,
|
||||
labelForGetApiKey: value.labelForGetApiKey,
|
||||
icon: value.icon,
|
||||
}));
|
||||
|
||||
const sorted = newFilteredProviders.sort((a, b) => a.name.localeCompare(b.name));
|
||||
const regular = sorted.filter((p) => !URL_CONFIGURABLE_PROVIDERS.includes(p.name));
|
||||
const urlConfigurable = sorted.filter((p) => URL_CONFIGURABLE_PROVIDERS.includes(p.name));
|
||||
setFilteredProviders(sorted);
|
||||
|
||||
setFilteredProviders([...regular, ...urlConfigurable]);
|
||||
// Update category enabled state
|
||||
const allEnabled = newFilteredProviders.every((p) => p.settings.enabled);
|
||||
setCategoryEnabled(allEnabled);
|
||||
}, [settings.providers]);
|
||||
|
||||
// Add effect to update category toggle state based on provider states
|
||||
useEffect(() => {
|
||||
const newCategoryState = filteredProviders.every((p) => p.settings.enabled);
|
||||
setCategoryEnabled(newCategoryState);
|
||||
}, [filteredProviders]);
|
||||
|
||||
const handleToggleCategory = useCallback(
|
||||
(enabled: boolean) => {
|
||||
setCategoryEnabled(enabled);
|
||||
// Update all providers
|
||||
filteredProviders.forEach((provider) => {
|
||||
settings.updateProviderSettings(provider.name, { ...provider.settings, enabled });
|
||||
});
|
||||
|
||||
setCategoryEnabled(enabled);
|
||||
toast.success(enabled ? 'All cloud providers enabled' : 'All cloud providers disabled');
|
||||
},
|
||||
[filteredProviders, settings],
|
||||
);
|
||||
|
||||
const handleToggleProvider = (provider: IProviderConfig, enabled: boolean) => {
|
||||
settings.updateProviderSettings(provider.name, { ...provider.settings, enabled });
|
||||
const handleToggleProvider = useCallback(
|
||||
(provider: IProviderConfig, enabled: boolean) => {
|
||||
// Update the provider settings in the store
|
||||
settings.updateProviderSettings(provider.name, { ...provider.settings, enabled });
|
||||
|
||||
if (enabled) {
|
||||
logStore.logProvider(`Provider ${provider.name} enabled`, { provider: provider.name });
|
||||
toast.success(`${provider.name} enabled`);
|
||||
} else {
|
||||
logStore.logProvider(`Provider ${provider.name} disabled`, { provider: provider.name });
|
||||
toast.success(`${provider.name} disabled`);
|
||||
}
|
||||
};
|
||||
if (enabled) {
|
||||
logStore.logProvider(`Provider ${provider.name} enabled`, { provider: provider.name });
|
||||
toast.success(`${provider.name} enabled`);
|
||||
} else {
|
||||
logStore.logProvider(`Provider ${provider.name} disabled`, { provider: provider.name });
|
||||
toast.success(`${provider.name} disabled`);
|
||||
}
|
||||
},
|
||||
[settings],
|
||||
);
|
||||
|
||||
const handleUpdateBaseUrl = (provider: IProviderConfig, baseUrl: string) => {
|
||||
let newBaseUrl: string | undefined = baseUrl;
|
||||
const handleUpdateBaseUrl = useCallback(
|
||||
(provider: IProviderConfig, baseUrl: string) => {
|
||||
const newBaseUrl: string | undefined = baseUrl.trim() || undefined;
|
||||
|
||||
if (newBaseUrl && newBaseUrl.trim().length === 0) {
|
||||
newBaseUrl = undefined;
|
||||
}
|
||||
// Update the provider settings in the store
|
||||
settings.updateProviderSettings(provider.name, { ...provider.settings, baseUrl: newBaseUrl });
|
||||
|
||||
settings.updateProviderSettings(provider.name, { ...provider.settings, baseUrl: newBaseUrl });
|
||||
logStore.logProvider(`Base URL updated for ${provider.name}`, {
|
||||
provider: provider.name,
|
||||
baseUrl: newBaseUrl,
|
||||
});
|
||||
toast.success(`${provider.name} base URL updated`);
|
||||
setEditingProvider(null);
|
||||
};
|
||||
logStore.logProvider(`Base URL updated for ${provider.name}`, {
|
||||
provider: provider.name,
|
||||
baseUrl: newBaseUrl,
|
||||
});
|
||||
toast.success(`${provider.name} base URL updated`);
|
||||
setEditingProvider(null);
|
||||
},
|
||||
[settings],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
|
||||
Reference in New Issue
Block a user