engines.node no package.json)http://localhost:6333)Ollama rodando com os modelos necessários:
ollama pull nomic-embed-text
ollama pull llama3.1
cd backend
npm install
Crie o arquivo backend/.env com base nas variáveis abaixo:
| Variável | Descrição | Exemplo |
|---|---|---|
PORT |
Porta HTTP da API | 3001 |
CORS_ORIGIN |
Origem permitida pelo CORS | http://localhost:5173 |
API_KEY |
Chave de API opcional | — |
RATE_LIMIT_PER_MINUTE |
Limite de requisições por minuto (0 desativa) |
0 |
| Variável | Descrição | Exemplo |
|---|---|---|
DB_HOST |
Host do MySQL | localhost |
DB_PORT |
Porta do MySQL | 3306 |
DB_USER |
Usuário do banco | root |
DB_PASS |
Senha do banco | senha |
DB_SCHEMA |
Nome do schema/database | oracle |
DB_SSL_REJECT_UNAUTHORIZED |
Ativa SSL na conexão MySQL e valida o certificado do servidor (setar sozinho já liga SSL, mesmo sem DB_SSL_CA) |
— |
DB_SSL_CA |
Caminho de um certificado CA para validar o servidor MySQL (se ele não usar CA público) | ./certs/rds-ca.pem |
| Variável | Descrição | Exemplo |
|---|---|---|
QDRANT_URL |
URL do Qdrant | http://localhost:6333 |
QDRANT_COLLECTION |
Nome da collection (default no código: oraculo_docs) |
empresa_docs |
QDRANT_API_KEY |
Chave de API do Qdrant (opcional) | — |
| Variável | Descrição | Exemplo |
|---|---|---|
OLLAMA_URL |
URL do Ollama | http://localhost:11434 |
OLLAMA_EMBEDDINGS_MODEL |
Modelo para embeddings | nomic-embed-text |
OLLAMA_CHAT_MODEL |
Modelo para chat | llama3.1 |
OLLAMA_VISION_MODEL |
Modelo de visão (default llava:latest) |
llava:latest |
OLLAMA_ATENDENTE_MODEL |
Modelo usado na sugestão de resposta ao atendente (default star-atendente) |
llama3.1 |
OLLAMA_TIMEOUT_MS |
Timeout (ms) para chamadas não-streaming ao Ollama (default 180000) |
180000 |
OLLAMA_STREAM_IDLE_TIMEOUT_MS |
Timeout (ms) de inatividade no streaming do chat — reinicia a cada chunk recebido (default 60000) |
60000 |
OLLAMA_EMBED_QUERY_PREFIX |
Prefixo prependado à query antes de gerar embedding (modelos assimétricos, ex.: e5) | — |
OLLAMA_EMBED_PASSAGE_PREFIX |
Prefixo prependado à passagem indexada antes de gerar embedding | — |
O runner do Ollama (llama-server) é o que pesa na máquina. A avaliação de atendimentos usa num_ctx 32768, e com o KV cache padrão (fp16) o llama3.1 8B ocupa ~9GB. Configure o servidor (não o backend) e reinicie o Ollama.app:
launchctl setenv OLLAMA_FLASH_ATTENTION 1
launchctl setenv OLLAMA_KV_CACHE_TYPE q8_0 # KV cache pela metade
launchctl setenv OLLAMA_NUM_PARALLEL 1 # não multiplica o KV cache por slots
launchctl setenv OLLAMA_MAX_LOADED_MODELS 1 # nunca duas instâncias residentes
launchctl setenv não sobrevive a reboot — reaplique após reiniciar o Mac (ou coloque num LaunchAgent).
Valem para avaliarAtendimentos e ingestAtendimentosRag: só um roda por vez (o outro pula o ciclo), com pausa entre itens e modelo descarregado do Ollama ao fim do lote.
| Variável | Descrição | Exemplo |
|---|---|---|
ATENDIMENTOS_AVALIACAO_BATCH |
Atendimentos avaliados por ciclo (default 10) |
20 |
ATENDIMENTOS_AVALIACAO_INTERVAL_MINUTES |
Intervalo do job de avaliação; 0 desliga (default 60) |
30 |
JOBS_PESADOS_JANELA |
Janela HH-HH (fuso SP) em que os jobs rodam; vazio = sempre. Disparo manual não é afetado |
19-07 |
JOBS_PESADOS_PAUSA_MS |
Pausa entre itens do lote (default 3000) |
3000 |
JOBS_PESADOS_DESCARREGAR_AO_FIM |
Descarrega o modelo (keep_alive: 0) ao fim do lote (default true) |
true |
WHISPER_THREADS |
Threads do whisper-cli na transcrição de áudio (default 4) |
4 |
Contexto do pipeline (rewrite, HyDE, rerank) em architecture.md.
| Variável | Descrição | Exemplo |
|---|---|---|
RAG_QUERY_REWRITE |
Reescrever query antes da busca, considerando o histórico da conversa (resolve follow-ups tipo "e o segundo caso?") | true |
RAG_HISTORY_LIMIT |
Quantidade de mensagens recentes do histórico incluídas no prompt de rewrite/chat (default 6) |
6 |
RAG_TOP_K |
Número de chunks recuperados (default 8) |
8 |
RAG_MIN_SCORE |
Score mínimo de similaridade (default 0.40) |
0.40 |
RAG_CHUNK_SIZE |
Tamanho de cada chunk (caracteres) | 900 |
RAG_CHUNK_OVERLAP |
Sobreposição entre chunks | 150 |
RAG_RERANK |
Reordenar os chunks recuperados por relevância via LLM antes de montar o contexto | true |
RAG_RERANK_TOP_N |
Quantos chunks manter após o reranking (default = RAG_TOP_K) |
8 |
RAG_HYDE |
HyDE: gera um trecho hipotético de resposta via LLM e usa ele para o embedding de busca (custa uma chamada LLM extra por pergunta) | false |
| Variável | Descrição | Exemplo |
|---|---|---|
LLM_TEMPERATURE |
Criatividade das respostas (0–1); baixo = mais fiel à fonte (default 0.2) |
0.2 |
LLM_TOP_P |
Nucleus sampling | 0.9 |
LLM_NUM_PREDICT |
Máximo de tokens gerados | 2048 |
LLM_REPEAT_PENALTY |
Penalidade de repetição | 1.1 |
Fluxo completo e níveis de acesso em auth.md.
| Variável | Descrição | Exemplo |
|---|---|---|
AUTH_MODE |
Modo de auth (jwt ou none) |
jwt |
JWT_SECRET |
Chave secreta para assinar tokens | trocar-em-producao |
JWT_ISSUER |
Issuer do token | oraculo-api |
JWT_ACCESS_TTL_SECONDS |
Duração do access token em segundos | 900 (15 min) |
JWT_REFRESH_TTL_SECONDS |
Duração do refresh token em segundos | 2592000 (30 dias) |
JWT_REFRESH_TTL_SHORT_SECONDS |
Duração do refresh token quando rememberMe=false/ausente no login |
86400 (1 dia) |
Atenção:
AUTH_MODE=nonedesativa a autenticação completamente. Nunca usar em produção.
| Variável | Descrição | Exemplo |
|---|---|---|
IFBOT_BASE_URL |
URL base da API do ifbot (default https://star.ifbot.com.br/api) |
https://star.ifbot.com.br/api |
IFBOT_TOKEN |
Token de autenticação da API do ifbot | — |
IFBOT_AUTH_HEADER |
Nome do header de autenticação (default Authorization) |
Authorization |
IFBOT_MEDIA_BASE_URL |
Base pública dos arquivos de mídia (/data/img, /data/aud); default é IFBOT_BASE_URL sem o sufixo /api |
https://star.ifbot.com.br |
ATENDIMENTOS_SYNC_INTERVAL_MINUTES |
Intervalo (min) do job de sincronização de atendimentos (0 desativa) |
30 |
Ingestão de conversas no Qdrant, em uma collection separada da de documentos.
| Variável | Descrição | Exemplo |
|---|---|---|
ATENDIMENTOS_RAG_SEARCH_ENABLED |
Habilita a busca vetorial no modo "atendimentos" do chat | false |
ATENDIMENTOS_RAG_COLLECTION |
Nome da collection no Qdrant | atendimentos_rag |
ATENDIMENTOS_RAG_INTERVAL_MINUTES |
Intervalo (min) do job de ingestão | 60 |
ATENDIMENTOS_RAG_BATCH |
Tamanho do lote por execução | 10 |
ATENDIMENTOS_RAG_CHUNK_SIZE |
Tamanho de cada chunk (caracteres) | 1800 |
ATENDIMENTOS_RAG_CHUNK_OVERLAP |
Sobreposição entre chunks | 200 |
ATENDIMENTOS_RAG_TOP_K |
Número de chunks recuperados | 20 |
ATENDIMENTOS_RAG_MIN_SCORE |
Score mínimo de similaridade | 0.5 |
ATENDIMENTOS_RAG_HYDE |
HyDE aplicado à busca de atendimentos | false |
Usada pelo chat de Atendimentos (/api/conversas) e pelo webhook em /webhooks/whatsapp (fora de /api, sem JWT — protegido por hub.verify_token na verificação e, opcionalmente, assinatura HMAC no recebimento). Valores vêm do painel da Meta (developers.facebook.com/apps/<seu-app>/whatsapp-business/wa-dev-console/).
| Variável | Descrição | Exemplo |
|---|---|---|
WHATSAPP_API_VERSION |
Versão da API (default v21.0) |
v25.0 |
WHATSAPP_PHONE_NUMBER_ID |
ID do número, aba "API Setup" | — |
WHATSAPP_TOKEN |
Token de acesso, aba "API Setup" (o temporário expira em 24h; gerar um permanente em System Users antes de produção) | — |
WHATSAPP_VERIFY_TOKEN |
Valor arbitrário definido por você; colar o mesmo valor no painel da Meta em Webhook → "Verify token" | — |
WHATSAPP_APP_SECRET |
Aba "App settings → Basic", campo "App Secret"; valida a assinatura X-Hub-Signature-256 (vazio desativa a validação) |
— |
WHATSAPP_BUSINESS_ACCOUNT_ID |
Opcional, não usado ainda; reservado para gestão de templates/perfil de negócio | — |
Usadas só pelo seed (npm run seed:run), que provisiona a linha na tabela integracao. Em runtime o service lê Url/Login/Senha/Token do banco, não do .env (o token sobrevive a restart). Rodar o seed de novo com Login/Senha diferentes força um novo login e invalida o token cacheado.
| Variável | Descrição | Exemplo |
|---|---|---|
IXC_INTEGRADOR_BASE_URL |
URL base do integrador | http://localhost:4001/ |
IXC_INTEGRADOR_LOGIN |
Login do integrador | — |
IXC_INTEGRADOR_SENHA |
Senha do integrador | — |
Como no IXC, ACS_URL/ACS_API_KEY são usadas só pelo seed, que grava a linha Tipo 2 na tabela integracao. A chave é criada no painel do ACS em "Chaves de API" com os escopos leitura + diagnostico (sem escrita: o Oráculo nunca reinicia nem altera a CPE). Usada pelo comando /acs, pela linha da CPE no /<pppoe> e como contexto da avaliação de atendimentos.
| Variável | Descrição | Exemplo |
|---|---|---|
ACS_URL |
URL da API pública do ACS | https://acs.star.psi.br/api/v1/ |
ACS_API_KEY |
Chave acsk_... |
— |
ACS_TIMEOUT_MS |
Timeout por requisição | 15000 |
ACS_DIAGNOSTICO_PRAZO_MS |
Quanto o /acs ping espera antes de responder "pendente" (abaixo dos 45 s do stream no front) |
30000 |
ACS_DIAGNOSTICO_INTERVALO_MS |
Intervalo entre leituras do resultado | 10000 |
ACS_CONTEXTO_JANELA_HORAS |
A avaliação só usa o estado da CPE (que é o atual) em atendimentos terminados há até X horas | 6 |
Fallback usado quando o ifbot não traz a transcrição do áudio. Requer brew install whisper-cpp ffmpeg e o modelo baixado em WHISPER_MODEL_PATH.
| Variável | Descrição | Exemplo |
|---|---|---|
WHISPER_TRANSCRICAO_ENABLED |
Liga a feature (default false) |
true |
WHISPER_BINARY_PATH |
Caminho do binário whisper-cli (default whisper-cli) |
whisper-cli |
WHISPER_FFMPEG_PATH |
Caminho do binário ffmpeg (default ffmpeg) |
ffmpeg |
WHISPER_MODEL_PATH |
Caminho do modelo Whisper | whisper_models/ggml-small.bin |
WHISPER_VAD_MODEL_PATH |
Caminho do modelo VAD (detecção de voz) | whisper_models/ggml-silero-vad.bin |
WHISPER_TIMEOUT_MS |
Timeout (ms) da transcrição (default 60000) |
60000 |
# Criar as tabelas no banco (rodar uma vez ou após novas migrations)
npm run migrate:latest
# Modo desenvolvimento (hot reload)
npm run dev
# Modo produção
npm start
A API estará disponível em http://localhost:3001.
Para verificar o status dos serviços:
GET http://localhost:3001/health
| Comando | Descrição |
|---|---|
npm run dev |
Inicia com hot reload (node --watch) |
npm start |
Inicia sem hot reload |
npm run migrate:latest |
Aplica todas as migrations pendentes |
npm run migrate:rollback |
Reverte a última migration |
npm run seed:run |
Executa os seeds do banco |