mountAgents (SDK ≥ 0.12.0) is the front door for an Edge Compute
function that serves agents.
One call replaces the routing file a function would otherwise write by hand. The function keeps only its own policy. It ships at @telnyx/edge-runtime/mount.
The Address, and What Selects the Transport
Every mounted agent answers on the same shape,<base>/<mount>/<name>, where <mount> is a key of the map and <name> is the routing name of one instance. The
request picks the transport; the path never changes:
base defaults to /agents, so the map above serves
/agents/conversation/alice on all three. That is the URL the
AgentClient examples connect to —
wss://my-func.telnyxcompute.com/agents/conversation/alice is this default base,
this mount key, and this name:
mountAgents is what makes
this shape route. The upgrade is handed to the agent’s
webSocket; GET and POST are handed to the agent’s
fetch, where an
AgentHttpServer over the agent’s
connection engine answers them once the class routes fetch there. The forwarded request keeps its URL and query string,
so subscribe, Last-Event-ID resume, and the /rpc/<method> segment all arrive as
the caller wrote them.
The Hand-Off
The handler the mount returns resolves the binding, then hands the request to the instance.fetchon the function’s default export is the entry this handler fills. The platform calls it with each request and the function’senv.ActorNamespaceis what each map value must be.map(env)reads the bindings on every request. The mount answers404for a value withoutidFromName.idFromNamereceives the actor id thatencodeAgentNamebuilt. The same id always reaches the same instance, as Addressing describes.ActorStub.fetchreceives the request with its URL unchanged and the stamped headers. An upgrade reaches the instance’swebSocketentry, and any other request reaches itsfetchentry.
Two Gates, Not One
The mount’sauthorize does not replace the agent’s own
authorize(token, req). It composes with it, and both run:
- At the edge, before any actor wakes —
authorize(req, route)sees the inbound request and what the mount resolved from it (mount,name,actorId,transport, and for RPC themethod). Return aResponseto reject — nothing is forwarded and no actor is woken — or return headers to stamp identity onto the request, or nothing to admit as-is. It runs identically on all three transports, so no request shape reaches an agent around it. - Inside the agent — the caller’s credential rides through untouched (
?token=, or anAuthorizationheader), soAgent.authorizeresolves this connection’s claims from it exactly as it would unmounted, andonAttachmay still veto.
Names
A routing name is what a caller writes in the address; an actor id is what the platform files an instance’s state and timers under, and only ASCII letters, digits,-, _, and . are addressable. mountAgents runs every name it resolves through
encodeAgentName, so natural names — a phone number, an email address, a composite
key, a name with accents or emoji — reach a persistent instance without the caller
thinking about encoding. Any front door written by hand that must address the same instances calls the same function. Re-deriving the rule points a name at a different, empty instance. The instance reads its actor id as
ctx.id.
The ceiling is on the id once URL-escaped, not on the name — see
MAX_ESCAPED_ACTOR_ID_LENGTH on
the Limits page for what each kind of character costs (225 ASCII, 54 two-byte, 36
three-byte, 27 emoji, plus 6 per escaped run) and why an over-long id fails only after
an eviction rather than on first use.