logoAnt Design X

⌘ K
DesignDevelopmentComponentsX MarkdownX SDKX CardX SkillPlayground
  • Introduction
  • Data Flow
    • useXChatConversation Data
      2.0.0
    • useXConversations
      2.0.0
  • Chat Provider
    • Chat Provider
      2.0.0
    • Agent ProviderAgent Event Integration
      2.9.0
    • OpenAIChatProvider
      2.0.0
    • DeepSeekChatProvider
      2.0.0
    • Custom Chat Provider
      2.0.0
  • Utilities
    • XRequestRequest
      2.0.0
    • XStreamStream
      2.0.0

useXChat
Conversation Data

Data management for single conversations.
Importimport { useXChat } from "@ant-design/x-sdk";
Sourcex-sdk/src/x-chat
Docs
Edit this page
Versionsupported since 2.0.0

When to Use

Manage conversation data through Agent and produce data for page rendering.

Code Examples

API

useXChat

tsx
type useXChat<
ChatMessage extends SimpleType = object,
ParsedMessage extends SimpleType = ChatMessage,
Input = RequestParams<ChatMessage>,
Output = SSEOutput,
> = (config: XChatConfig<ChatMessage, ParsedMessage, Input, Output>) => XChatConfigReturnType;

AgentProvider uses the same Hook. The overload infers input, Chunk, and structured state types:

tsx
const {
messages,
agentState,
agentActions,
commandStates,
latestCommandByAction,
onRequest,
abort,
isRequesting,
} = useXChat({ provider });

See Agent Provider for the complete contract and implementation guide.

PropertyDescriptionTypeDefaultVersion
ChatMessageMessage data type, defines the structure of chat messagesobjectobject-
ParsedMessageParsed message type, message format for component consumptionChatMessageChatMessage-
InputRequest parameter type, defines the structure of request parametersRequestParams<ChatMessage>RequestParams<ChatMessage>-
OutputResponse data type, defines the format of received response dataSSEOutputSSEOutput-

XChatConfig

PropertyDescriptionTypeDefaultVersion
providerThe only data entry. Use AbstractChatProvider for regular chat and AgentProvider for structured Agent streams. See Chat Provider and Agent ProviderAbstractChatProvider<ChatMessage, Input, Output> | AgentProvider<Input, Request, Chunk, Context>--
conversationKeySession unique identifier (globally unique), used to distinguish different sessionsstringSymbol('ConversationKey')-
defaultMessagesDefault display messagesMessageInfo<ChatMessage>[] | (info: { conversationKey?: string }) => MessageInfo<ChatMessage>[] | (info: { conversationKey?: string }) => Promise<MessageInfo<ChatMessage>[]>--
parserConverts ChatMessage into ParsedMessage for consumption. When not set, ChatMessage is consumed directly. Supports converting one ChatMessage into multiple ParsedMessages(message: ChatMessage) => BubbleMessage | BubbleMessage[]--
requestFallbackFallback message for failed requests. When not provided, no message will be displayedChatMessage | (requestParams: Partial<Input>,info: { error: Error; errorInfo: any; messages: ChatMessage[], messageInfo: MessageInfo<ChatMessage> }) => ChatMessage|Promise<ChatMessage>--
requestPlaceholderPlaceholder message during requests. When not provided, no message will be displayedChatMessage | (requestParams: Partial<Input>, info: { messages: Message[] }) => ChatMessage | Promise<Message>--

XChatConfigReturnType

PropertyDescriptionTypeDefaultVersion
abortCancel request() => void--
isRequestingWhether a request is in progressboolean--
isDefaultMessagesRequestingWhether the default message list is requestingbooleanfalse2.2.0
messagesCurrent managed message list contentMessageInfo<ChatMessage>[]--
parsedMessagesContent translated through parserMessageInfo<ParsedMessages>[]--
onReloadRegenerate, will send request to backend and update the message with new returned data(id: string | number, requestParams: Partial<Input>, opts?: { extraInfo: AnyObject }) => void--
onRequestAdd a Message and trigger request(requestParams: Partial<Input>, opts?: { extraInfo: AnyObject }) => void--
setMessagesDirectly modify messages without triggering requests(messages: Partial<MessageInfo<ChatMessage>>[]) => void--
setMessageDirectly modify a single message without triggering requests(id: string | number, info: Partial<MessageInfo<ChatMessage>>) => void--
removeMessageDeleting a single message will not trigger a request(id: string | number) => boolean--
queueRequestWill add the request to a queue, waiting for the conversationKey to be initialized before sending(conversationKey: string | symbol, requestParams: Partial<Input>, opts?: { extraInfo: AnyObject }) => void--
agentStateComplete structured state in AgentProvider mode; undefined in regular ChatProvider modeAgentState | undefinedundefined-
agentActionsApproval, tool retry, and Run cancellation operations in AgentProvider mode; undefined in regular ChatProvider modeAgentActions | undefinedundefined-
commandStatesCommand submission state for the active Runs, keyed by commandIdRecord<string, AgentCommandState> | undefinedundefined-
latestCommandByActionMaps an action key to its latest commandId for duplicate prevention and control state lookupRecord<string, string> | undefinedundefined-

