vortex123 commited on
Commit
ea307ae
·
verified ·
1 Parent(s): 0852e93

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -29
app.py CHANGED
@@ -35,11 +35,19 @@ for model_name in AVAILABLE_MODELS:
35
  # Когда пользователь переключается на модель, мы добавляем это сообщение в историю.
36
 
37
  DEFAULT_DEVELOPER_PROMPTS = {
38
- "gemini-1.5-flash": (
39
- "You are a helpful assistant (developer role). "
40
- "Provide direct answers."
 
 
 
 
 
 
 
 
 
41
  ),
42
- # Add default prompts for other models if needed
43
  }
44
 
45
  ###############################################################################
@@ -50,32 +58,37 @@ def _assistant_role(model_name: str) -> str:
50
  """
51
  Некоторые новые модели не принимают 'assistant', а требуют 'model'.
52
  """
53
- # Adjust based on model requirements
 
 
54
  return "assistant"
55
 
56
  ###############################################################################
57
  # 4. Преобразование истории из Gradio в формат Generative AI
58
  ###############################################################################
59
 
60
- def _history_to_genai(history, model_name):
61
  """
62
- Gradio хранит [(user_msg, bot_msg), ...].
63
- Google GenAI ждёт [{"role": "...", "parts": "..."}].
64
- Дополнительно учитываем developer-сообщения, которые мы вставляем.
65
  """
66
- genai_history = []
67
  asst_role = _assistant_role(model_name)
 
68
 
69
  for user_text, bot_text in history:
70
  if user_text:
71
  if user_text.startswith("<developer>: "):
72
- genai_history.append({"role": "system", "parts": user_text.replace("<developer>: ", "", 1)})
 
 
73
  else:
74
- # Пользовательское сообщение
75
  genai_history.append({"role": "user", "parts": user_text})
 
76
  if bot_text:
77
- # Ответ ассистента (или model)
78
  genai_history.append({"role": asst_role, "parts": bot_text})
 
79
  return genai_history
80
 
81
  ###############################################################################
@@ -83,6 +96,10 @@ def _history_to_genai(history, model_name):
83
  ###############################################################################
84
 
85
  async def _respond_stream_enh(model_name, user_message, history):
 
 
 
 
86
  if model_name not in MODELS:
87
  yield "Ошибка: модель не найдена."
88
  return
@@ -92,7 +109,7 @@ async def _respond_stream_enh(model_name, user_message, history):
92
 
93
  try:
94
  chat = model.start_chat(history=genai_history)
95
- stream = chat.send_message(user_message, stream=True) # stream=True here
96
 
97
  partial_text = ""
98
  async for chunk in stream:
@@ -104,7 +121,7 @@ async def _respond_stream_enh(model_name, user_message, history):
104
  yield f"Ошибка при запросе к API: {e}"
105
  return
106
 
