""" Streamlit UI için modül. Bu modül, Streamlit kullanarak web arayüzünü oluşturur. """ import streamlit as st import os from typing import Dict, Any, Optional, List import json import pandas as pd import re from pathlib import Path from dotenv import load_dotenv, set_key, find_dotenv import io import time import base64 import numpy as np import matplotlib.pyplot as plt # Kendi modüllerimizi içe aktar from prompt_templates import PROMPT_CATEGORIES from chatbot_backend import chatbot, ai_interface from api_integrations import ( api_manager, openai_handler, gemini_handler, openrouter_handler ) # API anahtarlarını yönetmek için fonksiyonlar def save_api_keys_to_env(api_keys: Dict[str, str]) -> bool: """ API anahtarlarını .env dosyasına kaydeder. Args: api_keys (Dict[str, str]): API anahtarları sözlüğü Returns: bool: İşlem başarılıysa True, değilse False """ try: # .env dosyasının yolunu bul dotenv_path = find_dotenv() # .env dosyası yoksa, proje dizininde oluştur if not dotenv_path: dotenv_path = os.path.join(os.getcwd(), ".env") # UTF-8 olarak yeni dosya oluştur with open(dotenv_path, "w", encoding="utf-8") as f: f.write("# API Anahtarları\n") # Mevcut .env dosyasını oku env_content = {} try: # Varolan dosya varsa içeriğini oku if os.path.exists(dotenv_path): with open(dotenv_path, "r", encoding="utf-8") as f: lines = f.readlines() # Mevcut içeriği dictionary'ye dönüştür for line in lines: line = line.strip() if line and not line.startswith("#") and "=" in line: key, value = line.split("=", 1) env_content[key.strip()] = value.strip().strip('"\'') except UnicodeDecodeError: # UTF-8 okunamıyorsa Latin-1 ile dene with open(dotenv_path, "r", encoding="latin-1") as f: lines = f.readlines() # Mevcut içeriği dictionary'ye dönüştür for line in lines: line = line.strip() if line and not line.startswith("#") and "=" in line: key, value = line.split("=", 1) env_content[key.strip()] = value.strip().strip('"\'') # API anahtarlarını env_content sözlüğüne ekle for key, value in api_keys.items(): if key == "openai" and value: env_content["OPENAI_API_KEY"] = value elif key == "gemini" and value: env_content["GEMINI_API_KEY"] = value elif key == "openrouter" and value: env_content["OPENROUTER_API_KEY"] = value # .env dosyasını yeniden oluştur with open(dotenv_path, "w", encoding="utf-8") as f: f.write("# API Anahtarları\n") for key, value in env_content.items(): f.write(f"{key}={value}\n") return True except Exception as e: st.error(f"API anahtarları kaydedilirken hata oluştu: {str(e)}") return False def load_api_keys_from_env() -> Dict[str, str]: """ API anahtarlarını .env dosyasından yükler. Returns: Dict[str, str]: API anahtarları sözlüğü """ try: # .env dosyasının yolunu bul dotenv_path = find_dotenv() # API anahtarlarını içeren sözlük api_keys = { "openai": "", "gemini": "", "openrouter": "" } # .env dosyası yoksa boş API anahtarlarını döndür if not dotenv_path or not os.path.exists(dotenv_path): return api_keys # .env dosyasını manuel olarak oku try: # Önce UTF-8 ile dene with open(dotenv_path, "r", encoding="utf-8") as f: lines = f.readlines() except UnicodeDecodeError: # UTF-8 çalışmazsa Latin-1 ile dene with open(dotenv_path, "r", encoding="latin-1") as f: lines = f.readlines() # Dosya içeriğini işle for line in lines: line = line.strip() if line and not line.startswith("#") and "=" in line: key, value = line.split("=", 1) key = key.strip() value = value.strip().strip('"\'') if key == "OPENAI_API_KEY": api_keys["openai"] = value elif key == "GEMINI_API_KEY": api_keys["gemini"] = value elif key == "OPENROUTER_API_KEY": api_keys["openrouter"] = value return api_keys except Exception as e: st.error(f"API anahtarları yüklenirken hata oluştu: {str(e)}") return { "openai": "", "gemini": "", "openrouter": "" } def load_saved_prompts() -> List[Dict[str, Any]]: """ Kaydedilmiş promptları dosyadan yükler. Returns: List[Dict[str, Any]]: Kaydedilmiş promptlar listesi """ save_dir = os.path.join(os.getcwd(), "saved_prompts") # Dizin yoksa oluştur if not os.path.exists(save_dir): os.makedirs(save_dir) save_path = os.path.join(save_dir, "saved_prompts.json") if os.path.exists(save_path): try: with open(save_path, "r", encoding="utf-8") as f: return json.load(f) except: return [] return [] def save_prompt(prompt: str, category: str, params: Dict[str, Any], name: str, tags: List[str] = None) -> bool: """ Bir promptu dosyaya kaydeder. Args: prompt (str): Kaydedilecek prompt category (str): Prompt kategorisi params (Dict[str, Any]): Prompt parametreleri name (str): Prompt adı tags (List[str], optional): Prompt etiketleri Returns: bool: İşlem başarılıysa True, değilse False """ save_dir = os.path.join(os.getcwd(), "saved_prompts") # Dizin yoksa oluştur if not os.path.exists(save_dir): os.makedirs(save_dir) save_path = os.path.join(save_dir, "saved_prompts.json") # Mevcut kaydedilmiş promptları yükle saved_prompts = [] if os.path.exists(save_path): try: with open(save_path, "r", encoding="utf-8") as f: saved_prompts = json.load(f) except: saved_prompts = [] # Etiketler için varsayılan değer if tags is None: tags = [category] # Yeni promptu ekle saved_prompts.append({ "name": name, "prompt": prompt, "category": category, "params": params, "tags": tags, "created_at": str(pd.Timestamp.now()) }) # Dosyaya kaydet try: with open(save_path, "w", encoding="utf-8") as f: json.dump(saved_prompts, f, ensure_ascii=False, indent=2) return True except Exception as e: st.error(f"Prompt kaydedilirken hata oluştu: {str(e)}") return False def main(): """ Ana Streamlit uygulaması. """ # Sayfa yapılandırması st.set_page_config( page_title="Kralkayra taner atmaca tarafından", page_icon="🤖", layout="wide", initial_sidebar_state="expanded" ) # .env dosyasından API anahtarlarını yükle env_api_keys = load_api_keys_from_env() # Session state başlatma if "api_keys" not in st.session_state: st.session_state.api_keys = env_api_keys # API anahtarlarını chatbot ve işleyicilere de yükle for provider, key in st.session_state.api_keys.items(): if key: api_manager.set_api_key(provider, key) if provider == "openai": openai_handler.set_api_key(key) chatbot.ai_generator.set_api_key(provider, key) elif provider == "gemini": gemini_handler.set_api_key(key) chatbot.ai_generator.set_api_key(provider, key) elif provider == "openrouter": openrouter_handler.set_api_key(key) chatbot.ai_generator.set_api_key(provider, key) # Gerekli importlar # Başlık ve açıklama st.title("Kralkayra taner atmaca tarafından") st.markdown("Bu uygulama, AI modellerine verilecek detaylı promptlar oluşturmanıza yardımcı olur.") # Sekmeler tabs = st.tabs(["Ana Sayfa", "Prompt Kütüphanesi", "Prompt Şablonları", "İleri Analiz", "Görsel Prompt Oluşturucu", "Toplu İşlem"]) # Sidebar - API anahtarları with st.sidebar: st.header("API Anahtarları") st.info("API anahtarlarınızı girin ve 'API Anahtarlarını Kaydet' butonuna tıklayarak kalıcı olarak kaydedin.") # OpenAI API anahtarı openai_api_key = st.text_input( "OpenAI API Anahtarı", type="password", value=st.session_state.api_keys.get("openai", "") ) # Google Gemini API anahtarı gemini_api_key = st.text_input( "Google Gemini API Anahtarı", type="password", value=st.session_state.api_keys.get("gemini", "") ) # OpenRouter API anahtarı openrouter_api_key = st.text_input( "OpenRouter API Anahtarı", type="password", value=st.session_state.api_keys.get("openrouter", "") ) # API anahtarlarını kaydet if st.button("API Anahtarlarını Kaydet"): # Yeni API anahtarları sözlüğü oluştur new_api_keys = { "openai": openai_api_key, "gemini": gemini_api_key, "openrouter": openrouter_api_key } # Session state'e API anahtarlarını kaydet st.session_state.api_keys = new_api_keys # API anahtarlarını ayarla api_manager.set_api_key("openai", openai_api_key) api_manager.set_api_key("gemini", gemini_api_key) api_manager.set_api_key("openrouter", openrouter_api_key) # API işleyicilerine de anahtarları ayarla openai_handler.set_api_key(openai_api_key) gemini_handler.set_api_key(gemini_api_key) openrouter_handler.set_api_key(openrouter_api_key) # Chatbot'un AI prompt generator'ına da anahtarları ayarla chatbot.ai_generator.set_api_key("openai", openai_api_key) chatbot.ai_generator.set_api_key("gemini", gemini_api_key) chatbot.ai_generator.set_api_key("openrouter", openrouter_api_key) # API anahtarlarını .env dosyasına kaydet if save_api_keys_to_env(new_api_keys): st.success("API anahtarları başarıyla kaydedildi ve kalıcı olarak saklandı!") else: st.warning("API anahtarları geçici olarak kaydedildi, ancak kalıcı saklama başarısız oldu.") # API anahtarlarının durumunu göster with st.expander("API Anahtarı Durumu", expanded=False): openai_status = "✅ Ayarlandı" if st.session_state.api_keys.get("openai") else "❌ Ayarlanmadı" gemini_status = "✅ Ayarlandı" if st.session_state.api_keys.get("gemini") else "❌ Ayarlanmadı" openrouter_status = "✅ Ayarlandı" if st.session_state.api_keys.get("openrouter") else "❌ Ayarlanmadı" st.write(f"OpenAI API: {openai_status}") st.write(f"Gemini API: {gemini_status}") st.write(f"OpenRouter API: {openrouter_status}") # AI modeli seçimi st.header("AI Modeli Seçimi") # API sağlayıcısı seçimi provider = st.selectbox( "API Sağlayıcısı", ["OpenAI", "Google Gemini", "OpenRouter"], index=0 ) # Seçilen sağlayıcıya göre model listesini al provider_key = provider.lower().replace(" ", "_") if provider_key == "google_gemini": provider_key = "gemini" # Modelleri al models = [] if provider_key == "openai": models = openai_handler.get_available_models() elif provider_key == "gemini": models = gemini_handler.get_available_models() elif provider_key == "openrouter": models = openrouter_handler.get_available_models() # Model seçimi selected_model = None if models: selected_model = st.selectbox("Model", models) # Ana Sayfa Sekmesi with tabs[0]: # Ana içerik col1, col2 = st.columns([1, 1]) with col1: st.header("Prompt Oluştur") # Kullanıcı girdisi user_input = st.text_area( "Ne yapmak istediğinizi açıklayın:", height=150, placeholder="Örnek: Bir e-ticaret web sitesi yapmak istiyorum. Ürünleri listeleyebilmeli, sepete ekleyebilmeli ve ödeme alabilmeliyim." ) # AI destekli prompt oluşturma seçeneği if "use_ai_generation" not in st.session_state: st.session_state.use_ai_generation = True use_ai_generation = st.checkbox( "AI destekli prompt oluşturma kullan", value=st.session_state.use_ai_generation, key="use_ai_generation_checkbox" ) # Checkbox değiştiğinde session state'i güncelle st.session_state.use_ai_generation = use_ai_generation # API anahtarı kontrolü ve uyarı selected_provider_key = provider.lower().replace(" ", "_") if selected_provider_key == "google_gemini": selected_provider_key = "gemini" if use_ai_generation and not st.session_state.api_keys.get(selected_provider_key): st.warning(f"AI destekli prompt oluşturma için {provider} API anahtarı gereklidir. Lütfen API anahtarınızı girin ve 'API Anahtarlarını Kaydet' butonuna tıklayın.") # Prompt oluştur butonu if st.button("Prompt Oluştur"): if user_input: with st.spinner("Prompt oluşturuluyor..."): # Prompt oluştur provider_key = provider.lower().replace(" ", "_") if provider_key == "google_gemini": provider_key = "gemini" # API anahtarı kontrolü if use_ai_generation and not st.session_state.api_keys.get(provider_key): st.error(f"AI destekli prompt oluşturma için {provider} API anahtarı gereklidir. Lütfen API anahtarınızı girin ve 'API Anahtarlarını Kaydet' butonuna tıklayın.") else: # Debug bilgisi st.session_state.debug_info = { "use_ai_generation": use_ai_generation, "provider": provider_key, "model": selected_model, "api_key_set": bool(st.session_state.api_keys.get(provider_key)) } try: prompt, category, params = chatbot.process_input( user_input, use_ai_generation=use_ai_generation, provider=provider_key, model=selected_model ) # Sonuçları session state'e kaydet st.session_state.prompt = prompt st.session_state.category = category st.session_state.params = params except Exception as e: st.error(f"Prompt oluşturma sırasında bir hata oluştu: {str(e)}") st.session_state.prompt = "Prompt oluşturulurken bir hata oluştu. Lütfen tekrar deneyin veya AI destekli prompt oluşturmayı kapatın." st.session_state.category = "error" st.session_state.params = {} # Sonuçları göster st.success("Prompt başarıyla oluşturuldu!") else: st.error("Lütfen ne yapmak istediğinizi açıklayın.") with col2: st.header("Oluşturulan Prompt") # Debug bilgisi (geliştirme aşamasında) if "debug_info" in st.session_state: with st.expander("Debug Bilgisi", expanded=False): st.write(st.session_state.debug_info) # Oluşturulan promptu göster if "prompt" in st.session_state: st.subheader(f"Kategori: {st.session_state.category}") # Parametreleri göster if st.session_state.params: with st.expander("Parametreler", expanded=False): for key, value in st.session_state.params.items(): st.write(f"**{key}:** {value}") # Promptu göster st.text_area( "Prompt:", value=st.session_state.prompt, height=400, disabled=True ) # Promptu kopyala butonu if st.button("Promptu Kopyala"): st.code(st.session_state.prompt) st.info("Yukarıdaki kodu seçip kopyalayabilirsiniz.") # AI ile Test Et bölümü st.subheader("AI ile Test Et") # Test için API sağlayıcısı seçimi test_provider = st.selectbox( "Test için API Sağlayıcısı", ["OpenAI", "Google Gemini", "OpenRouter"], index=0, key="test_provider" ) # Test için model seçimi test_provider_key = test_provider.lower().replace(" ", "_") if test_provider_key == "google_gemini": test_provider_key = "gemini" # Test için modelleri al test_models = [] if test_provider_key == "openai": test_models = openai_handler.get_available_models() elif test_provider_key == "gemini": test_models = gemini_handler.get_available_models() elif test_provider_key == "openrouter": test_models = openrouter_handler.get_available_models() # Test için model seçimi test_selected_model = None if test_models: test_selected_model = st.selectbox("Test için Model", test_models, key="test_model") # Test için API anahtarı giriş alanı st.markdown("### Test için API Anahtarı") st.info("Test için API anahtarını doğrudan buraya girebilirsiniz.") test_api_key = st.text_input( f"{test_provider} API Anahtarı (Test için)", type="password", key="test_api_key" ) # Kod şablonları oluşturma seçeneği generate_code_templates = st.checkbox("Kod şablonları ve dizin yapısı oluştur", value=True, key="generate_code_templates") # AI ile Test Et butonu if st.button("AI ile Test Et"): if "prompt" in st.session_state: if not test_api_key: st.error(f"Lütfen test için {test_provider} API anahtarını girin.") else: with st.spinner("AI yanıtı alınıyor..."): if generate_code_templates: # Kod şablonları ile yanıt al result = ai_interface.generate_response_with_code_templates( test_provider_key, st.session_state.prompt, test_selected_model, test_api_key ) # Yanıtı ve şablonları session state'e kaydet st.session_state.ai_response = result["response"] st.session_state.code_templates = result["templates"] else: # Sadece yanıt al response = ai_interface.generate_response( test_provider_key, st.session_state.prompt, test_selected_model, test_api_key ) # Yanıtı session state'e kaydet st.session_state.ai_response = response if "code_templates" in st.session_state: del st.session_state.code_templates # Yanıtı göster st.success("AI yanıtı başarıyla alındı!") else: st.error("Lütfen önce bir prompt oluşturun.") # AI yanıtını göster if "ai_response" in st.session_state: st.subheader("AI Yanıtı") st.text_area( "Yanıt:", value=st.session_state.ai_response, height=400, disabled=True ) # Kod şablonları ve dizin yapısı varsa göster if "code_templates" in st.session_state: templates = st.session_state.code_templates # Dizin yapısı if templates["directory_structure"]: with st.expander("📁 Dizin Yapısı", expanded=True): for structure in templates["directory_structure"]: st.code(structure, language="bash") # Kod şablonları if templates["code_templates"]: with st.expander("💻 Kod Şablonları", expanded=True): for template in templates["code_templates"]: st.subheader(f"{template['language'].capitalize()} Dosyası") st.code(template["code"], language=template["language"]) # Uygulama adımları if templates["implementation_steps"]: with st.expander("📝 Uygulama Adımları", expanded=True): for i, step in enumerate(templates["implementation_steps"]): if not step.startswith(f"{i+1}.") and not step.startswith("##"): st.markdown(f"**Adım {i+1}:** {step}") else: st.markdown(step) # Prompt Kaydetme Bölümü if "prompt" in st.session_state: with st.expander("Promptu Kaydet", expanded=False): prompt_name = st.text_input("Prompt Adı", key="save_prompt_name") prompt_tags = st.text_input("Etiketler (virgülle ayırın)", key="save_prompt_tags") if st.button("Kaydet"): if prompt_name: tags = [tag.strip() for tag in prompt_tags.split(",")] if prompt_tags else [] if save_prompt( st.session_state.prompt, st.session_state.category, st.session_state.params, prompt_name, tags ): st.success("Prompt başarıyla kaydedildi!") else: st.error("Lütfen prompt için bir isim girin.") else: st.info("Henüz bir prompt oluşturulmadı. Sol taraftaki formu doldurup 'Prompt Oluştur' butonuna tıklayın.") # Prompt Kütüphanesi Sekmesi with tabs[1]: st.header("Kaydedilmiş Promptlar Kütüphanesi") # Kaydedilmiş promptları yükle saved_prompts = load_saved_prompts() if not saved_prompts: st.info("Henüz kaydedilmiş prompt bulunmuyor. Ana sayfada oluşturduğunuz promptları kaydedebilirsiniz.") else: # Filtreler col1, col2 = st.columns(2) with col1: # Kategori filtresi categories = list(set([p["category"] for p in saved_prompts])) selected_category = st.selectbox("Kategori Filtresi", ["Tümü"] + categories, key="library_category_filter") with col2: # Etiket filtresi all_tags = [] for p in saved_prompts: all_tags.extend(p.get("tags", [])) unique_tags = list(set(all_tags)) selected_tag = st.selectbox("Etiket Filtresi", ["Tümü"] + unique_tags, key="library_tag_filter") # Arama search_query = st.text_input("Prompt Ara", key="library_search") # Filtreleme filtered_prompts = saved_prompts if selected_category != "Tümü": filtered_prompts = [p for p in filtered_prompts if p["category"] == selected_category] if selected_tag != "Tümü": filtered_prompts = [p for p in filtered_prompts if selected_tag in p.get("tags", [])] if search_query: search_lower = search_query.lower() filtered_prompts = [p for p in filtered_prompts if search_lower in p["name"].lower() or search_lower in p["prompt"].lower()] # Prompt listesi if not filtered_prompts: st.warning("Filtrelere uygun kayıtlı prompt bulunamadı.") else: for i, prompt_data in enumerate(filtered_prompts): with st.expander(f"{prompt_data['name']} ({prompt_data['category']})", expanded=False): st.text_area( "Prompt:", value=prompt_data["prompt"], height=200, disabled=True, key=f"saved_prompt_{i}" ) # Etiketler st.write("**Etiketler:** " + ", ".join(prompt_data.get("tags", []))) # Parametreler if prompt_data.get("params"): st.write("**Parametreler:**") for key, value in prompt_data["params"].items(): st.write(f"- {key}: {value}") # Oluşturulma tarihi if "created_at" in prompt_data: st.write(f"**Oluşturulma Tarihi:** {prompt_data['created_at']}") # Prompt'u düzenleme ekranına yükle butonu if st.button("Bu Prompt'u Düzenle", key=f"edit_prompt_{i}"): st.session_state.prompt = prompt_data["prompt"] st.session_state.category = prompt_data["category"] st.session_state.params = prompt_data["params"] st.session_state.editing_prompt = True st.info("Prompt ana sayfaya yüklendi! Ana sayfaya geçerek düzenleyebilirsiniz.") # Prompt'u sil butonu if st.button("Bu Prompt'u Sil", key=f"delete_prompt_{i}"): # Promptu listeden çıkar saved_prompts.remove(prompt_data) # Dosyaya kaydet save_dir = os.path.join(os.getcwd(), "saved_prompts") save_path = os.path.join(save_dir, "saved_prompts.json") try: with open(save_path, "w", encoding="utf-8") as f: json.dump(saved_prompts, f, ensure_ascii=False, indent=2) st.success("Prompt başarıyla silindi!") st.rerun() # Sayfayı yeniden yükle except Exception as e: st.error(f"Prompt silinirken hata oluştu: {str(e)}") # Prompt Şablonları Sekmesi with tabs[2]: st.header("Prompt Şablonları") # Kategori seçimi category = st.selectbox("Kategori", list(PROMPT_CATEGORIES.keys()), key="template_category") # Seçilen kategoriye göre şablon göster if category in PROMPT_CATEGORIES: # Kategori açıklaması if isinstance(PROMPT_CATEGORIES[category], dict) and "description" in PROMPT_CATEGORIES[category]: st.write(PROMPT_CATEGORIES[category]["description"]) # Şablon parametreleri st.subheader("Şablon Parametreleri") # Parametreleri dinamik olarak oluştur params = {} from prompt_templates import PROMPT_TEMPLATES if category in PROMPT_TEMPLATES: template = PROMPT_TEMPLATES[category] # Şablon parametrelerini regex ile bul pattern = r'{(\w+)}' params_keys = re.findall(pattern, template) # Her parametre için input alanı oluştur for param in params_keys: params[param] = st.text_area(f"{param}:", height=100, key=f"template_param_{param}") # Şablonu oluştur butonu if st.button("Şablonu Oluştur"): from prompt_templates import create_prompt prompt = create_prompt(category, params) # Promptu session state'e ekle st.session_state.prompt = prompt st.session_state.category = category st.session_state.params = params # Oluşturulan şablonu göster st.subheader("Oluşturulan Şablon") st.text_area( "Prompt:", value=prompt, height=400, disabled=True ) # Şablon kullanım bilgisi st.info("Bu şablon ana sayfaya yüklendi. Ana sayfaya geçerek düzenleyebilir veya API ile test edebilirsiniz.") # İleri Analiz Sekmesi (Placeholder) with tabs[3]: st.header("İleri AI Analizi") # Analiz edilecek prompt analysis_prompt = st.text_area( "Analiz edilecek prompt:", height=200, placeholder="Analiz etmek istediğiniz promptu buraya yapıştırın...", key="analysis_prompt" ) # Mevcut prompt varsa, onu otomatik olarak ekle if "prompt" in st.session_state and not analysis_prompt: if st.button("Mevcut promptu yükle"): analysis_prompt = st.session_state.prompt st.session_state.analysis_prompt = analysis_prompt st.rerun() if analysis_prompt: # Analiz türleri analysis_tabs = st.tabs(["Token Analizi", "Kalite Skorlaması", "Karmaşıklık Analizi"]) # Token Analizi with analysis_tabs[0]: st.subheader("Token Analizi") # Basit token sayacı words = analysis_prompt.split() word_count = len(words) # Yaklaşık token sayısı (GPT tokenizasyonu için yaklaşık değer) # GPT tokenizasyonu genellikle kelimelerden daha küçük birimlerdir # Yaklaşık olarak 4 karakter = 1 token olarak hesaplanabilir char_count = len(analysis_prompt) estimated_tokens = char_count // 4 # Sonuçları göster col1, col2, col3 = st.columns(3) with col1: st.metric("Kelime Sayısı", word_count) with col2: st.metric("Karakter Sayısı", char_count) with col3: st.metric("Tahmini Token Sayısı", estimated_tokens) # Token maliyeti tahmini st.subheader("Tahmini Maliyet") # Farklı modeller için maliyet tahminleri model_costs = { "gpt-3.5-turbo": {"input": 0.0000015, "output": 0.000002}, "gpt-4o": {"input": 0.00001, "output": 0.00003}, "gemini-1.5-pro": {"input": 0.000005, "output": 0.000005}, } # Maliyetleri hesapla ve göster cost_cols = st.columns(len(model_costs)) for i, (model, costs) in enumerate(model_costs.items()): input_cost = estimated_tokens * costs["input"] output_cost_1k = 1000 * costs["output"] # 1000 token yanıt için with cost_cols[i]: st.metric(f"{model}", f"${input_cost:.6f}") st.caption(f"Prompt maliyeti") st.metric("1000 token yanıt", f"${output_cost_1k:.4f}") # Token optimizasyonu önerileri st.subheader("Optimizasyon Önerileri") if word_count > 200: st.warning("Bu prompt oldukça uzun. Maliyeti düşürmek için kısaltmayı düşünebilirsiniz.") # Optimizasyon önerileri st.markdown(""" **Öneriler:** - Gereksiz tekrarları kaldırın - Örnek açıklamaları kısaltın - Açıklama cümlelerini daha özlü hale getirin """) else: st.success("Bu prompt token kullanımı açısından makul görünüyor.") # Kalite Skorlaması with analysis_tabs[1]: st.subheader("Prompt Kalite Analizi") # Kalite faktörleri quality_factors = [ "Açıklık ve Netlik", "Spesifiklik", "Bağlam Sağlama", "Hedef Belirleme", "Örnek İçerme" ] # Her faktör için puan hesapla (basit algoritmalar) clarity_score = min(10, max(1, 7 + (analysis_prompt.count(".") / max(1, word_count // 20)))) specificity_score = min(10, max(1, 5 + (analysis_prompt.count(":") * 2))) context_score = min(10, max(1, 5 + (analysis_prompt.lower().count("örneğin") + analysis_prompt.lower().count("bağlam")))) goal_score = min(10, max(1, 6 + (analysis_prompt.lower().count("hedef") + analysis_prompt.lower().count("amaç")))) example_score = min(10, max(1, 4 + (analysis_prompt.lower().count("örnek") * 2))) # Genel skor hesapla overall_score = (clarity_score + specificity_score + context_score + goal_score + example_score) / 5 # Sonuçları göster col1, col2 = st.columns([1, 2]) with col1: # Genel skor st.markdown(f"### Genel Skor: {overall_score:.1f}/10") if overall_score >= 8: st.success("Bu prompt yüksek kaliteye sahip! Mükemmel bir prompt oluşturdunuz.") elif overall_score >= 6: st.info("Bu prompt iyi görünüyor, ancak geliştirilebilir.") else: st.warning("Bu prompt iyileştirilmeli. Aşağıdaki önerilere göz atın.") with col2: # Faktör skorları scores = [clarity_score, specificity_score, context_score, goal_score, example_score] # Radar chart oluştur fig = plt.figure(figsize=(4, 4)) ax = fig.add_subplot(111, polar=True) # Skorlar ve faktörler için veri hazırlığı angles = np.linspace(0, 2*np.pi, len(quality_factors), endpoint=False) scores_for_plot = np.concatenate((scores, [scores[0]])) angles = np.concatenate((angles, [angles[0]])) labels = quality_factors + [quality_factors[0]] # Çizim ax.plot(angles, scores_for_plot, 'o-', linewidth=2) ax.fill(angles, scores_for_plot, alpha=0.25) ax.set_thetagrids(angles[:-1] * 180/np.pi, labels[:-1]) ax.set_ylim(0, 10) ax.grid(True) st.pyplot(fig) # İyileştirme önerileri st.subheader("İyileştirme Önerileri") if clarity_score < 7: st.markdown("- **Açıklık ve Netlik**: Daha kısa ve öz cümleler kullanın. Her cümle tek bir fikri ifade etmeli.") if specificity_score < 7: st.markdown("- **Spesifiklik**: Daha detaylı talimatlar verin. İstediğiniz format, stil ve içeriği açıkça belirtin.") if context_score < 7: st.markdown("- **Bağlam Sağlama**: Promptta daha fazla bağlam bilgisi sağlayın. Hedef kitle, amaç ve kullanım senaryosu ekleyin.") if goal_score < 7: st.markdown("- **Hedef Belirleme**: Promptun sonunda ne elde etmek istediğinizi net bir şekilde belirtin.") if example_score < 7: st.markdown("- **Örnek İçerme**: İstediğiniz çıktı formatına benzer örnekler ekleyin.") # Karmaşıklık Analizi with analysis_tabs[2]: st.subheader("Karmaşıklık Analizi") # Okunabilirlik skoru (Flesch Reading Ease formülüne yaklaşık bir değer) sentences = analysis_prompt.split('.') sentence_count = max(1, len(sentences) - 1) # Son nokta sonrası boş cümle olabilir avg_words_per_sentence = word_count / sentence_count avg_syllables_per_word = char_count / (word_count * 1.5) # Yaklaşık bir değer # Flesch Reading Ease skoru (0-100 arası, yüksek değer daha kolay okunabilir) readability_score = 206.835 - (1.015 * avg_words_per_sentence) - (84.6 * avg_syllables_per_word) readability_score = max(0, min(100, readability_score)) # Karmaşıklık seviyesi if readability_score >= 80: complexity_level = "Çok Kolay" complexity_description = "Çok basit, anlaşılması kolay bir prompt." elif readability_score >= 60: complexity_level = "Kolay" complexity_description = "Anlaşılması kolay, basit bir prompt." elif readability_score >= 40: complexity_level = "Orta" complexity_description = "Orta zorlukta, genel kullanıcılar için uygun." elif readability_score >= 20: complexity_level = "Zor" complexity_description = "Karmaşık, anlaşılması için teknik bilgi gerekebilir." else: complexity_level = "Çok Zor" complexity_description = "Çok karmaşık, sadece uzmanlar için uygun." # Sonuçları göster col1, col2 = st.columns(2) with col1: st.metric("Okunabilirlik Skoru", f"{readability_score:.1f}/100") st.metric("Cümle Sayısı", sentence_count) st.metric("Cümle Başına Kelime", f"{avg_words_per_sentence:.1f}") with col2: st.markdown(f"### Karmaşıklık: {complexity_level}") st.markdown(complexity_description) # Öneriler if readability_score < 40: st.warning("Bu promptu basitleştirmek AI'nın daha iyi anlamasını sağlayabilir.") elif readability_score > 80: st.warning("Bu prompt çok basit olabilir. Daha spesifik yönergeler eklemek isteyebilirsiniz.") else: st.success("Bu prompt karmaşıklık açısından iyi dengelenmiş.") # Görsel Prompt Oluşturucu Sekmesi with tabs[4]: st.header("Görsel Prompt Oluşturucu") # Prompt yapı blokları st.subheader("Prompt Blokları") prompt_blocks = { "Giriş Blokları": [ "Rolünüzü belirtin: Siz bir [ROL] olarak,", "Aşağıdaki görevde bana yardımcı olun:", "Ben bir [ROL] ve size [KONU] hakkında danışmak istiyorum.", "Bir [PROJE TİPİ] oluşturmam gerekiyor." ], "Görev Blokları": [ "Göreviniz: [GÖREVİ BURAYA YAZIN]", "Lütfen bana [KONU] hakkında detaylı bilgi verin.", "Lütfen bu [KODU/METNİ] analiz edin ve iyileştirin.", "Bana adım adım nasıl [GÖREV] yapacağımı açıklayın." ], "Format Blokları": [ "Yanıtınızı madde işaretleriyle listeleyin.", "Yanıtınızı bir tablo formatında düzenleyin.", "Lütfen yanıtınızı bölümlere ayırın.", "Lütfen açıklamanızı örneklerle destekleyin." ], "Spesifikasyon Blokları": [ "Çıktı uzunluğu: [KISACA/DETAYLI/KELİME SAYISI]", "Hedef kitle: [KİTLE]", "Kullanılacak ton: [RESMİ/ARKADAŞÇA/TEKNİK/vb.]", "Teknik seviye: [BAŞLANGIÇ/ORTA/İLERİ]" ], "Kapanış Blokları": [ "Yanıtınızın sonunda bir özet ekleyin.", "Sonraki adımlar için önerilerinizi ekleyin.", "Ek kaynak veya referanslar ekleyin.", "Konuyla ilgili potansiyel sorunları belirtin." ] } # Kullanıcı tarafından seçilen bloklar if "selected_blocks" not in st.session_state: st.session_state.selected_blocks = [] if "block_params" not in st.session_state: st.session_state.block_params = {} # Kullanılabilir blokları göster col1, col2 = st.columns([1, 2]) with col1: # Kategori seçimi block_category = st.selectbox("Blok Kategorisi", list(prompt_blocks.keys())) # O kategorideki blokları göster selected_block = st.selectbox("Kullanılabilir Bloklar", prompt_blocks[block_category]) # Bloğu ekle butonu if st.button("Bloğu Ekle"): if selected_block not in st.session_state.selected_blocks: st.session_state.selected_blocks.append(selected_block) st.session_state.block_params[selected_block] = {} with col2: # Seçilen blokları listele st.subheader("Seçilen Bloklar") if not st.session_state.selected_blocks: st.info("Henüz blok eklenmedi. Sol taraftan blok ekleyin.") else: updated_blocks = [] for i, block in enumerate(st.session_state.selected_blocks): col_block, col_delete = st.columns([5, 1]) with col_block: # Köşeli parantez içindeki parametreleri bul params = re.findall(r'\[(.*?)\]', block) # Parametreleri düzenlemek için giriş alanları oluştur edited_block = block if params: for param in params: param_key = f"block_{i}_{param}" # İlk kez için default değeri ayarla if param not in st.session_state.block_params.get(block, {}): st.session_state.block_params.setdefault(block, {})[param] = param # Parametre için input alanı param_value = st.text_input( f"**{param}** değeri:", value=st.session_state.block_params[block].get(param, param), key=param_key ) # Parametre değerini güncelle st.session_state.block_params[block][param] = param_value # Blok metnini güncelle edited_block = edited_block.replace(f"[{param}]", param_value) # Düzenlenen bloğu göster st.markdown(f"**{i+1}.** {edited_block}") updated_blocks.append(edited_block) with col_delete: # Bloğu sil butonu if st.button("🗑️", key=f"delete_block_{i}"): del st.session_state.selected_blocks[i] st.rerun() # Blokların sırasını değiştir col_up, col_down = st.columns(2) with col_up: block_to_move_up = st.number_input("Yukarı taşı (blok no)", min_value=0, max_value=len(st.session_state.selected_blocks), value=0, step=1) if st.button("Yukarı Taşı") and block_to_move_up > 1 and block_to_move_up <= len(st.session_state.selected_blocks): idx = block_to_move_up - 1 st.session_state.selected_blocks[idx], st.session_state.selected_blocks[idx-1] = st.session_state.selected_blocks[idx-1], st.session_state.selected_blocks[idx] st.rerun() with col_down: block_to_move_down = st.number_input("Aşağı taşı (blok no)", min_value=0, max_value=len(st.session_state.selected_blocks), value=0, step=1) if st.button("Aşağı Taşı") and block_to_move_down > 0 and block_to_move_down < len(st.session_state.selected_blocks): idx = block_to_move_down - 1 st.session_state.selected_blocks[idx], st.session_state.selected_blocks[idx+1] = st.session_state.selected_blocks[idx+1], st.session_state.selected_blocks[idx] st.rerun() # Tüm blokları temizle if st.button("Tüm Blokları Temizle"): st.session_state.selected_blocks = [] st.session_state.block_params = {} st.rerun() # Önizleme ve oluşturma st.subheader("Prompt Önizleme") if not st.session_state.selected_blocks: st.info("Blok ekleyerek promptunuzu oluşturmaya başlayın.") else: # Blokları birleştir preview_prompt = "\n\n".join(updated_blocks) # Önizleme göster st.text_area("Oluşturulan Prompt:", value=preview_prompt, height=200, disabled=True) # Promptu ana sayfaya ekle if st.button("Bu Promptu Kullan"): # Session state'e promptu kaydet st.session_state.prompt = preview_prompt st.session_state.category = "custom" st.session_state.params = {} # Başarı mesajı st.success("Prompt ana sayfaya yüklendi! Ana sayfaya geçerek düzenleyebilir veya API ile test edebilirsiniz.") # Özel blok ekleme with st.expander("Özel Blok Ekle", expanded=False): custom_block = st.text_area("Özel blok metnini girin:", placeholder="Örnek: Size [KONU] hakkında bir [İÇERİK TİPİ] yazmanızı istiyorum.") if st.button("Özel Bloğu Ekle") and custom_block: st.session_state.selected_blocks.append(custom_block) st.session_state.block_params[custom_block] = {} st.rerun() # Toplu İşlem Sekmesi with tabs[5]: st.header("Toplu Prompt Oluşturma") # Toplu işlem türü batch_tabs = st.tabs(["CSV/Excel ile Toplu Prompt", "Metin Tabanlı Çoklu Prompt", "Gelişmiş"]) # CSV/Excel ile Toplu Prompt with batch_tabs[0]: st.subheader("CSV/Excel Dosyası ile Toplu Prompt Oluşturma") # Açıklama st.markdown(""" Bu özellik, bir CSV veya Excel dosyası yükleyerek aynı şablona dayalı çoklu prompt oluşturmanıza olanak tanır. **Dosya formatı:** - İlk satır sütun başlıkları olmalıdır - Her satır farklı bir prompt için veri içermelidir - Şablondaki yer tutucular sütun adlarıyla aynı olmalıdır (ör. `{ürün_adı}`) """) # Örnek şablon template = st.text_area( "Prompt Şablonu:", placeholder="Örnek: {ürün_adı} ürünü için {hedef_kitle} hedef kitlesine yönelik {kelime_sayısı} kelimelik bir pazarlama metni yaz.", height=100, key="batch_template" ) # Dosya yükleme uploaded_file = st.file_uploader("CSV veya Excel Dosyası Yükle", type=["csv", "xlsx", "xls"]) if uploaded_file is not None and template: try: # Dosyayı dataframe'e yükle df = None if uploaded_file.name.endswith(".csv"): df = pd.read_csv(uploaded_file) else: df = pd.read_excel(uploaded_file) # İlk 5 satırı göster st.subheader("Veri Önizleme") st.dataframe(df.head()) # Şablondaki yer tutucuları bul placeholders = re.findall(r'{(.*?)}', template) # Yer tutucular df sütunlarıyla eşleşiyor mu kontrol et missing_columns = [p for p in placeholders if p not in df.columns] if missing_columns: st.error(f"Şablonda belirtilen yer tutucular dosyada bulunamadı: {', '.join(missing_columns)}") else: # Promptları oluştur generated_prompts = [] for _, row in df.iterrows(): # Bu satır için promptu hazırla prompt = template # Tüm yer tutucuları değiştir for placeholder in placeholders: prompt = prompt.replace(f"{{{placeholder}}}", str(row[placeholder])) generated_prompts.append(prompt) # Oluşturulan promptları göster st.subheader(f"Oluşturulan Promptlar ({len(generated_prompts)})") # Promptları göstermek için genişletilebilir paneller for i, prompt in enumerate(generated_prompts): with st.expander(f"Prompt {i+1}", expanded=i==0): st.text_area(f"Prompt {i+1}", value=prompt, height=150, disabled=True, key=f"batch_prompt_{i}") # Tüm promptları indirebilme seçeneği if st.button("Tüm Promptları TXT Dosyası Olarak İndir"): # Promptları birleştir all_prompts = "\n\n---\n\n".join(generated_prompts) # Promptları download link olarak sun st.download_button( label="İndirmeyi Başlat", data=all_prompts, file_name="toplu_promptlar.txt", mime="text/plain" ) # Promptları dataframe'e ekleyip Excel olarak indirme seçeneği if st.button("Promptları Excel Dosyası Olarak İndir"): # Kopya dataframe oluştur result_df = df.copy() # Prompt sütunu ekle result_df["generated_prompt"] = generated_prompts # Excel dosyası oluştur output = io.BytesIO() with pd.ExcelWriter(output, engine='xlsxwriter') as writer: result_df.to_excel(writer, index=False, sheet_name="Promptlar") # Download butonu oluştur st.download_button( label="Excel İndirmeyi Başlat", data=output.getvalue(), file_name="prompt_sonuçları.xlsx", mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) except Exception as e: st.error(f"Dosya işlenirken bir hata oluştu: {str(e)}") # Örnek dosya indirme with st.expander("Örnek CSV/Excel Dosyası İndir", expanded=False): st.markdown(""" Aşağıdaki örnek dosyayı indirip kendi verilerinizle doldurabilirsiniz: """) # Örnek veri example_data = { "ürün_adı": ["Akıllı Saat", "Kablosuz Kulaklık", "Robot Süpürge"], "hedef_kitle": ["spor tutkunları", "müzik severler", "yoğun çalışan profesyoneller"], "kelime_sayısı": [200, 150, 250] } example_df = pd.DataFrame(example_data) # CSV olarak indir csv_data = example_df.to_csv(index=False) st.download_button( label="Örnek CSV İndir", data=csv_data, file_name="ornek_veriler.csv", mime="text/csv" ) # Excel olarak indir output = io.BytesIO() with pd.ExcelWriter(output, engine='xlsxwriter') as writer: example_df.to_excel(writer, index=False) st.download_button( label="Örnek Excel İndir", data=output.getvalue(), file_name="ornek_veriler.xlsx", mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) # Metin Tabanlı Çoklu Prompt with batch_tabs[1]: st.subheader("Metin Tabanlı Çoklu Prompt Oluşturma") # Açıklama st.markdown(""" Bu özellik, aynı şablonu kullanarak birden fazla prompt oluşturmanızı sağlar. Her bir değişken değeri için farklı bir satır ekleyin. """) # Prompt şablonu text_template = st.text_area( "Prompt Şablonu:", value="Bir {konu} hakkında {kelime_sayısı} kelimelik bir yazı yaz.", height=100, key="text_batch_template" ) # Şablondaki değişkenleri bul text_placeholders = re.findall(r'{(.*?)}', text_template) if text_placeholders: st.subheader("Değişkenler") # Her değişken için değer listesi variable_values = {} for placeholder in text_placeholders: values = st.text_area( f"{placeholder} değerleri (her satıra bir değer):", height=100, key=f"variable_{placeholder}" ) if values: # Değerleri satırlara ayır variable_values[placeholder] = [v.strip() for v in values.strip().split("\n") if v.strip()] # Tüm değişkenler için değer var mı kontrol et missing_values = [p for p in text_placeholders if p not in variable_values or not variable_values[p]] if missing_values: st.warning(f"Lütfen şu değişkenler için değer girin: {', '.join(missing_values)}") else: # Tüm kombinasyonları oluştur import itertools # Değişkenlerin tüm değer kombinasyonlarını oluştur combinations = list(itertools.product(*[variable_values[p] for p in text_placeholders])) # Her kombinasyon için prompt oluştur text_generated_prompts = [] for combo in combinations: # Şablondan başla prompt = text_template # Her değişkeni değiştir for i, placeholder in enumerate(text_placeholders): prompt = prompt.replace(f"{{{placeholder}}}", combo[i]) text_generated_prompts.append(prompt) # Oluşturulan promptları göster st.subheader(f"Oluşturulan Promptlar ({len(text_generated_prompts)})") # Promptları göster for i, prompt in enumerate(text_generated_prompts): with st.expander(f"Prompt {i+1}", expanded=i==0): st.text_area(f"Prompt {i+1}", value=prompt, height=150, disabled=True, key=f"text_batch_prompt_{i}") # Tüm promptları indir butonu if st.button("Tüm Promptları İndir"): # Promptları birleştir all_prompts = "\n\n---\n\n".join(text_generated_prompts) # İndirme linki st.download_button( label="İndirmeyi Başlat", data=all_prompts, file_name="metin_tabanlı_promptlar.txt", mime="text/plain" ) # Gelişmiş Toplu İşlem with batch_tabs[2]: st.subheader("Gelişmiş Toplu İşlem") st.info("Bu özellik yakında eklenecektir. API otomasyonu ve programlı prompt üretimi gibi gelişmiş özellikler içerecektir.") # Kategori bilgileri st.header("Desteklenen Kategoriler") # Kategorileri göster categories_per_row = 3 categories = list(PROMPT_CATEGORIES.keys()) for i in range(0, len(categories), categories_per_row): cols = st.columns(categories_per_row) for j in range(categories_per_row): if i + j < len(categories): with cols[j]: category = categories[i + j] st.subheader(category) if isinstance(PROMPT_CATEGORIES[category], dict) and "description" in PROMPT_CATEGORIES[category]: st.write(PROMPT_CATEGORIES[category]["description"]) else: st.write("Bu kategori için açıklama bulunmuyor.") # Footer st.markdown("---") st.markdown("© 2025 AI Prompt Generator | Tüm hakları saklıdır.| created by Kralkayra Taner Atmaca") if __name__ == "__main__": main()