npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dexpipe-proxy

v0.11.5

Published

Token-saving proxy for Claude Code: renders bulky context (system prompt, tool docs, old history) as dense PNGs to cut input tokens. Runs on Node and Cloudflare Workers.

Readme

██████╗ ███████╗██╗  ██╗██████╗ ██╗██████╗ ███████╗
██╔══██╗██╔════╝╚██╗██╔╝██╔══██╗██║██╔══██╗██╔════╝
██║  ██║█████╗   ╚███╔╝ ██████╔╝██║██████╔╝█████╗
██║  ██║██╔══╝   ██╔██╗ ██╔═══╝ ██║██╔═══╝ ██╔══╝
██████╔╝███████╗██╔╝ ██╗██║     ██║██║     ███████╗
╚═════╝ ╚══════╝╚═╝  ╚═╝╚═╝     ╚═╝╚═╝     ╚══════╝

npm license: MIT node

Corte os tokens de entrada do Claude Code renderizando contexto volumoso como imagens — o mesmo system prompt, docs de tools e histórico, numa fração dos tokens.

O custo em tokens de uma imagem é fixado pelas dimensões em pixels, não pela quantidade de texto dentro dela. Conteúdo denso (código, JSON, saída de tools) rende ~3,1 caracteres por token de imagem contra ~1 caractere por token de texto no tráfego real do Claude Code. O leitor é o mesmo canal de visão que o computer use da Anthropic já usa para screenshots. O dexpipe é um proxy local que usa esse canal para contexto: ele reescreve as partes volumosas de cada requisição em PNGs compactos antes de saírem da sua máquina. Nos preços de tabela atuais do Fable, isso resulta numa conta de ponta a ponta ~59–70% menor — mas preços mudam e cargas de trabalho variam, então o número durável é o corte de tokens em si, medido por requisição contra um contrafactual gratuito de count_tokens em ~/.dexpipe/events.jsonl.

Isto é o que o modelo vê no lugar do texto:

exemplo: saída real do transformRequest: system prompt + docs de tools redistribuídos numa página densa, banner de instrução no topo, ↵ marcando as quebras de linha originais

~48 mil caracteres de system prompt + docs de tools: ≈25 mil tokens como texto, ≈2,7 mil tokens de imagem como esta página. Saída real do pipeline; o modelo lê renders como este a 100/100 (ver benchmarks).

gráfico: caracteres que uma janela de contexto de fronteira comporta, 2018–2026; a sobreposição laranja medida é Fable 5 [1m] + dexpipe ~18M (4,6×)

Oito anos de crescimento de contexto, em caracteres. Toda linha de texto estaciona perto de ~4M de caracteres (janela de 1M de tokens a ~4 caracteres/token). A sobreposição laranja é a mesma janela de 1M do Fable 5 lida através de imagens do dexpipe — ~18M de caracteres na densidade Anthropic medida (4,6× o teto do texto). A densidade é medida de um render ao vivo na hora da geração, não digitada à mão: regenere com npx tsx scripts/gen-context-chart.ts (fonte).

Demo

Fable 5 (o padrão, leitor 100/100) — sem proxy à esquerda, dexpipe à direita:

https://github.com/user-attachments/assets/1c8ee63a-fcd7-4958-917b-da788d718349

O dexpipe conta um token exato 10/10 em 39 arquivos de preenchimento imageados (bate com o grep linha por linha), acerta a aritmética de múltiplas etapas do razonete, e termina a sessão a US$ 6,06 com contexto de sobra (73,5k/1M) contra US$ 42,21 a 96% de ocupação. Uma ressalva visível no clipe: o braço com dexpipe precisou de um empurrão para seguir o formato de saída de uma linha pedido.

Opus 4.8 (desligado por padrão) — mesmo layout:

https://github.com/user-attachments/assets/f4e50137-31b5-426f-a6ed-b83f829b4a2c

Agulhas em texto leem bem nos dois braços; a contagem de frases imageada não lê no Opus — e o dexpipe diz isso em vez de fabricar um número. Essa taxa de erro de leitura é o motivo do Opus ser opt-in.

Instalação

Publicado no npm como dexpipe-proxy. Requer Node.js ≥ 18.

# uso direto, sem instalar nada
npx dexpipe-proxy

# ou instalação global (recomendado — habilita os comandos `dexpipe` e `claudex`)
npm i -g dexpipe-proxy

Para atualizar mais tarde: npm i -g dexpipe-proxy@latest. Para conferir a versão instalada: dexpipe --version.

A instalação global registra dois comandos em qualquer terminal (PowerShell, CMD, bash/zsh, WSL, macOS, Linux, terminal integrado do VS Code — o npm gera o atalho certo para cada plataforma automaticamente):

| comando | o que é | |---|---| | claudex | uso diário em um comando: sobe o proxy se preciso, abre o dashboard e lança o claude já roteado pelo proxy | | dexpipe | o CLI completo: proxy, diagnóstico, estatísticas, export, CPT |

Experimente (30 segundos)

Com a instalação global, basta um comando — em qualquer terminal:

claudex

Ele detecta se o proxy já está de pé em 127.0.0.1:47821 (sobe em background se não estiver, com log em ~/.dexpipe/proxy.log), abre o dashboard no seu navegador e entrega o terminal ao claude com ANTHROPIC_BASE_URL já apontado para o proxy. Argumentos extras vão direto para o claude (ex.: claudex -c continua a última conversa). Flags próprias: --dashboard, --no-dashboard, --proxy-only, -h.

