File size: 6,052 Bytes
4145939
43ef72c
4145939
b365cdb
43ef72c
b365cdb
43ef72c
 
4145939
43ef72c
 
b365cdb
 
 
 
 
 
 
43ef72c
4145939
b365cdb
43ef72c
4e3871a
 
 
b365cdb
43ef72c
b365cdb
 
43ef72c
 
 
 
 
4e3871a
43ef72c
4e3871a
 
b365cdb
4e3871a
 
 
 
b365cdb
 
 
 
 
4145939
43ef72c
 
4e3871a
 
 
43ef72c
b365cdb
43ef72c
 
b365cdb
43ef72c
b365cdb
43ef72c
 
b365cdb
43ef72c
 
 
 
b365cdb
4e3871a
b365cdb
43ef72c
b365cdb
 
4145939
43ef72c
4e3871a
b365cdb
43ef72c
4145939
b365cdb
4e3871a
 
 
b365cdb
 
4e3871a
4145939
b365cdb
43ef72c
 
4e3871a
b365cdb
 
43ef72c
4e3871a
b365cdb
 
43ef72c
b365cdb
 
4e3871a
43ef72c
b365cdb
43ef72c
4e3871a
43ef72c
b365cdb
43ef72c
 
4145939
b365cdb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4145939
b365cdb
4145939
43ef72c
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
import gradio as gr
from openai import OpenAI

# Инициализация клиента DeepSeek
client = OpenAI(
    api_key="sk-a02694cf3c8640c9ae60428ee2c5a62e",  # ЗАМЕНИТЕ на свой ключ
    base_url="https://api.deepseek.com"
)

def chat_with_deepseek(user_message, history):
    """
    user_message: строка, введённая пользователем.
    history: список словарей формата [{"role": ..., "content": ...}, ...]
             (в формате для Gradio Chatbot c type="messages").

    Возвращает (new_history, new_history, ""), где:
      - new_history — обновлённая история для Chatbot
      - "" — чтобы очистить поле ввода.
    """

    # Преобразуем history в messages для DeepSeek (по сути — то же самое, но на всякий случай)
    messages = []
    for item in history:
        messages.append({"role": item["role"], "content": item["content"]})
    
    # Добавляем текущее сообщение пользователя
    messages.append({"role": "user", "content": user_message})

    # Вызываем модель deepseek-reasoner
    try:
        response = client.chat.completions.create(
            model="deepseek-reasoner",
            messages=messages
        )
        assistant_content = response.choices[0].message.content
    except Exception as e:
        assistant_content = f"Ошибка при обращении к API: {e}"

    # Формируем новое состояние истории
    new_history = history + [
        {"role": "user", "content": user_message},
        {"role": "assistant", "content": assistant_content}
    ]
    # Возвращаем:
    # 1) обновлённый чат для Chatbot,
    # 2) обновлённый state,
    # 3) пустую строку для очистки поля ввода
    return new_history, new_history, ""

with gr.Blocks(
    theme=gr.themes.Base(
        primary_hue="slate",
        secondary_hue="blue",
        neutral_hue="slate",
        text_size="md",
        font=["Arial", "sans-serif"]
    ),
    css="""
    /* Чёрный фон для всего приложения */
    body {
        background-color: #000000 !important;
    }
    .block.block--main {
        background-color: #000000 !important;
    }
    .gradio-container {
        color: #ffffff !important;
    }
    /* Фон области чата */
    #chatbot {
        background-color: #111111 !important;
    }
    """
) as demo:

    gr.Markdown(
        "<h1 style='text-align:center; color:#ffffff;'>Чат с deepseek-reasoner</h1>"
        "<p style='text-align:center; color:#bbbbbb;'>Нажмите Enter, чтобы отправить; Ctrl+Enter для новой строки</p>"
    )

    # Компонент чата в «сообщениях» (OpenAI-стиле)
    chatbot = gr.Chatbot(
        label="Диалог",
        height=400,
        type="messages",
        elem_id="chatbot"
    )

    # Поле ввода
    msg = gr.Textbox(
        label="Ваш вопрос",
        placeholder="Введите сообщение...",
        lines=2,  # можно увеличить
        elem_id="user_input"
    )

    # Кнопка "Отправить"
    send_btn = gr.Button("Отправить", variant="primary", elem_id="send_button")

    # Gradio-хранилище истории
    # (по умолчанию пустой список [{"role": "...", "content": "..."}])
    state = gr.State([])

    # При клике на кнопку: вызываем функцию, обновляем чат и очищаем поле ввода
    send_btn.click(
        fn=chat_with_deepseek,
        inputs=[msg, state],
        outputs=[chatbot, state, msg],
        scroll_to_output=True
    )

    # Здесь мы не используем msg.submit(...), так как будем обрабатывать Enter
    # через JavaScript (чтобы Ctrl+Enter давал перенос строки).

    # Подключаем JS-код, который перехватывает Enter и Ctrl+Enter
    # - Enter => отправка (нажатие на send_button)
    # - Ctrl+Enter => вставка новой строки
    custom_js = """
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        // Ищем textarea внутри элемента #user_input
        const userInput = document.querySelector('#user_input textarea');
        // Ищем кнопку внутри #send_button
        const sendButton = document.querySelector('#send_button button');

        if (userInput && sendButton) {
            userInput.addEventListener('keydown', function(e) {
                if (e.key === 'Enter') {
                    if (e.ctrlKey) {
                        // Ctrl+Enter => вставляем новую строку
                        e.preventDefault();
                        const start = userInput.selectionStart;
                        const end = userInput.selectionEnd;
                        userInput.value = userInput.value.substring(0, start) 
                                         + "\\n" 
                                         + userInput.value.substring(end);
                        // Устанавливаем курсор ниже
                        userInput.selectionStart = userInput.selectionEnd = start + 1;
                    } else {
                        // Просто Enter => отправляем
                        e.preventDefault();
                        sendButton.click();
                    }
                }
            });
        }
    });
    </script>
    """

    # Добавляем HTML-блок с нашим кастомным JS
    gr.HTML(custom_js)

# Запуск приложения
if __name__ == "__main__":
    demo.launch(server_name="0.0.0.0", server_port=7860)