Skip to main content

x-chat-provider

Focus on implementing custom Chat Provider, helping to adapt any streaming interface to Ant Design X standard format

ソース情報

リポジトリ
modelscope/ms-agent
ソースの最終更新活動
2026年9月8日 10:28
検出された SKILL.md の言語
英語
スター
4,411
フォーク
530

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
2 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
x-chat-provider
version
2.8.1
description
Focus on implementing custom Chat Provider, helping to adapt any streaming interface to Ant Design X standard format
# 🎯 Skill Positioning **This skill focuses on solving one problem**: How to quickly adapt your streaming interface to Ant Design X's Chat Provider. **Not involved**: useXChat usage tutorial (that's another skill). ## Table of Contents - [📦 Technology Stack Overview](#-technology-stack-overview) - [🚀 Quick Start](#-quick-start) - [Built-in Provider](#built-in-provider) - [When to Use Custom Provider](#when-to-use-custom-provider) - [📋 Four Steps to Implement Custom Provider](#-four-steps-to-implement-custom-provider) - [🔑 Core Types and Exports](#-core-types-and-exports) - [⚙️ XRequest Advanced Configuration](#️-xrequest-advanced-configuration) - [callbacks](#callbacks) - [retryInterval Retry](#retryinterval-retry) - [transformStream Custom Stream](#transformstream-custom-stream) - [🔧 Common Scenario Adaptation](#-common-scenario-adaptation) - [⚠️ Important Reminders](#️-important-reminders) - [⚡ Quick Checklist](#-quick-checklist) - [🚨 Development Rules](#-development-rules) - [🔗 Reference Resources](#-reference-resources) # 📦 Technology Stack Overview | Layer | Package Name | Core Purpose | | ---------------- | -------------------------- | -------------------------- | | **UI Layer** | **@ant-design/x** | React UI component library | | **Logic Layer** | **@ant-design/x-sdk** | Development toolkit | | **Render Layer** | **@ant-design/x-markdown** | Markdown renderer | ```ts // ✅ Correct import examples import { Bubble } from '@ant-design/x'; import { AbstractChatProvider, OpenAIChatProvider } from '@ant-design/x-sdk'; import XRequest from '@ant-design/x-sdk'; ``` # 🚀 Quick Start ### 🎯 Provider Selection Decision Tree ```mermaid graph TD A[Start] --> B{Use standard OpenAI/DeepSeek API?} B -->|Yes| C[Use built-in Provider] B -->|No| D{Raw data format as message?} D -->|Yes| E[Use DefaultChatProvider] D -->|No| F[Custom Provider] C --> G[OpenAIChatProvider / DeepSeekChatProvider] E --> H[Pass-through, no conversion needed] F --> I[Four-step custom Provider] ``` ### 🏭 Built-in Provider Overview | Provider Type | Applicable Scenario | Import | | --- | --- | --- | | **OpenAIChatProvider** | Standard OpenAI API format | `import { OpenAIChatProvider } from '@ant-design/x-sdk'` | | **DeepSeekChatProvider** | Standard DeepSeek API format | `import { DeepSeekChatProvider } from '@ant-design/x-sdk'` | | **DefaultChatProvider** | Pass-through raw response, no format conversion | `import { DefaultChatProvider } from '@ant-design/x-sdk'` | > ⚠️ Export names are `OpenAIChatProvider` / `DeepSeekChatProvider` / `DefaultChatProvider`, watch spelling #### DefaultChatProvider Use Case `DefaultChatProvider` **passes through raw response data** without any conversion. Suitable for: - The interface response format is already what you want to display - You want full control over `Bubble.List`'s `contentRender` to render messages ```ts import { DefaultChatProvider, XRequest } from '@ant-design/x-sdk'; interface ChatInput { query: string; stream?: boolean; } interface ChatOutput { choices: Array<{ message: { content: string; role: string } }>; } // DefaultChatProvider generic: <ChatMessage, Input, Output> // ChatMessage is your Output type (passed through directly) const provider = new DefaultChatProvider<ChatOutput | ChatInput, ChatInput, ChatOutput>({ request: XRequest('https://your-api.com/chat', { manual: true, params: { stream: false }, }), }); // Render using contentRender in Bubble.List's role config // role={{ assistant: { contentRender(content) { return content?.choices?.[0]?.message?.content } } }} ``` > ⚠️ When using `DefaultChatProvider`, `ChatMessage` is typically your `Output` type or a union type; rendering requires `contentRender` # 📋 Four Steps to Implement Custom Provider ## Step 1: Analyze Interface Format ⏱️ 2 minutes | Information Type | Example Value | | ------------------- | --------------------------- | | **Interface URL** | `https://your-api.com/chat` | | **Request Method** | JSON, POST | | **Response Format** | Server-Sent Events | | **Auth Method** | Bearer Token | ## Step 2: Create Provider Class ⏱️ 5 minutes ```ts // MyChatProvider.ts import { AbstractChatProvider } from '@ant-design/x-sdk'; import type { TransformMessage } from '@ant-design/x-sdk'; import type { XRequestOptions } from '@ant-design/x-sdk'; interface MyInput { query: string; model?: string; stream?: boolean; } interface MyOutput { content: string; finish_reason?: string; } interface MyMessage { content: string; role: 'user' | 'assistant'; } export class MyChatProvider extends AbstractChatProvider<MyMessage, MyInput, MyOutput> { // Parameter conversion: merge onRequest params + XRequest default params // options comes from XRequest(url, options), can access options.params etc. transformParams( requestParams: Partial<MyInput>, options: XRequestOptions<MyInput, MyOutput, MyMessage>, ): MyInput { return { ...(options?.params || {}), query: requestParams.query || '', model: 'gpt-3.5-turbo', stream: true, }; } // Local message: convert onRequest params to the user-side display message (can return array) transformLocalMessage(requestParams: Partial<MyInput>): MyMessage { return { content: requestParams.query || '', role: 'user', }; } // Response conversion: // info.originMessage: previous content of this message (for stream accumulation) // info.chunk: current streaming chunk // info.chunks: all received chunks (used in onSuccess) // info.status: current status // ⚠️ Return only MyMessage type; do NOT add a status field transformMessage(info: TransformMessage<MyMessage, MyOutput>): MyMessage { const { originMessage, chunk } = info; if (!chunk?.content || chunk.content === '[DONE]') { return { ...(originMessage || { content: '', role: 'assistant' }) }; } return { content: `${originMessage?.content || ''}${chunk.content}`, role: 'assistant', }; } } ``` ## Step 3: Verify ⏱️ 1 minute | Check Item | Description | | ----------------------------- | ------------------------------------------------------------- | | **Only 3 methods** | transformParams, transformLocalMessage, transformMessage | | **transformParams signature** | Must include second parameter `options: XRequestOptions<...>` | | **No status in return** | transformMessage return value has no status field | | **No request method** | Confirm no request method implemented | | **Type check passes** | `tsc --noEmit` no errors | ## Step 4: Use Provider ⏱️ 1 minute ```ts import { MyChatProvider } from './MyChatProvider'; import XRequest from '@ant-design/x-sdk'; // ⚠️ Must pass manual: true, otherwise AbstractChatProvider constructor will throw const provider = new MyChatProvider({ request: XRequest('https://your-api.com/chat', { manual: true, headers: { Authorization: 'Bearer your-token', 'Content-Type': 'application/json', }, params: { model: 'gpt-3.5-turbo', stream: true, }, }), }); export { provider }; ``` # 🔑 Core Types and Exports Key types exported from `@ant-design/x-sdk`: ```ts import type { // OpenAI standard message format XModelMessage, // { role: string; content: string | { text: string; type: string } } XModelParams, // Full OpenAI request params type (model, messages, stream, temperature, etc.) XModelResponse, // Full OpenAI response type (choices, usage, etc.) // SSE stream field types SSEFields, // 'data' | 'event' | 'id' | 'retry' SSEOutput, // Partial<Record<SSEFields, any>> // Provider related TransformMessage, // { originMessage, chunk, chunks, status, responseHeaders } // XRequest related XRequestOptions, // Full request config XRequestCallbacks, // { onUpdate, onSuccess, onError } // Message related MessageInfo, // { id, message, status, extraInfo } } from '@ant-design/x-sdk'; ``` ### XModelMessage Structure (OpenAI message format) ```ts // XModelMessage is the standard OpenAI message format // Used for OpenAIChatProvider / DeepSeekChatProvider ChatMessage generic const userMessage: XModelMessage = { role: 'user', content: 'Hello' }; const systemMessage: XModelMessage = { role: 'system', content: 'You are an assistant' }; const developerMessage: XModelMessage = { role: 'developer', content: 'System prompt' }; ``` ### SSEOutput and SSEFields ```ts // SSEOutput is the type for raw SSE stream data // { data?: string; event?: string; id?: string; retry?: number } // DeepSeekChatProvider uses Partial<Record<SSEFields, XModelResponse>> import { DeepSeekChatProvider, XRequest } from '@ant-design/x-sdk'; import type { SSEFields, XModelParams, XModelResponse } from '@ant-design/x-sdk'; const provider = new DeepSeekChatProvider({ request: XRequest<XModelParams, Partial<Record<SSEFields, XModelResponse>>>( 'https://api.deepseek.com/v1/chat/completions', { manual: true, params: { model: 'deepseek-chat', stream: true }, }, ), }); ``` # ⚙️ XRequest Advanced Configuration ## callbacks `callbacks` allows monitoring request events at the Provider level. The third parameter in callbacks is the `MessageInfo` processed by `transformMessage`: ```ts const provider = new OpenAIChatProvider({ request: XRequest<XModelParams, XModelResponse, XModelMessage>(BASE_URL, { manual: true, callbacks: { // onUpdate: triggered on each streaming chunk arrival // chunk: current chunk; responseHeaders: response headers; message: current MessageInfo onUpdate: (chunk, responseHeaders, message) => { console.log('Stream update:', message?.message?.content); }, // onSuccess: triggered when all chunks are received // chunks: all chunks array; message: final MessageInfo onSuccess: (chunks, responseHeaders, message) => { console.log('Request complete:', message?.message?.content); // Good place for analytics, logging, etc. }, // onError: triggered on request failure (including AbortError) // error: error object; errorInfo: extra error info; message: MessageInfo at failure onError: (error, errorInfo, responseHeaders, message) => { console.error('Request failed:', error.message); }, }, params: { model: 'gpt-4o', stream: true }, }), }); ``` > ⚠️ `callbacks` and `useXChat`'s `requestFallback` do not conflict — both execute. `callbacks` is better for logging/reporting; `requestFallback` controls UI display. ## retryInterval Retry ```ts const request = XRequest('https://your-api.com/chat', { manual: true, // Retry interval after failure (ms) retryInterval: 3000, // Max retry count (unlimited if not set) retryTimes: 3, // onError can also return a number to dynamically set retry interval callbacks: { onError: (error) => { if (error.name === 'AbortError') return; // Don't retry on user cancel return 5000; // Return number = retry after 5s (higher priority than retryInterval) }, },
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る