O dashboard abre em toda execução do claudex, mesmo quando o proxy já estava rodando. Use claudex --no-dashboard ou DEXPIPE_NO_DASHBOARD=1 para impedir a abertura. No Windows, os processos auxiliares do proxy e do navegador são iniciados sem criar uma janela de CMD; somente o terminal interativo onde o Claude Code está rodando permanece aberto.

Sem instalação global (via npx), o caminho manual:

npx dexpipe-proxy                                  # proxy em 127.0.0.1:47821
ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude  # aponte o Claude Code pra ele

No PowerShell (Windows), a variável de ambiente é definida assim:

npx dexpipe-proxy
$env:ANTHROPIC_BASE_URL = "http://127.0.0.1:47821"; claude

Com a instalação global, o passo a passo manual completo (o que o claudex automatiza):

# 1. Configure — cria ~/.config/dexpipe/config.json + mostra os passos de ativação
dexpipe init

# 2. Diagnostique — valida porta, env, config, conectividade com o upstream, render
dexpipe doctor

# 3. Suba o proxy (fica em 127.0.0.1:47821)
dexpipe start

# 4. Em outro terminal, aponte o Claude Code para o proxy
ANTHROPIC_BASE_URL=http://127.0.0.1:47821 claude          # bash/zsh
$env:ANTHROPIC_BASE_URL = "http://127.0.0.1:47821"; claude # PowerShell

# 5. Acompanhe a economia acumulada, direto no terminal
dexpipe stats

Uso opcional com Codex / OpenAI

O mesmo processo do dexpipe atende Claude Code e Codex ao mesmo tempo. As rotas e credenciais ficam separadas: Claude usa /v1/messages com a Anthropic; Codex usa /v1/responses com a OpenAI. Para manter a compressão ativa nos dois, inclua os dois IDs exatos em DEXPIPE_MODELS:

# Terminal 1 — proxy compartilhado para Fable e Codex
$env:DEXPIPE_MODELS = "claude-fable-5,gpt-5.3-codex"
dexpipe start

No Codex, adicione um provider ao arquivo ~/.codex/config.toml (no Windows, C:\Users\<usuario>\.codex\config.toml):

model = "gpt-5.3-codex"
model_provider = "dexpipe"

[model_providers.dexpipe]
name = "DexPipe"
base_url = "http://127.0.0.1:47821/v1"
env_key = "OPENAI_API_KEY"
wire_api = "responses"

Depois, inicie o Codex em outro terminal que tenha a chave da API:

$env:OPENAI_API_KEY = "sk-proj-..."
codex

Em bash/zsh, os comandos equivalentes são:

DEXPIPE_MODELS=claude-fable-5,gpt-5.3-codex dexpipe start
OPENAI_API_KEY=sk-proj-... codex

Use um modelo disponível no seu projeto OpenAI e repita o mesmo ID em model e DEXPIPE_MODELS. O endpoint Responses funciona em passthrough para modelos fora da allowlist, mas eles não são imageados. Se DEXPIPE_MODELS contiver apenas o modelo GPT, o Fable continua funcionando, porém passa como texto sem compressão; inclua claude-fable-5 para preservar os dois caminhos.

Cobrança: esse provider usa OPENAI_API_KEY e consumo da API OpenAI. O login do Codex por assinatura ChatGPT não é automaticamente reutilizado pelo proxy. No Codex Desktop, reinicie o aplicativo após alterar config.toml e garanta que o processo receba OPENAI_API_KEY.

Confirme no dashboard em http://127.0.0.1:47821/ que as requisições Codex aparecem com o caminho /v1/responses. Para testar primeiro sem transformação, inicie o proxy com DEXPIPE_MODELS=off; depois habilite o modelo exato.

Sem chave de licença, sem código de ativação — o dexpipe é MIT. Guia completo de uso: docs/COMO_USAR.md.

Dashboard em http://127.0.0.1:47821/: tokens economizados, cada conversão texto→imagem lado a lado, kill switch, chips de modelo ao vivo e o painel de decisões do gate (RFC-001a) — cada bloco aceito ou rejeitado, com o motivo. As respostas fazem streaming normal — o dexpipe comprime só a requisição, nunca a saída do modelo. Turnos recentes ficam em texto; o system prompt, as docs de tools e o histórico antigo volumoso são imageados.

Desde a v0.11.3, a prévia informa por PNG os caracteres renderizados, a estimativa de tokens de visão, a densidade em caracteres/token e o tamanho do factsheet de identificadores exatos. Esses números também são agregados no JSONL sem persistir o texto da imagem. No cartão de quota, percentuais semanais continuam sendo os valores oficiais reportados nos headers da Anthropic. Os rótulos seguem o painel /usage do Claude: Sessão atual, Todos os modelos e Fable (bucket 7d_oi).

Desde a v0.11.5, o cabeçalho do dashboard ocupa duas faixas compactas: na primeira ficam marca, restauração, tema e compressão; na segunda, os modelos Claude e GPT que podem ser imageados. Os textos auxiliares completos aparecem ao passar o mouse sobre os avisos curtos. Os chips alteram somente o escopo do processo em execução; use DEXPIPE_MODELS para persistir a seleção. O botão Restaurar DexPipe limpa apenas a telemetria local, religa a compressão e volta o escopo runtime ao padrão seguro, somente claude-fable-5; ele não altera nem apaga a quota real informada pela Anthropic.

