Skip to main content

jev_repl/
lessons.rs

1//! The guided track: eleven short lessons, each with one command to try.
2
3pub struct Lesson {
4    pub title: &'static str,
5    pub body: &'static [&'static str],
6    /// Dropped into the input line by Ctrl-T (or `:try`).
7    pub try_this: &'static str,
8}
9
10pub const LESSONS: &[Lesson] = &[
11    Lesson {
12        title: "State and questions",
13        body: &[
14            "jev answers System One questions: fast, typed judgements about a piece of state.",
15            "You send two things — a `state` (the text or JSON being judged) and a map of named questions — and get one answer per question back, under the same names.",
16            "Start with the state. Everything else in this session is asked about it.",
17        ],
18        try_this: ":state I've been trying to connect my Stripe account for 3 days and it keeps failing. I'm losing sales. Please help ASAP.",
19    },
20    Lesson {
21        title: "Noul: the probability of yes",
22        body: &[
23            "A noul is a yes/no question, but the answer is not a boolean — it is `noul`, the probability of yes, from 0 to 1.",
24            "Add one, then run `:ask` to send the whole session.",
25        ],
26        try_this: ":noul is_urgent The message conveys urgency or time-sensitivity",
27    },
28    Lesson {
29        title: "Thresholds, not booleans",
30        body: &[
31            "Because a noul is a probability, you pick the threshold: `answer.is_yes(0.8)` is a different product decision from `is_yes(0.5)`.",
32            "Pick the threshold from the cost of being wrong — a cheap auto-reply can run at 0.5, a refund cannot.",
33            "`:threshold 0.8` changes what this REPL calls a yes, so you can watch the same answer flip.",
34            "Once you know the number, keep it with the question: `@threshold 0.8` under a noul in `:sketch` travels with the page, and `jev eval --calibrate` writes one from labelled cases.",
35        ],
36        try_this: ":threshold 0.8",
37    },
38    Lesson {
39        title: "Choice: one of N",
40        body: &[
41            "A choice picks one label from a set you define. You get the winning `choice`, the probability of every label, and a `confidence` derived from the spread.",
42            "Options are `label=description`. The descriptions are instructions to the model, so they are worth writing well.",
43        ],
44        try_this: ":choice department Which team should handle this | billing=Payment or subscription issues | technical=Bugs or integration problems | sales=Pricing or account questions",
45    },
46    Lesson {
47        title: "Confidence gating",
48        body: &[
49            "Two labels at 0.48 and 0.47 have a winner, but not a decision. That is what `confidence` is for.",
50            "The useful shape is: act automatically above a confidence bar, route to a human below it. Never branch on the label alone.",
51            "Run `:ask` again and read the confidence line before the label.",
52        ],
53        try_this: ":ask",
54    },
55    Lesson {
56        title: "Score: ordered levels",
57        body: &[
58            "A score rates the state along levels you define, in order. The answer is probability-weighted, so it lands between levels: 1.4 means \"past level 1, not quite level 2\".",
59            "Level 0 is the first one you list. Keep them monotonic — one axis, low to high.",
60        ],
61        try_this: ":score frustration How frustrated the customer appears | Calm, just stating facts | Frustrated but civil | Very angry, strong language",
62    },
63    Lesson {
64        title: "Criteria sharpen the question",
65        body: &[
66            "Every question type takes criteria: `yes:`/`no:` for a noul, option descriptions for a choice, level descriptions for a score.",
67            "Vague criteria are the usual cause of a low-confidence answer. Say what a yes actually requires.",
68            "Instructions and criteria also accept JSON objects, for rubrics with structure: `:noul refund {\"task\": \"…\", \"ignore\": [\"signatures\"]}`.",
69            "If the pipes are a lot to remember, `:build` opens the same question as a form with the JSON beside it.",
70        ],
71        try_this: ":noul is_urgent The message conveys urgency | yes: Explicit deadline, or money being lost right now | no: Routine question with no time pressure",
72    },
73    Lesson {
74        title: "The wire format",
75        body: &[
76            "`:json` prints the exact body this session POSTs to /v1/systemone: your state, the model, and questions as name → {type, instructions, criteria}.",
77            "Answers come back keyed by the same names, which is why names are yours to choose and worth keeping stable.",
78            "`:last` prints the last response body verbatim, next to the typed answers the SDK decoded from it.",
79        ],
80        try_this: ":json",
81    },
82    Lesson {
83        title: "What a call costs",
84        body: &[
85            "Every question is paid for twice: once in the request that carries it, once in the answer it asks for. A choice over eight labels comes back with eight probabilities; a score echoes its whole legend.",
86            "`:cost` estimates both sides, per question, so an expensive question is visible before it is sent. The tokens are estimated from the body — the `usage` on a live answer is the counted truth.",
87            "Rates are yours to supply, in dollars per million tokens: `:cost 0.20/1.00`, or `JEV_PRICE=0.20/1.00` in the environment. Nothing here guesses what a model charges.",
88        ],
89        try_this: ":cost",
90    },
91    Lesson {
92        title: "Models and per-call options",
93        body: &[
94            "`jev-latest` is an alias that moves; pin a version when you need reproducibility.",
95            "`:models` lists what the account can use, `:model jev-2` switches this session, and `:timeout 3` changes the per-attempt timeout the way `.timeout()` does on a call.",
96            "Retries are on by default: 2 retries, exponential backoff, a 30 s budget, and Retry-After is honoured.",
97        ],
98        try_this: ":models",
99    },
100    Lesson {
101        title: "Out of the REPL",
102        body: &[
103            "`:rust` prints this session as a compiling program against this SDK — the same state, questions and model, with the answer lookups filled in.",
104            "That is the whole loop: shape the questions here where iterating is cheap, then paste the generated code into your service.",
105        ],
106        try_this: ":rust",
107    },
108];