Skip to content

Record and replay

Use record to save provider responses, then replay to run the same requests offline. This gives tests repeatable answers and lets the built-in templates run without an API key.

nola.config.ts
import { openai, record, replay } from "@nola-lang/providers";
import { defineConfig } from "@nola-lang/runtime";
const live = process.env.NOLA_RECORD === "1";
export default defineConfig({
model: live
? record(openai({ model: "gpt-5-mini" }), "./nola.replay.jsonl")
: replay("./nola.replay.jsonl"),
});
Terminal window
NOLA_RECORD=1 nola run src/main.ts # talks to the provider, appends every exchange to the ledger
nola run src/main.ts # offline: answers come from the ledger

record(inner, path) wraps a provider and appends each exchange to a JSONL file. Each line contains a request fingerprint, the ask as data and the provider’s response text. Review the file before committing it for tests.

When replay loads a ledger, an unreadable file, invalid JSON or an entry missing its fingerprint or response produces NOLA3007.

replay(path) returns recorded answers. If a request has no matching entry, it raises NOLA3008. It never falls back to a network request.

An ask’s first attempt and its correction turn share a fingerprint because the key excludes the correction itself. Responses with the same key replay in their recorded order. A run that needed a correction will therefore reproduce that correction before returning the accepted answer.

The fingerprint uses the ask as data, as first composed — never a provider’s rendering — so a ledger can be used across models and survives an upgrade that changes Nola’s default wording. The following changes produce a new key:

  • the instruction text or contextual values;
  • the extractor’s type or schema;
  • provider params (temperature, maxOutputTokens, providerOptions);
  • an inference profile sent to the platform;
  • system.message.

The provider name is not part of the fingerprint. Switching from openai to anthropic does not require a new recording if the request stays the same.

After a change causes a replay miss, run with NOLA_RECORD=1 to record the new requests, review the ledger and commit it.

The feature-extraction, function-calling and typescript-interop templates include a nola.replay.jsonl ledger. If you skip provider setup, their config uses replay("./nola.replay.jsonl"), so npm start needs no API key.

The ledger matches the supplied example: src/main.tsi for feature-extraction and function-calling, or src/person.tsi for typescript-interop. Changes to its requests can cause replay misses. Follow the config’s comment to switch to a live provider, or record a new ledger.

Next: The nola CLI