From 782b361d24d8f367ce4ad083b79d7f6ff9fd8e61 Mon Sep 17 00:00:00 2001 From: ht Date: Sat, 5 Sep 2026 13:45:04 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20Gemini=20Flash=20=C3=BCcretli=20yedek?= =?UTF-8?q?=20=E2=80=94=20analiz=20zincirinin=20sonunda=20her=20zaman=20de?= =?UTF-8?q?nenir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Panelde seçilen modeller tıkanınca (limit/429) şartname analizi ve teklif asistanı boş kalıyordu; analyzeSpec zincire yoksa 'gemini'yi sona ekler. Panel ve kılavuz notu. Co-Authored-By: Claude Fable 5.1 --- server/ai.mjs | 7 ++++++- src/components/KullanimKilavuzu.jsx | 2 +- src/components/tools/AiModelSettings.jsx | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/server/ai.mjs b/server/ai.mjs index db194d6..f706d1f 100644 --- a/server/ai.mjs +++ b/server/ai.mjs @@ -314,8 +314,13 @@ function kesikJsonOnar(s) { /** Zinciri sırayla dener; ilk başarılı sonucu döndürür. */ export async function analyzeSpec({ text, fileName, tender, chain, systemOverride, mode }) { const derin = mode === 'derin'; - const order = (Array.isArray(chain) && chain.length ? chain : ['glmflash', 'gemini', 'deepseek', 'grok', 'gpt', 'claude']) + // Ücretli yedek: Gemini Flash her zaman zincirin sonunda. Panelde seçilen + // modeller (ör. ücretsiz/limitli olanlar) tıkanınca analiz boş kalmasın; + // yalnız üsttekilerin hepsi başarısız olursa devreye girer. + const YEDEK = 'gemini'; + const secim = (Array.isArray(chain) && chain.length ? chain : ['glmflash', 'gemini', 'deepseek', 'grok', 'gpt', 'claude']) .filter((id) => PROVIDERS[id]); + const order = secim.includes(YEDEK) ? secim : [...secim, YEDEK]; // Derin analiz hem daha çok metin okur hem daha uzun JSON üretir; çıktı // kesilirse JSON parse edilemez ve zincir boşuna tüketilir. const userPrompt = buildUserPrompt({ text, fileName, tender, limit: derin ? 90000 : 60000 }); diff --git a/src/components/KullanimKilavuzu.jsx b/src/components/KullanimKilavuzu.jsx index 985d112..4de61ee 100644 --- a/src/components/KullanimKilavuzu.jsx +++ b/src/components/KullanimKilavuzu.jsx @@ -58,7 +58,7 @@ const KILAVUZ = { api_webhooks: { baslik: 'API & Webhooks', ne: 'Kendi sistemlerinize ihale akışı.', adimlar: [ 'MCP: bir API anahtarı üretin, karttaki Claude Code komutunu veya mcp.json\'u kopyalayıp anahtarı yerine yazın; asistanınız search_tenders, get_tender, search_results, search_items, upcoming_deadlines araçlarını kullanır.', 'RSS: /api/feeds/tenders.rss?key=… adresini (il, sektor, q filtreleri) Feedly / Outlook / Slack RSS\'e ekleyin; sonuç ilanları için /api/feeds/sonuc.rss anahtarsızdır.','API anahtarı üretin; webhook adresinize yeni ihaleler gönderilir.'], ipuclari: [] }, - ai_ayarlari: { baslik: 'AI Model Ayarları', ne: 'Analizlerde kullanılacak model zinciri (yedekli).', adimlar: ['Sırayı sürükleyerek değiştirin; ilk başarılı model sonucu döner.'], ipuclari: [] }, + ai_ayarlari: { baslik: 'AI Model Ayarları', ne: 'Analizlerde kullanılacak model zinciri (yedekli).', adimlar: ['Sırayı sürükleyerek değiştirin; ilk başarılı model sonucu döner.', 'Gemini Flash ücretli yedek olarak zincirin sonunda her zaman denenir; seçtiğiniz modeller (ör. limitli/ücretsiz olanlar) tıkanınca analiz boş kalmaz.'], ipuclari: [] }, pwa_settings: { baslik: 'Mobil PWA & Bildirimler', ne: 'Uygulamayı telefona kurma, e-posta ve Telegram bildirimleri.', diff --git a/src/components/tools/AiModelSettings.jsx b/src/components/tools/AiModelSettings.jsx index ebdac96..cffab28 100644 --- a/src/components/tools/AiModelSettings.jsx +++ b/src/components/tools/AiModelSettings.jsx @@ -113,7 +113,7 @@ export const AiModelSettings = () => {

Aktif Model Sırası (Fallback Zinciri)

-

Birincil model yanıt vermezse sıradaki yedeğe otomatik geçilir.

+

Birincil model yanıt vermezse sıradaki yedeğe otomatik geçilir. Zincirde olmasa bile Gemini Flash ücretli yedek olarak her zaman en sonda denenir; yalnız üsttekilerin hepsi başarısız olursa devreye girer.