Skip to content

Costs and controls

Use this when you are accounting for what Spor spends on model calls, disabling distilling or nudging, or supplying your own backend.

You do not need this if the defaults are fine; only distilling and nudging make client model calls at all, and Use Spor covers the everyday loop.

After reading this, you should be able to name the two client model callers, summarize spend with spor cost, and apply the environment controls for distilling, nudging, or a custom backend.

The client makes small model calls for exactly two things:

  • distilling — turning the useful parts of a finished session into one or two graph nodes;
  • nudging — suggesting, mid-session, that a discovery is worth capturing before it vanishes.

Nothing else on the client calls a model. Briefings and digests are compiled from the graph, not generated. (In remote mode the server also runs an ingestion model to type and link captures; that cost sits with whoever operates the server, not with your client.)

Every model call the client makes is journaled locally, under $SPOR_HOME/journal/llm-calls/. Summarize spend with:

Terminal window
spor cost
spor cost --since 2026-06-01
spor cost --project harbor --json

--since/--until bound the date range, --project scopes to one project, and --json emits machine-readable output.

Both callers can be disabled independently, via the environment:

Terminal window
export SPOR_DISTILL=0 # no end-of-session distillation
export SPOR_NUDGE=0 # no mid-session capture suggestions

With both off, Spor makes no model calls at all from your machine: briefings, digests, the queue, and manual spor add continue to work, because none of them require one. What you lose is the automatic write-back — you would record outcomes yourself with spor add.

Instead of disabling a piece, you can point it at any command you control:

Terminal window
export SPOR_DISTILL_CMD=/usr/local/bin/my-distiller
export SPOR_NUDGE_CMD=/usr/local/bin/my-classifier

The contract is deliberately small: the prompt arrives on stdin, the response is read from stdout. That is enough to route the calls through a local model, a different provider, or a proxy that enforces your own budget and logging.