@cloudbase/ai 3.6.2 → 3.6.4-alpha.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.
Files changed (41) hide show
  1. package/dist/miniprogram/index.js +1 -1
  2. package/dist/miniprogram/index.js.LICENSE.txt +2 -2
  3. package/package.json +8 -4
  4. package/.eslintignore +0 -2
  5. package/.eslintrc.js +0 -16
  6. package/src/AI.ts +0 -191
  7. package/src/bot/index.ts +0 -278
  8. package/src/bot/types.ts +0 -165
  9. package/src/errors.ts +0 -23
  10. package/src/eventsource_parser/index.ts +0 -2
  11. package/src/eventsource_parser/parse.ts +0 -169
  12. package/src/eventsource_parser/stream.ts +0 -35
  13. package/src/eventsource_parser/types.ts +0 -90
  14. package/src/index.ts +0 -165
  15. package/src/models/Ark/index.ts +0 -94
  16. package/src/models/Ark/type.ts +0 -82
  17. package/src/models/DashScope/index.ts +0 -97
  18. package/src/models/DashScope/type.ts +0 -76
  19. package/src/models/DeepSeek/index.ts +0 -80
  20. package/src/models/Default/index.ts +0 -70
  21. package/src/models/HunYuan/index.ts +0 -94
  22. package/src/models/HunYuan/type.ts +0 -85
  23. package/src/models/HunYuan/util.ts +0 -60
  24. package/src/models/HunYuanBeta/index.ts +0 -83
  25. package/src/models/HunYuanExp/index.ts +0 -80
  26. package/src/models/HunYuanOpen/index.ts +0 -83
  27. package/src/models/Moonshot/index.ts +0 -95
  28. package/src/models/Moonshot/type.ts +0 -82
  29. package/src/models/Yi/index.ts +0 -100
  30. package/src/models/Yi/type.ts +0 -77
  31. package/src/models/ZhiPu/index.ts +0 -104
  32. package/src/models/ZhiPu/type.ts +0 -71
  33. package/src/models/image-model.ts +0 -100
  34. package/src/models/index.ts +0 -41
  35. package/src/models/model.ts +0 -425
  36. package/src/type.ts +0 -362
  37. package/src/utils.ts +0 -198
  38. package/tsconfig.esm.json +0 -16
  39. package/tsconfig.json +0 -16
  40. package/webpack/web.prod.js +0 -100
  41. package/webpack/webpack.miniprogram.js +0 -24
