Skip to content

Classification

Use a union or enum when a classification must belong to a fixed set of labels. Nola derives a JSON Schema enum from the type and validates the answer against it. If the model returns a different label, the correction retry includes the allowed values.

src/classify.tsi
export type Category = "billing" | "refund" | "fraud" | "other";
export enum Sentiment {
Positive = "positive",
Neutral = "neutral",
Negative = "negative",
}
export infer function classifyMessage(.message: string) {
const category = ask `the category of the customer message`: Category;
const sentiment = ask `the overall sentiment of the message`: Sentiment;
const urgent = ask `does the message need urgent attention`: "yes" | "no";
return { category, sentiment, urgent: urgent === "yes" };
}
  • A string-literal union alias, such as Category, gives a reusable name to the label set.
  • A string enum, such as Sentiment, also provides runtime members such as Sentiment.Negative.
  • An inline union, such as : "yes" | "no", works for a label set used in one place. This example converts the answer to a boolean.

All three asks receive .message from the function’s contextual parameter.

src/main.ts
import { classifyMessage, Sentiment } from "./classify.tsi";
const result = await classifyMessage("I was charged twice for order #4711 and nobody answers the phone.");
if (result.category === "fraud" || (result.sentiment === Sentiment.Negative && result.urgent)) {
console.log("escalate", result);
} else {
console.log("queue", result);
}

The returned labels retain their TypeScript types, so you can compare them in ordinary application code.

You can ask for a confidence estimate and an explanation after choosing a category:

src/classify-confident.tsi
export type Category = "billing" | "refund" | "fraud" | "other";
export infer function classifyWithConfidence(.message: string) {
const category = ask `the category of the customer message`: Category;
const confidence = ask `how confident is the "${category}" classification, from 0 to 1`: number;
const rationale = ask `one sentence explaining why the message is "${category}"`: string;
return { category, confidence, rationale };
}

All three asks share the contextual parameters. Earlier answers are not added automatically: the second and third asks receive category because their prompts interpolate it with ${}. See The ask operator.

The confidence here is a generated estimate, not a calibrated probability. Its number type also does not enforce the requested 0–1 range. For probabilities supplied by a model with decision support, see Decision types.

Nola does not currently support a separate description for each union or enum variant. Put label guidance in a JSDoc comment on the alias or in the instruction text.

Next: Function calling