Use this page to look up Nola syntax and follow links to the full explanations. .tsi files support TypeScript, with the additions below and a few restrictions , including the reserved word ask.
Construct
Example
Page
infer function
infer function f(.text: string) { … }
infer functions
exported
export infer function f(.text: string) { … }
infer functions
with a context statement
export infer function f(.ticket: string) { `triage like a support lead` … }
context statements
a context statement with values
`Page` oncall `when the ticket is an outage.`
context statements
annotated return type
export infer function f(.m: string): Intent<User> { … } — never Promise<T>
infer functions
Construct
Example
Page
typed
ask `the ticket id`: string
Extractors
typed, angle-bracket spelling (the same construct)
ask `the ticket id`<string>
Extractors
untyped (free text, static any)
ask `think step by step`
Extractors
interpolation
ask `the person described in: ${text}`: Person
Extractors
constructed, not yet resolved
export const nameIntent = ..`the user's full name`: string;
Extractors
the .. spelling (required off the ask site and outside a call’s slots)
const i = ..`x`: T; fn(cond ? ..`x`: T : y)
Extractors
a decision question: choice
ask `Which team?`: Choice<{ billing: "Payments"; sales: null }>
Decision types
a decision question: scale
ask `How frustrated?`: Scale<["Calm", "Civil", "Angry"]>
Decision types
a decision question: probability
ask `Is it urgent?`: Prob
Decision types
Construct
Example
Page
resolve an askable
const x = ask intent;
The ask operator
another infer function
const r = ask otherFn(arg);
The ask operator
pin a provider
ask with fast `a rough summary`: string
The ask operator
chain a method (precedence like await)
ask (..`x`: string).withRetry(2)
Intent methods
from plain TS
const v = await f("…"); — never bare-await a raw extractor
The ask operator
Construct
Example
Page
sigil-less (the slot’s .. is implied)
ask createTicket(`a short title`: string, 2)
Call intents
empty marker
ask createTicket``("title", 3)
Call intents
hint marker
ask createTicket`file the ticket`(`a short title`: string, `priority 1-5`: number)
Call intents
Construct
Example
Page
a value as data (an <input> block)
infer function f(.t: string) { `Rules: …` … }
Contextual parameters
a value as part of your words (text you control)
infer function f(.t: string, team: string) { `Triage for the ${team} team. Rules: …` … }
The prompt
A value written after text in a context statement is the same as a ${} hole.
Method
On
Page
.withRetry(n) · .withModel(nameOrProvider) · .withParams({…}) · .withTimeout(ms)
every intent
Intent methods
.detached()
the intent an infer function returns
Intent methods
Construct
Example
Page
.ts importing .tsi
import { f } from "./x.tsi"; — literal extension
TypeScript interop
.tsi importing plain TS
import { g } from "./y.js"; — NodeNext specifier, file is y.ts
TypeScript interop
types from another file
import type { Person } from "./models.js";
TypeScript interop
import { createTicket } from "./tickets.js" ;
export type Severity = "low" | "medium" | "high" ;
export interface Person {
export const nameIntent = .. `the user's full name` : string ;
export infer function triage (.ticket: string , fallback : Severity ) {
`Triage the ticket. Rules: never invent ticket ids.`
const person = ask `the person described in the ticket` : Person ;
const severity = ask with careful `the severity of the ticket` : Severity ;
const id = ask createTicket ( `a short ticket title for ${ person . name } ` : string , 2 );
const name = ask nameIntent ;
return { person , severity: severity || fallback , id , name };
export async function createTicket ( title : string , priority : number ): Promise < string > {
return ` ${ title } : ${ priority } ` ;
These forms are not supported: async infer function, export default infer function, infer function f`…`(…) (the marker slot is reserved), infer on methods or arrows, fn(..), var .x = …, ..name on a parameter, and ask as an identifier. See Restrictions for details.
Avoid identifiers starting with __nola. The compiler uses that prefix in generated code; shadowing one can break the output without producing a diagnostic.
Next: Intent API