# app.py import json import random import re from difflib import get_close_matches from huggingface_hub import InferenceClient from ddgs import DDGS import gradio as gr # === Загрузка patterns.json === try: with open("patterns.json", "r", encoding="utf-8") as f: PATTERNS = json.load(f) except: PATTERNS = { "привет": ["Привет!"], "пока": ["До свидания!"], "default": ["Не знаю."], "knowledge": {} } KEYWORDS = { "привет": ["привет", "здравствуй", "хай", "прив", "здарова"], "как дела": ["дела", "как ты", "ты как", "настроение"], "имя": ["имя", "кто ты", "зовут", "тебя зовут"], "школа": ["школа", "урок", "задача", "домашка", "математика", "геометрия"], "пока": ["пока", "выход", "quit", "до свидания", "закончить", "стоп"], "knowledge": ["что такое", "как приготовить", "что значит", "расскажи про", "как сделать"] } def preprocess(text): return re.sub(r'[^а-яё\s]', ' ', text.lower()).strip() # === Веб-поиск === def web_search(query, max_results=3): try: with DDGS() as ddgs: results = ddgs.text(query, region="ru-ru", max_results=max_results) return "\n".join([f"{r['title']}: {r['body']}" for r in results]) except Exception as e: return f"Поиск недоступен." # === Inference API (публичная модель, без токена) === MODEL_ID = "TinyLlama/TinyLlama-1.1B-Chat-v1.0" client = InferenceClient() def neural_generate(prompt_text): try: messages = [{"role": "user", "content": prompt_text}] response = "" for chunk in client.chat_completion( messages, model=MODEL_ID, max_tokens=256, temperature=0.6, top_p=0.92, stream=True ): token = chunk.choices[0].delta.content or "" response += token return response.strip() except Exception as e: return f"Ошибка генерации: {str(e)[:100]}" # === Основная логика (гибрид Micro + MAX) === def respond(message, history): user_input = message.strip() if not user_input: return "Введите запрос." user_lower = user_input.lower() # Система (заглушка) if user_lower.startswith("система:"): return "🔒 Управление ОС недоступно в демо." # Веб-поиск if user_lower.startswith("поиск:"): query = user_input[6:].strip() if not query: return "🔍 Пример: `поиск: погода в Москве`" yield "🔍 Ищу...\n" context = web_search(query) prompt = ( f"ИНФОРМАЦИЯ ИЗ ИНТЕРНЕТА:\n{context}\n\n" f"Кратко ответь на русском: {query}" ) yield neural_generate(prompt) return # === Newton Micro логика === clean = preprocess(user_input) if clean: if any(w in clean for w in ["пока", "выход", "стоп", "quit", "закончить"]): yield random.choice(PATTERNS["пока"]) return knowledge = PATTERNS.get("knowledge", {}) if clean in knowledge: yield knowledge[clean] return matches = get_close_matches(clean, knowledge.keys(), n=1, cutoff=0.6) if matches: yield knowledge[matches[0]] return all_keywords = [] keyword_to_intent = {} for intent, words in KEYWORDS.items(): if intent == "knowledge": continue for w in words: all_keywords.append(w) keyword_to_intent[w] = intent for token in clean.split(): kw_match = get_close_matches(token, all_keywords, n=1, cutoff=0.6) if kw_match: intent = keyword_to_intent[kw_match[0]] yield random.choice(PATTERNS[intent]) return # Fallback на нейросеть prompt = f"Ответь кратко на русском: {user_input}" yield neural_generate(prompt) # === Gradio интерфейс === chatbot = gr.ChatInterface( respond, title="Newton MAX (Micro + MAX)", description="Поддержка: `поиск: ...`, `система: ...`", examples=[ ["Привет!", None], ["Что такое ИИ?", None], ["поиск: что такое UncomOS", None], ["система: выключи компьютер", None] ], theme="soft" ) if __name__ == "__main__": chatbot.launch()