infer functions
An infer function defines inference work that you can call from Nola or TypeScript. Calling it returns a lazy Intent<T> without running the body. Resolve the intent with ask from Nola or await from plain TypeScript to run it.
Two declaration forms
Section titled “Two declaration forms”infer function summarize(.text: string) { return ask `a one-sentence summary`: string;}
export infer function classify(.message: string) { return ask `the category of the message`: string;}Context statements
Section titled “Context statements”A template literal on its own line in the body is a context statement. Its text applies to every ask written after it in the invocation:
export infer function triage(.ticket: string) { `triage the ticket like a support lead` return ask `the severity: low, medium or high`: "low" | "medium" | "high";}It can continue with values — `Page` oncall `when the ticket is an outage.` — and you can write several, anywhere in the body; each is read at each ask, so a statement placed before a loop shows the current state on every pass. The rules, the line rules and what the model sees are on Context statements.
Two spellings put a value in front of the model, and they mean different things. A contextual parameter, .ticket, is data: it renders as an <input name="ticket"> block after the text, and the system turn tells the model that input blocks are data, not instructions. A value in a context statement, or a ${team} hole, is part of your words, rendered where it stands, and the model follows it as instructions. So interpolate only text you control, and pass anything you did not write yourself as a contextual parameter. See Contextual parameters and The prompt.
The module body takes the same statements — see ask at module level. A backtick literal between the function name and its parameters (infer function f`…`(…)) is reserved for a later version (NOLA1019).
-
Top-level function declarations only.
inferis a keyword only directly beforefunctionat statement or export position, soinferon a method, an arrow function or a function expression is a plain parse error (NOLA1001); aninfergenerator is reserved for a later version (NOLA1004); a declaration nested in another function isNOLA2003. -
Never
async.async infer functionis a parse error — an infer function is implicitly awaitable throughIntent. -
awaitis legal in the body, for ordinary promises: fetch, a database, any library.enrich.tsi export infer function enrich(.handle: string, fetchProfile: (h: string) => Promise<string>) {const profile = await fetchProfile(handle); // ordinary promisereturn ask `the person's job title from: ${profile}`: string;} -
askonly directly inside the body (or directly in the module body — see ask) — not inside a nested closure, not even one written inside the infer function (NOLA2001). -
Export by name.
export default infer functiondoes not parse; writeexport infer function f(…)and let consumers import the name.
Return type
Section titled “Return type”Nola can infer the return type from the body. If you want an explicit annotation, use Intent<T> where the body returns T, just as an async function uses Promise<T>.
import type { Intent } from "@nola-lang/runtime";
interface User { name: string;}
export infer function getUser(.message: string): Intent<User> { const user = ask `the user described in the message`: User; return user;}Do not annotate it Promise<T>: Intent<T> is PromiseLike<T>, not a Promise, so nola check reports TS2739 (missing catch, finally, [Symbol.toStringTag]).
Calling from plain TypeScript
Section titled “Calling from plain TypeScript”import { classify } from "./forms.tsi";import { triage } from "./triage.tsi";
const category = await classify("My card was charged twice.");const severity = await triage("Checkout is down for every customer in the EU.");console.log(category, severity);Awaiting the intent starts an invocation. Before resolving it, you can configure it with methods such as .withTimeout(ms), .detached() and .withModel(…). See Intent methods.
Next: Contextual parameters