Skip to content

classify-message

Classification against closed label sets, in all three native TS forms: a string-literal union alias (Category), a string enum (Sentiment — a runtime value too, so consumers compare with Sentiment.Negative), and an inline union (<"yes" | "no">) mapped to a boolean in plain TS. Each lowers to a JSON Schema enum, is enforced by the provider’s structured outputs and re-validated by the runtime — a wrong label triggers a correction retry that lists the allowed values. The label set is the TypeScript type you already have; per-label descriptions (a hint attached to each variant) have no Nola equivalent yet.

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" };
}
Terminal window
npx nola run src/main.ts # mock provider (deterministic)
# real provider: edit nola.config.ts to openai({ model: "gpt-5-mini" }) (needs OPENAI_API_KEY)

Scaffold: npm create nola my-app -- --template classify-message Source: examples/classify-message on GitHub. The full walkthrough is Classification.

Next: Introduction — back to the start.