AnatoliiG commited on
Commit
76ded85
·
1 Parent(s): 0a33dc7

update ui

Browse files
Files changed (2) hide show
  1. ui.py +49 -33
  2. utils.py +13 -0
ui.py CHANGED
@@ -4,10 +4,11 @@ import gradio as gr
4
 
5
  import config
6
  from model import engine
7
- from utils import sanitize_content
8
 
 
9
  CUSTOM_CSS = """
10
- /* Убираем отступы у основного контейнера и растягиваем его */
11
  .gradio-container {
12
  width: 100% !important;
13
  height: 100vh !important;
@@ -17,43 +18,53 @@ CUSTOM_CSS = """
17
  overflow: hidden !important;
18
  }
19
 
20
- /* Настройка главной колонки чата */
21
- #main-col {
22
- height: 100% !important;
23
- max_height: 100vh !important;
24
- display: flex !important;
25
- flex-direction: column !important;
26
- justify-content: space-between !important; /* Распределяем пространство */
27
- padding-bottom: 10px !important;
28
  }
29
 
30
- /* Сам чатбот - он должен расти (flex-grow) и иметь скролл */
 
 
 
 
 
31
  #chatbot {
32
- flex-grow: 1 !important; /* Занимает всё доступное место */
33
- height: auto !important;
34
- min-height: 0 !important; /* Важно для работы скролла во flex-контейнере */
35
  overflow-y: auto !important;
36
  margin-bottom: 10px !important;
37
  }
38
 
39
- /* Скрываем футер */
 
 
 
 
 
40
  footer { display: none !important; }
41
  """
42
 
 
43
  # --- Логика событий ---
44
 
45
 
46
  def user_input(user_message, history):
47
  if not user_message:
48
  return None, history
 
49
  if history is None:
50
  history = []
51
 
52
  clean_history = []
53
  for msg in history:
54
- clean_history.append(
55
- {"role": msg["role"], "content": sanitize_content(msg.get("content", ""))}
56
- )
 
 
 
57
  clean_history.append({"role": "user", "content": str(user_message)})
58
  return "", clean_history
59
 
@@ -65,12 +76,16 @@ def bot_response(history, system_prompt, temperature, max_tokens):
65
  return
66
 
67
  messages = [{"role": "system", "content": system_prompt}]
 
 
68
  relevant_history = history[-15:] if len(history) > 15 else history
69
 
70
  for msg in relevant_history:
71
- messages.append(
72
- {"role": msg["role"], "content": sanitize_content(msg.get("content", ""))}
73
- )
 
 
74
 
75
  history.append({"role": "assistant", "content": ""})
76
 
@@ -81,6 +96,7 @@ def bot_response(history, system_prompt, temperature, max_tokens):
81
  temperature=temperature,
82
  stream=True,
83
  )
 
84
  partial_text = ""
85
  for chunk in stream:
86
  delta = chunk["choices"][0]["delta"]
@@ -99,9 +115,7 @@ def set_interactive(is_interactive):
99
  return (
100
  gr.update(
101
  interactive=is_interactive,
102
- placeholder="Wait for response..."
103
- if not is_interactive
104
- else "Type code question...",
105
  ),
106
  gr.update(interactive=is_interactive),
107
  )
@@ -113,10 +127,9 @@ def set_interactive(is_interactive):
113
  def create_ui():
114
  theme = gr.themes.Soft(primary_hue="blue", text_size="lg")
115
 
116
- with gr.Blocks(
117
- theme=theme, css=CUSTOM_CSS, title="Qwen Coder Pro", fill_height=True
118
- ) as demo:
119
- with gr.Row(elem_id="main-row", variant="panel"):
120
  # Боковая панель
121
  with gr.Sidebar():
122
  gr.Markdown("### ⚙️ Settings")
@@ -133,16 +146,19 @@ def create_ui():
133
  )
134
  clear_btn = gr.Button("🗑️ Clear Chat", variant="secondary")
135
 
136
- with gr.Column(scale=1, elem_id="main-col"):
 
 
137
  chatbot = gr.Chatbot(
138
  label="Code Assistant",
139
- elem_id="chatbot",
140
  avatar_images=(None, "https://api.iconify.design/noto:robot.svg"),
 
141
  scale=1,
142
  )
143
 
144
- # Группа ввода
145
- with gr.Row(variant="compact", elem_id="input-row"):
146
  msg = gr.Textbox(
147
  show_label=False,
148
  placeholder="Type your code question here...",
@@ -155,7 +171,7 @@ def create_ui():
155
  "Run ➤", variant="primary", scale=1, min_width=100
156
  )
157
 
158
- # Chains (События)
159
  submit_event = (
160
  msg.submit(user_input, [msg, chatbot], [msg, chatbot], queue=False)
161
  .then(lambda: set_interactive(False), None, [msg, submit_btn], queue=False)
 
4
 
5
  import config
6
  from model import engine
7
+ from utils import get_clean_text
8
 
9
+ # --- CSS стили ---
10
  CUSTOM_CSS = """
