Saltar para o conteúdo
Runic
Português
Esc
navegarabrir⌘Jpré-visualizar
Nesta página

@runic-labs/ledger

Contabilidade somente de acréscimo dos tokens gastos versus os tokens economizados.

@runic-labs/ledger é pura contabilidade — ele nunca impõe um orçamento, nunca recusa uma chamada, nunca estima um custo que você não informou. Ele responde a uma pergunta: quanto a resolução dessas decisões realmente custou, e quanto disso foi evitado pela reutilização?

npm install @runic-labs/ledger
pnpm add @runic-labs/ledger
yarn add @runic-labs/ledger
bun add @runic-labs/ledger

createLedger(store?)

import { createLedger, FileLedgerStore, defaultLedgerFilePath } from "@runic-labs/ledger";

const ledger = createLedger(new FileLedgerStore({ filePath: defaultLedgerFilePath() }));

Por padrão, usa um FileLedgerStore em .runic/ledger.json (ou $RUNIC_HOME/ledger.json) caso nenhum armazenamento seja fornecido.

PropType
recordMiss(signature, tokensSpent)?void

Logs a cache miss — the agent generated its own way and spent tokensSpent.

Typevoid
recordHit(signature)?void

Logs a cache hit, recording the same tokensSpent as the original miss for this signature.

Typevoid
summary()?LedgerSummary

Aggregated totals — see below.

TypeLedgerSummary
all()?LedgerEvent[]

The full raw event log.

TypeLedgerEvent[]
clear()?void

Removes all events.

Typevoid

LedgerSummary

interface LedgerSummary {
  totalSpent: number;
  totalSaved: number;
  hitsBySignature: Record<string, number>;
}
const summary = ledger.summary();
const totalHits = Object.values(summary.hitsBySignature).reduce((a, b) => a + b, 0);
const tokensWithoutRunic = summary.totalSpent + summary.totalSaved;
const savingsPercent = Math.round((summary.totalSaved / tokensWithoutRunic) * 100);

Este é exatamente o cálculo que tanto benchmarks/openrouter-savings quanto benchmarks/reuse-sweep usam para imprimir seus números finais — consulte Benchmarks.

Por que recordHit não recebe um argumento tokensSpent

O valor de um acerto é definido como o que quer que o erro original dessa assinatura tenha custado — o registro consulta isso por conta própria, em vez de confiar que o chamador o repita corretamente a cada acerto. Se não houver um erro anterior para uma assinatura que, de alguma forma, esteja sendo acertada (isso não deveria acontecer no uso normal, mas o registro não presume que não possa), ele registra 0 em vez de adivinhar.

Backends de armazenamento

O mesmo padrão de @runic-labs/cache: MemoryLedgerStore para testes e execuções efêmeras, FileLedgerStore para persistência entre invocações separadas de processos. Implemente você mesmo a interface LedgerStore para um backend diferente:

interface LedgerStore {
  append(event: LedgerEvent): void;
  all(): LedgerEvent[];
  clear(): void;
}

Próximo

  • Cache — o armazenamento correspondente indexado por assinatura
  • CLIrunic ledger status lê este resumo pela linha de comando

Esta página foi útil?