# Ambiente. Só "development" expõe a mensagem de erros 500 (mysql2, Ollama...) na resposta # HTTP; qualquer outro valor (ou vazio) responde "internal_error". "production" também # bloqueia o WHATSAPP_WEBHOOK_SKIP_SIGNATURE. NODE_ENV=development # Servidor (valores abaixo já são o padrão do código — só setar para sobrescrever) # PORT=3001 # CORS_ORIGIN=http://localhost:5173 # Atrás de proxy reverso (nginx, etc.): número de saltos confiáveis (ex.: 1). Sem isso o # rate limit e o bloqueio de login veem o IP do proxy para todo mundo. Padrão: desligado. # TRUST_PROXY=1 # Timeout padrão (ms) de chamadas HTTP de saída (WhatsApp, download de áudio do ifbot...) # HTTP_DEFAULT_TIMEOUT_MS=15000 # Autenticação. AUTH_MODE=jwt precisa ficar explícito: o padrão do código é "none" # (sem autenticação nenhuma) — não deixar essa linha comentada em produção. AUTH_MODE=jwt JWT_SECRET=coloque-um-segredo-longo-e-aleatorio-aqui # JWT_ISSUER=oraculo-api # JWT_ACCESS_TTL_SECONDS=900 # JWT_REFRESH_TTL_SECONDS=2592000 # TTL do refresh token quando rememberMe=false/ausente no login (default 1 dia, já é o padrão do código). # JWT_REFRESH_TTL_SHORT_SECONDS=86400 # API Key alternativa (opcional, deixar vazio/comentado para usar só JWT) # API_KEY= # Banco de dados MySQL DB_HOST=localhost DB_PORT=3306 DB_USER=usuario DB_PASS=senha DB_SCHEMA=oraculo # SSL para conexão MySQL (recomendado em produção). Deixe ambos vazios para desativar # SSL (comportamento padrão em dev local). DB_SSL_REJECT_UNAUTHORIZED=true valida o # certificado do servidor; DB_SSL_CA aponta para um arquivo de certificado CA (ex.: # ./certs/rds-ca.pem) se o servidor usar um certificado não confiável publicamente. DB_SSL_REJECT_UNAUTHORIZED=true DB_SSL_CA= # Qdrant (vector DB) — valores abaixo já são o padrão do código # QDRANT_URL=http://localhost:6333 # QDRANT_COLLECTION=oraculo_docs # QDRANT_TIMEOUT_MS=120000 QDRANT_API_KEY= # Ollama — valores abaixo já são o padrão do código # OLLAMA_URL=http://localhost:11434 # OLLAMA_EMBEDDINGS_MODEL=nomic-embed-text # OLLAMA_CHAT_MODEL=llama3.1 # OLLAMA_VISION_MODEL=llava:latest # Modelo usado na sugestão de resposta ao atendente (ConversasWhatsapp). Default # já é "star-atendente" no código mesmo sem essa variável — só setar se publicar # o modelo fine-tuned com outro nome no Ollama. # OLLAMA_ATENDENTE_MODEL=star-atendente # Modelo usado como juiz na avaliação de atendimentos; vazio = OLLAMA_CHAT_MODEL. # OLLAMA_JUDGE_MODEL= # Timeout (ms) para chamadas não-streaming ao Ollama (chat/embeddings) — já é o padrão do # código. Sem esse limite, uma chamada travada (modelo sobrecarregado, processo do Ollama # pendurado) nunca resolve nem rejeita — trava indefinidamente locks como o de avaliação # em lote de atendimentos. Só sobrescrever se precisar de um valor diferente. # OLLAMA_TIMEOUT_MS=180000 # Timeout de inatividade (ms) para o streaming do chat (chatCompletionStream) — já é o # padrão do código. Diferente do OLLAMA_TIMEOUT_MS (que limita o total de uma chamada # não-streaming), este reinicia a cada chunk recebido — só dispara se o Ollama parar de # mandar bytes no meio de uma resposta, o que antes deixava a UI presa em "Gerando # resposta..." para sempre. # OLLAMA_STREAM_IDLE_TIMEOUT_MS=60000 # Prefixos opcionais prependados ao texto antes de gerar embedding (útil para modelos # assimétricos que recomendam prefixo diferente para query de busca e passagem indexada, # ex.: "search_query: "/"search_document: " no nomic-embed-text, "query: "/"passage: " em # modelos da família e5). Vazio (padrão) = modelo não recebe prefixo. Validar empiricamente # com backend/scripts/evalRetrieval.mjs antes de habilitar em produção. # OLLAMA_EMBED_QUERY_PREFIX= # OLLAMA_EMBED_PASSAGE_PREFIX= # RAG — valores abaixo já são o padrão do código # RAG_TOP_K=8 # RAG_CHUNK_SIZE=900 # RAG_CHUNK_OVERLAP=150 # Quantidade de mensagens recentes do histórico incluídas no prompt de rewrite/chat (já é o padrão do código). # RAG_HISTORY_LIMIT=6 # Rate limiting por IP (0 = desativado). Recomendado manter >0 em produção — sem isso # o middleware de rate limit vira um no-op e o /api fica sem proteção contra abuso. RATE_LIMIT_PER_MINUTE=60 # Ajuste fino das respostas do LLM — valores abaixo já são o padrão do código, exceto # LLM_NUM_PREDICT (padrão real: 4096; aqui reduzido para respostas mais curtas/rápidas). # LLM_TEMPERATURE=0.2 # LLM_TOP_P=0.9 LLM_NUM_PREDICT=2048 # LLM_REPEAT_PENALTY=1.1 # Janela de contexto (tokens) do chat e do modo atendimentos (prompts bem maiores) # LLM_NUM_CTX=8192 # LLM_ATENDIMENTOS_NUM_CTX=32768 # Limite de tokens das chamadas auxiliares (rewrite, HyDE, rerank, roteamento) # LLM_AUX_NUM_PREDICT=400 # RAG avançado — valores abaixo já são o padrão do código (tudo desligado) # RAG_QUERY_REWRITE=false # RAG_MIN_SCORE=0.40 # RAG_RERANK=false # RAG_RERANK_TOP_N=8 # HyDE (Hypothetical Document Embeddings): gera um trecho hipotético de resposta via LLM # e usa ele (em vez da query crua) para o embedding de busca, o que tende a elevar o score # de similaridade porque vira matching passagem-passagem. Custa uma chamada LLM extra por # pergunta. Desligado por padrão no código. Validar com backend/scripts/evalRetrieval.mjs # antes de habilitar em produção. # RAG_HYDE=false # Chatbot ifbot (sincronização de atendimentos) — URL e intervalo abaixo já são o padrão do código # IFBOT_BASE_URL=https://star.ifbot.com.br/api IFBOT_TOKEN= # IFBOT_AUTH_HEADER=Authorization # base pública dos arquivos de mídia (/data/img, /data/aud); padrão: IFBOT_BASE_URL sem o sufixo /api # IFBOT_MEDIA_BASE_URL=https://star.ifbot.com.br # ATENDIMENTOS_SYNC_INTERVAL_MINUTES=30 # RAG de atendimentos (ingestão de conversas no Qdrant, coleção separada da de documentos) # ATENDIMENTOS_RAG_COLLECTION=atendimentos_rag # ATENDIMENTOS_RAG_INTERVAL_MINUTES=60 # ATENDIMENTOS_RAG_BATCH=10 # ATENDIMENTOS_RAG_CHUNK_SIZE=1800 # ATENDIMENTOS_RAG_CHUNK_OVERLAP=200 # ATENDIMENTOS_RAG_TOP_K=20 # ATENDIMENTOS_RAG_MIN_SCORE=0.5 # habilita a busca vetorial no modo "atendimentos" do chat — deixar false até calibrar # ATENDIMENTOS_RAG_MIN_SCORE com perguntas reais após o backfill inicial # ATENDIMENTOS_RAG_SEARCH_ENABLED=false # HyDE e rerank na busca do modo atendimentos (rerank ligado por padrão) # ATENDIMENTOS_RAG_HYDE=false # ATENDIMENTOS_RAG_RERANK=true # ATENDIMENTOS_RAG_RERANK_TOP_N=10 # Sugestão de resposta ao atendente (ConversasWhatsapp) — valores abaixo já são o padrão do código # ATENDENTE_SUGESTAO_HISTORY_LIMIT=20 # ATENDENTE_SUGESTAO_MAX_CHARS=8000 # ATENDENTE_SUGESTAO_GUARDRAIL=true # ATENDENTE_SUGESTAO_RAG_ENABLED=true # "nenhum" (padrão), "avaliacao" (resumos de avaliações) ou "conversa" (trechos anonimizados) # ATENDENTE_SUGESTAO_RAG_TIPO=nenhum # ATENDENTE_SUGESTAO_RAG_TOP_K=3 # ATENDENTE_SUGESTAO_RAG_MIN_SCORE=0.5 # ATENDENTE_SUGESTAO_RAG_MAX_CHARS_POR_HIT=600 # ATENDENTE_SUGESTAO_RAG_MAX_CHARS_POR_HIT_CONVERSA=900 # WhatsApp Cloud API (Meta) — 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//whatsapp-business/wa-dev-console/): # - WHATSAPP_PHONE_NUMBER_ID e WHATSAPP_TOKEN: aba "API Setup" (o token temporário expira # em 24h; gere um token permanente em System Users antes de ir pra produção) # - WHATSAPP_VERIFY_TOKEN: valor arbitrário definido por você — cole o mesmo valor no # painel da Meta em WhatsApp → Configuration → Webhook → "Verify token" # - WHATSAPP_APP_SECRET: aba "App settings → Basic", campo "App Secret" — valida a # assinatura X-Hub-Signature-256 dos eventos recebidos. Vazio = o webhook RECUSA todos os # eventos (401), a menos que WHATSAPP_WEBHOOK_SKIP_SIGNATURE=true e NODE_ENV != production # (só para testar localmente sem o App Secret) # - WHATSAPP_BUSINESS_ACCOUNT_ID (opcional, não usado ainda): mesma tela do API Setup, # reservado para gestão de templates/perfil de negócio no futuro # WHATSAPP_API_VERSION já é o padrão do código # WHATSAPP_API_VERSION=v21.0 WHATSAPP_PHONE_NUMBER_ID= WHATSAPP_TOKEN= WHATSAPP_VERIFY_TOKEN= WHATSAPP_APP_SECRET= # WHATSAPP_WEBHOOK_SKIP_SIGNATURE=false # WHATSAPP_BUSINESS_ACCOUNT_ID= # Integrador IXC (Alfred) — 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 daqui (token sobrevive a restart; ver src/functions/atualizaTokenIxcIntegradorERetorna.js). # Rodar o seed de novo com Login/Senha diferentes força um novo login (invalida o token cacheado). IXC_INTEGRADOR_BASE_URL=http://localhost:4001/ IXC_INTEGRADOR_LOGIN= IXC_INTEGRADOR_SENHA= # ACS Space (TR-069) — API pública /api/v1. Criar a chave no painel do ACS em "Chaves de API" com # escopos "leitura" + "diagnostico" (sem "escrita": o Oráculo nunca reinicia nem altera a CPE). # Como o IXC, Url/chave vão para a tabela integracao (Tipo 2) via `npm run seed:run`. ACS_URL=https://acs.star.psi.br/api/v1/ ACS_API_KEY= # ACS_TIMEOUT_MS=15000 # ACS_DIAGNOSTICO_PRAZO_MS=30000 # quanto o /acs ping espera antes de responder "pendente" (< 45s do stream no front) # ACS_DIAGNOSTICO_INTERVALO_MS=10000 # ACS_CONTEXTO_JANELA_HORAS=6 # avaliação só usa o estado da CPE em atendimentos recentes # Transcrição de áudio via Whisper local (whisper.cpp), usada como fallback quando o # ifbot não traz Transcricao — requer `brew install whisper-cpp ffmpeg` e o modelo # baixado em WHISPER_MODEL_PATH. Desligado por padrão no código (false); setar aqui # como lembrete de que a feature existe e precisa desses binários/modelo instalados. WHISPER_TRANSCRICAO_ENABLED=false # WHISPER_BINARY_PATH=whisper-cli # WHISPER_FFMPEG_PATH=ffmpeg # WHISPER_MODEL_PATH=whisper_models/ggml-small.bin # WHISPER_VAD_MODEL_PATH=whisper_models/ggml-silero-vad.bin # WHISPER_TIMEOUT_MS=60000 # WHISPER_THREADS=4 # Jobs pesados em background (avaliação de atendimentos e ingest RAG de atendimentos). # Lotes grandes com intervalo curto deixam o Ollama (llama-server) a 100% de GPU por horas # e travam um Mac de 16GB — prefira lotes pequenos e espaçados para deixar o backend ligado. # ATENDIMENTOS_AVALIACAO_BATCH=20 # ATENDIMENTOS_AVALIACAO_INTERVAL_MINUTES=30 # Máximo de caracteres da conversa enviados ao juiz # ATENDIMENTOS_AVALIACAO_MAX_CHARS=12000 # Janela "HH-HH" (fuso de São Paulo) em que esses jobs podem rodar; vazio = sempre. # Ex.: 19-07 só roda à noite. Disparos manuais pela UI/API ignoram a janela, mas recebem # 409 se outro job pesado estiver rodando naquele momento. # JOBS_PESADOS_JANELA= # Pausa (ms) entre itens do lote, para a máquina e o chat interativo respirarem. # JOBS_PESADOS_PAUSA_MS=3000 # Descarrega o modelo do Ollama (keep_alive 0) ao fim de cada lote. # JOBS_PESADOS_DESCARREGAR_AO_FIM=true