11
+ /* Убираем глобальные отступы и скролл страницы */
12
  .gradio-container {
13
  width: 100% !important;
14
  height: 100vh !important;
 
18
  overflow: hidden !important;
19
  }
20
 
21
+ /* Настройки боковой панели - она тоже должна быть во весь экран */
22
+ .sidebar {
23
+ height: 100vh !important;
24
+ overflow-y: auto !important;
 
 
 
 
25
  }
26
 
27
+ /*
28
+ ГЛАВНОЕ ИСПРАВЛЕНИЕ РАЗМЕРА:
29
+ Задаем высоту чата жестко: 75% от высоты экрана.
30
+ min-height гарантирует, что он не схлопнется.
31
+ flex-grow отключен, чтобы избежать конфликтов.
32
+ */
33
  #chatbot {
34
+ height: 75vh !important;
35
+ min-height: 75vh !important;
 
36
  overflow-y: auto !important;
37
  margin-bottom: 10px !important;
38
  }
39
 
40
+ /* Блок ввода прижимаем ниже */
41
+ .input-row {
42
+ height: auto !important;
43
+ padding-bottom: 15px !important;
44
+ }
45
+
46
  footer { display: none !important; }
47
  """
48
 
49
+
50
  # --- Логика событий ---
51
 
52
 
53
  def user_input(user_message, history):
54
  if not user_message:
55
  return None, history
56
+
57
  if history is None:
58
  history = []
59
 
60
  clean_history = []
61
  for msg in history:
62
+ # Чистим контент перед добавлением в историю
63
+ raw_content = msg.get("content", "")
64
+ text_content = get_clean_text(raw_content)
65
+
66
+ clean_history.append({"role": msg["role"], "content": text_content})
67
+
68
  clean_history.append({"role": "user", "content": str(user_message)})
69
  return "", clean_history
70
 
 
76
  return
77
 
78
  messages = [{"role": "system", "content": system_prompt}]
79
+
80
+ # Берем последние 15 сообщений
81
  relevant_history = history[-15:] if len(history) > 15 else history
82
 
83
  for msg in relevant_history:
84
+ # Также чистим контент перед отправкой в модель
85
+ raw_content = msg.get("content", "")
86
+ text_content = get_clean_text(raw_content)
87
+
88
+ messages.append({"role": msg["role"], "content": text_content})
89
 
90
  history.append({"role": "assistant", "content": ""})
91
 
 
96
  temperature=temperature,
97
  stream=True,
98
  )
99
+
100
  partial_text = ""
101
  for chunk in stream:
102
  delta = chunk["choices"][0]["delta"]
 
115
  return (
116
  gr.update(
117
  interactive=is_interactive,
118
+ placeholder="Wait..." if not is_interactive else "Type code question...",
 
 
119
  ),
120
  gr.update(interactive=is_interactive),
121
  )
 
127
  def create_ui():
128
  theme = gr.themes.Soft(primary_hue="blue", text_size="lg")
129
 
130
+ # Убрали fill_height=True, чтобы CSS работал жестко
131
+ with gr.Blocks(theme=theme, css=CUSTOM_CSS, title="Qwen Coder Pro") as demo:
132
+ with gr.Row():
 
133
  # Боковая панель
134
  with gr.Sidebar():
135
  gr.Markdown("### ⚙️ Settings")
 
146
  )
147
  clear_btn = gr.Button("🗑️ Clear Chat", variant="secondary")
148
 
149
+ # Основная колонка
150
+ with gr.Column(scale=1):
151
+ # Чатбот
152
  chatbot = gr.Chatbot(
153
  label="Code Assistant",
154
+ elem_id="chatbot", # Связка с CSS #chatbot
155
  avatar_images=(None, "https://api.iconify.design/noto:robot.svg"),
156
+ type="messages",
157
  scale=1,
158
  )
159
 
160
+ # Строка ввода
161
+ with gr.Row(variant="compact", elem_classes="input-row"):
162
  msg = gr.Textbox(
163
  show_label=False,
164
  placeholder="Type your code question here...",
 
171
  "Run ➤", variant="primary", scale=1, min_width=100
172
  )
173
 
174
+ # Chains
175
  submit_event = (
176
  msg.submit(user_input, [msg, chatbot], [msg, chatbot], queue=False)
177
  .then(lambda: set_interactive(False), None, [msg, submit_btn], queue=False)
utils.py CHANGED
@@ -6,3 +6,16 @@ def sanitize_content(content):
6
  if isinstance(content, list):
7
  return "\n".join(str(item) for item in content)
8
  return str(content) if content is not None else ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  if isinstance(content, list):
7
  return "\n".join(str(item) for item in content)
8
  return str(content) if content is not None else ""
9
+
10
+
11
+ def get_clean_text(content):
12
+ """
13
+ Извлекает текст из разных форматов Gradio 5 (словарь, список, строка).
14
+ Решает проблему отображения {'text': ...}
15
+ """
16
+ # Если пришел словарь {'text': '...', 'type': 'text'}
17
+ if isinstance(content, dict) and "text" in content:
18
+ return str(content["text"])
19
+
20
+ # Если пришла строка или список, используем вашу функцию из utils.py
21
+ return sanitize_content(content)