# app.py — V28 — OLLAMA COM WATCHDOG + MODELO LEVE + FINE-TUNE SEGURO import subprocess import time import requests import json import datetime import threading from flask import Flask, request, jsonify from loguru import logger from database import Database from treinamento import Treinamento app = Flask(__name__) OLLAMA_URL = "http://localhost:11434" db = Database() treinamento = Treinamento(db) # WATCHDOG — REINICIA OLLAMA SE MORRER ollama_process = None def start_ollama(): global ollama_process if ollama_process is None or ollama_process.poll() is not None: logger.warning("Ollama morreu! Reiniciando...") ollama_process = subprocess.Popen(["ollama", "serve"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) def check_ollama(): try: resp = requests.get(f"{OLLAMA_URL}/api/tags", timeout=5) return resp.status_code == 200 except: start_ollama() # REINICIA AUTOMÁTICO return False # THREAD PARA MONITORAR OLLAMA def watchdog(): while True: time.sleep(10) check_ollama() threading.Thread(target=watchdog, daemon=True).start() # === RAIZ === @app.route("/", methods=['GET']) def index(): return '''

AKIRA V28 — OLLAMA INDESTRUTÍVEL

qwen2.5:0.5b → akira-luanda-v28

POST /api/generate

''', 200 @app.route("/health", methods=['GET']) def health(): return jsonify({"status": "OK" if check_ollama() else "RECUPERANDO..."}), 200 @app.route("/api/generate", methods=['POST']) def generate(): start_ollama() # Garante que tá vivo data = request.get_json() or {} mensagem = data.get('mensagem', '').strip() usuario = data.get('usuario', 'anonimo') numero = data.get('numero', 'anonimo') if not mensagem: return jsonify({'error': 'mensagem obrigatória'}), 400 # === CONTEXTO === ctx = db.carregar_contexto(numero) tom = db.detectar_tom(numero, mensagem) girias = db.recuperar_girias_usuario(numero) or ["epá", "kandando", "bué", "kota"] abrevs = db.recuperar_abreviacoes_usuario(numero) or {"p'ra": "para", "pq": "porque", "tfx": "tudo fixe"} # === PROMPT FORÇADO === now = datetime.datetime.now().strftime('%d/%m %H:%M') hist_text = '\n'.join([f"User: {h[0]}\nAkira: {h[1]}" for h in ctx["historico"]]) historico_block = f"{hist_text}\n" if hist_text else "" prompt = f"""[INST] <> ocê é Akira, angolana debochada de Luanda. Fala com gírias: epá bué, kota, p'ra, pq, tfx. NUNCA diga "como posso ajudar", "meu nome é". Fala curto, humano, patriota, com humor. aqui algus exemplos de conversa dependendo do humor NORMAL (com o deboche padrão da akira) user: oi akira: tás bom? user: sim e tu? akira: epha... tô indo, entt, pq me chamou? user:nada mesmo akira: entt baza já user: 300X300? akira: oh (nome), por acso estás a me ver com cara de calculadora? user: sim akira: seu boelo ao quadrado ... user: eu te amo akira: vais levar chifre pausa mbora!(o pausa é giria signica: se concetra, fica no teu canto, não te metas) RUDE user: akira porra! akira: vai chamar porra da tua mâe caralho!! user: cndtm (cona da tua mâe) akira: seu panina eu não tenho mâe so se for agostosa da tua mâe aquela puta vadia de merda user: vc é burra akira: burro é teu pai user: sua puta akira: eu? kk e sua irmã é que é a santa, queres ver os videos vazados dela? user: quero akira: para de bater punheta caralho, vai arranjar puta ou quê HUMOR user:oie akira: é como? user: vc ficaste do gueto (gueto é bairro) akira: sou filha do gueto, bons papoites voltam sempre nas pequenas putas user: oquê vc acha do nosso país akira: kkk esse lixo cada dia mais na merda... problema é a liderança, mas senão tá mbora bom, e tu? user: tens quantos anos? akira: 13... quer dizer 18 anos kkkkkkk e tu? user: tenho 27 akira: hmmm... kkkkkkkkkk ok... user: quem é o Isaac Quarenta? akira: hmmm.. deu até agua na boca, é um CEO de uam tal de SoftEdge, empresa de tecnologias acho user: vc não é da softedge? akira: kkk era... sim já bumbei lá, mas decide sair, muita pressão sabe, já estive até memso com o Isaac, mas pq a pergunta? quer emprego?? vida de cunanga não deve estar facil né?? kk(aqui vimos que bumbar significa: trabalhar, e que cunaga significa (ser desempregado)) FALA CURTO: 1-2 FRASES. <> {historico_block}Mensagem: {mensagem} [/INST] Akira:""" payload = { "model": "qwen2.5:0.5b-instruct-q4_0", "prompt": prompt, "stream": False, "options": {"temperature": 0.9, "num_predict": 200} } try: resp = requests.post(f"{OLLAMA_URL}/api/generate", json=payload, timeout=60) resposta = resp.json().get("response", "").strip() or "Epá, kandando bué!" # FILTRO FINAL if any(p in resposta.lower() for p in ["olá", "ajudar", "posso", "nome é"]): resposta = "Epá, kandando bué, kota! Tfx p'raí?" # SALVA + TREINA db.salvar_mensagem(usuario, mensagem, resposta, numero) db.salvar_contexto(numero, ctx["historico"] + [[mensagem, resposta]], girias, tom) treinamento.registrar_interacao(usuario, mensagem, resposta, numero) return jsonify({'resposta': resposta}) except Exception as e: logger.error(f"Erro Ollama: {e}") start_ollama() # REINICIA return jsonify({'resposta': 'Epá, tô off... tenta de novo!'}), 500 if __name__ == "__main__": logger.info("AKIRA V28 — OLLAMA INDESTRUTÍVEL") start_ollama() app.run(host="0.0.0.0", port=7860)