diff --git a/x-blazor-skill/.claude-plugin/marketplace.json b/x-blazor-skill/.claude-plugin/marketplace.json
new file mode 100644
index 0000000..ba0e645
--- /dev/null
+++ b/x-blazor-skill/.claude-plugin/marketplace.json
@@ -0,0 +1,35 @@
+{
+ "name": "x-blazor-skills",
+ "metadata": {
+ "description": "AntDesign.X.Blazor skill package for building AI chat and agent workspace interfaces in Blazor.",
+ "descriptionZh": "AntDesign.X.Blazor 智能技能包,用于在 Blazor 中构建 AI 对话和 Agent 工作台界面。",
+ "version": "1.0.0",
+ "author": "IoTSharp",
+ "homepage": "https://github.com/IoTSharp/AntDesignXBlazor",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/IoTSharp/AntDesignXBlazor.git"
+ },
+ "keywords": [
+ "ant-design-x",
+ "ant-design-x-blazor",
+ "blazor",
+ "ai",
+ "chat",
+ "agent",
+ "dotnet"
+ ]
+ },
+ "plugins": [
+ {
+ "name": "x-blazor-skill",
+ "description": "AntDesign.X.Blazor component, chat store, request client, streaming, and React-to-Blazor migration guidance.",
+ "descriptionZh": "AntDesign.X.Blazor 组件、聊天状态、请求客户端、流式响应以及 React 到 Blazor 迁移指南。",
+ "source": "./",
+ "strict": false,
+ "skills": [
+ "./skills/x-blazor-skill"
+ ]
+ }
+ ]
+}
diff --git a/x-blazor-skill/.skill.json b/x-blazor-skill/.skill.json
new file mode 100644
index 0000000..fe19740
--- /dev/null
+++ b/x-blazor-skill/.skill.json
@@ -0,0 +1,32 @@
+{
+ "targets": {
+ "codefuse": {
+ "enabled": true,
+ "paths": {
+ "global": ".codefuse/fuse/skills",
+ "project": ".codefuse/skills"
+ }
+ },
+ "claude": {
+ "enabled": true,
+ "paths": {
+ "global": ".claude/skills",
+ "project": ".claude/skills"
+ }
+ },
+ "cursor": {
+ "enabled": true,
+ "paths": {
+ "global": ".cursor/skills",
+ "project": ".cursor/skills"
+ }
+ },
+ "codex": {
+ "enabled": true,
+ "paths": {
+ "global": ".codex/skills",
+ "project": ".codex/skills"
+ }
+ }
+ }
+}
diff --git a/x-blazor-skill/package.json b/x-blazor-skill/package.json
new file mode 100644
index 0000000..b2c6a39
--- /dev/null
+++ b/x-blazor-skill/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "x-blazor-skill",
+ "version": "1.0.0",
+ "description": "AI agent skill package for building AntDesign.X.Blazor chat and agent workspace interfaces.",
+ "homepage": "https://github.com/IoTSharp/AntDesignXBlazor",
+ "license": "MIT",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/IoTSharp/AntDesignXBlazor.git"
+ },
+ "keywords": [
+ "ant-design-x",
+ "ant-design-x-blazor",
+ "blazor",
+ "ai",
+ "chat",
+ "agent",
+ "skill"
+ ],
+ "files": [
+ "skills",
+ ".skill.json",
+ ".claude-plugin"
+ ]
+}
diff --git a/x-blazor-skill/skills/x-blazor-skill/SKILL.md b/x-blazor-skill/skills/x-blazor-skill/SKILL.md
new file mode 100644
index 0000000..5745a7b
--- /dev/null
+++ b/x-blazor-skill/skills/x-blazor-skill/SKILL.md
@@ -0,0 +1,135 @@
+---
+name: x-blazor-skill
+description: Build AI chat, agent workspace, and content-generation interfaces with AntDesign.X.Blazor. Use when working in Blazor projects that need Ant Design X concepts such as XProvider, XBubbleList, XSender, XConversations, XPrompts, XMarkdown, XMermaid, XChatStore, XAgentStore, IXRequestClient, streaming replies, attachments, sources, thought chains, or React Ant Design X to Blazor migration guidance.
+---
+
+# X Blazor Skill
+
+## Overview
+
+Use this skill to build Ant Design X style AI experiences in pure Blazor with `AntDesign.X.Blazor` and `AntDesign.Blazor`.
+
+This library maps Ant Design X concepts to C# records, Razor components, `EventCallback`, `RenderFragment`, and scoped stores. Do not use React hooks, JSX, or `@ant-design/x` APIs in Blazor code.
+
+## Setup
+
+Install and register both AntDesign.Blazor and AntDesign.X.Blazor:
+
+```powershell
+dotnet add package AntDesignX.Blazor
+```
+
+```html
+
+
+
+```
+
+```csharp
+using AntDesign.X;
+
+builder.Services.AddAntDesign();
+builder.Services.AddAntDesignX();
+```
+
+In Razor files, add:
+
+```razor
+@using AntDesign.X
+@using AntDesign.X.Components
+```
+
+For `XMermaid`, include Mermaid separately:
+
+```html
+
+```
+
+## Decision Guide
+
+| If you need to... | Start with |
+| --- | --- |
+| Render chat messages | `XBubbleList` with `IReadOnlyList` |
+| Render one-off assistant/user content | `XBubble` |
+| Build the chat composer | `XSender` and `XSenderRequest` |
+| Keep chat state and stream assistant replies | `XChatStore` |
+| Call an agent endpoint directly | `XAgentStore` or `IXRequestClient` |
+| Show sessions or history | `XConversations` and `XConversationItem` |
+| Show suggested prompts | `XPrompts` and `XPromptItem` |
+| Support file input | `XSender` attachments or `XAttachments` |
+| Display citations | `XSources` |
+| Display tool or reasoning progress | `XThoughtChain` or `XThink` |
+| Render Markdown, code, or diagrams | `XMarkdown`, `XCodeHighlighter`, `XMermaid` |
+| Apply X theme tokens | `XProvider` with optional `XThemeTokens` |
+
+## Workflow
+
+1. Read the host app's existing Blazor patterns before changing UI.
+2. Register services and static assets once at the app boundary.
+3. Wrap the AI surface with `XProvider`.
+4. Use model records from `AntDesign.X` instead of anonymous dictionaries for component data.
+5. Use `XBubbleList` for message collections; reserve `XBubble` for single messages or custom templates.
+6. Bind `XSender` through `@bind-Value` and handle `OnSubmit(XSenderRequest request)`.
+7. For streaming, update `XBubbleItem.Content`, `Streaming`, `Loading`, and `Status` through `XChatStore` or `XAgentStore` rather than ad hoc UI flags.
+8. Check reference files only when needed:
+ - [COMPONENTS.md](reference/COMPONENTS.md) for component choice and key props.
+ - [PATTERNS.md](reference/PATTERNS.md) for full-page composition examples.
+ - [API.md](reference/API.md) for model records, service APIs, and React-to-Blazor mappings.
+
+## Development Rules
+
+- Prefer `XProvider` around chat/workspace surfaces so theme tokens and locale services are available.
+- Prefer `XBubbleList` over manually looping `XBubble` for normal chat logs; it handles role defaults, loading rows, auto-scroll, and optional virtualization.
+- Use `Role` values such as `user`, `assistant`, `system`, and `tool`; role config defaults are case-insensitive.
+- Use `ContentTemplate`, `HeaderTemplate`, `FooterTemplate`, and item templates for rich Razor content. Do not serialize complex Blazor UI into strings.
+- Set `Markdown="true"` only when the content should be parsed as Markdown.
+- Treat `Streaming=true` as a transient state and set it to `false` when the final chunk arrives.
+- Use `XSender.Loading` plus `OnCancel` for stop behavior while a request is running.
+- Keep user secrets and model API keys on the server. Do not embed provider keys in browser-delivered Blazor WebAssembly code.
+- Keep custom CSS under the host app's scope; AntDesign.X.Blazor classes use the `antdx-` prefix.
+- Prefer examples under `examples/AntDesign.X.Blazor.Demo/Components/Pages/Components` when exact syntax is uncertain.
+
+## Minimal Example
+
+```razor
+@using AntDesign.X
+@using AntDesign.X.Components
+@using Microsoft.AspNetCore.Components.Forms
+
+
+
+
+
+
+
+@code {
+ private string? draft;
+ private bool loading;
+ private readonly List messages = [];
+ private readonly List attachments = [];
+
+ private Task Submit(XSenderRequest request)
+ {
+ messages.Add(new XBubbleItem
+ {
+ Role = "user",
+ Content = request.Text,
+ Attachments = request.Attachments
+ });
+
+ draft = string.Empty;
+ return Task.CompletedTask;
+ }
+
+ private Task Cancel() => Task.CompletedTask;
+ private Task HandleAction(string key) => Task.CompletedTask;
+ private Task AddFiles(IReadOnlyList files) => Task.CompletedTask;
+ private Task RemoveAttachment(string id) => Task.CompletedTask;
+}
+```
diff --git a/x-blazor-skill/skills/x-blazor-skill/agents/openai.yaml b/x-blazor-skill/skills/x-blazor-skill/agents/openai.yaml
new file mode 100644
index 0000000..5880448
--- /dev/null
+++ b/x-blazor-skill/skills/x-blazor-skill/agents/openai.yaml
@@ -0,0 +1,4 @@
+interface:
+ display_name: "AntDesign.X Blazor"
+ short_description: "Build Ant Design X chat UIs in Blazor"
+ default_prompt: "Use $x-blazor-skill to build an AntDesign.X.Blazor chat UI."
diff --git a/x-blazor-skill/skills/x-blazor-skill/reference/API.md b/x-blazor-skill/skills/x-blazor-skill/reference/API.md
new file mode 100644
index 0000000..7c5da0a
--- /dev/null
+++ b/x-blazor-skill/skills/x-blazor-skill/reference/API.md
@@ -0,0 +1,164 @@
+# AntDesign.X.Blazor API Notes
+
+Use this reference for service registration, core records, and request/streaming APIs.
+
+## Namespaces
+
+```razor
+@using AntDesign.X
+@using AntDesign.X.Components
+```
+
+```csharp
+using AntDesign.X;
+```
+
+Component classes live under `AntDesign.X.Components`; models, services, and extension methods live under `AntDesign.X`.
+
+## Service Registration
+
+`AddAntDesignX` registers:
+
+| Service | Lifetime | Purpose |
+| --- | --- | --- |
+| `XRequestClientOptions` | singleton | Request paths, base address, timeout, headers |
+| `IXNotificationService` | scoped | Notification queue |
+| `IXRequestClient` | scoped | Low-level request and stream client |
+| `XChatStore` | scoped | Chat message state and streaming lifecycle |
+| `XAgentStore` | scoped | Agent message/event/tool-call state |
+| `IXRendererRegistry` | singleton | Render delegation registry |
+| `IXLocaleService` | scoped | Component text locale service |
+
+```csharp
+builder.Services.AddAntDesignX(options =>
+{
+ options.BaseAddress = new Uri("https://example.com");
+ options.ChatPath = "/api/chat";
+ options.AgentPath = "/api/agent";
+ options.Timeout = TimeSpan.FromMinutes(2);
+ options.DefaultHeaders["x-client"] = "blazor";
+});
+```
+
+## Core Records
+
+| Record | Use |
+| --- | --- |
+| `XBubbleItem` | Message rows for `XBubbleList`. |
+| `XBubbleRoleConfig` | Role-specific placement, avatar, Markdown, shape, and template defaults. |
+| `XAttachmentItem` | Files displayed by `XSender`, `XAttachments`, `XFileCard`, or message bubbles. |
+| `XActionItem` | Button/action metadata for `XActions`, `XBubble`, and `XSender`. |
+| `XConversationItem` | Conversation list item. |
+| `XPromptItem` | Prompt card item, including nested children. |
+| `XSourceItem` | Citation/source row. |
+| `XThoughtItem` | Thought chain node. |
+| `XFolderItem` | File/folder tree item. |
+| `XNotificationItem` | Notification payload. |
+| `XSenderRequest` | Submitted text plus attachments. |
+| `XThemeTokens` | Theme custom properties for `XProvider`. |
+
+Prefer these records over anonymous objects so code remains strongly typed.
+
+## XBubbleItem Example
+
+```csharp
+var message = new XBubbleItem
+{
+ Role = "assistant",
+ Header = "Assistant",
+ AvatarIcon = "robot",
+ Content = "Here is **Markdown** content.",
+ Markdown = true,
+ Streaming = false,
+ Status = XMessageStatus.Success,
+ Actions =
+ [
+ new XActionItem { Key = "copy", Icon = "copy", Tooltip = "Copy" },
+ new XActionItem { Key = "retry", Icon = "reload", Tooltip = "Retry" }
+ ]
+};
+```
+
+## Request Client
+
+Use `IXRequestClient` when you need custom control below `XChatStore` or `XAgentStore`.
+
+```csharp
+var handle = await RequestClient.RequestAsync(new XRequestOptions
+{
+ RequestId = Guid.NewGuid().ToString("N"),
+ RequestUri = new Uri("/api/chat", UriKind.Relative),
+ Body = payload,
+ Stream = true,
+ StreamMode = XStreamReadMode.Sse,
+ OnChunk = chunk =>
+ {
+ // Append chunk content to the active assistant message.
+ return Task.CompletedTask;
+ }
+}, cancellationToken);
+
+await handle.Completion;
+```
+
+Use the stores first unless the app needs a custom protocol or message lifecycle.
+
+## Chat Store
+
+`XChatStore` exposes:
+
+| Member | Use |
+| --- | --- |
+| `Messages` | Snapshot for `XBubbleList.Items`. |
+| `IsLoading` | Bind to `XSender.Loading` and `XBubbleList.Loading`. |
+| `LastError` | Render errors or notifications. |
+| `ActiveRequestId` | Track the running assistant request. |
+| `Changed` | Subscribe and call `StateHasChanged`. |
+| `SubmitAsync(XSenderRequest, ct)` | Append user message and stream assistant response. |
+| `RetryAsync(ct)` | Re-run the last submission. |
+| `AbortAsync()` | Cancel the active request. |
+| `ReplaceMessages(...)` | Reset or hydrate conversation state. |
+
+Always unsubscribe from `Changed` in `Dispose`.
+
+## Agent Store
+
+`XAgentStore` follows the same UI subscription pattern as `XChatStore` and is intended for agent workflows. Use it when the UI shows tool calls, events, or agent-specific progress alongside chat messages.
+
+Typical binding:
+
+```razor
+
+
+
+```
+
+## Static Assets
+
+Include:
+
+```html
+
+
+
+```
+
+Add Mermaid only when rendering `XMermaid`:
+
+```html
+
+```
+
+## File Upload Notes
+
+Blazor file input uses `IBrowserFile`. Use `BeforeUpload` to filter files before they enter the attachment list.
+
+```csharp
+private ValueTask BeforeUpload(IBrowserFile file)
+{
+ var accepted = file.Size <= 10 * 1024 * 1024;
+ return ValueTask.FromResult(accepted);
+}
+```
+
+Do not trust browser-provided file metadata for security decisions on the server.
diff --git a/x-blazor-skill/skills/x-blazor-skill/reference/COMPONENTS.md b/x-blazor-skill/skills/x-blazor-skill/reference/COMPONENTS.md
new file mode 100644
index 0000000..c7bded6
--- /dev/null
+++ b/x-blazor-skill/skills/x-blazor-skill/reference/COMPONENTS.md
@@ -0,0 +1,186 @@
+# AntDesign.X.Blazor Components
+
+Use this reference when selecting components or checking the main data model for a UI surface.
+
+## Component Groups
+
+| Stage | Components | Blazor data |
+| --- | --- | --- |
+| General chat | `XBubble`, `XBubbleList`, `XConversations`, `XNotification` | `XBubbleItem`, `XConversationItem`, `XNotificationItem` |
+| Wake / prompt | `XWelcome`, `XPrompts` | `XPromptItem` |
+| Express / input | `XSender`, `XAttachments`, `XSuggestion` | `XSenderRequest`, `XAttachmentItem` |
+| Thinking | `XThoughtChain`, `XThink` | `XThoughtItem` |
+| Feedback / evidence | `XActions`, `XFileCard`, `XSources`, `XFolder` | `XActionItem`, `XSourceItem`, `XFolderItem` |
+| Content rendering | `XMarkdown`, `XCodeHighlighter`, `XMermaid` | string content plus optional templates |
+| Global | `XProvider` | `XThemeTokens` |
+
+## XProvider
+
+Wrap the AI experience in `XProvider` when you need theme, locale, or token support.
+
+```razor
+
+ @ChildContent
+
+
+@code {
+ private readonly XThemeTokens tokens = new()
+ {
+ PrimaryColor = "#1677ff",
+ BubbleStartBackground = "#f6f8fa",
+ BubbleEndBackground = "#e6f4ff"
+ };
+}
+```
+
+Use `Theme="light"` or `Theme="dark"`. `Tokens` become CSS custom properties through the `antdx-` styling layer.
+
+## XBubble and XBubbleList
+
+Use `XBubbleList` for normal chat history:
+
+```razor
+
+```
+
+`XBubbleList` applies default role config for:
+
+| Role | Default behavior |
+| --- | --- |
+| `assistant` / `ai` | start placement, filled, round, Markdown enabled |
+| `user` | end placement, filled, corner, Markdown enabled |
+| `system` | start placement, outlined, Markdown enabled |
+| `tool` | start placement, borderless, Markdown enabled |
+| `divider` | renders as a divider row |
+
+Use `XBubble` when rendering a single message or a fully custom slot:
+
+```razor
+
+```
+
+Key properties:
+
+| Property | Notes |
+| --- | --- |
+| `Role` | Semantic role used for styling and defaults. |
+| `Placement` | `Start` or `End`. User messages normally use `End`. |
+| `Variant` | Filled, outlined, borderless, and other enum values from `XBubbleVariant`. |
+| `Shape` | Default, round, or corner shape enum. |
+| `Content` | Plain text or Markdown string. |
+| `ContentTemplate` | Use for rich Razor UI. |
+| `Actions` | `IReadOnlyList` shown in the footer. |
+| `Attachments` | `IReadOnlyList` rendered compactly below content. |
+| `Loading` / `Streaming` / `Status` | Drive loading and stream state. |
+
+## XSender
+
+Use `XSender` for the composer. Bind draft text with `@bind-Value`; handle send with `OnSubmit`.
+
+```razor
+
+```
+
+Key properties:
+
+| Property | Notes |
+| --- | --- |
+| `Value` / `ValueChanged` | Text draft binding. |
+| `OnSubmit` | Receives `XSenderRequest` with `Text` and `Attachments`. |
+| `Loading` | Shows stop behavior and disables submit. |
+| `SubmitMode` | Controls Enter-key behavior via `XSenderSubmitMode`. |
+| `AttachmentsEnabled` | Enables the built-in file input surface. |
+| `BeforeUpload` | `Func>` filter. |
+| `Actions` / `OnAction` | Custom composer buttons. |
+| `HeaderTemplate`, `PrefixTemplate`, `SuffixTemplate`, `FooterTemplate` | Rich slots. |
+| `AllowSpeech` | Enables browser speech input when supported. |
+
+## Navigation and Prompt Components
+
+Use `XConversations` for session lists, `XPrompts` for suggested tasks, and `XSuggestion` for inline command hints.
+
+```razor
+
+
+
+```
+
+Create stable keys for conversation and prompt items so Blazor can preserve state across renders.
+
+## Attachments and Files
+
+Use `XAttachments` when the attachment list is independent from `XSender`; otherwise use the built-in attachment support on `XSender`.
+
+```razor
+
+```
+
+Represent files with `XAttachmentItem`; include `Name`, `ContentType`, `Size`, `Status`, and optional `Percent`.
+
+## Thinking, Sources, and Feedback
+
+Use `XThoughtChain` for multi-step agent/tool progress and `XThink` for one collapsible reasoning block.
+
+```razor
+
+
+
+```
+
+Use `XSources` for citations and retrieved documents. Use `XActions` for copy, retry, like/dislike, or custom operations under a message.
+
+## Content Rendering
+
+Use `XMarkdown` for Markdown strings, `XCodeHighlighter` for explicit code blocks, and `XMermaid` for diagrams.
+
+```razor
+
+
+
+```
+
+If content is part of a bubble, prefer `XBubble Markdown="true"` for simple Markdown and `ContentTemplate` for mixed Markdown/components.
+
+## Notifications
+
+Use `IXNotificationService` with `XNotification` host when the page needs queued status messages.
+
+```razor
+
+```
+
+Inject the service where actions occur:
+
+```csharp
+[Inject] private IXNotificationService Notifications { get; set; } = default!;
+```
diff --git a/x-blazor-skill/skills/x-blazor-skill/reference/PATTERNS.md b/x-blazor-skill/skills/x-blazor-skill/reference/PATTERNS.md
new file mode 100644
index 0000000..8a2af0a
--- /dev/null
+++ b/x-blazor-skill/skills/x-blazor-skill/reference/PATTERNS.md
@@ -0,0 +1,248 @@
+# AntDesign.X.Blazor Patterns
+
+Use this reference for full-page composition and streaming flows.
+
+## App Registration Pattern
+
+Register AntDesign.Blazor first, then AntDesign.X.Blazor:
+
+```csharp
+using AntDesign.X;
+
+builder.Services.AddAntDesign();
+builder.Services.AddAntDesignX(options =>
+{
+ options.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress);
+ options.ChatPath = "/api/chat";
+});
+```
+
+Include static assets once in the host document:
+
+```html
+
+
+
+```
+
+## Manual Local Chat Pattern
+
+Use this pattern when no server call is needed yet.
+
+```razor
+@using AntDesign.X
+@using AntDesign.X.Components
+@using Microsoft.AspNetCore.Components.Forms
+
+
+
+
+
+
+
+
+
+
+
+@code {
+ private string theme = "light";
+ private string? draft;
+ private readonly List messages = [];
+ private readonly List attachments = [];
+
+ private readonly IReadOnlyList prompts =
+ [
+ new() { Key = "summary", Title = "Summarize", Description = "Summarize the current document" },
+ new() { Key = "ideas", Title = "Ideas", Description = "Suggest follow-up questions" }
+ ];
+
+ private Task UsePrompt(XPromptItem item)
+ {
+ draft = item.Description ?? item.Title;
+ return Task.CompletedTask;
+ }
+
+ private Task Submit(XSenderRequest request)
+ {
+ messages.Add(new XBubbleItem
+ {
+ Role = "user",
+ Content = request.Text,
+ Attachments = request.Attachments
+ });
+
+ messages.Add(new XBubbleItem
+ {
+ Role = "assistant",
+ Header = "Assistant",
+ AvatarIcon = "robot",
+ Content = "Received: " + request.Text,
+ Markdown = true
+ });
+
+ draft = string.Empty;
+ return Task.CompletedTask;
+ }
+
+ private Task AddFiles(IReadOnlyList files)
+ {
+ attachments.AddRange(files.Select(file => new XAttachmentItem
+ {
+ Name = file.Name,
+ ContentType = file.ContentType,
+ Size = file.Size
+ }));
+
+ return Task.CompletedTask;
+ }
+
+ private Task RemoveAttachment(string id)
+ {
+ attachments.RemoveAll(item => item.Id == id);
+ return Task.CompletedTask;
+ }
+}
+```
+
+## Store-Based Streaming Pattern
+
+Use `XChatStore` for normal chat screens. It appends the user message, creates an assistant placeholder, streams chunks into the assistant message, and exposes `Changed`.
+
+```razor
+@implements IDisposable
+@inject XChatStore Chat
+
+
+
+
+
+
+
+@code {
+ private string? draft;
+
+ protected override void OnInitialized()
+ {
+ Chat.Changed += StateHasChanged;
+ }
+
+ public void Dispose()
+ {
+ Chat.Changed -= StateHasChanged;
+ }
+
+ private async Task Submit(XSenderRequest request)
+ {
+ await Chat.SubmitAsync(request);
+ draft = string.Empty;
+ }
+
+ private Task HandleAction(string actionKey)
+ {
+ return actionKey switch
+ {
+ "retry" => Chat.RetryAsync(),
+ "abort" => Chat.AbortAsync(),
+ _ => Task.CompletedTask
+ };
+ }
+}
+```
+
+## Agent Store Pattern
+
+Use `XAgentStore` when the screen is agent-first rather than chat-first. Bind `IsRunning` to sender loading state and subscribe to `Changed` just like `XChatStore`.
+
+```razor
+@implements IDisposable
+@inject XAgentStore Agent
+
+
+
+
+
+@code {
+ private string? prompt;
+
+ protected override void OnInitialized()
+ {
+ Agent.Changed += StateHasChanged;
+ }
+
+ public void Dispose()
+ {
+ Agent.Changed -= StateHasChanged;
+ }
+
+ private Task RunAgent(XSenderRequest request)
+ {
+ return Agent.RunAsync(new XAgentRequest
+ {
+ Prompt = request.Text,
+ Attachments = request.Attachments
+ });
+ }
+
+ private static XThoughtItem ToThought(XAgentEventItem item) => new()
+ {
+ Key = item.Key,
+ Title = item.Title,
+ Description = item.Description,
+ Content = item.Content,
+ Status = item.Status
+ };
+}
+```
+
+## Server Boundary Pattern
+
+Keep provider API keys and model credentials on the server. Point the client to an app-owned endpoint through `XRequestClientOptions`.
+
+```csharp
+builder.Services.AddAntDesignX(options =>
+{
+ options.ChatPath = "/api/ai/chat";
+ options.AgentPath = "/api/ai/agent";
+ options.Timeout = TimeSpan.FromMinutes(5);
+});
+```
+
+Use server-side middleware or API routes to translate `XChatRequestPayload` or `XAgentRequestPayload` into your provider-specific request.
+
+## React Ant Design X Migration Pattern
+
+Map React concepts to Blazor concepts directly:
+
+| React Ant Design X | AntDesign.X.Blazor |
+| --- | --- |
+| `XProvider` | `XProvider` Razor component |
+| `Bubble.List` | `XBubbleList` |
+| `Bubble` | `XBubble` |
+| `Sender` | `XSender` |
+| `Conversations` | `XConversations` |
+| `Prompts` | `XPrompts` |
+| `Attachments` | `XAttachments` |
+| `ThoughtChain` | `XThoughtChain` |
+| `Think` | `XThink` |
+| `Sources` | `XSources` |
+| `useXChat` | `XChatStore` |
+| `useXAgent` | `XAgentStore` |
+| `XRequest` | `IXRequestClient` |
+| JSX slots | `RenderFragment` parameters |
+| event props | `EventCallback` parameters |
+
+Do not copy JSX examples verbatim. Rebuild them as Razor markup with C# model records.