Cosmo Realtime SDK
Concepts

Protocol Version

PROTOCOL_VERSION on the wire vs SDK semver — when each changes and how breaking changes are signaled.

There are two independent version numbers in Cosmo Realtime: the wire protocol version and the SDK package semver. They change for different reasons.

Wire protocol version

EXTERNAL_PROTOCOL_VERSION = "1.0" is a string constant defined in backend/app/models/external_realtime_protocol.py and stamped on two frames:

MessageFieldDirection
session-configversionclient → server
RealtimeReadyversionserver → client
RealtimeReconnectingversionserver → client

The server checks the client's version on session start. If it does not match, the server sends:

{
  "type": "error",
  "code": "version_mismatch",
  "message": "Client protocol version '0.9' is not supported. Expected '1.0'.",
  "fatal": true
}

The session is terminated. The client must upgrade its SDK.

What counts as a breaking change

A change is breaking (increments the protocol version) if it:

  • Removes a field that the peer requires to be present.
  • Changes the meaning of an existing field.
  • Renames or removes a message type.
  • Changes the discriminator literal on any message.

A change is non-breaking (no version bump) if it:

  • Adds an optional field with a safe default.
  • Adds a new message type (the peer can ignore unknown types).
  • Fixes a documentation error.

SDK semver vs protocol version

DimensionVersionChanges when
Wire protocol"1.0" (string)Schema-breaking change to any wire message
cosmo-ai1.x.y (npm semver)New features, bug fixes, internal refactors
cosmo-ai-sdk1.x.y (PyPI semver)Same
CosmoRealtime1.x.y (Swift package semver)Same

An SDK minor version bump does not imply a protocol version bump. An SDK may ship new hooks, helpers, or performance improvements with no wire change.

A protocol version bump always comes with an SDK major version bump — the new SDK is the first one that speaks the new protocol.

Compatibility table

Server protocolSDK versionOutcome
1.0cosmo-ai@1.xCompatible
1.0cosmo-ai@0.x (hypothetical)version_mismatch error, fatal
Future 2.0cosmo-ai@1.xversion_mismatch error, fatal

Checking the protocol version at runtime

TypeScript

import { PROTOCOL_VERSION } from 'cosmo-ai';

console.log(`Client speaks protocol ${PROTOCOL_VERSION}`); // "1.0"

The ready event does not expose the server's protocol version on the ReadyEvent type. The raw RealtimeReady wire message has a version field, but the SDK normalizes it away. You can access it via the catch-all transport message listener if you need the server-side value at runtime; the PROTOCOL_VERSION constant above is what the client sends and what the server is guaranteed to match (otherwise the session is rejected with version_mismatch).

Python

from cosmo_ai import RealtimeReady

async for event in session:
    if isinstance(event, RealtimeReady):
        print(f"Server protocol version: {event.version}")  # "1.0"

The Python SDK does not export its own version constant publicly — read the server's off the ready event.

Swift

import CosmoRealtime

print("Client speaks protocol \(RealtimeSession.protocolVersion)")  // "1.0"

for try await event in session.events {
    if case .ready(let ready) = event {
        print("Server version: \(ready.version)")
    }
}

See also

  • Errorsversion_mismatch error code and recovery
  • Sessions — the version field on session-config

On this page