@obversa/engine-openai-decisions asks OpenAI’s
Decisions API
typed questions about state your run already recorded: does the draft hold,
which way should the work go, how ready is it to ship. Each attempt is one
call to /v1/decisions, and the answers come back as the structured result.
It runs with workspace mode none; it never reads or edits files.
It takes the questions of the Jev API engine’s
prompt document (noul, choice and score), so the runtime’s judge runs
on it unchanged. It loads none of your own setup, so it always runs clean and
has no clean option.
Install
@obversa/obversa; install it on its own.
Requirements
- An OpenAI API key with access to the Decisions API, passed as the
apiKeyoption.openaiDecisions()also reads it fromOPENAI_API_KEY.
Use it as the judge
openaiDecisions() makes a seat. It reads the key from OPENAI_API_KEY and
defaults the model to gpt-6-luna. Pass the seat wherever a Jev seat goes,
for example judge(openaiDecisions()) in a stage’s refine. The judge reads
each answer the same way it reads Jev’s.
The seat wraps OpenAIDecisionsEngine. This example makes the engine with a
placeholder key and checks a request without sending anything:
examples/engine-openai-decisions-binding.ts
npx tsx engine-openai-decisions-binding.ts:
Output
The document
A request’sprompt is a JSON document carrying the evidence and the
questions, keyed by name:
state as the evidence: a string as it is, anything else as
indented JSON. It sends each question in the API’s own shape:
The answers
The result is onestructured part: the answers keyed by question name, with
the fields the API returned.
- A predicate carries
probability, also given asnoul, the field a Jev answer carries. Itstypeispredicate, where a Jev answer’s isnoul. - A choice carries
choice,confidenceandprobabilities. - A score carries
score,confidenceandprobabilities. The score is the probability-weighted average of the level indices, which start at 0. - A refused question comes back as
{ "type": "refusal" }.
unknown. openaiDecisions() returns the answers as
assistant text, the JSON of the answers object, so a job reads them as it
reads any seat’s reply.
Cost
The Decisions API bills input tokens only, at $0.10 per million forgpt-6-luna. A response that reports no output count is read as zero output
tokens. The runtime’s shipped price table keys prices by model, and
gpt-6-luna is priced differently on OpenAI’s other endpoints, so the table
has no entry for it. Price your decision calls with the prices run option,
for example { 'gpt-6-luna': { inputPerMTokUsd: 0.1, outputPerMTokUsd: 0 } }.
Options
Errors
- HTTP status maps to a failure kind: 400 is
invalid-config, 401 and 403 areauth, 402 isbilling, 429 israte-limitwith itsRetry-After, and 5xx istransient. - The engine never retries and never invents an answer. An unreachable endpoint fails the attempt.
- Limits apply to the whole call.
timeoutMs, plustimeoutGraceMswhen set, bounds it, andmaxOutputBytescaps the response body. - Some request fields are refused before any call: a system prompt,
env,maxTokens, ajsonSchemaresult, a workspace mode other thannone, tools andeffort.
Identity
The plugin reportsprovider: 'openai', with the model family read from the
model name, so gpt-6-luna reports family gpt. If the API doesn’t echo a
model, the recorded effective model and family are null. A review panel
that requires different model families counts this seat as gpt, the same
family as a Codex seat.
Limits
- The Decisions API is in public beta.
gpt-6-lunais the only model it serves. - The engine sends the evidence as text. Images are not sent.
- A preflight live check can’t run on this engine. The check sends a
plain-text turn with
maxTokens, which the engine refuses. Setlive: 'skip'for its lane in a run’s preflight policy.