Recuperação de Context Overflow
Quando a API retorna um erro de “context too long”, o ChatCLI aplica até 3 niveis de recuperação antes de desistir:- Nivel 1: Orcamento Agressivo
- Nivel 2: Truncamento de Emergencia
- Nivel 3: Truncamento Nuclear
Primeira tentativa: reduz os limites de orcamento pela metade e limpa desalinhamentos.Acoes:
- Repara pareamento de tool results (remove orfaos, injeta sinteticos)
- Reduz
DefaultTurnBudgetCharseDefaultPerResultMaxCharspara 50% dos valores originais - Aplica enforcement de orcamento com limites reduzidos
- Trunca mensagens longas do assistente para 5.000 chars
Os limites originais sao restaurados após a aplicacao. Apenas o histórico atual e afetado pela reducao.
Detecção de Erro — overflow do modelo
O sistema reconhece múltiplas formas de erro de overflow:| Mensagem de Erro | Provedor |
|---|---|
context length exceeded | Anthropic |
prompt is too long | OpenAI |
request too large | Varios |
max_tokens exceed | Varios |
input too long | |
token limit | Genérico |
Recuperação de proxy/gateway corporativo
Ambientes corporativos frequentemente rodam atrás de proxies ou gateways que impõem um teto de body size para POSTs — tipicamente 1-5 MB, totalmente independente da janela de contexto do modelo. Você pode estar dentro do limite do Anthropic (200K tokens / ~800 KB) e mesmo assim tomar uma rejeição misteriosa do proxy. Pior: muitos proxies não retornam um 413 limpo — alguns mandam 403 do WAF (Cloudflare, Akamai, mod_security), 431 (header too large), ou simplesmente dropam a conexão TCP no meio do POST, emergindo comoEOF / connection reset no cliente.
O ChatCLI detecta esses três padrões e aplica o mesmo fluxo de recuperação do context overflow.
Detecção de Erro — proxy/gateway
| Padrão detectado | Exemplo | Função |
|---|---|---|
| HTTP 413 + variantes | 413 Payload Too Large, request entity too large, body too large, maximum request size, 431 Request Header Fields Too Large | IsPayloadTooLargeError |
| 403 com sinais de WAF/firewall | 403 com firewall, waf, security policy, blocked by, cloudflare, cf-ray, mod_security, akamai, proxy denied, policy violation | IsProxyWAFRejection |
| 403 com corpo HTML (Bedrock/AWS SDK) | StatusCode: 403 ... deserialization failed ... invalid character '<' looking for beginning of value (SDK tentando decodar uma página de bloqueio HTML do proxy como JSON) | IsProxyWAFRejection |
| EOF / reset com histórico grande | unexpected eof, connection reset, broken pipe, stream error e histórico > 500 KB | IsLikelyPayloadProblem (heurístico) |
A detecção de WAF é conservadora — um 403 sem sinais de firewall continua sendo tratado como erro de autenticação (refresh OAuth + retry). Só quando o 403 carrega sinais específicos do proxy/WAF é que ele é reclassificado como falha recuperável de payload. Isso evita invalidar credenciais OAuth válidas quando o problema real está na rede.
O caso Bedrock corporativo: quando o proxy/WAF intercepta a requisição POST ao Bedrock Runtime e devolve uma página HTML de bloqueio com status 403, o AWS SDK tenta fazer parse do body como JSON e falha com
"invalid character '<' looking for beginning of value" e RequestID vazio. Esse padrão é um fingerprint inequívoco de middlebox (um 403 real da AWS retorna JSON bem-formado) — o ChatCLI reclassifica para falha recuperável de payload e dispara a mesma ladder de recovery.A detecção de EOF/connection-reset aplica um limiar de tamanho do histórico (500 KB) antes de suspeitar de payload. Requisições pequenas que sofrem EOF continuam sendo tratadas como falhas transitórias de rede (retry normal). Só quando o histórico já está suspeitosamente grande é que o EOF é reclassificado como possível body cap.
Pre-flight check
A cada turno do agente, o histórico é medido antes do request sair. Dois caminhos: ComCHATCLI_MAX_PAYLOAD configurado:
Se o histórico passa de 85% do cap, o BudgetRatio é forçado para 0.40 antes de qualquer coisa — compactação agressiva preventiva. O usuário vê:
Auto-cap reativo após 413
Se um 413/WAF/EOF acontece e o usuário não configurouCHATCLI_MAX_PAYLOAD, o ChatCLI assume 4 MB automaticamente para o resto da sessão — dá uma chance alta de o retry passar no mesmo proxy:
System notice injetado na história
Após um recovery disparado por payload limit, o ChatCLI injeta uma mensagemuser antes do retry instruindo o modelo a fazer leituras menores no futuro. Isso quebra o loop do modelo de tentar re-ler o mesmo arquivo gigante que causou o 413 originalmente:
Escalação de Max Output Tokens
Quando o modelo para de gerar por atingir o limite demax_tokens, o ChatCLI pode escalar automaticamente:
| Tentativa | Acao |
|---|---|
| 1a | Dobra o max_tokens atual (até o cap do provedor) |
| 2a | Dobra novamente (até o cap do provedor) |
| 3a+ | Para de escalar, retorna conteúdo parcial |
Mensagem de Continuacao
Quando o modelo e interrompido por limite de tokens, o ChatCLI injeta uma mensagem de continuacao:Configuração
| Variável de Ambiente | Descrição | Default |
|---|---|---|
CHATCLI_CONTEXT_WINDOW | Override global da janela de contexto (em tokens), para qualquer provider/modelo. Tem precedência sobre o catálogo. Use quando a janela real do seu gateway/agente difere da assumida pelo ChatCLI — o orçamento de compactação deriva desse valor. | (auto via catálogo) |
CHATCLI_MAX_RECOVERY_ATTEMPTS | Tentativas máximas de recuperação de contexto | 3 |
CHATCLI_MAX_TOKEN_ESCALATIONS | Escalações máximas de max_tokens | 2 |
CHATCLI_EMERGENCY_KEEP_MESSAGES | Mensagens mantidas no truncamento de emergência | 10 |
CHATCLI_MAX_PAYLOAD | Teto human-friendly para o body size do POST (ex.: 5MB, 512KB, 2.5MB, 5=5MB). Quando setado, o compactor respeita esse teto como limite adicional à janela de contexto do modelo, e o pre-flight força compactação ao cruzar 85% do cap. | (não setado — sem teto) |
Feedback visual durante a compactação
Desde esta versão, o histórico nunca mais “congela” o terminal durante uma compactação longa. OHistoryCompactor emite status em cada fase do pipeline via SetStatusCallback:
Ctrl+C / ESC propaga corretamente e aborta a compactação sem corromper o histórico (retorna ctx.Err() em vez de cair para truncamento de emergência cego).
Microcompact (pré-budget)
Antes doNeedsCompaction checar se o histórico excede o budget, o agent loop aplica ApplyMicrocompact — uma passada pure-Go, sem LLM, sem rede que progressivamente trunca/resume tool results antigos (2+ turnos atrás → head+tail preview; 4+ turnos atrás → one-line summary). Na maioria dos casos isso mantém o histórico dentro do budget sem disparar o Level 2 (caro).
| Variável de Ambiente | Descrição | Default |
|---|---|---|
CHATCLI_MICROCOMPACT_TRUNCATE_TURNS | Turnos de idade para começar a truncar tool results | 2 |
CHATCLI_MICROCOMPACT_SUMMARIZE_TURNS | Turnos de idade para substituir por summary de uma linha | 4 |
Ratio de Orcamento Agressivo
No nivel 1, os limites de orcamento de tool results sao multiplicados por0.5 (50%). Isso significa:
| Parâmetro | Normal | Nivel 1 Recuperação |
|---|---|---|
| Budget por turno | 200.000 chars | 100.000 chars |
| Max por resultado | 20.000 chars | 10.000 chars |
Fluxo de Recuperação
Interação com Outros Sistemas
A recuperação de contexto trabalha em conjunto com:Tool Result Budget
O orcamento de resultados e a primeira linha de defesa. A recuperação ativa quando o orcamento não foi suficiente.
Microcompactacao
A compactação progressiva reduz o crescimento do contexto ao longo do tempo.
Controle de Conversa
O comando
/compact e a forma proativa de prevenir overflow.Cost Tracking
Monitore o uso de contexto para antecipar quando /compact sera necessário.