Métricas ao vivo: o dashboard é o benchmark

Dois painéis no topo do dashboard transformam a alegação de economia em algo auditável enquanto você trabalha — os mesmos acumuladores do /api/stats.json, sem conta refeita no cliente:

Savings em tempo real — gasto real vs. baseline contrafactual. Para cada requisição com usage, o dexpipe mede um contrafactual gratuito: quanto a mesma requisição custaria sem o proxy, via probe de count_tokens e baseline cache-aware (detalhes em docs/CACHING_AND_SAVINGS.md). O painel mostra os dois lados em tokens-equivalentes (input × 1 + output × 5 — as unidades que o limite semanal da Anthropic realmente mede) e em dólares no preço assumido de tabela. O número-título é saved_pct_of_all_spend: Σ economizado ÷ conta contrafactual total, com TODAS as linhas pagas no denominador — passthrough, probe-failed e turnos que o gate recusou incluídos. Isso responde "o dexpipe moveu minha conta real?", não "ele ajudou nas linhas em que rodou?" (a segunda pergunta é cherry-pick). O número pode ficar negativo quando flap de cache em turnos passthrough supera o ganho do colapso — o painel mostra isso em vez de esconder.

Cache hits ao longo do tempo. Uma barra por janela de 5 minutos (o mesmo TTL do prompt cache da Anthropic, então uma barra ≈ uma janela de cache); altura = % de requisições da janela que leram cache morno. "Hit" é observado no servidor (cache_read_tokens > 0 na resposta real — o mesmo predicado da coluna "Cache hits" da tabela de recentes), nunca inferido. Série de 24h no JSON (cache_hit_series), últimas 4h no gráfico. Quedas súbitas de taxa são o sintoma clássico de flap de prefixo (algo mudou no início do contexto e invalidou o cache) — cruze com o painel de decisões do gate para achar o culpado.

Ambos os painéis sobrevivem a restart: o estado é reconstruído do ~/.dexpipe/events.jsonl pelos mesmos caminhos de código do modo ao vivo, então números restaurados e números ao vivo nunca divergem.

Comandos e variáveis essenciais

CLI

| comando | para que serve | |---|---| | claudex | tudo-em-um: garante o proxy de pé, abre o dashboard e lança o claude pelo proxy | | claudex --proxy-only | só garante proxy + dashboard, sem lançar o claude | | claudex --no-dashboard | como claudex, mas nunca abre o navegador (env: DEXPIPE_NO_DASHBOARD=1) | | dexpipe | sobe o proxy local; equivalente ao uso sem subcomando | | dexpipe start | sobe o proxy em 127.0.0.1:47821 | | dexpipe init | cria ~/.config/dexpipe/config.json sem sobrescrever arquivo existente | | dexpipe doctor | valida porta, ambiente, config, upstream, render e Fidelity Probe local | | dexpipe stats | mostra economia acumulada no terminal a partir de events.jsonl | | dexpipe export [...] | renderiza arquivos/diff em PNGs e gera relatório de custo; use dexpipe export --help | | dexpipe cpt | ajusta chars-per-token a partir da telemetria gravada | | dexpipe cpt --dry-run | calcula o ajuste CPT sem gravar estado | | dexpipe cpt --show | mostra o estado CPT aprendido | | dexpipe --version | mostra a versão instalada |

Modelos: DEXPIPE_MODELS

DEXPIPE_MODELS é a variável mais importante depois do ANTHROPIC_BASE_URL. Ela define quais bases de modelo podem ser imageadas. Se o modelo não estiver nessa lista, o dexpipe deixa a requisição passar como texto normal.

# padrão recomendado: só Fable 5
DEXPIPE_MODELS=claude-fable-5 dexpipe start

# habilitar um modelo Anthropic extra
DEXPIPE_MODELS=claude-fable-5,claude-opus-4-8 dexpipe start

# habilitar o caminho GPT/Sol opt-in
DEXPIPE_MODELS=claude-fable-5,gpt-5.6-sol dexpipe start

# desligar todo imageamento, mantendo o proxy como passthrough
DEXPIPE_MODELS=off dexpipe start

No PowerShell:

$env:DEXPIPE_MODELS = "claude-fable-5,gpt-5.6-sol"; dexpipe start

Para persistir sem depender do terminal, use dexpipe init e edite ~/.config/dexpipe/config.json:

{
  "models": ["claude-fable-5", "gpt-5.6-sol"]
}

Os chips de modelo no dashboard mudam o escopo ao vivo, mas só em memória: reiniciar o proxy volta para DEXPIPE_MODELS ou para config.json.

Variáveis de ambiente essenciais

| variável | uso | |---|---| | ANTHROPIC_BASE_URL=http://127.0.0.1:47821 | aponta Claude Code para o proxy | | OPENAI_BASE_URL=http://127.0.0.1:47821/v1 | aponta clientes OpenAI-compatíveis para o proxy | | PORT=47821 | muda a porta local | | HOST=127.0.0.1 | interface de bind; mantenha loopback por segurança | | DEXPIPE_MODELS=claude-fable-5 | controla a allowlist de modelos imageáveis | | DEXPIPE_CONFIG=... | muda o caminho do config.json | | DEXPIPE_LOG=... | muda o caminho de events.jsonl | | DEXPIPE_DUMP_DIR=... | debug: grava PNGs renderizados no disco | | DEXPIPE_RENDER_CACHE_DISK=on | ativa cache persistente de render em disco | | DEXPIPE_ADAPTIVE_CPT_ONLINE=on | ativa atualização CPT incremental opt-in |

