@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.
- package/dist/miniprogram/index.js +1 -1
- package/dist/miniprogram/index.js.LICENSE.txt +2 -2
- package/package.json +8 -4
- package/.eslintignore +0 -2
- package/.eslintrc.js +0 -16
- package/src/AI.ts +0 -191
- package/src/bot/index.ts +0 -278
- package/src/bot/types.ts +0 -165
- package/src/errors.ts +0 -23
- package/src/eventsource_parser/index.ts +0 -2
- package/src/eventsource_parser/parse.ts +0 -169
- package/src/eventsource_parser/stream.ts +0 -35
- package/src/eventsource_parser/types.ts +0 -90
- package/src/index.ts +0 -165
- package/src/models/Ark/index.ts +0 -94
- package/src/models/Ark/type.ts +0 -82
- package/src/models/DashScope/index.ts +0 -97
- package/src/models/DashScope/type.ts +0 -76
- package/src/models/DeepSeek/index.ts +0 -80
- package/src/models/Default/index.ts +0 -70
- package/src/models/HunYuan/index.ts +0 -94
- package/src/models/HunYuan/type.ts +0 -85
- package/src/models/HunYuan/util.ts +0 -60
- package/src/models/HunYuanBeta/index.ts +0 -83
- package/src/models/HunYuanExp/index.ts +0 -80
- package/src/models/HunYuanOpen/index.ts +0 -83
- package/src/models/Moonshot/index.ts +0 -95
- package/src/models/Moonshot/type.ts +0 -82
- package/src/models/Yi/index.ts +0 -100
- package/src/models/Yi/type.ts +0 -77
- package/src/models/ZhiPu/index.ts +0 -104
- package/src/models/ZhiPu/type.ts +0 -71
- package/src/models/image-model.ts +0 -100
- package/src/models/index.ts +0 -41
- package/src/models/model.ts +0 -425
- package/src/type.ts +0 -362
- package/src/utils.ts +0 -198
- package/tsconfig.esm.json +0 -16
- package/tsconfig.json +0 -16
- package/webpack/web.prod.js +0 -100
- 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,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) {}
|
package/src/models/Ark/index.ts
DELETED
|
@@ -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
|
-
}
|
package/src/models/Ark/type.ts
DELETED
|
@@ -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
|
-
}
|