File size: 7,654 Bytes
6efabbd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3a44296
aea4153
6efabbd
3a44296
6efabbd
 
 
 
3a44296
6efabbd
2122d83
6efabbd
 
2122d83
 
3a44296
6efabbd
 
 
 
 
3a44296
6efabbd
 
 
 
 
3a44296
6efabbd
 
 
 
3a44296
 
6efabbd
 
 
 
 
 
3a44296
 
 
 
6efabbd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3a44296
c6b18de
3a44296
 
 
 
c6b18de
6efabbd
 
 
3a44296
6efabbd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2122d83
6efabbd
2122d83
3a44296
 
 
 
6efabbd
 
 
3a44296
 
 
6efabbd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2122d83
6efabbd
3a44296
6efabbd
 
 
 
 
 
 
 
3a44296
 
 
6efabbd
 
 
 
 
 
 
 
 
 
 
4b871d0
 
2122d83
6efabbd
2122d83
6efabbd
2122d83
3a44296
6efabbd
 
 
 
 
 
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
187
188
189
190
191
192
193
194
195
import gradio
from huggingface_hub import InferenceClient

import datetime
import uuid
import json

import re

import os
import sys

history = [
    {"role": "system", "content": ""},
]


tmp_dir = os.getenv('GRADIO_TEMP_DIR')


def generate_uuid():
    _uuid = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + str(uuid.uuid4())
    return _uuid


def write_current_chat_to_file(current_chat):
    os.makedirs(tmp_dir, exist_ok = True)
    with open(f"{tmp_dir}/{current_chat['chat_id']}.json", "w") as f:
        json.dump(current_chat, f, indent = 4)
    
    return gradio.DownloadButton(f"{tmp_dir}/{current_chat['chat_id']}.json")
        

def process_input_message(message_box, current_chat):
    current_chat["chat_history"].append({"role": "user", "content": message_box["text"]})
    return current_chat


def get_text_between_tags(text, start_tag, end_tag):
    pattern = rf'{re.escape(start_tag)}(.*?){re.escape(end_tag)}'
    match = re.search(pattern, text, re.DOTALL)
    return match.group(1) if match else ""


def remove_text_between_tags(text, start_tag, end_tag):
    pattern = rf'{re.escape(start_tag)}.*?{re.escape(end_tag)}'
    return re.sub(pattern, '', text, flags=re.DOTALL)


def call_chatbot(api_token, current_chat, system_message, max_tokens, temperature, top_p, use_thoughts_as_context):
    client = InferenceClient(
        provider = "hf-inference",
        api_key = api_token
    )

    current_chat["chat_history"][0]["content"] = system_message
    current_chat["chat_history"].append({"content": "", "role": "assistant"})
    
    messages = current_chat["chat_history"] if use_thoughts_as_context else [message for message in current_chat["chat_history"] if "metadata" not in message.keys()]
    print(messages)
    
    stream = client.chat.completions.create(
        model = "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B", 
        messages = current_chat["chat_history"], 
        max_tokens = max_tokens,
        temperature = temperature,
        top_p = top_p,
        stream = True
    )

    response = ""
    for chunk in stream:
        response = response + chunk.choices[0].delta.content
        current_chat["chat_history"][-1]["content"] = response
        yield current_chat["chat_history"], current_chat
        #yield current_chat["chat_history"], current_chat
    
    current_chat["chat_history"][-1] = {
        "content": get_text_between_tags("<begin>" + response, "<begin>", "</think>").replace("<think>", ""), 
        "role": "assistant", 
        "metadata": {
            "title": "💭 Thoughts:"
        }}
    current_chat["chat_history"].append({"content": get_text_between_tags(response + "</end>", "</think>", "</end>"), "role": "assistant"})
    
    yield current_chat["chat_history"], current_chat
    
    
def reset_chat():
    chatbot = gradio.Chatbot(history, type = "messages")
    message_box = gradio.MultimodalTextbox(
        value = "",
        interactive = True,
        file_count = "multiple",
        placeholder = "Enter message...",
        show_label = False,
        sources = [],
        stop_btn = True,
    )
    
    current_chat_id = generate_uuid()
    current_chat = gradio.JSON(
        {
            "version": "0.1",
            "chat_id": current_chat_id, 
            "chat_history": history
        }
    )
    download_file = gradio.File(label = "Save", value = f"{tmp_dir}/{current_chat_id}.json")
    
    return chatbot, message_box, current_chat, download_file


