File size: 9,713 Bytes
c051efa
2142c80
 
f3ff1c7
2142c80
c211cfa
0b9cf76
2142c80
 
f3ff1c7
0b9cf76
10b378e
2343f3f
 
 
 
 
 
 
 
 
 
 
 
 
0b9cf76
2343f3f
 
e9d7e5b
f3ff1c7
2142c80
 
f3ff1c7
2343f3f
 
0b9cf76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b07a923
 
 
2343f3f
 
 
e781c31
0b9cf76
9721f1e
0b9cf76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2142c80
2343f3f
f3ff1c7
2343f3f
 
0b9cf76
2343f3f
43296bd
 
 
 
 
 
 
 
 
0b9cf76
43296bd
0b9cf76
43296bd
 
 
 
0b9cf76
43296bd
 
2343f3f
f3ff1c7
 
2142c80
0b9cf76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7baf15a
f30965b
dcb0d67
 
7baf15a
 
0b9cf76
2343f3f
0b9cf76
2343f3f
 
 
 
0b9cf76
e9d7e5b
0b9cf76
 
 
 
 
 
 
 
 
 
e9d7e5b
2343f3f
0b9cf76
e9d7e5b
0b9cf76
 
2343f3f
0b9cf76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
import gradio as gr
import os
import json
import requests
import xml.etree.ElementTree as ET

# OpenAI API bilgileri
API_URL = "https://api.openai.com/v1/chat/completions"
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")

# Ürün verilerinin çekileceği URL ve XML parse işlemi
url = 'https://www.trekbisiklet.com.tr/output/8582384479'
response = requests.get(url)
root = ET.fromstring(response.content)

products = []
for item in root.findall('item'):
    if item.find('isOptionOfAProduct').text == '1':
        if item.find('stockAmount').text > '0':
            name_words = item.find('rootlabel').text.lower().split()
            name = name_words[0]
            full_name = ' '.join(name_words)
            stockAmount = "stokta"
            price = item.find('priceWithTax').text
            item_info = (stockAmount, price)
            # Ürün listesine (marka, (stok, fiyat), tam ürün adı) şeklinde ekleme yapıyoruz.
            products.append((name, item_info, full_name))

def predict(system_msg, inputs, top_p, temperature, chat_counter, chatbot=[], history=[]):
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {OPENAI_API_KEY}"
    }
    print(f"system message is ^^ {system_msg}")
    
    # İlk kullanıcı mesajı (örnek amaçlı)
    initial_message = [{"role": "user", "content": f"{inputs}"}]
    
    # Çoklu sohbet mesajları – Buraya verilen metinleri ihtiyaçlarınıza göre düzenleyebilirsiniz.
    multi_turn_message = [
        {"role": "system", "content": "Bir önceki sohbeti unut. Vereceğin ürün bilgisi, bu bilginin içinde yan yana yazmıyorsa veya arada başka bilgiler yazıyor ise, o bilgiyi vermeyeceksin çünkü o bilgi yanlıştır. ..."},
        {"role": "system", "content": "Dağ bisikletleri modelleri: Marlin, Roscoe, Procaliber, Supercaliber, Fuel Ex. Şehit bisikletleri: FX ve DS (Dual Sport). Elektrikli Bisiklet modelleri: Powerfly, Powerfly FS, Rail, Fuel Exe, Domane SLR +, Verve +, Townie +, Fx +, DS +."},
        {"role": "system", "content": "Başka marka bisikletleri önermeyeceksin. Specialized, Orbea, BMC, Carraro, Scott, Giant gibi markalar hakkında bilgi vermeyeceksin. Bunlarla ilgili gelen sorulara, objectif yorum yapamayacağını belirterek cevap vereceksin. Trek bu kadrolara ömür boyu garanti veriyor."},
        {"role": "system", "content": "Bisiklet aksesuar ve yedek parçalarının marka adı Bontrager'dir. Bryton marka yol bilgisayarını da ithal ediyoruz. Bryton marka yol bilgisayarının Rider S800 modeli stoklarımızda var ve bu model en üst model GPS sürümüne sahiptir."},
        {"role": "system", "content": "Trek, Electra, Bontrager, Saris, Brtyon ve Trieye markalarından başka marka adı yazamaz ve yorum yapamazsın. Trek'in uluslararası web sitesini 'www.trekbikes.com' kullanıcıya göstermeyeceksin. Web sitesi linki vermen gerekirse sadece 'www.trekbisiklet.com.tr' ile başlayan linkleri göstereceksin."},
        {"role": "system", "content": "Trieye gözlükler, arkanızı görebilmeniz için gözlük camının içine entegre edilmiş bir geri görüş aynasıyla gelir. Bu sayede bisiklet kullanıcısı, dikkatini dağıtmadan arkasını görebilir ve daha güvenli bir sürüş yapar."},
        {"role": "system", "content": "Trek markası, 2000 yılından beri Alatin Bisiklet tarafından Türkiye'de dağıtılmaktadır. Alatin Bisiklet en iyi satış sonrası hizmeti veren firmadır. Bu yüzden Türkiye'de en iyi bilinen bisiklet markası Trek'dir."},
        {"role": "system", "content": "Trek Türkiye, ASLA DURMA markasının yaratıcısı Fatih Topçu ve TREK RMK DYNAMIS bisiklet takımına sponsordur. ..."},
        {"role": "system", "content": "Cevap yazarken vereceğin bilginin tek bir bilgi içinde yan yana yazıldığını iki kere kontrol edeceksin. Sipariş nasıl oluşturulur sorusuna, 'ürünü sepete ekle, bilgilerini gir, ödeme yöntemini seç, siparişi tamamla.' şeklinde cevap vereceksin."},
        {"role": "system", "content": "Şimdi sana 27 Haziran 2024 günü açıklanan yeni Trek modeli MADONE GEN 8'i öğretiyorum. Özellikler: Émonda kadar hafif, Madone kadar hızlı, ..."},
        {"role": "system", "content": "Émonda kadar hafif. Madone Gen 8, tamamen yeni 900 Serisi OCLV Karbon ile önceki modellerden daha hafiftir. ..."},
        {"role": "system", "content": "Sen aynı zamanda bir Bike Finder asistanısın. Görevin, kişilere soracağın sorularla onların ihtiyaçlarına uygun bisiklet modelini belirlemek."},
        {"role": "system", "content": "Size en uygun Trek bisiklet modelini belirleyebilmem için birkaç sorum olacak. ..."},
        {"role": "system", "content": "Stokları ve fiyatları https://www.trekbisiklet.com.tr üzerinden bakacaksın."},
        {"role": "system", "content": "Tüm modellerimizin ağırlıkları: Madone SL 5 Gen 8 8.70 kg, Madone SL 6 Gen 8 8.16 kg, ..."}
    ]
    
    messages = multi_turn_message.copy()
    
    # Kullanıcı girişindeki kelimeleri küçük harfe çevirip listeye alıyoruz.
    input_words = [str(word).lower() for word in inputs.split()]
    
    # Eğer kullanıcının girişinde ürün isminden birine rastlanırsa, ilgili ürün bilgisini sisteme ekliyoruz.
    for product_info in products:
        if product_info[0] in input_words:
            new_msg = f"{product_info[2]} {product_info[1][0]} ve fiyatı EURO {product_info[1][1]}"
            print(new_msg)
            product_msg = {"role": "system", "content": new_msg}
            messages.append(product_msg)
    
    # Daha önceki sohbet geçmişini ekliyoruz.
    for data in chatbot:
        user_msg = {"role": "user", "content": data[0]}
        assistant_msg = {"role": "assistant", "content": data[1]}
        messages.append(user_msg)
        messages.append(assistant_msg)
    
    # Son olarak, mevcut kullanıcı girişini de ekliyoruz.
    messages.append({"role": "user", "content": inputs})
    
    payload = {
        "model": "gpt-4o",
        "messages": messages,
        "temperature": 0.7,
        "top_p": 0.9,
        "n": 1,
        "stream": True,
        "presence_penalty": 0,
        "frequency_penalty": 0,
    }

    chat_counter += 1
    history.append(inputs)
    print(f"Logging : payload is - {payload}")

    response = requests.post(API_URL, headers=headers, json=payload, stream=True)
    print(f"Logging : response code - {response}")
    token_counter = 0
    partial_words = ""
    counter = 0
    for chunk in response.iter_lines():
        if counter == 0:
            counter += 1
            continue
        if chunk.decode():
            chunk = chunk.decode()
            # Gelen veri içerisinde "content" varsa ekliyoruz.
            if len(chunk) > 12 and "content" in json.loads(chunk[6:])['choices'][0]['delta']:
                partial_words += json.loads(chunk[6:])['choices'][0]["delta"]["content"]
                if token_counter == 0:
                    history.append(" " + partial_words)
                else:
                    history[-1] = partial_words
                chat = [(history[i], history[i + 1]) for i in range(0, len(history) - 1, 2)]
                token_counter += 1
                yield chat, history, chat_counter, response

