vlasdadsda commited on
Commit
428a486
·
verified ·
1 Parent(s): 1c53431

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +360 -110
app.py CHANGED
@@ -1,9 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
1
  import g4f
2
  import gradio as gr
3
  import tempfile
4
  import os
5
  from pathlib import Path
6
- from g4f.client import Client
7
  from PIL import Image
8
  import io
9
  import requests
@@ -13,21 +24,32 @@ import subprocess
13
  import sys
14
  import time
15
  from typing import Dict, Any, Optional
 
 
16
 
17
  AVAILABLE_MODELS = {
18
  "GPT-4": "gpt-4",
19
  "GPT-4 Turbo": "gpt-4-turbo",
20
  "GPT-4o": "gpt-4o",
 
21
  }
22
 
23
  SYSTEM_PROMPT = """
24
  1. Всегда используйте кодировку UTF-8
25
  2. Используйте обработку ошибок
26
- 3. Если пользователь просит нарисовать или сгенерировать изображение:
 
 
 
 
27
  - Начните ответ с [GENERATE_IMAGE]
28
- - Напишите детальный промпт на английском языке
29
  - Завершите промпт строкой [/GENERATE_IMAGE]
30
  - Продолжите обычный ответ на русском языке
 
 
 
 
31
  """
32
 
33
  def test_code(code: str, file_type: str = ".py") -> Dict[str, Any]:
@@ -80,7 +102,7 @@ def process_file(file):
80
  return None
81
 
82
  try:
83
- # Получаем расширение файла
84
  file_extension = file.name.lower().split('.')[-1] if hasattr(file, 'name') else ''
85
 
86
  # Список поддерживаемых форматов изображений
@@ -132,7 +154,7 @@ def generate_image(prompt: str) -> str:
132
  try:
133
  client = Client()
134
  response = client.images.generate(
135
- model="flux-pro",
136
  prompt=prompt,
137
  response_format="url"
138
  )
@@ -141,20 +163,22 @@ def generate_image(prompt: str) -> str:
141
  return f"Ошибка при генерации изобраения: {str(e)}"
142
 
143
  def process_image(image_input) -> str:
144
- """Обработка изображения и распознавание объектов через YOLOv8"""
145
  try:
146
  # Загружаем модель YOLOv8n
147
- model = YOLO('s.pt')
148
 
149
- # Если передан URL
 
 
 
150
  if isinstance(image_input, str):
151
  response = requests.get(image_input)
152
  image = Image.open(io.BytesIO(response.content))
153
- # Если передан объект изображения
154
  elif isinstance(image_input, Image.Image):
155
  image = image_input
156
  else:
157
- return "❌ Неподдерживаемый формат изображения"
158
 
159
  # Конвертируем изображение в RGB если оно в RGBA
160
  if image.mode == 'RGBA':
@@ -163,9 +187,12 @@ def process_image(image_input) -> str:
163
  # Сохраняем изображение во временный файл для обработки
164
  with tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) as tmp:
165
  image.save(tmp.name, format='JPEG')
166
- # Запускаем ра��познавание
167
  results = model(tmp.name)
168
 
 
 
 
169
  # Собираем найденные объекты
170
  detected_objects = []
171
  for r in results:
@@ -174,12 +201,30 @@ def process_image(image_input) -> str:
174
  class_name = model.names[class_id]
175
  detected_objects.append(class_name)
176
 
