Repository navigation
Send jev decisions in the Decisions API's documented shape - #33
Merged
Merged
Conversation
A live probe against OpenRouter rejected the adapter's request with HTTP 400:
`questions` must be a record keyed by question id, not a list. OpenRouter's
published reference gives the rest of the contract: each choice question is
{type, instructions, criteria}, with criteria mapping every offered option to
its guidance or null, and usage reports input_tokens, output_tokens and cost.
- build_body sends questions as {id: {type, instructions, criteria}}; the
options carry no guidance of their own since the state describes each one.
The live validator accepts this form (the next refusal was the key's budget).
- Usage is read from input_tokens/output_tokens/cost; the old chat-completions
names never matched and only cost survived.
- The probe reports a 401/402/403 as a refused key or credit, not a rejected
request shape.
- The probe's recording transport re-served a decoded body under its original
content-encoding, so any compressed response surfaced as "unreachable".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NB8ieibwKFDVRzG8jXS6F6
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What the live probe found
Running
scripts/probe-jev-decisions.pyagainst OpenRouter got this:The jev adapter sent
questionsas a list. The Decisions API expects a record keyed by question id. OpenRouter's published reference gives the rest of the contract:{type: "choice", instructions, criteria}.criteriamaps every offered option to its guidance, or tonull.{type, choice, confidence?, probabilities?}, keyed by question id.{input_tokens, output_tokens, cost}.Changes
build_bodysendsquestions: {route: {type, instructions, criteria: {m1: null, …}}, effort: {…}}. The options carry no guidance of their own becausestatealready describes each model. Nothing new leaves Cerberus.input_tokens/output_tokens/cost. The old chat-completions names never matched, so onlycostwas ever recorded.KEY REFUSEDinstead ofREQUEST REJECTED, which wrongly pointed at the request shape.content-encodingheader, so httpx decoded it twice and any compressed response showed up asunreachable. Reproduced offline with a gzip 403, then fixed and covered by a test.architecture.md, README) and the tests to the documented shape.Verification
scripts/ci.sh: ruff clean, 443 tests passed.HTTP 403 Key limit exceeded (total limit). OpenRouter validated the old body and rejected it before reaching the budget check, so the new shape passes validation. The key has a $0 limit, so no decision was billed and the answer shape isn't confirmed live yet. It's still read tolerantly, as before.🤖 Generated with Claude Code
https://claude.ai/code/session_01NB8ieibwKFDVRzG8jXS6F6
Generated by Claude Code