> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Gerenciamento de Resultados de Ferramentas

> Pareamento, orcamento, microcompactacao progressiva e persistencia em disco para resultados de ferramentas

O ChatCLI implementa um sistema completo de **gerenciamento de resultados de ferramentas** que garante integridade, controla o tamanho do contexto e compacta resultados antigos progressivamente. Isso e essencial para sessões longas de agente onde dezenas de tool calls podem saturar a janela de contexto.

***

## Pareamento de Tool Results

Toda `tool_use` (chamada de ferramenta pelo modelo) deve ter um `tool_result` correspondente no histórico de conversacao. Quando essa correspondencia quebra -- por interrupcao, timeout ou erro silencioso -- a API rejeita o histórico.

O sistema `EnsureToolResultPairing` valida e repara automaticamente:

| Problema | Acao de Reparo |
| :- | :- |
| `tool_use` sem `tool_result` (orfao) | Injeta resultado sintetico de erro |
| `tool_result` sem `tool_use` (orfao) | Remove do histórico |
| IDs de `tool_use` duplicados | Mantém apenas a primeira ocorrencia |

### Resultados Sinteticos

Quando uma tool\_use não tem resultado correspondente, o ChatCLI injeta:

```text theme={"system"}
[Tool result missing — the tool execution was interrupted or failed silently.
Do NOT retry this tool call. Analyze what went wrong and try a different approach.]
```

<Warning>
  A mensagem instrui o modelo a **não repetir** a tool call falha, evitando loops infinitos de retentativa.
</Warning>

### Validação em 3 Fases

<Steps>
  <Step title="Coleta de IDs">
    Percorre todo o histórico coletando IDs de `tool_use` (de mensagens assistant) e IDs de `tool_result` (de mensagens tool).
  </Step>

  <Step title="Detecção de Desalinhamentos">
    Compara os dois conjuntos de IDs. Tool uses sem resultado sao "missing". Tool results sem uso sao "orphans". IDs duplicados sao marcados para dedup.
  </Step>

  <Step title="Reconstrucao do Histórico">
    Reconstroi o histórico: remove orphans, faz dedup de tool\_use IDs e injeta resultados sinteticos após mensagens assistant com tool\_uses sem resultado.
  </Step>
</Steps>

***

## Orcamento de Resultados (Budget Enforcement)

Resultados de ferramentas como leitura de arquivos grandes ou saida de comandos podem consumir rapidamente a janela de contexto. O sistema de orcamento limita o tamanho agregado em **três** niveis:

| Nivel | Limite | Variável / Override | Default |
| :- | :- | :- | :- |
| **Per-tool** (novo) | Cap aplicado dentro do dispatch antes da agregação | Capability `TruncationAware.MaxResultChars()` por plugin | 30.000 chars (global) |
| **Por resultado** | Tamanho máximo de um unico resultado | `CHATCLI_TOOL_RESULT_MAX_CHARS` | 20.000 chars |
| **Por turno** | Tamanho agregado de todos os resultados no turno | `CHATCLI_TOOL_RESULT_BUDGET_CHARS` | 200.000 chars |

### Per-tool truncation (capability)

Plugins que implementam `plugins.TruncationAware` declaram seu próprio cap — útil quando o tool tem necessidade de contexto fora do padrão:

| Plugin | Cap | Justificativa |
| - | - | - |
| `@read` | 80 000 | Arquivos grandes (\~1500 linhas) são primary code-learning surface; cap baixo cega o modelo |
| `@search` | 60 000 | Output estruturado breadth-oriented (file:line:match) — modelo precisa de amplitude |
| `@tree` | 50 000 | Listagens de monorepo facilmente passam de 30k |
| Demais plugins | 30 000 | Default global |

A truncação preserva o shape historic head/tail (preview 5000 chars + suffix 1000 chars + marker `[TRUNCATED N chars omitted, M kept]`).

### Como Funciona o Enforcement

O orcamento e aplicado em duas passadas:

