AnatoliiG commited on
Commit
4c14f1d
·
1 Parent(s): 8fe3b97

Update ui.py

Browse files
Files changed (1) hide show
  1. ui.py +48 -72
ui.py CHANGED
@@ -1,85 +1,76 @@
1
- import traceback
2
 
 
3
  import gradio as gr
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
- max-width: 100% !important;
14
  width: 100% !important;
15
  height: 100vh !important;
16
- padding: 0 !important;
17
  margin: 0 !important;
 
18
  overflow: hidden !important;
19
  }
20
 
21
- /* Настройки боковой панели */
22
  .sidebar {
23
  height: 100vh !important;
24
- overflow-y: auto !important;
25
- width: 300px !important; /* Фиксируем ширину сайдбара, чтобы не съедал место */
26
- }
27
-
28
- /*
29
- ГЛАВНОЕ: Убираем ограничение ширины текста.
30
- По умолчанию Gradio сужает текст для "читаемости",
31
- но для кода это вредно.
32
- */
33
- .prose {
34
- max-width: 100% !important;
35
- width: 100% !important;
36
  }
37
 
38
- .message {
39
- max-width: 100% !important;
40
- width: 100% !important;
41
- }
42
-
43
- .message-wrap {
44
- max-width: 100% !important;
 
45
  }
46
 
47
- /* Настройки окна чата */
48
  #chatbot {
49
- height: 82vh !important; /* Увеличили высоту */
50
- min-height: 82vh !important;
51
- overflow-y: auto !important;
52
- margin-bottom: 0 !important;
53
  flex-grow: 1 !important;
 
 
 
 
 
 
54
  }
55
 
56
- /* Блок ввода прижимаем к низу */
57
  .input-row {
58
- padding: 10px 15px !important;
59
- background: var(--background-fill-primary);
 
60
  border-top: 1px solid var(--border-color-primary);
 
61
  }
62
 
 
 
 
63
  footer { display: none !important; }
64
  """
65
 
66
 
67
  # --- Логика событий ---
68
 
69
-
70
  def user_input(user_message, history):
71
  if not user_message:
72
  return None, history
73
-
74
  if history is None:
75
  history = []
76
 
77
  clean_history = []
78
  for msg in history:
79
- # Чистим контент перед добавлением в историю
80
  raw_content = msg.get("content", "")
81
  text_content = get_clean_text(raw_content)
82
-
83
  clean_history.append({"role": msg["role"], "content": text_content})
84
 
85
  clean_history.append({"role": "user", "content": str(user_message)})
@@ -93,13 +84,11 @@ def bot_response(history, system_prompt, temperature, max_tokens):
93
  return
94
 
95
  messages = [{"role": "system", "content": system_prompt}]
96
-
97
  relevant_history = history[-15:] if len(history) > 15 else history
98
 
99
  for msg in relevant_history:
100
  raw_content = msg.get("content", "")
101
  text_content = get_clean_text(raw_content)
102
-
103
  messages.append({"role": msg["role"], "content": text_content})
104
 
105
  history.append({"role": "assistant", "content": ""})
@@ -111,7 +100,6 @@ def bot_response(history, system_prompt, temperature, max_tokens):
111
  temperature=temperature,
112
  stream=True,
113
  )
114
-
115
  partial_text = ""
116
  for chunk in stream:
117
  delta = chunk["choices"][0]["delta"]
@@ -119,7 +107,6 @@ def bot_response(history, system_prompt, temperature, max_tokens):
119
  partial_text += delta["content"]
120
  history[-1]["content"] = partial_text
121
  yield history
122
-
123
  except Exception as e:
124
  traceback.print_exc()
125
  history[-1]["content"] = partial_text + f"\n\n❌ **Error:** {str(e)}"
@@ -128,78 +115,67 @@ def bot_response(history, system_prompt, temperature, max_tokens):
128
 
129
  def set_interactive(is_interactive):
130
  return (
131
- gr.update(
132
- interactive=is_interactive,
133
- placeholder="Wait..." if not is_interactive else "Type code question...",
134
- ),
135
  gr.update(interactive=is_interactive),
136
  )
137
 
138
 
139
  # --- Создание интерфейса ---
140
 
141
-
142
  def create_ui():
143
  theme = gr.themes.Soft(primary_hue="blue", text_size="lg")
144
 
145
  with gr.Blocks(theme=theme, css=CUSTOM_CSS, title="Qwen Coder Pro") as demo:
146
- with gr.Row(equal_height=True, variant="default"):
147
- # Боковая панель
148
- with gr.Sidebar():
 
 
149
  gr.Markdown("### ⚙️ Settings")
150
  system_prompt = gr.Textbox(
151
  label="System Prompt",
152
  value="You are an expert coding assistant. Write clean, efficient code.",
153
  lines=5,
154
  )
155
- temperature = gr.Slider(
156
- 0.0, 1.0, value=config.DEFAULT_TEMP, label="Temperature"
157
- )
158
- max_tokens = gr.Slider(
159
- 512, 8192, value=config.DEFAULT_MAX_TOKENS, label="Max Tokens"
160
- )
161
  clear_btn = gr.Button("🗑️ Clear Chat", variant="secondary")
162
 
163
- # Основная колонка (теперь она будет растягиваться благодаря CSS)
164
- with gr.Column(scale=10, elem_classes=["main-column"]):
165
- # Чатбот
166
  chatbot = gr.Chatbot(
167
  label="Code Assistant",
168
  elem_id="chatbot",
169
  avatar_images=(None, "https://api.iconify.design/noto:robot.svg"),
170
  layout="bubble",
 
171
  )
172
 
173
- # Строка ввода
174
- with gr.Row(variant="compact", elem_classes="input-row"):
175
  msg = gr.Textbox(
176
  show_label=False,
177
  placeholder="Type your code question here...",
178
  lines=1,
179
- scale=15,
180
  autofocus=True,
181
  max_lines=10,
 
182
  )
183
- submit_btn = gr.Button(
184
- "Run ➤", variant="primary", scale=1, min_width=100
185
- )
186
 
187
- # Chains
188
  submit_event = (
189
  msg.submit(user_input, [msg, chatbot], [msg, chatbot], queue=False)
190
  .then(lambda: set_interactive(False), None, [msg, submit_btn], queue=False)
191
- .then(
192
- bot_response, [chatbot, system_prompt, temperature, max_tokens], chatbot
193
- )
194
  .then(lambda: set_interactive(True), None, [msg, submit_btn], queue=False)
195
  )
196
 
197
  click_event = (
198
  submit_btn.click(user_input, [msg, chatbot], [msg, chatbot], queue=False)
199
  .then(lambda: set_interactive(False), None, [msg, submit_btn], queue=False)
200
- .then(
201
- bot_response, [chatbot, system_prompt, temperature, max_tokens], chatbot
202
- )
203
  .then(lambda: set_interactive(True), None, [msg, submit_btn], queue=False)
204
  )
205
 
 
1
+ --- START OF FILE ui.py ---
2
 
3
+ import traceback
4
  import gradio as gr
 
5
  import config
6
  from model import engine
7
  from utils import get_clean_text
8
 
 
9
  CUSTOM_CSS = """
