File size: 6,397 Bytes
f63951f
99ad768
 
67da721
99ad768
61ddbf5
f63951f
99ad768
1b96f25
 
 
 
 
 
99ad768
ca2b862
43b505a
 
1b96f25
43b505a
c0cbb22
 
 
 
 
 
 
11e1de5
 
460611e
 
 
 
 
 
 
 
 
 
 
 
 
4259c8a
460611e
 
 
c0cbb22
 
 
 
43b505a
 
c0cbb22
 
 
11e1de5
 
 
 
c0cbb22
 
 
 
 
 
43b505a
f63951f
99ad768
43b505a
99ad768
 
 
 
 
 
 
 
 
 
 
 
61ddbf5
99ad768
f63951f
1b96f25
 
99ad768
1b96f25
 
99ad768
 
f63951f
99ad768
 
43b505a
 
433ad14
 
43b505a
 
 
 
 
 
 
 
433ad14
43b505a
99ad768
433ad14
99ad768
43b505a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1b96f25
99ad768
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
import gradio as gr
import requests
import os
import base64
from PIL import Image
import io

# Функция для кодирования изображения в base64
def encode_image_to_base64(image):
    buffered = io.BytesIO()
    image.save(buffered, format="JPEG")
    img_str = base64.b64encode(buffered.getvalue()).decode("utf-8")
    return img_str

# Функция для отправки запроса в OpenAI с изображением и получения ответа
def ask_openai_with_image(instruction, image, low):
    start = "..."  # Ваше начальное сообщение для OpenAI
    # В вашем коде необходимо определить переменную start

    if image is not None:
        # Кодируем загруженное изображение в base64
        base64_image = encode_image_to_base64(image)

        # Создаем данные для запроса с закодированным изображением
        payload = {
            "model": "gpt-4-vision-preview",
            "messages": [
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "text",
                            "text": start,
                        },
                        {
                            "type": "text",
                            "text": instruction,
                        },
                        {
                            "type": "image_url",
                            "image_url": {
                                "url": f"data:image/jpeg;base64,{base64_image}",
                                "detail": "high",
                            },
                        },
                    ],
                }
            ],
            "max_tokens": 4095,
        }
    else:
        # Создаем данные для запроса без изображения
        payload = {
            "model": "gpt-4-vision-preview",
            "messages": [
                {
                    "role": "user",
                    "content": start,
                },
                {
                    "role": "user",
                    "content": instruction,
                }
            ],
            "max_tokens": 4095,
        }

    # API ключ для OpenAI
    api_key = os.getenv("OPENAI_API_KEY")

    # Заголовки для запроса
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json',
    }

    # URL для запроса к API OpenAI
    url = "https://api.openai.com/v1/chat/completions"

    # Отправляем запрос в OpenAI
    response = requests.post(url, headers=headers, json=payload)

    # Проверяем ответ и возвращаем результат
    if response.status_code == 200:
        response_json = response.json()
        try:
            # Пытаемся извлечь текст из ответа
            return response_json["choices"][0]["message"]["content"]
        except Exception as e:
            # Если есть ошибка в структуре JSON, выводим ее
            return f"Error processing the image response: {e}"
    else:
        # Если произошла ошибка, возвращаем сообщение об ошибке
        return f"Error: {response.status_code} - {response.text}"

# CSS стили для интерфейса
css = """
footer {visibility: hidden !important;}
#message-input {width: calc(100% - 75px);}
#image-preview {border-radius: 10px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); max-width: 100px; max-height: 100px;}
#send-button {margin-left: 10px;}
#attachment-button {margin-right: 10px;}
.chat-container {height: calc(100vh - 70px); overflow-y: auto;}
.message {margin: 10px; padding: 10px; border-radius: 10px; background-color: #f0f0f0;}
.message.ai {background-color: #d1e7dd;}
.message.user {background-color: #f8d7da;}
"""

# Создаем интерфейс с помощью Gradio
with gr.Blocks(css=css) as demo:
    with gr.Row():
        chat_container = gr.Column(variant="panel", scroll="auto", id="chat-container", elem_id="chat-container")
        with chat_container:
            gr.Markdown("Привет! Я Помогатор, готов помочь тебе с любыми вопросами!) 😊", css_classes=["message", "ai"])
    
    with gr.Row():
        attachment_button = gr.Button(value="📎", id="attachment-button")
        message_input = gr.Textbox(placeholder="Напишите сообщение...", id="message-input")
        send_button = gr.Button(value="➤", id="send-button")
        image_input = gr.Image(type="pil", interactive=False, visible=False, id="image-preview")

    def send_message(message, image):
        if image is not None:
            image_base64 = encode_image_to_base64(image)
            ai_response = ask_openai_with_image(message, image, low=False)
        else:
            ai_response = ask_openai_with_image(message, None, low=False)
        
        # Добавляем сообщение пользователя в чат
        with chat_container:
            gr.Markdown(f"**Вы:** {message}", css_classes=["message", "user"])
            gr.Markdown(f"**AI:** {ai_response}", css_classes=["message", "ai"])
        # Очищаем поле ввода сообщения
        message_input.update(value="")
        # Если было загружено изображение, убираем его
        if image is not None:
            clear_image()

    def upload_image(file):
        if file is not None:
            image_input.update(value=file, visible=True)
            attachment_button.update(value="❌")
        else:
            image_input.update(value=None, visible=False)
            attachment_button.update(value="📎")

    def clear_image():
        image_input.update(value=None, visible=False)
        attachment_button.update(value="📎")

    message_input.change(send_message, [message_input, image_input], chat_container)
    send_button.click(send_message, [message_input, image_input], chat_container)
    attachment_button.click(clear_image if attachment_button.value == "❌" else upload_image, image_input, image_input)

demo.launch()