triage-ticket
Ticket triage on typesafe.ai’s Jev, a model that is not a chat model. Its API answers typed questions about a state — which option? is this true? — with calibrated probabilities, so the typesafe() provider serves exactly the asks whose output type it can express: a string literal union (Department) becomes a choice question with one option per value, a number literal union (Priority) a choice question decoded back to the number, a boolean (urgent, refundRequested) a yes/no question that is true at probability ≥ 0.5, and a flat object of those (Triage) one request with one question per property. The JSDoc comment on each property is that question’s instructions.
export type Department = "billing" | "shipping" | "account" | "other";export type Priority = 1 | 2 | 3;
export interface Triage { /** Which team owns this ticket? */ department: Department; /** Does the customer express urgency? */ urgent: boolean; /** 1 = low, 3 = high */ priority: Priority; /** Is the customer asking for a refund? */ refundRequested: boolean;}
export infer function triageTicket(.ticket: string) { return ask ..`triage the support ticket`<Triage>;}Free text, numbers, arrays and nested objects are not served: the provider fails before the network with an error naming the property, so a mixed project pairs it with a general model through fallback([typesafe(), openai("gpt-5-mini")]) — see Providers API.
Run it
Section titled “Run it”This is the one example whose committed config names a live vendor (model: typesafe()), because the vendor is the point. Put TYPESAFE_API_KEY=… in .env first.
npx nola-lang run src/main.ts # needs TYPESAFE_API_KEY# offline: edit nola.config.ts to the mockProvider line in its commentScaffold: npm create nola my-app -- --template triage-ticket — the scaffolder skips the Select an inference provider: question for this template and its next steps say to set the key.
Source: examples/triage-ticket on GitHub.
Next: Introduction — back to the start.