10
+ /* 1. Глобальный сброс отступов и фиксация высоты */
11
  .gradio-container {
 
12
  width: 100% !important;
13
  height: 100vh !important;
 
14
  margin: 0 !important;
15
+ padding: 0 !important;
16
  overflow: hidden !important;
17
  }
18
 
19
+ /* 2. Сайдбар тоже на всю высоту */
20
  .sidebar {
21
  height: 100vh !important;
22
+ border-right: 1px solid var(--border-color-primary) !important;
 
 
 
 
 
 
 
 
 
 
 
23
  }
24
 
25
+ /* 3. Главная колонка с чатом - превращаем во flex-контейнер */
26
+ .main-chat-col {
27
+ height: 100vh !important;
28
+ display: flex !important;
29
+ flex-direction: column !important;
30
+ padding: 0 !important;
31
+ margin: 0 !important;
32
+ border: none !important;
33
  }
34
 
35
+ /* 4. Окно чата: растягивается (flex-grow: 1) на всё доступное место */
36
  #chatbot {
 
 
 
 
37
  flex-grow: 1 !important;
38
+ height: auto !important; /* Сбрасываем фиксированную высоту */
39
+ min-height: 0 !important; /* Разрешаем сжиматься, если нужно */
40
+ overflow-y: auto !important; /* Скролл внутри чата */
41
+ margin-bottom: 0 !important;
42
+ border: none !important;
43
+ border-radius: 0 !important;
44
  }
45
 
46
+ /* 5. Полоса ввода: фиксирована внизу */
47
  .input-row {
48
+ flex-shrink: 0 !important; /* Не сжимать */
49
+ padding: 15px !important;
50
+ background: var(--background-fill-secondary); /* Цвет фона под вводом */
51
  border-top: 1px solid var(--border-color-primary);
52
+ z-index: 100;
53
  }
54
 
55
+ /* Доп. стили для ширины сообщений */
56
+ .message { width: 100% !important; max-width: 100% !important; }
57
+ .message-wrap { max-width: 100% !important; }
58
  footer { display: none !important; }
