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: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
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ê:
Cap adaptativo aprendido
Os providers Bedrock anotam cada erro de transporte com o tamanho exato da requisição que o middlebox rejeitou. Quando uma rejeição de payload acontece, o ChatCLI deriva o limite da sessão diretamente dessa observação — ¾ do tamanho rejeitado — em vez de chutar:CHATCLI_MAX_PAYLOAD já estiver abaixo dele, seu valor vence; uma rejeição menor posterior aperta ainda mais.
Quando o tamanho rejeitado é desconhecido (providers sem anotação de tamanho), vale o comportamento anterior como fallback: assumir 4 MB para o resto da sessão.
Diagnóstico de piso — quando compactar não resolve
O system prompt (charter do agente, personas, skills, docs de ferramentas MCP) nunca é compactado. Quando ele sozinho atinge o tamanho que o gateway acabou de rejeitar, nenhuma compactação de histórico produz uma requisição aceitável — repetir payloads idênticos só queimaria tentativas de recovery. O ChatCLI detecta isso e falha rápido com uma mensagem acionável:Encolhimento de conteúdo — o Nível 3 que funciona de verdade
Dropar mensagens inteiras é no-op quando o histórico é curto — sessões de agente frequentemente têm só o system prompt e um punhado de tool results gigantes, e oMinKeepRecent mantém exatamente as mensagens que carregam o volume. A truncagem de emergência ganhou por isso um passe final: encolhe o conteúdo das mensagens não-system, da maior para a menor, até caber no budget de payload. Mensagens system nunca são tocadas.
Com a camada de compressão ativa, cada mensagem é arquivada verbatim no store CCR antes do primeiro corte e o conteúdo encolhido carrega um marcador <<ccr:KEY>> — o modelo recupera o original a qualquer momento com @recall. A truncagem nuclear (nível 3 da escada de recovery) adicionalmente limita cada mensagem não-system mantida a 4.000 chars.
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. O notice é injetado no máximo uma vez por sessão — o recovery detecta uma cópia existente em qualquer lugar do histórico (mesmo dobrada num summary de compactação) e nunca empilha uma segunda, já que cada byte extra trabalha contra o próprio limite sendo recuperado:
Escalação de Max Output Tokens
Quando o modelo para de gerar por atingir o limite demax_tokens, o ChatCLI pode escalar automaticamente:
Mensagem de Continuacao
Quando o modelo e interrompido por limite de tokens, o ChatCLI injeta uma mensagem de continuacao:Configuração
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)
A checagem de budget em si é honesta com o payload: pesa o texto das mensagens mais argumentos de tool calls nativas, payloads de imagem e excesso de system-parts, então históricos pesados em tools ou visão cruzam o limiar quando a requisição real cruza — não depois de um proxy já ter rejeitado. 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).
Com a camada de compressão ativa, o microcompact é sem perda: o tool result original é arquivado no store CCR antes do corte e o stub de preview/summary embute um marcador <<ccr:KEY>>. Os marcadores sobrevivem entre níveis — quando um preview truncado depois vira um summary de uma linha, o marcador permanece no summary — então o modelo sempre pode expandir o original com @recall.
Ratio de Orcamento Agressivo
No nivel 1, os limites de orcamento de tool results sao multiplicados por0.5 (50%). Isso significa:
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.