Spaces:
Running
Running
Upload 13 files
Browse files- .dockerignore +27 -27
- .env.example +44 -44
- .gitattributes +37 -37
- Dockerfile +52 -41
- README.md +6 -6
- code-dev-fullstack.md +108 -0
- docker-compose.yml +13 -13
- main.py +191 -225
- plano_correcoes.md +100 -0
- plano_melhorias.md +132 -0
- requirements.txt +138 -19
- setup.py +47 -47
- testar_correcoes.py +312 -0
.dockerignore
CHANGED
|
@@ -1,27 +1,27 @@
|
|
| 1 |
-
**/__pycache__
|
| 2 |
-
**/.venv
|
| 3 |
-
**/.classpath
|
| 4 |
-
**/.dockerignore
|
| 5 |
-
**/.env
|
| 6 |
-
**/.git
|
| 7 |
-
**/.gitignore
|
| 8 |
-
**/.project
|
| 9 |
-
**/.settings
|
| 10 |
-
**/.toolstarget
|
| 11 |
-
**/.vs
|
| 12 |
-
**/.vscode
|
| 13 |
-
**/*.*proj.user
|
| 14 |
-
**/*.dbmdl
|
| 15 |
-
**/*.jfm
|
| 16 |
-
**/bin
|
| 17 |
-
**/charts
|
| 18 |
-
**/docker-compose*
|
| 19 |
-
**/compose*
|
| 20 |
-
**/Dockerfile*
|
| 21 |
-
**/node_modules
|
| 22 |
-
**/npm-debug.log
|
| 23 |
-
**/obj
|
| 24 |
-
**/secrets.dev.yaml
|
| 25 |
-
**/values.dev.yaml
|
| 26 |
-
LICENSE
|
| 27 |
-
README.md
|
|
|
|
| 1 |
+
**/__pycache__
|
| 2 |
+
**/.venv
|
| 3 |
+
**/.classpath
|
| 4 |
+
**/.dockerignore
|
| 5 |
+
**/.env
|
| 6 |
+
**/.git
|
| 7 |
+
**/.gitignore
|
| 8 |
+
**/.project
|
| 9 |
+
**/.settings
|
| 10 |
+
**/.toolstarget
|
| 11 |
+
**/.vs
|
| 12 |
+
**/.vscode
|
| 13 |
+
**/*.*proj.user
|
| 14 |
+
**/*.dbmdl
|
| 15 |
+
**/*.jfm
|
| 16 |
+
**/bin
|
| 17 |
+
**/charts
|
| 18 |
+
**/docker-compose*
|
| 19 |
+
**/compose*
|
| 20 |
+
**/Dockerfile*
|
| 21 |
+
**/node_modules
|
| 22 |
+
**/npm-debug.log
|
| 23 |
+
**/obj
|
| 24 |
+
**/secrets.dev.yaml
|
| 25 |
+
**/values.dev.yaml
|
| 26 |
+
LICENSE
|
| 27 |
+
README.md
|
.env.example
CHANGED
|
@@ -1,45 +1,45 @@
|
|
| 1 |
-
# .env.example — Copie para .env e preencha suas chaves
|
| 2 |
-
# ============================================================================
|
| 3 |
-
# 🔥 CHAVES DE API — OBTENHA EM:
|
| 4 |
-
# ============================================================================
|
| 5 |
-
|
| 6 |
-
# MISTRAL (https://console.mistral.ai/)
|
| 7 |
-
# Limite: 60k tokens/mês grátis
|
| 8 |
-
MISTRAL_API_KEY=jy0tmu2iAbPyhEFJORCECxEg7hh0pd3a
|
| 9 |
-
|
| 10 |
-
# GOOGLE GEMINI (https://aistudio.google.com/app/apikey)
|
| 11 |
-
# Limite: 1.5M tokens/mês grátis
|
| 12 |
-
GEMINI_API_KEY=AIzaSyBcX3wqmEDYTrggNNbv31-A2QG2A7IssRc
|
| 13 |
-
|
| 14 |
-
# GROQ (https://console.groq.com/keys)
|
| 15 |
-
# Limite: ~10k tokens/dia grátis
|
| 16 |
-
GROQ_API_KEY=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
|
| 17 |
-
|
| 18 |
-
# COHERE (https://dashboard.cohere.com/api-keys)
|
| 19 |
-
# Limite: 1k gerações/mês grátis
|
| 20 |
-
COHERE_API_KEY=sua_chave_aqui
|
| 21 |
-
|
| 22 |
-
# TOGETHER AI (https://api.together.xyz/settings/api-keys)
|
| 23 |
-
# Limite: $25 créditos iniciais grátis
|
| 24 |
-
TOGETHER_API_KEY=sua_chave_aqui
|
| 25 |
-
|
| 26 |
-
# HUGGING FACE (https://huggingface.co/settings/tokens)
|
| 27 |
-
# Limite: Ilimitado com rate limit
|
| 28 |
-
HF_API_KEY=hf_sua_chave_aqui
|
| 29 |
-
|
| 30 |
-
# ============================================================================
|
| 31 |
-
# 🌐 CONFIGURAÇÕES DE SERVIDOR (OPCIONAL)
|
| 32 |
-
# ============================================================================
|
| 33 |
-
|
| 34 |
-
API_HOST=0.0.0.0
|
| 35 |
-
API_PORT=7860
|
| 36 |
-
|
| 37 |
-
# ============================================================================
|
| 38 |
-
# 📝 NOTAS
|
| 39 |
-
# ============================================================================
|
| 40 |
-
#
|
| 41 |
-
# 1. Copie este arquivo: cp .env.example .env
|
| 42 |
-
# 2. Preencha PELO MENOS Mistral + Gemini (mínimo 2 APIs)
|
| 43 |
-
# 3. Adicione .env ao .gitignore (NUNCA commite chaves!)
|
| 44 |
-
# 4. Para Hugging Face Spaces: adicione chaves em Repository Secrets
|
| 45 |
#
|
|
|
|
| 1 |
+
# .env.example — Copie para .env e preencha suas chaves
|
| 2 |
+
# ============================================================================
|
| 3 |
+
# 🔥 CHAVES DE API — OBTENHA EM:
|
| 4 |
+
# ============================================================================
|
| 5 |
+
|
| 6 |
+
# MISTRAL (https://console.mistral.ai/)
|
| 7 |
+
# Limite: 60k tokens/mês grátis
|
| 8 |
+
MISTRAL_API_KEY=jy0tmu2iAbPyhEFJORCECxEg7hh0pd3a
|
| 9 |
+
|
| 10 |
+
# GOOGLE GEMINI (https://aistudio.google.com/app/apikey)
|
| 11 |
+
# Limite: 1.5M tokens/mês grátis
|
| 12 |
+
GEMINI_API_KEY=AIzaSyBcX3wqmEDYTrggNNbv31-A2QG2A7IssRc
|
| 13 |
+
|
| 14 |
+
# GROQ (https://console.groq.com/keys)
|
| 15 |
+
# Limite: ~10k tokens/dia grátis
|
| 16 |
+
GROQ_API_KEY=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
|
| 17 |
+
|
| 18 |
+
# COHERE (https://dashboard.cohere.com/api-keys)
|
| 19 |
+
# Limite: 1k gerações/mês grátis
|
| 20 |
+
COHERE_API_KEY=sua_chave_aqui
|
| 21 |
+
|
| 22 |
+
# TOGETHER AI (https://api.together.xyz/settings/api-keys)
|
| 23 |
+
# Limite: $25 créditos iniciais grátis
|
| 24 |
+
TOGETHER_API_KEY=sua_chave_aqui
|
| 25 |
+
|
| 26 |
+
# HUGGING FACE (https://huggingface.co/settings/tokens)
|
| 27 |
+
# Limite: Ilimitado com rate limit
|
| 28 |
+
HF_API_KEY=hf_sua_chave_aqui
|
| 29 |
+
|
| 30 |
+
# ============================================================================
|
| 31 |
+
# 🌐 CONFIGURAÇÕES DE SERVIDOR (OPCIONAL)
|
| 32 |
+
# ============================================================================
|
| 33 |
+
|
| 34 |
+
API_HOST=0.0.0.0
|
| 35 |
+
API_PORT=7860
|
| 36 |
+
|
| 37 |
+
# ============================================================================
|
| 38 |
+
# 📝 NOTAS
|
| 39 |
+
# ============================================================================
|
| 40 |
+
#
|
| 41 |
+
# 1. Copie este arquivo: cp .env.example .env
|
| 42 |
+
# 2. Preencha PELO MENOS Mistral + Gemini (mínimo 2 APIs)
|
| 43 |
+
# 3. Adicione .env ao .gitignore (NUNCA commite chaves!)
|
| 44 |
+
# 4. Para Hugging Face Spaces: adicione chaves em Repository Secrets
|
| 45 |
#
|
.gitattributes
CHANGED
|
@@ -1,37 +1,37 @@
|
|
| 1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
-
akira.db filter=lfs diff=lfs merge=lfs -text
|
| 37 |
-
test.db filter=lfs diff=lfs merge=lfs -text
|
|
|
|
| 1 |
+
*.7z filter=lfs diff=lfs merge=lfs -text
|
| 2 |
+
*.arrow filter=lfs diff=lfs merge=lfs -text
|
| 3 |
+
*.bin filter=lfs diff=lfs merge=lfs -text
|
| 4 |
+
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
| 5 |
+
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
| 6 |
+
*.ftz filter=lfs diff=lfs merge=lfs -text
|
| 7 |
+
*.gz filter=lfs diff=lfs merge=lfs -text
|
| 8 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
| 9 |
+
*.joblib filter=lfs diff=lfs merge=lfs -text
|
| 10 |
+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
| 11 |
+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
| 12 |
+
*.model filter=lfs diff=lfs merge=lfs -text
|
| 13 |
+
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
| 14 |
+
*.npy filter=lfs diff=lfs merge=lfs -text
|
| 15 |
+
*.npz filter=lfs diff=lfs merge=lfs -text
|
| 16 |
+
*.onnx filter=lfs diff=lfs merge=lfs -text
|
| 17 |
+
*.ot filter=lfs diff=lfs merge=lfs -text
|
| 18 |
+
*.parquet filter=lfs diff=lfs merge=lfs -text
|
| 19 |
+
*.pb filter=lfs diff=lfs merge=lfs -text
|
| 20 |
+
*.pickle filter=lfs diff=lfs merge=lfs -text
|
| 21 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
| 22 |
+
*.pt filter=lfs diff=lfs merge=lfs -text
|
| 23 |
+
*.pth filter=lfs diff=lfs merge=lfs -text
|
| 24 |
+
*.rar filter=lfs diff=lfs merge=lfs -text
|
| 25 |
+
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
| 26 |
+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
| 27 |
+
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
| 28 |
+
*.tar filter=lfs diff=lfs merge=lfs -text
|
| 29 |
+
*.tflite filter=lfs diff=lfs merge=lfs -text
|
| 30 |
+
*.tgz filter=lfs diff=lfs merge=lfs -text
|
| 31 |
+
*.wasm filter=lfs diff=lfs merge=lfs -text
|
| 32 |
+
*.xz filter=lfs diff=lfs merge=lfs -text
|
| 33 |
+
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
+
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
+
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
akira.db filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
test.db filter=lfs diff=lfs merge=lfs -text
|
Dockerfile
CHANGED
|
@@ -1,41 +1,52 @@
|
|
| 1 |
-
# Dockerfile — AKIRA
|
| 2 |
-
# Otimizado para Hugging Face Spaces (CPU básico)
|
| 3 |
-
|
| 4 |
-
FROM python:3.11-slim
|
| 5 |
-
|
| 6 |
-
# Variáveis de ambiente
|
| 7 |
-
ENV DEBIAN_FRONTEND=noninteractive \
|
| 8 |
-
PYTHONUNBUFFERED=1 \
|
| 9 |
-
PYTHONDONTWRITEBYTECODE=1 \
|
| 10 |
-
PIP_NO_CACHE_DIR=1 \
|
| 11 |
-
PIP_DISABLE_PIP_VERSION_CHECK=1
|
| 12 |
-
|
| 13 |
-
WORKDIR /
|
| 14 |
-
|
| 15 |
-
# Instala
|
| 16 |
-
RUN apt-get update && \
|
| 17 |
-
apt-get install -y --no-install-recommends \
|
| 18 |
-
curl \
|
| 19 |
-
ca-certificates
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
#
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Dockerfile — AKIRA V21 ULTIMATE (Janeiro 2025)
|
| 2 |
+
# Otimizado para Hugging Face Spaces (CPU básico)
|
| 3 |
+
|
| 4 |
+
FROM python:3.11-slim
|
| 5 |
+
|
| 6 |
+
# Variáveis de ambiente
|
| 7 |
+
ENV DEBIAN_FRONTEND=noninteractive \
|
| 8 |
+
PYTHONUNBUFFERED=1 \
|
| 9 |
+
PYTHONDONTWRITEBYTECODE=1 \
|
| 10 |
+
PIP_NO_CACHE_DIR=1 \
|
| 11 |
+
PIP_DISABLE_PIP_VERSION_CHECK=1
|
| 12 |
+
|
| 13 |
+
WORKDIR /akira
|
| 14 |
+
|
| 15 |
+
# Instala ferramentas essenciais + Tesseract OCR (OpenCV headless não precisa de OpenGL)
|
| 16 |
+
RUN apt-get update && \
|
| 17 |
+
apt-get install -y --no-install-recommends \
|
| 18 |
+
curl \
|
| 19 |
+
ca-certificates \
|
| 20 |
+
tesseract-ocr \
|
| 21 |
+
tesseract-ocr-por \
|
| 22 |
+
tesseract-ocr-eng \
|
| 23 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 24 |
+
|
| 25 |
+
# Copia dependências
|
| 26 |
+
COPY requirements.txt .
|
| 27 |
+
|
| 28 |
+
# Instala dependências Python
|
| 29 |
+
RUN pip install --upgrade pip && \
|
| 30 |
+
pip install --no-cache-dir --prefer-binary \
|
| 31 |
+
numpy \
|
| 32 |
+
torch --index-url https://download.pytorch.org/whl/cpu \
|
| 33 |
+
transformers \
|
| 34 |
+
peft \
|
| 35 |
+
accelerate \
|
| 36 |
+
bitsandbytes \
|
| 37 |
+
-r requirements.txt
|
| 38 |
+
|
| 39 |
+
# Copia código da aplicação
|
| 40 |
+
COPY main.py .
|
| 41 |
+
COPY modules/ modules/
|
| 42 |
+
|
| 43 |
+
# Healthcheck
|
| 44 |
+
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
| 45 |
+
CMD curl -f http://localhost:7860/health || exit 1
|
| 46 |
+
|
| 47 |
+
# Expõe porta
|
| 48 |
+
EXPOSE 7860
|
| 49 |
+
|
| 50 |
+
# Comando de inicialização
|
| 51 |
+
CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "2", "--threads", "4", "--timeout", "120", "main:app"]
|
| 52 |
+
|
README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
-
---
|
| 2 |
-
title: akira
|
| 3 |
-
sdk: docker
|
| 4 |
-
emoji: 🚀
|
| 5 |
-
colorFrom: blue
|
| 6 |
-
colorTo: purple
|
| 7 |
---
|
|
|
|
| 1 |
+
---
|
| 2 |
+
title: akira
|
| 3 |
+
sdk: docker
|
| 4 |
+
emoji: 🚀
|
| 5 |
+
colorFrom: blue
|
| 6 |
+
colorTo: purple
|
| 7 |
---
|
code-dev-fullstack.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Integração do Isolamento de Contexto e Manipulação de Respostas (AKIRA-SOFTEDGE)
|
| 2 |
+
|
| 3 |
+
## Visão Geral
|
| 4 |
+
Este documento descreve *tin-tin por tin-tin* as adaptações realizadas para integrar o sistema de Isolamento de Contexto, Memória de Curto Prazo (STM) e o Tratamento Avançado de Respostas (Reply Context) do projeto `akira-index` no `AKIRA-SOFTEDGE`. Todo o processo foi pensado de forma a manter intocados os algoritmos de **Personalidade** e **Prompt** presentes originalmente no `AKIRA-SOFTEDGE`.
|
| 5 |
+
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
## 1. O Problema Resolvido
|
| 9 |
+
O sistema anterior do `AKIRA-SOFTEDGE` compartilhava a memória de chamadas contínuas não isolando completamente quem mandava a mensagem (podendo misturar histórico de grupo com histórico privado em alguns escopos). Além disso:
|
| 10 |
+
- Respostas curtas que citavam outra mensagem do Bot perdiam contexto facilmente (ex: responder "qual?" para uma mensagem giganta).
|
| 11 |
+
- O Payload JSON retornado não coincidia com o que a ponte NodeJS (`index-js2.1`) agora esperava (metadados de quote, etc).
|
| 12 |
+
|
| 13 |
+
## 2. Ferramentas e Módulos Importados
|
| 14 |
+
Para sanar essas limitações, os seguintes módulos independentes foram copiados e inseridos no projeto base (`AKIRA-SOFTEDGE/modules/`):
|
| 15 |
+
|
| 16 |
+
* `context_isolation.py`: Contém o `ContextIsolationManager`. Cria Hash IDs de conversa combinando `usuario + tipo_conversa + grupo`, permitindo que o mesmo usuário tenha estados mentais (conversas) diferentes dependendo de onde ele está chamando o bot.
|
| 17 |
+
* `short_term_memory.py`: Contém a `ShortTermMemoryManager`. Uma lista na memória volátil limitando o cache rotativo a 15 mensagens estritas, evitando estouro de tokens sem danificar a coerência.
|
| 18 |
+
* `reply_context_handler.py`: Contém classes que dissecam o Payload de citação de resposta. Define scores e prioridades de atendimento (ex: Pergunta Curta com Reply tem altíssima prioridade).
|
| 19 |
+
* `unified_context.py`: Construtor (`UnifiedContextBuilder`) que cola o histórico do banco de dados, o isolamento e a Memória de Curto Prazo em um único Prompt String limpo.
|
| 20 |
+
|
| 21 |
+
---
|
| 22 |
+
|
| 23 |
+
## 3. Fluxo Técnico de Implementação
|
| 24 |
+
|
| 25 |
+
### 3.1. Integração no `api.py`
|
| 26 |
+
Foi necessário interceptar e adicionar novos gestores na classe `AkiraAPI`.
|
| 27 |
+
|
| 28 |
+
**Instanciamento na Inicialização:**
|
| 29 |
+
```python
|
| 30 |
+
# Em AkiraAPI.__init__
|
| 31 |
+
try:
|
| 32 |
+
db_instance = Database(getattr(self.config, 'DB_PATH', 'akira.db'))
|
| 33 |
+
except Exception:
|
| 34 |
+
db_instance = None
|
| 35 |
+
|
| 36 |
+
# Injetando construtores lógicos
|
| 37 |
+
self.context_manager = ContextIsolationManager(db=db_instance)
|
| 38 |
+
self.stm_manager = ShortTermMemoryManager(max_messages=15)
|
| 39 |
+
self.unified_builder = UnifiedContextBuilder(
|
| 40 |
+
context_manager=self.context_manager,
|
| 41 |
+
stm_manager=self.stm_manager,
|
| 42 |
+
db_instance=db_instance
|
| 43 |
+
)
|
| 44 |
+
```
|
| 45 |
+
|
| 46 |
+
**Rota de Escuta `/akira` e Fluxo de Entrada:**
|
| 47 |
+
1. A API recebe o payload contendo o texto, usuário, tipo de conversa, e agora o nó vital: `reply_metadata`.
|
| 48 |
+
2. Em vez de injetar o estado de usuário genérico diretamente, chamamos:
|
| 49 |
+
```python
|
| 50 |
+
conversation_id = self.context_manager.get_conversation_id(
|
| 51 |
+
usuario=usuario,
|
| 52 |
+
conversation_type=tipo_conversa,
|
| 53 |
+
group_id=numero if tipo_conversa == 'grupo' else None
|
| 54 |
+
)
|
| 55 |
+
```
|
| 56 |
+
3. O `conversation_id` cria e acopla a chave única. Em seguida, a inteligência `unified_builder.build_context()` entra em cena para absorver os metadados de reply (texto original, quem o bot está respondendo) junto ao histórico local.
|
| 57 |
+
|
| 58 |
+
**Mudanças cruciais no Prompt (`_build_prompt`):**
|
| 59 |
+
O prompt do `AKIRA-SOFTEDGE` (com suas restrições *STRICT_OVERRIDES* maravilhosas, incluindo o tom `love`) foi preservado. Entretanto, a assinatura agora aceita e acopla a string polida do `unified_context` no meio do payload:
|
| 60 |
+
```python
|
| 61 |
+
if unified_context and unified_context.formatted_prompt_section:
|
| 62 |
+
strict_override += "\n" + unified_context.formatted_prompt_section + "\n"
|
| 63 |
+
```
|
| 64 |
+
Com isso, a IA passa a receber o **[CONTEXTO DE REPLY]** e **[HISTÓRICO RECENTE]** unificados logo acima do seu próprio `SYSTEM_PROMPT`.
|
| 65 |
+
|
| 66 |
+
**Resposta JSON Adequada:**
|
| 67 |
+
Por fim, atualizamos o `jsonify()` do Flask para retornar variáveis mandatórias como `is_reply`, `quoted_author` e `context_hint`.
|
| 68 |
+
|
| 69 |
+
### 3.2. Integração no `contexto.py`
|
| 70 |
+
A classe Base `Contexto` precisava ler e compreender as sub-janelas de análise (usadas pelo `reply_context_handler`). Adicionamos novos métodos:
|
| 71 |
+
* `obter_historico_expandido(self, limite)`
|
| 72 |
+
* `criar_resumo_topicos_conversa(self, historico)`
|
| 73 |
+
* E todo o pipeline de extração de reply (como `processar_contexto_reply`).
|
| 74 |
+
|
| 75 |
+
Essas funções fazem parseamentos sintáticos manuais baseados em expressões regulares simples, detectando se uma citação abrange `tempo_clima`, `pesquisa` ou `emocao`.
|
| 76 |
+
|
| 77 |
+
---
|
| 78 |
+
|
| 79 |
+
## 4. Variáveis e Estado
|
| 80 |
+
* `reply_metadata_robust`: Um dicionário recriado no pipeline de resposta para garantir que nunca enviaremos "Nones" ou "Undefineds" pelo Request da Citação.
|
| 81 |
+
* `smart_context_instruction`: Flag em texto bruto. Se a prioridade de uma Citação / Reply for `>= 3` (Significa usualmente: Um reply curto feito diretamente a uma mensagem do bot), adicionamos no fim da string uma ordem extrema: `"⚠️ ATENÇÃO: PERGUNTA CURTA COM REPLY. FOCAR TOTALMENTE NO CONTEXTO DO REPLY CITADO ACIMA!"`
|
| 82 |
+
|
| 83 |
+
## Conclusão de Facilitação de Debug e Escalabilidade
|
| 84 |
+
Ao separar as responsabilidades, se a memória falhar, você sabe que está em `short_term_memory.py`. Se ela enxergar os grupos em privados, você debugará apenas `context_isolation.py`. E se o payload JSON arrebentar o Front, ele ocorre diretamente nos últimos domínios JSON da classe Flask de rotas `api.py`.
|
| 85 |
+
O design plug-and-play do `unified_context` permitiu não tocarmos na variável basilar `system_prompt` do Bot, prevenindo as famosas regressões de personalidade.
|
| 86 |
+
|
| 87 |
+
---
|
| 88 |
+
|
| 89 |
+
## 5. Fase 2: Construção da Memória de Longo Prazo (RAG Inteligente)
|
| 90 |
+
Apenas armazenar o Hit/Miss na memória de curto prazo (STM) não era suficiente para criar um vínculo com o usuário. Desenvolvemos uma injeção Real-Time da memória de BD no prompt:
|
| 91 |
+
|
| 92 |
+
**Como Funciona no `unified_context.py`:**
|
| 93 |
+
- O `UnifiedContextBuilder.build()` agora captura ativamente o contexto consolidado de longo prazo usando as queries de `Database.py`.
|
| 94 |
+
- Ele invoca `recuperar_aprendizado_detalhado()` ignorando marcadores técnicos pontuais e exibe apenas Fatualidades (fatos sobre o usuário) e invoca `obter_tom_predominante()`.
|
| 95 |
+
- Estes dados são convertidos numa string listada em `[📖 MEMÓRIA DE LONGO PRAZO (BANCO DE DADOS)]` no meio do prompt, acima do STM, ativando uma recuperação contextual de Recuperação baseada em Geração (RAG).
|
| 96 |
+
|
| 97 |
+
**Refatorações de Segurança em RAG (`contexto.py`):**
|
| 98 |
+
A API do `EmotionAnalyzer` gerava crashes (*Object of type None is not callable/has no attribute*) por falta de tipagem estrita no Python. Nós transformamos os try/catches para usar inspeção de métodos dinamicamente (`hasattr(emotion_analyzer, 'analisar')`).
|
| 99 |
+
|
| 100 |
+
---
|
| 101 |
+
|
| 102 |
+
## 6. Prevenção Rígida de Alucinação (Anti Auto-Resposta)
|
| 103 |
+
A Akira corria o risco de tratar mensagens citadas em modo *Reply* como se pertencessem a terceiros, mesmo que ela mesma tivesse enviado aquela mensagem (comum em IAs conversacionais em WhatsApp sem flag is_bot explícita do BD).
|
| 104 |
+
|
| 105 |
+
**Correção Cronológica e de Identidade:**
|
| 106 |
+
- **Injeção de Identidade JID:** Quando `reply_to_bot=True` é identificado pelo `api.py`, o prompt agora acorda a Akira violentamente com a String:
|
| 107 |
+
> `⛔ ALERTA ANTI-ALUCINAÇÃO (AUTO-RESPOSTA): O usuário citou/deu reply NUMA MENSAGEM QUE VOCÊ MESMA, A AKIRA, MANDOU ANTES! Não aja como se a mensagem citada fosse de um terceiro ou atendente! VOCÊ disse aquilo. Complete sua linha de raciocínio ou tire a dúvida da pessoa sobre o que você falou.`
|
| 108 |
+
- **Cronologia Real (`api.py`):** Modificamos o injetor de `data_hora`. Ao invés de um estático `DD/MM/YYYY`, ele monta uma estrutura literal humana (ex: *Hoje é Quarta-Feira, 24 de Abril de 2024, e agora são exatamente 16:45.*), facilitando associações temporais naturais nas réplicas do LLM.
|
docker-compose.yml
CHANGED
|
@@ -1,14 +1,14 @@
|
|
| 1 |
-
version: '3.8'
|
| 2 |
-
services:
|
| 3 |
-
akira:
|
| 4 |
-
build: .
|
| 5 |
-
ports:
|
| 6 |
-
- "5000:5000"
|
| 7 |
-
volumes:
|
| 8 |
-
- .:/app
|
| 9 |
-
environment:
|
| 10 |
-
- PYTHONUNBUFFERED=1
|
| 11 |
-
- MISTRAL_API_KEY=${MISTRAL_API_KEY}
|
| 12 |
-
- GEMINI_API_KEY=${GEMINI_API_KEY}
|
| 13 |
-
- MISTRAL_MODEL=${MISTRAL_MODEL:-mistral-small-latest}
|
| 14 |
- GEMINI_MODEL=${GEMINI_MODEL:-gemini-1.5-flash}
|
|
|
|
| 1 |
+
version: '3.8'
|
| 2 |
+
services:
|
| 3 |
+
akira:
|
| 4 |
+
build: .
|
| 5 |
+
ports:
|
| 6 |
+
- "5000:5000"
|
| 7 |
+
volumes:
|
| 8 |
+
- .:/app
|
| 9 |
+
environment:
|
| 10 |
+
- PYTHONUNBUFFERED=1
|
| 11 |
+
- MISTRAL_API_KEY=${MISTRAL_API_KEY}
|
| 12 |
+
- GEMINI_API_KEY=${GEMINI_API_KEY}
|
| 13 |
+
- MISTRAL_MODEL=${MISTRAL_MODEL:-mistral-small-latest}
|
| 14 |
- GEMINI_MODEL=${GEMINI_MODEL:-gemini-1.5-flash}
|
main.py
CHANGED
|
@@ -1,225 +1,191 @@
|
|
| 1 |
-
# main.py — AKIRA V21 ULTIMATE
|
| 2 |
-
"""
|
| 3 |
-
Entry point Flask API para Akira IA V21
|
| 4 |
-
- Multi-API com fallback (6 provedores)
|
| 5 |
-
- Suporte a .env para secrets
|
| 6 |
-
- Otimizado para Hugging Face Spaces
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
import
|
| 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 |
-
apis_ok
|
| 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 |
-
if __name__ == "__main__":
|
| 193 |
-
logger.info("=" * 80)
|
| 194 |
-
logger.info("🔥 AKIRA V21 ULTIMATE — SISTEMA MULTI-API 🔥")
|
| 195 |
-
logger.info("=" * 80)
|
| 196 |
-
logger.info(f"Data/hora local: {datetime.datetime.now().strftime('%d/%m/%Y %H:%M:%S')}")
|
| 197 |
-
logger.info(f"Servidor: http://{config.API_HOST}:{config.API_PORT}")
|
| 198 |
-
logger.info("Endpoints:")
|
| 199 |
-
logger.info(" - GET / → Página inicial")
|
| 200 |
-
logger.info(" - GET /health → Health check")
|
| 201 |
-
logger.info(" - GET /status → Status das APIs")
|
| 202 |
-
logger.info(" - GET /debug → Debugging")
|
| 203 |
-
logger.info(" - POST /api/akira → Endpoint principal")
|
| 204 |
-
logger.info("=" * 80)
|
| 205 |
-
logger.info("✅ Sistema pronto!")
|
| 206 |
-
logger.info("✅ Contexto otimizado (sem repetições)")
|
| 207 |
-
logger.info("✅ Compatibilidade total com index.js V21")
|
| 208 |
-
logger.info("✅ STT Deepgram + TTS Google")
|
| 209 |
-
logger.info("✅ Comandos restritos: Apenas Isaac Quarenta")
|
| 210 |
-
logger.info("=" * 80)
|
| 211 |
-
logger.info("Aguardando conexões... (Ctrl+C para parar)")
|
| 212 |
-
|
| 213 |
-
# Modo de execução
|
| 214 |
-
if os.getenv("PRODUCTION", "false").lower() == "true":
|
| 215 |
-
# Produção: usar Gunicorn (via Dockerfile CMD)
|
| 216 |
-
logger.info("Modo: PRODUÇÃO (Gunicorn)")
|
| 217 |
-
else:
|
| 218 |
-
# Desenvolvimento: usar Flask dev server
|
| 219 |
-
logger.info("Modo: DESENVOLVIMENTO (Flask)")
|
| 220 |
-
app.run(
|
| 221 |
-
host=config.API_HOST,
|
| 222 |
-
port=config.API_PORT,
|
| 223 |
-
debug=False,
|
| 224 |
-
use_reloader=False
|
| 225 |
-
)
|
|
|
|
| 1 |
+
# main.py — AKIRA V21 ULTIMATE (Janeiro 2025)
|
| 2 |
+
"""
|
| 3 |
+
Entry point Flask API para Akira IA V21
|
| 4 |
+
- Multi-API com fallback (6 provedores)
|
| 5 |
+
- Suporte a .env para secrets
|
| 6 |
+
- Otimizado para Hugging Face Spaces
|
| 7 |
+
"""
|
| 8 |
+
import os
|
| 9 |
+
import sys
|
| 10 |
+
|
| 11 |
+
# === CORREÇÃO: Garante imports funcionam em qualquer estrutura ===
|
| 12 |
+
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
|
| 13 |
+
APP_ROOT = os.path.dirname(PROJECT_ROOT) # Para docker/HF Spaces
|
| 14 |
+
|
| 15 |
+
# Adiciona ambos os paths (projeto e akira/)
|
| 16 |
+
for path in [PROJECT_ROOT, APP_ROOT]:
|
| 17 |
+
if path not in sys.path:
|
| 18 |
+
sys.path.insert(0, path)
|
| 19 |
+
|
| 20 |
+
print(f"Project root: {PROJECT_ROOT}")
|
| 21 |
+
print(f"App root: {APP_ROOT}")
|
| 22 |
+
|
| 23 |
+
# Carregar variáveis de ambiente (.env)
|
| 24 |
+
try:
|
| 25 |
+
from dotenv import load_dotenv
|
| 26 |
+
load_dotenv()
|
| 27 |
+
print(".env carregado")
|
| 28 |
+
except ImportError:
|
| 29 |
+
print("python-dotenv nao instalado")
|
| 30 |
+
|
| 31 |
+
from flask import Flask, jsonify
|
| 32 |
+
from loguru import logger
|
| 33 |
+
import datetime
|
| 34 |
+
|
| 35 |
+
# === LOGS ===
|
| 36 |
+
logger.remove()
|
| 37 |
+
logger.add(
|
| 38 |
+
sys.stderr,
|
| 39 |
+
format="<green>{time:HH:mm:ss}</green> | <level>{level}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan> -> <level>{message}</level>",
|
| 40 |
+
colorize=True,
|
| 41 |
+
backtrace=True,
|
| 42 |
+
diagnose=True,
|
| 43 |
+
level="INFO"
|
| 44 |
+
)
|
| 45 |
+
|
| 46 |
+
# === FLASK APP ===
|
| 47 |
+
app = Flask(__name__)
|
| 48 |
+
|
| 49 |
+
# Make app available for Gunicorn
|
| 50 |
+
application = app
|
| 51 |
+
|
| 52 |
+
# === ROTAS BASICAS ===
|
| 53 |
+
@app.route("/")
|
| 54 |
+
def index():
|
| 55 |
+
"""Pagina inicial com status"""
|
| 56 |
+
apis_configuradas = []
|
| 57 |
+
|
| 58 |
+
if os.getenv("MISTRAL_API_KEY"):
|
| 59 |
+
apis_configuradas.append("Mistral")
|
| 60 |
+
if os.getenv("GEMINI_API_KEY"):
|
| 61 |
+
apis_configuradas.append("Gemini")
|
| 62 |
+
if os.getenv("GROQ_API_KEY"):
|
| 63 |
+
apis_configuradas.append("Groq")
|
| 64 |
+
if os.getenv("COHERE_API_KEY"):
|
| 65 |
+
apis_configuradas.append("Cohere")
|
| 66 |
+
if os.getenv("TOGETHER_API_KEY"):
|
| 67 |
+
apis_configuradas.append("Together")
|
| 68 |
+
# HF não está sendo usado mais
|
| 69 |
+
|
| 70 |
+
apis_texto = ", ".join(apis_configuradas) if apis_configuradas else "Nenhuma (configure em .env)"
|
| 71 |
+
|
| 72 |
+
return f'''
|
| 73 |
+
<div style="font-family: Courier New, monospace; text-align: center; margin: 50px; background: #000; color: #0f0; padding: 40px; border: 2px solid #0f0;">
|
| 74 |
+
<h1>AKIRA V21 ULTIMATE ONLINE!</h1>
|
| 75 |
+
<p><strong>Multi-API System com 6 Provedores</strong></p>
|
| 76 |
+
<p><strong>APIs Configuradas:</strong> {apis_texto}</p>
|
| 77 |
+
<p><strong>Endpoint:</strong> POST /api/akira</p>
|
| 78 |
+
<hr style="border-color: #0f0;">
|
| 79 |
+
<p><em>Luanda, Angola — Softedge Corporation</em></p>
|
| 80 |
+
</div>
|
| 81 |
+
''', 200
|
| 82 |
+
|
| 83 |
+
@app.route("/health")
|
| 84 |
+
def health():
|
| 85 |
+
"""Health check para Docker/HF Spaces"""
|
| 86 |
+
return "OK", 200
|
| 87 |
+
|
| 88 |
+
@app.route("/status")
|
| 89 |
+
def status():
|
| 90 |
+
"""Status detalhado das APIs"""
|
| 91 |
+
try:
|
| 92 |
+
import modules.config as config
|
| 93 |
+
|
| 94 |
+
status_info = {
|
| 95 |
+
"timestamp": datetime.datetime.now().isoformat(),
|
| 96 |
+
"versao": "V21 ULTIMATE",
|
| 97 |
+
"apis_disponiveis": [],
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
if config.MISTRAL_API_KEY:
|
| 101 |
+
status_info["apis_disponiveis"].append("mistral")
|
| 102 |
+
if config.GEMINI_API_KEY:
|
| 103 |
+
status_info["apis_disponiveis"].append("gemini")
|
| 104 |
+
if config.GROQ_API_KEY:
|
| 105 |
+
status_info["apis_disponiveis"].append("groq")
|
| 106 |
+
if config.COHERE_API_KEY:
|
| 107 |
+
status_info["apis_disponiveis"].append("cohere")
|
| 108 |
+
if config.TOGETHER_API_KEY:
|
| 109 |
+
status_info["apis_disponiveis"].append("together")
|
| 110 |
+
# HF não está sendo usado mais
|
| 111 |
+
|
| 112 |
+
return jsonify(status_info), 200
|
| 113 |
+
except Exception as e:
|
| 114 |
+
return jsonify({"error": str(e)}), 500
|
| 115 |
+
|
| 116 |
+
# === INTEGRAÇÃO DA API ===
|
| 117 |
+
akira_api = None
|
| 118 |
+
api_disponivel = False
|
| 119 |
+
|
| 120 |
+
try:
|
| 121 |
+
# Tenta importar a API
|
| 122 |
+
from modules.api import AkiraAPI, get_blueprint
|
| 123 |
+
|
| 124 |
+
import modules.config as config
|
| 125 |
+
|
| 126 |
+
# API_AVAILABLE está em config.py
|
| 127 |
+
API_AVAILABLE = getattr(config, 'API_AVAILABLE', {})
|
| 128 |
+
|
| 129 |
+
if API_AVAILABLE or True: # Always try if imports succeeded
|
| 130 |
+
logger.info("Modulos importados com sucesso")
|
| 131 |
+
|
| 132 |
+
if hasattr(config, 'validate_config'):
|
| 133 |
+
config.validate_config()
|
| 134 |
+
logger.info("Config validada")
|
| 135 |
+
|
| 136 |
+
akira_api = AkiraAPI()
|
| 137 |
+
|
| 138 |
+
app.register_blueprint(get_blueprint(), url_prefix="/api")
|
| 139 |
+
logger.success("API V21 integrada -> /api/akira")
|
| 140 |
+
|
| 141 |
+
apis_ok = []
|
| 142 |
+
if config.MISTRAL_API_KEY:
|
| 143 |
+
apis_ok.append("Mistral")
|
| 144 |
+
if config.GEMINI_API_KEY:
|
| 145 |
+
apis_ok.append("Gemini")
|
| 146 |
+
if config.GROQ_API_KEY:
|
| 147 |
+
apis_ok.append("Groq")
|
| 148 |
+
if config.COHERE_API_KEY:
|
| 149 |
+
apis_ok.append("Cohere")
|
| 150 |
+
if config.TOGETHER_API_KEY:
|
| 151 |
+
apis_ok.append("Together")
|
| 152 |
+
# HF não está sendo usado mais
|
| 153 |
+
|
| 154 |
+
if apis_ok:
|
| 155 |
+
logger.info(f"APIs: {', '.join(apis_ok)}")
|
| 156 |
+
else:
|
| 157 |
+
logger.warning("NENHUMA API CONFIGURADA!")
|
| 158 |
+
|
| 159 |
+
api_disponivel = True
|
| 160 |
+
else:
|
| 161 |
+
logger.warning("API nao disponivel (erro de import)")
|
| 162 |
+
|
| 163 |
+
except ImportError as e:
|
| 164 |
+
logger.critical(f"ERRO DE IMPORTACAO: {e}")
|
| 165 |
+
import traceback
|
| 166 |
+
logger.critical(traceback.format_exc())
|
| 167 |
+
|
| 168 |
+
except Exception as e:
|
| 169 |
+
logger.critical(f"FALHA: {e}")
|
| 170 |
+
import traceback
|
| 171 |
+
logger.critical(traceback.format_exc())
|
| 172 |
+
|
| 173 |
+
# === INICIO DO SERVIDOR ===
|
| 174 |
+
if __name__ == "__main__":
|
| 175 |
+
logger.info("=" * 60)
|
| 176 |
+
logger.info("AKIRA V21 ULTIMATE — SISTEMA MULTI-API")
|
| 177 |
+
logger.info("=" * 60)
|
| 178 |
+
|
| 179 |
+
host = os.getenv("API_HOST", "0.0.0.0")
|
| 180 |
+
port = int(os.getenv("API_PORT", "7860"))
|
| 181 |
+
|
| 182 |
+
logger.info(f"Servidor: http://{host}:{port}")
|
| 183 |
+
logger.info("Endpoints: /, /health, /status, /api/akira")
|
| 184 |
+
logger.info("=" * 60)
|
| 185 |
+
|
| 186 |
+
if os.getenv("PRODUCTION", "false").lower() == "true":
|
| 187 |
+
logger.info("Modo: PRODUCAO (Gunicorn)")
|
| 188 |
+
else:
|
| 189 |
+
logger.info("Modo: DESENVOLVIMENTO")
|
| 190 |
+
app.run(host=host, port=port, debug=False, use_reloader=False)
|
| 191 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plano_correcoes.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
# 📋 PLANO DE CORREÇÕES E MELHORIAS - AKIRA V21
|
| 3 |
+
|
| 4 |
+
## 🔥 PROBLEMAS IDENTIFICADOS
|
| 5 |
+
|
| 6 |
+
### 1. Database.py
|
| 7 |
+
- ❌ Banco não está sendo criado corretamente
|
| 8 |
+
- ❌ Dados não estão sendo inseridos
|
| 9 |
+
- ❌ message_id gerando erros de UNIQUE constraint
|
| 10 |
+
|
| 11 |
+
### 2. Treinamento.py
|
| 12 |
+
- ❌ Erro: "nenhum texto encontrado para ser treinado"
|
| 13 |
+
- ❌ Dataset não está sendo gerado
|
| 14 |
+
- ❌ Integração com database falhando
|
| 15 |
+
|
| 16 |
+
### 3. Web_search.py
|
| 17 |
+
- ❌ Busca não funciona adequadamente
|
| 18 |
+
- ❌ Scraper de notícias falhando
|
| 19 |
+
- ❌ API DuckDuckGo não retorna resultados
|
| 20 |
+
|
| 21 |
+
### 4. Contexto.py
|
| 22 |
+
- ❌ BERT não está carregando corretamente
|
| 23 |
+
- ❌ Cache de emoções não persistindo
|
| 24 |
+
|
| 25 |
+
### 5. API.py
|
| 26 |
+
- ❌ Erros de integração com módulos
|
| 27 |
+
- ❌ Respostas inconsistentes
|
| 28 |
+
|
| 29 |
+
### 6. Segurança
|
| 30 |
+
- ❌ Usuários privilegiados precisam de verificação robusta
|
| 31 |
+
- ❌ Proteção contra jailbreak insuficiente
|
| 32 |
+
|
| 33 |
+
---
|
| 34 |
+
|
| 35 |
+
## ✅ PLANO DE CORREÇÕES
|
| 36 |
+
|
| 37 |
+
### FASE 1: Database (CRÍTICO)
|
| 38 |
+
- [ ] Corrigir criação automática do banco
|
| 39 |
+
- [ ] Adicionar logs detalhados de inserção
|
| 40 |
+
- [ ] Remover constraints problemáticos
|
| 41 |
+
- [ ] Adicionar método de verificação
|
| 42 |
+
|
| 43 |
+
### FASE 2: Treinamento
|
| 44 |
+
- [ ] Corrigir geração de dataset
|
| 45 |
+
- [ ] Adicionar tratamento de erros
|
| 46 |
+
- [ ] Melhorar logging
|
| 47 |
+
|
| 48 |
+
### FASE 3: Web Search
|
| 49 |
+
- [ ] Corrigir APIs de busca
|
| 50 |
+
- [ ] Adicionar fallbacks
|
| 51 |
+
- [ ] Melhorar scraping
|
| 52 |
+
|
| 53 |
+
### FASE 4: Segurança
|
| 54 |
+
- [ ] Adicionar verificação por código
|
| 55 |
+
- [ ] Implementar proteção contra jailbreak
|
| 56 |
+
- [ ] Log de comandos sensíveis
|
| 57 |
+
|
| 58 |
+
### FASE 5: Compatibilidade
|
| 59 |
+
- [ ] Criar script de inicialização
|
| 60 |
+
- [ ] Adicionar verificação de dependências
|
| 61 |
+
- [ ] Criar logs de debugging
|
| 62 |
+
|
| 63 |
+
---
|
| 64 |
+
|
| 65 |
+
## 👑 USUÁRIOS PRIVILEGIADOS
|
| 66 |
+
|
| 67 |
+
### Números Verificados:
|
| 68 |
+
- **244937035662** - Isaac Quarenta (ROOT)
|
| 69 |
+
- **244978787009** - Isaac Quarenta (2)
|
| 70 |
+
|
| 71 |
+
### Permissões:
|
| 72 |
+
- ✅ Reset de contexto
|
| 73 |
+
- ✅ Comandos especiais
|
| 74 |
+
- ✅ Mudança de modo
|
| 75 |
+
- ✅ Modo formal por padrão
|
| 76 |
+
|
| 77 |
+
### Sistema de Verificação:
|
| 78 |
+
- Código numérico aleatório para confirmar identidade
|
| 79 |
+
- Logs de todos os comandos executados
|
| 80 |
+
|
| 81 |
+
---
|
| 82 |
+
|
| 83 |
+
## 🚀 PRÓXIMOS PASSOS
|
| 84 |
+
|
| 85 |
+
1. Criar script de correção `corrigir_tudo.py`
|
| 86 |
+
2. Executar correções no database
|
| 87 |
+
3. Testar treinamento
|
| 88 |
+
4. Verificar web search
|
| 89 |
+
5. Implementar segurança
|
| 90 |
+
6. Testar integração completa
|
| 91 |
+
|
| 92 |
+
---
|
| 93 |
+
|
| 94 |
+
## 📝 NOTAS
|
| 95 |
+
|
| 96 |
+
- Todas as correções devem manter compatibilidade com versão anterior
|
| 97 |
+
- Logs devem ser detalhados para debugging
|
| 98 |
+
- Sistema deve funcionar offline (sem dependência de APIs externas)
|
| 99 |
+
- Dados devem persistir corretamente
|
| 100 |
+
|
plano_melhorias.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Plano de Melhorias AKIRA V21 ULTIMATE
|
| 2 |
+
|
| 3 |
+
## Objetivo
|
| 4 |
+
Implementar melhorias de personalidade e performance conforme solicitado.
|
| 5 |
+
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
## 1. CONFIGURAÇÕES DE PERFORMANCE ✅
|
| 9 |
+
|
| 10 |
+
### 1.1 MAX_TOKENS
|
| 11 |
+
- **Atual**: 700 → **Novo**: 1000
|
| 12 |
+
- **Status**: ✅ Implementado
|
| 13 |
+
|
| 14 |
+
### 1.2 MEMORIA_MAX_MENSAGENS
|
| 15 |
+
- **Atual**: 20 → **Novo**: 100
|
| 16 |
+
- **Status**: ✅ Implementado
|
| 17 |
+
|
| 18 |
+
### 1.3 MEMORIA_EMOCIONAL_MAX
|
| 19 |
+
- **Atual**: 50 → **Novo**: 100 (RAM suficiente disponível)
|
| 20 |
+
- **Status**: ✅ Implementado
|
| 21 |
+
|
| 22 |
+
---
|
| 23 |
+
|
| 24 |
+
## 2. REGRAS DE PRIMEIRA MENSAGEM (IMERSÃO) ✅
|
| 25 |
+
|
| 26 |
+
### 2.1 Novos Prompts para Primeira Mensagem
|
| 27 |
+
- **Regra**: Se for a primeira mensagem do usuário
|
| 28 |
+
- **Resposta**: Apenas 2-3 palavras curtas
|
| 29 |
+
- **Exemplos**: "oi", "fala", "sim", "que foi", "é oquê"
|
| 30 |
+
|
| 31 |
+
### 2.2 Implementação
|
| 32 |
+
- Adicionado ao SYSTEM_PROMPT em `modules/config.py`
|
| 33 |
+
- Adicionadas flags `primeira_mensagem` em `modules/contexto.py`
|
| 34 |
+
- **Status**: ✅ Implementado
|
| 35 |
+
|
| 36 |
+
---
|
| 37 |
+
|
| 38 |
+
## 3. RESPOSTAS DINÂMICAS POR TAMANHO ✅
|
| 39 |
+
|
| 40 |
+
### 3.1 Lógica de Comprimento
|
| 41 |
+
| Tamanho da Mensagem | Resposta Akira |
|
| 42 |
+
|---------------------|----------------|
|
| 43 |
+
| Curta (1-5 palavras) | Curta (1-8 palavras) |
|
| 44 |
+
| Média (6-20 palavras) | Média (10-30 palavras) |
|
| 45 |
+
| Longa (20+ palavras) | Longa (20-60 palavras) |
|
| 46 |
+
|
| 47 |
+
### 3.2 Implementação
|
| 48 |
+
- Adicionado ao SYSTEM_PROMPT em `modules/config.py`
|
| 49 |
+
- **Status**: ✅ Implementado
|
| 50 |
+
|
| 51 |
+
---
|
| 52 |
+
|
| 53 |
+
## 4. TRANSIÇÃO GRADUAL DE TOM ✅
|
| 54 |
+
|
| 55 |
+
### 4.1 Nova Lógica
|
| 56 |
+
- **Nível de transição máximo**: 3 → **1** (muito lento)
|
| 57 |
+
- **Threshold de transição**: 0.7 → **0.9** (maior limiar)
|
| 58 |
+
- **Delay entre mudanças**: Múltiplas mensagens necessárias
|
| 59 |
+
|
| 60 |
+
### 4.2 Arquivos Modificados
|
| 61 |
+
- `modules/config.py`:
|
| 62 |
+
- `NIVEL_TRANSICAO_MAX`: 3 → 1
|
| 63 |
+
- `TRANSICAO_HUMOR_THRESHOLD`: 0.7 → 0.9
|
| 64 |
+
- `modules/contexto.py`: `determinar_nivel_transicao()` atualizado
|
| 65 |
+
- **Status**: ✅ Implementado
|
| 66 |
+
|
| 67 |
+
---
|
| 68 |
+
|
| 69 |
+
## 5. RESUMO DAS MUDANÇAS
|
| 70 |
+
|
| 71 |
+
### 5.1 constants.py (modules/config.py)
|
| 72 |
+
```python
|
| 73 |
+
MAX_TOKENS: int = 1000 # ✅ Mantido em 1000
|
| 74 |
+
MEMORIA_MAX_MENSAGENS: int = 100 # ✅ 20 → 100
|
| 75 |
+
MEMORIA_EMOCIONAL_MAX: int = 100 # ✅ 50 → 100
|
| 76 |
+
NIVEL_TRANSICAO_MAX: int = 1 # ✅ 3 → 1
|
| 77 |
+
TRANSICAO_HUMOR_THRESHOLD: float = 0.9 # ✅ 0.7 → 0.9
|
| 78 |
+
```
|
| 79 |
+
|
| 80 |
+
### 5.2 SYSTEM_PROMPT Additions ✅
|
| 81 |
+
- Primeira mensagem: respostas de 2-3 palavras
|
| 82 |
+
- Respostas dinâmicas baseadas no comprimento da msg do usuário
|
| 83 |
+
- Transição de tom muito lenta (mudar gradualmente)
|
| 84 |
+
|
| 85 |
+
### 5.3 Contexto Changes ✅
|
| 86 |
+
- Adicionado flags: `primeira_mensagem`, `tom_anterior`, `contagem_mensagens_tom`
|
| 87 |
+
- Função `determinar_nivel_transicao()` atualizada para transição lenta
|
| 88 |
+
|
| 89 |
+
---
|
| 90 |
+
|
| 91 |
+
## 6. ORDEM DE IMPLEMENTAÇÃO
|
| 92 |
+
|
| 93 |
+
1. ✅ Análise e planejamento
|
| 94 |
+
2. ✅ Modificar `modules/config.py` (constantes e prompts)
|
| 95 |
+
3. ✅ Modificar `modules/contexto.py` (memória e transição)
|
| 96 |
+
4. ⬜ Testar as mudanças
|
| 97 |
+
|
| 98 |
+
---
|
| 99 |
+
|
| 100 |
+
## 7. ARQUIVOS MODIFICADOS
|
| 101 |
+
|
| 102 |
+
- `modules/config.py` - Constantes e prompts atualizados
|
| 103 |
+
- `modules/contexto.py` - Contexto e memória atualizados
|
| 104 |
+
|
| 105 |
+
---
|
| 106 |
+
|
| 107 |
+
## 8. EXEMPLOS DE RESPOSTAS
|
| 108 |
+
|
| 109 |
+
### Primeira Mensagem
|
| 110 |
+
```
|
| 111 |
+
Usuário: "oi"
|
| 112 |
+
Akira: "oi e aí! 😎"
|
| 113 |
+
```
|
| 114 |
+
|
| 115 |
+
### Resposta Curta
|
| 116 |
+
```
|
| 117 |
+
Usuário: "bom dia"
|
| 118 |
+
Akira: "bom dia! 🎉 tudo bem?"
|
| 119 |
+
```
|
| 120 |
+
|
| 121 |
+
### Resposta Longa
|
| 122 |
+
```
|
| 123 |
+
Usuário: "Akira, preciso de ajuda com código"
|
| 124 |
+
Akira: "Claro mano! Manda o código que a gente olha. Qual linguagem?"
|
| 125 |
+
```
|
| 126 |
+
|
| 127 |
+
---
|
| 128 |
+
|
| 129 |
+
**Data**: 06/01/2025
|
| 130 |
+
**Versão**: 1.0
|
| 131 |
+
**Status**: ✅ Implementado
|
| 132 |
+
|
requirements.txt
CHANGED
|
@@ -1,19 +1,138 @@
|
|
| 1 |
-
# ===
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
# ===
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
#
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# === AKIRA V21 ULTIMATE - Requirements ===
|
| 2 |
+
# Versão: Janeiro 2025
|
| 3 |
+
# Arquitetura: Multi-API com fallback + BART Emotion Analysis + Aprendizado Contínuo
|
| 4 |
+
|
| 5 |
+
# ============================================================
|
| 6 |
+
# 🔥 CORE - Web Framework & API
|
| 7 |
+
# ============================================================
|
| 8 |
+
flask>=2.0.0,<4.0.0
|
| 9 |
+
flask-cors>=4.0.0
|
| 10 |
+
gunicorn>=21.0.0
|
| 11 |
+
loguru>=0.7.0
|
| 12 |
+
python-dotenv>=1.0.0
|
| 13 |
+
requests>=2.31.0
|
| 14 |
+
beautifulsoup4>=4.12.0
|
| 15 |
+
lxml>=5.0.0
|
| 16 |
+
|
| 17 |
+
# ============================================================
|
| 18 |
+
# 🤖 IA & ML - Multi-API Support
|
| 19 |
+
# ============================================================
|
| 20 |
+
# Google Gemini API (google.genai - nova API)
|
| 21 |
+
google-genai>=1.0.0
|
| 22 |
+
|
| 23 |
+
# Mistral API via requests (sem cliente deprecated)
|
| 24 |
+
# A API é chamada diretamente via HTTP, sem precisar da biblioteca mistralai
|
| 25 |
+
|
| 26 |
+
# Groq API
|
| 27 |
+
groq>=0.4.0,<1.0.0
|
| 28 |
+
|
| 29 |
+
# Cohere API
|
| 30 |
+
cohere>=5.0.0,<6.0.0
|
| 31 |
+
|
| 32 |
+
# Together AI (compatible with OpenAI SDK)
|
| 33 |
+
openai>=1.0.0,<2.0.0
|
| 34 |
+
|
| 35 |
+
# HuggingFace Hub - versão COMPATÍVEL (não usa snapshot_download)
|
| 36 |
+
# ⚠️ IMPORTANTE: sentence-transformers 2.2.2+ não usa mais cached_download
|
| 37 |
+
huggingface-hub>=0.23.0,<0.27.0
|
| 38 |
+
|
| 39 |
+
# Transformers core (BERT, BART, etc.)
|
| 40 |
+
transformers>=4.38.0,<4.50.0
|
| 41 |
+
|
| 42 |
+
# PyTorch - versão estável e compatível
|
| 43 |
+
torch>=2.1.0,<2.6.0
|
| 44 |
+
peft>=0.7.0
|
| 45 |
+
bitsandbytes>=0.41.0
|
| 46 |
+
|
| 47 |
+
# Sentence Transformers - versão mais recente compatível
|
| 48 |
+
# ⚠️ A versão 2.2.2+ funciona corretamente com huggingface-hub>=0.23
|
| 49 |
+
sentence-transformers>=2.2.2,<3.0.0
|
| 50 |
+
|
| 51 |
+
# ============================================================
|
| 52 |
+
# 📊 NLP & Text Processing
|
| 53 |
+
# ============================================================
|
| 54 |
+
numpy>=1.26.0,<2.0.0
|
| 55 |
+
nltk>=3.8.1,<3.10.0
|
| 56 |
+
spacy>=3.7.0,<4.0.0
|
| 57 |
+
# Modelos pt_core_news_lg serão baixados automaticamente
|
| 58 |
+
accelerate>=0.20.0
|
| 59 |
+
|
| 60 |
+
# ============================================================
|
| 61 |
+
# 🔌 Utilities & Integration
|
| 62 |
+
# ============================================================
|
| 63 |
+
requests>=2.31.0
|
| 64 |
+
python-dotenv>=1.0.0
|
| 65 |
+
tqdm>=4.66.0
|
| 66 |
+
beautifulsoup4>=4.12.0
|
| 67 |
+
lxml>=5.0.0
|
| 68 |
+
|
| 69 |
+
# ============================================================
|
| 70 |
+
# 🗄️ Database
|
| 71 |
+
# ============================================================
|
| 72 |
+
# SQLite3 já vem com Python
|
| 73 |
+
# Opcional: Redis para cache (descomente se precisar)
|
| 74 |
+
# redis>=5.0.0
|
| 75 |
+
|
| 76 |
+
# ============================================================
|
| 77 |
+
# 📱 Web Search & Tools
|
| 78 |
+
# ============================================================
|
| 79 |
+
googlesearch-python>=1.1.0
|
| 80 |
+
ddgs>=5.3.0
|
| 81 |
+
|
| 82 |
+
# deepgram-sdk>=3.0.0 # Para STT (opcional)
|
| 83 |
+
# google-cloud-texttospeech>=2.0.0 # Para TTS (opcional)
|
| 84 |
+
|
| 85 |
+
# ============================================================
|
| 86 |
+
# 👁️ VISÃO COMPUTACIONAL & OCR
|
| 87 |
+
# ============================================================
|
| 88 |
+
# OpenCV headless - versão sem GUI, otimizada para servidores
|
| 89 |
+
opencv-python-headless>=4.8.0,<4.10.0
|
| 90 |
+
|
| 91 |
+
# Pillow - Manipulação de imagens PIL
|
| 92 |
+
pillow>=10.0.0,<11.0.0
|
| 93 |
+
|
| 94 |
+
# Tesseract OCR wrapper Python
|
| 95 |
+
pytesseract>=0.3.10
|
| 96 |
+
|
| 97 |
+
# Tesseract binary (Linux)
|
| 98 |
+
# Instalado via apt no Dockerfile:
|
| 99 |
+
# apt-get install tesseract-ocr tesseract-ocr-por tesseract-ocr-eng
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
# ============================================================
|
| 103 |
+
# 🎨 Media & QR Codes
|
| 104 |
+
# ============================================================
|
| 105 |
+
pillow>=10.0.0,<11.0.0
|
| 106 |
+
qrcode>=7.4.2,<8.0.0
|
| 107 |
+
|
| 108 |
+
# ============================================================
|
| 109 |
+
# ⚡ Performance & Monitoring
|
| 110 |
+
# ============================================================
|
| 111 |
+
# APScheduler>=7.0.0 # Para tarefas agendadas (opcional)
|
| 112 |
+
# prometheus-client>=0.19.0 # Para métricas (opcional)
|
| 113 |
+
|
| 114 |
+
# ============================================================
|
| 115 |
+
# 🧪 Testing (dev only - descomente se necessário)
|
| 116 |
+
# ============================================================
|
| 117 |
+
# pytest>=7.4.0
|
| 118 |
+
# pytest-cov>=4.1.0
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
# ============================================================
|
| 122 |
+
# 📝 NOTAS DE COMPATIBILIDADE (CRÍTICO!)
|
| 123 |
+
# ============================================================
|
| 124 |
+
#
|
| 125 |
+
# Para AKIRA V21 ULTIMATE:
|
| 126 |
+
# - sentence-transformers>=2.2.2 usa huggingface_hub.file_download
|
| 127 |
+
# - huggingface-hub>=0.23.0 não tem cached_download
|
| 128 |
+
# - Se tiver erro de import, atualize os pacotes:
|
| 129 |
+
#
|
| 130 |
+
# Exemplo de instalação limpa:
|
| 131 |
+
# pip install --upgrade pip
|
| 132 |
+
# pip install "sentence-transformers>=2.2.2"
|
| 133 |
+
# pip install "huggingface-hub>=0.23.0,<0.27.0"
|
| 134 |
+
# pip install "transformers>=4.38.0"
|
| 135 |
+
# pip install "torch>=2.1.0"
|
| 136 |
+
#
|
| 137 |
+
# ============================================================
|
| 138 |
+
|
setup.py
CHANGED
|
@@ -1,48 +1,48 @@
|
|
| 1 |
-
"""
|
| 2 |
-
Script de setup para instalar dependências e configurar o projeto Akira IA
|
| 3 |
-
"""
|
| 4 |
-
import subprocess
|
| 5 |
-
import sys
|
| 6 |
-
import os
|
| 7 |
-
|
| 8 |
-
def install_dependencies():
|
| 9 |
-
"""Instala as dependências do requirements.txt"""
|
| 10 |
-
print("📦 Instalando dependências...")
|
| 11 |
-
try:
|
| 12 |
-
subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"])
|
| 13 |
-
print("✅ Dependências instaladas com sucesso!")
|
| 14 |
-
return True
|
| 15 |
-
except subprocess.CalledProcessError as e:
|
| 16 |
-
print(f"❌ Erro ao instalar dependências: {e}")
|
| 17 |
-
return False
|
| 18 |
-
|
| 19 |
-
def check_env_file():
|
| 20 |
-
"""Verifica se o arquivo .env existe"""
|
| 21 |
-
if not os.path.exists('.env'):
|
| 22 |
-
print("⚠️ Arquivo .env não encontrado!")
|
| 23 |
-
print("📝 Copie .env.example para .env e configure suas chaves de API:")
|
| 24 |
-
print(" cp .env.example .env")
|
| 25 |
-
return False
|
| 26 |
-
print("✅ Arquivo .env encontrado!")
|
| 27 |
-
return True
|
| 28 |
-
|
| 29 |
-
def main():
|
| 30 |
-
print("🚀 Configurando Akira IA...\n")
|
| 31 |
-
|
| 32 |
-
# Instalar dependências
|
| 33 |
-
if not install_dependencies():
|
| 34 |
-
sys.exit(1)
|
| 35 |
-
|
| 36 |
-
print()
|
| 37 |
-
|
| 38 |
-
# Verificar .env
|
| 39 |
-
check_env_file()
|
| 40 |
-
|
| 41 |
-
print("\n✨ Setup concluído!")
|
| 42 |
-
print("\n📖 Próximos passos:")
|
| 43 |
-
print("1. Configure suas chaves de API no arquivo .env")
|
| 44 |
-
print("2. Execute: python main.py")
|
| 45 |
-
print("3. Acesse: http://localhost:5000/health")
|
| 46 |
-
|
| 47 |
-
if __name__ == "__main__":
|
| 48 |
main()
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Script de setup para instalar dependências e configurar o projeto Akira IA
|
| 3 |
+
"""
|
| 4 |
+
import subprocess
|
| 5 |
+
import sys
|
| 6 |
+
import os
|
| 7 |
+
|
| 8 |
+
def install_dependencies():
|
| 9 |
+
"""Instala as dependências do requirements.txt"""
|
| 10 |
+
print("📦 Instalando dependências...")
|
| 11 |
+
try:
|
| 12 |
+
subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"])
|
| 13 |
+
print("✅ Dependências instaladas com sucesso!")
|
| 14 |
+
return True
|
| 15 |
+
except subprocess.CalledProcessError as e:
|
| 16 |
+
print(f"❌ Erro ao instalar dependências: {e}")
|
| 17 |
+
return False
|
| 18 |
+
|
| 19 |
+
def check_env_file():
|
| 20 |
+
"""Verifica se o arquivo .env existe"""
|
| 21 |
+
if not os.path.exists('.env'):
|
| 22 |
+
print("⚠️ Arquivo .env não encontrado!")
|
| 23 |
+
print("📝 Copie .env.example para .env e configure suas chaves de API:")
|
| 24 |
+
print(" cp .env.example .env")
|
| 25 |
+
return False
|
| 26 |
+
print("✅ Arquivo .env encontrado!")
|
| 27 |
+
return True
|
| 28 |
+
|
| 29 |
+
def main():
|
| 30 |
+
print("🚀 Configurando Akira IA...\n")
|
| 31 |
+
|
| 32 |
+
# Instalar dependências
|
| 33 |
+
if not install_dependencies():
|
| 34 |
+
sys.exit(1)
|
| 35 |
+
|
| 36 |
+
print()
|
| 37 |
+
|
| 38 |
+
# Verificar .env
|
| 39 |
+
check_env_file()
|
| 40 |
+
|
| 41 |
+
print("\n✨ Setup concluído!")
|
| 42 |
+
print("\n📖 Próximos passos:")
|
| 43 |
+
print("1. Configure suas chaves de API no arquivo .env")
|
| 44 |
+
print("2. Execute: python main.py")
|
| 45 |
+
print("3. Acesse: http://localhost:5000/health")
|
| 46 |
+
|
| 47 |
+
if __name__ == "__main__":
|
| 48 |
main()
|
testar_correcoes.py
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
# -*- coding: utf-8 -*-
|
| 3 |
+
"""
|
| 4 |
+
🚀 TESTE FINAL - AKIRA V21 ULTIMATE CORRIGIDO
|
| 5 |
+
Testa todos os módulos corrigidos
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import sys
|
| 9 |
+
import os
|
| 10 |
+
|
| 11 |
+
# Adiciona o diretório pai ao path (onde está a pasta modules/)
|
| 12 |
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
| 13 |
+
|
| 14 |
+
def testar_database():
|
| 15 |
+
"""Testa o módulo Database."""
|
| 16 |
+
print("\n" + "=" * 50)
|
| 17 |
+
print("🗄️ TESTANDO DATABASE")
|
| 18 |
+
print("=" * 50)
|
| 19 |
+
try:
|
| 20 |
+
from modules.database import Database
|
| 21 |
+
db = Database("akira_teste.db")
|
| 22 |
+
print("✅ Database instanciado")
|
| 23 |
+
|
| 24 |
+
# Testa usuário privilegiado
|
| 25 |
+
ok, codigo = db.adicionar_usuario_privilegiado("244937035662", "Isaac Quarenta", "Isaac", "tecnico_formal")
|
| 26 |
+
print(f" Usuário privilegiado: {'OK' if ok else 'ERRO'} (código: {codigo})")
|
| 27 |
+
|
| 28 |
+
# Testa privilégios
|
| 29 |
+
eh_priv = db.eh_privilegiado("244937035662")
|
| 30 |
+
print(f" Verificação privilégio: {'OK' if eh_priv else 'ERRO'}")
|
| 31 |
+
|
| 32 |
+
# Testa salvar mensagem
|
| 33 |
+
ok = db.salvar_mensagem(
|
| 34 |
+
usuario="Isaac",
|
| 35 |
+
mensagem="Oi",
|
| 36 |
+
resposta="Eae",
|
| 37 |
+
numero="244937035662"
|
| 38 |
+
)
|
| 39 |
+
print(f" Mensagem salva: {'OK' if ok else 'ERRO'}")
|
| 40 |
+
|
| 41 |
+
# Testa recuperar mensagens
|
| 42 |
+
msgs = db.recuperar_mensagens("Isaac", limite=5)
|
| 43 |
+
print(f" Mensagens recuperadas: {len(msgs)}")
|
| 44 |
+
|
| 45 |
+
# Testa salvar contexto
|
| 46 |
+
ok = db.salvar_contexto(
|
| 47 |
+
user_key="244937035662",
|
| 48 |
+
emocao_atual="neutra",
|
| 49 |
+
humor_atual="neutro"
|
| 50 |
+
)
|
| 51 |
+
print(f" Contexto salvo: {'OK' if ok else 'ERRO'}")
|
| 52 |
+
|
| 53 |
+
# Testa tom do usuário
|
| 54 |
+
ok = db.registrar_tom_usuario("244937035662", "formal", 0.8, "contexto teste")
|
| 55 |
+
print(f" Tom registrado: {'OK' if ok else 'ERRO'}")
|
| 56 |
+
|
| 57 |
+
tom = db.obter_tom_predominante("244937035662")
|
| 58 |
+
print(f" Tom predominante: {tom}")
|
| 59 |
+
|
| 60 |
+
# Testa gírias
|
| 61 |
+
ok = db.salvar_giria_aprendida("244937035662", "bué", "termo regional", "contexto")
|
| 62 |
+
print(f" Gíria salva: {'OK' if ok else 'ERRO'}")
|
| 63 |
+
|
| 64 |
+
girias = db.recuperar_girias_usuario("244937035662")
|
| 65 |
+
print(f" Gírias recuperadas: {len(girias)}")
|
| 66 |
+
|
| 67 |
+
# Limpa
|
| 68 |
+
if os.path.exists("akira_teste.db"):
|
| 69 |
+
os.remove("akira_teste.db")
|
| 70 |
+
return True
|
| 71 |
+
except Exception as e:
|
| 72 |
+
print(f"❌ ERRO: {e}")
|
| 73 |
+
import traceback
|
| 74 |
+
traceback.print_exc()
|
| 75 |
+
return False
|
| 76 |
+
|
| 77 |
+
def testar_treinamento():
|
| 78 |
+
"""Testa o módulo Treinamento."""
|
| 79 |
+
print("\n" + "=" * 50)
|
| 80 |
+
print("🧠 TESTANDO TREINAMENTO")
|
| 81 |
+
print("=" * 50)
|
| 82 |
+
try:
|
| 83 |
+
from modules.treinamento import Treinamento
|
| 84 |
+
from modules.database import Database
|
| 85 |
+
|
| 86 |
+
db = Database("akira_teste.db")
|
| 87 |
+
t = Treinamento(db)
|
| 88 |
+
print("✅ Treinamento instanciado")
|
| 89 |
+
|
| 90 |
+
# Testa registrar interação
|
| 91 |
+
t.registrar_interacao(
|
| 92 |
+
usuario="Isaac",
|
| 93 |
+
mensagem="Oi",
|
| 94 |
+
resposta="Eae",
|
| 95 |
+
numero="244937035662"
|
| 96 |
+
)
|
| 97 |
+
print("✅ Interação registrada")
|
| 98 |
+
|
| 99 |
+
# Testa estatísticas
|
| 100 |
+
stats = t.obter_estatisticas()
|
| 101 |
+
print(f" Stats: {stats}")
|
| 102 |
+
|
| 103 |
+
# Limpa
|
| 104 |
+
if os.path.exists("akira_teste.db"):
|
| 105 |
+
os.remove("akira_teste.db")
|
| 106 |
+
return True
|
| 107 |
+
except Exception as e:
|
| 108 |
+
print(f"❌ ERRO: {e}")
|
| 109 |
+
import traceback
|
| 110 |
+
traceback.print_exc()
|
| 111 |
+
return False
|
| 112 |
+
|
| 113 |
+
def testar_contexto():
|
| 114 |
+
"""Testa o módulo Contexto."""
|
| 115 |
+
print("\n" + "=" * 50)
|
| 116 |
+
print("🎭 TESTANDO CONTEXTO")
|
| 117 |
+
print("=" * 50)
|
| 118 |
+
try:
|
| 119 |
+
from modules.contexto import criar_contexto, Contexto
|
| 120 |
+
from modules.database import Database
|
| 121 |
+
|
| 122 |
+
db = Database("akira_teste.db")
|
| 123 |
+
c = criar_contexto(db=db, identificador="teste")
|
| 124 |
+
print("✅ Contexto criado via factory")
|
| 125 |
+
|
| 126 |
+
# Testa atributos
|
| 127 |
+
print(f" Usuário: {c.usuario}")
|
| 128 |
+
print(f" Emoção atual: {c.emocao_atual}")
|
| 129 |
+
|
| 130 |
+
# Testa análise de emoções
|
| 131 |
+
analise = c.analisar_emocoes_mensagem("Hoje estou muito feliz!")
|
| 132 |
+
print(f" Análise emocional: {analise}")
|
| 133 |
+
|
| 134 |
+
# Testa análise de intenção
|
| 135 |
+
historico = []
|
| 136 |
+
analise_intencao = c.analisar_intencao_e_normalizar("Oi Akira, tudo bem?", historico)
|
| 137 |
+
print(f" Intenção: {analise_intencao['intencao']}")
|
| 138 |
+
print(f" Estilo: {analise_intencao['estilo']}")
|
| 139 |
+
print(f" Emoção: {analise_intencao['emocao']}")
|
| 140 |
+
|
| 141 |
+
# Testa atualizar contexto
|
| 142 |
+
c.atualizar_contexto(mensagem="Oi", resposta="Eae", numero="244937035662")
|
| 143 |
+
print("✅ Contexto atualizado")
|
| 144 |
+
|
| 145 |
+
# Testa obter histórico
|
| 146 |
+
hist = c.obter_historico(limite=5)
|
| 147 |
+
print(f" Histórico: {len(hist)} mensagens")
|
| 148 |
+
|
| 149 |
+
# Testa obter aprendizados
|
| 150 |
+
apr = c.obter_aprendizados()
|
| 151 |
+
print(f" Aprendizados: {list(apr.keys())}")
|
| 152 |
+
|
| 153 |
+
# Testa obter histórico para LLM
|
| 154 |
+
hist_llm = c.obter_historico_para_llm()
|
| 155 |
+
print(f" Histórico LLM: {len(hist_llm)} mensagens")
|
| 156 |
+
|
| 157 |
+
# Limpa
|
| 158 |
+
if os.path.exists("akira_teste.db"):
|
| 159 |
+
os.remove("akira_teste.db")
|
| 160 |
+
return True
|
| 161 |
+
except Exception as e:
|
| 162 |
+
print(f"❌ ERRO: {e}")
|
| 163 |
+
import traceback
|
| 164 |
+
traceback.print_exc()
|
| 165 |
+
return False
|
| 166 |
+
|
| 167 |
+
def testar_config():
|
| 168 |
+
"""Testa as funções auxiliares do config e contexto."""
|
| 169 |
+
print("\n" + "=" * 50)
|
| 170 |
+
print("⚙️ TESTANDO CONFIG/CONTEXTO")
|
| 171 |
+
print("=" * 50)
|
| 172 |
+
try:
|
| 173 |
+
from modules.contexto import (
|
| 174 |
+
eh_usuario_privilegiado,
|
| 175 |
+
forcar_modo_inicial_privilegiado,
|
| 176 |
+
analisar_tom_usuario,
|
| 177 |
+
determinar_nivel_transicao
|
| 178 |
+
)
|
| 179 |
+
from modules.config import validate_config
|
| 180 |
+
|
| 181 |
+
num = "244937035662"
|
| 182 |
+
|
| 183 |
+
# Testa privilégios
|
| 184 |
+
priv = eh_usuario_privilegiado(num)
|
| 185 |
+
print(f" Privilegiado: {priv}")
|
| 186 |
+
|
| 187 |
+
# Testa modo inicial
|
| 188 |
+
modo = forcar_modo_inicial_privilegiado(num)
|
| 189 |
+
print(f" Modo inicial: {modo}")
|
| 190 |
+
|
| 191 |
+
# Testa análise de tom
|
| 192 |
+
tom = analisar_tom_usuario("Oi tudo bem? kkk")
|
| 193 |
+
print(f" Tom: {tom}")
|
| 194 |
+
|
| 195 |
+
# Testa nível de transição
|
| 196 |
+
trans = determinar_nivel_transicao(num, tom, 1)
|
| 197 |
+
print(f" Transição: {trans}")
|
| 198 |
+
|
| 199 |
+
# Testa validação
|
| 200 |
+
print("\n Validando config:")
|
| 201 |
+
validate_config()
|
| 202 |
+
print(" ✅ Config válida")
|
| 203 |
+
|
| 204 |
+
return True
|
| 205 |
+
except Exception as e:
|
| 206 |
+
print(f"❌ ERRO: {e}")
|
| 207 |
+
import traceback
|
| 208 |
+
traceback.print_exc()
|
| 209 |
+
return False
|
| 210 |
+
|
| 211 |
+
def testar_api():
|
| 212 |
+
"""Testa a API."""
|
| 213 |
+
print("\n" + "=" * 50)
|
| 214 |
+
print("🌐 TESTANDO API")
|
| 215 |
+
print("=" * 50)
|
| 216 |
+
try:
|
| 217 |
+
from modules.api import AkiraAPI, SimpleTTLCache
|
| 218 |
+
|
| 219 |
+
# Testa cache
|
| 220 |
+
cache = SimpleTTLCache(ttl_seconds=60)
|
| 221 |
+
cache["teste"] = {"chave": "valor"}
|
| 222 |
+
valor = cache.get("teste")
|
| 223 |
+
print(f" Cache test: {'OK' if valor else 'ERRO'}")
|
| 224 |
+
print(f" Valor: {valor}")
|
| 225 |
+
|
| 226 |
+
# Testa API (sem parâmetros como esperado)
|
| 227 |
+
api = AkiraAPI()
|
| 228 |
+
print("✅ API instanciada")
|
| 229 |
+
|
| 230 |
+
# Testa blueprint
|
| 231 |
+
bp = api.get_blueprint()
|
| 232 |
+
print(f" Blueprint: {bp.name}")
|
| 233 |
+
|
| 234 |
+
# Testa health
|
| 235 |
+
print("\n Health check:")
|
| 236 |
+
# Não podemos testar diretamente sem cliente
|
| 237 |
+
|
| 238 |
+
return True
|
| 239 |
+
except Exception as e:
|
| 240 |
+
print(f"❌ ERRO: {e}")
|
| 241 |
+
import traceback
|
| 242 |
+
traceback.print_exc()
|
| 243 |
+
return False
|
| 244 |
+
|
| 245 |
+
def testar_web_search():
|
| 246 |
+
"""Testa o módulo WebSearch."""
|
| 247 |
+
print("\n" + "=" * 50)
|
| 248 |
+
print("🔍 TESTANDO WEB SEARCH")
|
| 249 |
+
print("=" * 50)
|
| 250 |
+
try:
|
| 251 |
+
from modules.web_search import WebSearch
|
| 252 |
+
ws = WebSearch()
|
| 253 |
+
print("✅ WebSearch instanciado")
|
| 254 |
+
|
| 255 |
+
# Testa detecção de intenção
|
| 256 |
+
i1 = ws.detectar_intencao_busca("Qual o clima em Luanda?")
|
| 257 |
+
i2 = ws.detectar_intencao_busca("Notícias de Angola")
|
| 258 |
+
print(f" Intenção clima: {i1}")
|
| 259 |
+
print(f" Intenção notícias: {i2}")
|
| 260 |
+
|
| 261 |
+
return True
|
| 262 |
+
except Exception as e:
|
| 263 |
+
print(f"❌ ERRO: {e}")
|
| 264 |
+
import traceback
|
| 265 |
+
traceback.print_exc()
|
| 266 |
+
return False
|
| 267 |
+
|
| 268 |
+
def main():
|
| 269 |
+
"""Executa todos os testes."""
|
| 270 |
+
print("\n" + "=" * 60)
|
| 271 |
+
print("🚀 AKIRA V21 ULTIMATE - TESTE COMPLETO")
|
| 272 |
+
print("=" * 60)
|
| 273 |
+
|
| 274 |
+
resultados = []
|
| 275 |
+
|
| 276 |
+
# Executa testes
|
| 277 |
+
resultados.append(("Database", testar_database()))
|
| 278 |
+
resultados.append(("Treinamento", testar_treinamento()))
|
| 279 |
+
resultados.append(("Contexto", testar_contexto()))
|
| 280 |
+
resultados.append(("Config/Contexto", testar_config()))
|
| 281 |
+
resultados.append(("API", testar_api()))
|
| 282 |
+
resultados.append(("Web Search", testar_web_search()))
|
| 283 |
+
|
| 284 |
+
# Resumo
|
| 285 |
+
print("\n" + "=" * 60)
|
| 286 |
+
print("📊 RESUMO DOS TESTES")
|
| 287 |
+
print("=" * 60)
|
| 288 |
+
|
| 289 |
+
todos_ok = True
|
| 290 |
+
for nome, ok in resultados:
|
| 291 |
+
status = "✅ OK" if ok else "❌ ERRO"
|
| 292 |
+
print(f" {nome}: {status}")
|
| 293 |
+
if not ok:
|
| 294 |
+
todos_ok = False
|
| 295 |
+
|
| 296 |
+
print("\n" + "=" * 60)
|
| 297 |
+
if todos_ok:
|
| 298 |
+
print("🎉 TODOS OS TESTES PASSARAM!")
|
| 299 |
+
print("\n📋 PRÓXIMOS PASSOS:")
|
| 300 |
+
print("1. pip install -r requirements.txt")
|
| 301 |
+
print("2. python main.py")
|
| 302 |
+
print("3. http://localhost:7860/health")
|
| 303 |
+
else:
|
| 304 |
+
print("⚠️ ALGUNS TESTES FALHARAM")
|
| 305 |
+
print(" Verifique os erros acima")
|
| 306 |
+
print("=" * 60)
|
| 307 |
+
|
| 308 |
+
return 0 if todos_ok else 1
|
| 309 |
+
|
| 310 |
+
if __name__ == "__main__":
|
| 311 |
+
sys.exit(main())
|
| 312 |
+
|