Skip to content

Describe the live channels in AsyncAPI, with lint and a breaking-change check - #1616

Merged
davidmckayv merged 4 commits into
mainfrom
api/asyncapi-channels
Nov 14, 2026
Merged

davidmckayv merged 4 commits into
mainfrom
api/asyncapi-channels

Conversation

@davidmckayv

@davidmckayv davidmckayv commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

What

api/asyncapi.yaml (AsyncAPI 3.1.0) describes every WebSocket a client opens today, beside the REST spec:

  • A conversation's runs on Intelligence's realtime gateway: the Phoenix frames of thread:{threadId} (join, connected, ag_ui_event, replay complete, stream idle, replay failed, expired, stop a run, leave, close), with how replay and the event id work.
  • Conversation events (/api/channels/events): what changed in a person's conversations.
  • A Bot's screen (/api/computers/{botId}/stream): frames out, mouse and keyboard in.
  • A Bot's terminal (/api/computers/{botId}/terminal): bytes out, input, resize and acknowledgements in.

It describes the sockets as they are served now. The three OpenBot serves are named as the legacy channels (legacyConversationEvents, legacyBotScreen, legacyBotTerminal), so that their addresses under /api/v2, which follow with voice and the Recorder's topic, can take the plain names without a breaking change to this file.

Checks

  • Lint: bun run api:lint now lints both files. Redocly validates the file against the AsyncAPI 3.1 schema, WebSocket bindings included.
  • Breaking changes: on a pull request, CI compares the file with the base branch's and fails on a change that could break a client. A change that takes nothing from a client is listed with its reason in api/accepted-live-breaking-changes.md.

What the breaking-change check relies on

The differences come from the AsyncAPI CLI's diff, pinned at @asyncapi/cli 6.3.0 in api/asyncapi-tools with its own lockfile, so only the API job installs it. The CLI wraps @asyncapi/diff, which is still 0.x (0.6.1). We rely on it for one thing: the list of what changed and where. It classifies changes to the document's own structure (a channel's address, a removed channel or message) but calls every change inside a payload schema "unclassified", so api/asyncapi-diff.ts decides those itself, strictly: new things, a new optional member and wording pass, and anything else fails. api/asyncapi-diff.test.ts holds that to real edits of the real file, and runs in the API job.

Tested

  • The lint fails on a broken file (an unknown field, a bad binding, an unresolved reference).
  • The breaking-change tests: a moved address, a removed message, a member made required, a changed type and a removed member fail; a new optional member and a reworded description pass; an accepted change passes and nothing else does.
  • Against a running OpenBot with Intelligence 0.16.0-rc.13, in Chromium: every frame of a first conversation, of taking over a Bot's browser and of typing in its terminal is one the file describes. That run found three things the first draft had wrong (a join with no event seen yet, leaving a thread, the gateway closing it), which are fixed here.

…ge check

api/asyncapi.yaml (AsyncAPI 3.1.0) describes every WebSocket a client opens today: a conversation's
runs on Intelligence's realtime gateway, and OpenBot's own sockets for conversation events, a Bot's
screen and its terminal.

Redocly lints it with the REST spec. On a pull request, the AsyncAPI CLI's diff (pinned in
api/asyncapi-tools) lists what changed against the base branch, and api/asyncapi-diff.ts fails on
anything that could break a client unless api/accepted-live-breaking-changes.md lists it.
@davidmckayv
davidmckayv force-pushed the api/asyncapi-channels branch from 11df094 to 14dd7a4 Compare November 14, 2026 15:03
@davidmckayv
davidmckayv merged commit 8777bd0 into main Nov 14, 2026
28 checks passed
@davidmckayv
davidmckayv deleted the api/asyncapi-channels branch November 14, 2026 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant