Member Junction
    Preparing search index...

    The LIVE WHITEBOARD as a pluggable interactive channel — the canonical BaseRealtimeChannelClient implementation, resolved from the MJ: AI Agent Channels registry row whose ClientPluginClass is 'RealtimeWhiteboardChannel'.

    One instance per session (created via ClassFactory at session start). It owns the board's WhiteboardState engine and contributes the channel's full contract:

    • Action: the Whiteboard_* client-executed tool set (WHITEBOARD_TOOL_DEFINITIONS); ApplyAgentTool prefers the BOUND host component (board mutation + violet pop-in / toast / presence-cursor garnish) and falls back to the pure ApplyWhiteboardAgentTool engine call when no surface is bound (e.g. the surface panel is collapsed) — the channel keeps working, just without the garnish.
    • Perception: BindSurface subscribes the host's coalesced (750 ms) SceneDelta stream and pipes each delta into the live model's context as a [whiteboard] background note; the agent-undo toast click flows the same way.
    • Surface: RealtimeWhiteboardHostComponent, created dynamically by the overlay's channel tab; the host's Focus toggle rides Context.SetFocusMode so the shell can collapse/restore the main call column.
    • State of record: every board mutation (user edits AND agent tool calls) requests a save of WhiteboardState.ToJSON under channel name 'Whiteboard' — the host debounces and flushes at teardown.

    A PRIOR session's persisted board is restored through RestoreState (invoked by the session host after Initialize, before any surface binding): the saved JSON is rehydrated IN PLACE into the same WhiteboardState instance, so the save subscription and any later surface binding keep pointing at one engine. Malformed or incompatible payloads are tolerated — the board simply starts fresh.

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    Context: RealtimeChannelContext | null = null

    The host context, available from Initialize until Dispose. null outside that window — guard with ?. in any code that can run early/late.

    SessionIdWaitIntervalMs: number = 200
    SessionIdWaitTimeoutMs: number = 8000

    Max time ResolveAgentSessionId waits for the session id to bind before giving up, and the poll interval it re-checks on. Protected so tests can shrink the wait; production keeps the defaults (the real mint race is sub-second, 8s is generous headroom).

    State: WhiteboardState = ...

    The board's state of record — created fresh with the plugin (one per session).

    Accessors

    • get TabColor(): string | null

      OPTIONAL accent color for the channel's tab (a CSS color string, e.g. an hsl() / token). When a plugin supplies one, the overlay paints the tab's dot + active underline with it; when omitted (the default null), the overlay derives a stable, deterministic color from the ChannelName so every channel still reads as a distinct, colored surface. A channel only overrides this to enforce a specific brand accent.

      Returns string | null

    Methods

    • Resolves the live RealtimeChannelContext.AgentSessionID, briefly WAITING for it when it isn't bound yet rather than giving up instantly. AgentSessionID is a live getter over the session service's current id: it reads null in the window BEFORE the session mints (the realtime model can fire a tool call the very first beat it connects, before mintSession resolves) and again AFTER teardown. Server-backed tool paths (e.g. the Remote Browser channel's browser_* tools) call this instead of reading Context?.AgentSessionID synchronously, so a tool invoked a beat early WAITS for the session to come live — defense-in-depth against the "session id missing" race — instead of returning a hard failure to the model.

      Returns the id as soon as it's non-null (the common path resolves immediately, no delay), or null if it's still unbound after SessionIdWaitTimeoutMs — or the channel was Disposed in the meantime (Context goes null, so we stop waiting on a torn-down session).

      Returns Promise<string | null>