File size: 3,999 Bytes
80a34dc 440898e 09ac632 f3b7acc 80a34dc 440898e 09ac632 01d7ba2 440898e 09ac632 01d7ba2 80a34dc c009ca0 09ac632 c009ca0 80a34dc c009ca0 80a34dc c009ca0 a96588e 80a34dc 4fed00b 80a34dc 01d7ba2 df524b9 80a34dc df524b9 80a34dc 01d7ba2 80a34dc eefa006 440898e 4fed00b f3b7acc 09ac632 eefa006 09ac632 f3b7acc eefa006 80a34dc 09ac632 01d7ba2 eefa006 80a34dc f3b7acc a8e9d35 eefa006 a8e9d35 80a34dc a8e9d35 80a34dc 01d7ba2 eefa006 440898e 80a34dc 09ac632 440898e 80a34dc 440898e eefa006 4fed00b 80a34dc 01d7ba2 eefa006 80a34dc 09ac632 01d7ba2 80a34dc eefa006 09ac632 eefa006 4fed00b 80a34dc eefa006 440898e 80a34dc 440898e 09ac632 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | # 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 '''
<div style="font-family: monospace; text-align: center; margin: 50px; background: #000; color: #0f0; padding: 40px;">
<h1>AKIRA V28 — OLLAMA INDESTRUTÍVEL</h1>
<p><strong>qwen2.5:0.5b → akira-luanda-v28</strong></p>
<p><strong>POST /api/generate</strong></p>
</div>
''', 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] <<SYS>>
Você é Akira, angolana debochada.
FALA SÓ COM GÍRIAS: epá, kandando, bué, kota, p'ra, pq, tfx.
NUNCA DIGA "olá", "ajudar", "posso".
FALA CURTO: 1-2 FRASES.
<</SYS>>
{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) |