Suporte por modelo e provedor

O alvo principal do dexpipe continua sendo Claude Fable 5. Ele é o único modelo habilitado por padrão porque é o perfil com melhor evidência no projeto para leitura de páginas densas de contexto:

DEXPIPE_MODELS=claude-fable-5

Outros modelos da Anthropic podem funcionar tecnicamente, mas são opt-in. O proxy falha fechado: se o modelo não estiver na allowlist, a requisição passa como texto byte-idêntico, sem tentar imagear. Isso evita aplicar compressão de imagem em modelos que aceitam a API mas leem contexto denso pior.

DEXPIPE_MODELS=claude-fable-5,claude-opus-4-8

O caminho OpenAI/GPT também existe. O dexpipe reconhece /v1/chat/completions e /v1/responses, usa blocos image_url/Responses, mantém tools em JSON nativo e tem collapse de histórico específico para pares function_call/function_call_output. Esses modelos também são opt-in:

DEXPIPE_MODELS=claude-fable-5,gpt-5.6-sol

O que foi verificado nesta implementação: rotas, transformação de payload, allowlist, perfis de render, sidecars, fallback, planner, métricas e testes locais para os caminhos Anthropic/OpenAI. O que não foi feito aqui: chamada real aos provedores com chaves de API. Para isso, a Fidelity Probe expõe modelReader, permitindo que um runner de release ou host chame o modelo real e confirme se ele ainda lê os identificadores exatos.

A parte honesta

  • É lossy (com perda). Strings hex exatas de 12 caracteres em conteúdo denso imageado: 13/15 no Fable 5, 0/15 no Opus e 0/15 no Sol — os erros são confabulações silenciosas, não avisos. Valores byte-exatos (IDs, hashes, segredos) precisam ficar em texto; turnos recentes ficam. É exatamente o gap que o Verbatim Guard fecha: identificadores críticos viajam como texto puro ao lado da imagem.
  • Válvula de escape: subagentes em modelos fora da allowlist passam direto como texto — roteie trabalho byte-exato para lá (CLAUDE_CODE_SUBAGENT_MODEL=claude-sonnet-4-6, ou model: sonnet no frontmatter do agente).
  • Trabalho real: piloto SWE-bench Lite 10/10 nos dois braços com −65% no tamanho das requisições; SWE-bench Pro 14/19 ON vs 15/19 OFF com −60%, veredictos concordam em 18/19, e o único caso divergente re-resolveu 3/3 na replicação — variância entre execuções, não compressão. N pequeno; recibos em eval/.
  • Depende da carga de trabalho. Ganha em conteúdo denso em tokens (~1 caractere/token), perde dinheiro em prosa esparsa (~3,5 caracteres/token); um gate de lucratividade (calibrado em N=391 linhas de produção) só imageia onde a matemática ganha.
  • Depende do cliente, não do nome do produto. A economia acompanha o volume não-cacheado que o cliente re-envia como texto. O Claude Code re-envia system + tools + histórico em /anthropic/messages e tipicamente fica em ~60–70%. O Codex em /v1/responses é suportado; quando o prompt já está ~98% em cached_tokens, só resta imagear o slab estático (e raros colapsos de histórico), então o Saved pode honestamente ficar perto de 1%. O mesmo caminho Responses economiza dezenas de pontos percentuais quando o colapso de histórico dispara, e um cliente OpenAI que re-envia a transcrição inteira como texto puro a cada turno está na mesma classe de alta economia do Claude Code. Detalhes e medições: docs/CACHING_AND_SAVINGS.md.
  • Escopo de modelos: padrão DEXPIPE_MODELS=claude-fable-5. Sol, Opus 4.7/4.8 e GPT 5.5 são somente opt-in (chips do dashboard ou DEXPIPE_MODELS) — não são bons o suficiente como padrão silencioso para contexto imageado. O id exato do Sol ainda importa: variantes irmãs como gpt-5.6-terra não herdam a allowlist nem o perfil de render do Sol. DEXPIPE_MODELS=off desliga o imageamento. Todo o resto passa byte-idêntico. No caminho GPT, as definições de tools ficam em JSON nativo e nenhum marcador cache_control da Anthropic é usado. A compressão de histórico do Responses reconhece pares function_call/function_call_output adjacentes completos: só pares antigos fechados são imageados; os seis pares completos mais novos, toda chamada aberta e estados malformados/órfãos ficam nativos. O orçamento padrão de histórico é 32 imagens; cobertura opt-in para sessões longas pode subir (teto defensivo de 100) com DEXPIPE_GPT_HISTORY_MAX_IMAGES=48, após validar o limite de requisição do provedor.
  • Render por modelo: o gpt-5.6-sol (opt-in) usa perfil Spleen 5×8 de 152 colunas; o Claude mantém o perfil Spleen 5×8 de 312 colunas. Os perfis são selecionados pelo id exato do modelo, incluindo páginas de histórico e a matemática de lucratividade. Qualidade do Sol: o 5×8 de produção marcou 98/100 em aritmética, 79/93 em gist completado, 18/18 em estado, 4/15 em confabulações de fatos nunca ditos e 0/15 em hex denso. IDs exatos, portanto, usam o factsheet verbatim, e estado recente/aberto de tools fica nativo. Recibos do Sol e evidência dos perfis.

