These libraries are experimental. APIs may change without notice. Generated from source with koruc 0.1.7 on 10/5/2026.
Odds
@korulang/odds@0.0.1System One judgments as Koru tors — typed questions over a closed answer space, calibrated probabilities as branch payloads, decode policy as a phantom state
odds/index.kz · 16 tors· 1 internal
@koru/odds — System One judgments as Koru tors. · 28 more lines
@koru/odds — System One judgments as Koru tors.
A System One model (TypeSafe's Jev is the first) answers typed
questions over a CLOSED answer space and returns calibrated
probabilities — which is already the shape of a Koru tor: the
branch set IS the answer space, the payload IS the winner's
probability, `when` clauses ARE confidence gates, and the decode
policy IS a phantom state on the judge.
THE REFLECTION: a judgment tor's f64-payload branches ARE the
question's criteria, enumerated at comptime from @This().Output.
The answer space is declared exactly once — in the event
signature — and the API question is built by reflecting on it.
Pattern-named branches spell "[tag: description]": the tag is the
criteria key, the rest the description Jev reads. Non-f64 branches
(`exhausted`, `err`) are control flow, never criteria.
Backend: OpenRouter's Decisions API
(POST https://openrouter.ai/api/alpha/decisions, model
`typesafe/jev-1.13-20260917` — pinned, dated: `-latest` floats and a
gate must know which judge it is under), reached with std.http — no
package dependencies.
`gen` is deliberately a DIFFERENT category: System One models
cannot generate text, so revision goes to a chat-completions
model. The polish loop composes the two categories in one flow.
`gen` may migrate to @koru/ai when that package grows an
OpenRouter endpoint.
Phantom lifecycles
Derived from the phantom labels in the declarations below — state! issues an
obligation the compiler will chase, !state discharges it, a bare state holds it without moving it. Nothing here is hand-drawn.
Judge 2 states greedy!chaotic!// ── The judge resource ─────────────────────────────────────────────
//
// judge — issue a LIVE judge: budget judgments of fuel, backend is the
// Decisions API. Requires OPENROUTER_API_KEY in the environment.
~pub tor judge { budget: i32 } -> *Judge<greedy!>// chaos — flip to sampled mode. Consumes <greedy>, reissues <chaotic>.
~pub tor chaos { j: *Judge<!greedy> } -> *Judge<chaotic!>// settle — back to argmax. The two modes form a phantom cycle.
~pub tor settle { j: *Judge<!chaotic> } -> *Judge<greedy!>// retire — the discharge. Every issued judge must be retired, and
// the caller never spells it: retire is the sole spliceable disposer
// of <greedy> (void, no output — chaos returns a value and is never
// a candidate), so the emitter inserts the call at every scope exit.
~pub tor retire { j: *Judge<!greedy> }feels.map
index.kz:352// ── Judgments ──────────────────────────────────────────────────────
//
// Each judgment is split in two: `*.map` asks (one POST, fuel spent)
// and returns the WHOLE distribution as a `| map` payload; `*.pick`
// (greedy borrow) argmaxes it and `*.draw` (chaotic borrow) samples it
// — the decode is pure, free, repeatable. `feels`/`triage` and their
// chaotic twins are the same ask+decode composed as sugar.
//
// The judge on `map` is unphased: asking is mode-agnostic — the decode
// carries the policy, so a greedy judge picks and a chaotic one draws.
//
// feels.map — the binary ask, undecoded. `| map d` binds the whole
// distribution: d.yes / d.no are probabilities, d.confidence.* the
// API's per-choice confidence.
~pub tor feels.map { j: *Judge, text: string, question: string }
| map FeelsDist
| exhausted
| err Err// feels.pick — greedy decode over a fetched distribution.
~pub tor feels.pick { j: *Judge<greedy>, d: FeelsDist }
| yes f64
| no f64
| err Err// feels.draw — sampled decode over the same distribution.
~pub tor feels.draw { j: *Judge<chaotic>, d: FeelsDist }
| yes f64
| no f64
| err Errtriage.map
index.kz:391// triage.map — the multi-way ask, undecoded.
~pub tor triage.map { j: *Judge, text: string, question: string }
| map TriageDist
| exhausted
| err Err// triage.pick — greedy decode.
~pub tor triage.pick { j: *Judge<greedy>, d: TriageDist }
| bug: Bug reports f64
| feature: Feature requests f64
| other: Other messages f64
| err Err// triage.draw — sampled decode.
~pub tor triage.draw { j: *Judge<chaotic>, d: TriageDist }
| bug: Bug reports f64
| feature: Feature requests f64
| other: Other messages f64
| err Err// feels — binary judgment: | yes f64 | no f64 asks exactly that
// question — the branch names are the criteria keys. Sugar: map+pick.
~pub tor feels { j: *Judge<greedy>, text: string, question: string }
| yes f64
| no f64
| exhausted
| err Err// cfeels — same question, sampled. Only a <chaotic> judge can be asked.
// Sugar: map+draw.
~pub tor cfeels { j: *Judge<chaotic>, text: string, question: string }
| yes f64
| no f64
| exhausted
| err Err// triage — multi-way choice. The answer space lives ONLY in the type:
// each [tag: description] branch is one criterion — tag the key Jev
// answers with, description the text it reads to separate options.
// Proc, not sugar: `=>` branch ctors cannot spell a pattern name —
// `=> [bug: Bug reports] p` does not parse — so the subflow that
// would compose map+pick cannot construct these branches. FLOATED.
~pub tor triage { j: *Judge<greedy>, text: string, question: string }
| bug: Bug reports f64
| feature: Feature requests f64
| other: Other messages f64
| exhausted
| err Err// ctriage — same label set, sampled from the real distribution.
// Proc for the same reason as triage.
~pub tor ctriage { j: *Judge<chaotic>, text: string, question: string }
| bug: Bug reports f64
| feature: Feature requests f64
| other: Other messages f64
| exhausted
| err Err// gen — NOT a System One call. Judgment models cannot generate text;
// revision goes to a chat-completions model on the same key.
~pub tor gen { j: *Judge<greedy>, instruction: string, using: string }
| done string
| exhausted
| err Err~pub tor polish { j: *Judge<greedy>, draft: string }
| polished string
| exhausted