ChatDock 2.0 — A Drop-in Blazor Chat Panel for AI Agents
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:
@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:
<!-- 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:
| Position | Icon Location | Panel Behavior |
|---|---|---|
BottomRight | Bottom-right corner | Panel slides up (default) |
BottomLeft | Bottom-left corner | Panel slides up |
Right | Right edge | Full-height panel slides in from right |
Left | Left edge | Full-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.
<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— aFunc<AgentMessage, Task<bool>>invoked when the agent responds. Returntrueto display the message in chat,falseto suppress it. Useful for routing status updates to a sidebar without cluttering the conversation.OnMessageSent— anEventCallback<string>fired when the user sends a message. Use it to trigger page refreshes or log activity.
<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:
<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:
<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
| Parameter | Type | Default | Description |
|---|---|---|---|
UserHandle | string | — | User/client identifier (required) |
AgentHandle | string | — | Agent instance handle (required) |
AgentType | string | — | Matches [AgentAlias] (required) |
SystemPrompt | string | "You are a helpful AI assistant." | System instructions |
Title | string | "Assistant" | Panel header title |
Icon | string | "bi bi-chat-dots" | Bootstrap icon class |
WelcomeMessage | string | "How can I help you today?" | Empty state message |
Position | ChatDockPosition | BottomRight | Panel position |
LazyLoad | bool | false | Defer agent creation until first expand |
Plugins | List<string> | null | Plugin aliases to enable |
Tools | List<string> | null | Standalone 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.
Builder of FabrCore and OpenCaddis.