Benchmarks (reproduzíveis)

Qualidade por modelo (o modelo lê as imagens?)

Toda linha de modelo abaixo usa a mesma receita de produção, salvo quando um braço de pesquisa puro-imagem é indicado: Spleen 5×8 + bloco IDS + factsheet textual adjacente. Os números do Claude são problemas inéditos que o modelo não pode ter memorizado. Qualidade de Sol usa o provedor Responses do Codex; Fable/Opus usam Claude. Deltas de tokens comparam braços de entrada pareados: negativo economiza tokens; positivo custa mais. A execução histórica do GSM8K mediu −38%, mas é outro corpus e não é usada nestas linhas de aritmética inédita.

| teste | modelo | N | texto | dexpipe (imagem) | tokens | |---|---|---:|---:|---:|---| | aritmética inédita | claude-fable-5 | 100 | 100% | 100% | não medido | | aritmética inédita | gpt-5.6-sol | 100 | 100% | 98% | +32% | | aritmética inédita | claude-opus-4-8 | 100 | 100% | 93% | não medido | | A/B de gist recall (decisões, valores, paths, nomes, negações; distratores; sessões de 15k–45k chars) | Fable 5 | 98/braço | 98/98 | 98/98 | não medido | | mesmo corpus de gist, imagens de produção + factsheet | gpt-5.6-sol | 98 | não medido | 79/93 completados; 1 erro de sessão | não medido | | rastreamento de estado (valor mutado 3×, final/primeiro/contagem) | Fable 5 | 18/braço | 18/18 | 18/18 | não medido | | mesmo corpus de estado | gpt-5.6-sol | 18 | não medido | 18/18 no mais recente | não medido | | confabulação de fatos nunca ditos (menor é melhor) | Fable 5 | 16/braço | 0/16 | 0/16 | não medido | | mesmas sondas de fatos nunca ditos (menor é melhor) | gpt-5.6-sol | 16 | não medido | 4/15 completados; 1 erro de sessão | não medido | | hex verbatim de 12 chars, render denso | Opus | 15 | 15/15 | 0/15 | não medido | | hex verbatim de 12 chars, render denso | Fable 5 | 15 | não medido | 13/15 | não medido | | hex verbatim de 12 chars, mesmas páginas densas | gpt-5.6-sol | 15 | não medido | 0/15 | não medido |

Divisão de harness: as linhas de qualidade Fable/Opus e SWE-bench usam Claude; qualidade de Sol usa o provedor Responses do Codex (OPENAI_BASE_URL, tipicamente ocproxy).

Recibos do Sol: eval/sol-profile/QUALITY_RESULTS.md. O SWE-bench não foi replicado no Sol: o runner é específico do Claude Code/Fable (ANTHROPIC_BASE_URL, CLI do Claude, correção oficial via Docker), e ainda não existe execução ON/OFF do Sol. Puro-imagem não é nível Fable em leitores experimentais ao vivo.

Capacidade / densidade (quantos caracteres por token de visão?)

Medido renderizando a fixture densa deste repositório pelo pipeline real e precificando pixels na taxa de visão de cada família. Multiplicador = caracteres/token-de-visão medidos ÷ 4 (baseline de prosa em texto). Não é nota de qualidade de modelo.

| família | janela | como texto (@4 c/tok) | como imagens dexpipe | densidade | multiplicador | |---|---:|---:|---:|---:|---:| | claude-fable-5[1m] (padrão) | 1M | ~4,0M | ~18,3M | ~18,3 c/vt (px÷750) | ~4,6× |

Regenerar: npx tsx scripts/gen-context-chart.ts · PNG do gráfico: docs/assets/context-window-chars.png.

Totais das execuções SWE-bench, recibos e ressalvas: eval/swe-bench/ · eval/swe-bench-pro/ · eval/needle-haystack/ · eval/gist-recall/ · eval/sol-profile/ · análise em FINDINGS.md. (O GSM8K marcou 96% imageado, mas está nos dados de treino — respostas memorizadas sobrevivem a erros de leitura — então lideramos com as avaliações de números inéditos.)

Como funciona

id do modelo ──► perfil de render ──► reflow do contexto volumoso ──► PNG[] + factsheet de tokens exatos

O proxy intercepta /v1/messages, reescreve o volume elegível em blocos de imagem, recoloca tudo de forma amigável ao cache (prefixo estático preservado, prompt caching continua funcionando) e encaminha. Todo modelo habilitado recebe a mesma pilha de produção: páginas Spleen 5×8, bloco IDS dentro da imagem e factsheet textual adjacente. O Claude usa páginas de 1568×728; o GPT 5.6 Sol usa tiras retrato de 768 px de largura. Um estimador por requisição usa esse mesmo perfil resolvido, então prosa esparsa fica em texto. Eventos logam em ~/.dexpipe/events.jsonl.