107
- async def _respond_thinking(model_name, user_message, history):
108
  """
109
  Для thinking-моделей:
110
  1) Выводим "Думаю..."
@@ -115,7 +132,7 @@ async def _respond_thinking(model_name, user_message, history):
115
  return
116
 
117
  model = MODELS[model_name]
118
- genai_history = _history_to_genai(history, model_name)
119
 
120
  # Сначала "Думаю..."
121
  yield "Думаю...", ""
@@ -130,14 +147,10 @@ async def _respond_thinking(model_name, user_message, history):
130
  if response.candidates:
131
  parts = response.candidates[0].content.parts
132
  for p in parts:
133
- # Assuming a specific structure for "thinking" models' output
134
- # This part might need adjustments based on actual model output
135
- if isinstance(p, dict) and "output" not in p: # Heuristic for thought
136
  thinking_process_text += p.text or ""
137
- elif isinstance(p, dict) and "output" in p:
138
- final_text += p["output"] # Assuming output is directly in the dict
139
  else:
140
- final_text += p.text or "" # Fallback
141
 
142
  # Для thinking-моделей просили итоговый ответ в {output: ...}
143
  final_text_formatted = f"{{output: {final_text}}}"
@@ -171,16 +184,16 @@ async def user_send_message(
171
  # Добавляем (user_message, None)
172
  history.append((user_message, None))
173
 
174
- # Если модель — thinking (adjust logic based on actual model names)
175
  if "thinking" in model_name.lower():
176
- async for assistant_text, thought_text in _respond_thinking(model_name, user_message, history):
177
  history[-1] = (user_message, assistant_text)
178
  yield history, thought_text
179
  return
180
  else:
181
  # Обычная модель
182
  partial_answer = ""
183
- async for chunk in _respond_stream(model_name, user_message, history):
184
  partial_answer = chunk
185
  history[-1] = (user_message, partial_answer)
186
  yield history, ""
@@ -207,7 +220,7 @@ def on_model_change(selected_model, history, thinking_text):
207
 
208
  # Cообщаем модели, что переключились (developer role)
209
  new_history.append((
210
- f"<developer>: Switched to model: {selected_model}",
211
  None
212
  ))
213
 
@@ -217,7 +230,7 @@ def on_model_change(selected_model, history, thinking_text):
217
  "No default prompt for this model."
218
  )
219
  new_history.append((
220
- f"<developer>: {default_prompt}",
221
  None
222
  ))
223
 
@@ -227,7 +240,29 @@ def on_model_change(selected_model, history, thinking_text):
227
  # 9. Функция конвертации истории с учётом developer role
228
  ###############################################################################
229
 
230
- # This part is already implemented in _history_to_genai
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
 
232
  ###############################################################################
233
  # 10. Построение интерфейса Gradio
@@ -239,7 +274,7 @@ with gr.Blocks() as demo:
239
  with gr.Row():
240
  model_dropdown = gr.Dropdown(
241
  choices=AVAILABLE_MODELS,
242
- value=AVAILABLE_MODELS[0] if AVAILABLE_MODELS else None,
243
  label="Выберите модель"
244
  )
245
  clear_button = gr.Button("Очистить чат")
 
35
  # Когда пользователь переключается на модель, мы добавляем это сообщение в историю.
36
 
37
  DEFAULT_DEVELOPER_PROMPTS = {
38
+ "gemini-2.0-flash-exp": (
39
+ "You are a normal model (developer role). "
40
+ "Provide direct answers with no JSON wrapping."
41
+ ),
42
+ "gemini-exp-1206": (
43
+ "You are an experimental normal model (developer role). "
44
+ "Provide direct answers with no JSON wrapping."
45
+ ),
46
+ "gemini-2.0-flash-thinking-exp-1219": (
47
+ "You are a thinking model (developer role). "
48
+ "Please provide your final answer in the format {output: ...}. "
49
+ "You may use internal thoughts but do not show them directly to the user."
50
  ),
 
51
  }
52
 
53
  ###############################################################################
 
58
  """
59
  Некоторые новые модели не принимают 'assistant', а требуют 'model'.
60
  """
61
+ # Допустим "gemini-exp-1206" и "gemini-2.0-flash-thinking-exp-1219" хотят "model"
62
+ if model_name in ["gemini-exp-1206", "gemini-2.0-flash-thinking-exp-1219"]:
63
+ return "model"
64
  return "assistant"
65
 
66
  ###############################################################################
67
  # 4. Преобразование истории из Gradio в формат Generative AI
68
  ###############################################################################
69
 
70
+ def _history_to_genai_enhanced(history, model_name):
71
  """
72
+ Улучшенная версия, отличающая developer-сообщения
73
+ (префикс "<developer>: ") от user-сообщений.
 
