ProtectedContextThe bound session context, available from Initialize until Dispose.
null outside that window — guard with ?. in any code that can run early/late.
The channel definition name — MUST match the MJ: AI Agent Channels row's Name
(e.g. 'Whiteboard'). The host routes OnChannelStateSave by the registry row's
name and warns when a resolved plugin's ChannelName disagrees with its row.
The shared name prefix of every server-executed tool this channel contributes (e.g.
'MeetingControls_'). The host routes any tool call whose name starts with this prefix to
THIS plugin's ExecuteServerTool, which is what prevents tool-name collisions when
multiple channels are active in one session. A channel that contributes no server tools may
leave the default empty string (the host then never routes any call to it).
Mirrors the client half's ToolNamePrefix. Default: '' (no server tools).
Disposal hook (fires after the host's post-close linger window). A safety net mirroring
OnSessionClosed — if the session somehow closed without it running, this still releases any
browser the session held. Idempotent against the engine's own no-op-when-absent teardown. MUST call
super.Dispose() to drop the bound context.
Executes ONE of this channel's server-side tools (a tool whose name starts with
ToolNamePrefix) and returns the result fed back to the model as the tool_response.
Implementations should NOT throw — return a { Success: false, Output } result so the model can
narrate the failure. The host additionally wraps anything thrown into a structured error, so a
throwing implementation can never break the live session. The default implementation returns a
structured "not implemented" error, so a channel that declares tools via
GetServerToolDefinitions but forgets to implement execution fails safely and visibly.
The full tool name the model invoked (begins with ToolNamePrefix).
The raw arguments JSON string the model emitted for the call.
The execution result (or a structured error), synchronously or as a promise.
Returns this channel's server-executed tool declarations — the tools the agent can invoke
on this channel that run server-side (a bot has no browser). May be runtime-computed: the
returned set can depend on the live session, the connected platform, or current channel state,
so a bridge-contributed channel can declare a vocabulary that only exists because of the live
connection. Every tool's Name SHOULD start with ToolNamePrefix so the host can route
its execution back here unambiguously.
Invoked by RealtimeChannelServerHost when assembling the session's tool set (after the
plugin's OnSessionStarted). Default: [] (a state-only channel contributes none).
The channel's server-executed tool definitions (possibly empty).
Binds the session context and invokes the OnInitialize hook. Called exactly once per session by the host, right after ClassFactory instantiation and before any lifecycle hook.
Invoked when the client's debounced channel-state save for THIS channel lands on the server,
BEFORE the state is persisted onto the session's MJ: AI Agent Session Channels row.
The plugin may validate/normalize the payload: return a replacement JSON string to persist
instead of stateJson, or null to persist the original unchanged (the default). The host
treats a thrown error, a non-string, or an empty string as "keep the original" — a plugin can
therefore never lose a state save, only improve it.
The raw state-of-record payload the client submitted (already size-capped host-side).
The normalized payload to persist, or null to keep stateJson as-is.
ProtectedOnSubclass hook invoked from Initialize once Context is bound — allocate any per-session state here. Default: no-op.
Session-closed hook (every close provenance funnels here). Tears down any browser this session
lazily started via the ExecuteRemoteBrowserAction mutation. Best-effort: teardown failures are
logged, never thrown, so a channel plugin can never break a closing session.
The persisted close provenance (unused — every reason tears the browser down).
Invoked by the host immediately after Initialize, when the durable session record has
been persisted (Status = 'Active') — the session id, agent, and conversation are all in
Context. Default: no-op.
Server half of the Remote Browser interactive channel — ONE instance per realtime session, created by
RealtimeChannelServerHostfrom the channel registry (never constructed directly). Registered under'RemoteBrowserChannelServer'so the seeded registry row resolves it via the ClassFactory.It is deliberately a lifecycle-only plugin: it contributes no server-executed tools (the agent's browser tools are client-executed in the client-direct topology and reach the server through the
ExecuteRemoteBrowserActionmutation). Its sole job is teardown — when the session closes or the plugin is disposed, end any browser the session lazily started so a leased Chrome is never leaked.