Kolyadual commited on
Commit
0429733
·
verified ·
1 Parent(s): c26c7c7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +29 -143
app.py CHANGED
@@ -1,33 +1,11 @@
1
- # app.py
2
  import gradio as gr
3
- import json
4
- import re
5
- from difflib import get_close_matches
6
  from huggingface_hub import InferenceClient
7
  from ddgs import DDGS
8
 
9
- # === Поддержка patterns.json (опционально) ===
10
- PATTERNS = {}
11
- KEYWORDS = {}
12
- HAS_PATTERNS = False
13
-
14
- try:
15
- with open("patterns.json", "r", encoding="utf-8") as f:
16
- PATTERNS = json.load(f)
17
- KEYWORDS = {
18
- "привет": ["привет", "здравствуй", "хай", "прив", "здарова"],
19
- "как дела": ["дела", "как ты", "ты как", "настроение"],
20
- "имя": ["имя", "кто ты", "зовут", "тебя зовут"],
21
- "школа": ["школа", "урок", "задача", "домашка", "математика", "геометрия"],
22
- "пока": ["пока", "выход", "quit", "до свидания", "закончить", "стоп"],
23
- "knowledge": ["что такое", "как приготовить", "что значит", "расскажи про", "как сделать"]
24
- }
25
- HAS_PATTERNS = True
26
- except Exception:
27
- HAS_PATTERNS = False
28
-
29
- def preprocess(text):
30
- return re.sub(r'[^а-яё\s]', ' ', text.lower()).strip()
31
 
32
  def web_search(query, max_results=3):
33
  try:
@@ -37,144 +15,52 @@ def web_search(query, max_results=3):
37
  except Exception:
38
  return ""
39
 
40
- def fallback_response(user_input):
41
- if not HAS_PATTERNS:
42
- return None
43
- clean = preprocess(user_input)
44
- if not clean:
45
- return None
46
- if any(w in clean for w in ["пока", "выход", "стоп", "quit", "закончить"]):
47
- return random.choice(PATTERNS["пока"])
48
- knowledge = PATTERNS.get("knowledge", {})
49
- if clean in knowledge:
50
- return knowledge[clean]
51
- matches = get_close_matches(clean, knowledge.keys(), n=1, cutoff=0.6)
52
- if matches:
53
- return knowledge[matches[0]]
54
- all_keywords = []
55
- keyword_to_intent = {}
56
- for intent, words in KEYWORDS.items():
57
- if intent == "knowledge":
58
- continue
59
- for w in words:
60
- all_keywords.append(w)
61
- keyword_to_intent[w] = intent
62
- for token in clean.split():
63
- kw_match = get_close_matches(token, all_keywords, n=1, cutoff=0.6)
64
- if kw_match:
65
- intent = keyword_to_intent[kw_match[0]]
66
- return random.choice(PATTERNS[intent])
67
- return random.choice(PATTERNS["default"])
68
-
69
- def respond(
70
- message: str,
71
- history: list,
72
- system_message: str,
73
- max_tokens: int,
74
- temperature: float,
75
- top_p: float,
76
- hf_token: gr.OAuthToken = None, # ← Сделали опциональным
77
- ):
78
- if not hf_token or not hf_token.token:
79
- # В примерах или без логина — возвращаем заглушку
80
- if message.lower().startswith("поиск:"):
81
- return "🔍 Пример поиска: погода сегодня — +2°C, солнечно."
82
- elif message.lower().startswith("система:"):
83
- return "🔒 Пример: команда 'выключи компьютер' недоступна в демо."
84
- else:
85
- return "👋 Привет! Это Newton MAX. Войдите в Hugging Face, чтобы начать общение."
86
 
87
-
88
- # === Системные команды ===
89
  if user_lower.startswith("система:"):
90
- yield "🔒 Управление системой недоступно в онлайн-демо. Установите Newton MAX локально для полного функционала."
91
- return
92
 
93
- # === Веб-поиск по запросу ===
94
  if user_lower.startswith("поиск:"):
95
  query = user_input[6:].strip()
96
  if not query:
97
- yield "🔍 Укажите, что искать. Пример: `поиск: погода в Москве`"
98
- return
99
- yield "🔍 Ищу в интернете...\n"
100
  context = web_search(query)
101
- if context:
102
- full_prompt = (
103
- f"Информация из интернета:\n{context}\n\n"
104
- f"На основе этого дай краткий и точный ответ на русском языке на вопрос: {query}\n"
105
- f"Отвечай строго на русском."
106
- )
107
- else:
108
- full_prompt = f"Не удалось найти информацию по запросу: {query}. Скажи об этом кратко на русском."
109
  else:
110
- # === Fallback через patterns.json (если запрос простой) ===
111
- if HAS_PATTERNS and not any(kw in user_lower for kw in ["что такое", "как сделать", "почему", "кто такой", "расскажи про", "почему"]):
112
- fallback = fallback_response(user_input)
113
- if fallback:
114
- yield fallback
115
- return
116
-
117
- # === Стандартный промпт для LLM ===
118
- full_prompt = f"{user_input}\nОтветь кратко и чётко на русском языке."
119
 
120
- # === Формируем историю в формате ChatCompletion ===
121
- messages = [{"role": "system", "content": system_message}]
122
- for msg in history:
123
- messages.append({"role": msg["role"], "content": msg["content"]})
124
- messages.append({"role": "user", "content": full_prompt})
125
-
126
- if not hf_token or not hf_token.token:
127
- yield "🔑 Пожалуйста, войдите в аккаунт Hugging Face (кнопка слева), чтобы использовать Newton MAX."
128
- return
129
-
130
- client = InferenceClient(
131
- token=hf_token.token,
132
- model="gpt-oss-20b"
133
- )
134
 
