Package-level declarations

The whole public API: the question DSL, typed answers, the client, configuration and errors.

Types

Link copied to clipboard
sealed interface Answer

A typed answer to one question.

Link copied to clipboard
expect class BlockingJev

JevApi as blocking calls, for scripts, main, and tests, reached through JevClient.blocking, or blocking for any other JevApi.

actual class BlockingJev

JevApi as blocking calls, for scripts, main, and tests. Every call declares InterruptedException, which runBlocking throws when the waiting thread is interrupted, so Java code can catch it.

actual class BlockingJev

Blocking calls are JVM-only; on Kotlin/Native, call the suspend API, wrapped in runBlocking if need be.

actual class BlockingJev

Blocking calls are JVM-only; on Kotlin/JS and Kotlin/Wasm, call the suspend API.

Link copied to clipboard
data class BoundingBox(val top: Double, val bottom: Double, val left: Double, val right: Double)

Where a Box found its target. Each edge is a fraction, from 0 to 1, of the image's height (top, bottom) or width (left, right), measured from the top-left corner, so the same box fits the image at any size.

Link copied to clipboard
data class BoxAnswer(val box: BoundingBox, val confidence: Double?) : Answer

The answer to a Box: the box around the target, and a confidence from 0 to 1, or null when the API reports none. A Box always answers with a box, even when the target isn't in the image.

Link copied to clipboard
data class BoxQuestion(val instructions: JsonElement) : Question

Find one thing in an image: the answer is a BoxAnswer, the box around it. Box takes no criteria, and needs an image attached to the request. It always returns a box, even for a target that isn't there, so ask a Noul too. Box needs Jev 1.14 (jev-preview or jev-1.14.0).

Link copied to clipboard
data class ChoiceAnswer<K : Any>(val choice: K, val probabilities: Map<K, Double>, val confidence: Double) : Answer

The answer to a Choice: the highest-probability option, the probability of every option, and a confidence from 0 to 1. Confidence is not the winner's probability, but it depends on nothing else: it rescales that probability so that an even split across the options is 0 and certainty is 1. A close runner-up therefore shows only in probabilities; compare the top two entries of ranked to catch a near-tie.

Link copied to clipboard

A Choice's options, in order. Option keys and descriptions are both sent to the model.

Link copied to clipboard
data class ChoiceQuestion(val instructions: JsonElement, val options: Map<String, JsonElement>) : Question

Pick one of options, in order; a JsonNull description sends the option undescribed.

Link copied to clipboard
@RequiresOptIn(level = RequiresOptIn.Level.ERROR, message = "TypeSafe's images and Box questions are experimental; this API can change in any jev4k release")
annotation class ExperimentalJevImages

Marks jev4k's support for TypeSafe's images and Box questions. TypeSafe calls both "Dreamer-ready": the request format, the answers and the limits can change between its releases, so this API can change in any jev4k release. Opting in also stands for what TypeSafe's TypeSafe-Danger-Zone-Images: true header does: jev4k sends that header with every request that carries an image or a Box question.

Link copied to clipboard
interface JevApi

The Jev API. evaluate is the only call that sends questions; query and ask are conveniences on top of it, so application code that depends on JevApi can be tested with a fake or mock.

Link copied to clipboard
open class JevApiException(val status: Int, val body: String?, headers: Map<String, List<String>>, val requestId: String?, val endpoint: String, message: String, cause: Throwable? = null) : JevException

The API answered with an error, or with a body jev4k couldn't use. body is the raw response body, requestId the x-typesafe-request-id header, and endpoint the method and URL called.

Link copied to clipboard

401: the API key is missing or invalid.

Link copied to clipboard

400: the request was malformed.

Link copied to clipboard

Settings for single calls that override the client's own, as both official SDKs allow:

Link copied to clipboard

Builder for JevCallOptions. Every setting starts unset, which keeps the client's value. build reports every problem it finds at once, as JevConfigBuilder.build does.

