Deciders
One model that can answer a decision, with its protocol, secret, and certificate.
A decider is the model behind a decision. Two presets are filled in. Every other host passes the protocol, the URL, and what it can answer.
The one rule
Use provider: "openrouter" or provider: "openai" when that is the host. Any other host needs
driverId, baseUrl, secret, and capabilities.
Quick start
OpenRouter
Certificates bind to the dated model id the host echoes.
import { ai } from "okengine";
export const jev = ai.decider("jev", {
provider: "openrouter",
model: "typesafe/jev-1.13-20260917",
});The request is System One: POST https://openrouter.ai/api/alpha/decisions with { model, state, questions }. The secret is OPENROUTER_API_KEY.
OpenAI
The certificate binds to the echoed id, stays unpinned, and expires 30 days after certify.
export const luna = ai.decider("luna", {
provider: "openai",
model: "gpt-6-luna",
});The request is { model, input, questions } at https://api.openai.com/v1/decisions. Object state is sent as JSON text. The secret is OPENAI_API_KEY.
Any other host
Name the protocol. Do not invent a preset.
export const local = ai.decider("local", {
driverId: "systemone",
baseUrl: "https://decisions.example.com/v1",
model: "local-decider",
secret: "DECISION_API_KEY",
capabilities: { boolean: true, choice: true, score: true, refusal: false },
region: "self",
});region and zdr are your declaration. The Manifest marks them declared.
Presets
| Provider | Protocol | URL | Secret | Pinning | Answers |
|---|---|---|---|---|---|
openrouter | systemone | https://openrouter.ai/api/alpha/decisions | OPENROUTER_API_KEY | dated | boolean, choice, score |
openai | openai-decisions | https://api.openai.com/v1/decisions | OPENAI_API_KEY | alias | boolean, choice, score, refusal |
No other host is filled in. A dated certificate stores the echoed canonical slug. An alias certificate stores pinned: false and expiresAt. Console shows the unpinned flag. oke decide certify prints it.
If OpenRouter lists a dated id for the model, autonomy requires the decider to use that id.
Capabilities
| Field | Meaning |
|---|---|
boolean / choice / score / refusal | Whether that question kind is allowed. |
maxChoices | Enforced only when the row sets it. |
minLevels / maxLevels | Enforced only when the row sets it. |
maxContext | Estimated input tokens. Over the limit throws before the call. |
Presets do not set a numeric limit. A custom row's false flag rejects that question at compile time.
Both wires become one answer: boolean, choice, score, refusal, or malformed. A refusal carries no text.
Options
| Option | Preset | Custom host |
|---|---|---|
provider | openrouter or openai | Optional label |
driverId | Filled in | systemone or openai-decisions |
baseUrl | Filled in | Required |
model | Required | Required |
secret | Preset secret, or your override | Required |
region / zdr | Stored as declared | Stored as declared |
timeout | Optional | Optional |
concurrency | Optional cap for this decider | Optional |
One decider has one breaker. Three HTTP 5xx responses open it for 30 seconds. The next call skips that decider and tries backup.
Troubleshooting
oke decide certify: autonomy requires model "…" on decider "…". The catalog lists a dated id.
Put that id on the decider.
Certify prints model "…" is unpinned. An alias certificate expires 30 days later. After that,
answers take otherwise with why: "uncertified".
ai.decision("…"): decider "…" cannot answer choice "…". The capability row has that kind set to
false.
Learn more
- Decisions —
otherwise, certificates, andfx.decide - Configuration —
drivers.decide