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] --> 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.
Three 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 |
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. - Suspend-first client on Ktor, with a blocking mirror for scripts and
main. - SDK-parity retries: the official SDKs' retry and timeout 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.