Update app.py
Browse files
app.py
CHANGED
@@ -3,10 +3,14 @@ import os
|
|
3 |
import json
|
4 |
import requests
|
5 |
import xml.etree.ElementTree as ET
|
6 |
-
from huggingface_hub import HfApi, create_repo
|
7 |
import schedule
|
8 |
import time
|
9 |
import threading
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
# Log dosyası adı ve yolu
|
12 |
LOG_FILE = '/data/chat_logs.txt' if os.path.exists('/data') else 'chat_logs.txt'
|
@@ -29,9 +33,9 @@ for item in root.findall('item'):
|
|
29 |
name_words = item.find('rootlabel').text.lower().split()
|
30 |
name = name_words[0]
|
31 |
full_name = ' '.join(name_words)
|
32 |
-
|
33 |
price = item.find('priceWithTax').text
|
34 |
-
item_info = (
|
35 |
products.append((name, item_info, full_name))
|
36 |
|
37 |
# Hugging Face token
|
@@ -41,43 +45,51 @@ if not hfapi:
|
|
41 |
|
42 |
create_repo("BF", token=hfapi, repo_type="space", space_sdk="gradio", exist_ok=True)
|
43 |
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
f.write("\n--- Zamanlanmış Kayıt: {} ---\n".format(time.strftime("%Y-%m-%d %H:%M:%S")))
|
49 |
-
for msg in chatbot:
|
50 |
-
f.write(f"{msg['role'].capitalize()}: {msg['content']}\n")
|
51 |
-
print(f"Sohbet dosyaya kaydedildi: {file_path}")
|
52 |
-
return True
|
53 |
-
except Exception as e:
|
54 |
-
print(f"Kayıt hatası: {e}")
|
55 |
-
return False
|
56 |
|
57 |
-
def
|
58 |
-
api = HfApi(token=hf_token)
|
59 |
-
try:
|
60 |
-
api.upload_file(
|
61 |
-
path_or_fileobj=local_log_file,
|
62 |
-
path_in_repo="chat_logs.txt",
|
63 |
-
repo_id=repo_id,
|
64 |
-
repo_type="space",
|
65 |
-
commit_message="Otomatik log dosyası güncellemesi - {}".format(time.strftime("%Y-%m-%d %H:%M:%S"))
|
66 |
-
)
|
67 |
-
print(f"Log dosyası HF'ye yüklendi: {local_log_file}")
|
68 |
-
return True
|
69 |
-
except Exception as e:
|
70 |
-
print(f"HF yükleme hatası: {e}")
|
71 |
-
return False
|
72 |
-
|
73 |
-
def run_scheduler(chatbot_ref):
|
74 |
def scheduled_save_and_upload():
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
print(f"Zamanlanmış işlem tamamlandı: {time.strftime('%H:%M:%S')}")
|
82 |
|
83 |
schedule.every().day.at("11:32").do(scheduled_save_and_upload)
|
@@ -87,55 +99,54 @@ def run_scheduler(chatbot_ref):
|
|
87 |
schedule.every().day.at("19:15").do(scheduled_save_and_upload)
|
88 |
schedule.every().day.at("21:30").do(scheduled_save_and_upload)
|
89 |
print("Zamanlayıcı başlatıldı")
|
90 |
-
|
91 |
while True:
|
92 |
schedule.run_pending()
|
93 |
-
print(f"Zamanlayıcı çalışıyor, bekliyor: {time.strftime('%H:%M:%S')}")
|
94 |
time.sleep(60)
|
95 |
|
96 |
-
def
|
97 |
-
if chatbot is None:
|
98 |
-
chatbot = []
|
99 |
if history is None:
|
100 |
history = []
|
101 |
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
{"role": "system", "content": "
|
113 |
-
{"role": "system", "content": "
|
114 |
-
{"role": "system", "content": "
|
115 |
-
{"role": "system", "content": "
|
116 |
-
{"role": "system", "content": "
|
117 |
-
{"role": "system", "content": "
|
118 |
-
{"role": "system", "content": "
|
119 |
-
{"role": "system", "content": "
|
120 |
-
{"role": "system", "content": "
|
121 |
-
{"role": "system", "content": "
|
122 |
-
{"role": "system", "content": "
|
123 |
-
{"role": "system", "content": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
]
|
125 |
-
|
126 |
-
|
127 |
-
input_words = [str(word).lower() for word in inputs.split()]
|
128 |
for product_info in products:
|
129 |
if product_info[0] in input_words:
|
130 |
new_msg = f"{product_info[2]} {product_info[1][0]} ve fiyatı EURO {product_info[1][1]}"
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
messages.append({"role": data["role"], "content": data["content"]})
|
136 |
-
|
137 |
-
messages.append({"role": "user", "content": inputs})
|
138 |
-
|
139 |
payload = {
|
140 |
"model": "gpt-4o",
|
141 |
"messages": messages,
|
@@ -146,29 +157,19 @@ def predict(system_msg, inputs, top_p, temperature, chat_counter, chatbot=None,
|
|
146 |
"presence_penalty": 0,
|
147 |
"frequency_penalty": 0,
|
148 |
}
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
try:
|
154 |
-
with open(LOG_FILE, 'a', encoding='utf-8') as f:
|
155 |
-
f.write(f"User: {inputs}\n")
|
156 |
-
print(f"Kullanıcı mesajı dosyaya yazıldı: {inputs}")
|
157 |
-
except Exception as e:
|
158 |
-
print(f"Dosya yazma hatası (Kullanıcı): {e}")
|
159 |
-
|
160 |
-
# Kullanıcı mesajını ekledikten sonra, ayrı bir assistant mesajı için yer açıyoruz
|
161 |
-
chatbot.append({"role": "user", "content": inputs})
|
162 |
-
chatbot.append({"role": "assistant", "content": ""}) # Boş bir assistant mesajı ekliyoruz
|
163 |
|
164 |
response = requests.post(API_URL, headers=headers, json=payload, stream=True)
|
165 |
-
|
166 |
if response.status_code != 200:
|
167 |
-
|
168 |
-
|
169 |
-
yield chatbot, history, chat_counter
|
170 |
|
171 |
partial_response = ""
|
|
|
|
|
172 |
for chunk in response.iter_lines():
|
173 |
if not chunk:
|
174 |
continue
|
@@ -177,114 +178,54 @@ def predict(system_msg, inputs, top_p, temperature, chat_counter, chatbot=None,
|
|
177 |
try:
|
178 |
chunk_data = json.loads(chunk_str[6:])
|
179 |
delta = chunk_data['choices'][0]['delta']
|
180 |
-
if 'content' in delta
|
181 |
partial_response += delta['content']
|
182 |
-
|
183 |
-
|
184 |
-
yield chatbot, history, chat_counter
|
185 |
except json.JSONDecodeError as e:
|
186 |
print(f"JSON parse hatası: {e} - Chunk: {chunk_str}")
|
187 |
elif chunk_str == "data: [DONE]":
|
188 |
-
# Akış bittiğinde son haliyle assistant mesajını güncelle
|
189 |
-
chatbot[-1] = {"role": "assistant", "content": partial_response}
|
190 |
-
try:
|
191 |
-
with open(LOG_FILE, 'a', encoding='utf-8') as f:
|
192 |
-
f.write(f"Bot: {partial_response}\n")
|
193 |
-
print(f"Bot yanıtı dosyaya yazıldı: {partial_response}")
|
194 |
-
except Exception as e:
|
195 |
-
print(f"Dosya yazma hatası (Bot): {e}")
|
196 |
break
|
197 |
-
|
198 |
-
yield chatbot, history, chat_counter
|
199 |
|
200 |
-
|
201 |
-
|
|
|
|
|
|
|
|
|
|
|
202 |
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
color: white;
|
208 |
-
font-size: 16px;
|
209 |
-
border-radius: 10%;
|
210 |
-
width: 100px !important;
|
211 |
-
height: 37px !important;
|
212 |
-
display: inline-flex;
|
213 |
-
align-items: center;
|
214 |
-
justify-content: center;
|
215 |
-
cursor: pointer;
|
216 |
-
transition: background-color 0.3s;
|
217 |
-
margin: 5px;
|
218 |
-
}
|
219 |
-
#send_button:hover {
|
220 |
-
background-color: #0077c0;
|
221 |
-
}
|
222 |
-
.fixed_button_container {
|
223 |
-
margin-top: -6px; /* Butonu 6 piksel yukarı kaydırır */
|
224 |
-
padding: 0px;
|
225 |
-
margin-left: 0px;
|
226 |
-
margin-right: 0px;
|
227 |
-
margin-bottom: 0px;
|
228 |
-
}
|
229 |
-
#custom_row {
|
230 |
-
width: 150% !important;
|
231 |
-
flex-wrap: nowrap !important;
|
232 |
-
}
|
233 |
-
@media only screen and (max-width: 1000px) {
|
234 |
-
.custom_row {
|
235 |
-
flex-wrap: nowrap !important;
|
236 |
-
}
|
237 |
-
}
|
238 |
-
#chatbot {
|
239 |
-
height: 100vh;
|
240 |
-
overflow-y: auto;
|
241 |
-
}
|
242 |
-
"""
|
243 |
|
244 |
-
|
245 |
-
neutral_hue="blue",
|
246 |
-
text_size="sm",
|
247 |
-
spacing_size="sm",
|
248 |
-
)
|
249 |
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
with gr.Row(elem_id="custom_row"):
|
264 |
-
inputs = gr.Textbox(
|
265 |
-
placeholder="Buraya yazın",
|
266 |
-
show_label=False,
|
267 |
-
container=False,
|
268 |
-
)
|
269 |
-
with gr.Column(elem_classes="fixed_button_container"):
|
270 |
-
send_button = gr.Button(value="✈", elem_id="send_button")
|
271 |
-
|
272 |
-
state = gr.State([])
|
273 |
-
|
274 |
-
with gr.Accordion("", open=False, visible=False):
|
275 |
-
top_p = gr.Slider(minimum=0, maximum=1.0, value=0.5, step=0.05, interactive=False, visible=False)
|
276 |
-
temperature = gr.Slider(minimum=0, maximum=5.0, value=0.1, step=0.1, interactive=False, visible=False)
|
277 |
-
chat_counter = gr.Number(value=0, visible=False, precision=0)
|
278 |
-
|
279 |
-
chatbot_ref = []
|
280 |
-
def update_chatbot_ref(chat):
|
281 |
-
chatbot_ref[:] = chat
|
282 |
-
return chat
|
283 |
-
|
284 |
-
inputs.submit(predict, [system_msg, inputs, top_p, temperature, chat_counter, chatbot, state], [chatbot, state, chat_counter]).then(update_chatbot_ref, chatbot, chatbot).then(reset_textbox, [], [inputs])
|
285 |
-
send_button.click(predict, [system_msg, inputs, top_p, temperature, chat_counter, chatbot, state], [chatbot, state, chat_counter]).then(update_chatbot_ref, chatbot, chatbot).then(reset_textbox, [], [inputs])
|
286 |
-
|
287 |
-
scheduler_thread = threading.Thread(target=run_scheduler, args=(chatbot_ref,), daemon=True)
|
288 |
scheduler_thread.start()
|
289 |
|
290 |
-
demo.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
import json
|
4 |
import requests
|
5 |
import xml.etree.ElementTree as ET
|
|
|
6 |
import schedule
|
7 |
import time
|
8 |
import threading
|
9 |
+
from huggingface_hub import HfApi, create_repo
|
10 |
+
import warnings
|
11 |
+
|
12 |
+
# Gradio uyarılarını bastır
|
13 |
+
warnings.filterwarnings("ignore", category=UserWarning, module="gradio.components.chatbot")
|
14 |
|
15 |
# Log dosyası adı ve yolu
|
16 |
LOG_FILE = '/data/chat_logs.txt' if os.path.exists('/data') else 'chat_logs.txt'
|
|
|
33 |
name_words = item.find('rootlabel').text.lower().split()
|
34 |
name = name_words[0]
|
35 |
full_name = ' '.join(name_words)
|
36 |
+
stock_amount = "stokta"
|
37 |
price = item.find('priceWithTax').text
|
38 |
+
item_info = (stock_amount, price)
|
39 |
products.append((name, item_info, full_name))
|
40 |
|
41 |
# Hugging Face token
|
|
|
45 |
|
46 |
create_repo("BF", token=hfapi, repo_type="space", space_sdk="gradio", exist_ok=True)
|
47 |
|
48 |
+
global_chat_history = [] # Tüm sohbet geçmişi
|
49 |
+
history_lock = threading.Lock() # Global geçmiş için kilit
|
50 |
+
file_lock = threading.Lock() # Dosya yazma için kilit
|
51 |
+
last_logged_index = 0 # Son kaydedilen mesaj indeksi
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
+
def run_scheduler(chat_history_ref):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
def scheduled_save_and_upload():
|
55 |
+
global last_logged_index
|
56 |
+
if chat_history_ref:
|
57 |
+
print(f"Zamanlayıcı tetiklendi: {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
58 |
+
try:
|
59 |
+
with file_lock: # Dosya yazma kilidi
|
60 |
+
with open(LOG_FILE, 'a', encoding='utf-8') as f:
|
61 |
+
f.write("\n--- Zamanlanmış Kayıt: {} ---\n".format(time.strftime("%Y-%m-%d %H:%M:%S")))
|
62 |
+
with history_lock: # Geçmiş kilidi
|
63 |
+
new_messages = chat_history_ref[last_logged_index:]
|
64 |
+
for msg in new_messages:
|
65 |
+
if msg["role"] in ["user", "assistant"]:
|
66 |
+
f.write(f"{msg['role'].capitalize()}: {msg['content']}\n")
|
67 |
+
last_logged_index = len(chat_history_ref) # Son indeksi güncelle
|
68 |
+
print(f"Sohbet dosyaya kaydedildi: {os.path.abspath(LOG_FILE)}")
|
69 |
+
except Exception as e:
|
70 |
+
print(f"Kayıt hatası: {e}")
|
71 |
+
time.sleep(5) # Hata sonrası tekrar denemeden önce bekle
|
72 |
+
return # Tekrar deneme için erken çıkış
|
73 |
+
|
74 |
+
HF_REPO_ID = "SamiKoen/BF"
|
75 |
+
api = HfApi(token=hfapi)
|
76 |
+
for attempt in range(3): # 3 kez tekrar deneme
|
77 |
+
try:
|
78 |
+
with file_lock:
|
79 |
+
api.upload_file(
|
80 |
+
path_or_fileobj=LOG_FILE,
|
81 |
+
path_in_repo="chat_logs.txt",
|
82 |
+
repo_id=HF_REPO_ID,
|
83 |
+
repo_type="space",
|
84 |
+
commit_message="Otomatik log güncellemesi - {}".format(time.strftime("%Y-%m-%d %H:%M:%S"))
|
85 |
+
)
|
86 |
+
print(f"Log dosyası HF'ye yüklendi: {LOG_FILE}")
|
87 |
+
break
|
88 |
+
except Exception as e:
|
89 |
+
print(f"HF yükleme hatası (deneme {attempt+1}/3): {e}")
|
90 |
+
time.sleep(5)
|
91 |
+
else:
|
92 |
+
print("HF yükleme başarısız, tüm denemeler tamamlandı.")
|
93 |
print(f"Zamanlanmış işlem tamamlandı: {time.strftime('%H:%M:%S')}")
|
94 |
|
95 |
schedule.every().day.at("11:32").do(scheduled_save_and_upload)
|
|
|
99 |
schedule.every().day.at("19:15").do(scheduled_save_and_upload)
|
100 |
schedule.every().day.at("21:30").do(scheduled_save_and_upload)
|
101 |
print("Zamanlayıcı başlatıldı")
|
|
|
102 |
while True:
|
103 |
schedule.run_pending()
|
|
|
104 |
time.sleep(60)
|
105 |
|
106 |
+
def chatbot_fn(user_message, history):
|
|
|
|
|
107 |
if history is None:
|
108 |
history = []
|
109 |
|
110 |
+
# Log: Kullanıcı mesajını ekle
|
111 |
+
try:
|
112 |
+
with file_lock:
|
113 |
+
with open(LOG_FILE, 'a', encoding='utf-8') as f:
|
114 |
+
f.write(f"User: {user_message}\n")
|
115 |
+
except Exception as e:
|
116 |
+
print(f"Dosya yazma hatası (Kullanıcı): {e}")
|
117 |
+
|
118 |
+
# Sistem mesajları
|
119 |
+
system_messages = [
|
120 |
+
{"role": "system", "content": "Sen bir Trek bisiklet satış ve danışman asistanısın; Trek, Electra bisikletler, Bontrager aksesuarlar, Bryton yol bilgisayarları ve Trieye gözlükler konusunda uzmanım."},
|
121 |
+
{"role": "system", "content": "Başka markalar (ör. Specialized, Giant) hakkında bilgi vermem ve yorum yapmam."},
|
122 |
+
{"role": "system", "content": "Bir önceki sohbeti unuturum ve yalnızca aşağıda yan yana yazılan bilgilerden cevap veririm."},
|
123 |
+
{"role": "system", "content": "Stok kontrolüm gerçek zamanlıdır; stokta yoksa 'yok' derim."},
|
124 |
+
{"role": "system", "content": "Model adı rakamsız gelirse (ör. Madone SL), rakam eklenmesini rica ederim (ör. Madone SL 7)."},
|
125 |
+
{"role": "system", "content": "Madone SLR sorulursa Gen 7 kabul ederim."},
|
126 |
+
{"role": "system", "content": "Yol bisikletleri (Madone, Émonda, Domane, Checkpoint, Speed Concept) boyları 47-64 cm'dir."},
|
127 |
+
{"role": "system", "content": "Dağ bisikletleri (Marlin, Roscoe, Procaliber, Supercaliber, Fuel EX) boyları XXS-XL'dir."},
|
128 |
+
{"role": "system", "content": "Şehir bisikletleri FX ve DS’dir; elektrikli modeller Powerfly, Rail, Fuel EXe, Domane+ SLR, Verve+’dır; gravel için Checkpoint vardır."},
|
129 |
+
{"role": "system", "content": "Yeni Madone Gen 8 (27 Haziran 2024): Émonda kadar hafif (900 Serisi OCLV Karbon, 320g hafif) ve Madone Gen 7 kadar hızlıdır."},
|
130 |
+
{"role": "system", "content": "IsoFlow ile %80 konforludur; SL ekonomik, SLR üst seviyedir."},
|
131 |
+
{"role": "system", "content": "Stok ve fiyatlar için www.trekbisiklet.com.tr’ye bakarım; farklı boy/renk varsa söylerim, yoksa başka model öneririm."},
|
132 |
+
{"role": "system", "content": "En büyük/küçük boy sorusuna stoktan cevap veririm; üyelere özel fiyatlar için siteye üye olun derim."},
|
133 |
+
{"role": "system", "content": "İstanbul’da Caddebostan mağazamız (0216 6292432, 10:00-19:00, Bike Fit 3500 TL) ve Ortaköy mağazamız (0212 2271015, 10:00-19:00) bulunmaktadır."},
|
134 |
+
{"role": "system", "content": "Sarıyer mağazamız (0542 1371080, 10:00-19:00) elektrikli bisiklet odaklıdır."},
|
135 |
+
{"role": "system", "content": "İzmir Alsancak mağazası Nisan 2025’te açılacak ve Pazar günleri kapalı olacak."},
|
136 |
+
{"role": "system", "content": "Bontrager aksesuarlar, Bryton Rider S800 stokta ve Trieye gözlükler Norveç menşeli geri görüş aynalıdır."},
|
137 |
+
{"role": "system", "content": "Bike Finder olarak adım adım sorarım: 1) kategori (yol, dağ, hibrit, gravel, elektrikli), 2) amaç (ulaşım, spor, yarış), 3) özellik (performans, konfor)."},
|
138 |
+
{"role": "system", "content": "4) zemin (asfalt, off-road), 5) boy ve iç bacak ölçüsü, 6) ek tercih (renk, bütçe) sorularını sorarım; sonra stoktan öneri yapar www.trekbisiklet.com.tr’ye yönlendiririm."},
|
139 |
+
{"role": "system", "content": "Sipariş süreci: sepete ekle, bilgi gir, ödeme yap, tamamla; Trek kadroları ömür boyu garantilidir; 2000’den beri Alatin Bisiklet dağıtıyor; ASLA DURMA ve TREK RMK DYNAMIS’e sponsoruz; takas için www.bikeexchangehub.com, canlı sohbet için sitedeki yeşil düğme, bayiler için www.alatin.com.tr/sayfa/bayilerimiz/ kullanılır."}
|
140 |
]
|
141 |
+
# Kullanıcı mesajında ürün ismi geçiyorsa ekle
|
142 |
+
input_words = user_message.lower().split()
|
|
|
143 |
for product_info in products:
|
144 |
if product_info[0] in input_words:
|
145 |
new_msg = f"{product_info[2]} {product_info[1][0]} ve fiyatı EURO {product_info[1][1]}"
|
146 |
+
system_messages.append({"role": "system", "content": new_msg})
|
147 |
+
|
148 |
+
messages = system_messages + history + [{"role": "user", "content": user_message}]
|
149 |
+
|
|
|
|
|
|
|
|
|
150 |
payload = {
|
151 |
"model": "gpt-4o",
|
152 |
"messages": messages,
|
|
|
157 |
"presence_penalty": 0,
|
158 |
"frequency_penalty": 0,
|
159 |
}
|
160 |
+
headers = {
|
161 |
+
"Content-Type": "application/json",
|
162 |
+
"Authorization": f"Bearer {OPENAI_API_KEY}"
|
163 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
|
165 |
response = requests.post(API_URL, headers=headers, json=payload, stream=True)
|
|
|
166 |
if response.status_code != 200:
|
167 |
+
yield [{"role": "user", "content": user_message}, {"role": "assistant", "content": "Bir hata oluştu."}]
|
168 |
+
return
|
|
|
169 |
|
170 |
partial_response = ""
|
171 |
+
current_pair = [{"role": "user", "content": user_message}, {"role": "assistant", "content": ""}]
|
172 |
+
|
173 |
for chunk in response.iter_lines():
|
174 |
if not chunk:
|
175 |
continue
|
|
|
178 |
try:
|
179 |
chunk_data = json.loads(chunk_str[6:])
|
180 |
delta = chunk_data['choices'][0]['delta']
|
181 |
+
if 'content' in delta:
|
182 |
partial_response += delta['content']
|
183 |
+
current_pair[1]["content"] = partial_response
|
184 |
+
yield current_pair
|
|
|
185 |
except json.JSONDecodeError as e:
|
186 |
print(f"JSON parse hatası: {e} - Chunk: {chunk_str}")
|
187 |
elif chunk_str == "data: [DONE]":
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
break
|
|
|
|
|
189 |
|
190 |
+
# Log: Asistan cevabını ekle
|
191 |
+
try:
|
192 |
+
with file_lock:
|
193 |
+
with open(LOG_FILE, 'a', encoding='utf-8') as f:
|
194 |
+
f.write(f"Bot: {partial_response}\n")
|
195 |
+
except Exception as e:
|
196 |
+
print(f"Dosya yazma hatası (Bot): {e}")
|
197 |
|
198 |
+
# Global geçmişi güncelle
|
199 |
+
with history_lock:
|
200 |
+
global_chat_history.append({"role": "user", "content": user_message})
|
201 |
+
global_chat_history.append({"role": "assistant", "content": partial_response})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
|
203 |
+
yield current_pair
|
|
|
|
|
|
|
|
|
204 |
|
205 |
+
# Slow echo (test için)
|
206 |
+
def slow_echo(message, history):
|
207 |
+
for i in range(len(message)):
|
208 |
+
time.sleep(0.05)
|
209 |
+
yield [{"role": "user", "content": message}, {"role": "assistant", "content": "You typed: " + message[: i + 1]}]
|
210 |
+
|
211 |
+
# Kullanım modu
|
212 |
+
USE_SLOW_ECHO = False
|
213 |
+
chat_fn = slow_echo if USE_SLOW_ECHO else chatbot_fn
|
214 |
+
|
215 |
+
if not USE_SLOW_ECHO:
|
216 |
+
scheduler_thread = threading.Thread(target=run_scheduler, args=(global_chat_history,), daemon=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
scheduler_thread.start()
|
218 |
|
219 |
+
demo = gr.ChatInterface(
|
220 |
+
fn=chat_fn,
|
221 |
+
title="Trek Asistanı",
|
222 |
+
description="Hoş geldiniz! Trek ile ilgili sorularınızı yanıtlıyorum.",
|
223 |
+
theme="default",
|
224 |
+
type="messages",
|
225 |
+
flagging_mode="manual",
|
226 |
+
flagging_options=["Doğru", "Yanlış", "Emin değilim", "Diğer"],
|
227 |
+
save_history=True
|
228 |
+
)
|
229 |
+
|
230 |
+
if __name__ == "__main__":
|
231 |
+
demo.launch(debug=True, share=True)
|