Link copied to clipboard
class JevClient(val config: JevConfig) : JevApi, AutoCloseable

A Jev client over Ktor, on the platform's default engine (CIO on the JVM) unless one is supplied. Configure it inline, or rely on TYPESAFE_API_KEY:

Link copied to clipboard
class JevConfig

Resolved client settings. Build one with JevConfigBuilder or the JevClient { } constructor.

Link copied to clipboard

Builder for JevConfig. Each setting resolves as: explicit value, then environment variable, then default. String settings are trimmed, and a leading byte-order mark is dropped, so the trailing newline or the mark of a value read from a file is harmless, and a value that is blank after trimming counts as unset. build fails on a missing API key first, on its own, and otherwise reports every problem it finds at once, without echoing a secret.

Link copied to clipboard

The client could not be configured, e.g. no API key was supplied.

Link copied to clipboard
open class JevConnectionException(message: String, cause: Throwable? = null) : JevException

No complete HTTP response was received (DNS, TLS, a refused or dropped connection, a truncated body).

Link copied to clipboard

Environment variable names, defaults, and header names shared with the official TypeSafe SDKs.

Link copied to clipboard
annotation class JevDsl

Marks jev4k's DSL receivers so nested builder lambdas can't call an outer builder by accident.

Link copied to clipboard
sealed class JevException(message: String, cause: Throwable? = null) : RuntimeException

Base class for every error raised by jev4k.

Link copied to clipboard
@Serializable(with = JevImageSerializer::class)
class JevImage

A PNG or JPEG image to send with a request.

Link copied to clipboard

5xx: a server-side failure.

Link copied to clipboard

404: unknown endpoint or resource.

Link copied to clipboard
interface JevOption

Optional metadata for enum constants used as Choice options. By default an option's key is the constant's name and it is sent undescribed.

Link copied to clipboard

529: TypeSafe is temporarily overloaded.

Link copied to clipboard

403: the API key may not do this.

Link copied to clipboard
abstract class JevQuery

A reusable set of questions declared as properties; each property name becomes the question id.

Link copied to clipboard

429: rate limited. retryAfter is the server's hint, when it sent one.

Link copied to clipboard
class JevResponseValidationException(detail: String, val fieldPath: String?, body: String?, requestId: String?, endpoint: String, status: Int = 200, headers: Map<String, List<String>> = emptyMap(), cause: Throwable? = null) : JevApiException

A successful response was missing data or didn't match the questions asked; fieldPath locates the problem.

Link copied to clipboard
class JevResult

The answers to one request. Read them with the handles you declared (result[Triage.department]) or by id (result.noul("urgent")). A missing or mismatched answer raises JevResponseValidationException when it is read; an id or handle that wasn't part of the request raises IllegalArgumentException.

Link copied to clipboard

A request attempt timed out: the configured timeout, or, with a caller-supplied engine, that engine's own connect or socket timeout, which the message then names.

Link copied to clipboard

422: the request failed server-side validation; body names the offending field.

Link copied to clipboard
class JevValidationException(val problems: List<String>, cause: Throwable? = null) : JevException

A request was rejected locally, before anything was sent. problems lists every issue found.

Link copied to clipboard
data class ModelInfo(val name: String, val description: String?, val releaseDate: String?)

One entry from GET /v1/models.

Link copied to clipboard
class ModelList(models: List<ModelInfo>, val requestId: String? = null) : List<ModelInfo>

What GET /v1/models returned: the models, in the server's order, as a List<ModelInfo>, plus the call's requestId (the x-typesafe-request-id header). It equals any list holding the same models, whatever its request id, so a test can compare it with listOf(...).

Link copied to clipboard
data class NoulAnswer(val noul: Double) : Answer

The answer to a Noul: noul is the probability, from 0 to 1, that the answer is yes. Nouls have no confidence.

Link copied to clipboard
Link copied to clipboard

Optional descriptions of what a Noul's yes and no mean.

