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)