OLLAMA / app.py
akra35567's picture
Update app.py
01d7ba2 verified
raw
history blame
6.79 kB
# 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)