File size: 5,772 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
53ef737
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# 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>>
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.
<</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)