<Tabs>
  <Tab title="Passada 1: Por Resultado">
    Cada resultado individual e verificado contra `DefaultPerResultMaxChars` (20KB). Se exceder, o conteúdo completo e salvo em disco e substituido por um preview:

    ```text theme={"system"}
    [primeiros 4.000 chars do resultado]

    ... [85.432 chars omitted — full output saved to /tmp/chatcli-tool-results/budget_tc_1_3f9a1c02d7e4b5a6.txt]

    [ultimos 1.000 chars do resultado]
    ```
  </Tab>

  <Tab title="Passada 2: Por Turno">
    Se o total de todos os resultados do turno exceder `DefaultTurnBudgetChars` (200KB), os maiores resultados sao truncados progressivamente (do maior para o menor) até o turno caber no orcamento.
  </Tab>
</Tabs>

### Persistência em Disco

Resultados truncados são salvos em arquivos temporários **dentro do [Workspace de Sessão](/pt/context/session-workspace)**, em vez do antigo diretório global `/tmp/chatcli-tool-results/`:

```text theme={"system"}
$TMPDIR/chatcli-agent-<random>/tool-results/
  budget_tc_1_3f9a1c02d7e4b5a6.txt    # Resultado completo da tool call 1
  budget_tc_2_8b04de11c6f2a9d3.txt    # Resultado completo da tool call 2
  result_read_3.txt      # Storage secundário (workers package)
```

A mudança para o diretório por sessão tem dois efeitos importantes:

1. **Isolamento entre sessões.** Múltiplas instâncias de `chatcli` rodando em paralelo no mesmo host não compartilham mais o pool de overflow.
2. **Leitura sob demanda pelo agente.** O scratch dir está na allowlist de leitura do agente, então quando o modelo encontra a marca `[full output saved to ...]` no preview, ele consegue abrir o arquivo com `read_file`:

```xml theme={"system"}
<tool_call name="@coder" args='{"cmd":"read","args":{"file":"/tmp/chatcli-agent-Xy7K3a/tool-results/budget_tc_3_5c71e0aa92bd4f18.txt","start":1200,"end":1500}}' />
```

Antes desta versão, o caminho era um beco sem saída — o read tool bloqueava por estar fora do workspace boundary. O orçamento "salvava o output" mas o agente não tinha como acessá-lo.

<Tip>
  Os arquivos são limpos automaticamente quando a sessão termina (`ChatCLI.cleanup`), respeitando `CHATCLI_AGENT_KEEP_TMPDIR=true` para depuração. Não é mais necessária uma limpeza global periódica.
</Tip>

### Preview: Head + Tail

O preview mantem o inicio e o final do resultado para maximizar utilidade:

| Componente | Tamanho |
| :- | :- |
| Head (inicio) | 4.000 chars (corta na ultima quebra de linha) |
| Referência | Caminho do arquivo em disco |
| Tail (final) | 1.000 chars (corta na primeira quebra de linha) |

***

## Microcompactacao Progressiva

A microcompactacao reduz progressivamente o tamanho de resultados antigos de ferramentas conforme a conversa avanca, sem perder informação crítica:

| Idade do Resultado | Acao | Detalhes |
| :- | :- | :- |
| Turno atual e anterior | Sem alteracao | Resultados preservados integralmente |
| 2+ turnos atras | Truncado | Head (2.000 chars) + tail (500 chars) |
| 4+ turnos atras | Resumido | Uma linha descritiva: `[Old tool result cleared — 450 lines, 28K chars, Go source]` |

Com a [camada de compressão](/pt/context/context-compression) ativa, os dois níveis são **sem perda**: o resultado original é arquivado no store CCR antes do corte e o preview/summary carrega um marcador `<<ccr:KEY>>` (preservado entre níveis) que o modelo expande com `@recall`.

### Detecção de Tipo de Conteúdo

O resumo identifica automaticamente o tipo do conteúdo para contexto:

| Conteúdo | Tipo Detectado |
| :- | :- |
| Comeca com `{` ou `[` | JSON |
| Contem `package ` | Go source |
| Contem `def ` | Python source |
| Contem `function ` | JavaScript source |
| Comeca com `diff ` ou `---` | diff |
| Comeca com `commit ` | git log |
| Outros | text |

