Release

ChatDock 2.0 — A Drop-in Blazor Chat Panel for AI Agents

Eric Brasher February 27, 2026 at 10:30 AM 7 min read

ChatDock is FabrCore's floating chat panel component for Blazor Server. Drop it onto any page and your users get a fully managed AI agent conversation — complete with markdown rendering, typing indicators, health status, and keyboard shortcuts. Version 2.0 adds four-position sizing, document upload, agent lifecycle management, plugin output rendered inline, and support for cross-owner agents.

Getting Started

ChatDock renders as a small circular icon (36×36px) that expands into a full chat panel when clicked. The panel is portaled to document.body via JavaScript so it escapes any CSS stacking contexts on the page. Here is the minimal markup:

Razor — Basic ChatDock Usage
@using FabrCore.Client.Components

<ChatDock UserHandle="user1"
          AgentHandle="assistant"
          AgentType="my-agent"
          SystemPrompt="You are a helpful assistant."
          Title="Assistant" />

ChatDock manages the full agent lifecycle internally — it connects via IClientContext, checks whether the agent is already configured with GetAgentHealth(), creates the agent if needed, and cleans up on dispose. Messages are sent with SendMessage (fire-and-forget) and responses arrive through the AgentMessageReceived event subscription.

Include the FabrCore stylesheet in your App.razor or _Host.cshtml:

HTML — Static Assets
<!-- In App.razor or _Host.cshtml -->
<link href="_content/FabrCore.Client/fabrcore.css" rel="stylesheet" />

Positioning & Sizing

ChatDock supports four positions through the ChatDockPosition enum. Each controls where the floating icon appears and how the panel slides in:

PositionIcon LocationPanel Behavior
BottomRightBottom-right cornerPanel slides up (default)
BottomLeftBottom-left cornerPanel slides up
RightRight edgeFull-height panel slides in from right
LeftLeft edgeFull-height panel slides in from left

On mobile viewports (under 480px), the panel automatically expands to full width regardless of the configured position. The floating icon uses color to indicate state: blue for connected, green pulsing for open, orange pulsing for unread messages, and gray for lazy/not yet loaded.

Razor — Full-Height Right Panel
<ChatDock UserHandle="user1"
          AgentHandle="code-reviewer"
          AgentType="code-review-agent"
          Title="Code Review"
          Icon="bi bi-code-slash"
          Position="ChatDockPosition.Right"
          LazyLoad="true" />

Setting LazyLoad="true" defers agent creation until the user first opens the panel, which is useful when a page hosts multiple ChatDock instances and you want to avoid creating agents the user may never interact with.

Document Upload & Agent Reset

ChatDock 2.0 includes a file upload area within the chat input. Users can drag and drop documents directly into the chat panel or click to select files. Uploaded files are sent to the agent via the FabrCore File API — the file is stored server-side and the file ID is attached to the AgentMessage.Files list. The agent's plugins and tools can then retrieve and process the document.

The panel header includes a clear button that resets the conversation. This destroys the current agent session and chat history, then re-creates the agent with a fresh configuration. It is equivalent to starting a new conversation without navigating away from the page.

Callbacks & Multi-Dock Coordination

Two callback parameters let the host page react to ChatDock activity:

  • OnMessageReceived — a Func<AgentMessage, Task<bool>> invoked when the agent responds. Return true to display the message in chat, false to suppress it. Useful for routing status updates to a sidebar without cluttering the conversation.
  • OnMessageSent — an EventCallback<string> fired when the user sends a message. Use it to trigger page refreshes or log activity.
Razor — Scoped ChatDock with Callbacks
<ChatDock UserHandle="user1"
          AgentHandle="@($"project-{ProjectId}")"
          AgentType="project-agent"
          SystemPrompt="@($"You manage project {ProjectId}. Use this ID automatically.")"
          Title="Project Assistant"
          OnMessageSent="@(async (msg) => { await RefreshData(); StateHasChanged(); })"
          Position="ChatDockPosition.Right" />

When a page hosts multiple ChatDock instances, use the ChatDockManager to coordinate them — only one panel can be expanded at a time. Wrap the docks in a CascadingValue:

Razor — Multiple ChatDocks with Manager
<CascadingValue Value="chatDockManager">
    <ChatDock UserHandle="user1" AgentHandle="coding-agent"
              AgentType="code-reviewer" Title="Code Review"
              Position="ChatDockPosition.BottomRight" />
    <ChatDock UserHandle="user1" AgentHandle="writing-agent"
              AgentType="writer" Title="Writing Help"
              Position="ChatDockPosition.BottomLeft" />
</CascadingValue>

@code {
    [Inject] ChatDockManager chatDockManager { get; set; } = default!;
}

Cross-Owner Messaging

ChatDock can connect to agents owned by a different user or the system. When AgentHandle contains a colon, ChatDock skips auto-creation — the agent must already exist server-side. This is the pattern for shared system agents or agents owned by another tenant:

Razor — Cross-Owner Agent
<ChatDock UserHandle="@userId"
          AgentHandle="system:automation_agent-123"
          AgentType="automation-agent"
          Title="Automation" />

Response matching uses the full handle as FromHandle, and the ACL system enforces Message permission before delivery. If the cross-owner agent is not yet configured, ChatDock displays an error state rather than attempting to create it.

Full Parameter Reference

ParameterTypeDefaultDescription
UserHandlestringUser/client identifier (required)
AgentHandlestringAgent instance handle (required)
AgentTypestringMatches [AgentAlias] (required)
SystemPromptstring"You are a helpful AI assistant."System instructions
Titlestring"Assistant"Panel header title
Iconstring"bi bi-chat-dots"Bootstrap icon class
WelcomeMessagestring"How can I help you today?"Empty state message
PositionChatDockPositionBottomRightPanel position
LazyLoadboolfalseDefer agent creation until first expand
PluginsList<string>nullPlugin aliases to enable
ToolsList<string>nullStandalone tool aliases to enable

CSS customization is available through three custom properties: --chat-dock-primary, --chat-dock-width, and --chat-dock-icon-size.


Built with FabrCore on .NET 10.


Eric Brasher

Builder of FabrCore and OpenCaddis.