Config schema
defineConfig(config) provides type checking and returns the config unchanged. Nola validates and freezes it when it loads. The table below lists the supported settings.
| Key | Type | Default | Invalid → | Read by |
|---|---|---|---|---|
model |
ModelConfigInput | ({ default: ModelConfigInput } & Record<string, ModelConfigInput>) — a bare model is { default }; the string "nola" is the platform model (short for nola.infer()), legal only as the bare value or the map’s default |
— (required) | NOLA3003 — neither a model nor an object; a map missing default; an entry missing name or infer() (a complete()-only model is the retired chat form and the error names the migration); any string other than "nola"; the platform model nested anywhere but the root |
runtime — every ask |
project |
non-empty string — names this app in traces and platform requests; never part of the ask fingerprint |
the nearest package.json name, walking up from the working directory (unset when none exists) |
NOLA3003 — empty or non-string |
trace envelopes and managed infer requests — the console groups runs by it |
forceModel |
string naming a key of the model map |
unset | NOLA3004 |
runtime — overrides every ask-site pin |
telemetry |
{ level?: NolaLogLevel } | NolaTelemetry | string | (NolaTelemetry | string)[] — { level } is the terminal alone (terminalTrace({ level })); an observer or a list replaces it (terminalTrace(...), nola.tracer(...), an http(s) URL string as the alias of nola.tracer(url), or an object with any of onAskStart, onProviderRequest, onProviderResponse, onValidationFailed, onRetry, onAskEnd, onInvocationStart, onInvocationEnd) |
{} — the terminal at debug |
NOLA3003 — a bad level; an unknown terminal option; an entry that is not an object with an on* method; a string that is not an http(s) URL; hooks (removed) |
runtime — every entry gets every event in list order; NOLA_TRACING_URL appends a tracer |
middleware |
NolaMiddleware[] (functions) |
[] |
NOLA3003 |
validated, but currently has no effect; the ask path calls the provider directly |
cache |
{} or { store: NolaCacheStore } |
unset ({} → in-memory store) |
NOLA3006 |
validated, but currently has no effect |
system.message |
string |
unset | NOLA3003 |
runtime — replaces the default system text of every ask (DEFAULT_SYSTEM from @nola-lang/providers to compose) |
ask.timeoutMs |
non-negative finite number (ms); 0 disables |
60000 |
NOLA3003 — also for unknown keys under ask |
runtime — per-invocation timeout |
compiler.underivableContextType |
"error" | "prune" | "omit" — keep it a literal |
"error" |
NOLA3003 |
nola build / nola check / the loader / the editor — never the runtime |
build.target |
"app" | "lib" |
"app" |
NOLA3003 |
nola build only |
plugins |
reserved | — | NOLA3005 — rejected at load |
— |
Nola also raises NOLA3003 if the config is not an object, contains an unknown top-level key or is changed after the first ask. Unknown-key messages list the allowed keys; hooks points to its replacement, telemetry. In tests, call nolaRuntime.reset() before configuring the runtime again.
Resolved shape
Section titled “Resolved shape”After loading, the runtime holds a frozen ResolvedNolaConfig:
modelis always a map; a single model becomes{ default }.project?andforceModel?retain their resolved values.telemetryis an observer array. Terminal settings have been converted toterminalTrace(), and theNOLA_TRACING_URLtracer has been appended when applicable.middlewareis a frozen array. Ifcacheis configured, it has a concrete store.system?remains optional. Defaults are filled in forask.timeoutMs,compiler.underivableContextTypeandbuild.target.
@nola-lang/runtime exports NolaConfig, NolaTelemetry, NolaMiddleware, NolaLogLevel, LanguageModel, ModelConfigEntry and ModelConfigInput. It also exports defineConfig, resolveNolaConfig, resolveCompilerConfig and resolveBuildConfig.
ModelConfigInput accepts a model instance or the string "nola". NolaCacheStore is not re-exported; cache settings are validated but currently have no effect.
import { mockProvider, openai } from "@nola-lang/providers";import { defineConfig, terminalTrace } from "@nola-lang/runtime";
export default defineConfig({ model: { default: openai({ model: "gpt-5-mini" }), mock: mockProvider(() => ({ ok: true })), }, forceModel: process.env.CI ? "mock" : undefined, telemetry: [terminalTrace({ level: "info" }), { name: "audit", onAskEnd: ({ receipt }) => console.log(receipt.site, receipt.servedBy) }], // or just { level: "info" } system: { message: "Answer in British English." }, ask: { timeoutMs: 60_000 }, compiler: { underivableContextType: "error" }, build: { target: "app" },});Next: Error codes