jev4k¶
A Kotlin DSL and client for TypeSafe's Jev model.
Jev is a System One model: fast, calibrated judgments instead of generated text. You give it a state (a message, a document, a record) and a set of typed questions, and it returns typed answers with probabilities your code can branch on, sort by, and threshold.
jev4k lets you declare those questions in Kotlin, send them in one request, and read the answers back as
typed values, down to enum-valued choices that work with an exhaustive when.
object FirstTriage : JevQuery() {
val urgent by noul("Does this message convey urgency or time-sensitivity?")
val team by choice<Team>("Which team should handle this message?")
val frustration by score("How frustrated does the customer appear?") {
levels("Calm, just stating facts", "Frustrated but civil", "Very angry, strong language")
}
}
suspend fun routeTicket(
jev: JevApi,
ticket: String,
): String {
val result = jev.ask(FirstTriage, state = ticket)
val queue =
when (result[FirstTriage.team].choice) {
Team.BILLING -> "billing"
Team.TECHNICAL -> "engineering"
Team.SALES -> "sales"
}
val priority = if (result[FirstTriage.urgent].isTrue(threshold = 0.7)) "high" else "normal"
return "$queue ($priority)"
}
How it works¶
graph TD
S[State: text, JSON, or @Serializable] --> R
Q[Questions: Noul, Choice, Score, and the experimental Box] --> R
R[jev.ask / jev.query] -->|one HTTP request| J[Jev]
J -->|typed answers + probabilities| A[JevResult]
A --> C[Your code: branch, rank, threshold, escalate]
- Declare questions with the inline DSL or as a reusable, typed
JevQuery. - Ask them about a state in one request. Jev answers every question in parallel, in about 100 ms.
- Read typed answers: a probability for a Noul, an option (or enum constant) for a Choice, a position on your levels for a Score, each with the probabilities behind it.
- Decide in code. Control flow, arithmetic, thresholds and side effects stay in your program.
Kinds of question¶
| Question | Asks | Answer |
|---|---|---|
| Noul | Is this true? | noul: the probability of yes, 0 to 1 |
| Choice | Which of these options? | choice, a probability per option, confidence |
| Score | Where on these ordered levels? | score (can fall between levels), per-level probabilities, confidence |
| Box | Where is this in an image? | box: four edges as fractions; experimental |
Features¶
- Two DSL styles: quick inline queries with string ids, or reusable typed queries whose property names become question ids.
- Typed enum choices:
choice<Team>()answers with aTeam, so the compiler checks every branch. - Structured criteria: contrastive rubrics, examples, and JSON field specs in instructions and options.
- Any state: text, JSON, or any
@Serializablevalue. - Images and Box (experimental): PNG and JPEG images in the state, instructions and criteria, and Box questions that find where something is, on the Images & Box page.
- Suspend-first client on Ktor, with a blocking mirror on the JVM for scripts and
main. - Multiplatform: the JVM, Apple platforms, Linux, Windows, and Node.js, with the same API on every one.
- SDK-parity retries: the official JS SDK's retry rules, including server
Retry-Afterhints. - Validation before sending: every problem with a request is reported at once, without a network call.
-
Quick Start
Set an API key and run your first query in a few lines.
-
Concepts
State, questions, answers, and what calibrated confidence means.
-
Patterns
Routing, composite scoring, verification, extraction, ranking, and guardrails.
-
Writing Good Questions
The habits that make Jev's answers accurate and useful.
-
The Jev Docs
TypeSafe's own documentation: concepts, primitives, and cookbooks.
-
API Reference
Every public type and function, generated from the source by Dokka.
Thanks to TypeSafe¶
Jev, and the System One idea behind it, come from TypeSafe, who have done a great job with both. Their documentation at docs.typesafe.ai is excellent. jev4k follows Jev's concepts and naming, so what you learn there carries straight over to this library.