Skip to content

Intent API

Askable<T> and Intent<T> describe the two kinds of intent. Both types are exported from @nola-lang/runtime. This page lists their methods; see Intents for how they work.

types.ts
import type { Askable, Intent } from "@nola-lang/runtime";
export type Extracted = Askable<string>;
export type Result = Intent<{ name: string }>;

Raw extractors (..`…`: T) and call intents have type Askable<T>. Resolve them with ask. A bare await throws NOLA3010, so the interface does not expose then.

T describes the result. It appears in the method return types without adding a property to the intent.

Method Returns Meaning
withRetry(retries: number) Askable<T> extra whole-ask attempts, flat, no backoff — unrelated to the provider-level withRetry combinator
withModel(model: ModelRef) Askable<T> route this ask through a configured name or a provider object
withParams(params: ProviderParams) Askable<T> request parameters, merged with those already on the intent
withTimeout(timeout: number) Askable<T> sets a timeout in ms for this intent’s provider calls; the invocation’s timeout still applies; 0 adds no timeout

Intent<T> extends Askable<T>, PromiseLike<T>

Section titled “Intent<T> extends Askable<T>, PromiseLike<T>”

An infer function returns a lazy Intent<T>. It can be resolved with ask or await and opens an inference frame when it starts. Its detached() method controls whether that frame inherits the caller’s context.

Method Returns Meaning
withRetry(retries: number) Intent<T> as above
withModel(model: ModelRef) Intent<T> as above
withParams(params: ProviderParams) Intent<T> as above
withTimeout(timeout: number) Intent<T> sets the invocation timeout in ms for a root intent (0 disables); adds its own timeout when asked inside another invocation
detached() Intent<T> resolve without inheriting the caller frame’s context
then(…) — PromiseLike<T>: await it from plain TypeScript

The configuration methods and detached() return a new intent without starting the original. Each intent resolves at most once. For an explicit infer-function return type, use Intent<T>. It implements PromiseLike<T>; annotating it as Promise<T> produces TS2739.

// not-checked — the shapes .withModel()/.withParams() accept (ModelRef is exported from @nola-lang/runtime; ProviderParams is not re-exported — use it structurally)
type ModelRef = LanguageModel | string;
interface ProviderParams {
temperature?: number;
maxOutputTokens?: number;
/** opaque provider-specific knobs, passed through untouched; JSON-serializable */
providerOptions?: Record<string, unknown>;
}

When you chain .withParams(), later fields override earlier ones and providerOptions merges by key. Nested frames follow the same rule, with the nearest value taking precedence. Params are part of the ask fingerprint.

guard.ts
import { isIntent } from "@nola-lang/runtime";
export const describe = (v: unknown) => (isIntent(v) ? "an intent" : "a plain value");

isIntent(v: unknown): v is Askable — a runtime type guard for any intent object (extractor, call intent, or infer-function result).

Next: Providers API