un wanted ai configs removed
This commit is contained in:
parent
068faad462
commit
b9a8c5bf52
@ -11,10 +11,6 @@ import { toast } from 'sonner';
|
|||||||
|
|
||||||
interface AIConfigData {
|
interface AIConfigData {
|
||||||
aiEnabled: boolean;
|
aiEnabled: boolean;
|
||||||
aiProvider: 'claude' | 'openai' | 'gemini';
|
|
||||||
claudeApiKey: string;
|
|
||||||
openaiApiKey: string;
|
|
||||||
geminiApiKey: string;
|
|
||||||
aiRemarkGeneration: boolean;
|
aiRemarkGeneration: boolean;
|
||||||
maxRemarkChars: number;
|
maxRemarkChars: number;
|
||||||
}
|
}
|
||||||
@ -22,19 +18,10 @@ interface AIConfigData {
|
|||||||
export function AIConfig() {
|
export function AIConfig() {
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
const [showApiKeys, setShowApiKeys] = useState<Record<string, boolean>>({
|
|
||||||
claude: false,
|
|
||||||
openai: false,
|
|
||||||
gemini: false
|
|
||||||
});
|
|
||||||
const [config, setConfig] = useState<AIConfigData>({
|
const [config, setConfig] = useState<AIConfigData>({
|
||||||
aiEnabled: true,
|
aiEnabled: true,
|
||||||
aiProvider: 'claude',
|
|
||||||
claudeApiKey: '',
|
|
||||||
openaiApiKey: '',
|
|
||||||
geminiApiKey: '',
|
|
||||||
aiRemarkGeneration: true,
|
aiRemarkGeneration: true,
|
||||||
maxRemarkChars: 500
|
maxRemarkChars: 2000
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -54,10 +41,6 @@ export function AIConfig() {
|
|||||||
|
|
||||||
setConfig({
|
setConfig({
|
||||||
aiEnabled: configMap['AI_ENABLED'] === 'true',
|
aiEnabled: configMap['AI_ENABLED'] === 'true',
|
||||||
aiProvider: (configMap['AI_PROVIDER'] || 'claude') as 'claude' | 'openai' | 'gemini',
|
|
||||||
claudeApiKey: configMap['CLAUDE_API_KEY'] || '',
|
|
||||||
openaiApiKey: configMap['OPENAI_API_KEY'] || '',
|
|
||||||
geminiApiKey: configMap['GEMINI_API_KEY'] || '',
|
|
||||||
aiRemarkGeneration: configMap['AI_REMARK_GENERATION_ENABLED'] === 'true',
|
aiRemarkGeneration: configMap['AI_REMARK_GENERATION_ENABLED'] === 'true',
|
||||||
maxRemarkChars: parseInt(configMap['AI_MAX_REMARK_LENGTH'] || '2000')
|
maxRemarkChars: parseInt(configMap['AI_MAX_REMARK_LENGTH'] || '2000')
|
||||||
});
|
});
|
||||||
@ -76,10 +59,6 @@ export function AIConfig() {
|
|||||||
// Save all configurations
|
// Save all configurations
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
updateConfiguration('AI_ENABLED', config.aiEnabled.toString()),
|
updateConfiguration('AI_ENABLED', config.aiEnabled.toString()),
|
||||||
updateConfiguration('AI_PROVIDER', config.aiProvider),
|
|
||||||
updateConfiguration('CLAUDE_API_KEY', config.claudeApiKey),
|
|
||||||
updateConfiguration('OPENAI_API_KEY', config.openaiApiKey),
|
|
||||||
updateConfiguration('GEMINI_API_KEY', config.geminiApiKey),
|
|
||||||
updateConfiguration('AI_REMARK_GENERATION_ENABLED', config.aiRemarkGeneration.toString()),
|
updateConfiguration('AI_REMARK_GENERATION_ENABLED', config.aiRemarkGeneration.toString()),
|
||||||
updateConfiguration('AI_MAX_REMARK_LENGTH', config.maxRemarkChars.toString())
|
updateConfiguration('AI_MAX_REMARK_LENGTH', config.maxRemarkChars.toString())
|
||||||
]);
|
]);
|
||||||
@ -100,19 +79,6 @@ export function AIConfig() {
|
|||||||
setConfig(prev => ({ ...prev, ...updates }));
|
setConfig(prev => ({ ...prev, ...updates }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleApiKeyVisibility = (provider: 'claude' | 'openai' | 'gemini') => {
|
|
||||||
setShowApiKeys(prev => ({
|
|
||||||
...prev,
|
|
||||||
[provider]: !prev[provider]
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const maskApiKey = (key: string): string => {
|
|
||||||
if (!key || key.length === 0) return '';
|
|
||||||
if (key.length <= 8) return '••••••••';
|
|
||||||
return key.substring(0, 4) + '••••••••' + key.substring(key.length - 4);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<Card className="shadow-lg border-0 rounded-md">
|
<Card className="shadow-lg border-0 rounded-md">
|
||||||
@ -134,7 +100,7 @@ export function AIConfig() {
|
|||||||
<div>
|
<div>
|
||||||
<CardTitle className="text-lg font-semibold text-gray-900">AI Features Configuration</CardTitle>
|
<CardTitle className="text-lg font-semibold text-gray-900">AI Features Configuration</CardTitle>
|
||||||
<CardDescription className="text-sm text-gray-600">
|
<CardDescription className="text-sm text-gray-600">
|
||||||
Configure AI provider, API keys, and enable/disable AI-powered features
|
Configure Vertex AI Gemini settings and enable/disable AI-powered features
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -142,18 +108,7 @@ export function AIConfig() {
|
|||||||
<CardContent className="space-y-6">
|
<CardContent className="space-y-6">
|
||||||
<AIProviderSettings
|
<AIProviderSettings
|
||||||
aiEnabled={config.aiEnabled}
|
aiEnabled={config.aiEnabled}
|
||||||
aiProvider={config.aiProvider}
|
|
||||||
claudeApiKey={config.claudeApiKey}
|
|
||||||
openaiApiKey={config.openaiApiKey}
|
|
||||||
geminiApiKey={config.geminiApiKey}
|
|
||||||
showApiKeys={showApiKeys}
|
|
||||||
onAiEnabledChange={(enabled) => updateConfig({ aiEnabled: enabled })}
|
onAiEnabledChange={(enabled) => updateConfig({ aiEnabled: enabled })}
|
||||||
onProviderChange={(provider) => updateConfig({ aiProvider: provider })}
|
|
||||||
onClaudeApiKeyChange={(key) => updateConfig({ claudeApiKey: key })}
|
|
||||||
onOpenaiApiKeyChange={(key) => updateConfig({ openaiApiKey: key })}
|
|
||||||
onGeminiApiKeyChange={(key) => updateConfig({ geminiApiKey: key })}
|
|
||||||
onToggleApiKeyVisibility={toggleApiKeyVisibility}
|
|
||||||
maskApiKey={maskApiKey}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Separator />
|
<Separator />
|
||||||
|
|||||||
@ -1,63 +1,25 @@
|
|||||||
import { Label } from '@/components/ui/label';
|
|
||||||
import { Input } from '@/components/ui/input';
|
|
||||||
import { Switch } from '@/components/ui/switch';
|
import { Switch } from '@/components/ui/switch';
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import {
|
import { Brain } from 'lucide-react';
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from '@/components/ui/select';
|
|
||||||
import { Brain, Eye, EyeOff, Key } from 'lucide-react';
|
|
||||||
import { Button } from '@/components/ui/button';
|
|
||||||
|
|
||||||
interface AIProviderSettingsProps {
|
interface AIProviderSettingsProps {
|
||||||
aiEnabled: boolean;
|
aiEnabled: boolean;
|
||||||
aiProvider: 'claude' | 'openai' | 'gemini';
|
|
||||||
claudeApiKey: string;
|
|
||||||
openaiApiKey: string;
|
|
||||||
geminiApiKey: string;
|
|
||||||
showApiKeys: Record<string, boolean>;
|
|
||||||
onAiEnabledChange: (enabled: boolean) => void;
|
onAiEnabledChange: (enabled: boolean) => void;
|
||||||
onProviderChange: (provider: 'claude' | 'openai' | 'gemini') => void;
|
|
||||||
onClaudeApiKeyChange: (key: string) => void;
|
|
||||||
onOpenaiApiKeyChange: (key: string) => void;
|
|
||||||
onGeminiApiKeyChange: (key: string) => void;
|
|
||||||
onToggleApiKeyVisibility: (provider: 'claude' | 'openai' | 'gemini') => void;
|
|
||||||
maskApiKey: (key: string) => string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PROVIDERS = [
|
|
||||||
{ value: 'claude', label: 'Claude (Anthropic)', description: 'Advanced AI by Anthropic' },
|
|
||||||
{ value: 'openai', label: 'OpenAI (GPT-4)', description: 'GPT-4 by OpenAI' },
|
|
||||||
{ value: 'gemini', label: 'Gemini (Google)', description: 'Gemini by Google' }
|
|
||||||
];
|
|
||||||
|
|
||||||
export function AIProviderSettings({
|
export function AIProviderSettings({
|
||||||
aiEnabled,
|
aiEnabled,
|
||||||
aiProvider,
|
onAiEnabledChange
|
||||||
claudeApiKey,
|
|
||||||
openaiApiKey,
|
|
||||||
geminiApiKey,
|
|
||||||
showApiKeys,
|
|
||||||
onAiEnabledChange,
|
|
||||||
onProviderChange,
|
|
||||||
onClaudeApiKeyChange,
|
|
||||||
onOpenaiApiKeyChange,
|
|
||||||
onGeminiApiKeyChange,
|
|
||||||
onToggleApiKeyVisibility,
|
|
||||||
maskApiKey
|
|
||||||
}: AIProviderSettingsProps) {
|
}: AIProviderSettingsProps) {
|
||||||
return (
|
return (
|
||||||
<Card className="border-0 shadow-sm">
|
<Card className="border-0 shadow-sm">
|
||||||
<CardHeader className="pb-3">
|
<CardHeader className="pb-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Brain className="w-5 h-5 text-re-green" />
|
<Brain className="w-5 h-5 text-re-green" />
|
||||||
<CardTitle className="text-base font-semibold">AI Provider & API Keys</CardTitle>
|
<CardTitle className="text-base font-semibold">Vertex AI Gemini Configuration</CardTitle>
|
||||||
</div>
|
</div>
|
||||||
<CardDescription className="text-sm">
|
<CardDescription className="text-sm">
|
||||||
Select your AI provider and configure API keys
|
Configure AI features. Model and region are configured via environment variables.
|
||||||
</CardDescription>
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="space-y-4">
|
<CardContent className="space-y-4">
|
||||||
@ -74,145 +36,7 @@ export function AIProviderSettings({
|
|||||||
onCheckedChange={onAiEnabledChange}
|
onCheckedChange={onAiEnabledChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{aiEnabled && (
|
|
||||||
<>
|
|
||||||
{/* Provider Selection */}
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="ai-provider" className="text-sm font-medium">
|
|
||||||
AI Provider
|
|
||||||
</Label>
|
|
||||||
<Select value={aiProvider} onValueChange={(value: any) => onProviderChange(value)}>
|
|
||||||
<SelectTrigger
|
|
||||||
id="ai-provider"
|
|
||||||
className="border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20"
|
|
||||||
>
|
|
||||||
<SelectValue placeholder="Select AI provider" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
{PROVIDERS.map((provider) => (
|
|
||||||
<SelectItem key={provider.value} value={provider.value}>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<span className="font-medium">{provider.label}</span>
|
|
||||||
<span className="text-xs text-muted-foreground">-</span>
|
|
||||||
<span className="text-xs text-muted-foreground">{provider.description}</span>
|
|
||||||
</div>
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* API Keys for each provider */}
|
|
||||||
<div className="space-y-4 pt-2">
|
|
||||||
<Label className="text-sm font-medium flex items-center gap-2">
|
|
||||||
<Key className="w-4 h-4" />
|
|
||||||
API Keys
|
|
||||||
</Label>
|
|
||||||
|
|
||||||
{/* Claude API Key */}
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="claude-key" className="text-xs text-muted-foreground">
|
|
||||||
Claude API Key
|
|
||||||
</Label>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Input
|
|
||||||
id="claude-key"
|
|
||||||
type={showApiKeys.claude ? 'text' : 'password'}
|
|
||||||
value={claudeApiKey}
|
|
||||||
onChange={(e) => onClaudeApiKeyChange(e.target.value)}
|
|
||||||
placeholder={showApiKeys.claude ? "sk-ant-..." : maskApiKey(claudeApiKey) || "sk-ant-..."}
|
|
||||||
className="border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20 font-mono text-sm"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
variant="outline"
|
|
||||||
size="icon"
|
|
||||||
onClick={() => onToggleApiKeyVisibility('claude')}
|
|
||||||
className="border-gray-200"
|
|
||||||
>
|
|
||||||
{showApiKeys.claude ? (
|
|
||||||
<EyeOff className="w-4 h-4" />
|
|
||||||
) : (
|
|
||||||
<Eye className="w-4 h-4" />
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<p className="text-xs text-muted-foreground">
|
|
||||||
Get your API key from console.anthropic.com
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* OpenAI API Key */}
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="openai-key" className="text-xs text-muted-foreground">
|
|
||||||
OpenAI API Key
|
|
||||||
</Label>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Input
|
|
||||||
id="openai-key"
|
|
||||||
type={showApiKeys.openai ? 'text' : 'password'}
|
|
||||||
value={openaiApiKey}
|
|
||||||
onChange={(e) => onOpenaiApiKeyChange(e.target.value)}
|
|
||||||
placeholder={showApiKeys.openai ? "sk-..." : maskApiKey(openaiApiKey) || "sk-..."}
|
|
||||||
className="border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20 font-mono text-sm"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
variant="outline"
|
|
||||||
size="icon"
|
|
||||||
onClick={() => onToggleApiKeyVisibility('openai')}
|
|
||||||
className="border-gray-200"
|
|
||||||
>
|
|
||||||
{showApiKeys.openai ? (
|
|
||||||
<EyeOff className="w-4 h-4" />
|
|
||||||
) : (
|
|
||||||
<Eye className="w-4 h-4" />
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<p className="text-xs text-muted-foreground">
|
|
||||||
Get your API key from platform.openai.com
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Gemini API Key */}
|
|
||||||
<div className="space-y-2">
|
|
||||||
<Label htmlFor="gemini-key" className="text-xs text-muted-foreground">
|
|
||||||
Gemini API Key
|
|
||||||
</Label>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Input
|
|
||||||
id="gemini-key"
|
|
||||||
type={showApiKeys.gemini ? 'text' : 'password'}
|
|
||||||
value={geminiApiKey}
|
|
||||||
onChange={(e) => onGeminiApiKeyChange(e.target.value)}
|
|
||||||
placeholder={showApiKeys.gemini ? "AIza..." : maskApiKey(geminiApiKey) || "AIza..."}
|
|
||||||
className="border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20 font-mono text-sm"
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
variant="outline"
|
|
||||||
size="icon"
|
|
||||||
onClick={() => onToggleApiKeyVisibility('gemini')}
|
|
||||||
className="border-gray-200"
|
|
||||||
>
|
|
||||||
{showApiKeys.gemini ? (
|
|
||||||
<EyeOff className="w-4 h-4" />
|
|
||||||
) : (
|
|
||||||
<Eye className="w-4 h-4" />
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<p className="text-xs text-muted-foreground">
|
|
||||||
Get your API key from ai.google.dev
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user