FreshPixels commited on
Commit
fc5b058
·
verified ·
1 Parent(s): 9fd70c0

Delete server/telegram_handlers.py

Browse files
Files changed (1) hide show
  1. server/telegram_handlers.py +0 -316
server/telegram_handlers.py DELETED
@@ -1,316 +0,0 @@
1
- """Обработчики команд Telegram"""
2
-
3
- import json
4
- import threading
5
- from datetime import datetime
6
- from .config import ALLOWED_USER
7
- from .state import STATE
8
- from .process_manager import PROCESS_MANAGER
9
- from .internet_agent import INTERNET_AGENT
10
- from .file_manager import FILE_MANAGER
11
- from .notification_system import NOTIFICATIONS
12
- from .conductor_engine import ConductorEngine
13
- from .skill_orchestrator import SkillOrchestrator
14
- from .build_mode_editor import BuildModeEditor
15
- from .mode_handlers import run_chat_mode, run_skill_mode, run_build_mode
16
- from .telegram_utils import send_tg, download_tg_file, send_tg_file
17
- from .helpers import parse_skill_agents, parse_build_args, get_current_mode_info
18
-
19
- class BotHandler:
20
- HELP_TEXT = """PinkSky v7.0 — МОДУЛЬНАЯ АРХИТЕКТУРА
21
-
22
- 🎛️ Режимы:
23
- Chat — отправь сообщение
24
- /skill [задача] — Open Interpreter
25
- /build [спек] — сборка через кондуктор
26
-
27
- 🎭 Роли:
28
- /role [guru|hacker|architect|principal|evangelist|techlead|qa|sdet|qe|researcher|critic|universal]
29
- /role list — список ролей
30
-
31
- 🧠 Кондукторы:
32
- /conductor [default|strict|creative|economy|review|build]
33
- /conductor list — список
34
-
35
- 🤖 Модели:
36
- /model [имя] — переключить модель
37
- /model list — список моделей
38
-
39
- 📁 Файлы:
40
- /get [путь] — скачать файл
41
- /stop — остановить все процессы
42
-
43
- 🌐 Интернет:
44
- /search [запрос] — поиск в интернете
45
- /cache — статистика кэша
46
- /cache clear — очистить кэш
47
-
48
- 📊 Система:
49
- /status — текущий статус
50
- /history — история
51
- /export [json|md] — экспорт истории
52
- /mode — текущий режим"""
53
-
54
- def __init__(self):
55
- self.mode_editor = BuildModeEditor(STATE)
56
- self.skill_orchestrator = SkillOrchestrator(STATE)
57
-
58
- def handle_message(self, data: dict):
59
- if "message" not in data:
60
- return
61
-
62
- message = data["message"]
63
- chat_id = str(message.get("chat", {}).get("id", ""))
64
- if ALLOWED_USER and chat_id != ALLOWED_USER:
65
- return
66
-
67
- NOTIFICATIONS.set_chat_id(chat_id)
68
-
69
- text = message.get("text", message.get("caption", "")).strip()
70
-
71
- file_id, file_name = None, None
72
- target_msg = message
73
- if "reply_to_message" in message:
74
- if "document" in message["reply_to_message"] or "photo" in message["reply_to_message"]:
75
- target_msg = message["reply_to_message"]
76
- if "document" in target_msg:
77
- file_id = target_msg["document"]["file_id"]
78
- file_name = target_msg["document"].get("file_name", "document.file")
79
- elif "photo" in target_msg:
80
- file_id = target_msg["photo"][-1]["file_id"]
81
- file_name = "photo.jpg"
82
-
83
- file_context = ""
84
- if file_id:
85
- dl_path = download_tg_file(file_id, file_name)
86
- if dl_path:
87
- file_context = f"\n\n[SYSTEM: User attached file: ./{dl_path}]"
88
- if not text:
89
- send_tg(chat_id, f"📁 Файл `{file_name}` сохранён. Ответь командой, например: `/build Что в этом файле?`")
90
- return
91
-
92
- if not text:
93
- return
94
-
95
- parts = text.split(maxsplit=1)
96
- command = parts[0].lower()
97
- args = parts[1].strip() if len(parts) > 1 else ""
98
-
99
- # === HELP ===
100
- if command in ["/help", "/start"]:
101
- send_tg(chat_id, self.HELP_TEXT)
102
- return
103
-
104
- # === STOP ===
105
- if command == "/stop":
106
- result = PROCESS_MANAGER.cancel_all()
107
- send_tg(chat_id, f"{result}\n\n{self.HELP_TEXT}")
108
- return
109
-
110
- # === STATUS ===
111
- if command == "/status":
112
- info = get_current_mode_info()
113
- stats = f"""{info}
114
-
115
- 📊 Моделей: {len(STATE.models)}
116
- 📊 Ролей: {len(STATE.roles)}
117
- 📊 Кондукторов: {len(STATE.conductors)}
118
- 🌐 Интернет: {'✅' if STATE.build_context.get('internet_access', True) else '❌'}
119
- 🗑️ Кэш: {INTERNET_AGENT.get_cache_stats()}
120
- 🧵 Активных потоков: {PROCESS_MANAGER.get_active_count()}"""
121
- send_tg(chat_id, stats)
122
- return
123
-
124
- # === MODE ===
125
- if command == "/mode":
126
- send_tg(chat_id, get_current_mode_info())
127
- return
128
-
129
- # === CONDUCTOR ===
130
- if command == "/conductor":
131
- if args == "list":
132
- lines = ["🧠 Доступные кондукторы:"]
133
- for name, cond in STATE.conductors.items():
134
- marker = " [ACTIVE]" if name == STATE.current_conductor else ""
135
- lines.append(f"- {name}{marker}: {cond.description} [rank_by={cond.auto_rank_by}]")
136
- send_tg(chat_id, "\n".join(lines))
137
- return
138
- if args in STATE.conductors:
139
- STATE.current_conductor = args
140
- send_tg(chat_id, f"🧠 Кондуктор: {args.upper()}\n{STATE.conductors[args].description}")
141
- else:
142
- available = ", ".join(STATE.conductors.keys())
143
- send_tg(chat_id, f"Текущий: {STATE.current_conductor}\nДоступные: {available}")
144
- return
145
-
146
- # === ROLE ===
147
- if command == "/role":
148
- role_parts = args.split(maxsplit=1)
149
- subcmd = role_parts[0].lower() if role_parts else ""
150
- subargs = role_parts[1] if len(role_parts) > 1 else ""
151
-
152
- if subcmd == "list":
153
- lines = ["🎭 Доступные роли:"]
154
- for name, role in STATE.roles.items():
155
- marker = " [ACTIVE]" if name == STATE.current_role else ""
156
- lines.append(f"- {name}{marker}: {role.description} (complexity: {role.complexity})")
157
- send_tg(chat_id, "\n".join(lines))
158
- return
159
-
160
- if subcmd == "info" and subargs:
161
- role = STATE.roles.get(subargs)
162
- if role:
163
- send_tg(chat_id, f"🎭 Роль {subargs}:\n\n{role.description}\n\nComplexity: {role.complexity}\nPreferred: {', '.join(role.preferred_models)}\n\nPrompt:\n```\n{role.prompt[:500]}...\n```")
164
- else:
165
- send_tg(chat_id, f"❌ Роль {subargs} не найдена")
166
- return
167
-
168
- if subcmd == "add" and subargs:
169
- add_parts = subargs.split(maxsplit=1)
170
- if len(add_parts) < 2:
171
- send_tg(chat_id, "Формат: /role add <name> <prompt>")
172
- return
173
- new_name, new_prompt = add_parts[0], add_parts[1]
174
- from .models import Role
175
- STATE.roles[new_name] = Role(
176
- name=new_name, prompt=new_prompt,
177
- description=f"Custom role (added {datetime.now().strftime('%Y-%m-%d')})",
178
- complexity="medium"
179
- )
180
- STATE.save_roles()
181
- send_tg(chat_id, f"✅ Роль {new_name} добавлена!")
182
- return
183
-
184
- if subcmd in STATE.roles:
185
- STATE.current_role = subcmd
186
- send_tg(chat_id, f"🎭 Роль: {subcmd.upper()}\n{STATE.roles[subcmd].description}")
187
- else:
188
- available = ", ".join(STATE.roles.keys())
189
- send_tg(chat_id, f"Текущая: {STATE.current_role}\nДоступные: {available}")
190
- return
191
-
192
- # === MODEL ===
193
- if command == "/model":
194
- model_parts = args.split(maxsplit=1)
195
- subcmd = model_parts[0].lower() if model_parts else ""
196
- subargs = model_parts[1] if len(model_parts) > 1 else ""
197
-
198
- if subcmd == "list":
199
- lines = ["🤖 Модели (по coding rank):"]
200
- for name, model in sorted(STATE.models.items(), key=lambda x: x[1].coding_rank):
201
- if name == "hf_fallback":
202
- continue
203
- marker = " [ACTIVE]" if name == STATE.current_model else ""
204
- tier = 1
205
- if model.coding_rank > 5: tier = 2
206
- if model.coding_rank > 12: tier = 3
207
- if model.coding_rank > 18: tier = 4
208
- if model.coding_rank > 24: tier = 5
209
- cost = f"${model.cost_per_1k_output}/1k" if model.cost_per_1k_output > 0 else "free"
210
- lines.append(f"- {name}{marker} -- TIER {tier} | coding={model.coding_rank} speed={model.speed_rank} reasoning={model.reasoning_rank} | {cost}")
211
- send_tg(chat_id, "\n".join(lines))
212
- return
213
-
214
- if subcmd == "add" and subargs:
215
- add_parts = subargs.split()
216
- if len(add_parts) < 2:
217
- send_tg(chat_id, "Формат: /model add <name> <endpoint>")
218
- return
219
- new_name, new_endpoint = add_parts[0], add_parts[1]
220
- from .models import ModelConfig
221
- STATE.models[new_name] = ModelConfig(
222
- name=new_name, provider="openai", endpoint=new_endpoint,
223
- api_key_env="NVIDIA_API_KEY"
224
- )
225
- STATE.save_models()
226
- send_tg(chat_id, f"✅ Модель {new_name} добавлена!")
227
- return
228
-
229
- if subcmd in STATE.models:
230
- STATE.current_model = subcmd
231
- send_tg(chat_id, f"🤖 Модель: {subcmd.upper()}\n{STATE.models[subcmd].endpoint}")
232
- else:
233
- available = ", ".join([k for k in STATE.models.keys() if k != "hf_fallback"])
234
- send_tg(chat_id, f"Текущая: {STATE.current_model}\nДоступные: {available}")
235
- return
236
-
237
- # === GET FILE ===
238
- if command == "/get":
239
- if not args:
240
- send_tg(chat_id, "Использование: /get ./projects/test.py")
241
- else:
242
- send_tg_file(chat_id, args)
243
- return
244
-
245
- # === SEARCH ===
246
- if command == "/search":
247
- if not args:
248
- send_tg(chat_id, "Использование: /search запрос")
249
- return
250
- results = INTERNET_AGENT.search_web(args)
251
- if results:
252
- lines = [f"🔍 Результаты поиска: {args}\n"]
253
- for i, r in enumerate(results[:5], 1):
254
- lines.append(f"{i}. [{r['title']}]({r['url']})\n{r['snippet'][:150]}...\n")
255
- send_tg(chat_id, "\n".join(lines))
256
- else:
257
- send_tg(chat_id, "❌ Ничего не найдено")
258
- return
259
-
260
- # === CACHE ===
261
- if command == "/cache":
262
- if args == "clear":
263
- result = INTERNET_AGENT.clear_cache()
264
- send_tg(chat_id, result)
265
- else:
266
- send_tg(chat_id, INTERNET_AGENT.get_cache_stats())
267
- return
268
-
269
- # === HISTORY ===
270
- if command == "/history":
271
- mode = args if args in ("chat", "skill", "build") else "chat"
272
- history = getattr(STATE, f"{mode}_history", [])
273
- if not history:
274
- send_tg(chat_id, f"📋 История {mode} пуста")
275
- return
276
- lines = [f"📋 История {mode} (последние 5):"]
277
- for entry in history[-5:]:
278
- ts = entry.get("timestamp", "unknown")
279
- role = entry.get("role", "unknown")
280
- content = entry.get("content", "")[:200]
281
- lines.append(f"\n[{ts}] {role}:\n{content}...")
282
- send_tg(chat_id, "\n".join(lines))
283
- return
284
-
285
- # === EXPORT ===
286
- if command == "/export":
287
- fmt = args if args in ("json", "md") else "json"
288
- if fmt == "json":
289
- data = STATE.export_history_json()
290
- FILE_MANAGER.save_file("exports/history.json", data)
291
- send_tg_file(chat_id, "exports/history.json")
292
- else:
293
- data = STATE.export_history_md()
294
- FILE_MANAGER.save_file("exports/history.md", data)
295
- send_tg_file(chat_id, "exports/history.md")
296
- return
297
-
298
- # === BUILD MODE ===
299
- if command == "/build":
300
- if not args:
301
- send_tg(chat_id, "Укажите спецификацию проекта.")
302
- return
303
- params, clean_args = parse_build_args(args)
304
- run_build_mode(chat_id, clean_args, file_context, params)
305
- return
306
-
307
- # === SKILL MODE ===
308
- if command == "/skill":
309
- if not args:
310
- send_tg(chat_id, "Укажите задачу.")
311
- return
312
- run_skill_mode(chat_id, args, file_context)
313
- return
314
-
315
- # === DEFAULT: CHAT MODE ===
316
- run_chat_mode(chat_id, text, file_context)