Edge relay: your laptop is the model behind your number¶
One signed-in browser with an on-device model can answer a whole SMS number or WhatsApp account. No API key, no GPU server, no per-token cost: a teacher's laptop serves the class group, a clinic's front-desk PC answers the patients' texts, a shop's phone answers its customers, all with the model that the free local models page installed in the browser.
How it works¶
- On /edge, with an on-device model installed, pick the channels this device should answer (SMS, WhatsApp) and press Start answering. The browser registers as a relay for your workspace and heartbeats every twenty seconds.
- An inbound message on one of those channels, from a paired sender with no workflow bound, is queued in Valkey instead of being sent to the hosted model. The webhook still acknowledges the provider at once.
- The browser long-polls, claims the message, and runs it through the local tier ladder with the agent's own persona and the last twelve messages of that conversation. It hands the text back.
- The server thread that owns the inbound message sends the reply through
the same approval gate a hosted reply would use (
channel.sms.send,channel.whatsapp.send). The browser never talks to a channel. - If no relay is online, the queue is full, the relay does not answer within a minute, declines (no local model ready), or Valkey is unavailable, the hosted model answers the same message on the same thread. A message is never lost and never answered twice: a timed-out job is cancelled and a late reply is dropped.
Several devices can relay at once; each claims from the queues of the channels it registered for. The /edge card lists the other devices answering right now and how many messages each has answered.
Who may do this¶
Starting a relay needs the channel-management permission
(PERM_MANAGE_CHANNELS), the same one that sets a channel's default agent.
The relay sees the inbound text of its own workspace's senders, which that
permission already grants through the conversation inbox; the sender's phone
number is masked in what the browser receives. A job can only be answered by
the device that claimed it, and only for its own workspace.
Configuration¶
| Property | Env | Default | |
|---|---|---|---|
app.omnichannel.edge-relay.enabled |
EDGE_RELAY_ENABLED |
true |
false removes the feature: the register call returns 409 and every message goes hosted |
app.omnichannel.edge-relay.heartbeat-ttl-seconds |
EDGE_RELAY_HEARTBEAT_TTL_SECONDS |
45 |
a relay is online while its heartbeat key lives |
app.omnichannel.edge-relay.claim-wait-seconds-max |
EDGE_RELAY_CLAIM_WAIT_SECONDS_MAX |
25 |
longest a long-poll may block |
app.omnichannel.edge-relay.reply-wait-seconds |
EDGE_RELAY_REPLY_WAIT_SECONDS |
60 |
how long the inbound thread waits for the relay before answering hosted |
app.omnichannel.edge-relay.lease-seconds |
EDGE_RELAY_LEASE_SECONDS |
90 |
lease on a claimed job |
app.omnichannel.edge-relay.queue-max |
EDGE_RELAY_QUEUE_MAX |
100 |
queued messages per channel beyond which new ones go hosted at once |
app.omnichannel.edge-relay.history-turns |
EDGE_RELAY_HISTORY_TURNS |
12 |
earlier messages of the session handed to the relay |
API, all under /api/channels/edge-relay: GET /status, POST /register,
POST /{relayId}/heartbeat, DELETE /{relayId}, GET /{relayId}/next?wait=20
(200 with the job, 204 when idle), POST /jobs/{jobId}/reply,
POST /jobs/{jobId}/fail.
Limits, honestly¶
- Channels: SMS and WhatsApp (Twilio and Meta). Telegram, Slack and the others still use the hosted path; adding one is a three-line hook in its webhook controller.
- The relay answers text only. A voice note or an image on WhatsApp goes hosted as before.
- Server-side tools do not run on the relay path unless the local tier calls them through the edge tool bridge; a hosted reply has the full tool set.
- A busy relay answers one message at a time per tab; the queue absorbs
bursts up to
queue-max, then overflow goes hosted. Reply latency is the device's generation time plus the poll interval. - Unit-tested on both sides; not yet exercised against a real phone number.