Ephemerent Ephemeral - Emergent
SENTINEL / ENERGY-BASED CLM

Give your agent
a next step.

A dedicated decision layer for AI workflows. Turn context and candidate actions into structured scores—alongside the language model you already use.

Interactive examples · Live inference · Inspectable responses

THE MOMENT BETWEEN ACTIONS↗
Context→Sentinel→Next step
See the options. Inspect the scores. Make the call.
Modelsentinel-1
AnswersYes/no, a choice, or a ranking
Speed0.73 s median¹
StatusEarly access

Sentinel does not write code or prose. It reads the evidence and alternatives you provide, then returns a structured decision with model scores. Your agent retains control of execution and verification.

¹ Local RTX 5060 Ti deployment smoke, 12 synthetic requests, September 28, 2026. This is a latency observation, not a quality benchmark or service-level guarantee.

What it does

Three structured interfaces for decisions between agent steps. The outputs below illustrate response formats; they are not measured results.

Decide

Yes or no

A direct question about the current state, answered with the probability that the answer is yes.

Will this patch make the failing test pass?yes · p_yes 0.91
Choose

One of several

Name the options and describe each in a line. Sentinel picks one and gives a probability for every option.

Which of these should the agent do next: edit, read, or run?edit · 0.84
Rank

In order

Hand it a list of candidates and get them back best first, each with its share of the probability.

Which fix should we try first?fix the parser 0.78 · fix the test 0.22

Why use it

  • FastA small 12-request deployment smoke measured a 0.73-second median round trip. Actual latency depends on input length, load and connection.¹
  • InspectableCompare scores across the options you supply. These are model estimates, not verified outcomes or universally calibrated confidence. Check consequential choices against evidence.
  • Fails fastBounded timeouts and circuit breakers let your agent continue when Sentinel is unavailable. Handle busy or offline responses explicitly in your workflow.

Where it works

  • OrrerySentinel runs inside Orrery, where the agent consults it for the quick calls during a run.
  • MCP agentsAdd the Sentinel MCP server to any agent that speaks the Model Context Protocol: Claude Code, OpenCode, Cursor, Codex CLI, Gemini CLI or VS Code. The agent gets three tools, sentinel_decide, sentinel_rank and sentinel_status, with descriptions that tell it when to ask.
  • Function callingFor your own agent loop, register sentinel_decide as a tool in the OpenAI or Anthropic format and forward the call to the API.
  • ShellA small command-line client answers in its exit code, for scripts and shell-driven agents.
  • APITwo HTTP endpoints on api.ephemerent.com, with the same key as the Orrery API.

API quickstart

Sentinel uses the API key from your account page, sent as a bearer token. Give it the facts in state (code, a diff, an error message), ask one question, and add options when there are more than two answers.

POST/v1/sentinel/decideA yes/no answer with p_yes, or with options, the chosen option, its confidence and a probability for each.
POST/v1/sentinel/rankCandidates in order, best first, each with its probability.
GET/v1/sentinel/statusWhether Sentinel is up right now.
curl https://api.ephemerent.com/v1/sentinel/decide \
  -H "Authorization: Bearer $ORRERY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "state": "test_parse_date fails: ValueError on \"2026-09-26T10:00Z\". The patch adds a branch for a trailing Z in parse_date.",
    "question": "Will this patch make the failing test pass?"
  }'

# {"answer": "yes", "p_yes": 0.91, "model": "sentinel-1"}
# Python (pip install requests)
import os, requests

r = requests.post(
    "https://api.ephemerent.com/v1/sentinel/decide",
    headers={"Authorization": f"Bearer {os.environ['ORRERY_API_KEY']}"},
    json={
        "state": diff + "\n\n" + test_output,
        "question": "Which of these should the agent do next?",
        "options": {
            "edit": "apply the fix to parse_date",
            "read": "open the caller before changing anything",
            "run": "run the test suite as it is",
        },
    },
    timeout=8,
)
if r.status_code == 503:
    decision = None          # Sentinel is offline: decide without it
else:
    r.raise_for_status()
    decision = r.json()
    # {"answer": "edit", "confidence": 0.84,
    #  "p": {"edit": 0.84, "read": 0.12, "run": 0.04}, "model": "sentinel-1"}
// JavaScript (fetch)
const res = await fetch("https://api.ephemerent.com/v1/sentinel/rank", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ORRERY_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    context: failingTestOutput,
    candidates: ["fix the parser", "fix the test"],
    question: "Which fix should we try first?",
  }),
  signal: AbortSignal.timeout(8000),
});
const ranked = res.ok ? (await res.json()).ranked : null; // null: go on without it
// [["fix the parser", 0.78], ["fix the test", 0.22]]

For your own agent loop, this is the tool definition to register. Forward its arguments to /v1/sentinel/decide and return the answer to the model.

{
  "name": "sentinel_decide",
  "description": "Ask Sentinel to compare concrete next actions using the supplied evidence. Returns model scores; verify consequential choices independently.",
  "parameters": {
    "type": "object",
    "properties": {
      "state":    { "type": "string", "description": "The facts the decision depends on: code, a diff, error output." },
      "question": { "type": "string", "description": "One question with a short answer." },
      "options":  { "type": "object", "additionalProperties": { "type": "string" },
                    "description": "Named options, each with a one-line description. Omit for a yes/no question." }
    },
    "required": ["state", "question"]
  }
}

Limits and pricing

Each decision costs a fraction of a cent, metered in the same compute credits as the rest of the API and drawn from the same balance. sentinel-1 is listed in /v1/models, but it is not a chat model: sending it to /chat/completions returns 400. When Sentinel is offline the API answers 503 with a Retry-After header; clients should carry on without it rather than wait. Sentinel requests are never stored or used for training, whatever your data setting: the service keeps counts and an access-log line, never what you sent or what it answered.

An honest note

Sentinel is in early access. Capacity is limited, and availability, latency and pricing can change. Treat it as a quick second opinion, not ground truth: scores can be wrong, even when strongly separated. You remain responsible for what your agent runs and ships.