isRecoverableError inclui fetch failed/timeout/econnreset/etimedout/und_err —
um blip de rede no primeiro provider agora cai para o próximo da chain (openai→
gemini→anthropic→ollama) em vez de virar "[Erro ao chamar IA: fetch failed]".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A secretária passa a "lembrar" do cliente entre conversas:
- tabela sec_contact_memory (fato + embedding JSON), chave = ext_chat_id/contact_name.
- na sumarização (a cada ~10 trocas) extrai fatos duradouros do cliente via LLM
e salva com embedding + dedup por similaridade (>0.92).
- buildSystemPrompt injeta "MEMÓRIA DO CLIENTE" com os fatos mais relevantes à
pergunta (cosseno); sem chave de embedding usa os mais recentes; tudo com
fallback silencioso (não regride).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adiciona busca semântica na Base de Conhecimento da secretária:
- embeddings.ts: chunking, embed (OpenAI text-embedding-3-small ou Gemini
text-embedding-004) e similaridade cosseno — tudo na aplicação, sem pgvector.
- tabela sec_knowledge_chunks (vetor em JSON/text) com índices.
- brain.ts: no nó 'knowledge', injeta só os top-4 trechos relevantes à pergunta
do usuário; indexação lazy por hash do conteúdo. Fallback para o conteúdo
inteiro se não houver chave de embedding ou em qualquer falha (não regride).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>