Connect by JBRH Open Connect

Who ended the call

hangup_by names which of six parties ended the call: caller, model, owner, engine, carrier or agent. Before this vocabulary existed, every ending that was not the caller's read as agent, which made a model that stopped talking, a colleague hanging up and a carrier dropping the leg indistinguishable in the record.

Status
Available What this means
Audience
both
Channels
phone
In the app
#/calls
Last verified
Product version
6.3.2

The six words#

caller
The person on the other end hung up. On an abandoned call this is what the hang-up watcher records after the silence, rather than any word being spoken.
model
The realtime model's session ended the call from its side.
owner
A person ended it deliberately — the supervisor panel's engine:hangup control, which rides the guidance log and is never spoken aloud.
engine
Connect ended it for a reason of its own. The clearest case is a greeting that could not be said: the worker posts engine_error {at: greeting} and ends the call rather than leaving the caller in silence.
carrier
The provider ended the leg. A carrier that runs off the end of a document it was given, or clears the channel on its own, lands here.
agent
The voice concluded the conversation itself.

The words are narrow on purpose. Each excludes the others, so a row that says engine is a statement that Connect chose to stop — not a shrug about who did.

Why the old value was worse than useless#

A single catch-all attribution does not merely lose detail; it produces confident wrong answers. With every non-caller ending recorded as agent, a week of calls that were actually being dropped by a carrier looked like a week of calls the voice had ended — which reads as a voice that ends conversations too early, and sends whoever is tuning it to change the closing behaviour of something that was working.

The same field made silent failures invisible. Five inbound calls on one day in September 2026 sat in silence and were recorded as "the caller hung up before speaking" — a completely reasonable-looking row, and untrue. The engine now writes facts.silent_failure from the greeting error event, voice.no_conversation says so, and the outcome is not_reached.

Reading it alongside the outcome#

hangup_byTypical outcome beside itWhat to look at next
callerA conversation, or an abandoned callThe last reply's turn_timing — a long wait before the hang-up is a latency problem, not a caller problem
enginenot_reached with a silent failureThe greeting: whether it could be synthesised, and whether the model accepts a generated line
ownerA conversationThe guidance log for the call, which is where the control came from
carrierAnythingThe provider's own call log for the same call, since the ending was theirs
modelA conversation, or an engine errorWhether model_session_restarted is on the record — a session that refused to start is retried twice before the call is given up

Attribution answers who; outcome answers what. Neither is a diagnosis on its own, and the pair is usually enough to decide whether a call belongs to the conversation layer, the carrier or the fleet.

Endings that are not hang-ups#

Two endings deserve separating from the six. A call is no longer cut at the model's session limit: session resumption plus a sliding-window context compression let the plugin reconnect on the server's go_away carrying the conversation, so the session's own cap is not the call's. What does end a long call is MAX_CALL_SECONDS, 30 minutes, which is the product's own ceiling rather than a provider limit.

The other is a call that never ends at all. sweep_stale closes calls past the configured cap and charges what it closes; it runs from the engine tick as well as the worker heartbeat, because a browser call has no worker and one such call sat active for 24.78 hours before that path was covered.

Questions#

The record says the caller hung up, but they say the line went dead. Who is right?

Check for a silent failure first: if the greeting could not be spoken, the modern record says engine with outcome not_reached, but a call from before that fix would read exactly as the caller describes. Then check the last reply's timing — a caller who waited many seconds and gave up is recorded as hanging up, which is technically true and practically your fault.

Does the supervisor hanging up look different from the voice ending the call?

Yes — owner against agent. That is one of the main reasons the vocabulary was widened: a colleague taking a call off the voice is a deliberate act, and it should not be indistinguishable from the voice deciding it was finished.

Is hangup_by ever unknown?

The field records what the ending evidence supports, so an ending Connect did not observe directly is attributed to whoever the provider event says ended the leg. Where nothing is observed at all, the call is one the stale sweep closes rather than one that was hung up.