### Configuração da Microcompactacao

| Variável | Descricao | Default |
| :- | :- | :- |
| `CHATCLI_MICROCOMPACT_TRUNCATE_TURNS` | Turnos antes de truncar | 2 |
| `CHATCLI_MICROCOMPACT_SUMMARIZE_TURNS` | Turnos antes de resumir | 4 |
| `CHATCLI_HISTORY_REWRITE_PRESSURE` | Fração do budget de compactação que o histórico precisa atingir antes das reescritas por idade rodarem contra um cache de prefixo quente (`0` = todo turno, como antes) | 0.75 |

<Info>
  Apenas resultados com mais de 3.000 chars sao compactados. Resultados pequenos sao sempre preservados. Resultados de ferramentas de escrita e execução sao preservados por conterem informações críticas de erro.
</Info>

### Agendamento Consciente do Cache

Toda reescrita de uma mensagem antiga invalida o prefixo cacheado do provider daquela mensagem em diante: na Anthropic e no Bedrock a cauda inteira é cobrada de novo como escrita de cache (1,25x ou 2x o preço de input); na OpenAI, Gemini, xAI, Kimi e nos demais providers com cache de prompt ela é cobrada a preço cheio em vez do desconto de cache. Raspar algumas centenas de tokens de um resultado que já vem do cache não paga essa conta.

Por isso microcompactação, dedup de leituras repetidas e skill aging são agendados contra o cache, em todos os providers:

* Enquanto o cache de prefixo está **quente** e o histórico está abaixo de `CHATCLI_HISTORY_REWRITE_PRESSURE` do budget de compactação, os passes esperam. Os resultados antigos seguem como leituras baratas de cache.
* Quando o histórico atinge essa fração, os passes rodam: encolher agora é o que mantém longe a compactação com sumarização, muito mais cara.
* Sem prefixo quente a proteger (provider que não reporta cache, cache expirado, primeiro request) os passes rodam a cada turno como sempre rodaram.

O mesmo gate vale para workers de squad, taskgraph e delegate. `CHATCLI_HISTORY_REWRITE_PRESSURE=0` restaura o comportamento só por idade.

***

## Fluxo Completo

O gerenciamento de resultados e aplicado nesta ordem durante o loop do agente:

```text theme={"system"}
1. Tool executa e retorna resultado
2. EnsureToolResultPairing → corrige desalinhamentos
3. EnforceToolResultBudget → trunca resultados grandes
4. ApplyMicrocompact → compacta resultados antigos
5. Histórico limpo enviado para a API
```

***

## Configuração Completa

| Variável de Ambiente | Descricao | Default |
| :- | :- | :- |
| `CHATCLI_TOOL_RESULT_BUDGET_CHARS` | Orcamento agregado por turno | 200.000 |
| `CHATCLI_TOOL_RESULT_MAX_CHARS` | Tamanho máximo por resultado | 20.000 |
| `CHATCLI_MICROCOMPACT_TRUNCATE_TURNS` | Turnos para iniciar truncamento | 2 |
| `CHATCLI_MICROCOMPACT_SUMMARIZE_TURNS` | Turnos para iniciar sumarizacao | 4 |
| `CHATCLI_HISTORY_REWRITE_PRESSURE` | Fração do budget de compactação antes das reescritas rodarem contra cache quente (`0` = todo turno) | 0.75 |

***

## Próximos Passos

<CardGroup cols={2}>
  <Card title="Workspace de Sessão" icon="folder-tree" href="/pt/context/session-workspace">
    Onde os arquivos de overflow vivem e como o agente os lê.
  </Card>

  <Card title="Subagent Delegation" icon="diagram-project" href="/pt/agents/subagent-delegation">
    Estratégia complementar para evitar saturar o contexto com dados brutos.
  </Card>

  <Card title="Recuperação de Contexto" icon="life-ring" href="/pt/context/context-recovery">
    O que acontece quando mesmo com orçamento o contexto transborda.
  </Card>

  <Card title="Cost Tracking" icon="money-bill-trend-up" href="/pt/providers/cost-tracking">
    Monitore o consumo de tokens incluindo tool results.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.