74
  """
 
75
  asst_role = _assistant_role(model_name)
76
+ genai_history = []
77
 
78
  for user_text, bot_text in history:
79
  if user_text:
80
  if user_text.startswith("<developer>: "):
81
+ # Считаем это developer role
82
+ dev_content = user_text.replace("<developer>: ", "", 1)
83
+ genai_history.append({"role": "system", "parts": dev_content})
84
  else:
85
+ # Обычный пользователь
86
  genai_history.append({"role": "user", "parts": user_text})
87
+
88
  if bot_text:
89
+ # Ответ ассистента / модель
90
  genai_history.append({"role": asst_role, "parts": bot_text})
91
+
92
  return genai_history
93
 
94
  ###############################################################################
 
96
  ###############################################################################
97
 
98
  async def _respond_stream_enh(model_name, user_message, history):
99
+ """
100
+ Стриминговый ответ для обычных моделей:
101
+ - Кусочек за кусочком (partial_text).
102
+ """
103
  if model_name not in MODELS:
104
  yield "Ошибка: модель не найдена."
105
  return
 
109
 
110
  try:
111
  chat = model.start_chat(history=genai_history)
112
+ stream = chat.send_message(user_message, stream=True)
113
 
114
  partial_text = ""
115
  async for chunk in stream:
 
121
  yield f"Ошибка при запросе к API: {e}"
122
  return
123
 
124
+ async def _respond_thinking_enh(model_name, user_message, history):
125
  """
126
  Для thinking-моделей:
127
  1) Выводим "Думаю..."
 
132
  return
133
 
134
  model = MODELS[model_name]
135
+ genai_history = _history_to_genai_enhanced(history, model_name)
136
 
137
  # Сначала "Думаю..."
138
  yield "Думаю...", ""
 
147
  if response.candidates:
148
  parts = response.candidates[0].content.parts
149
  for p in parts:
150
+ if hasattr(p, "thought") and p.thought:
 
 
151
  thinking_process_text += p.text or ""
 
 
152
  else:
153
+ final_text += p.text or ""
154
 
155
  # Для thinking-моделей просили итоговый ответ в {output: ...}
156
  final_text_formatted = f"{{output: {final_text}}}"
 
184
  # Добавляем (user_message, None)
185
  history.append((user_message, None))
186
 
187
+ # Если модель — thinking
188
  if "thinking" in model_name.lower():
189
+ async for (assistant_text, thought_text) in _respond_thinking_enh(model_name, user_message, history):
190
  history[-1] = (user_message, assistant_text)
191
  yield history, thought_text
192
  return
193
  else:
194
  # Обычная модель
195
  partial_answer = ""
196
+ async for chunk in _respond_stream_enh(model_name, user_message, history):
197
  partial_answer = chunk
198
  history[-1] = (user_message, partial_answer)
199
  yield history, ""
 
220
 
221
  # Cообщаем модели, что переключились (developer role)
222
  new_history.append((
223
+ "<developer>: Switched to model: " + selected_model,
224
  None
225
  ))
226
 
 
230
  "No default prompt for this model."
231
  )
232
  new_history.append((
233
+ "<developer>: " + default_prompt,
234
  None
235
  ))
236
 
 
240
  # 9. Функция конвертации истории с учётом developer role
241
  ###############################################################################
242
 
243
+ def _history_to_genai_enhanced(history, model_name):
244
+ """
245
+ Улучшенная версия, отличающая developer-сообщения
246
+ (префикс "<developer>: ") от user-сообщений.
247
+ """
248
+ asst_role = _assistant_role(model_name)
249
+ genai_history = []
250
+
251
+ for user_text, bot_text in history:
252
+ if user_text:
253
+ if user_text.startswith("<developer>: "):
254
+ # Считаем это developer role
255
+ dev_content = user_text.replace("<developer>: ", "", 1)
256
+ genai_history.append({"role": "system", "parts": dev_content})
257
+ else:
258
+ # Обычный пользователь
259
+ genai_history.append({"role": "user", "parts": user_text})
260
+
261
+ if bot_text:
262
+ # Ответ ассистента / модель
263
+ genai_history.append({"role": asst_role, "parts": bot_text})
264
+
265
+ return genai_history
266
 
267
  ###############################################################################
268
  # 10. Построение интерфейса Gradio
 
274
  with gr.Row():
275
  model_dropdown = gr.Dropdown(
276
  choices=AVAILABLE_MODELS,
277
+ value="gemini-2.0-flash-exp",
278
  label="Выберите модель"
279
  )
280
  clear_button = gr.Button("Очистить чат")