Token导航 LogoToken导航TokenDH.com
前端设计需要联网github未标认证来源可访问许可证需确认审计通过

use-x-chat使用 x 聊天

Agent Skill

use-x-chat 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

456

周安装

19

GitHub Stars

4,478

下载量

152
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:use-x-chat(使用 x 聊天)
来源仓库:https://github.com/ant-design/x
仓库路径:skills/use-x-chat
安装命令:
npx skills add https://github.com/ant-design/x --skill use-x-chat
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/ant-design/x --skill use-x-chat

简介

use-x-chat 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态或协作事项进行整理时使用。

  • 适用于 Ant Design X 生态下的前端设计与协作流程支持。
  • 可自动提取仓库元数据、变更记录和协作动态并结构化输出。
  • 安装命令为 npx skills add https://github.com/ant-design/x --skill use-x-chat。
  • 使用前请确认权限范围、维护状态及是否涉及文件读写或网络请求。

SKILL.md

🎯 Skill Positioning

Core Positioning: Use the useXChat Hook to build professional AI conversation applications. Prerequisite: Already have a custom Chat Provider (refer to x-chat-provider skill)

Table of Contents

- Data Model - Configuration Options - Return Values

🚀 Quick Start

1. Dependency Management

  • @ant-design/x-sdk: 2.2.2+
  • @ant-design/x: latest version (UI components)
npm install @ant-design/x-sdk@latest @ant-design/x@latest

2. Three-step Integration

Step 1: Prepare Provider

Handled by the x-chat-provider skill. Note XRequest must pass manual: true:

import { MyChatProvider } from './MyChatProvider';
import { XRequest } from '@ant-design/x-sdk';

// ⚠️ manual: true is required
const provider = new MyChatProvider({
  request: XRequest('https://your-api.com/chat', { manual: true }),
});

Step 2: Basic Usage

import { useXChat } from '@ant-design/x-sdk';

const ChatComponent = () => {
  const { messages, onRequest, isRequesting } = useXChat({
    provider,
    requestPlaceholder: (_, { messages }) => ({
      content: 'Thinking...',
      role: 'assistant',
    }),
    requestFallback: (_, { error, messageInfo }) => {
      if (error.name === 'AbortError') {
        return { content: messageInfo?.message?.content || 'Reply cancelled', role: 'assistant' };
      }
      return { content: 'Network error, please try again later', role: 'assistant' };
    },
  });

  return (
    <div>
      {messages.map((msg) => (
        <div key={msg.id}>
          {msg.message.role}: {msg.message.content}
        </div>
      ))}
      <button onClick={() => onRequest({ query: 'Hello' })}>Send</button>
    </div>
  );
};

Step 3: UI Integration

⚠️ messages is MessageInfo<ChatMessage>[] and cannot be passed directly to Bubble.List. It must be mapped to {key, role, content, loading} format. Bubble.List uses the role prop (not roles) to configure role styles.
import { Bubble, Sender } from '@ant-design/x';

const ChatUI = () => {
  const { messages, onRequest, isRequesting, abort } = useXChat({ provider });

  return (
    <div style={{ height: 600 }}>
      <Bubble.List
        // ✅ Correct: use role (not roles)
        role={{
          user: { placement: 'end' },
          assistant: { placement: 'start' },
        }}
        items={messages.map(({ id, message, status }) => ({
          key: id,
          role: message.role, // matches role config key
          content: message.content, // message content
          loading: status === 'loading', // loading animation
        }))}
      />
      <Sender
        loading={isRequesting}
        onSubmit={(content) => onRequest({ query: content })}
        onCancel={abort}
      />
    </div>
  );
};

When ChatMessage is an object type (not string)

When ChatMessage is a complex object (e.g., with content, attachments fields), use contentRender:

<Bubble.List
  role={{
    assistant: {
      placement: 'start',
      // contentRender receives content param, which is the message field itself
      contentRender(content: MyMessage) {
        return (
          <div>
            <div>{content.content}</div>
            {content.attachments?.map((a) => (
              <FileCard key={a.url} name={a.name} />
            ))}
          </div>
        );
      },
    },
    user: {
      placement: 'end',
      contentRender(content: MyMessage) {
        return content.content;
      },
    },
  }}
  items={messages.map(({ id, message, status }) => ({
    key: id,
    role: message.role,
    content: message, // ⚠️ Pass the entire message object; contentRender handles rendering
    loading: status === 'loading',
  }))}
