Nola 0.1.14: context statements
Nola 0.1.14: context statements
Evgen MykhailenkoSeptember 30, 2026
- release
- Context statements. Give the model instructions anywhere in your code, and show it live values from your program.
- Colon types. Type an ask the same way you type a variable: `` ask `the ticket id`: string ``.
- Simpler function calls. Let the model fill in a function’s arguments without the `..` prefix.
- A prompt you can read. The model gets your own words in four plain tags, and nothing else.
- A new starter. `npm create nola` now includes a small agent in a single file.
- Better debugging. Breakpoints stop where you put them.
Welcome to Nola 0.1.14. Here are the new features and improvements we think you’ll like most:
A few older forms were removed along the way. If you are coming from 0.1.13, read Upgrading before you update.
Language
Context statements
Until now, a function or a file could carry a single instruction for the model. Real programs need more: different guidance at different points, and a way to show the model what the program has worked out so far.
In this release, any template literal on a line of its own, in an infer function or at the top level of a file, is a context statement. Every `ask` below it sees the text. Add a value after the text, and the model sees that value as it is at the moment of the ask.
`You triage a support inbox. Suggest one step at a time.`
const .ticket = "Since yesterday our nightly export job fails with \"disk quota exceeded\".";const steps: string[] = [];`Steps taken so far:` steps;
while (steps.length < 3) { `Answer "done" when nothing is left to do.`
const next = ask `the next step`: string;
if (next === "done") break;
steps.push(next);}
console.log(steps);Each time the loop asks, the model sees the current list of steps. There is no prompt string to rebuild and no history to manage. You update the array, and the next ask sees it.
A few things worth knowing:
Prefer `${…}`? It now works in every instruction. `` `Page ${oncall} first.` `` and `` `Page` oncall `first.` `` mean the same thing.
Read more in Context statements.
Type an ask with a colon
You can now write the type of an ask after a colon, the way you annotate a variable:
const .message = "Hi, I'm Ada Lovelace. I'm 36 and I work as a mathematician.";
const name = ask `the person's name`: string;const age = ask `the person's age`: number;
console.log(name, age);The angle-bracket form, `` ask `the person's name`<string> ``, still works and means exactly the same, so your existing code needs no change. The docs, the examples and the editor snippets use the colon from now on.
Keep the angle brackets when you chain a method straight off the ask, as in `` ask `the person's name`<string>.withRetry(2) ``.
Function calls without the dots
When you ask the model to fill in a function’s arguments, you no longer need the `..` prefix on each one. Write the prompt and its type right where the value would go:
const .request = "Checkout shows a blank page after paying, and I was charged twice.";
function createTicket(title: string, priority: number) { console.log(`[p${priority}] ${title}`);}
ask createTicket( `a short ticket title`: string, `priority 1-5, where 1 is most urgent`: number,);The model fills in both arguments, and then `createTicket` runs with them. You can pass ordinary values too: `` ask createTicket(`a short ticket title`: string, 2) `` asks the model for the title only. Code that uses the dots keeps working.
A prompt you can read
Nola no longer adds wording of its own to your prompt. The model receives the text you wrote, wrapped in four tags that say what each part is:
| Tag | What it holds | | ------------ | ------------------------------------------------------------- | | <context> | One function or file: its context statements, then its inputs | | <input> | One .param or const .x value, by name | | <task> | The ask itself | | <correction> | What was wrong with a rejected reply, when Nola retries |
Here is what the third ask of the triage loop above sends:
<context module="src/triage.tsi">You triage a support inbox. Suggest one step at a time.Steps taken so far: ["check the disk quota on the export host","clear last month's export archives"]Answer "done" when nothing is left to do.<input name="ticket">Since yesterday our nightly export job fails with "disk quota exceeded".</input></context>
<task>the next step</task>That is the whole message. The answer’s type is not in it, because it travels through the provider’s structured output instead. The system message is four short sentences, and you can replace them with `system.message` in `nola.config.ts`.
If your server cannot enforce a schema, set `structuredOutputs: false` on the provider, and Nola writes the schema into the system message.
The prompt has more examples.
Tooling
A new starter: the agent loop
`npm create nola` now opens with five ready-made examples and an empty project. The new one, `agent-loop`, is a small agent in a single file: a `while` loop that keeps asking until the model answers `null`, with a context statement that shows the model what it has found so far. It runs offline on a mock provider, so you can try it without an API key.
Two smaller changes: the empty template now starts you in `src/main.tsi`, and example templates are downloaded from GitHub when you pick one, so you need to be online to scaffold them.
`nola run` exits like `node`
`nola run` now ends when your program is done, the way `node` does. A script that starts a server keeps running, and the last traces reach the console before the process exits.
Debugging
Editor
Completion lists and unused-variable warnings no longer show the `__nola` names that Nola generates. The VS Code extension highlights colon types, and its snippets write the new forms.
Custom providers
If you maintain your own provider, there is now one method to implement: `infer`. It receives the ask as data. Call `renderPrompt` for the default prompt, send it to your backend, and return the reply:
import type { LanguageModel } from "@nola-lang/runtime";import { renderPrompt } from "@nola-lang/providers";
export const myProvider: LanguageModel = { name: "my-provider", async infer(req) { const sent = renderPrompt(req.intent); // { system, messages } const text = await callMyBackend(sent, req.intent.output, req.signal); return { text, sent }; },};Here `callMyBackend` stands for your own request code, and `req.intent.output` carries the schema of the answer. Return `sent`, and the receipt shows exactly what went out. Providers API has a complete example.
Upgrading
Update every Nola package to 0.1.14 together, then rebuild your project. Code built with 0.1.13 does not run on the new runtime.
Then look for these, which were removed in this release:
Everything else keeps working, including `<T>` types and `..` in call arguments.
Questions or feedback? Join us on Discord or open an issue on GitHub.
