Aller au contenu
Runic
Français
Esc
naviguerouvrir⌘Japerçu
Sur cette page

@runic-labs/ledger

Comptabilité en ajout seul des jetons dépensés et économisés.

@runic-labs/ledger est un simple outil de comptabilité : il n’applique jamais de budget, ne refuse jamais un appel et n’estime jamais un coût que vous n’avez pas signalé. Il répond à une question : combien la résolution de ces décisions a-t-elle réellement coûté, et quelle part de ce coût a été évitée grâce à la réutilisation ?

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() }));

Utilise par défaut un FileLedgerStore dans .runic/ledger.json (ou $RUNIC_HOME/ledger.json) si aucun stockage n’est fourni.

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);

C’est exactement le calcul utilisé par benchmarks/openrouter-savings et benchmarks/reuse-sweep pour afficher leurs chiffres finaux ; consultez Benchmarks.

Pourquoi recordHit ne prend pas d’argument tokensSpent

La valeur d’un hit est définie comme le coût du miss initial pour cette signature : le registre le recherche lui-même plutôt que de faire confiance à l’appelant pour le répéter correctement à chaque hit. S’il n’existe aucun miss antérieur pour une signature qui est néanmoins touchée (cela ne devrait pas se produire en utilisation normale, mais le registre ne suppose pas que ce soit impossible), il enregistre 0 plutôt que de deviner.

Backends de stockage

Même modèle que @runic-labs/cache : MemoryLedgerStore pour les tests et les exécutions éphémères, FileLedgerStore pour la persistance entre des invocations de processus distinctes. Implémentez vous-même l’interface LedgerStore pour un autre backend :

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

Suite

  • Cache — le stockage correspondant, indexé par signature
  • CLIrunic ledger status lit ce résumé depuis la ligne de commande

Cette page vous a-t-elle été utile ?