135
  response = ""
136
  try:
137
  for chunk in client.chat_completion(
138
- messages,
139
- max_tokens=max_tokens,
140
- stream=True,
141
- temperature=temperature,
142
- top_p=top_p,
143
  ):
144
- delta = chunk.choices[0].delta.content if chunk.choices and chunk.choices[0].delta.content else ""
145
- response += delta
146
  yield response
147
  except Exception as e:
148
- yield f"⚠️ Ошибка Inference API: {str(e)}"
149
 
150
- # === Gradio интерфейс ===
151
  chatbot = gr.ChatInterface(
152
  respond,
153
- type="messages",
154
  additional_inputs=[
155
- gr.Textbox(
156
- value="Ты Newton MAX, умный ассистент на русском языке. Отвечай кратко, точно и только на русском.",
157
- label="Системное сообщение"
158
- ),
159
- gr.Slider(minimum=1, maximum=1024, value=512, step=1, label="Макс. токенов"),
160
- gr.Slider(minimum=0.1, maximum=1.5, value=0.7, step=0.1, label="Температура"),
161
- gr.Slider(minimum=0.1, maximum=1.0, value=0.92, step=0.01, label="Top-p"),
162
- ],
163
- title="🚀 Newton MAX (gpt-oss-20b + Веб-поиск)",
164
- description="Поддерживает команды: `поиск: ...` и `система: ...`. Для работы требуется вход в Hugging Face.",
165
- examples=[
166
- ["Привет!", "Ты — Newton MAX, умный ассистент на русском языке. Отвечай кратко, точно и только на русском.", 512, 0.7, 0.92],
167
- ["Что такое квантовый компьютер?", "Ты — Newton MAX, умный ассистент на русском языке. Отвечай кратко, точно и только на русском.", 512, 0.7, 0.92],
168
- ["поиск: курс доллара сегодня", "Ты — Newton MAX, умный ассистент на русском языке. Отвечай кратко, точно и только на русском.", 768, 0.8, 0.95],
169
- ["система: перезагрузи компьютер", "Ты — Newton MAX, умный ассистент на русском языке. Отвечай кратко, точно и только на русском.", 256, 0.5, 0.9],
170
  ],
 
 
171
  )
172
 
173
- with gr.Blocks() as demo:
174
- with gr.Sidebar():
175
- gr.Markdown("### 🔑 Требуется вход")
176
- gr.LoginButton()
177
- chatbot.render()
178
-
179
  if __name__ == "__main__":
180
- demo.launch()
 
1
+ import os
2
  import gradio as gr
 
 
 
3
  from huggingface_hub import InferenceClient
4
  from ddgs import DDGS
5
 
6
+ HF_TOKEN = os.getenv("HF_TOKEN")
7
+ if not HF_TOKEN:
8
+ raise RuntimeError("Токен HF_TOKEN не задан в Secrets.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  def web_search(query, max_results=3):
11
  try:
 
15
  except Exception:
16
  return ""
17
 
18
+ def respond(message, history, system_message, max_tokens, temperature, top_p):
19
+ user_input = message.strip()
20
+ user_lower = user_input.lower()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
 
 
22
  if user_lower.startswith("система:"):
23
+ return "🔒 Управление системой недоступно в демо."
 
24
 
 
25
  if user_lower.startswith("поиск:"):
26
  query = user_input[6:].strip()
27
  if not query:
28
+ return "🔍 Укажите запрос."
 
 
29
  context = web_search(query)
30
+ prompt = (
31
+ f"{system_message}\n\n"
32
+ f"Информация из интернета:\n{context}\n\n"
33
+ f"Вопрос: {query}\nОтвет на русском:"
34
+ )
 
 
 
35
  else:
36
+ prompt = f"{system_message}\n\nВопрос: {user_input}\nОтвет на русском:"
 
 
 
 
 
 
 
 
37
 
38
+ messages = [{"role": "user", "content": prompt}]
39
+ client = InferenceClient(token=HF_TOKEN, model="openai/gpt-oss-20b")
 
 
 
 
 
 
 
 
 
 
 
 
40
 
41
  response = ""
42
  try:
43
  for chunk in client.chat_completion(
44
+ messages, max_tokens=max_tokens, stream=True,
45
+ temperature=temperature, top_p=top_p
 
 
 
46
  ):
47
+ token = chunk.choices[0].delta.content or ""
48
+ response += token
49
  yield response
50
  except Exception as e:
51
+ yield f"⚠️ Ошибка: {str(e)}"
52
 
 
53
  chatbot = gr.ChatInterface(
54
  respond,
 
55
  additional_inputs=[
56
+ gr.Textbox(value="Ты — Newton MAX. Отвечай кратко на русском.", label="Системное сообщение"),
57
+ gr.Slider(1, 1024, 512, label="Макс. токенов"),
58
+ gr.Slider(0.1, 1.5, 0.7, label="Температура"),
59
+ gr.Slider(0.1, 1.0, 0.92, label="Top-p"),
 
 
 
 
 
 
 
 
 
 
 
60
  ],
61
+ title="🚀 Newton MAX",
62
+ description="Демо с веб-поиском. Без входа!"
63
  )
64
 
 
 
 
 
 
 
65
  if __name__ == "__main__":
66
+ chatbot.launch()