From d24e9fe15df6b11d508b801ef8ea41a0cbfd2231 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 6 Oct 2026 08:04:29 +0000 Subject: [PATCH] Record that a live call confirmed the Decisions API contract The live probe against typesafe/jev-1.13-20260917 returned HTTP 200 with answers in exactly the documented shape: choice, confidence and per-option probabilities keyed by question id, and usage with input_tokens, output_tokens and cost. The adapter and architecture notes no longer call the answer unconfirmed; tolerant reading stays so a future change degrades to configured order rather than breaking. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01NB8ieibwKFDVRzG8jXS6F6 --- docs/architecture.md | 10 +++++----- src/cerberus/jev/backend.py | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 3637d1c..e036c68 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -127,12 +127,12 @@ latency, status and usage. It never carries request text. The request follows OpenRouter's published Decisions API reference: `questions` is a record keyed by question id, and each `choice` question carries `instructions` and `criteria`, a record of the offered options (with no guidance -of their own; the state describes each model). The live validator rejects a list -of questions and accepts this form. A choice answer is documented as `choice`, +of their own; the state describes each model). A choice answer carries `choice`, `confidence` and per-option `probabilities`; the record keeps the probability of -the option chosen. Until a live call confirms the answer, it is read tolerantly, -and a misread degrades to configured order rather than to an unvetted model. -`scripts/probe-jev-decisions.py` settles it against a live +the option chosen. A live call to `typesafe/jev-1.13-20260917` confirmed both +shapes. The answer is still read tolerantly, so a future change to it degrades +to configured order rather than to an unvetted model. +`scripts/probe-jev-decisions.py` checks this again against a live endpoint: it sends one synthetic decision through the production adapter and reports whether the request was accepted and each answer read as an offered option. diff --git a/src/cerberus/jev/backend.py b/src/cerberus/jev/backend.py index ea12574..de5f9ba 100644 --- a/src/cerberus/jev/backend.py +++ b/src/cerberus/jev/backend.py @@ -5,18 +5,18 @@ needs — and gets back, per question, one of the options it offered or nothing usable. Nothing outside this module knows the wire shape of a decision service. -Contract for OpenRouter's Decisions API, from its published reference: ``POST +Contract for OpenRouter's Decisions API, from its published reference and +confirmed by a live call to ``typesafe/jev-1.13-20260917``: ``POST /api/alpha/decisions`` with a bearer key; the body carries ``model``, ``state`` and ``questions``, a record keyed by question id. A ``choice`` question is ``{type, instructions, criteria}``, where ``criteria`` maps each option to its -guidance or ``null``; the live validator rejects a list of questions and -accepts this form. The response carries ``answers`` keyed by question id — a -choice answer is ``{type, choice, confidence?, probabilities?}`` — and ``usage`` +guidance or ``null``. The response carries ``answers`` keyed by question id — a +choice answer is ``{type, choice, confidence, probabilities}`` — and ``usage`` with ``input_tokens``, ``output_tokens`` and ``cost``. The answer is still read -tolerantly until a live call confirms it. A misread can only ever produce "no -usable answer", because each choice must equal an option Cerberus sent; the -request then runs in configured order and configured effort, which policy -already allows. +tolerantly, so a future change to it degrades rather than breaks: a misread can +only ever produce "no usable answer", because each choice must equal an option +Cerberus sent; the request then runs in configured order and configured effort, +which policy already allows. """ from __future__ import annotations