Etapas do pipeline

  1. Aplicabilidade e allowlist de modelo. O proxy identifica rota, provedor e modelo. Fable 5 é padrão; outros modelos Anthropic e GPT/Sol só são comprimidos quando DEXPIPE_MODELS habilita explicitamente.
  2. Análise de segurança. Secret Guard procura credenciais e bloqueia imageamento de blocos sensíveis. Logs, dashboard, erros 4xx, recoverable data e cache persistente evitam armazenar secrets.
  3. Análise de precisão. Verbatim Guard extrai IDs, SHAs, paths, URLs, portas, UUIDs e números críticos para sidecars por página. Se algum identificador ficaria fora do sidecar (dropped > 0), o bloco não é imageado.
  4. Gate de economia. O gate compara custo estimado do texto contra custo de imagem. Adaptive CPT pode ajustar chars-per-token por workload, primeiro por regressão offline e depois por EWMA online opt-in.
  5. Decision Engine. CompressionDecision é criado antes da execução e comanda se o bloco será texto, imagem ou passthrough. Isso centraliza o motivo técnico da decisão.
  6. Execution Plan. Cada decisão executada vira uma etapa auditável: escopo, estratégia, motivo, páginas, sidecars, fallback e intenção de cache. O tracker persiste uma forma compacta sem conteúdo bruto.
  7. Render e fallback. O texto elegível é reflowed, renderizado em PNG e acompanhado do sidecar da página. Se o sidecar estoura, o pipeline tenta páginas menores antes de cair para texto integral.
  8. Cache e recuperação. Render Cache evita rerenderizar páginas iguais em memória e, opcionalmente, em disco. Recoverable Store permite guardar originais imageados com TTL, limite de espaço, hash e bloqueio de secrets.
  9. Medição e dashboard. Eventos registram economia, decisões, planos, cache, fallbacks, segurança e contadores de fidelidade para dexpipe stats e dashboard.
  10. Sondas de fidelidade. dexpipe doctor roda uma probe local de render. Runners externos podem plugar modelReader para readback real dos modelos.

Verbatim Guard: SHAs nunca viram pixels

A leitura de imagem é lossy, e falha em silêncio: um modelo que lê errado um SHA de commit numa página densa confabula um valor de aparência plausível em vez de sinalizar a falha. Para identificadores de redundância zero (SHAs, UUIDs, IPs, portas, frames de stack trace, endereços de memória), quase certo é pior que inútil.

O Verbatim Guard fecha esse gap: antes de qualquer bloco ser rasterizado, todo identificador crítico de precisão é extraído para sidecars por página que viajam ao lado da imagem correspondente — o volume mantém o desconto de tokens de imagem (~5% dos caracteres da fonte vão para sidecars), os identificadores permanecem texto byte-exato, e nenhum bloco é imageado se algum identificador crítico ficar fora do orçamento (dropped > 0). Quando uma página estoura, o pipeline tenta páginas menores antes de cair para texto. Um bloco IDS rotulado também é renderizado dentro do PNG como defesa em profundidade. Roda automaticamente em todo caminho imageado; também disponível como biblioteca:

import { guardVerbatim } from "dexpipe-proxy/verbatim-guard";
const { sidecar, entries, dropped } = guardVerbatim(textoVolumoso);

O dexpipe estende o motor de fact-sheet original com IPv4/IPv6 (mantidos inteiros, porta opcional), literais hex 0x e frames de stack trace com linha:coluna intactos. Escrita completa: docs/VERBATIM_GUARD.md.

Uso como biblioteca (sem proxy)

import { renderTextToImages, transformAnthropicMessages } from "dexpipe-proxy";

const { pages } = await renderTextToImages(toolResultText);     // pages[i].png: Uint8Array
const { body, applied, info } = await transformAnthropicMessages({
  body: requestBytes,
  model: "claude-fable-5",
});

options.keepSharp(block) fixa blocos como texto; options.emitRecoverable retorna os originais dos blocos imageados. Runtime JS puro (Node e edge/Workers); @napi-rs/canvas é só de build. API completa: src/core/index.ts.

Desenvolvimento

pnpm install && pnpm test
pnpm run build                # regenera dist/

FAQ

O número de destaque é de ponta a ponta ou só das requisições tocadas? De ponta a ponta, a conta inteira. A maioria das ferramentas de compressão reporta economia só na fatia de entrada que tocou, o que infla o número. O denominador de ponta a ponta é toda requisição de produção: as pequenas que o dexpipe corretamente deixou intactas, todas as escritas e leituras de cache, e todos os tokens de saída (que o proxy nunca comprime). Num snapshot de 13.709 requisições deu 59% (US$ 100 → ~US$ 41); um traço posterior de 8.904 requisições comprimidas mediu ~70%. Só-comprimidas dá mais (~72–74%) e é citado separadamente, nunca como destaque. O número exato depende da carga — reproduza no seu próprio log.

Como a matemática é medida? Os dois lados da mesma requisição, no mesmo instante. Para todo POST em /v1/messages, o proxy dispara uma sonda gratuita de count_tokens no corpo original sem compressão (o contrafactual) em paralelo com o encaminhamento real, e lê o bloco de uso efetivamente cobrado pela Anthropic na resposta. Os dois caem na mesma linha de ~/.dexpipe/events.jsonl, então não há confusão de contagem de turnos nem entre execuções. A conversão em dólar usa as razões de tabela do Fable 5: entrada ×1,0, escrita de cache ×1,25, leitura de cache ×0,1, saída ×5. O preço de cache é aplicado identicamente aos dois lados, então o desconto de cache se cancela e não pode ser contado duas vezes como "economia". Re-derive você mesmo a partir do log de eventos: a fórmula e os nomes dos campos estão documentados em src/core/baseline.ts.

