Skip to main content
@obversa/engine-jev-api asks Jev structured questions about state your run already recorded: should the writer run again, which stage should take it, how ready is this change to land. Each attempt is one Jev decision call over the TypeSafe API, and the answers come back as the structured result. Jev runs with workspace mode none; it never reads or edits files. It loads none of your own setup, so it always runs clean and has no clean option. Its row in the engines table says the same.

Install

Not in @obversa/obversa; install it on its own.

Requirements

  • A Jev endpoint and API key, passed as the endpoint and apiKey options. jev() also reads them from TYPESAFE_ENDPOINT and TYPESAFE_API_KEY.

Identity

The plugin reports provider: 'typesafe', with the model family read from the model name. It sends the model the request names, or model from its options, or jev-latest. If the API doesn’t echo a model, or echoes one that can’t be read, the recorded effective model and family are both null, and the answers are still returned.

Quickstart

Construct the engine with the endpoint and key, and ask it what it will run as, with no network call:
examples/engine-jev-api-binding.ts
admit returns the identity the engine reports before any request. Run it with npx tsx engine-jev-api-binding.ts:
Output
In a run, read the key from your environment instead of a literal. The result’s structured value is the answers object itself, so a binding’s parseResult reads part.value.send_back directly.

A seat for a team

In a workflow, jev() builds the seat in one line, as claude(model) does for Claude. It reads the endpoint and key from TYPESAFE_ENDPOINT and TYPESAFE_API_KEY, or from its endpoint and apiKey options. It throws when either is missing, and the message names both variables. The model defaults to jev-latest. The seat returns the answers object as assistant text, the JSON of that object, so an agentJob and the runtime’s judge read it as they read any seat’s reply. Offline, recordedJudge from @obversa/runtime/testing stands in for it and replays recorded answers from a JSON file:
examples/judge-stops-the-loop.ts (excerpt)

Ask a question

The prompt is a JSON document of the shape { state, questions }:
Request
state is whatever your run recorded. Each question names a type: noul (true or false), whose criteria say what true and false mean; choice, whose criteria map each option to its description; or score, whose criteria are the array of labels the score indexes. Before any network call, the adapter checks that the prompt parses to an object, that questions is a non-empty object, and that every question names one of the three types. A missing or null state is sent as an empty object; the adapter forwards criteria unchanged. The adapter returns the answer objects unchanged and doesn’t check their shape. What the provider has been seen to return: a noul answer carries a probability and no separate confidence; choice and score answers carry a confidence, and may carry probabilities. parseJevDocument reads a prompt into the request shape before it’s sent.

Options

Errors

  • invalid-config before any network call, for a malformed prompt or a request field Jev can’t take: system or systemMode (Jev carries no system prompt), env (the key comes from the option), maxTokens (no server-side cap), effort (the service decides how hard it works), a workspaceMode other than none, or a non-empty tools list.
  • timeout when timeoutMs, plus timeoutGraceMs when set, elapses across the whole call, from connecting to reading the body. aborted on a caller abort.
  • Provider response data, error bodies included, is recorded in the result and in error details.

Limits

  • One HTTP request per attempt. The adapter never retries by itself; retry safety belongs to the node’s binding.
  • maxOutputBytes on the request caps the response body the adapter reads. It isn’t a general memory limit.
  • A low-confidence answer completes like any other result. Thresholds and routing are up to your workflow.

API

  • JevApiEngine: the engine class. JevApiEngineOptions: its options. Quickstart.
  • jev: the seat for a team workflow or a judge. JevSeat and JevSeatOptions: its types. A seat for a team.
  • parseJevDocument: read a prompt into the request shape. Ask a question.

Next steps