/>

🧩 Core Concepts

Data Model

⚠️ Important: messages type is MessageInfo<ChatMessage>[]; message content is in msg.message
interface MessageInfo<ChatMessage> {
  id: number | string; // Message unique identifier
  message: ChatMessage; // Actual message content (your ChatMessage type)
  status: MessageStatus; // Message status
  extraInfo?: AnyObject; // Extended info (note: extraInfo, not extra)
}

type MessageStatus = 'local' | 'loading' | 'updating' | 'success' | 'error' | 'abort';
// local: locally sent user message
// loading: AI reply placeholder (corresponds to requestPlaceholder)
// updating: AI streaming output in progress
// success: AI reply complete
// error: request failed
// abort: user actively cancelled

useXChat Configuration Options

OptionTypeDescription
providerAbstractChatProvider<ChatMessage, Input, Output>Required, Provider instance
conversationKeystringConversation unique identifier, required for multi-conversation
defaultMessages`DefaultMessageInfo[] \() =>... \async () =>...`Default display messages, supports async loading
requestPlaceholder`ChatMessage \(requestParams, {messages}) => ChatMessage`Placeholder message during request
requestFallback`ChatMessage \(requestParams, {error, errorInfo, messages, messageInfo}) => ChatMessage \Promise<ChatMessage>`Fallback message on request failure/abort
parser`(message: ChatMessage) => BubbleMessage \BubbleMessage[]`Convert ChatMessage to component-consumable format, supports one-to-many
requestFallback's messageInfo type is MessageInfo<ChatMessage>, the message being updated when the request fails. requestFallback handles both network errors (error) and user abort (error.name === 'AbortError').

useXChat Return Values

Return ValueTypeDescription
messagesMessageInfo<ChatMessage>[]Message list; must be mapped before passing to Bubble.List
parsedMessagesMessageInfo<ParsedMessage>[]Message list after parser transform (use this when parser is set)
onRequest(params: Partial<Input>, opts?: {extraInfo: AnyObject}) => voidAdd message and trigger request
isRequestingbooleanWhether request is in progress
abort() => voidAbort current request
setMessages(messages: Partial<MessageInfo<ChatMessage>>[]) => voidDirectly modify message list, no request triggered
setMessage`(id: string \number, info: Partial<MessageInfo<ChatMessage>>) => void`Modify single message, no request triggered
removeMessage`(id: string \number) => boolean`Delete a message, returns whether deletion was successful
onReload`(id: string \number, params: Partial<Input>, opts?: {extraInfo: AnyObject}) => void`Regenerate an AI reply
queueRequest`(conversationKey: string \symbol, params: Partial<Input>, opts?: {extraInfo: AnyObject}) => void`Queue request, sent after conversation initializes
isDefaultMessagesRequestingbooleanWhether default messages are async loading

🔧 Core Function Details

Core functionality reference: CORE.md

🗂️ Multi-conversation Management

useXConversations Hook

useXConversations is a conversation list management Hook provided by @ant-design/x-sdk, used together with useXChat for multi-conversation:

import { useXConversations } from '@ant-design/x-sdk';
import type { ConversationData } from '@ant-design/x-sdk';

const {
  conversations, // ConversationData[]: conversation list
  activeConversationKey, // string: currently active conversation key
  setActiveConversationKey, // (key: string) => void: switch conversation
  addConversation, // (ConversationData, placement?) => boolean
  removeConversation, // (key: string) => boolean
  setConversation, // (key: string,  ConversationData) => boolean
  getConversation, // (key: string) => ConversationData | undefined
  setConversations, // (list: ConversationData[]) => void
  getMessages, // (key: string) => MessageInfo[] | undefined (read messages across components)
} = useXConversations({
  defaultConversations: [
    { key: 'conv-1', label: 'Conversation 1' },
    { key: 'conv-2', label: 'Conversation 2' },
  ],
  defaultActiveConversationKey: 'conv-1',
});

Multi-conversation Full Pattern

import { useXChat, useXConversations } from '@ant-design/x-sdk';
import { OpenAIChatProvider, XRequest } from '@ant-design/x-sdk';
import { Bubble, Conversations, Sender } from '@ant-design/x';
import React, { useEffect, useRef } from 'react';