Link copied to clipboard
data class NoulQuestion(val instructions: JsonElement, val whenTrue: JsonElement? = null, val whenFalse: JsonElement? = null) : Question

A yes/no question; whenTrue and whenFalse optionally define what yes and no mean.

Link copied to clipboard

Collects the questions for one request, keyed by ids you choose. Every function returns a QuestionRef handle, so val urgent = noul(...) then result[urgent] works too.

Link copied to clipboard
sealed interface Question

What one question asks, independent of its id: instructions plus criteria, each arbitrary JSON (usually a string). Named after the TypeSafe JS SDK's Question / NoulQuestion / ChoiceQuestion / ScoreQuestion. A QuestionRef pairs one with an id.

Link copied to clipboard

Creates a question when it is bound to a JevQuery property, using the property name as the default id.

Link copied to clipboard
class QuestionRef<out A : Answer>

A handle to one question. The same handle reads its typed answer back from a JevResult, and it can be used as a property delegate so val urgent by noul(...) works in a JevQuery.

Link copied to clipboard

An ordered, validated set of questions: everything one request asks about a single state.

Link copied to clipboard
data class RetryPolicy(val maxRetries: Int = 2, val initialBackoff: Duration = 500.milliseconds, val maxBackoff: Duration = 5.seconds, val jitter: Double = 0.25, val retryStatuses: Set<Int> = DEFAULT_RETRY_STATUSES, val respectRetryAfter: Boolean = true, val maxRetryAfter: Duration = 60.seconds, val retryOnConnectionError: Boolean = true, val retryOnTimeout: Boolean = true)

When and how failed requests are retried. The defaults match the official JS SDK: two retries, 0.5 s backoff doubling to a 5 s cap with up to 25% subtracted as jitter, and server retry-after-ms / Retry-After hints honored up to maxRetryAfter. The Python SDK shares the retries, backoff and statuses but doesn't cap hints, and adds a 30 s budget per call, which jev4k doesn't have: timeout applies per attempt.

Link copied to clipboard
data class ScoreAnswer(val score: Double, val probabilities: Map<Int, Double>, val legend: Map<Int, JsonElement>, val confidence: Double, val levelCount: Int) : Answer

The answer to a Score: score is the probability-weighted level (Σ level × p), so it can fall between levels. probabilities and legend are keyed by level number; the legend holds the level entries that were sent. levelCount is the number of levels asked about.

Link copied to clipboard

A Score's levels, lowest first. Describe situations, not degrees; each level is judged on its own.

Link copied to clipboard
data class ScoreQuestion(val instructions: JsonElement, val levels: List<JsonElement>) : Question

Rate along ordered levels; a level's number is its index.

Link copied to clipboard
data class UnknownAnswer(val type: String?, val raw: JsonObject) : Answer

An answer of a type this version of jev4k doesn't know; raw is the answer object as received.

Link copied to clipboard
data class Usage(val inputTokens: Long?, val outputTokens: Long?)

Token counts reported by the API; either may be absent.

Properties

Link copied to clipboard
const val MAX_CHOICE_OPTIONS: Int = 255

Most options a Choice may offer.

Link copied to clipboard
const val MAX_SCORE_LEVELS: Int = 10

Most levels a Score may have.

Link copied to clipboard
const val MIN_SCORE_LEVELS: Int = 2

Fewest levels a Score may have.

Functions

Link copied to clipboard
inline suspend fun <T : Any> JevApi.ask(query: JevQuery, state: T, model: String? = null): JevResult

Asks a JevQuery's questions about a @Serializable state.

suspend fun JevApi.ask(query: JevQuery, state: String, model: String? = null): JevResult

Asks a JevQuery's questions about a text state.

suspend fun JevApi.ask(query: JevQuery, state: JsonElement, model: String? = null): JevResult

Asks a JevQuery's questions about a JSON state.

