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)})