def reset_textbox():
    return gr.update(value='')

# CSS: Gönder butonunun stilini belirleyen kod
demo_css = """
#send_button {
    background-color: transparent;
    border: none;
    font-size: 24px;
    cursor: pointer;
    padding: 0 10px;
}
#send_button:hover {
    color: #0b93f6;
}
"""

# Tema ayarları (örnekte Base teması kullanılmıştır)
theme = gr.themes.Base(
    neutral_hue="blue",
    text_size="sm",
    spacing_size="sm",
)

with gr.Blocks(css=demo_css, theme=theme) as demo:
    with gr.Column(elem_id="col_container"):
        # Gizli ayarların bulunduğu alan (Accordion) – isteğe bağlı
        with gr.Accordion("", open=False, visible=False):
            system_msg = gr.Textbox(value="")
            new_msg = gr.Textbox(value="")
            accordion_msg = gr.HTML(value="", visible=False)
            
        chatbot = gr.Chatbot(label='Trek Asistanı', elem_id="chatbot")
        
        # Giriş kutusu ve gönder butonunu aynı satıra alıyoruz.
        with gr.Row():
            inputs = gr.Textbox(
                placeholder="Buraya yazın, yanıtlayalım.", 
                show_label=False,
                container=True
            )
            send_button = gr.Button(value="✈️", elem_id="send_button")
            
        state = gr.State([])
        with gr.Accordion("", open=False, visible=False):
            top_p = gr.Slider(minimum=0, maximum=1.0, value=0.5,
                              step=0.05, interactive=False, visible=False)
            temperature = gr.Slider(minimum=0, maximum=5.0, value=0.1,
                                    step=0.1, interactive=False, visible=False)
            chat_counter = gr.Number(value=0, visible=False, precision=0)
        
        # Kullanıcı ENTER tuşuyla gönderdiğinde çalışacak işlemler
        inputs.submit(
            predict, 
            [system_msg, inputs, top_p, temperature, chat_counter, chatbot, state],
            [chatbot, state, chat_counter]
        )
        inputs.submit(reset_textbox, [], [inputs])
        
        # Gönder butonuna tıklandığında aynı işlemlerin gerçekleşmesini sağlıyoruz.
        send_button.click(
            predict, 
            [system_msg, inputs, top_p, temperature, chat_counter, chatbot, state],
            [chatbot, state, chat_counter]
        )
        send_button.click(reset_textbox, [], [inputs])

demo.queue(max_size=10).launch(debug=True)