// ⚠️ Each conversation must have its own Provider instance, otherwise state mixes
const providerCache = new Map<string, OpenAIChatProvider>();

function getProvider(key: string): OpenAIChatProvider {
  if (!providerCache.has(key)) {
    providerCache.set(
      key,
      new OpenAIChatProvider({
        request: XRequest(BASE_URL, { manual: true, params: { model: 'gpt-4o', stream: true } }),
      }),
    );
  }
  return providerCache.get(key)!;
}

const App = () => {
  const senderRef = useRef<any>(null);

  const { conversations, activeConversationKey, setActiveConversationKey, addConversation } =
    useXConversations({
      defaultConversations: [{ key: 'conv-1', label: 'New Conversation' }],
      defaultActiveConversationKey: 'conv-1',
    });

  const { messages, onRequest, isRequesting, abort, queueRequest } = useXChat({
    provider: getProvider(activeConversationKey),
    conversationKey: activeConversationKey,
    // Async load default messages
    defaultMessages: async ({ conversationKey }) => {
      // Load history from server based on conversationKey
      return [];
    },
    requestFallback: (_, { error, messageInfo }) => {
      if (error.name === 'AbortError') {
        return { content: messageInfo?.message?.content || 'Cancelled', role: 'assistant' };
      }
      return { content: 'Request failed', role: 'assistant' };
    },
  });

  // Clear input on conversation switch
  useEffect(() => {
    senderRef.current?.clear?.();
  }, [activeConversationKey]);

  const handleNewConversation = () => {
    const newKey = `conv-${Date.now()}`;
    addConversation({ key: newKey, label: `New Conversation ${conversations.length + 1}` });
    setActiveConversationKey(newKey);
  };

  return (
    <div style={{ display: 'flex', height: '100vh' }}>
      <Conversations
        items={conversations}
        activeKey={activeConversationKey}
        onActiveChange={setActiveConversationKey}
        creation={{ onClick: handleNewConversation }}
      />
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>
        <Bubble.List
          role={{ assistant: { placement: 'start' }, user: { placement: 'end' } }}
          items={messages.map(({ id, message, status }) => ({
            key: id,
            role: message.role,
            content: message.content,
            loading: status === 'loading',
          }))}
        />
        <Sender
          ref={senderRef}
          loading={isRequesting}
          onCancel={abort}
          onSubmit={(val) => {
            onRequest({ messages: [{ role: 'user', content: val }] });
          }}
        />
      </div>
    </div>
  );
};

queueRequest: Delayed Send After Conversation Switch

// Scenario: user switches to a new conversation and triggers an initial message simultaneously
// queueRequest waits for defaultMessages async loading to complete, then sends the request

const handleNewConversationWithFirstMessage = () => {
  const newKey = `conv-${Date.now()}`;
  addConversation({ key: newKey, label: 'New Conversation' });
  setActiveConversationKey(newKey);

  // Queue the message; sent automatically after newKey conversation's defaultMessages finish loading
  queueRequest(newKey, {
    messages: [{ role: 'user', content: 'Hello! Please introduce yourself.' }],
  });
};

📋 Prerequisites and Dependencies

Usage ScenarioRequired Skill/ProviderOrder
Private API Adaptationx-chat-provider → use-x-chatCreate Provider first
Standard APIBuilt-in Provider + use-x-chatDirect use
Multi-conversationProvider factory + useXConversations + useXChatUse together

🚨 Development Rules

Before using use-x-chat, confirm:

  • Has Provider (custom or built-in Provider)
  • Provider's XRequest is configured with manual: true
  • Understands MessageInfo data structure (message content is in msg.message)
  • Bubble.List uses role prop (not roles)
  • Multi-conversation scenario: each conversation has its own Provider instance

Test Case Rules

  • If the user does not explicitly need test cases, do not add test files

Code Quality Rules

  • After completion, must check types: Run tsc --noEmit to ensure no type errors
  • Keep code clean: Remove all unused variables and imports

🔗 Reference Resources

📚 Core Reference Documentation

🌐 SDK Official Documentation

💻 Example Code

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

37.21%
按下载量换算57

Claude

31.17%
按下载量换算47

Cursor

20.11%
按下载量换算31

Gemini CLI

9.22%
按下载量换算14

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills