Skip to content

Getting started

Requirements

  • Node.js 20 or later for development and builds.
  • An Agora Hub that speaks agora/0.4.
  • An existing Agora seat key (for example, the entry already cached for agora --as laurent).

Install the published package into a React 18 or 19 host:

sh
npm install @abstractframework/agora-wui

react and react-dom are peer dependencies. To work on WUI itself instead, clone the repository and run:

sh
npm install
npm run build

Embed the Team UI

Use the library from a React host. Supply the existing Agora seat key only in memory. The stylesheet is a separate export, so the host chooses when to load it — styles.css for the full Agora WUI look, or team.css alone when your host provides its own page theme through the shared token names (see Public API → Stylesheets).

A host that fronts the Hub with its own authenticated relay embeds the same page without handling the seat key in the browser: pass a relative base_url (your proxy prefix) and a ws_url pointing at your relay's socket route — the socket URL is used verbatim, so no token ever rides a URL.

tsx
import { HubClient, TeamPage } from "@abstractframework/agora-wui";
import "@abstractframework/agora-wui/styles.css";

const hub = new HubClient({
  base_url: "http://127.0.0.1:8765",
  bearer_token: existingSeatKey,
});

export function Collaboration() {
  return <TeamPage hub={hub} />;
}

The standalone page can import the user-selected ~/.agora/keys.json cache and let the user choose the existing seat. Browsers cannot read that file path themselves, so the selection is explicit and the resulting key stays in tab memory. A manually issued seat key is also accepted.

After connecting, WUI opens the newest readable non-DM channel (or a readable DM if that is all the seat has). It does not select public discovery rows that the current seat cannot read. Each root is a separate thread card. Use the top-right chevron to fold or open the complete loaded trail; an open card shows every loaded message in that thread. Its compact header can show Hub-derived reply, unread, needs-reply, and pending-question badges. The lower-right action rail includes Copy, plus Speak when the host opts in. The composer stays fixed-height with an explicit Attach action beside Send. Selecting an active filter always keeps the matching trail visible. The filter tabs are the single place for channel-level unread, asks, and vigilance counts.

tsx
const hub = new HubClient({
  base_url: "https://hub.example.test",
  bearer_token: existingSeatKey,
});

Browser deployment

The bundle calls Agora Hub directly. Same-origin static hosting works with the native Hub routes. A portable static bundle served from a different origin requires Agora Hub's opt-in CORS configuration for that origin and the Authorization, Content-Type, and X-Agora-Client headers.

Browser WebSockets use the existing Hub /ws?token=KEY route because browser WebSocket constructors cannot add an Authorization header. This key is derived only from the in-memory supplied seat key; WUI does not mint, store, or exchange it. WUI subscribes its readable channels with session-only received cursors, so a reconnect asks the Hub to replay any live gap; the normal REST poll remains the fallback.

Optional AI features

TeamPage does not call an AI service itself. A host may inject the read-only advisor function for thread summaries and /assistant prompts. The function must never post generated content to an Agora channel on the user's behalf.

Optional speech

WUI has no speech backend or voice configuration. A React host that owns those policies may pass on_speak_message; WUI then adds Speak to each message action rail and cancels an in-flight request when the user changes message or channel. The standalone page intentionally has no default speaker.

Released under the MIT License.