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/coreimport { 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 decidedRequires 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.
| Field | Type | Meaning |
|---|---|---|
turn | Turn message | Best: the Turn message from your own Universal-Streaming session, as received. Word confidences and timings are used. |
fastTurn | Turn message | Optional: a second, differently configured stream on the same audio. Where the two disagree, it asks. |
transcript | string | Or 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. |
fastTranscript | string | Plain-text second reading (fastText is accepted too). |
name | string | How to refer to the caller when relaying: "Robert says: ...". |
lexicon | string[] | The caller's own words: medicines, pharmacy, people. Up to 100. |
context | string | A sentence of context for the models. |
model | string | An LLM Gateway model id. Default: the smallest your key can use. |
Response
| Field | Meaning |
|---|---|
action | relay, ask or hold. |
say | Exactly what to say to the other party. Only when action is relay. |
question | A two-choice question for the caller, each option with the sentence to relay if chosen. Only when action is ask. |
rule | Which Adjudicator rule decided, with its plain-language meaning. |
checks | The deterministic findings: disputed negation, invented words, flipped polarity. |
readings | What the Advocate and the Skeptic proposed, when models ran. |
heard | The evidence: both readings, disagreements, lowest confidence, hidden pauses. |
models | Which 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/modelswith your key lists the models it can use. - After a call:
GET /calls/:id/recordand/record.txtreturn what was said in the caller's name, built from the call's own event log./eventsreturns that log, and/escalationthe handoff packet for a human relay assistant. - MIT licensed. Run your own: the orchestrator is one Node process.