59
  """
60
 
61
 
62
  # --- Логика событий ---
63
 
 
64
  def user_input(user_message, history):
65
  if not user_message:
66
  return None, history
 
67
  if history is None:
68
  history = []
69
 
70
  clean_history = []
71
  for msg in history:
 
72
  raw_content = msg.get("content", "")
73
  text_content = get_clean_text(raw_content)
 
74
  clean_history.append({"role": msg["role"], "content": text_content})
75
 
76
  clean_history.append({"role": "user", "content": str(user_message)})
 
84
  return
85
 
86
  messages = [{"role": "system", "content": system_prompt}]
 
87
  relevant_history = history[-15:] if len(history) > 15 else history
88
 
89
  for msg in relevant_history:
90
  raw_content = msg.get("content", "")
91
  text_content = get_clean_text(raw_content)
 
92
  messages.append({"role": msg["role"], "content": text_content})
93
 
94
  history.append({"role": "assistant", "content": ""})
 
100
  temperature=temperature,
101
  stream=True,
102
  )
 
103
  partial_text = ""
104
  for chunk in stream:
105
  delta = chunk["choices"][0]["delta"]
 
107
  partial_text += delta["content"]
108
  history[-1]["content"] = partial_text
109
  yield history
 
110
  except Exception as e:
111
  traceback.print_exc()
112
  history[-1]["content"] = partial_text + f"\n\n❌ **Error:** {str(e)}"
 
115
 
116
  def set_interactive(is_interactive):
117
  return (
118
+ gr.update(interactive=is_interactive, placeholder="Wait..." if not is_interactive else "Type code question..."),
 
 
 
119
  gr.update(interactive=is_interactive),
120
  )
121
 
122
 
123
  # --- Создание интерфейса ---
124
 
 
125
  def create_ui():
126
  theme = gr.themes.Soft(primary_hue="blue", text_size="lg")
127
 
128
  with gr.Blocks(theme=theme, css=CUSTOM_CSS, title="Qwen Coder Pro") as demo:
129
+ # fill_height=True помогает растянуть layout
130
+ with gr.Row(equal_height=True, variant="default", elem_classes=["main-row"]):
131
+
132
+ # --- Боковая панель ---
133
+ with gr.Sidebar(elem_classes=["sidebar"]):
134
  gr.Markdown("### ⚙️ Settings")
135
  system_prompt = gr.Textbox(
136
  label="System Prompt",
137
  value="You are an expert coding assistant. Write clean, efficient code.",
138
  lines=5,
139
  )
140
+ temperature = gr.Slider(0.0, 1.0, value=config.DEFAULT_TEMP, label="Temperature")
141
+ max_tokens = gr.Slider(512, 8192, value=config.DEFAULT_MAX_TOKENS, label="Max Tokens")
 
 
 
 
142
  clear_btn = gr.Button("🗑️ Clear Chat", variant="secondary")
143
 
144
+ # --- Основная колонка (Чат + Ввод) ---
145
+ with gr.Column(scale=1, elem_classes=["main-chat-col"]):
146
+
147
  chatbot = gr.Chatbot(
148
  label="Code Assistant",
149
  elem_id="chatbot",
150
  avatar_images=(None, "https://api.iconify.design/noto:robot.svg"),
151
  layout="bubble",
152
+ render_markdown=True,
153
  )
154
 
155
+ with gr.Row(elem_classes=["input-row"]):
 
156
  msg = gr.Textbox(
157
  show_label=False,
158
  placeholder="Type your code question here...",
159
  lines=1,
160
+ scale=9,
161
  autofocus=True,
162
  max_lines=10,
163
+ container=False
164
  )
165
+ submit_btn = gr.Button("Run ➤", variant="primary", scale=1, min_width=80)
 
 
166
 
167
+ # --- Привязка событий ---
168
  submit_event = (
169
  msg.submit(user_input, [msg, chatbot], [msg, chatbot], queue=False)
170
  .then(lambda: set_interactive(False), None, [msg, submit_btn], queue=False)
171
+ .then(bot_response, [chatbot, system_prompt, temperature, max_tokens], chatbot)
 
 
172
  .then(lambda: set_interactive(True), None, [msg, submit_btn], queue=False)
173
  )
174
 
175
  click_event = (
176
  submit_btn.click(user_input, [msg, chatbot], [msg, chatbot], queue=False)
177
  .then(lambda: set_interactive(False), None, [msg, submit_btn], queue=False)
178
+ .then(bot_response, [chatbot, system_prompt, temperature, max_tokens], chatbot)
 
 
179
  .then(lambda: set_interactive(True), None, [msg, submit_btn], queue=False)
180
  )
181