Skip to content
One Moment

For developers

The patient-mode layer, as an API

Any voice application can add this: a pharmacy line, a bank, a telehealth platform. Send what your AssemblyAI stream heard. Get back what a careful partner would do: say it (and exactly what to say), ask (and the two-choice question), or keep waiting. It never guesses.

Try it

Or install the engine

The decision layer is published, so it can be used without the service and without this repository. It is pure: no network, no audio, no I/O of any kind except an optional model client you pass in. That is why it is testable, and why every number on the evidence page can be re-derived from committed files.

npm install @one-moment/core
import { assembleEvidence, runDissent } from '@one-moment/core';

const evidence = assembleEvidence({ patient: turn, fastFinals: [fastTurn] });
const result = await runDissent(evidence, { apiKey, callerName: 'Robert', lexicon });

result.decision.action;     // 'relay' | 'ask' | 'hold'
result.decision.text;       // exactly what to say, when the action is relay
result.decision.policyRule; // which rule decided

Requires Node 24. Ships compiled JavaScript with type declarations. MIT licensed, same as the rest.

POST /v1/decide

curl -X POST https://orchestrator-production-494f.up.railway.app/v1/decide \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ASSEMBLYAI_API_KEY" \
  -d '{"transcript": "I need to refill my amlodipine prescription, please.", "name": "Robert"}'

The key is optional. Without one, every turn that needs no model is still answered (a clear sentence, a disputed “not”), and the rest are asked rather than guessed. With your AssemblyAI key, it runs the Advocate and the Skeptic on the LLM Gateway on your account.

Request fields
FieldTypeMeaning
turnTurn messageBest: the Turn message from your own Universal-Streaming session, as received. Word confidences and timings are used.
fastTurnTurn messageOptional: a second, differently configured stream on the same audio. Where the two disagree, it asks.
transcriptstringOr plain text, if you have no Turn (text is accepted too). Confidence is then treated as unknown. Send it formatted: a complete, punctuated sentence takes the verbatim path and needs no model, while an unpunctuated string is read as a fragment.
fastTranscriptstringPlain-text second reading (fastText is accepted too).
namestringHow to refer to the caller when relaying: "Robert says: ...".
lexiconstring[]The caller's own words: medicines, pharmacy, people. Up to 100.
contextstringA sentence of context for the models.
modelstringAn LLM Gateway model id. Default: the smallest your key can use.

Response

Response fields
FieldMeaning
actionrelay, ask or hold.
sayExactly what to say to the other party. Only when action is relay.
questionA two-choice question for the caller, each option with the sentence to relay if chosen. Only when action is ask.
ruleWhich Adjudicator rule decided, with its plain-language meaning.
checksThe deterministic findings: disputed negation, invented words, flipped polarity.
readingsWhat the Advocate and the Skeptic proposed, when models ran.
heardThe evidence: both readings, disagreements, lowest confidence, hidden pauses.
modelsWhich model ran, and how many calls it took. Often zero.

Limits and privacy

  • Stateless. Nothing you send is stored. A key, if sent, is used for that request only.
  • Twenty requests a minute per address on the public demo.
  • Also: GET /v1/models with your key lists the models it can use.
  • After a call: GET /calls/:id/record and /record.txt return what was said in the caller's name, built from the call's own event log. /events returns that log, and /escalation the handoff packet for a human relay assistant.
  • MIT licensed. Run your own: the orchestrator is one Node process.