feat: OpenRouter entegrasyonu — tek anahtarla tüm modeller, latest alias'lar
- server/ai.mjs: OpenRouter öncelikli yönlendirme (routeFor). OPENROUTER_API_KEY
tanımlıysa zincirdeki tüm modeller OpenRouter üzerinden çağrılır; doğrudan
sağlayıcı anahtarı varsa o ezer
- Tüm modeller OpenRouter floating 'latest' alias'larına çevrildi (sabit sürüm
yerine otomatik güncel kalır):
~z-ai/glm-latest · ~deepseek/deepseek-v4-flash-latest
~google/gemini-flash-latest · ~x-ai/grok-latest
openai/gpt-chat-latest · ~anthropic/claude-opus-latest
- /api/ai/config artık her model için kullanılan yolu (openrouter|direct) döner
- AI Model Ayarları: canlı durum bandı (aktif modeller + yol) ve OpenRouter
kurulum yönergesi; eski 'alias' alanı gerçek OpenRouter kimliğiyle değişti
- Analiz modali: tek OPENROUTER_API_KEY önerisi
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useApp } from '../../context/AppContext';
|
||||
import { Cpu, Check, ArrowUp, ArrowDown, X, Plus, Sparkles, Save, Shield } from 'lucide-react';
|
||||
import { Cpu, Check, ArrowUp, ArrowDown, X, Plus, Sparkles, Save, Shield, Zap, AlertTriangle } from 'lucide-react';
|
||||
import { getAiConfig } from '../../services/ai';
|
||||
import confetti from 'canvas-confetti';
|
||||
|
||||
const RENK = {
|
||||
@@ -17,6 +18,10 @@ const SIRA_ETIKET = ['Birincil (Primary)', '2. Yedek (Fallback)', '3. Yedek (Fal
|
||||
export const AiModelSettings = () => {
|
||||
const { AI_MODEL_CATALOG, aiModelConfig, setAiModelConfig, getModelById } = useApp();
|
||||
const [saved, setSaved] = useState(false);
|
||||
const [cfg, setCfg] = useState(null);
|
||||
|
||||
useEffect(() => { getAiConfig().then(setCfg); }, []);
|
||||
const aktifYol = cfg?.providers?.[0]?.yol;
|
||||
|
||||
const chain = aiModelConfig.chain;
|
||||
const available = AI_MODEL_CATALOG.filter(m => !chain.includes(m.id));
|
||||
@@ -58,6 +63,30 @@ export const AiModelSettings = () => {
|
||||
|
||||
return (
|
||||
<div className="space-y-6 animate-fade-in">
|
||||
{/* Canlı AI durumu */}
|
||||
{cfg && (
|
||||
cfg.configured ? (
|
||||
<div className="bg-emerald-50 border border-emerald-200 rounded-xl p-4 flex gap-3">
|
||||
<Zap className="w-4 h-4 text-emerald-700 shrink-0 mt-0.5" />
|
||||
<div className="text-xs text-emerald-900 leading-relaxed">
|
||||
<strong>AI aktif</strong> — {cfg.providers.length} model kullanılabilir
|
||||
{aktifYol === 'openrouter' ? ' (OpenRouter üzerinden tek anahtarla)' : ' (doğrudan sağlayıcı anahtarlarıyla)'}.
|
||||
<div className="font-mono text-[11px] mt-1 text-emerald-800">
|
||||
{cfg.providers.map((p) => `${p.label}: ${p.model}`).join(' · ')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="bg-amber-50 border border-amber-200 rounded-xl p-4 flex gap-3">
|
||||
<AlertTriangle className="w-4 h-4 text-amber-700 shrink-0 mt-0.5" />
|
||||
<p className="text-xs text-amber-900 leading-relaxed">
|
||||
<strong>AI anahtarı yok.</strong> Sunucuya tek bir <code className="bg-amber-100 px-1 rounded">OPENROUTER_API_KEY</code> ekleyin —
|
||||
aşağıdaki tüm modeller bu tek anahtarla çalışır. Aşağıdaki sıralama yalnızca tercih kaydeder;
|
||||
çağrılar anahtar eklendiğinde başlar.
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
{/* Header */}
|
||||
<div className="bg-linear-to-r from-slate-900 via-indigo-950 to-blue-900 text-white p-6 rounded-2xl shadow-lg border border-indigo-800/40 flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
@@ -117,7 +146,10 @@ export const AiModelSettings = () => {
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-[11px] text-slate-500 font-mono mt-1">{m.alias} <span className="text-slate-400">→</span> <span className="text-slate-700 font-semibold">{m.model}</span></div>
|
||||
<div className="text-[11px] text-slate-500 font-mono mt-1">
|
||||
<span className="text-slate-700 font-semibold">{m.or}</span>
|
||||
<span className="text-slate-400"> · doğrudan: </span>{m.model}
|
||||
</div>
|
||||
<div className="text-[10px] text-slate-400 mt-0.5">{SIRA_ETIKET[idx] || `${idx + 1}. sırada`}</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user