| import json |
| from typing import Any |
|
|
| import gradio as gr |
|
|
| from agent import BookstoreAgent |
| from data.seed_database import seed_books |
|
|
|
|
| |
| _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ı.", |
| "", |
| ) |
|
|
|
|
| |
| |
| 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() |