package/src/errors.ts DELETED
@@ -1,23 +0,0 @@
1
- /**
2
- * 参数校验错误类
3
- * 用于统一参数校验错误的格式
4
- */
5
- export class InvalidParamsError extends Error {
6
- public code: string
7
- public field?: string
8
-
9
- constructor(message: string, field?: string) {
10
- super(message)
11
- this.name = 'InvalidParamsError'
12
- this.code = 'INVALID_PARAMS'
13
- this.field = field
14
- }
15
-
16
- toJSON() {
17
- return {
18
- code: this.code,
19
- message: this.message,
20
- field: this.field,
21
- }
22
- }
23
- }
@@ -1,2 +0,0 @@
1
- export type { EventSourceParser, ParsedEvent, ReconnectInterval, ParseEvent, EventSourceParseCallback } from './types'
2
- export { createParser } from './parse'
@@ -1,169 +0,0 @@
1
- /**
2
- * EventSource/Server-Sent Events parser
3
- * @see https://html.spec.whatwg.org/multipage/server-sent-events.html
4
- *
5
- * Based on code from the {@link https://github.com/EventSource/eventsource | EventSource module},
6
- * which is licensed under the MIT license. And copyrighted the EventSource GitHub organisation.
7
- */
8
- import type { EventSourceParseCallback, EventSourceParser } from './types'
9
-
10
- /**
11
- * Creates a new EventSource parser.
12
- *
13
- * @param onParse - Callback to invoke when a new event is parsed, or a new reconnection interval
14
- * has been sent from the server
15
- *
16
- * @returns A new EventSource parser, with `parse` and `reset` methods.
17
- * @public
18
- */
19
- export function createParser(onParse: EventSourceParseCallback): EventSourceParser {
20
- // Processing state
21
- let isFirstChunk: boolean
22
- let buffer: string
23
- let startingPosition: number
24
- let startingFieldLength: number
25
-
26
- // Event state
27
- let eventId: string | undefined
28
- let eventName: string | undefined
29
- let data: string
30
-
31
- reset()
32
- return { feed, reset }
33
-
34
- function reset(): void {
35
- isFirstChunk = true
36
- buffer = ''
37
- startingPosition = 0
38
- startingFieldLength = -1
39
-
40
- eventId = undefined
41
- eventName = undefined
42
- data = ''
43
- }
44
-
45
- function feed(chunk: string): void {
46
- buffer = buffer ? buffer + chunk : chunk
47
-
48
- // Strip any UTF8 byte order mark (BOM) at the start of the stream.
49
- // Note that we do not strip any non - UTF8 BOM, as eventsource streams are
50
- // always decoded as UTF8 as per the specification.
51
- if (isFirstChunk && hasBom(buffer)) {
52
- buffer = buffer.slice(BOM.length)
53
- }
54
-
55
- isFirstChunk = false
56
-
57
- // Set up chunk-specific processing state
58
- const { length } = buffer
59
- let position = 0
60
- let discardTrailingNewline = false
61
-
62
- // Read the current buffer byte by byte
63
- while (position < length) {
64
- // EventSource allows for carriage return + line feed, which means we
65
- // need to ignore a linefeed character if the previous character was a
66
- // carriage return
67
- // @todo refactor to reduce nesting, consider checking previous byte?
68
- // @todo but consider multiple chunks etc
69
- if (discardTrailingNewline) {
70
- if (buffer[position] === '\n') {
71
- position += 1
72
- }
73
- discardTrailingNewline = false
74
- }
75
-
76
- let lineLength = -1
77
- let fieldLength = startingFieldLength
78
- let character: string
79
-
80
- for (let index = startingPosition; lineLength < 0 && index < length; index++) {
81
- character = buffer[index]
82
- if (character === ':' && fieldLength < 0) {
83
- fieldLength = index - position
84
- } else if (character === '\r') {
85
- discardTrailingNewline = true
86
- lineLength = index - position
87
- } else if (character === '\n') {
88
- lineLength = index - position
89
- }
90
- }
91
-
92
- if (lineLength < 0) {
93
- startingPosition = length - position
94
- startingFieldLength = fieldLength
95
- break
96
- } else {
97
- startingPosition = 0
98
- startingFieldLength = -1
99
- }
100
-
101
- parseEventStreamLine(buffer, position, fieldLength, lineLength)
102
-
103
- position += lineLength + 1
104
- }
105
-
106
- if (position === length) {
107
- // If we consumed the entire buffer to read the event, reset the buffer
108
- buffer = ''
109
- } else if (position > 0) {
110
- // If there are bytes left to process, set the buffer to the unprocessed
111
- // portion of the buffer only
112
- buffer = buffer.slice(position)
113
- }
114
- }
115
-
116
- function parseEventStreamLine(lineBuffer: string, index: number, fieldLength: number, lineLength: number) {
117
- if (lineLength === 0) {
118
- // We reached the last line of this event
119
- if (data.length > 0) {
120
- onParse({
121
- type: 'event',
122
- id: eventId,
123
- event: eventName || undefined,
124
- data: data.slice(0, -1), // remove trailing newline
125
- })
126
-
127
- data = ''
128
- eventId = undefined
129
- }
130
- eventName = undefined
131
- return
132
- }
133
-
134
- const noValue = fieldLength < 0
135
- const field = lineBuffer.slice(index, index + (noValue ? lineLength : fieldLength))
136
- let step = 0
137
-
138
- if (noValue) {
139
- step = lineLength
140
- } else if (lineBuffer[index + fieldLength + 1] === ' ') {
141
- step = fieldLength + 2
142
- } else {
143
- step = fieldLength + 1
144
- }
145
-
146
- const position = index + step
147
- const valueLength = lineLength - step
148
- const value = lineBuffer.slice(position, position + valueLength).toString()
149
-
150
- if (field === 'data') {
151
- data += value ? `${value}\n` : '\n'
152
- } else if (field === 'event') {
153
- eventName = value
154
- } else if (field === 'id' && !value.includes('\u0000')) {
155
- eventId = value
156
- } else if (field === 'retry') {
157
- const retry = parseInt(value, 10)
158
- if (!Number.isNaN(retry)) {
159
- onParse({ type: 'reconnect-interval', value: retry })
160
- }
161
- }
162
- }
163
- }
164
-
165
- const BOM = [239, 187, 191]
166
-
167
- function hasBom(buffer: string) {
168
- return BOM.every((charCode: number, index: number) => buffer.charCodeAt(index) === charCode)
169
- }
@@ -1,35 +0,0 @@
1
- import type { EventSourceParser, ParsedEvent } from './types'
2
- import { createParser } from './parse'
3
-
4
- /**
5
- * A TransformStream that ingests a stream of strings and produces a stream of ParsedEvents.
6
- *
7
- * @example
8
- * ```
9
- * const eventStream =
10
- * response.body
11
- * .pipeThrough(new TextDecoderStream())
12
- * .pipeThrough(new EventSourceParserStream())
13
- * ```
14
- * @public
15
- */
16
- export class EventSourceParserStream extends TransformStream<string, ParsedEvent> {
17
- constructor() {
18
- let parser!: EventSourceParser
19
-
20
- super({
21
- start(controller) {
22
- parser = createParser((event) => {
23
- if (event.type === 'event') {
24
- controller.enqueue(event)
25
- }
26
- })
27
- },
28
- transform(chunk) {
29
- parser.feed(chunk)
30
- },
31
- })
32
- }
33
- }
34
-
35
- export type { ParsedEvent } from './types'
@@ -1,90 +0,0 @@
1
- /**
2
- * EventSource parser instance.
3
- *
4
- * Needs to be reset between reconnections/when switching data source, using the `reset()` method.
5
- *
6
- * @public
7
- */
8
- export interface EventSourceParser {
9
- /**
10
- * Feeds the parser another chunk. The method _does not_ return a parsed message.
11
- * Instead, if the chunk was a complete message (or completed a previously incomplete message),
12
- * it will invoke the `onParse` callback used to create the parsers.
13
- *
14
- * @param chunk - The chunk to parse. Can be a partial, eg in the case of streaming messages.
15
- * @public
16
- */
17
- feed(chunk: string): void
18
-
19
- /**
20
- * Resets the parser state. This is required when you have a new stream of messages -
21
- * for instance in the case of a client being disconnected and reconnecting.
22
- *
23
- * @public
24
- */
25
- reset(): void
26
- }
27
-
28
- /**
29
- * A parsed EventSource event
30
- *
31
- * @public
32
- */
33
- export interface ParsedEvent {
34
- /**
35
- * Differentiates the type from reconnection intervals and other types of messages
36
- * Not to be confused with `event`.
37
- */
38
- type: 'event'
39
-
40
- /**
41
- * The event type sent from the server. Note that this differs from the browser `EventSource`
42
- * implementation in that browsers will default this to `message`, whereas this parser will
43
- * leave this as `undefined` if not explicitly declared.
44
- */
45
- event?: string
46
-
47
- /**
48
- * ID of the message, if any was provided by the server. Can be used by clients to keep the
49
- * last received message ID in sync when reconnecting.
50
- */
51
- id?: string
52
-
53
- /**
54
- * The data received for this message
55
- */
56
- data: string
57
- }
58
-
59
- /**
60
- * An event emitted from the parser when the server sends a value in the `retry` field,
61
- * indicating how many seconds the client should wait before attempting to reconnect.
62
- *
63
- * @public
64
- */
65
- export interface ReconnectInterval {
66
- /**
67
- * Differentiates the type from `event` and other types of messages
68
- */
69
- type: 'reconnect-interval'
70
-
71
- /**
72
- * Number of seconds to wait before reconnecting. Note that the parser does not care about
73
- * this value at all - it only emits the value for clients to use.
74
- */
75
- value: number
76
- }
77
-
78
- /**
79
- * The different types of messages the parsed can emit to the `onParse` callback
80
- *
81
- * @public
82
- */
83
- export type ParseEvent = ParsedEvent | ReconnectInterval
84
-
85
- /**
86
- * Callback passed as the `onParse` callback to a parser
87
- *
88
- * @public
89
- */
90
- export type EventSourceParseCallback = (event: ParseEvent) => void
package/src/index.ts DELETED
@@ -1,165 +0,0 @@
1
- /* eslint-disable eqeqeq */
2
- import type { IFetchOptions, SDKRequestInterface } from '@cloudbase/adapter-interface'
3
- import type { ICloudbase, ICloudbaseConfig } from '@cloudbase/types'
4
- import type { ICloudbaseComponent } from '@cloudbase/types/component'
5
- import { AI } from './AI'
6
- import { Bot } from './bot'
7
- import * as models from './models'
8
- import * as utils from './utils'
9
-
10
- const COMPONENT_NAME = 'ai'
11
-
12
- const { MODELS, ...restModels } = models
13
-
14
- interface IHandleRequestInstance {
15
- req: SDKRequestInterface
16
- }
17
-
18
- type HandleRequestInstanceFunc = (options: IHandleRequestInstance) => SDKRequestInterface
19
-
20
- const createRequestInstanceWithAccessTokenHeader = ({
21
- getAccessToken,
22
- req,
23
- }: IHandleRequestInstance & { getAccessToken: () => Promise<{ accessToken: string }> }) => {
24
- const fetch: typeof req.fetch = async (options: IFetchOptions & { token?: string }) => {
25
- if (typeof req.fetch !== 'function') {
26
- throw new Error('req.fetch is not a function')
27
- }
28
-
29
- const { token, headers = {}, ...restOptions } = options
30
- let accessToken: string
31
- if (token != null) {
32
- accessToken = token
33
- } else {
34
- accessToken = (await getAccessToken()).accessToken
35
- }
36
-
37
- return req.fetch({
38
- headers: {
39
- Authorization: `Bearer ${accessToken}`,
40
- ...headers,
41
- },
42
- ...restOptions,
43
- })
44
- }
45
-
46
- return {
47
- download: req.download,
48
- post: req.post,
49
- upload: req.upload,
50
- fetch,
51
- }
52
- }
53
-
54
- interface AIInitOption {
55
- baseUrl?: string
56
- }
57
-
58
- interface ICreateAI {
59
- req: SDKRequestInterface
60
- baseUrl?: string
61
- /** 动态获取 baseUrl 的函数,若提供则优先使用,支持端点变更后请求自动跟随 */
62
- getBaseUrl?: () => string
63
- env?: string
64
- getAccessToken?: () => Promise<{ accessToken: string }>
65
- handleReqInstance?: HandleRequestInstanceFunc
66
- i18n?: ICloudbaseConfig['i18n']
67
- }
68
-
69
- /**
70
- * 最简地创建一个接云开发网关服务的 `AI` 实例,请求时会自动带上鉴权请求头。
71
- * 只需要传入:
72
- *
73
- * - `getAccessToken`: 获取 accessToken 的函数
74
- * - `req`: 请求函数,一般从 adapter 上拿
75
- * - `env`: 云开发环境 ID
76
- *
77
- * 其他参数可按需传入覆盖函数逻辑。
78
- */
79
- function createAI({ env, baseUrl, getBaseUrl: getBaseUrlFunc, req, getAccessToken, handleReqInstance, i18n }: ICreateAI) {
80
- const getBaseUrl = () => {
81
- if (getBaseUrlFunc != null) {
82
- return getBaseUrlFunc()
83
- }
84
- if (baseUrl != null) {
85
- return baseUrl
86
- }
87
- if (env == null) {
88
- throw new Error('`env` is required when `baseUrl` is not provided!')
89
- }
90
- return `https://${env}.api.tcloudbasegateway.com/v1`
91
- }
92
-
93
- const getReq = () => {
94
- if (handleReqInstance == null) {
95
- if (getAccessToken == null) {
96
- throw new Error('`getAccessToken` is required when `handleReqInstance` is not provided!')
97
- }
98
- return createRequestInstanceWithAccessTokenHeader({ req, getAccessToken })
99
- }
100
- return handleReqInstance({ req })
101
- }
102
-
103
- return new AI(getReq(), getBaseUrl(), i18n, getBaseUrlFunc)
104
- }
105
-
106
- // 兼容
107
- /**
108
- * @deprecated use `createAI`
109
- */
110
- const createAi = createAI
111
-
112
- /**
113
- * 创建 `AI` 实例。
114
- * 该函数挂载在 js sdk 的 Cloudbase 实例上。
115
- * 该函数调用了本模块暴露的 `createAI` 函数,但调用时通过传入参数做了逻辑覆盖:
116
- *
117
- * - 传入从 Cloudbase 实例上的中心的 `req`
118
- * - 传入从 Cloudbase 实例上拿到的 `baseUrl`
119
- * - 传入一个不处理 `req` 的 `handleReqInstance`,由于 `req` 是从 Cloudbase 实例上拿到的,这个中心的 `req` 已经可用了
120
- * - 不用传入 `env` 了,因为已经传了 `baseUrl`
121
- * - 不用传入 `getAccessToken` 了,因为传了 `handleReqInstance`
122
- */
123
- function ai(
124
- this: ICloudbase & { getEndPointWithKey: (key: 'GATEWAY') => { BASE_URL: string; PROTOCOL: string } },
125
- options?: AIInitOption,
126
- ) {
127
- const req = this.request
128
-
129
- if (req.fetch == null) {
130
- throw new Error('cloudbase.request.fetch() unimplemented!')
131
- }
132
-
133
- const getUrlFromCloud = () => {
134
- const { BASE_URL, PROTOCOL } = this.getEndPointWithKey('GATEWAY')
135
- return `${PROTOCOL}${BASE_URL}`
136
- }
137
-
138
- // 若用户传了静态 baseUrl 则使用静态值,否则传入动态获取函数支持端点变更后生效
139
- if (options?.baseUrl) {
140
- return createAI({ req, baseUrl: options.baseUrl, handleReqInstance: ({ req }) => req, i18n: this.config.i18n })
141
- }
142
-
143
- return createAI({ req, baseUrl: getUrlFromCloud(), getBaseUrl: getUrlFromCloud, handleReqInstance: ({ req }) => req, i18n: this.config.i18n })
144
- }
145
-
146
- const component: ICloudbaseComponent = {
147
- name: COMPONENT_NAME,
148
- entity: { ai },
149
- }
150
-
151
- function registerAi(app: ICloudbase) {
152
- try {
153
- app.registerComponent(component)
154
- } catch (e) {
155
- console.warn(e)
156
- }
157
- }
158
-
159
- export { AI, Bot, createAi, createAI, restModels as models, registerAi, utils }
160
- export * from './type'
161
- export * from './errors'
162
-
163
- try {
164
- (window as any).registerAi = registerAi
165
- } catch (e) {}
@@ -1,94 +0,0 @@
1
- /* eslint-disable eqeqeq */
2
- /* eslint-disable @typescript-eslint/naming-convention */
3
- import {
4
- createAsyncIterable,
5
- TransformStream,
6
- toPolyfillReadable,
7
- intoStandardStream,
8
- isToolCallAssistantMessage,
9
- } from '../../utils'
10
- import type { ArkGenerateTextOutput, ArkInputData, ArkStreamTextOutput } from './type'
11
- import type {
12
- ModelReq,
13
- BaseChatModelInput,
14
- SimpleChatModel,
15
- DoGenerateOutput,
16
- DoStreamOutput,
17
- BaseDoStreamOutputChunk,
18
- ReqOptions,
19
- } from '../../type'
20
-
21
- function processInput(input: BaseChatModelInput): ArkInputData {
22
- const { messages, model, temperature, tools, top_p } = input
23
-
24
- return {
25
- ...input,
26
- messages,
27
- model,
28
- tools,
29
- top_p,
30
- temperature,
31
- }
32
- }
33
-
34
- export class ArkSimpleModel implements SimpleChatModel {
35
- public subUrl = 'ark/api/v3/chat/completions'
36
- constructor(private req: ModelReq, public baseUrl: string, subUrl?: string) {
37
- if (subUrl != null) {
38
- this.subUrl = subUrl
39
- }
40
- }
41
-
42
- private get url() {
43
- return `${this.baseUrl}/${this.subUrl}`
44
- }
45
-
46
- public async doGenerate(data: BaseChatModelInput, options?: ReqOptions): Promise<DoGenerateOutput> {
47
- const res = (await this.req({
48
- url: this.url,
49
- data: {
50
- ...processInput(data),
51
- stream: false,
52
- },
53
- stream: false,
54
- timeout: options?.timeout,
55
- })) as ArkGenerateTextOutput
56
- return { ...res, rawResponse: res }
57
- }
58
-
59
- public async doStream(data: BaseChatModelInput, options?: ReqOptions): Promise<DoStreamOutput> {
60
- let isToolCall: null | boolean = null
61
- const _stream = await this.req({
62
- url: this.url,
63
- data: {
64
- ...processInput(data),
65
- stream: true,
66
- },
67
- stream: true,
68
- timeout: options?.timeout,
69
- })
70
- const stream = toPolyfillReadable(_stream) as typeof _stream
71
-
72
- const arkStream = intoStandardStream<ArkStreamTextOutput>(stream)
73
- const streamWithRaw = arkStream.pipeThrough(new TransformStream<ArkStreamTextOutput, BaseDoStreamOutputChunk & { rawResponse?: any }>({
74
- transform(chunk, controller) {
75
- const newChoices = chunk.choices.map((choice) => {
76
- const message = choice.delta
77
- if (isToolCall == null) isToolCall = isToolCallAssistantMessage(message)
78
- if (isToolCall) {
79
- return {
80
- ...choice,
81
- finish_reason: 'tool_calls' as const,
82
- delta: message,
83
- }
84
- }
85
- return choice
86
- })
87
- const newChunk = { ...chunk, choices: newChoices }
88
- controller.enqueue({ ...newChunk, rawResponse: chunk })
89
- },
90
- }),)
91
-
92
- return createAsyncIterable(streamWithRaw)
93
- }
94
- }
@@ -1,82 +0,0 @@
1
- type UserMessage = {
2
- role: 'user'
3
- content: string
4
- }
5
-
6
- type SystemMessage = {
7
- role: 'system'
8
- content: string
9
- }
10
-
11
- type ToolMessage = {
12
- role: 'tool'
13
- content: string
14
- tool_call_id: string
15
- }
16
-
17
- type AssistantMessage =
18
- | {
19
- role: 'assistant'
20
- content: string
21
- }
22
- | {
23
- role: 'assistant'
24
- tool_calls: Array<ToolCall>
25
- content?: string
26
- }
27
-
28
- type ToolCall = {
29
- id: string
30
- type: string
31
- function: {
32
- name: string
33
- arguments: string
34
- }
35
- }
36
-
37
- type ArkMessage = UserMessage | SystemMessage | AssistantMessage | ToolMessage
38
-
39
- export type ArkInputData = {
40
- model: string
41
- messages: Array<ArkMessage>
42
- max_tokens?: number
43
- stop?: string | Array<string>
44
- frequency_penalty?: number
45
- temperature?: number
46
- top_p?: number
47
- tools?: Array<Tool>
48
- }
49
-
50
- type Tool = {
51
- type: string
52
- function: {
53
- name: string
54
- description?: string
55
- parameters?: object
56
- }
57
- }
58
-
59
- export type ArkGenerateTextOutput = {
60
- choices?: Array<{
61
- finish_reason: string
62
- message?: AssistantMessage
63
- }>
64
- usage?: {
65
- prompt_tokens: number
66
- completion_tokens: number
67
- total_tokens: number
68
- }
69
- }
70
-
71
- // todo: more precise
72
- export type ArkStreamTextOutput = {
73
- choices?: Array<{
74
- finish_reason: string
75
- delta: AssistantMessage
76
- }>
77
- usage?: {
78
- prompt_tokens: number
79
- completion_tokens: number
80
- total_tokens: number
81
- }
82
- }