@antdv-next/x-sdk 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_util/types.d.ts +1 -0
- package/dist/chat-providers/AbstractChatProvider.d.ts +42 -0
- package/dist/chat-providers/DeepSeekChatProvider.d.ts +15 -0
- package/dist/chat-providers/DefaultChatProvider.d.ts +8 -0
- package/dist/chat-providers/OpenAIChatProvider.d.ts +15 -0
- package/dist/chat-providers/index.d.ts +5 -0
- package/dist/chat-providers/index.js +2 -0
- package/dist/chat-providers/types/model.d.ts +108 -0
- package/dist/chat-providers/types/model.js +0 -0
- package/dist/chat-providers-5x9Va7p5.js +167 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +26 -0
- package/dist/store-C1diHqNH.js +145 -0
- package/dist/x-chat/index.d.ts +86 -0
- package/dist/x-chat/index.js +292 -0
- package/dist/x-chat/store.d.ts +38 -0
- package/dist/x-conversations/index.d.ts +20 -0
- package/dist/x-conversations/index.js +2 -0
- package/dist/x-conversations/store.d.ts +26 -0
- package/dist/x-conversations-BrKWhj5r.js +122 -0
- package/dist/x-request/index.d.ts +74 -0
- package/dist/x-request/index.js +2 -0
- package/dist/x-request/x-fetch.d.ts +8 -0
- package/dist/x-request-BSFGaKND.js +234 -0
- package/dist/x-stream/index.d.ts +49 -0
- package/dist/x-stream/index.js +114 -0
- package/package.json +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type AnyObject = Record<PropertyKey, any>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { MessageStatus, SimpleType } from '../x-chat';
|
|
2
|
+
import { AbstractXRequestClass, XRequestOptions } from '../x-request';
|
|
3
|
+
export interface ChatProviderConfig<Input, Output, ChatMessage extends SimpleType = any> {
|
|
4
|
+
request: AbstractXRequestClass<Input, Output, ChatMessage> | (() => AbstractXRequestClass<Input, Output, ChatMessage>);
|
|
5
|
+
}
|
|
6
|
+
export interface TransformMessage<ChatMessage extends SimpleType, Output> {
|
|
7
|
+
originMessage?: ChatMessage;
|
|
8
|
+
chunk: Output;
|
|
9
|
+
chunks: Output[];
|
|
10
|
+
status: MessageStatus;
|
|
11
|
+
responseHeaders: Headers;
|
|
12
|
+
}
|
|
13
|
+
export default abstract class AbstractChatProvider<ChatMessage extends SimpleType, Input, Output> {
|
|
14
|
+
private _request;
|
|
15
|
+
private _getMessagesFn;
|
|
16
|
+
private _originalCallbacks?;
|
|
17
|
+
get request(): AbstractXRequestClass<Input, Output, ChatMessage>;
|
|
18
|
+
constructor(config: ChatProviderConfig<Input, Output, ChatMessage>);
|
|
19
|
+
/**
|
|
20
|
+
* 转换onRequest传入的参数,你可以和Provider实例化时request配置中的params进行合并或者额外处理
|
|
21
|
+
* @param requestParams 请求参数
|
|
22
|
+
* @param options 请求配置,从Provider实例化时request配置中来
|
|
23
|
+
*/
|
|
24
|
+
abstract transformParams(requestParams: Partial<Input>, options: XRequestOptions<Input, Output, ChatMessage>): Input;
|
|
25
|
+
/**
|
|
26
|
+
* 将onRequest传入的参数转换为本地(用户发送)的ChatMessage,用于消息渲染
|
|
27
|
+
* @param requestParams onRequest传入的参数
|
|
28
|
+
*/
|
|
29
|
+
abstract transformLocalMessage(requestParams: Partial<Input>): ChatMessage | ChatMessage[];
|
|
30
|
+
/**
|
|
31
|
+
* 可在更新返回数据时对messages做转换,同时会更新到messages
|
|
32
|
+
* @param info
|
|
33
|
+
*/
|
|
34
|
+
abstract transformMessage(info: TransformMessage<ChatMessage, Output>): ChatMessage;
|
|
35
|
+
getMessages(): ChatMessage[];
|
|
36
|
+
injectGetMessages(getMessages: () => ChatMessage[]): void;
|
|
37
|
+
injectRequest({ onUpdate, onSuccess, onError, }: {
|
|
38
|
+
onUpdate: (data: Output, responseHeaders: Headers) => any;
|
|
39
|
+
onSuccess: (data: Output[], responseHeaders: Headers) => any;
|
|
40
|
+
onError: (error: any, errorInfo?: any) => any;
|
|
41
|
+
}): void;
|
|
42
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { XRequestOptions } from '../x-request';
|
|
2
|
+
import { SSEFields } from '../x-stream';
|
|
3
|
+
import { TransformMessage, default as AbstractChatProvider } from './AbstractChatProvider';
|
|
4
|
+
import { XModelMessage, XModelParams } from './types/model';
|
|
5
|
+
/**
|
|
6
|
+
* DeepSeek Chat Provider
|
|
7
|
+
* @template ChatMessage 消息类型
|
|
8
|
+
* @template Input 请求参数类型
|
|
9
|
+
* @template Output 响应数据类型
|
|
10
|
+
*/
|
|
11
|
+
export default class DeepSeekChatProvider<ChatMessage extends XModelMessage = XModelMessage, Input extends XModelParams = XModelParams, Output extends Partial<Record<SSEFields, any>> = Partial<Record<SSEFields, any>>> extends AbstractChatProvider<ChatMessage, Input, Output> {
|
|
12
|
+
transformParams(requestParams: Partial<Input>, options: XRequestOptions<Input, Output, ChatMessage>): Input;
|
|
13
|
+
transformLocalMessage(requestParams: Partial<Input>): ChatMessage[];
|
|
14
|
+
transformMessage(info: TransformMessage<ChatMessage, Output>): ChatMessage;
|
|
15
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { SimpleType } from '../x-chat';
|
|
2
|
+
import { XRequestOptions } from '../x-request';
|
|
3
|
+
import { TransformMessage, default as AbstractChatProvider } from './AbstractChatProvider';
|
|
4
|
+
export default class DefaultChatProvider<ChatMessage extends SimpleType, Input, Output> extends AbstractChatProvider<ChatMessage, Input, Output> {
|
|
5
|
+
transformParams(requestParams: ChatMessage & Partial<Input>, options: XRequestOptions<Input, Output, ChatMessage>): Input;
|
|
6
|
+
transformLocalMessage(requestParams: Partial<Input>): ChatMessage;
|
|
7
|
+
transformMessage(info: TransformMessage<ChatMessage, Output>): ChatMessage;
|
|
8
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { XRequestOptions } from '../x-request';
|
|
2
|
+
import { SSEFields } from '../x-stream';
|
|
3
|
+
import { TransformMessage, default as AbstractChatProvider } from './AbstractChatProvider';
|
|
4
|
+
import { XModelMessage, XModelParams } from './types/model';
|
|
5
|
+
/**
|
|
6
|
+
* LLM OpenAI Compatible Chat Provider
|
|
7
|
+
* @template ChatMessage 消息类型
|
|
8
|
+
* @template Input 请求参数类型
|
|
9
|
+
* @template Output 响应数据类型
|
|
10
|
+
*/
|
|
11
|
+
export default class OpenAIChatProvider<ChatMessage extends XModelMessage = XModelMessage, Input extends XModelParams = XModelParams, Output extends Partial<Record<SSEFields, any>> = Partial<Record<SSEFields, any>>> extends AbstractChatProvider<ChatMessage, Input, Output> {
|
|
12
|
+
transformParams(requestParams: Partial<Input>, options: XRequestOptions<Input, Output, ChatMessage>): Input;
|
|
13
|
+
transformLocalMessage(requestParams: Partial<Input>): ChatMessage[];
|
|
14
|
+
transformMessage(info: TransformMessage<ChatMessage, Output>): ChatMessage;
|
|
15
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { ChatProviderConfig, TransformMessage, } from './AbstractChatProvider';
|
|
2
|
+
export { default as AbstractChatProvider } from './AbstractChatProvider';
|
|
3
|
+
export { default as DeepSeekChatProvider } from './DeepSeekChatProvider';
|
|
4
|
+
export { default as DefaultChatProvider } from './DefaultChatProvider';
|
|
5
|
+
export { default as OpenAIChatProvider } from './OpenAIChatProvider';
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { AnyObject } from '../../_util/types';
|
|
2
|
+
export interface XModelMessage extends AnyObject {
|
|
3
|
+
role: string;
|
|
4
|
+
content: string | {
|
|
5
|
+
text: string;
|
|
6
|
+
type: string;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export interface XModelParams extends AnyObject {
|
|
10
|
+
model?: string;
|
|
11
|
+
messages?: XModelMessage[];
|
|
12
|
+
frequency_penalty?: number;
|
|
13
|
+
logit_bias?: AnyObject;
|
|
14
|
+
logprobs?: boolean;
|
|
15
|
+
max_completion_tokens?: number;
|
|
16
|
+
metadata?: AnyObject;
|
|
17
|
+
modalities?: string[];
|
|
18
|
+
n?: number;
|
|
19
|
+
parallel_tool_calls?: boolean;
|
|
20
|
+
prediction?: {
|
|
21
|
+
content: string;
|
|
22
|
+
type: string;
|
|
23
|
+
};
|
|
24
|
+
presence_penalty?: number;
|
|
25
|
+
reasoning_effort?: string;
|
|
26
|
+
response_format?: "text" | {
|
|
27
|
+
type: "json_object";
|
|
28
|
+
} | {
|
|
29
|
+
type: "json_schema";
|
|
30
|
+
json_schema: {
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
schema?: AnyObject;
|
|
34
|
+
strict?: boolean;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
seed?: number;
|
|
38
|
+
service_tier?: string;
|
|
39
|
+
stop?: string | string[];
|
|
40
|
+
store?: boolean;
|
|
41
|
+
stream?: boolean;
|
|
42
|
+
stream_options?: {
|
|
43
|
+
include_usage?: boolean;
|
|
44
|
+
};
|
|
45
|
+
temperature?: number;
|
|
46
|
+
tool_choice?: string | {
|
|
47
|
+
type: "function";
|
|
48
|
+
function: {
|
|
49
|
+
name: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
top_logprobs?: number;
|
|
53
|
+
top_p?: number;
|
|
54
|
+
user?: string;
|
|
55
|
+
web_search_options?: {
|
|
56
|
+
search_context_size?: string;
|
|
57
|
+
user_location?: {
|
|
58
|
+
type: "approximate";
|
|
59
|
+
approximate?: {
|
|
60
|
+
city?: string;
|
|
61
|
+
country?: string;
|
|
62
|
+
region?: string;
|
|
63
|
+
timezone?: string;
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export interface XModelResponse {
|
|
69
|
+
choices: {
|
|
70
|
+
index: number;
|
|
71
|
+
message: {
|
|
72
|
+
role: string;
|
|
73
|
+
content: string | null;
|
|
74
|
+
reasoning_content: string | null;
|
|
75
|
+
refusal: string | null;
|
|
76
|
+
annotations: {
|
|
77
|
+
type: "url_citation";
|
|
78
|
+
end_index: number;
|
|
79
|
+
start_index: number;
|
|
80
|
+
url: string;
|
|
81
|
+
title: string;
|
|
82
|
+
}[];
|
|
83
|
+
};
|
|
84
|
+
logprobs: AnyObject | null;
|
|
85
|
+
finish_reason: "stop" | "length" | "content_filter" | "tool_calls" | string;
|
|
86
|
+
}[];
|
|
87
|
+
created: number;
|
|
88
|
+
id: string;
|
|
89
|
+
model: string;
|
|
90
|
+
object: "chat.completion" | "chat.completion.chunk";
|
|
91
|
+
service_tier: string | null;
|
|
92
|
+
system_fingerprint: string | null;
|
|
93
|
+
usage: {
|
|
94
|
+
completion_tokens: number;
|
|
95
|
+
prompt_tokens: number;
|
|
96
|
+
total_tokens: number;
|
|
97
|
+
completion_tokens_details: {
|
|
98
|
+
reasoning_tokens: number;
|
|
99
|
+
audio_tokens: number;
|
|
100
|
+
accepted_prediction_tokens: number;
|
|
101
|
+
rejected_prediction_tokens: number;
|
|
102
|
+
};
|
|
103
|
+
prompt_tokens_details: {
|
|
104
|
+
cached_tokens: number;
|
|
105
|
+
audio_tokens: number;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
//#region src/chat-providers/AbstractChatProvider.ts
|
|
2
|
+
var AbstractChatProvider = class {
|
|
3
|
+
_request;
|
|
4
|
+
_getMessagesFn;
|
|
5
|
+
_originalCallbacks;
|
|
6
|
+
get request() {
|
|
7
|
+
return this._request;
|
|
8
|
+
}
|
|
9
|
+
constructor(config) {
|
|
10
|
+
const request = typeof config.request === "function" ? config.request() : config.request;
|
|
11
|
+
if (!request.manual) throw new Error("request must be manual");
|
|
12
|
+
this._request = request;
|
|
13
|
+
this._originalCallbacks = this._request.options?.callbacks;
|
|
14
|
+
}
|
|
15
|
+
getMessages() {
|
|
16
|
+
return this?._getMessagesFn();
|
|
17
|
+
}
|
|
18
|
+
injectGetMessages(getMessages) {
|
|
19
|
+
this._getMessagesFn = getMessages;
|
|
20
|
+
}
|
|
21
|
+
injectRequest({ onUpdate, onSuccess, onError }) {
|
|
22
|
+
const originalOnUpdate = this._originalCallbacks?.onUpdate;
|
|
23
|
+
const originalOnSuccess = this._originalCallbacks?.onSuccess;
|
|
24
|
+
const originalOnError = this._originalCallbacks?.onError;
|
|
25
|
+
this._request.options.callbacks = {
|
|
26
|
+
onUpdate: (data, responseHeaders) => {
|
|
27
|
+
const msg = onUpdate(data, responseHeaders);
|
|
28
|
+
if (originalOnUpdate) originalOnUpdate(data, responseHeaders, msg);
|
|
29
|
+
},
|
|
30
|
+
onSuccess: (data, responseHeaders) => {
|
|
31
|
+
const msg = onSuccess(data, responseHeaders);
|
|
32
|
+
if (originalOnSuccess) originalOnSuccess(data, responseHeaders, msg);
|
|
33
|
+
},
|
|
34
|
+
onError: (error, errorInfo, responseHeaders) => {
|
|
35
|
+
const fallbackMsg = onError(error, errorInfo);
|
|
36
|
+
if (originalOnError) originalOnError(error, errorInfo, responseHeaders, fallbackMsg);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/chat-providers/DeepSeekChatProvider.ts
|
|
43
|
+
/**
|
|
44
|
+
* DeepSeek Chat Provider
|
|
45
|
+
* @template ChatMessage 消息类型
|
|
46
|
+
* @template Input 请求参数类型
|
|
47
|
+
* @template Output 响应数据类型
|
|
48
|
+
*/
|
|
49
|
+
var DeepSeekChatProvider = class extends AbstractChatProvider {
|
|
50
|
+
transformParams(requestParams, options) {
|
|
51
|
+
return {
|
|
52
|
+
...options?.params,
|
|
53
|
+
...requestParams,
|
|
54
|
+
messages: this.getMessages()
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
transformLocalMessage(requestParams) {
|
|
58
|
+
return requestParams?.messages || [];
|
|
59
|
+
}
|
|
60
|
+
transformMessage(info) {
|
|
61
|
+
const { originMessage, chunk, responseHeaders } = info;
|
|
62
|
+
let currentContent = "";
|
|
63
|
+
let currentThink = "";
|
|
64
|
+
let role = "assistant";
|
|
65
|
+
try {
|
|
66
|
+
let message;
|
|
67
|
+
if (responseHeaders.get("content-type")?.includes("text/event-stream")) {
|
|
68
|
+
if (chunk && chunk.data?.trim() !== "[DONE]") message = JSON.parse(chunk.data);
|
|
69
|
+
} else message = chunk;
|
|
70
|
+
if (message) message?.choices?.forEach((choice) => {
|
|
71
|
+
if (choice?.delta) {
|
|
72
|
+
currentThink = choice.delta.reasoning_content || "";
|
|
73
|
+
currentContent += choice.delta.content || "";
|
|
74
|
+
role = choice.delta.role;
|
|
75
|
+
} else if (choice?.message) {
|
|
76
|
+
currentThink = choice.message.reasoning_content || "";
|
|
77
|
+
currentContent += choice.message.content || "";
|
|
78
|
+
role = choice.message.role;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error("transformMessage error", error);
|
|
83
|
+
}
|
|
84
|
+
let content = "";
|
|
85
|
+
let originMessageContent = typeof originMessage?.content === "string" ? originMessage?.content : originMessage?.content.text || "";
|
|
86
|
+
if (!originMessageContent && currentThink) content = `\n\n<think>\n\n${currentThink?.replace?.(/^\n{0,2}/, "")}`;
|
|
87
|
+
else if (originMessageContent.includes("<think>") && !originMessageContent.includes("</think>") && currentContent) {
|
|
88
|
+
originMessageContent = originMessageContent.replace("<think>", "<think status=\"done\">");
|
|
89
|
+
content = `${originMessageContent?.replace?.(/[\s\n]{0,2}$/, "")}\n\n</think>\n\n${currentContent}`;
|
|
90
|
+
} else content = `${originMessageContent || ""}${currentThink}${currentContent}`;
|
|
91
|
+
return {
|
|
92
|
+
content,
|
|
93
|
+
role: role || "assistant"
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/chat-providers/DefaultChatProvider.ts
|
|
99
|
+
var DefaultChatProvider = class extends AbstractChatProvider {
|
|
100
|
+
transformParams(requestParams, options) {
|
|
101
|
+
if (typeof requestParams !== "object") throw new Error("requestParams must be an object");
|
|
102
|
+
return {
|
|
103
|
+
...options?.params,
|
|
104
|
+
...requestParams
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
transformLocalMessage(requestParams) {
|
|
108
|
+
return requestParams;
|
|
109
|
+
}
|
|
110
|
+
transformMessage(info) {
|
|
111
|
+
const { chunk, chunks, originMessage } = info;
|
|
112
|
+
if (chunk) return chunk;
|
|
113
|
+
if (Array.isArray(chunks)) {
|
|
114
|
+
const chunk = chunks?.length > 0 ? chunks?.[chunks?.length - 1] : void 0;
|
|
115
|
+
return originMessage ? originMessage : chunk;
|
|
116
|
+
}
|
|
117
|
+
return chunks;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region src/chat-providers/OpenAIChatProvider.ts
|
|
122
|
+
/**
|
|
123
|
+
* LLM OpenAI Compatible Chat Provider
|
|
124
|
+
* @template ChatMessage 消息类型
|
|
125
|
+
* @template Input 请求参数类型
|
|
126
|
+
* @template Output 响应数据类型
|
|
127
|
+
*/
|
|
128
|
+
var OpenAIChatProvider = class extends AbstractChatProvider {
|
|
129
|
+
transformParams(requestParams, options) {
|
|
130
|
+
return {
|
|
131
|
+
...options?.params,
|
|
132
|
+
...requestParams,
|
|
133
|
+
messages: this.getMessages()
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
transformLocalMessage(requestParams) {
|
|
137
|
+
return requestParams?.messages || [];
|
|
138
|
+
}
|
|
139
|
+
transformMessage(info) {
|
|
140
|
+
const { originMessage, chunk, responseHeaders } = info;
|
|
141
|
+
let currentContent = "";
|
|
142
|
+
let role = "assistant";
|
|
143
|
+
try {
|
|
144
|
+
let message;
|
|
145
|
+
if (responseHeaders.get("content-type")?.includes("text/event-stream")) {
|
|
146
|
+
if (chunk && chunk.data?.trim() !== "[DONE]") message = JSON.parse(chunk.data);
|
|
147
|
+
} else message = chunk;
|
|
148
|
+
if (message) message?.choices?.forEach((choice) => {
|
|
149
|
+
if (choice?.delta) {
|
|
150
|
+
currentContent += choice.delta.content || "";
|
|
151
|
+
role = choice.delta.role || "assistant";
|
|
152
|
+
} else if (choice?.message) {
|
|
153
|
+
currentContent += choice.message.content || "";
|
|
154
|
+
role = choice.message.role || "assistant";
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error("transformMessage error", error);
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
content: `${originMessage?.content || ""}${currentContent || ""}`,
|
|
162
|
+
role
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
//#endregion
|
|
167
|
+
export { AbstractChatProvider as i, DefaultChatProvider as n, DeepSeekChatProvider as r, OpenAIChatProvider as t };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export * from './chat-providers';
|
|
2
|
+
export type { XModelMessage, XModelParams, XModelResponse, } from './chat-providers/types/model';
|
|
3
|
+
export type { DefaultMessageInfo, MessageInfo } from './x-chat';
|
|
4
|
+
export { default as useXChat } from './x-chat';
|
|
5
|
+
export type { ConversationData } from './x-conversations';
|
|
6
|
+
export { default as useXConversations } from './x-conversations';
|
|
7
|
+
export type { XRequestCallbacks, XRequestClass, XRequestFunction, XRequestGlobalOptions, XRequestOptions, } from './x-request';
|
|
8
|
+
export { AbstractXRequestClass, default as XRequest, setXRequestGlobalOptions, } from './x-request';
|
|
9
|
+
export type { SSEFields, SSEOutput, XReadableStream, XStreamOptions, } from './x-stream';
|
|
10
|
+
export { default as XStream } from './x-stream';
|
|
11
|
+
export interface XSdkClientOptions {
|
|
12
|
+
baseURL: string;
|
|
13
|
+
fetcher?: typeof fetch;
|
|
14
|
+
}
|
|
15
|
+
export interface RequestOptions {
|
|
16
|
+
headers?: HeadersInit;
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
}
|
|
19
|
+
export declare class XSdkClient {
|
|
20
|
+
private readonly baseURL;
|
|
21
|
+
private readonly fetcher;
|
|
22
|
+
constructor(options: XSdkClientOptions);
|
|
23
|
+
get<T = unknown>(path: string, options?: RequestOptions): Promise<T>;
|
|
24
|
+
}
|
|
25
|
+
export declare function createXSdkClient(options: XSdkClientOptions): XSdkClient;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { i as AbstractChatProvider, n as DefaultChatProvider, r as DeepSeekChatProvider, t as OpenAIChatProvider } from "./chat-providers-5x9Va7p5.js";
|
|
2
|
+
import XStream from "./x-stream/index.js";
|
|
3
|
+
import { i as setXRequestGlobalOptions, n as XRequest, t as AbstractXRequestClass } from "./x-request-BSFGaKND.js";
|
|
4
|
+
import useXChat from "./x-chat/index.js";
|
|
5
|
+
import { t as useXConversations } from "./x-conversations-BrKWhj5r.js";
|
|
6
|
+
//#region src/index.ts
|
|
7
|
+
var XSdkClient = class {
|
|
8
|
+
baseURL;
|
|
9
|
+
fetcher;
|
|
10
|
+
constructor(options) {
|
|
11
|
+
this.baseURL = options.baseURL.replace(/\/$/, "");
|
|
12
|
+
this.fetcher = options.fetcher ?? fetch;
|
|
13
|
+
}
|
|
14
|
+
async get(path, options = {}) {
|
|
15
|
+
return (await this.fetcher(`${this.baseURL}/${path.replace(/^\//, "")}`, {
|
|
16
|
+
method: "GET",
|
|
17
|
+
headers: options.headers,
|
|
18
|
+
signal: options.signal
|
|
19
|
+
})).json();
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
function createXSdkClient(options) {
|
|
23
|
+
return new XSdkClient(options);
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { AbstractChatProvider, AbstractXRequestClass, DeepSeekChatProvider, DefaultChatProvider, OpenAIChatProvider, XRequest, XSdkClient, XStream, createXSdkClient, setXRequestGlobalOptions, useXChat, useXConversations };
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
//#region src/x-chat/store.ts
|
|
2
|
+
var chatMessagesStoreHelper = {
|
|
3
|
+
_chatMessagesStores: /* @__PURE__ */ new Map(),
|
|
4
|
+
get: (conversationKey) => {
|
|
5
|
+
return chatMessagesStoreHelper._chatMessagesStores.get(conversationKey);
|
|
6
|
+
},
|
|
7
|
+
set: (key, store) => {
|
|
8
|
+
chatMessagesStoreHelper._chatMessagesStores.set(key, store);
|
|
9
|
+
},
|
|
10
|
+
delete: (key) => {
|
|
11
|
+
chatMessagesStoreHelper._chatMessagesStores.delete(key);
|
|
12
|
+
},
|
|
13
|
+
getMessages: (conversationKey) => {
|
|
14
|
+
return chatMessagesStoreHelper._chatMessagesStores.get(conversationKey)?.getMessages();
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var ChatMessagesStore = class {
|
|
18
|
+
listeners = [];
|
|
19
|
+
conversationKey;
|
|
20
|
+
snapshotResult = {
|
|
21
|
+
messages: [],
|
|
22
|
+
isDefaultMessagesRequesting: false
|
|
23
|
+
};
|
|
24
|
+
throttleTimer = null;
|
|
25
|
+
pendingEmit = false;
|
|
26
|
+
throttleInterval = 50;
|
|
27
|
+
isDestroyed = false;
|
|
28
|
+
emitListeners() {
|
|
29
|
+
this.listeners.forEach((listener) => {
|
|
30
|
+
listener();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
throttledEmitListeners() {
|
|
34
|
+
if (!this.throttleTimer) {
|
|
35
|
+
this.emitListeners();
|
|
36
|
+
this.pendingEmit = false;
|
|
37
|
+
this.throttleTimer = setTimeout(() => {
|
|
38
|
+
this.throttleTimer = null;
|
|
39
|
+
if (this.pendingEmit) {
|
|
40
|
+
this.emitListeners();
|
|
41
|
+
this.pendingEmit = false;
|
|
42
|
+
}
|
|
43
|
+
}, this.throttleInterval);
|
|
44
|
+
} else this.pendingEmit = true;
|
|
45
|
+
}
|
|
46
|
+
constructor(defaultMessages, conversationKey) {
|
|
47
|
+
this.initializeMessages(defaultMessages, (value) => {
|
|
48
|
+
this.setSnapshotResult("isDefaultMessagesRequesting", value);
|
|
49
|
+
this.emitListeners();
|
|
50
|
+
});
|
|
51
|
+
if (conversationKey) {
|
|
52
|
+
this.conversationKey = conversationKey;
|
|
53
|
+
chatMessagesStoreHelper.set(this.conversationKey, this);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async initializeMessages(defaultMessages, setDefaultMessagesRequesting) {
|
|
57
|
+
try {
|
|
58
|
+
setDefaultMessagesRequesting(true);
|
|
59
|
+
const messages = await defaultMessages();
|
|
60
|
+
if (!this.isDestroyed) this.setMessagesInternal(messages, false);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.warn("Failed to initialize messages:", error);
|
|
63
|
+
if (!this.isDestroyed) this.setMessagesInternal([], false);
|
|
64
|
+
} finally {
|
|
65
|
+
setDefaultMessagesRequesting(false);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
setSnapshotResult = (key, value) => {
|
|
69
|
+
this.snapshotResult = {
|
|
70
|
+
...this.snapshotResult,
|
|
71
|
+
[key]: value
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
setMessagesInternal = (messages, throttle = true) => {
|
|
75
|
+
let list;
|
|
76
|
+
if (typeof messages === "function") list = messages(this.snapshotResult.messages);
|
|
77
|
+
else list = messages;
|
|
78
|
+
this.setSnapshotResult("messages", list);
|
|
79
|
+
if (throttle) this.throttledEmitListeners();
|
|
80
|
+
else this.emitListeners();
|
|
81
|
+
return true;
|
|
82
|
+
};
|
|
83
|
+
setMessages = (messages) => {
|
|
84
|
+
return this.setMessagesInternal(messages, true);
|
|
85
|
+
};
|
|
86
|
+
getMessages = () => {
|
|
87
|
+
return this.snapshotResult.messages;
|
|
88
|
+
};
|
|
89
|
+
getMessage = (id) => {
|
|
90
|
+
return this.getMessages().find((item) => item.id === id);
|
|
91
|
+
};
|
|
92
|
+
addMessage = (message) => {
|
|
93
|
+
if (!this.getMessage(message.id)) {
|
|
94
|
+
this.setMessages([...this.snapshotResult.messages, message]);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
};
|
|
99
|
+
setMessage = (id, message) => {
|
|
100
|
+
const originMessage = this.getMessage(id);
|
|
101
|
+
if (originMessage) {
|
|
102
|
+
const mergeMessage = typeof message === "function" ? message(originMessage) : message;
|
|
103
|
+
Object.assign(originMessage, mergeMessage);
|
|
104
|
+
this.setMessages([...this.snapshotResult.messages]);
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
};
|
|
109
|
+
removeMessage = (id) => {
|
|
110
|
+
const index = this.getMessages().findIndex((item) => item.id === id);
|
|
111
|
+
if (index !== -1) {
|
|
112
|
+
this.snapshotResult.messages.splice(index, 1);
|
|
113
|
+
this.setMessages([...this.getMessages()]);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
};
|
|
118
|
+
getSnapshot = () => {
|
|
119
|
+
return this.snapshotResult;
|
|
120
|
+
};
|
|
121
|
+
subscribe = (callback) => {
|
|
122
|
+
this.listeners.push(callback);
|
|
123
|
+
return () => {
|
|
124
|
+
this.listeners = this.listeners.filter((listener) => listener !== callback);
|
|
125
|
+
if (this.listeners.length === 0) {
|
|
126
|
+
if (this.throttleTimer) {
|
|
127
|
+
clearTimeout(this.throttleTimer);
|
|
128
|
+
this.throttleTimer = null;
|
|
129
|
+
}
|
|
130
|
+
this.pendingEmit = false;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
destroy = () => {
|
|
135
|
+
this.isDestroyed = true;
|
|
136
|
+
if (this.throttleTimer) {
|
|
137
|
+
clearTimeout(this.throttleTimer);
|
|
138
|
+
this.throttleTimer = null;
|
|
139
|
+
}
|
|
140
|
+
this.pendingEmit = false;
|
|
141
|
+
this.listeners = [];
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
//#endregion
|
|
145
|
+
export { chatMessagesStoreHelper as n, ChatMessagesStore as t };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
import { AnyObject } from '../_util/types';
|
|
3
|
+
import { ConversationData } from '../x-conversations';
|
|
4
|
+
import { SSEOutput } from '../x-stream';
|
|
5
|
+
import { ConversationKey } from './store';
|
|
6
|
+
import { AbstractChatProvider } from '../chat-providers';
|
|
7
|
+
export type SimpleType = string | number | boolean | object;
|
|
8
|
+
declare enum MessageStatusEnum {
|
|
9
|
+
local = "local",
|
|
10
|
+
loading = "loading",
|
|
11
|
+
updating = "updating",
|
|
12
|
+
success = "success",
|
|
13
|
+
error = "error",
|
|
14
|
+
abort = "abort"
|
|
15
|
+
}
|
|
16
|
+
export type MessageStatus = `${MessageStatusEnum}`;
|
|
17
|
+
type RequestPlaceholderFn<Input, Message> = (requestParams: Partial<Input>, info: {
|
|
18
|
+
messages: Message[];
|
|
19
|
+
}) => Message;
|
|
20
|
+
type RequestFallbackFn<Input, MessageInfoType, Message> = (requestParams: Partial<Input>, info: {
|
|
21
|
+
error: Error;
|
|
22
|
+
errorInfo?: any;
|
|
23
|
+
messages: Message[];
|
|
24
|
+
messageInfo: MessageInfoType;
|
|
25
|
+
}) => Message | Promise<Message>;
|
|
26
|
+
export type RequestParams<Message> = {
|
|
27
|
+
[Key: PropertyKey]: Message;
|
|
28
|
+
} & AnyObject;
|
|
29
|
+
type MaybeRef<T> = T | Ref<T>;
|
|
30
|
+
export interface XChatConfig<ChatMessage extends SimpleType = string, BubbleMessage extends SimpleType = ChatMessage, Input = ChatMessage, Output = ChatMessage> {
|
|
31
|
+
provider?: AbstractChatProvider<ChatMessage, Input, Output>;
|
|
32
|
+
conversationKey?: MaybeRef<ConversationData["key"] | undefined>;
|
|
33
|
+
defaultMessages?: DefaultMessageInfo<ChatMessage>[] | ((info: {
|
|
34
|
+
conversationKey?: ConversationData["key"];
|
|
35
|
+
}) => Promise<DefaultMessageInfo<ChatMessage>[]>) | ((info?: {
|
|
36
|
+
conversationKey?: ConversationData["key"];
|
|
37
|
+
}) => DefaultMessageInfo<ChatMessage>[]);
|
|
38
|
+
parser?: (message: ChatMessage) => BubbleMessage | BubbleMessage[];
|
|
39
|
+
requestPlaceholder?: ChatMessage | RequestPlaceholderFn<Input, ChatMessage>;
|
|
40
|
+
requestFallback?: ChatMessage | RequestFallbackFn<Input, MessageInfo<ChatMessage>, ChatMessage>;
|
|
41
|
+
}
|
|
42
|
+
export interface MessageInfo<Message extends SimpleType> {
|
|
43
|
+
id: number | string;
|
|
44
|
+
message: Message;
|
|
45
|
+
status: MessageStatus;
|
|
46
|
+
extraInfo?: AnyObject;
|
|
47
|
+
}
|
|
48
|
+
export type DefaultMessageInfo<Message extends SimpleType> = Pick<MessageInfo<Message>, "message"> & Partial<Omit<MessageInfo<Message>, "message">>;
|
|
49
|
+
export type RequestResultObject<Message> = {
|
|
50
|
+
message: Message | Message[];
|
|
51
|
+
status: MessageStatus;
|
|
52
|
+
};
|
|
53
|
+
export type StandardRequestResult<Message extends SimpleType> = Omit<RequestResultObject<Message>, "message" | "status"> & {
|
|
54
|
+
message: Message;
|
|
55
|
+
status?: MessageStatus;
|
|
56
|
+
};
|
|
57
|
+
export default function useXChat<ChatMessage extends SimpleType = string, ParsedMessage extends SimpleType = ChatMessage, Input = RequestParams<ChatMessage>, Output = SSEOutput>(config: XChatConfig<ChatMessage, ParsedMessage, Input, Output>): {
|
|
58
|
+
readonly onRequest: (requestParams: Partial<Input>, opts?: {
|
|
59
|
+
extraInfo: AnyObject;
|
|
60
|
+
}) => void;
|
|
61
|
+
readonly isDefaultMessagesRequesting: Ref<boolean, boolean>;
|
|
62
|
+
readonly messages: Ref<{
|
|
63
|
+
id: number | string;
|
|
64
|
+
message: import('vue').UnwrapRef<ChatMessage>;
|
|
65
|
+
status: MessageStatus;
|
|
66
|
+
extraInfo?: AnyObject | undefined;
|
|
67
|
+
}[], MessageInfo<ChatMessage>[] | {
|
|
68
|
+
id: number | string;
|
|
69
|
+
message: import('vue').UnwrapRef<ChatMessage>;
|
|
70
|
+
status: MessageStatus;
|
|
71
|
+
extraInfo?: AnyObject | undefined;
|
|
72
|
+
}[]>;
|
|
73
|
+
readonly parsedMessages: import('vue').ComputedRef<MessageInfo<ParsedMessage>[]>;
|
|
74
|
+
readonly setMessages: (updater: MessageInfo<ChatMessage>[] | ((ori: MessageInfo<ChatMessage>[]) => MessageInfo<ChatMessage>[])) => boolean;
|
|
75
|
+
readonly removeMessage: (id: string | number) => boolean;
|
|
76
|
+
readonly setMessage: (id: string | number, message: Partial<MessageInfo<ChatMessage>> | ((message: MessageInfo<ChatMessage>) => Partial<MessageInfo<ChatMessage>>)) => boolean;
|
|
77
|
+
readonly abort: () => void;
|
|
78
|
+
readonly isRequesting: import('vue').ComputedRef<boolean>;
|
|
79
|
+
readonly onReload: (id: string | number, requestParams: Partial<Input>, opts?: {
|
|
80
|
+
extraInfo: AnyObject;
|
|
81
|
+
}) => void;
|
|
82
|
+
readonly queueRequest: (currentConversationKey: ConversationKey, requestParams: Partial<Input>, opts?: {
|
|
83
|
+
extraInfo: AnyObject;
|
|
84
|
+
}) => void;
|
|
85
|
+
};
|
|
86
|
+
export {};
|