inline suspend fun <T : Any> JevApi.ask(query: JevQuery, state: T, vararg images: JevImage, model: String? = null): JevResult

Asks a JevQuery's questions about a @Serializable state, with images attached after the query's own.

suspend fun JevApi.ask(query: JevQuery, state: String, vararg images: JevImage, model: String? = null): JevResult

Asks a JevQuery's questions about a text state, with images attached after the query's own.

suspend fun JevApi.ask(query: JevQuery, state: JsonElement, vararg images: JevImage, model: String? = null): JevResult

Asks a JevQuery's questions about a JSON state, with images attached after the query's own.

Link copied to clipboard

This API as blocking calls, for code that depends on a JevApi rather than a JevClient, so a fake or a withOptions view can be handed in. From Java: BlockingJevKt.blocking(api). The calls exist on the JVM only.

Link copied to clipboard
fun entry(vararg fields: Pair<String, Any?>): JsonObject

Builds a structured JSON entry for instructions, option descriptions, or levels, e.g. entry("question" to "Which team?", "focus" to "The primary request"). Keys keep their order, and the model sees both the keys and the values.

Link copied to clipboard
fun jevApiException(status: Int, body: String? = null, requestId: String? = null, headers: Map<String, List<String>> = emptyMap(), retryAfter: Duration? = null): JevApiException

The JevApiException subclass the client raises for HTTP status, for testing a caller's error handling: 429 gives a JevRateLimitException, 401 a JevAuthenticationException, and so on.

Link copied to clipboard
fun jevResult(body: String, questions: QuestionSet, model: String = JevDefaults.MODEL, requestId: String? = null): JevResult

The same, from the response body as JSON text. Text that isn't JSON, or isn't a JSON object, raises JevResponseValidationException, as it does from the client, so a garbled response can be simulated too. A leading byte-order mark is dropped, as the client drops one.

fun jevResult(body: JsonObject, questions: QuestionSet, model: String = JevDefaults.MODEL, requestId: String? = null): JevResult

A JevResult built from a raw response body, as JevApi.evaluate would have returned it for questions.

Link copied to clipboard
inline fun <T> jsonEntry(value: T): JsonElement

Encodes a @Serializable value as JSON, keeping fields that equal their defaults.

Link copied to clipboard
fun jsonOf(value: Any?): JsonElement

Converts plain Kotlin values (null, strings, numbers, booleans, enums, maps with string keys, iterables, arrays, primitive arrays such as IntArray, JSON elements, and JevImages, as their reference) to JSON. Use jsonEntry for @Serializable values.

Link copied to clipboard
inline suspend fun <T : Any> JevApi.query(state: T, model: String? = null, noinline block: QueryBuilder.() -> Unit): JevResult

Asks inline questions about a @Serializable state.

suspend fun JevApi.query(state: String, model: String? = null, block: QueryBuilder.() -> Unit): JevResult

Asks inline questions about a text state.

suspend fun JevApi.query(state: JsonElement, model: String? = null, block: QueryBuilder.() -> Unit): JevResult

Asks inline questions about a JSON state.

Link copied to clipboard

Builds a validated QuestionSet inline.

Link copied to clipboard
fun JevImage.Companion.read(file: File, reference: String? = null): JevImage

An image read now from file, with the same limit.

fun JevImage.Companion.read(path: Path, reference: String? = null): JevImage

An image read now from path. A file over the API's 16 MiB limit isn't read: the image carries that problem instead. These are Kotlin extensions on the companion; from Java, which would have to pass the companion explicitly, write JevImage.of(Files.readAllBytes(path)).

Link copied to clipboard
fun rubric(what: String, notFor: String? = null, examples: List<String> = emptyList()): JsonObject

A contrastive option or level description, {"what", "not_for", "examples"}, the shape the TypeSafe docs use to sharpen boundaries between similar options.

Link copied to clipboard

This API with options applied to every call, including those made through query, ask and blocking. Options passed to a call on the result are merged over options.