diff --git a/app.py b/app.py index a91bba0..67af6f9 100644 --- a/app.py +++ b/app.py @@ -44,6 +44,7 @@ import logging import os import queue +import re import signal import sqlite3 import subprocess @@ -313,6 +314,14 @@ def estimate_tokens(text: str) -> int: return max(1, len(text) // AVG_CHARS_PER_TOKEN) +def _strip_tool_blocks(text: str) -> str: + """ + LLM yanıtından ... bloklarını sil. + Temiz metni konuşma geçmişine kaydetmek için kullanılır. + """ + return re.sub(r'.*?', '', text, flags=re.DOTALL).strip() + + def fit_messages_to_budget( messages: List[Dict[str, str]], budget: int, @@ -2907,7 +2916,7 @@ def webchat_stats_route(): return jsonify({"ok": False, "error": str(e)}), 500 -@app.route('/api/webchat/users/', methods=['POST']) +@app.route('/api/webchat/users/', methods=['POST', 'PUT']) def webchat_update_user_route(uid: str): data = request.json or {} # Remove non-updatable keys @@ -2983,6 +2992,11 @@ def webchat_chat_route(): if not uid or not content: return jsonify({"ok": False, "error": "uid ve content zorunlu"}), 400 + # LLM çalışıyor mu? Erken kontrol — stream açmadan önce hata döndür + if not _llm_status.get("running"): + return jsonify({"ok": False, + "error": "LLM sunucusu çalışmıyor. Panelden başlatın."}), 503 + # Rate check rate = mm.webchat_check_rate(uid) if not rate.get("allowed"): @@ -3305,7 +3319,11 @@ def stream_conversation(): if content: mm.save_message(chat_id, "user", content) if full_reply: - mm.save_message(chat_id, "assistant", full_reply) + # ... bloklarını geçmişe kaydetme — sadece temiz metin sakla + reply_to_save = _strip_tool_blocks(full_reply) + if reply_to_save: + mm.save_message(chat_id, "assistant", reply_to_save) + # LLM cevap üretti → rate sayacını artır (araç çağrısı olsa bile) mm.webchat_log_message(uid) def _normal_stream(msgs, max_tok): @@ -3373,6 +3391,12 @@ def _normal_stream(msgs, max_tok): except Exception: pass + # Araç etiketi açıldı ama kapanmadı — sessiz tekrara izin verme + if in_tool and "" not in tool_buffer: + yield (f'data: {{"choices":[{{"delta":{{"content":' + f'" \\n[⚠ Araç etiketi kapatılmadı, yeniden deneyin]"}}}}]}}\n\n') + break # while döngüsünü bitir + if not in_tool or "" in tool_buffer: if not in_tool: break # Normal exit @@ -3497,8 +3521,7 @@ def files_upload(): # Boyut kontrolü try: - import base64 - raw = base64.b64decode(data_b64) + raw = b64mod.b64decode(data_b64) except Exception: return jsonify({"ok": False, "error": "Geçersiz base64 verisi"}), 400 diff --git a/chat_client.py b/chat_client.py index fe50288..360ab12 100644 --- a/chat_client.py +++ b/chat_client.py @@ -1606,7 +1606,7 @@ const row = document.createElement('div'); row.className = 'sb-file'; row.innerHTML = ` - ${escHtml(f.name)} (${f.size}) + ${escHtml(f.name)} (${fmtSize(f.size)})