AgentProvider Mode

AgentProvider mode accepts only provider, conversationKey, defaultMessages, and parser. requestPlaceholder and requestFallback belong to regular ChatProvider. Requesting, failure, and cancellation state in an Agent run are driven by standard events.

messages remains compatible with existing message components and contains AgentMessageState. Non-message data such as reasoning, tools, approvals, tasks, and artifacts is available from agentState.

setMessages, setMessage, and removeMessage only affect the compatibility message layer and do not directly mutate agentState. In AgentProvider mode, onReload starts a new Run.

Agent Actions

After an AgentProvider declares command capabilities and implements executeCommand, the UI invokes operations through agentActions:

tsx
await agentActions.resolveApproval({
runId,
approvalId,
decision: 'approved',
expectedVersion: approval.version,
});
await agentActions.retryTool({ runId, toolCallId });
await agentActions.cancelRun({ runId, reason: 'User cancelled' });
  • resolveApproval only accepts a non-expired Approval in the waiting state.
  • retryTool only accepts a failed ToolCall with error.retryable === true.
  • cancelRun is a business command sent to the Runtime and waits for run.cancelled; abort() only interrupts the local Transport.
  • Commands for one Run execute serially. The SDK rejects duplicate in-flight actions and further actions after cancellation is submitted.
  • commandStates exposes submitting, succeeded, and failed, and is cleared after the Run reaches a terminal state.

MessageInfo

ts
interface MessageInfo<ChatMessage> {
id: number | string;
message: ChatMessage;
status: MessageStatus;
extraInfo?: AnyObject;
}

MessageStatus

ts
type MessageStatus = 'local' | 'loading' | 'updating' | 'success' | 'error' | 'abort';
OpenAI Model Integration

Use OpenAIChatProvider to integrate models with OpenAI data format, enabling message sending, data processing, and message termination.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
Thinking Model Integration

Use DeepSeekChatProvider to integrate thinking models, enabling message sending, data processing, and message termination.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
Generic AgentProvider Integration

Connect local Runtime events to useXChat through a generic AgentProvider and render reasoning, tools, tasks, and artifacts directly inside chat bubbles. Start from a sample task, switch between successful and failed runs, or cancel an active run.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
Agent Command Interaction

This demo uses three local scenarios to show the same interaction flow: an Agent Event first puts actionable state into the SDK, a user action sends an Agent Command, and the Provider's next event updates the entity state.

  • Approval: approval.requested -> approval.resolve -> approval.resolved
  • Tool retry: tool.failed -> tool.retry -> tool.completed
  • Run cancellation: task.updated -> run.cancel -> run.cancelled

The main area presents the current action and its three-step progress. The SDK state section below exposes Command States and AgentTimeline for verification.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
Historical Messages Setup

You can use defaultMessages to set historical messages.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
Request Remote Historical Messages

Set defaultMessages as an asynchronous method to load historical messages during initialization.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
System Prompt Setup

You can use defaultMessages to set system prompts.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
Model Request Callback

When working with Chat Provider, the XRequest callback can obtain the assembled Chat Message data.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
Custom XRequest.fetch

Custom XRequest.fetch.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
Custom request

When using SDKs (such as openai-node, @openrouter/ai-sdk-provider) to request models or agents, you need to use the built-in Provider to handle data and customize the Request. Please refer to this example. Note: This example only demonstrates the logic for integrating openai using X SDK as a reference, and does not process model data. You need to fill in the correct apiKey for data debugging.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
SessionId - ConversationKey

Integrate useXConversations and queueRequest to implement intelligent request queuing based on sessionId, ensuring messages are sent orderly by conversation and context remains accurate in multi-conversation scenarios.

CodeSandbox Icon
codepen icon
External Link Icon
expand codeexpand code
Current status: No messages yet, please enter a question and send
Current status:No messages yet, please enter a question and send
Hi, I am a local research agent
Pick a task to see reasoning, tools, tasks, and artifacts update in chat.
Research Agent UI trends

Search and create a brief

Compare Provider approaches

Produce structured findings

1
Agent requests action
2
User sends command
3
State is updated
Production deployment needs approval
The Agent pauses before a high-risk action and waits for a decision.
Current status: No messages yet, please enter a question and send
Current status: No messages yet, please enter a question and send
Current status: No messages yet, please enter a question and send
Current system prompt: None
Current status:No messages yet, please enter a question and send
Callback Message: No data available
  • Conversation Item 4
  • This's Conversation Item 3, you can click me!
  • Conversation Item 2
  • Conversation Item 1
icon

Hello, I'm Ant Design X

Base on Ant Design, AGI product interface solution, create a better intelligent vision~