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

Agent Provider
Agent Event Integration

Adapt any model or Agent Runtime to a unified event stream.
Importimport { Agent Provider } from "@ant-design/x-sdk";
Sourcex-sdk/src/agent-provider
Docs
Edit this page
Versionsupported since 2.9.0

AgentProvider is a model- and Runtime-independent Agent integration contract. It converts SSE, WebSocket, local Runtimes, recorded fixtures, and other sources into unified Agent Events. The AgentStore inside useXChat reduces those events into messages and structured state.

text
Model / Agent Runtime / Fixture
-> AgentProvider (with a bound Transport)
-> AgentEvent
-> AgentStore
-> useXChat
-> messages + agentState

The frontend entry remains useXChat({ provider }). There is no additional useAgent Hook and no mode, agent, transport, or store configuration.

Examples

Quick Start

tsx
import { useXChat } from '@ant-design/x-sdk';
const { messages, agentState, onRequest, abort, isRequesting } = useXChat({
provider,
conversationKey: 'conversation-1',
});
onRequest({ prompt: 'Analyze this report' });
  • messages is a compatible MessageInfo[] projection of AgentMessageState for message components such as Bubble.
  • agentState preserves complete runs, reasoning, tool calls, approvals, tasks, and artifacts.
  • abort() cancels the active Run. The Provider should convert the interruption into entity cancellation events followed by run.cancelled.

Provider Contract

ts
interface AgentProvider<Input, Request, Chunk, Context = unknown> {
readonly id: string;
readonly protocol: {
readonly name: 'agent-event';
readonly version: '0.1';
};
readonly capabilities: AgentProviderCapabilities;
readonly transport: AgentTransport<Request, Chunk>;
createContext(options: AgentProviderContextOptions): Context;
start(input: Input, context: Context): readonly AgentEvent[];
prepareRequest(input: Input, context: Context): Request;
transformChunk(chunk: Chunk, context: Context): readonly AgentEvent[];
flush(context: Context): readonly AgentEvent[];
transformError(error: unknown, context: Context): readonly AgentEvent[];
executeCommand?(command: AgentCommand, options: AgentCommandOptions): AsyncIterable<AgentEvent>;
}
MemberResponsibility
idUnique Provider metadata; it is never used for capability detection
protocolExplicit protocol declaration used by useXChat to identify AgentProvider
capabilitiesDeclares event and Transport types the Provider may use
transportBinds request execution; the frontend does not configure it separately
createContextCreates per-Run parsing state shared across chunks
startEmits the Run, user message, and initial entity events
prepareRequestConverts onRequest input into a Runtime request
transformChunkConverts one chunk into zero or more standard events
flushCloses remaining entities and emits the terminal Run event
transformErrorConverts errors and interruptions into failure or cancellation events
executeCommandExecutes UI approval, tool retry, or Run cancellation commands and returns standard events

A Provider does not render React UI, maintain another message reducer, execute tools, or infer capabilities from a model name.

Command Interaction

A Provider declares supported commands through capabilities.commands and sends each command to the Runtime through executeCommand:

tsx
const capabilities = {
eventTypes: [
'approval.resolved',
'tool.requested',
'tool.running',
'tool.completed',
'run.cancelled',
],
transports: ['company.sse'],
commands: ['approval.resolve', 'tool.retry', 'run.cancel'],
};
async function* executeCommand(command, { signal, initialSequence }) {
const events = createAgentEventFactory({
sessionId: command.sessionId,
runId: command.runId,
initialSequence,
});
const result = await runtime.execute(command, { signal });
yield events.create('approval.resolved', result);
}

Every command contains a commandId and idempotencyKey. Providers should forward the idempotency key to the server and ensure returned events belong to the command's sessionId and runId, with sequence greater than initialSequence. Command success means the Provider command event stream ended normally; entity completion is still determined by the returned AgentEvents.

Transport

ts
interface AgentTransport<Request, Chunk> {
readonly kind: AgentTransportKind;
open(request: Request, signal: AbortSignal): AsyncIterable<Chunk>;
}

