import json from typing import Any import gradio as gr from agent import BookstoreAgent from data.seed_database import seed_books # Agent nesnesini uygulama boyunca tek kez oluşturmak için kullanılır. _AGENT: BookstoreAgent | None = None def get_agent() -> BookstoreAgent: """ BookstoreAgent nesnesini ilk kullanıcı isteğinde oluşturur. Böylece her mesaj gönderildiğinde yeni bir agent ve model istemcisi oluşturulmaz. """ global _AGENT if _AGENT is None: _AGENT = BookstoreAgent() return _AGENT def format_tool_logs( tool_logs: list[dict[str, Any]], ) -> str: """ Agent tarafından döndürülen tool loglarını Gradio arayüzünde gösterilecek Markdown metnine dönüştürür. """ if not tool_logs: return "Bu cevap sırasında herhangi bir tool çağrısı yapılmadı." sections: list[str] = [] for index, log in enumerate(tool_logs, start=1): tool_name = log.get("tool_name", "unknown") arguments = json.dumps( log.get("arguments", {}), ensure_ascii=False, indent=2, ) result = json.dumps( log.get("result", {}), ensure_ascii=False, indent=2, ) section = f""" ### {index}. `{tool_name}` **Gönderilen argümanlar** ```json {arguments} ``` **Tool sonucu** ```json {result} ``` """ sections.append(section.strip()) return "\n\n---\n\n".join(sections) def respond( message: str, history: list[dict[str, Any]] | None, ) -> tuple[str, list[dict[str, Any]], str]: """ Kullanıcının mesajını agent'a gönderir. Dönüş değerleri: 1. Temizlenmiş mesaj kutusu 2. Güncellenmiş sohbet geçmişi 3. Tool-call logları """ message = (message or "").strip() current_history = list(history or []) if not message: return ( "", current_history, "Lütfen bir mesaj yazın.", ) try: agent_result = get_agent().run( user_message=message, history=current_history, ) answer = agent_result.get( "answer", "Asistan bir cevap oluşturamadı.", ) tool_logs = agent_result.get( "tool_logs", [], ) updated_history = current_history + [ { "role": "user", "content": message, }, { "role": "assistant", "content": answer, }, ] formatted_logs = format_tool_logs(tool_logs) return ( "", updated_history, formatted_logs, ) except Exception as error: error_message = ( "İstek işlenirken bir hata oluştu.\n\n" "Hugging Face tokenını, internet bağlantısını ve " "model erişimini kontrol edin.\n\n" f"**Hata:** `{type(error).__name__}: {error}`" ) updated_history = current_history + [ { "role": "user", "content": message, }, { "role": "assistant", "content": error_message, }, ] return ( "", updated_history, error_message, ) def clear_chat() -> tuple[ list[dict[str, Any]], str, str, ]: """ Sohbet geçmişini, tool loglarını ve mesaj kutusunu temizler. """ return ( [], "Henüz tool çağrısı yapılmadı.", "", ) # Uygulama başladığında veritabanını oluşturur # ve 40 örnek kitabı ekler. seed_books() with gr.Blocks( title="Akıllı Kitapçı Asistanı", ) as demo: gr.Markdown( """ # 📚 Akıllı Kitapçı Tool-Calling Asistanı Kitap arayabilir, fiyat ve stok bilgisi sorgulayabilir, sipariş oluşturabilir veya sipariş durumunu kontrol edebilirsiniz. Asistan; kitap, fiyat, stok ve sipariş bilgilerini SQLite veritabanından tool çağrılarıyla alır. """ ) with gr.Row(): with gr.Column(scale=2): chatbot = gr.Chatbot( value=[], label="Sohbet", height=560, ) message_box = gr.Textbox( label="Mesajınız", placeholder=( "Örnek: Dune kitabından Yusuf Şimşek adına " "1 adet sipariş oluştur." ), lines=2, ) with gr.Row(): send_button = gr.Button( value="Gönder", variant="primary", ) clear_button = gr.Button( value="Temizle", ) with gr.Column(scale=1): gr.Markdown( """ ## 🔧 Tool-Call Logu Modelin çağırdığı fonksiyonlar, gönderdiği parametreler ve veritabanından dönen gerçek sonuçlar burada gösterilir. """ ) tool_logs = gr.Markdown( value="Henüz tool çağrısı yapılmadı.", ) gr.Markdown("## 💬 Örnek İstekler") gr.Examples( examples=[ [ "Dune kitabının fiyatı ve stok durumu nedir?" ], [ "Bilim kurgu kategorisindeki stokta olan " "kitapları göster." ], [ "George Orwell tarafından yazılan kitapları listele." ], [ "Dune kitabından Yusuf Şimşek adına " "1 adet sipariş oluştur." ], [ "2 numaralı siparişim ne durumda?" ], [ "Veritabanında Olmayan Hayali Kitap stokta mı?" ], ], inputs=message_box, ) message_box.submit( fn=respond, inputs=[ message_box, chatbot, ], outputs=[ message_box, chatbot, tool_logs, ], ) send_button.click( fn=respond, inputs=[ message_box, chatbot, ], outputs=[ message_box, chatbot, tool_logs, ], ) clear_button.click( fn=clear_chat, inputs=None, outputs=[ chatbot, tool_logs, message_box, ], queue=False, ) if __name__ == "__main__": demo.queue().launch()