thrift-memory
Thrift Memory é um servidor de memória MCP focado em custo para agentes de codificação que param de recarregar grandes arquivos MEMORY.md, AGENTS.md e de contexto de projeto a cada sessão. Ele recupera apenas a memória relevante para a tarefa dentro de um orçamento rígido de tokens e retorna um recibo de economia: baselineTokens vs injectedTokens vs savedTokens.
Documentação
Thrift Memory
O servidor de memória MCP que prova quantos tokens você economizou. (npm: thrift-memory)
🌐 Página inicial do thrift-memory → · npm
Não afiliado ao Apache Thrift, o framework RPC. Este projeto é sempre referido como Thrift Memory — uma camada de memória MCP para agentes de codificação.
Thrift Memory é um servidor de memória MCP com foco em custo para agentes de codificação que param de recarregar grandes arquivos de MEMORY.md, AGENTS.md e contexto de projeto a cada sessão. Ele recupera apenas memória relevante à tarefa sob um orçamento rígido de tokens e retorna um recibo de economia: baselineTokens vs injectedTokens vs savedTokens.
savedTokens = baselineTokens - injectedTokens
Se o seu agente de codificação recarrega o mesmo arquivo de contexto grande a cada início de sessão, essa recarga é um custo de token puro e repetido. O Thrift Memory limita isso e — de forma única — registra um recibo a cada recuperação para que você veja o uso de tokens que evitou, não apenas confie que evitou.
Recuperação com orçamento, em uma linha: Thrift Memory recupera apenas memória relevante à tarefa sob um orçamento rígido de tokens e registra um recibo mostrando baselineTokens vs injectedTokens vs savedTokens.
Status:
0.0.xinicial. As APIs são úteis, mas ainda podem mudar antes dev0.1.
O que ele faz
O Thrift tem três superfícies:
| Superfície | Propósito |
|---|---|
| Servidor MCP | Ferramentas de memória do agente: remember, recall, search_memory |
| Painel local | UI de economia apoiada pelo JSONL do medidor, além de controles do proprietário (fixar/desativar, orçamentos, kill-switch) |
| Proxy | Gateway HTTP opcional que ajusta solicitações LLM ao vivo e tenta novamente limites de taxa |
Seja preciso sobre a divisão:
- MCP gerencia recuperação de memória e recibos de tokens.
thrift-proxygerencia o ajuste de solicitações ao vivo e novas tentativas de limite de taxa.
Como se compara
A comparação certa para o Thrift Memory não é com camadas de qualidade de recuperação / grafo de conhecimento como Mem0, Zep ou Graphiti — essas otimizam o quão inteligente é a recuperação. O Thrift Memory compete com o conjunto crescente de servidores de memória MCP para agentes de codificação, e difere de todos eles em um eixo: visibilidade de custo.
Cada recuperação retorna um recibo de economia — baselineTokens, injectedTokens, savedTokens — para que você veja quantos tokens evitou. Nenhum outro servidor nesta categoria se posiciona em torno de provar a economia.
| Servidor | O que otimiza | Orçamento rígido de tokens na recuperação? | Emite um recibo de economia (baseline vs injected vs saved)? |
|---|---|---|---|
| Thrift Memory | Recuperação com foco em custo — limite os tokens e prove a economia | Sim | Sim — a cada recuperação |
| Official Memory MCP | Memória de grafo de conhecimento (entidades / relações) | Não | Não |
| Context Mode | Sandbox de contexto — mantém saídas grandes de ferramentas/arquivos fora do contexto (SQLite FTS5) | Não (sandbox, não um orçamento de recuperação) | Não |
| Agent Memory MCP | Retorna um pequeno índice via memory_read, depois memory_search por tópico | Não | Não |
| @provos/memory-mcp-server | Recuperação memory_context / task dentro de um orçamento de tokens | Sim | Não |
| memento-memory-mcp | Memória para agentes de codificação — importa CLAUDE.md, SQLite, sincronização git, UI local | Não | Não |
| MCP Context Server | Armazenamento com escopo de thread, busca de texto completo / semântica / híbrida, reclassificação | Não | Não |
| smart-claude-memory-mcp | Armazenamento de memória orientado a Claude | Não | Não |
O concorrente mais próximo, @provos/memory-mcp-server, também recupera sob um orçamento de tokens — mas não mostra o que o orçamento economizou para você. O diferencial do Thrift Memory não é "eu faço memória"; é "eu faço memória com contabilidade de custo." O recibo savedTokens = baselineTokens - injectedTokens é a coisa que ninguém mais nesta categoria lidera.
Resumo honesto: se você precisa da recuperação mais inteligente possível, use uma camada de grafo de conhecimento como Mem0 ou Zep. Se seus agentes de codificação continuam pagando para recarregar grandes arquivos de MEMORY.md / AGENTS.md / contexto de projeto a cada início de sessão e você quer medir e limitar esse custo sem infraestrutura extra, essa lacuna é o que o Thrift Memory preenche. Os dois não são mutuamente exclusivos — o Thrift Memory pode ficar na frente de um armazenamento mais pesado como a camada de orçamento/medição.
Para a comparação completa — incluindo como o Thrift Memory difere de Mem0, Zep e Graphiti no eixo custo vs qualidade de recuperação — veja docs/COMPARISON.md. Perguntas comuns são respondidas em docs/FAQ.md. Para um passeio narrativo de todo o campo de memória — camadas de qualidade de recuperação vs. os servidores de memória MCP com foco em custo — leia o post do blog Mem0 vs Zep vs Graphiti.
Ferramentas MCP
remember(scope, text, agentId?, sessionId?, tags?)
Store a memory in org, agent, or session scope.
recall(agentId, tokenBudget, task?, tags?)
Return relevant memories under a hard token budget.
Also returns { injectedTokens, baselineTokens, savedTokens }.
search_memory(agentId, task?, tags?, limit?)
Browse matching memories without applying a small recall budget.
Veja seu próprio desperdício (10 segundos, nada instalado)
Antes de adotar qualquer coisa, meça o que seus agentes já recarregam a cada sessão:
npx -y thrift-memory audit
Ele escaneia o repositório atual em busca de arquivos de memória / instrução do agente — CLAUDE.md, CLAUDE.local.md, MEMORY.md, AGENTS.md, GEMINI.md, .cursorrules, .cursor/rules/, .windsurfrules, .clinerules, .github/copilot-instructions.md, além do seu ~/.claude/CLAUDE.md global do usuário — e imprime a conta:
Thrift Memory audit — D:\myrepo
File Tokens
CLAUDE.md 3,000
.cursor/rules/api.mdc 900
AGENTS.md 800
.github/copilot-instructions.md 300
TOTAL reloaded per session 5,000
At 10 sessions/day (--sessions): ~50,000 tokens/day, ~1,500,000/month
≈ $22.50/month at $15/M input tokens (an assumption — adjust: --price-per-mtok)
With recall capped at 2,000 tokens/session (--budget): projected saving ~60%
Cada número é calculado a partir dos seus arquivos com o mesmo estimador que o medidor usa — nada é enviado para casa, nada é instalado. Flags: --path=, --sessions=, --budget=, --price-per-mtok=.
Início rápido
Opção A — Plugin do Claude Code (um comando, memória automática)
Se você usa Claude Code, instale tudo — servidor MCP, um agente com memória e comandos /thrift-recall / /thrift-remember — em um único passo:
/plugin marketplace add YohadH/thrift-memory
/plugin install thrift-memory@thrift
Isso registra o servidor MCP thrift automaticamente (via npx thrift-memory), então recall / remember / search_memory ficam disponíveis sem edição de configuração. Veja plugins/thrift-memory/ para o que o plugin inclui.
Memória automática (plugin v0.2.0): o plugin inclui um hook SessionStart que executa thrift-memory session-context e injeta uma fatia de memória com orçamento (padrão 1.500 tokens) diretamente no contexto a cada início de sessão, retomada, /clear e pós-compactação. Suas memórias duráveis sobrevivem à perda de contexto com zero chamadas de ferramenta — e cada auto-injeção é medida (agente session-start), então o painel mostra o que o caminho automático custa e economiza também. Um armazenamento vazio não injeta nada.
Opção B — Configuração MCP (qualquer cliente MCP)
npm install -g thrift-memory
Adicione o Thrift a um cliente compatível com MCP:
{
"mcpServers": {
"thrift": {
"command": "npx",
"args": ["thrift-memory"]
}
}
}
Ou execute o servidor MCP diretamente:
npx thrift-memory \
--store-path=~/.thrift/memories.jsonl \
--meter-path=~/.thrift/meter.jsonl \
--default-budget=2000
Recuperação com suporte a arquivos + sobreposição JSONL
Por padrão, o servidor MCP também escaneia o diretório de trabalho atual em busca de arquivos de contexto do agente existentes: MEMORY.md, AGENTS.md, CLAUDE.md, GEMINI.md, .cursorrules, .windsurfrules, .clinerules, .cursor/rules/*.md|*.mdc, .windsurf/rules/*.md|*.mdc, .github/copilot-instructions.md e pastas específicas do agente que correspondem a memory/<agentId>/*.md.
Esses arquivos são tratados como fontes de recuperação somente leitura. remember() ainda grava novas memórias duráveis no armazenamento JSONL em --store-path, então o modelo de execução é:
MEMORY.md / AGENTS.md / rules files / memory/<agentId>/*.md + ~/.thrift/memories.jsonl
read-only sources + writable overlay
Arquivos sob memory/<agentId>/*.md são carregados como memórias com escopo de agente, então memory/takshi/crm.md é visível para agentId: "takshi", enquanto memory/qa-manager/smoke.md é visível para agentId: "qa-manager". Pastas compartilhadas como memory/reports, memory/feed e memory/advice não são tratadas como IDs de agente.
Edições de arquivo são capturadas na próxima recuperação/busca. Para escanear uma raiz de projeto diferente, passe --file-root=/path/to/repo ou defina THRIFT_FILE_ROOT. Para desativar a recuperação com suporte a arquivos e usar apenas memórias JSONL, passe --file-memory=false ou defina THRIFT_FILE_MEMORY=0.
Demonstração de 60 segundos
Nenhum agente necessário — prove o loop remember → recall → receipt com a biblioteca. Salve como demo.mjs após npm install thrift-memory, depois node demo.mjs:
import { JsonlStore, ScopedRetriever } from "thrift-memory";
const store = new JsonlStore({ path: "./demo.jsonl" });
const now = Date.now();
// 1. remember — store a few org memories (cheap, no LLM enrichment)
store.add({ scope: "org", text: "All money values are stored as integer cents, never floats." }, now);
store.add({ scope: "org", text: "We deploy only on green CI; no Friday-evening releases." }, now);
store.add({ scope: "org", text: "Postgres is the system of record; Redis is cache-only." }, now);
// 2. recall — load only what the task needs, under a hard token budget
const r = new ScopedRetriever().recall(store, {
agentId: "dev",
task: "how should I store money values?",
tokenBudget: 40,
});
// 3. receipt
for (const m of r.memories) console.log("•", m.text);
console.log(`injected ${r.injectedTokens} / baseline ${r.baselineTokens} (saved ${r.savedTokens})`);
• All money values are stored as integer cents, never floats.
injected 15 / baseline 43 (saved 28)
Apenas a memória relevante é injetada — as notas de cadência de deploy e Postgres são descartadas porque não correspondem à tarefa, não apenas por causa do orçamento (recall aplica um piso de relevância). Essa lacuna, baseline - injected, é exatamente o que você para de pagar a cada execução. A relevância aqui é sobreposição lexical, então formule a tarefa com palavras que suas memórias realmente usam; um resultado vazio significa que nada no escopo era relevante — o que é a resposta honesta, não ruído para preencher o orçamento.
Painel
O painel opcional é local. Ele mostra se o Thrift está realmente economizando tokens em execuções reais de agentes e (a partir de 0.0.3) expõe uma pequena superfície de escrita para controles do proprietário — fixar/desativar uma memória, definir orçamentos por agente, silenciar um agente e um kill-switch para toda a frota — por meio de endpoints locais POST/DELETE. Os mesmos controles estão disponíveis na CLI thrift-panel.
npx thrift-panel serve \
--store-path=~/.thrift/memories.jsonl \
--meter-path=~/.thrift/meter.jsonl \
--control-path=~/.thrift/control.json \
--port=8585
Abra http://127.0.0.1:8585.
O painel mostra:
| Visão | O que prova |
|---|---|
| Resumo da frota | Total de tokens baseline, injetados, economizados e taxa de economia |
| Fluxo diário de tokens | Se as economias persistem em dias reais |
| Economia por agente | Quais agentes são caros e quais economizam mais |
| Recibos recentes | Os eventos mais recentes de recuperação/proxy medidos |
| Caminhos de auditoria | Os arquivos locais que sustentam os números |
Equivalentes de CLI:
npx thrift-panel summary --store-path=~/.thrift/memories.jsonl --meter-path=~/.thrift/meter.jsonl
npx thrift-panel agents --store-path=~/.thrift/memories.jsonl --meter-path=~/.thrift/meter.jsonl
npx thrift-panel memories --store-path=~/.thrift/memories.jsonl --scope=org
Medindo desempenho
Cada recall grava um recibo em THRIFT_METER_PATH quando um caminho de medidor está configurado:
{"at":1760000000000,"agentId":"dev","injectedTokens":420,"baselineTokens":2100,"savedTokens":1680}
Definições:
| Campo | Significado |
|---|---|
baselineTokens | O contrafactual sem Thrift: toda a memória no escopo que teria sido carregada |
injectedTokens | A fatia que o Thrift realmente retornou sob orçamento |
savedTokens | baselineTokens - injectedTokens |
| Taxa de economia | savedTokens / baselineTokens |
Loop de medição recomendado:
- Semeie memórias a partir dos seus próprios arquivos markdown ou use
remember. - Deixe agentes reais chamarem
recalldurante o trabalho normal. - Revise
thrift-panel summaryethrift-panel agents. - Valide a qualidade separadamente comparando os resultados das tarefas com memória completa vs. recuperação do Thrift.
Para um relatório público confiável, publique tanto a redução de tokens quanto as evidências de qualidade. Por exemplo: "economizou 72% dos tokens de memória em 200 recuperações reais, com 19/20 tarefas pareadas produzindo o mesmo resultado."
Economizador de tokens seguro — sinais de pressão de orçamento
Cortar tokens só é seguro se o agente conseguir distinguir "recebi tudo que era relevante" de "recebi uma fração disso." Então, cada resultado de recall também relata quanto de memória relevante o orçamento forçou a deixar de fora:
{
"injectedTokens": 492,
"baselineTokens": 14000,
"savedTokens": 13508,
"relevantTokens": 2100,
"skippedForBudget": 12,
"skippedTokensForBudget": 1608,
"hasMoreRelevantMemory": true,
"budgetPressure": "high"
}
| Campo | Significado |
|---|---|
relevantTokens | Tokens de memória que passaram no filtro de relevância — o que valia a pena injetar antes de o orçamento ser aplicado |
skippedForBudget | Contagem de memórias relevantes descartadas apenas porque não cabiam no orçamento |
skippedTokensForBudget | relevantTokens - injectedTokens |
hasMoreRelevantMemory | true quando memória relevante foi deixada de fora por orçamento |
budgetPressure | none (tudo relevante coube) · low · high (tanta memória relevante pulada quanto injetada) |
Esses contam apenas memória que passou no filtro de relevância, então hasMoreRelevantMemory nunca dispara em ruído que a recuperação descartou corretamente. O loop pretendido é recuperação progressiva, feita pelo agente (não pelo usuário final): comece com um orçamento pequeno e, se budgetPressure for high, faça mais uma recuperação focada antes de agir — nunca excedendo um orçamento total de tarefa. É isso que transforma o Thrift de um economizador de tokens em um economizador de tokens seguro: você nunca age silenciosamente com uma fatia esgotada. O agente memory-keeper e o comando /thrift-recall do plugin do Claude Code já seguem esse loop.
Considere a sobrecarga do MCP. Registrar qualquer servidor MCP adiciona a carga do esquema de ferramentas ao contexto de cada agente (frequentemente vários milhares de tokens). O número honesto é líquido:
savings = recall reduction − MCP schema/tool-call overhead. Em um agente com contexto pesado que recarrega memória ampla a cada execução, a recuperação geralmente vence por uma margem ampla — mas confirme com o medidor na sua própria carga de trabalho antes de adotar em toda a frota, em vez de presumir. Os recibos existem justamente para que você não precise adivinhar.
Benchmark Sintético
Este repositório inclui um pequeno fixture sintético para que os usuários possam verificar o pipeline de medição sem dados privados:
npm run build
node benchmark/run.mjs
Ele lê:
benchmark/fixtures/memories.jsonlbenchmark/fixtures/meter.jsonl
Veja docs/case-study.md para um exemplo sanitizado de como interpretar os números.
Monitoramento de Contexto
O hook UserPromptSubmit do plugin executa thrift-memory context-watch em cada
prompt. Ele rastreia o uso de contexto em relação à janela do modelo e, quando o uso
cruza um limite de etapa, injeta uma instrução dizendo ao agente para salvar fatos
duráveis via remember e sugere executar /compact — para que as decisões
sobrevivam à compactação em vez de serem descartadas silenciosamente.
O tamanho da etapa é limitado entre um piso e um teto para que não dispare com muita frequência em janelas pequenas nem raramente demais em janelas enormes:
step = clamp(stepPct% × window, minStepTokens, maxStepPct% × window)
| Flag | Padrão | Significado |
|---|---|---|
--step-pct= | 20 | Tamanho alvo da etapa, como porcentagem da janela |
--min-step-tokens= | 80000 | Piso do tamanho da etapa, em tokens |
--max-step-pct= | 50 | Teto do tamanho da etapa, como porcentagem da janela |
--window-tokens= | (auto) | Substituir o tamanho da janela do modelo detectado |
--state-path= | ~/.thrift/context-watch/ | Onde o estado de cruzamento de etapa é persistido |
O ciclo salvar → compactar → recarregar: context-watch solicita um salvamento antes que um
limite de etapa seja cruzado, PreCompact imprime orientação de compactação como rede
de segurança, e o hook pré-existente SessionStart recarrega uma fatia de memória com orçamento
imediatamente depois — fechando o ciclo para que nenhum fato durável seja perdido na compactação.
Salvamentos delta, não re-salvamentos: cada cruzamento agora marca sua orientação com um
marcador específico da sessão, session:<sessionId>, para que o agente não receba apenas a
instrução de "salvar fatos" às cegas toda vez. A instrução injetada faz o agente chamar
search_memory para essa tag primeiro, a fim de ver o que já foi armazenado nesta
sessão, e então salvar apenas fatos genuinamente novos, marcando-os da mesma forma. Isso
impede que cruzamentos posteriores na mesma sessão relembrem o mesmo fato
repetidamente e impede que o agente presuma incorretamente que algo já foi salvo.
Opte por não participar removendo as entradas UserPromptSubmit (e opcionalmente PreCompact)
de plugins/thrift-memory/hooks/hooks.json.
Economia medida: node benchmark/context-watch.mjs mostra ~72,5% menos tokens
recarregados em janelas simuladas (37.744 na linha de base vs. 10.367 injetados, economizando
27.377 tokens) — veja Benchmark Sintético acima para a
metodologia.
Verificado
Testes de unidade. npm test — 157 testes em 12 arquivos, incluindo um
test/contextWatch.test.ts dedicado que cobre a tabela de limites (tamanhos de etapa 1M→200k,
200k→80k, 128k→64k, 32k→16k), a máquina de estados de cruzamento de etapa (primeiro
cruzamento dispara, a mesma etapa não dispara novamente, a próxima etapa dispara de novo,
isolamento por sessão), análise do final do transcript (message.usage real, uma
leitura limitada do final para transcripts grandes, fallback para fileSize / 4), inferência de
modelo → janela, rejeição de path-traversal no ID de sessão e entrada malformada/ausente.
Tudo verde.
Execução manual do contrato do hook. A CLI compilada (node dist/mcp/bin.js context-watch) foi acionada diretamente com JSON de stdin em formato de hook contra um
transcript sintético: ela dispara com o JSON exato hookSpecificOutput em um
cruzamento, permanece silenciosa em uma repetição da mesma etapa, dispara novamente na
próxima etapa e permanece silenciosa (exit 0) em stdin inválido, stdin vazio e um
caminho de transcript ausente — confirmando que o contrato de "nunca quebrar o prompt" se mantém
em todos os modos de falha, não apenas no caminho feliz.
Execução real de ponta a ponta, contra a sessão de desenvolvimento desta própria funcionalidade.
Em vez de apenas um fixture sintético, context-watch foi reproduzido contra
o transcript real e ao vivo do Claude Code que foi gerado durante a construção
desta funcionalidade — uma sessão genuinamente longa (963 KB, 410 linhas, dados
reais de uso de claude-sonnet-5 / claude-fable-5, sem substituição de janela). Quatro
snapshots reais foram extraídos desse transcript em pontos crescentes do
histórico real da sessão e alimentados pela CLI em ordem cronológica,
cada um como uma nova invocação de hook:
| Turno | Uso real (tokens) | % da janela de 200k | Resultado |
|---|---|---|---|
| T1 | 31.686 | ~16% | silencioso (abaixo da primeira etapa) |
| T2 | 94.821 | ~47% | dispara — cruza a etapa de 40% |
| T3 | 135.227 | ~68% | silencioso (mesma etapa que T2, sem novo disparo) |
| T4 | 182.661 | ~91% | dispara — cruza a etapa de 80% |
Isso corresponde exatamente ao comportamento documentado de "janela de 200k → salva em ~40% e ~80%", usando crescimento real de tokens por turno em vez de números escolhidos a dedo. O transcript completo de 963 KB (bem acima do limite de 64 KB da leitura limitada do final) também foi executado de forma independente e retornou em bem menos de um segundo (~0,3–0,6s de tempo real, dominado pela inicialização do processo Node, não pela análise do transcript) — confirmando que a leitura limitada do final mantém o hook barato mesmo contra uma sessão grande, real e de longa duração.
Proxy e Limites de Taxa
O proxy é opcional. Use-o quando um agente puder apontar seu base_url de LLM para um
gateway HTTP local.
Segurança — execute apenas localmente. O proxy encaminha sua chave de API real do provedor upstream sem alterações. Ele vincula a
127.0.0.1por padrão (aplicado no código, não apenas na documentação), portanto não é acessível fora do host, a menos que você opte deliberadamente com--host=0.0.0.0/THRIFT_PROXY_HOST. Nunca o exponha em uma interface pública nem compartilhe a porta. É uma ferramenta de desenvolvimento de locatário único, não um gateway multiusuário endurecido. As respostas também são armazenadas em buffer, portanto o streaming SSE ainda não é repassado.
npx thrift-proxy \
--upstream=https://api.anthropic.com \
--host=127.0.0.1 \
--port=8787 \
--budget=4000 \
--meter-path=~/.thrift/meter.jsonl
Em seguida, configure a URL base do LLM do agente como http://localhost:8787 e continue usando
a chave de API real do provedor.
O proxy:
- aparar o contexto de solicitação em tempo real sob um orçamento rígido de tokens,
- grava os mesmos recibos de economia que a superfície MCP,
- tenta novamente respostas upstream
429e503 Retry-After, - limita solicitações upstream concorrentes por provedor.
Padrões de limite de taxa:
| Configuração | Padrão | Variável de ambiente |
|---|---|---|
| Concorrência máxima | 5 | THRIFT_MAX_CONCURRENCY |
| Máximo de tentativas | 5 | THRIFT_MAX_RETRIES |
| Base de backoff | 1000ms | THRIFT_BACKOFF_BASE_MS |
| Backoff máximo | 60000ms | THRIFT_MAX_BACKOFF_MS |
thrift-proxy armazena respostas em buffer nesta versão; o repasse de streaming é uma
melhoria futura.
Importar Memórias Existentes
O script de importação é genérico e apenas local. Ele pode importar arquivos markdown para um armazenamento JSONL:
node scripts/import-memories.mjs \
--source=./memory \
--scope=org \
--store-path=~/.thrift/memories.jsonl \
--dry-run
Para memórias com escopo de agente, coloque arquivos markdown em diretórios de projeto e use
--scope=agent:
memory/
checkout-service/
dev.md
qa.md
docs-site/
writer.md
node scripts/import-memories.mjs --source=./memory --scope=agent
Uso da Biblioteca
import { JsonlStore, ScopedRetriever, InMemoryMeter, ThriftMcpServer } from "thrift-memory";
const server = new ThriftMcpServer({
store: new JsonlStore({ path: "./memories.jsonl" }),
retriever: new ScopedRetriever(),
meter: new InMemoryMeter(),
defaultTokenBudget: 2000,
});
await server.runStdio();
Desenvolvimento
npm install
npm run typecheck
npm run build
npm test
Estrutura
| Caminho | Finalidade |
|---|---|
src/mcp/ | Servidor MCP stdio e definições de ferramentas |
src/store/ | Armazenamento de memória JSONL |
src/retrieval/ | Recuperação com escopo e orçamento limitado |
src/meter/ | Medidor de tokens e agregações |
src/control/ | CLI e painel local |
src/proxy/ | Proxy HTTP, aparação de contexto, tentativas com limite de taxa |
benchmark/fixtures/ | Dados públicos de benchmark sintético |
docs/ | Documentação pública, captura de tela, estudo de caso sanitizado |
test/ | Testes de unidade e integração |