@cloudbase/ai 3.6.5-alpha.0 → 3.6.5-alpha.2
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/.eslintignore +2 -0
- package/.eslintrc.js +16 -0
- package/package.json +4 -8
- package/src/AI.ts +191 -0
- package/src/bot/index.ts +278 -0
- package/src/bot/types.ts +165 -0
- package/src/errors.ts +23 -0
- package/src/eventsource_parser/index.ts +2 -0
- package/src/eventsource_parser/parse.ts +169 -0
- package/src/eventsource_parser/stream.ts +35 -0
- package/src/eventsource_parser/types.ts +90 -0
- package/src/index.ts +165 -0
- package/src/models/Ark/index.ts +94 -0
- package/src/models/Ark/type.ts +82 -0
- package/src/models/DashScope/index.ts +97 -0
- package/src/models/DashScope/type.ts +76 -0
- package/src/models/DeepSeek/index.ts +80 -0
- package/src/models/Default/index.ts +70 -0
- package/src/models/HunYuan/index.ts +94 -0
- package/src/models/HunYuan/type.ts +85 -0
- package/src/models/HunYuan/util.ts +60 -0
- package/src/models/HunYuanBeta/index.ts +83 -0
- package/src/models/HunYuanExp/index.ts +80 -0
- package/src/models/HunYuanOpen/index.ts +83 -0
- package/src/models/Moonshot/index.ts +95 -0
- package/src/models/Moonshot/type.ts +82 -0
- package/src/models/Yi/index.ts +100 -0
- package/src/models/Yi/type.ts +77 -0
- package/src/models/ZhiPu/index.ts +104 -0
- package/src/models/ZhiPu/type.ts +71 -0
- package/src/models/image-model.ts +100 -0
- package/src/models/index.ts +41 -0
- package/src/models/model.ts +425 -0
- package/src/type.ts +362 -0
- package/src/utils.ts +198 -0
- package/tsconfig.esm.json +16 -0
- package/tsconfig.json +16 -0
- package/webpack/web.prod.js +100 -0
- package/webpack/webpack.miniprogram.js +24 -0
package/src/type.ts
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
export abstract class SimpleChatModel {
|
|
2
|
+
public abstract doGenerate(data: BaseChatModelInput, options?: ReqOptions): Promise<DoGenerateOutput>
|
|
3
|
+
|
|
4
|
+
public abstract doStream(data: BaseChatModelInput, options?: ReqOptions): Promise<DoStreamOutput>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
type RawResponse = { rawResponse?: any }
|
|
8
|
+
|
|
9
|
+
export type DoGenerateOutput = BaseDoGenerateOutput & RawResponse
|
|
10
|
+
|
|
11
|
+
export type DoStreamOutput = AsyncIterableReadableStream<BaseDoStreamOutputChunk & RawResponse>
|
|
12
|
+
|
|
13
|
+
export type ChatModelConstructor = typeof SimpleChatModel
|
|
14
|
+
|
|
15
|
+
export type AsyncIterableReadableStream<T> = ReadableStream<T> & {
|
|
16
|
+
[Symbol.asyncIterator]: () => { next(): Promise<IteratorResult<T>> }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface IModelReqInput {
|
|
20
|
+
url: string
|
|
21
|
+
headers?: Record<string, string>
|
|
22
|
+
data?: Object
|
|
23
|
+
stream?: boolean
|
|
24
|
+
timeout?: number
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type ModelReq = <T extends IModelReqInput>(
|
|
28
|
+
props: T,
|
|
29
|
+
) => T['stream'] extends true ? Promise<ReadableStream<Uint8Array>> : Promise<Object>
|
|
30
|
+
|
|
31
|
+
export interface IBotReqInput {
|
|
32
|
+
url: string
|
|
33
|
+
method: string
|
|
34
|
+
headers?: Record<string, string>
|
|
35
|
+
data?: Object
|
|
36
|
+
stream?: boolean
|
|
37
|
+
timeout?: number
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface ReqOptions {
|
|
41
|
+
timeout?: number
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export type BotReq = <T extends IBotReqInput>(
|
|
45
|
+
props: T,
|
|
46
|
+
) => T['stream'] extends true ? Promise<ReadableStream<Uint8Array>> : Promise<Object>
|
|
47
|
+
|
|
48
|
+
export type UserMessage = {
|
|
49
|
+
role: 'user'
|
|
50
|
+
content: string
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export type SystemMessage = {
|
|
54
|
+
role: 'system'
|
|
55
|
+
content: string
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type AssistantMessage = PlainAssistantMessage | ToolCallAssistantMessage
|
|
59
|
+
|
|
60
|
+
export type PlainAssistantMessage = {
|
|
61
|
+
role: 'assistant'
|
|
62
|
+
content: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type ToolCallAssistantMessage = {
|
|
66
|
+
role: 'assistant'
|
|
67
|
+
tool_calls: Array<ToolCall>
|
|
68
|
+
content?: string
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type ToolMessage = {
|
|
72
|
+
role: 'tool'
|
|
73
|
+
tool_call_id: string
|
|
74
|
+
content: string
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export type ChatModelMessage = UserMessage | SystemMessage | AssistantMessage | ToolMessage
|
|
78
|
+
|
|
79
|
+
export type FunctionTool = {
|
|
80
|
+
name: string
|
|
81
|
+
description: string
|
|
82
|
+
fn: CallableFunction
|
|
83
|
+
parameters: object
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// #region 大模型标准输入类型
|
|
87
|
+
export interface BaseChatModelInput {
|
|
88
|
+
model: string
|
|
89
|
+
messages: Array<ChatModelMessage>
|
|
90
|
+
temperature?: number
|
|
91
|
+
top_p?: number
|
|
92
|
+
tools?: Array<ModelTool>
|
|
93
|
+
tool_choice?: 'none' | 'auto' | 'custom'
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 给 LLM 发请求时要传的工具
|
|
98
|
+
*/
|
|
99
|
+
export type ModelTool = {
|
|
100
|
+
type: string
|
|
101
|
+
function: ModelToolFunction
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* 给 LLM 发请求时要传的工具函数
|
|
106
|
+
*/
|
|
107
|
+
export type ModelToolFunction = {
|
|
108
|
+
name: string
|
|
109
|
+
description: string
|
|
110
|
+
/**
|
|
111
|
+
* 描述函数参数的 JSON Schema
|
|
112
|
+
*/
|
|
113
|
+
parameters: object
|
|
114
|
+
}
|
|
115
|
+
// #endregion
|
|
116
|
+
|
|
117
|
+
// #region 大模型标准响应类型
|
|
118
|
+
export type ToolCall = {
|
|
119
|
+
id: string
|
|
120
|
+
type: string
|
|
121
|
+
function: { name: string; arguments: string }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
type FinishReason = 'tool_calls' | (string & {})
|
|
125
|
+
|
|
126
|
+
export type Usage = {
|
|
127
|
+
completion_tokens: number
|
|
128
|
+
prompt_tokens: number
|
|
129
|
+
total_tokens: number
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface BaseDoGenerateOutput {
|
|
133
|
+
choices?: Array<{
|
|
134
|
+
finish_reason?: FinishReason
|
|
135
|
+
message?: ChatModelMessage
|
|
136
|
+
}>
|
|
137
|
+
usage?: Usage
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface BaseDoStreamOutputChunk {
|
|
141
|
+
choices?: Array<{
|
|
142
|
+
finish_reason?: FinishReason
|
|
143
|
+
delta?: ChatModelMessage
|
|
144
|
+
}>
|
|
145
|
+
usage?: Usage
|
|
146
|
+
}
|
|
147
|
+
// #endregion
|
|
148
|
+
|
|
149
|
+
// #region Image Model Types
|
|
150
|
+
/**
|
|
151
|
+
* 图片生成输入参数
|
|
152
|
+
*/
|
|
153
|
+
export interface ImageGenerateInput {
|
|
154
|
+
model: string // 模型名称,例如 'hunyuan-image'、'dall-e-3'
|
|
155
|
+
prompt: string // 用于描述要生成的图片内容
|
|
156
|
+
size?: string // 尺寸
|
|
157
|
+
n?: number // 张数
|
|
158
|
+
[key: string]: unknown // 允许额外的厂商特定参数
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* 图片编辑输入参数
|
|
163
|
+
*/
|
|
164
|
+
export interface ImageEditInput {
|
|
165
|
+
model: string
|
|
166
|
+
prompt: string
|
|
167
|
+
size?: string // 尺寸
|
|
168
|
+
n?: number // 张数
|
|
169
|
+
[key: string]: unknown // 允许额外的厂商特定参数
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface HunyuanGenerateImageInput {
|
|
173
|
+
model: 'hunyuan-image'
|
|
174
|
+
/** 用来生成图像的文本描述 */
|
|
175
|
+
prompt: string
|
|
176
|
+
/**
|
|
177
|
+
* 模型版本,支持 v1.8.1 和 v1.9,默认版本 v1.8.1
|
|
178
|
+
* - v1.8.1: 采用二阶段模型支持文生图任务,针对图像细节、稳定性等要求高的任务较为合适
|
|
179
|
+
* - v1.9: 采用模型矩阵能力支持文生图任务,后端由人像、游戏、通用模型,以及各类功能插件组成,灵活适配多种文生图任务
|
|
180
|
+
*/
|
|
181
|
+
version?: 'v1.8.1' | 'v1.9' | (string & {})
|
|
182
|
+
/**
|
|
183
|
+
* 图片尺寸,默认 "1024x1024"
|
|
184
|
+
* v1.9 仅支持以下几个尺寸:
|
|
185
|
+
* - 1024x1024
|
|
186
|
+
* - 1024x768, 1152x864
|
|
187
|
+
* - 768x1024, 864x1152
|
|
188
|
+
* - 1280x768 (16:9)
|
|
189
|
+
* - 768x1280 (9:16)
|
|
190
|
+
* - 1280x720 (16:9)
|
|
191
|
+
* - 720x1280 (9:16)
|
|
192
|
+
*
|
|
193
|
+
* 支持用户自定义尺寸,但输入尺寸只支持 768-1280 之间且为 64 的倍数的数字
|
|
194
|
+
*/
|
|
195
|
+
size?: string
|
|
196
|
+
/**
|
|
197
|
+
* 仅 v1.9 支持,负向词
|
|
198
|
+
* 如果不传则使用各个模型内部的默认负向词
|
|
199
|
+
*/
|
|
200
|
+
negative_prompt?: string
|
|
201
|
+
/**
|
|
202
|
+
* 仅 v1.9 支持,可指定风格:
|
|
203
|
+
* - 古风二次元风格
|
|
204
|
+
* - 都市二次元风格
|
|
205
|
+
* - 悬疑风格
|
|
206
|
+
* - 校园风格
|
|
207
|
+
* - 都市异能风格
|
|
208
|
+
*/
|
|
209
|
+
style?: '古风二次元风格' | '都市二次元风格' | '悬疑风格' | '校园风格' | '都市异能风格' | (string & {})
|
|
210
|
+
/**
|
|
211
|
+
* 为 true 时对 prompt 进行改写,实际生成的图片会使用改写后的 prompt 进行生成
|
|
212
|
+
* 多数场景可提升生成的图片效果,默认为 true
|
|
213
|
+
*/
|
|
214
|
+
revise?: boolean
|
|
215
|
+
/**
|
|
216
|
+
* 生成图片个数,默认为 1
|
|
217
|
+
* 目前只支持生成一张,固定为 1,传其他的值会报错
|
|
218
|
+
*/
|
|
219
|
+
n?: number
|
|
220
|
+
/**
|
|
221
|
+
* 业务自定义水印内容
|
|
222
|
+
* 限制 16 个字符长度(不区分中英文),生成在图片右下角
|
|
223
|
+
*/
|
|
224
|
+
footnote?: string
|
|
225
|
+
/**
|
|
226
|
+
* 生成种子,仅当生成图片数为 1 时生效
|
|
227
|
+
* 范围 [1, 4294967295],不传时默认随机
|
|
228
|
+
*/
|
|
229
|
+
seed?: number
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export interface HunyuanARGenerateImageInput {
|
|
233
|
+
/** 模型名称:hunyuan-image-v3.0-v1.0.4(推荐)或 hunyuan-image-v3.0-v1.0.1 */
|
|
234
|
+
model:
|
|
235
|
+
| 'HY-Image-3.0-Plus-4090-Tob-v1.0'
|
|
236
|
+
| 'HY-Image-v3.0-I2I-ToB-v1.0.1'
|
|
237
|
+
| 'hunyuan-image-v3.0-v1.0.4'
|
|
238
|
+
| 'hunyuan-image-v3.0-v1.0.1'
|
|
239
|
+
| 'hunyuan-image-v3.0-v1.0.5'
|
|
240
|
+
/** 生成图片使用的文本,不超过 8192 字符 */
|
|
241
|
+
prompt: string
|
|
242
|
+
/**
|
|
243
|
+
* 图片尺寸,格式 "${宽}x${高}",默认 "1024x1024"
|
|
244
|
+
* HY-Image-3.0-Plus-4090-Tob-v1.0 hunyuan-image-v3.0-v1.0.4:宽高 [512, 2048],面积不超过 1024x1024
|
|
245
|
+
* hunyuan-image-v3.0-v1.0.1:支持固定尺寸列表
|
|
246
|
+
*/
|
|
247
|
+
size?: string
|
|
248
|
+
/** 生成种子,仅当生成图片数为 1 时生效,范围 [1, 4294967295] */
|
|
249
|
+
seed?: number
|
|
250
|
+
/** 业务自定义水印内容,限制 16 字符,生成在图片右下角 */
|
|
251
|
+
footnote?: string
|
|
252
|
+
/** 是否对 prompt 改写,默认开启。改写会增加约 30s 耗时 */
|
|
253
|
+
revise?: { value: boolean }
|
|
254
|
+
/** 改写是否开启 thinking 模式,默认开启。开启后效果提升但耗时增加(最大 60s) */
|
|
255
|
+
enable_thinking?: { value: boolean }
|
|
256
|
+
/**
|
|
257
|
+
* 垫图url列表,与image二选一,优先选image,大小不超过10MB,支持 jpg jpeg png 格式,最多3张图,image_urls和images必有一个非空
|
|
258
|
+
*/
|
|
259
|
+
image_urls?: string[]
|
|
260
|
+
/**
|
|
261
|
+
* 垫图base64列表,与image_url二选一,优先选image,大小不超过10MB,支持 jpg jpeg png 格式,最多3张图
|
|
262
|
+
*/
|
|
263
|
+
images?: string[]
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export interface HunyuanARGenerateImageOutput {
|
|
267
|
+
/** 此次请求的 id */
|
|
268
|
+
id: string
|
|
269
|
+
/** unix 时间戳 */
|
|
270
|
+
created: number
|
|
271
|
+
/** 返回的图片生成内容 */
|
|
272
|
+
data: Array<{
|
|
273
|
+
/** 生成的图片 url,有效期 24 小时 */
|
|
274
|
+
url: string
|
|
275
|
+
/** 改写后的 prompt */
|
|
276
|
+
revised_prompt?: string
|
|
277
|
+
}>
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export type HunyuanEditImageInput = {
|
|
281
|
+
/** 模型名称,本期为 hunyuan-image,即为商品图编辑场景 */
|
|
282
|
+
model: 'hunyuan-image' | (string & {})
|
|
283
|
+
/** 编辑的文本描述 */
|
|
284
|
+
prompt: string
|
|
285
|
+
/** 模型版本 */
|
|
286
|
+
version?: string
|
|
287
|
+
/**
|
|
288
|
+
* 图片尺寸,默认 "800x800"
|
|
289
|
+
* 支持用户自定义尺寸,但输入尺寸只支持 512-1280 之间
|
|
290
|
+
* 目前只支持 1:1、16:9、9:16 三个尺寸
|
|
291
|
+
*/
|
|
292
|
+
size?: string
|
|
293
|
+
/**
|
|
294
|
+
* 生成图片个数,默认为 1
|
|
295
|
+
* 目前只支持生成一张,固定为 1,传其他的值会报错
|
|
296
|
+
*/
|
|
297
|
+
n?: number
|
|
298
|
+
/**
|
|
299
|
+
* beta 参数,随机种子
|
|
300
|
+
* 范围 [1, 4294967295],不传时默认随机
|
|
301
|
+
*/
|
|
302
|
+
seed?: number
|
|
303
|
+
/**
|
|
304
|
+
* 业务自定义角标内容
|
|
305
|
+
* 限制 16 个字符长度(不区分中英文)
|
|
306
|
+
*/
|
|
307
|
+
footnote?: string
|
|
308
|
+
/**
|
|
309
|
+
* 图 base64 编码,大小不超过 6M
|
|
310
|
+
* 支持 jpg/jpeg 格式,和 image_url 二选一
|
|
311
|
+
* 长短边比例要求 2:1 内
|
|
312
|
+
*/
|
|
313
|
+
image?: string
|
|
314
|
+
/**
|
|
315
|
+
* 图片 url
|
|
316
|
+
* 长短边比例要求 2:1 内,和 image 二选一
|
|
317
|
+
*/
|
|
318
|
+
image_url?: string
|
|
319
|
+
} & (
|
|
320
|
+
| {
|
|
321
|
+
mask: string
|
|
322
|
+
mask_url?: never
|
|
323
|
+
}
|
|
324
|
+
| {
|
|
325
|
+
mask?: never
|
|
326
|
+
mask_url: string
|
|
327
|
+
}
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* 混元图片生成输出
|
|
332
|
+
*/
|
|
333
|
+
export interface HunyuanGenerateImageOutput {
|
|
334
|
+
/** 此次请求的 id */
|
|
335
|
+
id: string
|
|
336
|
+
/** unix 时间戳 */
|
|
337
|
+
created: number
|
|
338
|
+
/** 返回的图片生成内容 */
|
|
339
|
+
data: Array<{
|
|
340
|
+
/** 生成的图片 url,有效期为 24 小时 */
|
|
341
|
+
url: string
|
|
342
|
+
/** 原 prompt 改写后的文本。若 revise 为 false,则为原 prompt */
|
|
343
|
+
revised_prompt?: string
|
|
344
|
+
}>
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* 混元图片编辑输出
|
|
349
|
+
*/
|
|
350
|
+
export interface HunyuanEditImageOutput {
|
|
351
|
+
/** 此次请求的 id */
|
|
352
|
+
id: string
|
|
353
|
+
/** unix 时间戳 */
|
|
354
|
+
created: number
|
|
355
|
+
/** 返回的图片生成内容 */
|
|
356
|
+
data: Array<{
|
|
357
|
+
/** 生成的图片 url,有效期为 24 小时 */
|
|
358
|
+
url: string
|
|
359
|
+
}>
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// #endregion
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { TransformStream as _TransformStream, ReadableStream as _ReadableStream } from 'web-streams-polyfill'
|
|
2
|
+
import { createReadableStreamWrapper } from '@mattiasbuelens/web-streams-adapter'
|
|
3
|
+
import { createParser, type EventSourceParser, type ParsedEvent } from './eventsource_parser'
|
|
4
|
+
import type {
|
|
5
|
+
AsyncIterableReadableStream,
|
|
6
|
+
ChatModelMessage,
|
|
7
|
+
ToolCallAssistantMessage,
|
|
8
|
+
ModelTool,
|
|
9
|
+
FunctionTool,
|
|
10
|
+
} from './type'
|
|
11
|
+
import { TextDecoder } from 'text-encoding-shim'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 检测当前环境是否原生支持完整的 Web Streams API(Node.js >= 18 或现代浏览器)
|
|
15
|
+
* 如果原生支持,则无需使用 polyfill,避免 web-streams-adapter 在高版本 Node.js 中的兼容问题
|
|
16
|
+
*/
|
|
17
|
+
const hasNativeStreams = typeof globalThis.ReadableStream === 'function'
|
|
18
|
+
&& typeof globalThis.TransformStream === 'function'
|
|
19
|
+
&& typeof globalThis.ReadableStream.prototype.pipeThrough === 'function'
|
|
20
|
+
|
|
21
|
+
export const ReadableStream = (hasNativeStreams ? globalThis.ReadableStream : _ReadableStream) as {
|
|
22
|
+
prototype: ReadableStream
|
|
23
|
+
|
|
24
|
+
new (
|
|
25
|
+
underlyingSource: UnderlyingByteSource,
|
|
26
|
+
strategy?: {
|
|
27
|
+
highWaterMark?: number
|
|
28
|
+
},
|
|
29
|
+
): ReadableStream<Uint8Array>
|
|
30
|
+
new <R = any>(underlyingSource: UnderlyingDefaultSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>
|
|
31
|
+
new <R = any>(underlyingSource?: UnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const TransformStream = (hasNativeStreams ? globalThis.TransformStream : _TransformStream) as {
|
|
35
|
+
prototype: TransformStream
|
|
36
|
+
|
|
37
|
+
new <I = any, O = any>(
|
|
38
|
+
transformer?: Transformer<I, O>,
|
|
39
|
+
writableStrategy?: QueuingStrategy<I>,
|
|
40
|
+
readableStrategy?: QueuingStrategy<O>,
|
|
41
|
+
): TransformStream<I, O>
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const createEventSourceParserTransformStream = () => {
|
|
45
|
+
let parser!: EventSourceParser
|
|
46
|
+
|
|
47
|
+
return new TransformStream<string, ParsedEvent>({
|
|
48
|
+
start(controller) {
|
|
49
|
+
parser = createParser((event) => {
|
|
50
|
+
if (event.type === 'event') {
|
|
51
|
+
controller.enqueue(event)
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
},
|
|
55
|
+
transform(chunk) {
|
|
56
|
+
parser.feed(chunk)
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 将任意 ReadableStream 转换为当前环境使用的 ReadableStream 实现
|
|
63
|
+
* - 在原生支持 Web Streams 的环境(Node.js >= 18、现代浏览器)中,直接返回原始 stream(无需转换)
|
|
64
|
+
* - 在不支持原生 Web Streams 的环境(旧浏览器、小程序)中,使用 web-streams-adapter 进行转换
|
|
65
|
+
*/
|
|
66
|
+
export const toPolyfillReadable: (readable: any) => any = hasNativeStreams
|
|
67
|
+
? readable => readable
|
|
68
|
+
: createReadableStreamWrapper(ReadableStream)
|
|
69
|
+
|
|
70
|
+
export class TextDecoderStream {
|
|
71
|
+
private handle: TextDecoder
|
|
72
|
+
|
|
73
|
+
private transform = new TransformStream({
|
|
74
|
+
transform: (chunk, controller) => {
|
|
75
|
+
const value = this.handle.decode(new Uint8Array(chunk), { stream: true })
|
|
76
|
+
|
|
77
|
+
if (value) {
|
|
78
|
+
controller.enqueue(value)
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
flush: (controller) => {
|
|
82
|
+
const value = this.handle.decode()
|
|
83
|
+
if (value) {
|
|
84
|
+
controller.enqueue(value)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
controller.terminate()
|
|
88
|
+
},
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
constructor(encoding = 'utf-8', options: TextDecoderOptions = {}) {
|
|
92
|
+
this.handle = new TextDecoder(encoding, options)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
get encoding() {
|
|
96
|
+
return this.handle.encoding
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
get fatal() {
|
|
100
|
+
return this.handle.fatal
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
get ignoreBOM() {
|
|
104
|
+
return this.handle.ignoreBOM
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
get readable() {
|
|
108
|
+
return this.transform.readable
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
get writable() {
|
|
112
|
+
return this.transform.writable
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
get [Symbol.toStringTag]() {
|
|
116
|
+
return 'TextDecoderStream'
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function createAsyncIterable<T>(stream: ReadableStream<T>) {
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
122
|
+
const _stream = stream as AsyncIterableReadableStream<T>
|
|
123
|
+
(_stream as any)[Symbol.asyncIterator] = () => {
|
|
124
|
+
const reader = stream.getReader()
|
|
125
|
+
return {
|
|
126
|
+
async next(): Promise<IteratorResult<T>> {
|
|
127
|
+
const { done, value } = await reader.read()
|
|
128
|
+
return done ? { done: true, value: undefined } : { done: false, value }
|
|
129
|
+
},
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return _stream
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* 将 SSE 二进制流转换为 T 类型的流
|
|
137
|
+
*/
|
|
138
|
+
export function intoStandardStream<T>(stream: ReadableStream<Uint8Array>): ReadableStream<T> {
|
|
139
|
+
return createAsyncIterable(stream
|
|
140
|
+
.pipeThrough(new TextDecoderStream())
|
|
141
|
+
.pipeThrough(createEventSourceParserTransformStream())
|
|
142
|
+
.pipeThrough(new TransformStream<ParsedEvent, T>({
|
|
143
|
+
transform(chunk, controller) {
|
|
144
|
+
try {
|
|
145
|
+
const data = JSON.parse(chunk.data) as T
|
|
146
|
+
controller.enqueue(data)
|
|
147
|
+
} catch (e) {
|
|
148
|
+
if (chunk.data !== '[DONE]') {
|
|
149
|
+
console.warn('Error when transforming event source data to json', e, chunk)
|
|
150
|
+
} else {
|
|
151
|
+
controller.terminate()
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
}),),)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 将 SSE 二进制流转换为字符串流
|
|
160
|
+
*/
|
|
161
|
+
export function intoTextStream(stream: ReadableStream<Uint8Array>): AsyncIterableReadableStream<string> {
|
|
162
|
+
return createAsyncIterable((toPolyfillReadable(stream) as typeof stream).pipeThrough(new TextDecoderStream()))
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export async function readableStream2JsonObject(stream: ReadableStream) {
|
|
166
|
+
const s = intoTextStream(stream)
|
|
167
|
+
let total = ''
|
|
168
|
+
for await (const chunk of s) {
|
|
169
|
+
total += chunk
|
|
170
|
+
}
|
|
171
|
+
return JSON.parse(total)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function createPromise<T = unknown>() {
|
|
175
|
+
let res: (value: T | PromiseLike<T>) => void
|
|
176
|
+
let rej: (reason?: any) => void
|
|
177
|
+
const promise = new Promise<T>((resolve, reject) => {
|
|
178
|
+
res = resolve
|
|
179
|
+
rej = reject
|
|
180
|
+
})
|
|
181
|
+
return { promise, res, rej }
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export function isToolCallAssistantMessage(message: ChatModelMessage): message is ToolCallAssistantMessage {
|
|
185
|
+
// eslint-disable-next-line eqeqeq
|
|
186
|
+
return message.role === 'assistant' && 'tool_calls' in message && message.tool_calls?.[0] != null
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function functionToolToModelTool(tool: FunctionTool): ModelTool {
|
|
190
|
+
return {
|
|
191
|
+
type: 'function',
|
|
192
|
+
function: {
|
|
193
|
+
description: tool.description,
|
|
194
|
+
name: tool.name,
|
|
195
|
+
parameters: tool.parameters,
|
|
196
|
+
},
|
|
197
|
+
}
|
|
198
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const webpack = require('webpack')
|
|
3
|
+
const TerserPlugin = require('terser-webpack-plugin')
|
|
4
|
+
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
|
5
|
+
module.exports = function (options) {
|
|
6
|
+
const { context, entry, output, mode, watch, externals, definePlugin = {}, optimization = {} } = options
|
|
7
|
+
const isDevelopment = mode !== 'production'
|
|
8
|
+
let plugins = [
|
|
9
|
+
new webpack.DefinePlugin(definePlugin),
|
|
10
|
+
// new BundleAnalyzerPlugin()
|
|
11
|
+
].filter((item) => !!item)
|
|
12
|
+
|
|
13
|
+
const BABEL_LOADER = {
|
|
14
|
+
loader: 'babel-loader',
|
|
15
|
+
options: {
|
|
16
|
+
presets: [
|
|
17
|
+
[
|
|
18
|
+
'@babel/preset-env',
|
|
19
|
+
{
|
|
20
|
+
modules: false,
|
|
21
|
+
targets: {
|
|
22
|
+
esmodules: true,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
context,
|
|
32
|
+
entry,
|
|
33
|
+
mode,
|
|
34
|
+
watch,
|
|
35
|
+
watchOptions: {
|
|
36
|
+
ignored: [output.path],
|
|
37
|
+
},
|
|
38
|
+
output,
|
|
39
|
+
externals,
|
|
40
|
+
cache: {
|
|
41
|
+
type: 'memory',
|
|
42
|
+
},
|
|
43
|
+
devtool: false,
|
|
44
|
+
resolve: {
|
|
45
|
+
extensions: ['.ts', '.js', '.json'],
|
|
46
|
+
},
|
|
47
|
+
module: {
|
|
48
|
+
rules: [
|
|
49
|
+
{
|
|
50
|
+
test: /\.ts$/,
|
|
51
|
+
exclude: [/node_modules/],
|
|
52
|
+
use: [
|
|
53
|
+
BABEL_LOADER,
|
|
54
|
+
{
|
|
55
|
+
loader: require.resolve('ts-loader'),
|
|
56
|
+
options: {
|
|
57
|
+
configFile: path.resolve(context, './tsconfig.esm.json'),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
test: /\.js$/,
|
|
64
|
+
exclude: [/node_modules/],
|
|
65
|
+
use: [BABEL_LOADER],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
test: /package\.json$/,
|
|
69
|
+
loader: 'package-json-cleanup-loader',
|
|
70
|
+
options: {
|
|
71
|
+
only: ['version'],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
noParse: [/sjcl\.js$/],
|
|
76
|
+
},
|
|
77
|
+
plugins,
|
|
78
|
+
optimization: {
|
|
79
|
+
emitOnErrors: false,
|
|
80
|
+
removeEmptyChunks: true,
|
|
81
|
+
usedExports: true,
|
|
82
|
+
...optimization,
|
|
83
|
+
...(isDevelopment
|
|
84
|
+
? {
|
|
85
|
+
minimize: false,
|
|
86
|
+
removeAvailableModules: false,
|
|
87
|
+
concatenateModules: true,
|
|
88
|
+
}
|
|
89
|
+
: {
|
|
90
|
+
minimizer: [
|
|
91
|
+
new TerserPlugin({
|
|
92
|
+
test: /\.js(\?.*)?$/i,
|
|
93
|
+
cache: false,
|
|
94
|
+
parallel: true,
|
|
95
|
+
}),
|
|
96
|
+
],
|
|
97
|
+
}),
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
|
|
3
|
+
const params = {
|
|
4
|
+
context: path.resolve(__dirname, '../'),
|
|
5
|
+
mode: 'production',
|
|
6
|
+
watch: false,
|
|
7
|
+
entry: path.resolve(__dirname, '../src/index.ts'),
|
|
8
|
+
output: {
|
|
9
|
+
path: path.resolve(__dirname, '../dist/miniprogram'),
|
|
10
|
+
filename: 'index.js',
|
|
11
|
+
library: `tcbauth`,
|
|
12
|
+
libraryTarget: 'umd',
|
|
13
|
+
umdNamedDefine: true,
|
|
14
|
+
globalObject: 'typeof window !== "undefined"?window:this',
|
|
15
|
+
},
|
|
16
|
+
externals: {
|
|
17
|
+
},
|
|
18
|
+
definePlugin: {
|
|
19
|
+
'process.env.NODE_ENV': JSON.stringify('production'), // 注入环境变量,用于业务代码判断
|
|
20
|
+
'globalThis.IS_MP_BUILD': true,
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = require('./web.prod.js')(params)
|