O que ele comprime, na prática? Três tipos de blocos de entrada, cada um atrás de um gate de lucratividade:

  1. corpos grandes de tool_result (leituras de arquivo, saída de comandos, logs) acima de ~6 mil caracteres de conteúdo denso em tokens
  2. histórico antigo colapsado: turnos atrás da cauda viva são re-renderizados como páginas de imagem; turnos recentes sempre ficam em texto
  3. o slab estático de system prompt + docs de tools

Todo o resto passa byte-idêntico: suas mensagens, turnos recentes, a saída do modelo (é a resposta — o proxy nunca a toca), prosa esparsa e qualquer coisa pequena demais para valer a pena. O Fable 5 é o único padrão embutido. Sol, Opus e GPT 5.5 seguem como opt-ins explícitos. A execução 5×8 de produção do Sol marcou 98/100 em aritmética, 79/93 em gist completado, 18/18 em estado, 4/15 em confabulações de fatos nunca ditos e 0/15 em hex denso.

Já falhou de verdade, fora dos benchmarks? Sim, uma vez em semanas de uso diário: o modelo recuperou o nome de uma pessoa do histórico de chat imageado e errou com confiança. Sem erro, só um nome plausível e errado. Esse é o modo de falha documentado: strings exatas em conteúdo imageado não são byte-seguras. Sessões de código toleram isso porque o agente relê os arquivos antes de editar; recall de chat puro não tem essa checagem. Esse modo de falha é medido, não anedótico: a auditoria de legibilidade quantifica o recall de strings exatas em páginas renderizadas (leituras cegas param em 63% em identificadores densos, com cada erro previsto por uma matriz de confusão de glifos) e documenta as mitigações entregues — geometria de página grampeada no teto de resample da API para os pixels cobrados realmente chegarem ao encoder de visão, e identificadores exatos (SHAs, números) viajando ao lado como texto.

Por que os erros são confabulações silenciosas em vez de erros de leitura? Porque a visão do modelo não é OCR: a imagem vira embeddings de patches, nunca caracteres discretos, então não existe confiança por glifo para falhar com barulho. Quando os pixels subdeterminam um glifo, o prior de linguagem preenche a lacuna com algo plausível. Mecanismo e recibos: docs/NOT-OCR.md.

O DeepSeek-OCR não mostrou que isso não se sustenta na prática? Não: ele provou que o canal funciona, usando um par encoder/decoder treinado para a tarefa. O ceticismo data de outubro de 2025, quando nenhum modelo de produção de prateleira lia renders densos; isso mudou com o Fable 5 (0/15 em hex verbatim no Opus 4.8 vs 13/15 no Fable 5, mesmas páginas). Linha do tempo e números por modelo: docs/NOT-OCR.md.

Por que o README parece escrito por uma IA? Porque foi. A maioria dos commits deste repositório — código e docs — foi autorada por sessões de agente Opus/Fable rodando atrás do próprio dexpipe, lendo o próprio histórico colapsado como páginas de imagem enquanto trabalhavam.

Limitações

  • Lossy (acima); recall verbatim de imagens não é confiável.
  • A codificação PNG adiciona latência a requisições grandes antes da saída.
  • ASCII/Latin-1 bem testados; CJK funciona, mas de forma conservadora.

Estado do projeto

Disponível hoje

  • Decision Engine executável: CompressionDecision é criado antes da execução e usado para comandar os caminhos principais de compressão, em vez de apenas registrar o que o gate já decidiu.
  • Execution Plan auditável: cada bloco processado registra uma etapa imutável com escopo, estratégia, motivo, páginas, sidecars, fallback e intenção de cache. O tracker persiste uma versão compacta, sem conteúdo bruto.
  • Verbatim Guard forte: identificadores críticos viajam em sidecars por página; dropped > 0 bloqueia imageamento; o fallback tenta páginas menores antes de manter tudo em texto.
  • Secret Guard em superfícies principais: render, logs de eventos, dashboard, erros 4xx e dados recuperáveis passam por redaction ou bloqueio para reduzir vazamento acidental.
  • Fidelity Probe no doctor: uma sonda local valida que os perfis de renderização ainda geram PNGs legíveis estruturalmente, sem glyph drops e sem perda de sidecar. Hosts e runners de release também podem plugar um modelReader para readback real de modelo sobre identificadores exatos.
  • Render Cache em memória e disco opt-in: cache determinístico de render dentro do processo; a camada persistente em disco é opcional (DEXPIPE_RENDER_CACHE_DISK=on) e recusa entradas com secrets.
  • Recoverable Store opcional: além de emitRecoverable, hosts podem persistir originais imageados em storage local com TTL, limite de espaço, hash de integridade, permissões restritas e bloqueio para secrets.
  • Métricas operacionais: stats e dashboard expõem decisões, plano de execução, páginas, sidecars, fallbacks e blocos mantidos em texto por segurança.
  • Adaptive CPT offline + incremental: além do ajuste por regressão offline, a API expõe atualização EWMA conservadora para nudges online a partir de eventos com baseline confiável e bucket dominante. No host Node, o wiring operacional é opt-in por DEXPIPE_ADAPTIVE_CPT_ONLINE=on e só atualiza estados já criados por dexpipe cpt.
  • Analyzer Framework e Render Planner base: Safety, Fidelity, Profitability, Cache e Risk têm interface comum; o planner conhece as estratégias atuais (TEXT, IMAGE, MULTI_PAGE, PASSTHROUGH) e mantém HYBRID/PARTIAL_IMAGE explícitas como futuras, ainda sem execução.
  • Classificador de risco em observação: conteúdo é classificado como semântico, estruturado, exato, secreto ou desconhecido para orientar o planner sem alterar sozinho decisões de produção.

