Smart Context — Visão Geral
Módulo que centraliza busca, recorte e entrega do histórico de conversa para prompts, reduzindo custo de contexto sem perder dados importantes
O Smart Context centraliza como o histórico de conversa é buscado, recortado e entregue para os prompts do Tolky Reasoning. O objetivo principal é reduzir custo de contexto (tokens e caracteres) sem perder dados importantes para a operação.
Por que existe
O histórico de conversa é consumido em dezenas de pontos do codebase. Sem centralização, cada ponto tinha sua própria regra de recorte e formatação, gerando:
- Lógica de recorte duplicada
- Diálogos maiores que o necessário para cada tipo de captura
- Pouco aproveitamento do resumo existente nas conversas
- Sem controle centralizado do custo de contexto
Arquitetura
O Smart Context resolve o problema com duas peças principais:
getContext()— Função central que busca e entrega o contexto no formato e tamanho certo para quem chama, aplicando resumo e mensagens recentes quando necessário.SummaryManager— Mantém um resumo compacto e atualizado do diálogo em JSONB, registrando até qual mensagem o resumo cobre, para que as mensagens seguintes continuem em full.
Estrutura do módulo
| Arquivo | Responsabilidade |
|---|---|
contextFetcher.js | Busca o diálogo da fonte correta e mensagens ancoradas de campanha |
campaignPinnedFetcher.js | Query de mensagens system com campaign_id ativo |
contextFormatter.js | Aplica recorte e monta a saída |
summaryManager.js | Gerencia o smart_context_summary (JSONB) |
savingsReporter.js | Calcula economia de caracteres e tokens estimados |
Fontes de diálogo (ordem de prioridade)
globalData.conversations.conversationglobalData.inputBody.originalDialogueglobalData.inputBody.openaiDialogue- Cache por
conversationId - Banco de dados (
vw_conversations) viaconversationId
As fontes 2 e 3 vêm do cliente e têm limite hard de entrada (max_input_chars). Se o diálogo recebido exceder o limite, é truncado antes de qualquer processamento.
Resumo inteligente (SummaryManager)
Estrutura JSONB
O resumo não é uma string simples. É um JSONB que guarda o texto resumido e o ID da última mensagem consumida:
{
"summary": "Usuário informou que tem 3 filhos e mora em São Paulo. Está interessado no plano Premium.",
"lastMessageId": "uuid-da-ultima-mensagem-consumida-pelo-resumo"
}
summary— Texto semântico compacto do diálogo atélastMessageIdlastMessageId— ID da última mensagem coberta pelo resumo; todas as mensagens após essa ID aparecem em full no retorno
Threshold com histerese
O SummaryManager é acionado por threshold com histerese — dois limiares distintos evitam oscilação em conversas que ficam perto do limite:
| Evento | Threshold |
|---|---|
| Acionar sumarização pela primeira vez | threshold_tokens * 1.15 |
| Re-sumarizar quando já existe resumo | threshold_tokens * 1.30 |
A última mensagem user e a última assistant nunca são consumidas pelo resumo — sempre aparecem em full.
Mensagens ancoradas de campanha
O início de uma conversa oriunda de campanha contém mensagens system com dados pré-coletados do contato (telefone, nome, variáveis do template). Quando a conversa cresce e o contexto sofre corte, essas mensagens poderiam desaparecer.
Solução: Mensagens system com campaign_id apontando para uma campanha ativa são sempre incluídas no contexto, independentemente de qualquer corte.
Campanha ativa: deleted = false AND (expire_at IS NULL OR expire_at >= CURRENT_DATE)
Estrutura da saída com mensagens ancoradas
[mensagens system de campanha ativa (ancoradas)]
+ [summary (se ativo)]
+ [mensagens user/assistant recentes (boxes)]
Economia de contexto (savings)
O savingsReporter torna a economia mensurável por requisição:
| Medida | O que representa |
|---|---|
originalCharCount | Total de caracteres do diálogo bruto, antes de qualquer recorte |
returnedCharCount | Total de caracteres do conteúdo final entregue |
savedCharCount | originalCharCount - returnedCharCount |
savedPercent | Percentual de economia |
estimatedOriginalTokens | charCount / 4 (proxy) |
estimatedReturnedTokens | charCount / 4 (proxy) |
estimatedSavedTokens | Tokens economizados estimados |
Configuração via avatar_config
Campo JSONB smart_context em public.avatar_config:
{
"summary_model": "qwen-3-32b",
"summary_provider": "cerebras",
"threshold_tokens": 3000,
"max_input_chars": 50000,
"max_single_message_tokens": 1200,
"truncated_message_target_tokens": 700
}
| Chave | Tipo | Descrição |
|---|---|---|
summary_model | string | Modelo de sumarização |
summary_provider | string | Provider do modelo |
threshold_tokens | number | Base do threshold para acionar resumo (histerese: 1.15x / 1.30x) |
max_input_chars | number | Limite hard de entrada para fontes do cliente |
max_single_message_tokens | number | Threshold por mensagem para truncamento interno |
truncated_message_target_tokens | number | Alvo de tokens após truncamento da mensagem grande |
Prioridade de lookup: config do avatar → config do host (avatar_id = null) → config do domínio.
Próximos passos
- Obter contexto de uma conversa — Endpoint da API para retornar o smart context