def reset_parameters():
    system_message = gradio.Textbox(label = "System Message", value = "You are a helpful bot. Be concise with your answers. Do not think with more than 3 lines. Answer in 2 lines. Only answer in English.")
    max_tokens = gradio.Slider(label = "Max Tokens", minimum = 500, maximum = 3000, step = 100, value = 1000)
    temperature = gradio.Slider(label = "Temperature", minimum = 0.1, maximum = 2.0, step = 0.1, value = 0.5)
    top_p = gradio.Slider(label = "Top P", minimum = 0.1, maximum = 1.0, step = 0.1, value = 0.9)
    use_thoughts_as_context = gradio.Checkbox(value = False, label = "Use thoughts as context")
    return  system_message, max_tokens, temperature, top_p, use_thoughts_as_context


def process_token(secret_token):
    try:
        passwords = os.environ.get("PASSWORDS")
        passwords = passwords.split(":")
        
        if secret_token in passwords:
            secret_token = os.environ.get("HF_KEY")
        
        return secret_token
    except:
        return secret_token
    
    
with gradio.Blocks(fill_height = True) as base_app:
    gradio.Markdown("# ChatSeek")
    gradio.Markdown("## ")
    
    with gradio.Row():
        with gradio.Column(scale = 2):
            secret_token = gradio.Textbox(label = "API Key", placeholder = "Enter Password/API Token. The key is never stored.", type = "password")
    
    chatbot = gradio.Chatbot(history, type = "messages")
    message_box = gradio.MultimodalTextbox(
        interactive = True,
        file_count = "multiple",
        placeholder = "Enter message...",
        show_label = False,
        sources = [],
        stop_btn = True,
    )
    
    current_chat_id = generate_uuid()
    
    with gradio.Row(equal_height = True):
        with gradio.Column():
            reset_chat_button = gradio.Button(value = "Start a New Chat")
        with gradio.Column():
            save_chat_button = gradio.DownloadButton(label = "Save", value = f"{tmp_dir}/{current_chat_id}.json")
            
    with gradio.Accordion(label = "Advanced Parameters", open = False):
        system_message = gradio.Textbox(label = "System Message", value = "You are a helpful bot. Be concise with your answers. Do not think with more than 3 lines. Answer in 2 lines. Only answer in English.")
        max_tokens = gradio.Slider(label = "Max Tokens", minimum = 500, maximum = 3000, step = 100, value = 1000)
        temperature = gradio.Slider(label = "Temperature", minimum = 0.1, maximum = 2.0, step = 0.1, value = 0.5)
        top_p = gradio.Slider(label = "Top P", minimum = 0.1, maximum = 1.0, step = 0.1, value = 0.9)
        use_thoughts_as_context = gradio.Checkbox(value = False, label = "Use thoughts as context")
        
        reset_parameters_button = gradio.Button(value = "Reset Parameters")
    
    with gradio.Accordion(label = "Metadata", open = False):
        current_chat = gradio.JSON(
            {
                "version": "0.1",
                "chat_id": current_chat_id, 
                "chat_history": history
            },
            visible = True
        )
    
    secret_token_submit_call = secret_token.submit(process_token, [secret_token], [secret_token])
    
    submit_message_call = message_box.submit(process_input_message, [message_box, current_chat], [current_chat], queue=False).then(write_current_chat_to_file, [current_chat], [save_chat_button])
    clear_message_box_call = submit_message_call.then(lambda: gradio.MultimodalTextbox(value = "", interactive = True) , None, [message_box])
    invoke_chatbot_call = clear_message_box_call.then(call_chatbot, [secret_token, current_chat, system_message, max_tokens, temperature, top_p, use_thoughts_as_context], [chatbot, current_chat]).then(write_current_chat_to_file, [current_chat], [save_chat_button])
    
    reset_chat_button_call = reset_chat_button.click(reset_chat, [], [chatbot, message_box, current_chat])
    reset_parameters_button_call = reset_parameters_button.click(reset_parameters, [], [system_message, max_tokens, temperature, top_p, use_thoughts_as_context])
    
if __name__ == "__main__":
    base_app.launch(
        allowed_paths = [tmp_dir]
    )