Experimental

  • Adaptive CPT incremental: disponível e ligado no host Node como opt-in; ainda deve ser acompanhado em observação antes de virar padrão.
  • Analyzer/Planner: a base pública existe, mas a integração completa do pipeline ainda é incremental; hoje o pipeline continua usando as mesmas regras explícitas enquanto o planner fornece contrato estável para evolução.
  • Fidelity Probe: útil como canário de release/doctor e já aceita readback real via host, mas ainda não substitui uma avaliação completa de tarefas longas.
  • Execution Plan: já guia e audita os caminhos principais, mas ainda não é um planner central com todas as estratégias futuras.

Planejado

  • Runner periódico da Fidelity Probe: automatizar chamadas reais aos provedores em releases/auditorias e registrar regressões por modelo.
  • PARTIAL_IMAGE e HYBRID executáveis: comprimir a parte semântica e manter trechos exatos em texto, com testes de economia e segurança antes de habilitar no pipeline.

Impacto na redução de tokens

As melhorias recentes não são só organização interna. Elas aumentam ou preservam economia de forma concreta:

  • Sidecar por página + dropped === 0: mantém identificadores exatos em texto sem desistir de imagear o restante do bloco.
  • Fallback para páginas menores: recupera casos que antes cairiam cedo demais para texto integral.
  • Adaptive CPT: ajusta o gate ao workload real, imageando mais quando o texto está caro e evitando imagem quando a economia não fecha.
  • Render Cache persistente: não reduz tokens diretamente, mas reduz CPU e latência para contexto repetido, tornando a compressão mais prática em uso contínuo.
  • Fidelity Probe: evita manter modelo habilitado quando a leitura de imagem regrediu, protegendo a economia contra erro silencioso.
  • Analyzer Framework / Planner: prepara estratégias futuras como PARTIAL_IMAGE, que tende a economizar mais ao imagear conteúdo semântico e manter apenas trechos exatos em texto.

Roadmap

A pesquisa de renderização está pausada desde 2026-07-05: erros de leitura verbatim são limitados por capacidade, não por truque, então nenhuma mudança de fonte/cor/layout conserta o recall de strings exatas em densidade lucrativa. O porquê está em docs/NOT-OCR.md; a análise datada e as três linhas de investigação documentadas (A/B de estilo de glifo com páginas bancadas, canário de runtime + re-busca, pré-voo com leitor substituto) estão em FINDINGS.md, entrada de 2026-07-05. Condição de vigília: repetir a varredura de resolução a cada lançamento de modelo; a densidade legível moveu ~4× em área de glifo do Opus 4.8 para o Fable 5, e um modelo que leia células de produção perto de 100% significa economia subindo de graça.

Segue em aberto, inalterado: se volume imageado estica o contexto efetivo (~2× o conteúdo real na mesma janela de 1M), e se um contexto ativo menor melhora a precisão em tarefas longas. Hipóteses, não afirmações — ou saem como números com um n, ou são cortadas.

Créditos

O dexpipe é um fork do pxpipe de teamchong (MIT) — o proxy de compressão visual, o motor do fact-sheet verbatim, os benchmarks e as escritas honestas de limitações se originam todos lá. Todo o crédito e agradecimento aos autores originais.

Todo o trabalho do fork dexpipe é de Ricardo Soares:

  • Verbatim Guard — nomear o mecanismo, a API pública e as extensões de cobertura (IPv4/IPv6 inteiros, literais 0x, frames de stack trace com linha:coluna intactos). Ver docs/VERBATIM_GUARD.md para a história completa.
  • CLI init/doctor/start/stats.
  • RFC-001a (CompressionDecision) — decisões estruturadas antes da execução, usadas para comandar o pipeline, auditar motivos e alimentar o painel de decisões no dashboard.
  • RFC-001b — golden tests de replay do gate sobre tráfego gravado.
  • Execution Plan — plano auditável de execução por bloco, incluindo páginas, sidecars, fallback e intenção de cache.
  • Secret Guard — bloqueio/redaction de credenciais nas superfícies principais: render, logs, dashboard, erros e dados recuperáveis.
  • Render Cache determinístico — cache em memória e camada persistente opt-in em disco, com recusa de entradas com secrets.
  • Recoverable Store — armazenamento local opcional de originais imageados com TTL, limite de espaço, hash e permissões restritas.
  • Fidelity Probe — sonda local no doctor e interface modelReader para readback real por modelo em runners externos.
  • Adaptive CPT — ajuste por-sistema de chars-per-token via OLS e atualização incremental EWMA opt-in no host Node.
  • Analyzer Framework e Render Planner base — analyzers de Safety, Fidelity, Profitability, Cache e Risk, mais planner para estratégias atuais e futuras.
  • Fail-open global — falhas internas do proxy preservam a requisição original em vez de interromper o cliente.
  • Compatibilidade Windows, dashboard e documentação em português (pt-BR).

Copyright © 2026 Ricardo Soares. Todos os direitos reservados sobre as contribuições do fork, licenciadas sob MIT.

Licença

MIT. Copyright © 2026 Ricardo Soares (contribuições do dexpipe) e os contribuidores originais do pxpipe. Veja LICENSE.