177
- if not detected_objects:
178
- return ничего не вижу на этом изображении."
179
-
180
- # Переводим объекты на русский
181
- objects_str = ", ".join(detected_objects)
 
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  messages = [
184
  {
185
  "role": "system",
@@ -188,93 +233,166 @@ def process_image(image_input) -> str:
188
  1. Перевести названия объектов на русский язык
189
  2. Описать что ты видишь простыми словами
190
  3. Всегда отвечать на русском языке
191
- 4. Начинать ответ со слов на этом изображении вижу..."
192
- 5. Никогда не говри "Похоже,что у вас есть описание изображения..."
193
  """
194
  },
195
  {
196
  "role": "user",
197
- "content": f"Переведи и опиши эти объекты: {objects_str}"
198
  }
199
  ]
200
 
201
  response = g4f.ChatCompletion.create(
202
  model="gpt-4o",
203
- messages=messages,
204
- # provider=g4f.Provider.Airforce
205
  )
206
 
207
- # Сохраняем результат в истории чата
208
- if isinstance(response, str):
209
- return response
210
- elif isinstance(response, dict) and "content" in response:
211
- return response["content"]
212
- else:
213
- # Если что-то пошло не так, хотя бы покажем список объектов
214
- return f"Я на этом изображении вижу: {objects_str}"
215
-
216
  except Exception as e:
217
  return f"❌ Ошибка при обработке изображения: {str(e)}"
218
  finally:
219
  if 'tmp' in locals():
220
  Path(tmp.name).unlink(missing_ok=True)
221
 
222
- def chat_response(message, history, model_name, direct_mode, uploaded_file=None):
223
  messages = [{"role": "system", "content": SYSTEM_PROMPT}]
224
  history = history or []
225
  history.append({"role": "user", "content": message})
226
  history.append({"role": "assistant", "content": ""})
227
- print(f"Получено сообщение: {message}")
228
- print(f"Модель: {model_name}")
229
- print(f"Прямая генерация: {direct_mode}")
230
- print(f"Загруженный файл: {uploaded_file}")
231
  try:
232
- if direct_mode:
233
- # Прямая отправка в нейронку для генерации изображения
234
- image_url = generate_image(message)
235
- if not image_url.startswith("Ошибка"):
236
- # Анализируем изображение на наличие текста
237
- image_analysis = process_image(image_url)
238
- history[-1]["content"] = f"![Generated Image]({image_url})\n\n{image_analysis}"
239
- else:
240
- history[-1]["content"] = f"��� {image_url}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  yield history, *[gr.update(visible=False) for _ in range(6)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  return
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
- # Начальные значения
245
- yield (
246
- history,
247
- gr.update(visible=False),
248
- gr.update(visible=False),
249
- gr.update(visible=False),
250
- "",
251
- gr.update(visible=False),
252
- gr.update(visible=False)
253
- )
254
-
255
- if uploaded_file:
256
- file_content = process_file(uploaded_file)
257
- if file_content:
258
- message = f"Файл содержит:\n```\n{file_content}\n```\n\n{message}"
259
-
260
- # Формируем историю сообщений
261
- for msg in history[:-2]:
262
- messages.append({"role": msg["role"], "content": msg["content"]})
263
- messages.append({"role": "user", "content": str(message)})
264
-
265
- partial_message = ""
266
- code_block = None
267
-
268
- response = g4f.ChatCompletion.create(
269
- model=AVAILABLE_MODELS.get(model_name, "gpt-4o"),
270
- messages=messages,
271
- stream=True,
272
- provider=g4f.Provider.Airforce
273
- )
274
-
275
- for chunk in response:
276
- if chunk:
277
- if isinstance(chunk, str):
278
  partial_message += chunk
279
 
280
  # Проверяем на запрос генерации изображения
@@ -283,7 +401,7 @@ def chat_response(message, history, model_name, direct_mode, uploaded_file=None)
283
  end_idx = partial_message.find("[/GENERATE_IMAGE]")
284
  image_prompt = partial_message[start_idx:end_idx].strip()
285
 
286
- # Показываем статус генерации
287
  history[-1]["content"] = """
288
  <div class="generating-animation">
289
  <div class="generating-text">Генерация изображения...</div>
@@ -311,13 +429,15 @@ def chat_response(message, history, model_name, direct_mode, uploaded_file=None)
311
  code_end = partial_message.find("```", code_start)
312
  if code_end != -1:
313
  code_block = partial_message[code_start:code_end].strip()
314
-
315
- # В конце убираем курсор
316
- history[-1]["content"] = partial_message
317
- yield history, *[gr.update(visible=True if code_block else False) for _ in range(6)]
318
 
319
  except Exception as e:
320
  print(f"Error: {e}")
 
 
321
  history[-1]["content"] = f"❌ Произошла ошибка: {str(e)}"
322
  yield (
323
  history,
@@ -371,7 +491,7 @@ def create_interface():
371
  input_background_fill="#2d2d2d",
372
  )
373
 
374
- # Обновляем CSS стили для управления цветом кода
375
  css = """
376
  .gradio-container {
377
  background-color: #1a1a1a !important;
@@ -511,8 +631,125 @@ def create_interface():
511
  .footer {
512
  display: none !important;
513
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  """
515
 
 
 
 
516
 
517
  with gr.Blocks(theme=theme, css=css) as demo:
518
  # gr.Markdown("# 💬 AI Chat Assistant")
@@ -531,7 +768,7 @@ def create_interface():
531
  render_markdown=True
532
  )
533
 
534
- # Добавляем компоненты для вывода
535
  output_text = gr.Textbox(
536
  label="Вывод",
537
  interactive=False,
@@ -570,6 +807,17 @@ def create_interface():
570
  value="GPT-4o",
571
  label="Модель"
572
  )
 
 
 
 
 
 
 
 
 
 
 
573
  direct_mode = gr.Checkbox(
574
  label="Прямая генерация (без обрботки прмпта)",
575
  value=False
@@ -633,24 +881,16 @@ def create_interface():
633
  # Обработчики событий
634
  msg.submit(
635
  fn=chat_response,
636
- inputs=[msg, chatbot, model, direct_mode, file_output],
637
  outputs=[chatbot, output_text, error_text, ask_help_btn, current_code, analyze_btn, run_btn],
638
- api_name=None, # Изменим с False на None
639
- show_progress=True
640
- ).then(
641
- fn=lambda: gr.update(value=""),
642
- outputs=[msg]
643
  )
644
 
645
  submit.click(
646
  fn=chat_response,
647
- inputs=[msg, chatbot, model, direct_mode, file_output],
648
  outputs=[chatbot, output_text, error_text, ask_help_btn, current_code, analyze_btn, run_btn],
649
- api_name=None, # Изменим с False на None
650
- show_progress=True
651
- ).then(
652
- fn=lambda: gr.update(value=""),
653
- outputs=[msg]
654
  )
655
 
656
  ask_help_btn.click(
@@ -676,22 +916,32 @@ def create_interface():
676
  outputs=[chatbot, output_text, error_text, ask_help_btn, current_code]
677
  )
678
 
 
 
 
 
 
 
 
 
 
 
679
  return demo
680
 
681
 
682
  if __name__ == "__main__":
683
  demo = create_interface()
684
-
685
-
686
- # Запускаем мониторинг изменений в тдельном потоке
687
-
688
 
689
- demo.launch(
690
- show_api=False,
691
- show_error=True,
692
- favicon_path=None,
693
- auth=None,
694
- # quiet=True, # Добавим этот параметр
695
-
696
-
697
- )
 
 
 
 
 
1
+ import asyncio
2
+ import sys
3
+
4
+ if sys.platform.startswith('win'):
5
+ # Используем более стабильную политику событий для Windows
6
+ asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
7
+
8
+ # Создаем новый цикл событий
9
+ loop = asyncio.new_event_loop()
10
+ asyncio.set_event_loop(loop)
11
+
12
  import g4f
13
  import gradio as gr
14
  import tempfile
15
  import os
16
  from pathlib import Path
17
+ from g4f.client import Client, AsyncClient
18
  from PIL import Image
19
  import io
20
  import requests
 
24
  import sys
25
  import time
26
  from typing import Dict, Any, Optional
27
+ import easyocr
28
+ import asyncio
29
 
30
  AVAILABLE_MODELS = {
31
  "GPT-4": "gpt-4",
32
  "GPT-4 Turbo": "gpt-4-turbo",
33
  "GPT-4o": "gpt-4o",
34
+ "GPT-4o THINK": "gpt-4o-think"
35
  }
36
 
37
  SYSTEM_PROMPT = """
38
  1. Всегда используйте кодировку UTF-8
39
  2. Используйте обработку ошибок
40
+ 3. Если пользователь отправляет изображение или пишет чтото на подобие 'посмотри на изображение':
41
+ - Автоматически проанализируйте изображение
42
+ - Опишите что вы видите на русском языке
43
+ - Тебе дается текстовая информация, которая может быть полезна для анализа
44
+ 4. Если пользователь просит нарисовать или сгенерировать изображение:
45
  - Начните ответ с [GENERATE_IMAGE]
46
+ - Напишите детальный промпт на ангийском языке
47
  - Завершите промпт строкой [/GENERATE_IMAGE]
48
  - Продолжите обычный ответ на русском языке
49
+ 5. В режиме размышления:
50
+ - Используйте [THINKING_STEP] для обозначения шага размышления
51
+ - Используйте [FINAL_ANSWER] для итогового ответа
52
+ - Старайтесь подробно описывать ход мыслей
53
  """
54
 
55
  def test_code(code: str, file_type: str = ".py") -> Dict[str, Any]:
 
102
  return None
103
 
104
  try:
105
+ # Получаем расширение файл��
106
  file_extension = file.name.lower().split('.')[-1] if hasattr(file, 'name') else ''
107
 
108
  # Список поддерживаемых форматов изображений
 
154
  try:
155
  client = Client()
156
  response = client.images.generate(
157
+ model="flux",
158
  prompt=prompt,
159
  response_format="url"
160
  )
 
163
  return f"Ошибка при генерации изобраения: {str(e)}"
164
 
165
  def process_image(image_input) -> str:
166
+ """Обработка изображения и распознавание объектов через YOLOv8 и текста через EasyOCR"""
167
  try:
168
  # Загружаем модель YOLOv8n
169
+ model = YOLO('yolov8n.pt')
170
 
171
+ # Инициализируем EasyOCR для русского и английского языков
172
+ reader = easyocr.Reader(['ru', 'en'])
173
+
174
+ # Обработка входного изображения
175
  if isinstance(image_input, str):
176
  response = requests.get(image_input)
177
  image = Image.open(io.BytesIO(response.content))
 
178
  elif isinstance(image_input, Image.Image):
179
  image = image_input
180
  else:
181
+ return "[IMAGE]\n❌ Неподдерживаемый формат изображения\n[/IMAGE]"
182
 
183
  # Конвертируем изображение в RGB если оно в RGBA
184
  if image.mode == 'RGBA':
 
187
  # Сохраняем изображение во временный файл для обработки
188
  with tempfile.NamedTemporaryFile(suffix='.jpg', delete=False) as tmp:
189
  image.save(tmp.name, format='JPEG')
190
+ # Запускаем распознавание объектов
191
  results = model(tmp.name)
192
 
193
+ # Распознаем текст
194
+ text_results = reader.readtext(tmp.name)
195
+
196
  # Собираем найденные объекты
197
  detected_objects = []
198
  for r in results:
 
201
  class_name = model.names[class_id]
202
  detected_objects.append(class_name)
203
 
204
+ # Собираем найденный текст
205
+ detected_text = []
206
+ for detection in text_results:
207
+ text = detection[1]
208
+ if text.strip(): # Проверяем, что текст не пустой
209
+ detected_text.append(text)
210
 
211
+ if not detected_objects and not detected_text:
212
+ return """
213
+ <div class="image-analysis-animation">
214
+ <div class="analysis-text">К сожалению, я не смог распознать объекты на этом изображении</div>
215
+ </div>
216
+ """
217
+
218
+ # Формируем сообщение для GPT
219
+ prompt = "Я на этом изображении вижу "
220
+ if detected_objects:
221
+ objects_str = ", ".join(detected_objects)
222
+ prompt += f"следующие объекты: {objects_str}. "
223
+
224
+ if detected_text:
225
+ text_str = ", ".join(detected_text)
226
+ prompt += f"Также на изображении есть текст: {text_str}"
227
+
228
  messages = [
229
  {
230
  "role": "system",
 
233
  1. Перевести названия объектов на русский язык
234
  2. Описать что ты видишь простыми словами
235
  3. Всегда отвечать на русском языке
236
+ 4. Если есть текст, упомянуть его в описании
237
+ 5. Никогда не говори "Похоже,что у вас есть описание изображения..."
238
  """
239
  },
240
  {
241
  "role": "user",
242
+ "content": prompt
243
  }
244
  ]
245
 
246
  response = g4f.ChatCompletion.create(
247
  model="gpt-4o",
248
+ messages=messages
 
249
  )
250
 
251
+ return response if isinstance(response, str) else prompt
252
+
 
 
 
 
 
 
 
253
  except Exception as e:
254
  return f"❌ Ошибка при обработке изображения: {str(e)}"
255
  finally:
256
  if 'tmp' in locals():
257
  Path(tmp.name).unlink(missing_ok=True)
258
 
259
+ async def chat_response(message, history, model_name, direct_mode, thinking_depth=1.0, uploaded_file=None):
260
  messages = [{"role": "system", "content": SYSTEM_PROMPT}]
261
  history = history or []
262
  history.append({"role": "user", "content": message})
263
  history.append({"role": "assistant", "content": ""})
264
+
 
 
 
265
  try:
266
+ if model_name == "GPT-4o THINK":
267
+ client = AsyncClient()
268
+ min_steps = 3
269
+ max_steps = 20
270
+ num_steps = int(min_steps + (max_steps - min_steps) * (thinking_depth / 10.0))
271
+
272
+ thinking_prompt = f"""Ты - система глубокого анализа.
273
+ СТРОГО СОБЛЮДАЙ ФОРМАТ:
274
+ 1. Каждый шаг должен быть в отдельных тегах [THINKING_STEP]текст шага[/THINKING_STEP]
275
+ 2. После ВСЕХ шагов размышления пиши [FINAL_ANSWER]итоговый ответ[/FINAL_ANSWER]
276
+ 3. Не пиши ничего между тегами
277
+ 4. Не используй теги внутри других тегов
278
+ 5. Обязательно сделай {num_steps} шагов, не больше и не меньше
279
+
280
+ Глубина анализа: {thinking_depth:.1f}/10
281
+
282
+ Вопрос для анализа: {message}
283
+ """
284
+
285
+ thinking_html = f"""
286
+ <div class="thinking-animation">
287
+ <div class="thinking-step">🤔 Начинаю анализ (глубина: {thinking_depth:.1f}, шагов: {num_steps})</div>
288
+ </div>
289
+ """
290
+ history[-1]["content"] = thinking_html
291
  yield history, *[gr.update(visible=False) for _ in range(6)]
292
+
293
+ try:
294
+ stream = await client.chat.completions.create(
295
+ model="gpt-4o",
296
+ messages=[{"role": "user", "content": thinking_prompt}],
297
+ stream=True
298
+ )
299
+
300
+ thinking_steps = []
301
+ current_text = ""
302
+
303
+ async for chunk in stream:
304
+ if chunk.choices and chunk.choices[0].delta.content:
305
+ current_text += chunk.choices[0].delta.content
306
+
307
+ while "[THINKING_STEP]" in current_text and "[/THINKING_STEP]" in current_text:
308
+ start = current_text.find("[THINKING_STEP]")
309
+ end = current_text.find("[/THINKING_STEP]")
310
+ if start != -1 and end != -1:
311
+ step = current_text[start + len("[THINKING_STEP]"):end].strip()
312
+ if step and step not in thinking_steps:
313
+ thinking_steps.append(step)
314
+ thinking_html = f"""
315
+ <div class="thinking-animation">
316
+ <div class="thinking-step">🤔 Процесс размышления ({len(thinking_steps)}/{num_steps}):</div>
317
+ """
318
+ for i, s in enumerate(thinking_steps, 1):
319
+ thinking_html += f'<div class="thinking-step">Шаг {i}: {s}</div>'
320
+ thinking_html += '</div>'
321
+ history[-1]["content"] = thinking_html
322
+ yield history, *[gr.update(visible=False) for _ in range(6)]
323
+ current_text = current_text[end + len("[/THINKING_STEP]"):]
324
+
325
+ if "[FINAL_ANSWER]" in current_text and "[/FINAL_ANSWER]" in current_text:
326
+ start = current_text.find("[FINAL_ANSWER]")
327
+ end = current_text.find("[/FINAL_ANSWER]")
328
+ final_answer = current_text[start + len("[FINAL_ANSWER]"):end].strip()
329
+
330
+ thinking_html = f"""
331
+ <div class="thinking-animation">
332
+ <div class="thinking-step">✨ Результат анализа (выполнено шагов: {len(thinking_steps)}/{num_steps}):</div>
333
+ """
334
+ for i, step in enumerate(thinking_steps, 1):
335
+ thinking_html += f'<div class="thinking-step">Шаг {i}: {step}</div>'
336
+ thinking_html += f'<div class="thinking-conclusion">{final_answer}</div>'
337
+ thinking_html += '</div>'
338
+ history[-1]["content"] = thinking_html
339
+ yield history, *[gr.update(visible=False) for _ in range(6)]
340
+ break
341
+
342
+ except Exception as e:
343
+ history[-1]["content"] = f"❌ Ошибка при анализе: {str(e)}"
344
+ yield history, *[gr.update(visible=False) for _ in range(6)]
345
+ finally:
346
+ await client.close()
347
+
348
  return
349
+
350
+ else:
351
+ # Обычный режим работы
352
+ if direct_mode:
353
+ # Прямая отправка в нейронку для генерации изображения
354
+ image_url = generate_image(message)
355
+ if not image_url.startswith("Ошибка"):
356
+ image_analysis = process_image(image_url)
357
+ history[-1]["content"] = f"![Generated Image]({image_url})\n\n{image_analysis}"
358
+ else:
359
+ history[-1]["content"] = f"❌ {image_url}"
360
+ yield history, *[gr.update(visible=False) for _ in range(6)]
361
+ return
362
 
363
+ # Начальные значения
364
+ yield (
365
+ history,
366
+ gr.update(visible=False),
367
+ gr.update(visible=False),
368
+ gr.update(visible=False),
369
+ "",
370
+ gr.update(visible=False),
371
+ gr.update(visible=False)
372
+ )
373
+
374
+ if uploaded_file:
375
+ file_content = process_file(uploaded_file)
376
+ if file_content:
377
+ message = f"Файл содержит:\n```\n{file_content}\n```\n\n{message}"
378
+
379
+ # Формируем историю сообщений
380
+ for msg in history[:-2]:
381
+ messages.append({"role": msg["role"], "content": msg["content"]})
382
+ messages.append({"role": "user", "content": str(message)})
383
+
384
+ partial_message = ""
385
+ code_block = None
386
+
387
+ response = g4f.ChatCompletion.create(
388
+ model=AVAILABLE_MODELS.get(model_name, "gpt-4o"),
389
+ messages=messages,
390
+ stream=True,
391
+ provider=g4f.Provider.Airforce
392
+ )
393
+
394
+ for chunk in response:
395
+ if chunk and isinstance(chunk, str):
 
396
  partial_message += chunk
397
 
398
  # Проверяем на запрос генерации изображения
 
401
  end_idx = partial_message.find("[/GENERATE_IMAGE]")
402
  image_prompt = partial_message[start_idx:end_idx].strip()
403
 
404
+ # Показываем статус ге��ерации
405
  history[-1]["content"] = """
406
  <div class="generating-animation">
407
  <div class="generating-text">Генерация изображения...</div>
 
429
  code_end = partial_message.find("```", code_start)
430
  if code_end != -1:
431
  code_block = partial_message[code_start:code_end].strip()
432
+
433
+ # В конце убираем курсор
434
+ history[-1]["content"] = partial_message
435
+ yield history, *[gr.update(visible=True if code_block else False) for _ in range(6)]
436
 
437
  except Exception as e:
438
  print(f"Error: {e}")
439
+ if not history:
440
+ history = [{"role": "user", "content": message}, {"role": "assistant", "content": ""}]
441
  history[-1]["content"] = f"❌ Произошла ошибка: {str(e)}"
442
  yield (
443
  history,
 
491
  input_background_fill="#2d2d2d",
492
  )
493
 
494
+ # Обновляем CSS стили для управлен��я цветом кода
495
  css = """
496
  .gradio-container {
497
  background-color: #1a1a1a !important;
 
631
  .footer {
632
  display: none !important;
633
  }
634
+
635
+ /* Добавляем анимацию для просмотра изображения */
636
+ .image-analysis-animation {
637
+ position: relative;
638
+ width: 100%;
639
+ min-height: 100px;
640
+ background: linear-gradient(45deg, #2d2d2d, #3d3d3d);
641
+ border-radius: 15px;
642
+ overflow: hidden;
643
+ display: flex;
644
+ align-items: center;
645
+ justify-content: center;
646
+ margin: 10px 0;
647
+ }
648
+
649
+ .analysis-text {
650
+ color: white;
651
+ font-size: 16px;
652
+ z-index: 2;
653
+ text-align: center;
654
+ animation: pulse 1.5s infinite;
655
+ }
656
+
657
+ .image-analysis-animation::before {
658
+ content: '';
659
+ position: absolute;
660
+ width: 100%;
661
+ height: 100%;
662
+ background: linear-gradient(90deg,
663
+ transparent 0%,
664
+ rgba(255,255,255,0.1) 50%,
665
+ transparent 100%);
666
+ animation: scanning 2s linear infinite;
667
+ }
668
+
669
+ @keyframes scanning {
670
+ 0% { transform: translateX(-100%); }
671
+ 100% { transform: translateX(100%); }
672
+ }
673
+
674
+ .thinking-animation {
675
+ position: relative;
676
+ width: 100%;
677
+ min-height: 100px;
678
+ background: linear-gradient(45deg, #1a1a1a, #2d2d2d);
679
+ border-radius: 15px;
680
+ overflow: hidden;
681
+ margin: 10px 0;
682
+ padding: 20px;
683
+ border-left: 4px solid #4a90e2;
684
+ transition: all 0.3s ease;
685
+ }
686
+
687
+ .thinking-animation:hover {
688
+ background: linear-gradient(45deg, #202020, #333333);
689
+ }
690
+
691
+ .thinking-step {
692
+ color: #b0b0b0;
693
+ font-style: italic;
694
+ margin-bottom: 10px;
695
+ padding-left: 20px;
696
+ border-left: 2px solid #4a90e2;
697
+ opacity: 0;
698
+ transform: translateY(10px);
699
+ animation: fadeInStep 0.5s ease-in-out forwards;
700
+ }
701
+
702
+ .thinking-conclusion {
703
+ color: white;
704
+ font-weight: bold;
705
+ margin-top: 15px;
706
+ padding: 10px;
707
+ background: rgba(74, 144, 226, 0.1);
708
+ border-radius: 8px;
709
+ border-left: 4px solid #4a90e2;
710
+ }
711
+
712
+ @keyframes fadeInStep {
713
+ to {
714
+ opacity: 1;
715
+ transform: translateY(0);
716
+ }
717
+ }
718
+
719
+ .typing-cursor {
720
+ display: inline-block;
721
+ width: 2px;
722
+ height: 15px;
723
+ background: #4a90e2;
724
+ margin-left: 5px;
725
+ animation: blink 1s infinite;
726
+ }
727
+
728
+ @keyframes blink {
729
+ 50% { opacity: 0; }
730
+ }
731
+
732
+ /* Стили для слайдера глубины размышления */
733
+ .thinking-depth-slider {
734
+ margin-top: 10px;
735
+ padding: 8px;
736
+ background: rgba(74, 144, 226, 0.1);
737
+ border-radius: 8px;
738
+ border-left: 4px solid #4a90e2;
739
+ }
740
+
741
+ /* Индикатор глубины размышления в сообщении */
742
+ .thinking-depth-indicator {
743
+ font-size: 0.9em;
744
+ color: #4a90e2;
745
+ margin-bottom: 10px;
746
+ font-style: italic;
747
+ }
748
  """
749
 
750
+ # Добавте этот скрипт в create_interface()
751
+
752
+
753
 
754
  with gr.Blocks(theme=theme, css=css) as demo:
755
  # gr.Markdown("# 💬 AI Chat Assistant")
 
768
  render_markdown=True
769
  )
770
 
771
+ # Добавляем омпоненты для вывода
772
  output_text = gr.Textbox(
773
  label="Вывод",
774
  interactive=False,
 
807
  value="GPT-4o",
808
  label="Модель"
809
  )
810
+
811
+ # Добавляем слайдер глубины размышления (изначально скрытый)
812
+ thinking_depth = gr.Slider(
813
+ minimum=0.1,
814
+ maximum=10.0,
815
+ value=1.0,
816
+ step=0.1,
817
+ label="Глубина размышления",
818
+ visible=False
819
+ )
820
+
821
  direct_mode = gr.Checkbox(
822
  label="Прямая генерация (без обрботки прмпта)",
823
  value=False
 
881
  # Обработчики событий
882
  msg.submit(
883
  fn=chat_response,
884
+ inputs=[msg, chatbot, model, direct_mode, thinking_depth, file_output],
885
  outputs=[chatbot, output_text, error_text, ask_help_btn, current_code, analyze_btn, run_btn],
886
+ api_name=None
 
 
 
 
887
  )
888
 
889
  submit.click(
890
  fn=chat_response,
891
+ inputs=[msg, chatbot, model, direct_mode, thinking_depth, file_output],
892
  outputs=[chatbot, output_text, error_text, ask_help_btn, current_code, analyze_btn, run_btn],
893
+ api_name=None
 
 
 
 
894
  )
895
 
896
  ask_help_btn.click(
 
916
  outputs=[chatbot, output_text, error_text, ask_help_btn, current_code]
917
  )
918
 
919
+ # Добавляем обработчик изменения модели
920
+ def update_thinking_depth_visibility(model_name):
921
+ return gr.update(visible=model_name == "GPT-4o THINK")
922
+
923
+ model.change(
924
+ fn=update_thinking_depth_visibility,
925
+ inputs=[model],
926
+ outputs=[thinking_depth]
927
+ )
928
+
929
  return demo
930
 
931
 
932
  if __name__ == "__main__":
933
  demo = create_interface()
 
 
 
 
934
 
935
+ try:
936
+ demo.launch(
937
+ server_name="127.0.0.1", # Явно указываем хост
938
+ server_port=7860, # Явно указываем порт
939
+ show_api=False,
940
+ show_error=True,
941
+ debug=True
942
+ )
943
+ except Exception as e:
944
+ print(f"Ошибка запуска: {e}")
945
+ finally:
946
+ # Закрываем цикл событий
947
+ loop.close()