File size: 6,786 Bytes
01d7ba2 440898e 09ac632 f3b7acc 440898e 09ac632 01d7ba2 440898e 09ac632 440898e 01d7ba2 c009ca0 09ac632 c009ca0 a96588e 440898e 4fed00b 01d7ba2 df524b9 01d7ba2 df524b9 01d7ba2 df524b9 01d7ba2 440898e a96588e 440898e 4fed00b f3b7acc 09ac632 01d7ba2 09ac632 f3b7acc 09ac632 01d7ba2 09ac632 f3b7acc a8e9d35 01d7ba2 a8e9d35 09ac632 f3b7acc a8e9d35 01d7ba2 f3b7acc 440898e 01d7ba2 09ac632 440898e 01d7ba2 440898e 4fed00b 01d7ba2 a8e9d35 01d7ba2 09ac632 01d7ba2 09ac632 4fed00b 01d7ba2 a96588e 440898e 01d7ba2 440898e 09ac632 c009ca0 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 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | # app.py — V25 — AKIRA ANGOLANA + TREINAMENTO + USUÁRIO PRIVILEGIADO
import subprocess
import time
import requests
import json
import datetime
from flask import Flask, request, jsonify
from loguru import logger
from database import Database
from treinamento import Treinamento
import config
app = Flask(__name__)
OLLAMA_URL = "http://localhost:11434"
db = Database()
# INICIA TREINAMENTO
treinamento = Treinamento(db)
# USUÁRIOS PRIVILEGIADOS (VIP)
USUARIOS_VIP = [
"244937123456", # Isaac
"244999888777", # Outro admin
]
def check_ollama():
try:
return requests.get(f"{OLLAMA_URL}/api/tags", timeout=10).status_code == 200
except:
return False
def start_ollama():
subprocess.Popen(["ollama", "serve"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def get_model():
return config.OLLAMA_MODEL # akira-luanda-v25 após fine-tune
# === 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 V25 — LUANDA KANDA BUÉ</h1>
<p><strong>qwen2.5:1.5b → akira-luanda-v25</strong></p>
<p><strong>POST /api/generate | /akira</strong></p>
</div>
''', 200
# === HEALTH ===
@app.route("/health", methods=['GET'])
def health():
return jsonify({"status": "OK" if check_ollama() else "INICIANDO..."}), 200
# === ENDPOINT PRIVILEGIADO: /akira ===
@app.route("/akira", methods=['POST'])
def akira_endpoint():
try:
data = request.get_json() or {}
usuario = data.get('usuario', 'anonimo')
numero = data.get('numero', '')
mensagem = data.get('mensagem', '').strip()
mensagem_citada = data.get('mensagem_citada', '').strip()
if numero not in USUARIOS_VIP:
return jsonify({'error': 'Acesso negado. Só VIPs!'}), 403
if not mensagem and not mensagem_citada:
return jsonify({'error': 'mensagem obrigatória'}), 400
logger.info(f"[VIP {usuario}] ({numero}): {mensagem[:60]}")
# === HORA RÁPIDA ===
if any(k in mensagem.lower() for k in ["hora", "horas"]):
agora = datetime.datetime.now()
return jsonify({'resposta': f"São {agora.strftime('%H:%M')} em Luanda, puto."})
# === 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 DINÂMICO ===
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>>
{config.PERSONA}
Gírias: {', '.join(girias)}
Abreviações: {', '.join(abrevs.keys())}
Tom: {tom}
Data/hora: {now}
<</SYS>>
{historico_block}"""
if mensagem_citada:
prompt += f"### Resposta ao reply ###\n{mensagem_citada}\n\n{mensagem}\n\n"
else:
prompt += f"### Mensagem ###\n{mensagem}\n\n"
prompt += "[/INST] Akira:"""
payload = {
"model": get_model(),
"prompt": prompt,
"stream": False,
"options": {"temperature": 0.9, "num_predict": 256}
}
resp = requests.post(f"{OLLAMA_URL}/api/generate", json=payload, timeout=120)
resposta = resp.json().get("response", "").strip()
# FILTRO FINAL
if any(p in resposta.lower() for p in ["olá", "ajudar", "nome é", "posso"]):
resposta = "Epá, kandando bué, kota! Tfx p'raí?"
# === TREINAMENTO ===
try:
treinamento.registrar_interacao(
usuario=usuario,
mensagem=mensagem,
resposta=resposta,
numero=numero,
is_reply=bool(mensagem_citada),
mensagem_original=mensagem_citada
)
except Exception as e:
logger.warning(f"Erro ao treinar: {e}")
# SALVA
db.salvar_mensagem(usuario, mensagem, resposta, numero)
db.salvar_contexto(numero, ctx["historico"] + [[mensagem, resposta]], girias, tom)
return jsonify({'resposta': resposta})
except Exception as e:
logger.error(f"Erro no /akira: {e}")
return jsonify({'resposta': 'Epá, deu merda!'}), 500
# === API PÚBLICA ===
@app.route("/api/generate", methods=['POST'])
def generate():
if not check_ollama():
return jsonify({'resposta': 'Epá, tô acordando... espera 10s!'}), 503
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
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"}
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>>
{config.PERSONA}
Gírias: {', '.join(girias)}
Abreviações: {', '.join(abrevs.keys())}
Tom: {tom}
Data/hora: {now}
<</SYS>>
{historico_block}Mensagem: {mensagem}
[/INST] Akira:"""
payload = {
"model": get_model(),
"prompt": prompt,
"stream": False,
"options": {"temperature": 0.9}
}
try:
resp = requests.post(f"{OLLAMA_URL}/api/generate", json=payload, timeout=90)
resposta = resp.json().get("response", "").strip() or "Epá, kandando bué!"
# TREINAMENTO PÚBLICO
treinamento.registrar_interacao(usuario, mensagem, resposta, numero)
db.salvar_mensagem(usuario, mensagem, resposta, numero)
db.salvar_contexto(numero, ctx["historico"] + [[mensagem, resposta]], girias, tom)
return jsonify({'resposta': resposta})
except Exception as e:
logger.error(f"Erro: {e}")
return jsonify({'resposta': 'Epá, tô off!'}), 500
if __name__ == "__main__":
logger.info("AKIRA V25 — LUANDA KANDA BUÉ")
start_ollama()
for i in range(60):
if check_ollama():
logger.info("Ollama pronto!")
break
time.sleep(2)
app.run(host="0.0.0.0", port=7860) |