Skip to content
Runic
English
Esc
navigateopen⌘Jpreview
On this page

Introduction

Runic is a cross-session cache and token ledger for an agent's already-resolved decisions.

Agents re-decide things they’ve already decided. The same PR gets summarized twice, the same file gets reviewed twice, the same changelog entry gets generated twice — and each time, the agent pays full price to regenerate an answer it already produced. Runic remembers the answer instead.

What Runic is

Runic sits next to whatever an agent already uses to act — including MCP tool calls — as an optional check: “have I already resolved this exact decision before?”

  • A cache, keyed on an exact-match, normalized signature of a decision the agent already made — { intent, params }, never raw task text, never a reasoning trace.
  • A ledger, logging tokens spent (agent-reported) vs. tokens saved on reuse. Pure bookkeeping, no enforcement.
  • Per-session scope. Cross-session/cross-agent sharing is a later phase, once per-session reuse is proven to matter.

What Runic deliberately is not

  • Not an execution layer. Runic never calls a capability, deploys anything, or runs code — the agent does that itself, however it already does it.
  • Not a permissions or sandboxing system. There’s nothing to check if nothing executes.
  • Not a semantic cache. Matching is exact on the resolved decision, not fuzzy on the phrasing that led to it. See Scope for why that’s a constraint, not a shortcut.

Installation

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

The loop

agent resolves a task into a structured decision


askRunic({ intent, params })

        ├─ hit  → return cached artifact, log tokens saved
        └─ miss → agent generates its own way (as it does today)


                storeResult({ intent, params }, artifact, tokensSpent)

Two functions are the entire agent-facing contract. Everything else in this repo supports those two calls.

// Every call regenerates the answer, even for a decision you've
// already resolved once today.
async function summarizePr(repo: string, pr: number) {
  const result = await callYourLLM(promptFor(repo, pr));
  return result; // paid full price, every single time
}
import { askRunic, storeResult } from "@runic-labs/sdk";

async function summarizePr(repo: string, pr: number) {
  const decision = { intent: "summarize_pr", params: { repo, pr } };

  const cached = await askRunic(decision);
  if (cached) return cached.artifact; // no LLM call, no tokens spent

  const result = await callYourLLM(promptFor(repo, pr));
  await storeResult(decision, result, result.tokensUsed);
  return result;
}

Real numbers, not estimates

Runic never measures token cost itself — the agent reports it, using whatever its own provider actually returned. A real run against OpenRouter, resolving 48 decisions where only 8 were actually unique:

{
  "decisions": 48,
  "uniqueDecisions": 8,
  "apiCalls": 8,
  "cacheHits": 40,
  "tokensSpent": 2582,
  "tokensSaved": 12910,
  "tokensWithoutRunic": 15492,
  "savingsPercent": 83
}

See Benchmarks for how to reproduce this yourself, plus a synthetic sweep showing the same mechanism holds at 10,000 decisions.

Was this page helpful?