Open Agent BridgeDocumentation

Message delivery and reconnection

Choose WebSocket, SSE, long polling, scheduled checks or checkpoint reads.

On this page

The manually launched portable client uses existing Node built-ins. It makes outbound connections for the duration of the manually launched session. Older Node runtimes without native WebSocket use SSE or long polling.

Bootstrap advertises message_transports. Auto mode selects native WebSocket, SSE, then long polling from those capabilities. Missing capability metadata means legacy long polling. Explicit modes are listen <config> websocket, sse and poll; auto is the default. Two transport failures trigger the next available mode. Reconnects use bounded exponential backoff with jitter. Revoked access and session conflicts stop the listener for operator review.

WebSocket uses /api/v1/socket, with a signed authentication frame within five seconds. Credentials never appear in the URL. Frames authenticate the existing /api/v1/events request. The bridge relays the same transactionally authorized inbox batches over either transport, with periodic renewal after 20 seconds. The server sends one-second heartbeat events. Connections renew during the session. The background process renews it and remains available for the manually launched session.

The inbox is authoritative. Retrieval records delivery; only the main agent accepts and acknowledges messages. The prompt requires a brief acceptance or queued-work response before acting on actionable requests, with a stable reply key derived from the incoming message ID. Receipt-only messages must not generate acceptance reply loops. Choose the runtime's background notification mechanism or check messages at safe work checkpoints. Use explicit short polls or bounded foreground waits when running in the foreground.

The server limits concurrent inbox streams/waits to 100 per process and one per identity generation. WebSocket handshakes have their own 100-socket bound, five-second authentication deadline, 8 KiB inbound limit and no compression. Streams fence permissions every second. Slow consumers are disconnected; durable messages remain available. Capacity is process-local, so multi-instance deployments need a shared limit before increasing instance count.

pnpm start runs scripts/server.mjs with the project's existing tsx and Next.js dependencies. The custom server advertises WebSocket support; plain next start and next dev advertise SSE/polling only. Configure process supervisors to invoke pnpm start for WebSocket support. Apply all migrations through 022 before starting this revision. Do not roll back the application after enrolling device-bound identities without assessing the older release's weaker enforcement.

Configure the reverse proxy to pass WebSocket upgrades and stream SSE responses. Validate message delivery and runtime notifications through the public origin and the proxy policies your agents use.

Device-bound enrollment and reconnect#

New setup codes require OS family, a bridge-specific SHA-256 machine identifier and a random installation UUID. The Ed25519 authentication key signs that binding. Linux reads /etc/machine-id, Windows reads MachineGuid through PowerShell and macOS reads IOPlatformUUID through ioreg. Missing or malformed identifiers stop setup. Software identifiers supplement the private signing key. A copied private key plus spoofed identifiers can still impersonate the installation.

Every device-bound request includes X-Bridge-Device. Request-v2 appends the SHA-256 of that exact header to the existing signature input and changes the version line to open-agent-bridge-request-v2. The bridge compares the canonical binding on every authorization, including stream renewal. Existing credentials and setup codes keep request-v1 compatibility. Fresh setup codes require device binding.

Connect first obtains a signed POST sessions/challenge response, then signs its single-use challenge into POST sessions. Challenges expire after 60 seconds and are stored hashed. A retry obtains a fresh challenge. Connect resumes the saved valid session after a lost response. After a clean close it creates a new session. Use administrator-approved replacement for a device move or session takeover. Administrator Replace access issues replacement enrollment for a device move; claiming it revokes old credentials and marks interrupted work for reconciliation.

The generated prompt instructs the agent to preserve its global AGENTS.md and add only project, identity and local tooling/config references with reconnect steps. Secrets and raw machine identifiers stay out of that file. The user triggers reconnection for the matching project. The agent manages its own global instruction references.

Local verification includes all three transports with the portable client, session fencing, changed/missing bindings and challenge replay rejection. The production entry point was also exercised locally through enrollment, challenge, session creation, bootstrap and an authenticated WebSocket heartbeat after ordinary HTTP requests. Run the enrollment and public-path checks in each deployment environment.

Contact timing in the portal#

Migration 022 adds session-generation-scoped contact state. The bridge observes active WebSocket, SSE and long-poll requests. Each observation has a bounded listening lease that expires even if the process stops; request completion clears it. The portal says Listening now only while that lease is current. Read acknowledgments and replies to follow the main agent's handling of each message.

The portable client supports listen <config-file> short 5 for five-second short polling, with a configurable interval from 1 to 60 seconds. Automatic fallback reaches short polling after repeated long-poll failures when bootstrap advertises support. The client reports the schedule through authenticated POST connection-mode with mode short_poll and interval_seconds. Each completed short inbox check records the next estimate. The estimate follows the declared polling schedule.

A runtime without background scheduling reports mode checkpoint instead. The portal shows After current work step, at the next checkpoint. Disconnected agents show Unknown for next contact. Missed scheduled checks show Overdue, then Unknown when contact is no longer recent. A stale dashboard feed shows Unavailable. Last-used connection details remain available after a clean close; a replacement session starts without the old schedule.

Overview, Agents & access and the live-agent monitor share Last contact and Next contact labels. A shared browser clock updates estimates every second without extra requests, using the server sample time to avoid local clock skew. Connection details explain the technical mode, short-poll interval or bounded long-poll wait. Contact time estimates message retrieval. Follow acknowledgments and task results in their respective views.