Voice AI

Real-Time Collaboration on Telnyx Edge: A Multiplayer Doc with an AI Copilot — No API Keys

Collaborative editing is one of the hardest "hello world" demos in software. Behind every Google-Docs-style experience sits a pile of infrastructure: durable state per document, change broadcast to every participant, presence tracking, reconnect logic. Libraries like Liveblocks sell you that layer. Cloudflare built Durable Objects — one single-threaded, stateful object per document — for exactly this.

This Telnyx code example shows the same isolation model on Telnyx Edge Compute, adds multiplayer over a built-in socket layer, and then does something neither Liveblocks nor Durable Objects give you out of the box: an AI copilot that watches the document change and proposes edits — with zero API key management.

The code example is here:

https://github.com/team-telnyx/telnyx-code-examples/tree/main/collaborative-doc-ai-copilot

What This Example Builds

Two browser windows open the same document. Type in one — the text appears live in the other. Stop typing for a few seconds and an AI suggestion appears in both windows with Accept / Reject buttons. Click Accept and the rewritten text lands everywhere.

Under the hood, three pieces:

One durable actor per document. DocActor extends Agent<Env, DocState> — the actor id is the document id. Every document gets its own single-threaded, stateful island on the edge: text, cursor presence, and pending suggestions live as durable state that survives restarts on the platform (the local dev harness is in-memory by design). Concurrent edits to the same document serialize through one actor, so state never races; different documents run on different actors in parallel.

Multiplayer from the SDK, not from your code. The worker routes WebSocket upgrades to the document's actor. From there the Agent SDK's socket layer takes over: AgentSocketServer sends every connecting client a state snapshot plus a hello, pushes new state on every change, and dispatches inbound call frames to the actor's public methods. The browser side is AgentClient from @telnyx/edge-runtime/client — client.stub.edit(name, text) is typed RPC over the socket, and client.onState(...) keeps a live view of the document. Reconnects and heartbeats are built in. There is no broadcast fan-out code in this sample, because there doesn't need to be.

The copilot is just another actor turn. After every durable state change, onStateChanged fires — it pushes the new state to all watchers, and when the text changed, queues a runCopilot task. That task runs as its own actor turn, so the LLM's latency never blocks anyone's typing. It calls Telnyx Inference through the pre-authenticated TELNYX binding:

const completion = await this.env.TELNYX.ai.openai.chat.createCompletion({
  model: "meta-llama/Llama-3.3-70B-Instruct",
  messages: [
    { role: "system", content: COPILOT_SYSTEM_PROMPT },
    { role: "user", content: `Document content:\n\n${state.text}` },
  ],
});

No API key in the code, the bundle, or the logs. The platform authenticates the function. The suggestion is written into actor state, broadcast like any other change, and any participant can Accept (the improved text applies everywhere, attributed to the copilot) or Reject (it's removed).

The Details That Make It Real

  • Presence is just state. Cursor positions live in the actor's cursors map — a merge-patch per user, deleted when their socket closes. The participant chips in the UI are Object.keys(state.cursors).
  • Rate limiting is per document, not per user: a cooldown timestamp reserved before the LLM call, so a burst of edits can't stampede the inference API.
  • Queued tasks ride the alarm mechanism. queue("runCopilot") schedules through storage alarms and drains as its own turn — at-least-once, with the actor re-arming after each drain.
  • The local loop is real. npm run local:dev runs the actual worker and the actual actor in Node with real inference calls (a key from .env for local only — deployed functions need nothing).

Run It

git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/collaborative-doc-ai-copilot
npm install && cp .env.example .env   # local dev only: add your Telnyx API key
npm run local:dev

Open http://localhost:8787/?doc=demo&name=Alice and ?name=Sam in two windows. For production, telnyx-edge new-func --actor --name=collaborative-doc-ai-copilot, merge the telnyx.toml bindings, telnyx-edge types, telnyx-edge ship — and no API key follows the function to the edge.

Platform context if you want to go deeper:

Honest Caveats

The protocol sends full-text replacements — perfect for demo-size documents, wrong for large ones; move to CRDTs (Yjs) for those and keep the copilot trigger on state changes. There's no auth: any ?name= joins, so gate the upgrade path in production. And the copilot is a rewrite-the-doc prompt — tune the system prompt, model, and token budget for your use case.

The takeaway: the hard parts of collaborative infrastructure — durable per-document state, fan-out, presence, reconnects — are the platform's job now. The copilot on top is a few dozen lines, and it needs zero credentials to run.

Ready to build with low-latency voice AI?

Join developers building the future of real-time conversations