A Transport only converts a Provider request into AsyncIterable<Chunk>. HTTP SSE, WebSocket, and local Runtimes can implement the same interface. The Transport belongs to the Provider and is not a second useXChat option.

Custom Transport types use a namespaced value such as company.websocket. Generic built-in types include sse, websocket, and async-iterable.

Event Lifecycle

Every Run needs exactly one run.started and one terminal event: run.completed, run.failed, or run.cancelled.

Event familyLifecycle
Messagemessage.started -> message.delta -> message.completed/failed/cancelled
Reasoningreasoning.started -> reasoning.delta -> reasoning.completed/failed/cancelled
Tooltool.requested -> tool.arguments_delta -> tool.running -> tool.completed/failed/cancelled
Approvalapproval.requested -> approval.resolved
Tasktask.created -> task.updated -> task.completed/failed/cancelled
Artifactartifact.created -> artifact.updated -> artifact.completed/failed

Events must follow these rules:

  • sequence increases strictly within one Run.
  • eventId is unique within one Run.
  • sessionId and runId match the active execution.
  • Entity delta and terminal events follow their corresponding start event.
  • Active entities are closed before the Run terminates.
  • The Provider only emits event types declared in capabilities.eventTypes.

useXChat Configuration

AgentProvider mode uses AgentXChatConfig:

PropertyDescriptionType
providerThe only execution entryAgentProvider<Input, Request, Chunk, Context>
conversationKeyState isolation keystring
defaultMessagesInitial messages in the compatibility layerDefaultMessageInfo<AgentMessageState>[] or an async loader
parserProjects Agent messages into a component-facing type(message: AgentMessageState) => ParsedMessage | ParsedMessage[]

requestPlaceholder and requestFallback belong to the legacy ChatProvider path. AgentProvider expresses loading, failure, and cancellation through standard events.

Return Value

In addition to the existing useXChat result, AgentProvider mode always returns agentState: AgentState.

setMessages, setMessage, and removeMessage only mutate the compatibility message layer. They do not synthesize Agent Events or directly change agentState. onReload starts a new Run instead of rewriting an old Run.

AgentState

FieldContents
sessionsSession metadata
runsRun input, output, status, errors, and usage
messagesUser, assistant, system, and tool messages
reasoningReasoning content, summary, and status
toolCallsTool name, arguments, result, and status
approvalsApproval description, risk, and decision
tasksTask description, progress, and result
artifactsArtifact content, version, and media type
issuesProtocol issues recorded by the Reducer

Store entities are scoped by runId + entityId, so different Runs may safely reuse Runtime entity IDs.

Errors and Cancellation

Transport errors are passed to transformError. The Provider closes any started messages, reasoning, tools, or tasks before emitting the terminal Run event. User abort() calls and component unmounts use the same AbortSignal.

If the event consumer or Store throws, runAgentProvider propagates the original exception instead of passing it back through Provider error transformation.

Contract Validation

Provider fixtures can use validateAgentProviderEvents for model-independent contract tests:

ts
import { validateAgentProviderEvents } from '@ant-design/x-sdk';
const issues = validateAgentProviderEvents(provider.capabilities, events);
expect(issues).toEqual([]);

Validation covers event shape, declared capabilities, IDs, sequence, Run ownership, lifecycle, and terminal entities.

Export Boundaries

ts
import type { AgentProvider, AgentTransport } from '@ant-design/x-sdk';
import { runAgentProvider, validateAgentProviderEvents } from '@ant-design/x-sdk';
import { experimentalAgent } from '@ant-design/x-sdk';
  • Provider, Transport, runner, and contract validation are top-level chat-providers exports.
  • Event protocol, Reducer, and Store are exposed through experimentalAgent.
  • The React bridge is internal to useXChat; there is no second Hook.

This API remains experimental. The protocol may evolve until at least two structurally different reference Providers and an official Agent UI have validated it.

Generic AgentProvider

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
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.