@planet-matrix/mobius-model 0.5.0 → 0.9.0
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/CHANGELOG.md +61 -0
- package/README.md +123 -36
- package/dist/index.js +715 -4
- package/dist/index.js.map +981 -13
- package/oxlint.config.ts +6 -0
- package/package.json +36 -18
- package/src/abort/README.md +92 -0
- package/src/abort/abort-manager.ts +278 -0
- package/src/abort/abort-signal-listener-manager.ts +81 -0
- package/src/abort/index.ts +2 -0
- package/src/ai/README.md +1 -0
- package/src/ai/ai.ts +107 -0
- package/src/ai/chat-completion-ai/aihubmix-chat-completion.ts +78 -0
- package/src/ai/chat-completion-ai/chat-completion-ai.ts +270 -0
- package/src/ai/chat-completion-ai/chat-completion.ts +189 -0
- package/src/ai/chat-completion-ai/index.ts +7 -0
- package/src/ai/chat-completion-ai/lingyiwanwu-chat-completion.ts +78 -0
- package/src/ai/chat-completion-ai/ohmygpt-chat-completion.ts +78 -0
- package/src/ai/chat-completion-ai/openai-next-chat-completion.ts +78 -0
- package/src/ai/embedding-ai/embedding-ai.ts +63 -0
- package/src/ai/embedding-ai/embedding.ts +50 -0
- package/src/ai/embedding-ai/index.ts +4 -0
- package/src/ai/embedding-ai/openai-next-embedding.ts +23 -0
- package/src/ai/index.ts +4 -0
- package/src/aio/README.md +100 -0
- package/src/aio/content.ts +141 -0
- package/src/aio/index.ts +3 -0
- package/src/aio/json.ts +127 -0
- package/src/aio/prompt.ts +246 -0
- package/src/basic/README.md +72 -116
- package/src/basic/error.ts +19 -5
- package/src/basic/function.ts +83 -64
- package/src/basic/index.ts +1 -0
- package/src/basic/is.ts +152 -71
- package/src/basic/promise.ts +29 -8
- package/src/basic/schedule.ts +111 -0
- package/src/basic/stream.ts +135 -25
- package/src/basic/string.ts +2 -33
- package/src/color/README.md +105 -0
- package/src/color/index.ts +3 -0
- package/src/color/internal.ts +42 -0
- package/src/color/rgb/analyze.ts +236 -0
- package/src/color/rgb/construct.ts +130 -0
- package/src/color/rgb/convert.ts +227 -0
- package/src/color/rgb/derive.ts +303 -0
- package/src/color/rgb/index.ts +6 -0
- package/src/color/rgb/internal.ts +208 -0
- package/src/color/rgb/parse.ts +302 -0
- package/src/color/rgb/serialize.ts +144 -0
- package/src/color/types.ts +57 -0
- package/src/color/xyz/analyze.ts +80 -0
- package/src/color/xyz/construct.ts +19 -0
- package/src/color/xyz/convert.ts +71 -0
- package/src/color/xyz/index.ts +3 -0
- package/src/color/xyz/internal.ts +23 -0
- package/src/credential/README.md +107 -0
- package/src/credential/api-key.ts +158 -0
- package/src/credential/bearer.ts +73 -0
- package/src/credential/index.ts +4 -0
- package/src/credential/json-web-token.ts +96 -0
- package/src/credential/password.ts +170 -0
- package/src/cron/README.md +86 -0
- package/src/cron/cron.ts +87 -0
- package/src/cron/index.ts +1 -0
- package/src/css/README.md +93 -0
- package/src/css/class.ts +559 -0
- package/src/css/index.ts +1 -0
- package/src/drizzle/README.md +1 -0
- package/src/drizzle/drizzle.ts +1 -0
- package/src/drizzle/helper.ts +47 -0
- package/src/drizzle/index.ts +5 -0
- package/src/drizzle/infer.ts +52 -0
- package/src/drizzle/kysely.ts +8 -0
- package/src/drizzle/pagination.ts +200 -0
- package/src/email/README.md +1 -0
- package/src/email/index.ts +1 -0
- package/src/email/resend.ts +25 -0
- package/src/encoding/README.md +66 -79
- package/src/encoding/base64.ts +13 -4
- package/src/environment/README.md +97 -0
- package/src/environment/basic.ts +26 -0
- package/src/environment/device.ts +311 -0
- package/src/environment/feature.ts +285 -0
- package/src/environment/geo.ts +337 -0
- package/src/environment/index.ts +7 -0
- package/src/environment/runtime.ts +400 -0
- package/src/environment/snapshot.ts +60 -0
- package/src/environment/variable.ts +239 -0
- package/src/event/README.md +90 -0
- package/src/event/class-event-proxy.ts +229 -0
- package/src/event/common.ts +29 -0
- package/src/event/event-manager.ts +203 -0
- package/src/event/index.ts +4 -0
- package/src/event/instance-event-proxy.ts +187 -0
- package/src/event/internal.ts +24 -0
- package/src/exception/README.md +96 -0
- package/src/exception/browser.ts +219 -0
- package/src/exception/index.ts +4 -0
- package/src/exception/nodejs.ts +169 -0
- package/src/exception/normalize.ts +106 -0
- package/src/exception/types.ts +99 -0
- package/src/form/README.md +25 -0
- package/src/form/index.ts +1 -0
- package/src/form/inputor-controller/base.ts +874 -0
- package/src/form/inputor-controller/boolean.ts +39 -0
- package/src/form/inputor-controller/file.ts +39 -0
- package/src/form/inputor-controller/form.ts +181 -0
- package/src/form/inputor-controller/helper.ts +117 -0
- package/src/form/inputor-controller/index.ts +17 -0
- package/src/form/inputor-controller/multi-select.ts +99 -0
- package/src/form/inputor-controller/number.ts +116 -0
- package/src/form/inputor-controller/select.ts +109 -0
- package/src/form/inputor-controller/text.ts +82 -0
- package/src/http/READMD.md +1 -0
- package/src/http/api/api-core.ts +84 -0
- package/src/http/api/api-handler.ts +79 -0
- package/src/http/api/api-host.ts +47 -0
- package/src/http/api/api-result.ts +56 -0
- package/src/http/api/api-schema.ts +154 -0
- package/src/http/api/api-server.ts +130 -0
- package/src/http/api/api-test.ts +142 -0
- package/src/http/api/api-type.ts +37 -0
- package/src/http/api/api.ts +81 -0
- package/src/http/api/index.ts +11 -0
- package/src/http/api-adapter/api-core-node-http.ts +260 -0
- package/src/http/api-adapter/api-host-node-http.ts +156 -0
- package/src/http/api-adapter/api-result-arktype.ts +297 -0
- package/src/http/api-adapter/api-result-zod.ts +286 -0
- package/src/http/api-adapter/index.ts +5 -0
- package/src/http/bin/gen-api-list/gen-api-list.ts +126 -0
- package/src/http/bin/gen-api-list/index.ts +1 -0
- package/src/http/bin/gen-api-test/gen-api-test.ts +136 -0
- package/src/http/bin/gen-api-test/index.ts +1 -0
- package/src/http/bin/gen-api-type/calc-code.ts +25 -0
- package/src/http/bin/gen-api-type/gen-api-type.ts +127 -0
- package/src/http/bin/gen-api-type/index.ts +2 -0
- package/src/http/bin/index.ts +2 -0
- package/src/http/index.ts +3 -0
- package/src/huawei/README.md +1 -0
- package/src/huawei/index.ts +2 -0
- package/src/huawei/moderation/index.ts +1 -0
- package/src/huawei/moderation/moderation.ts +355 -0
- package/src/huawei/obs/esdk-obs-nodejs.d.ts +87 -0
- package/src/huawei/obs/index.ts +1 -0
- package/src/huawei/obs/obs.ts +42 -0
- package/src/identifier/README.md +92 -0
- package/src/identifier/id.ts +119 -0
- package/src/identifier/index.ts +2 -0
- package/src/identifier/uuid.ts +187 -0
- package/src/index.ts +33 -1
- package/src/json/README.md +92 -0
- package/src/json/index.ts +1 -0
- package/src/json/repair.ts +18 -0
- package/src/log/README.md +79 -0
- package/src/log/index.ts +5 -0
- package/src/log/log-emitter.ts +72 -0
- package/src/log/log-record.ts +10 -0
- package/src/log/log-scheduler.ts +74 -0
- package/src/log/log-type.ts +8 -0
- package/src/log/logger.ts +554 -0
- package/src/openai/README.md +1 -0
- package/src/openai/index.ts +1 -0
- package/src/openai/openai.ts +510 -0
- package/src/orchestration/README.md +91 -0
- package/src/orchestration/coordination/barrier.ts +214 -0
- package/src/orchestration/coordination/count-down-latch.ts +215 -0
- package/src/orchestration/coordination/errors.ts +98 -0
- package/src/orchestration/coordination/index.ts +16 -0
- package/src/orchestration/coordination/internal/wait-constraints.ts +95 -0
- package/src/orchestration/coordination/internal/wait-queue.ts +109 -0
- package/src/orchestration/coordination/keyed-lock.ts +168 -0
- package/src/orchestration/coordination/mutex.ts +257 -0
- package/src/orchestration/coordination/permit.ts +127 -0
- package/src/orchestration/coordination/read-write-lock.ts +444 -0
- package/src/orchestration/coordination/semaphore.ts +280 -0
- package/src/orchestration/dispatching/dispatcher.ts +83 -0
- package/src/orchestration/dispatching/index.ts +2 -0
- package/src/orchestration/dispatching/selector/base-selector.ts +39 -0
- package/src/orchestration/dispatching/selector/down-count-selector.ts +119 -0
- package/src/orchestration/dispatching/selector/index.ts +2 -0
- package/src/orchestration/index.ts +3 -0
- package/src/orchestration/scheduling/index.ts +2 -0
- package/src/orchestration/scheduling/scheduler.ts +103 -0
- package/src/orchestration/scheduling/task.ts +32 -0
- package/src/random/README.md +56 -86
- package/src/random/base.ts +66 -0
- package/src/random/index.ts +5 -1
- package/src/random/random-boolean.ts +40 -0
- package/src/random/random-integer.ts +60 -0
- package/src/random/random-number.ts +72 -0
- package/src/random/random-string.ts +66 -0
- package/src/reactor/README.md +4 -0
- package/src/reactor/reactor-core/primitive.ts +9 -9
- package/src/reactor/reactor-core/reactive-system.ts +5 -5
- package/src/request/README.md +108 -0
- package/src/request/fetch/base.ts +108 -0
- package/src/request/fetch/browser.ts +285 -0
- package/src/request/fetch/general.ts +20 -0
- package/src/request/fetch/index.ts +4 -0
- package/src/request/fetch/nodejs.ts +285 -0
- package/src/request/index.ts +2 -0
- package/src/request/request/base.ts +250 -0
- package/src/request/request/general.ts +64 -0
- package/src/request/request/index.ts +3 -0
- package/src/request/request/resource.ts +68 -0
- package/src/result/README.md +4 -0
- package/src/result/controller.ts +54 -0
- package/src/result/either.ts +193 -0
- package/src/result/index.ts +2 -0
- package/src/route/README.md +105 -0
- package/src/route/adapter/browser.ts +122 -0
- package/src/route/adapter/driver.ts +56 -0
- package/src/route/adapter/index.ts +2 -0
- package/src/route/index.ts +3 -0
- package/src/route/router/index.ts +2 -0
- package/src/route/router/route.ts +630 -0
- package/src/route/router/router.ts +1642 -0
- package/src/route/uri/hash.ts +308 -0
- package/src/route/uri/index.ts +7 -0
- package/src/route/uri/pathname.ts +376 -0
- package/src/route/uri/search.ts +413 -0
- package/src/singleton/README.md +79 -0
- package/src/singleton/factory.ts +55 -0
- package/src/singleton/index.ts +2 -0
- package/src/singleton/manager.ts +204 -0
- package/src/socket/README.md +105 -0
- package/src/socket/client/index.ts +2 -0
- package/src/socket/client/socket-unit.ts +660 -0
- package/src/socket/client/socket.ts +203 -0
- package/src/socket/common/index.ts +2 -0
- package/src/socket/common/socket-unit-common.ts +23 -0
- package/src/socket/common/socket-unit-heartbeat.ts +427 -0
- package/src/socket/index.ts +3 -0
- package/src/socket/server/index.ts +3 -0
- package/src/socket/server/server.ts +183 -0
- package/src/socket/server/socket-unit.ts +449 -0
- package/src/socket/server/socket.ts +264 -0
- package/src/storage/README.md +107 -0
- package/src/storage/index.ts +1 -0
- package/src/storage/table.ts +449 -0
- package/src/timer/README.md +86 -0
- package/src/timer/expiration/expiration-manager.ts +594 -0
- package/src/timer/expiration/index.ts +3 -0
- package/src/timer/expiration/min-heap.ts +208 -0
- package/src/timer/expiration/remaining-manager.ts +241 -0
- package/src/timer/index.ts +1 -0
- package/src/tube/README.md +99 -0
- package/src/tube/helper.ts +138 -0
- package/src/tube/index.ts +2 -0
- package/src/tube/tube.ts +880 -0
- package/src/type/README.md +54 -307
- package/src/type/class.ts +2 -2
- package/src/type/index.ts +14 -14
- package/src/type/is.ts +265 -2
- package/src/type/object.ts +37 -0
- package/src/type/string.ts +7 -2
- package/src/type/tuple.ts +6 -6
- package/src/type/union.ts +16 -0
- package/src/web/README.md +77 -0
- package/src/web/capture.ts +35 -0
- package/src/web/clipboard.ts +97 -0
- package/src/web/dom.ts +117 -0
- package/src/web/download.ts +16 -0
- package/src/web/event.ts +46 -0
- package/src/web/index.ts +10 -0
- package/src/web/local-storage.ts +113 -0
- package/src/web/location.ts +28 -0
- package/src/web/permission.ts +172 -0
- package/src/web/script-loader.ts +432 -0
- package/src/weixin/README.md +1 -0
- package/src/weixin/index.ts +2 -0
- package/src/weixin/official-account/authorization.ts +159 -0
- package/src/weixin/official-account/index.ts +2 -0
- package/src/weixin/official-account/js-api.ts +134 -0
- package/src/weixin/open/index.ts +1 -0
- package/src/weixin/open/oauth2.ts +133 -0
- package/tests/unit/abort/abort-manager.spec.ts +225 -0
- package/tests/unit/abort/abort-signal-listener-manager.spec.ts +62 -0
- package/tests/unit/ai/ai.spec.ts +85 -0
- package/tests/unit/aio/content.spec.ts +105 -0
- package/tests/unit/aio/json.spec.ts +147 -0
- package/tests/unit/aio/prompt.spec.ts +111 -0
- package/tests/unit/basic/array.spec.ts +1 -1
- package/tests/unit/basic/error.spec.ts +16 -4
- package/tests/unit/basic/schedule.spec.ts +74 -0
- package/tests/unit/basic/stream.spec.ts +91 -38
- package/tests/unit/basic/string.spec.ts +0 -9
- package/tests/unit/color/rgb/analyze.spec.ts +110 -0
- package/tests/unit/color/rgb/construct.spec.ts +56 -0
- package/tests/unit/color/rgb/convert.spec.ts +60 -0
- package/tests/unit/color/rgb/derive.spec.ts +103 -0
- package/tests/unit/color/rgb/parse.spec.ts +66 -0
- package/tests/unit/color/rgb/serialize.spec.ts +46 -0
- package/tests/unit/color/xyz/analyze.spec.ts +33 -0
- package/tests/unit/color/xyz/construct.spec.ts +10 -0
- package/tests/unit/color/xyz/convert.spec.ts +18 -0
- package/tests/unit/credential/api-key.spec.ts +37 -0
- package/tests/unit/credential/bearer.spec.ts +23 -0
- package/tests/unit/credential/json-web-token.spec.ts +23 -0
- package/tests/unit/credential/password.spec.ts +41 -0
- package/tests/unit/cron/cron.spec.ts +84 -0
- package/tests/unit/css/class.spec.ts +157 -0
- package/tests/unit/environment/basic.spec.ts +20 -0
- package/tests/unit/environment/device.spec.ts +146 -0
- package/tests/unit/environment/feature.spec.ts +388 -0
- package/tests/unit/environment/geo.spec.ts +111 -0
- package/tests/unit/environment/runtime.spec.ts +364 -0
- package/tests/unit/environment/snapshot.spec.ts +4 -0
- package/tests/unit/environment/variable.spec.ts +190 -0
- package/tests/unit/event/class-event-proxy.spec.ts +225 -0
- package/tests/unit/event/event-manager.spec.ts +246 -0
- package/tests/unit/event/instance-event-proxy.spec.ts +187 -0
- package/tests/unit/exception/browser.spec.ts +213 -0
- package/tests/unit/exception/nodejs.spec.ts +144 -0
- package/tests/unit/exception/normalize.spec.ts +57 -0
- package/tests/unit/form/inputor-controller/base.spec.ts +458 -0
- package/tests/unit/form/inputor-controller/boolean.spec.ts +30 -0
- package/tests/unit/form/inputor-controller/file.spec.ts +27 -0
- package/tests/unit/form/inputor-controller/form.spec.ts +120 -0
- package/tests/unit/form/inputor-controller/helper.spec.ts +67 -0
- package/tests/unit/form/inputor-controller/multi-select.spec.ts +34 -0
- package/tests/unit/form/inputor-controller/number.spec.ts +36 -0
- package/tests/unit/form/inputor-controller/select.spec.ts +49 -0
- package/tests/unit/form/inputor-controller/text.spec.ts +34 -0
- package/tests/unit/http/api/api-core-host.spec.ts +207 -0
- package/tests/unit/http/api/api-schema.spec.ts +120 -0
- package/tests/unit/http/api/api-server.spec.ts +363 -0
- package/tests/unit/http/api/api-test.spec.ts +117 -0
- package/tests/unit/http/api/api.spec.ts +121 -0
- package/tests/unit/http/api-adapter/node-http.spec.ts +191 -0
- package/tests/unit/identifier/id.spec.ts +71 -0
- package/tests/unit/identifier/uuid.spec.ts +85 -0
- package/tests/unit/json/repair.spec.ts +11 -0
- package/tests/unit/log/log-emitter.spec.ts +33 -0
- package/tests/unit/log/log-scheduler.spec.ts +40 -0
- package/tests/unit/log/log-type.spec.ts +7 -0
- package/tests/unit/log/logger.spec.ts +237 -0
- package/tests/unit/openai/openai.spec.ts +64 -0
- package/tests/unit/orchestration/coordination/barrier.spec.ts +96 -0
- package/tests/unit/orchestration/coordination/count-down-latch.spec.ts +63 -0
- package/tests/unit/orchestration/coordination/errors.spec.ts +29 -0
- package/tests/unit/orchestration/coordination/keyed-lock.spec.ts +109 -0
- package/tests/unit/orchestration/coordination/mutex.spec.ts +132 -0
- package/tests/unit/orchestration/coordination/permit.spec.ts +43 -0
- package/tests/unit/orchestration/coordination/read-write-lock.spec.ts +154 -0
- package/tests/unit/orchestration/coordination/semaphore.spec.ts +135 -0
- package/tests/unit/orchestration/dispatching/dispatcher.spec.ts +41 -0
- package/tests/unit/orchestration/dispatching/selector/down-count-selector.spec.ts +81 -0
- package/tests/unit/orchestration/scheduling/scheduler.spec.ts +103 -0
- package/tests/unit/random/base.spec.ts +58 -0
- package/tests/unit/random/random-boolean.spec.ts +25 -0
- package/tests/unit/random/random-integer.spec.ts +32 -0
- package/tests/unit/random/random-number.spec.ts +33 -0
- package/tests/unit/random/random-string.spec.ts +22 -0
- package/tests/unit/reactor/alien-signals-effect.spec.ts +11 -10
- package/tests/unit/reactor/preact-signal.spec.ts +1 -2
- package/tests/unit/request/fetch/browser.spec.ts +222 -0
- package/tests/unit/request/fetch/general.spec.ts +43 -0
- package/tests/unit/request/fetch/nodejs.spec.ts +225 -0
- package/tests/unit/request/request/base.spec.ts +385 -0
- package/tests/unit/request/request/general.spec.ts +161 -0
- package/tests/unit/route/router/route.spec.ts +431 -0
- package/tests/unit/route/router/router.spec.ts +407 -0
- package/tests/unit/route/uri/hash.spec.ts +72 -0
- package/tests/unit/route/uri/pathname.spec.ts +147 -0
- package/tests/unit/route/uri/search.spec.ts +107 -0
- package/tests/unit/singleton/singleton.spec.ts +49 -0
- package/tests/unit/socket/client.spec.ts +208 -0
- package/tests/unit/socket/server.spec.ts +135 -0
- package/tests/unit/socket/socket-unit-heartbeat.spec.ts +214 -0
- package/tests/unit/storage/table.spec.ts +620 -0
- package/tests/unit/timer/expiration/expiration-manager.spec.ts +464 -0
- package/tests/unit/timer/expiration/min-heap.spec.ts +71 -0
- package/tests/unit/timer/expiration/remaining-manager.spec.ts +234 -0
- package/tests/unit/tube/helper.spec.ts +139 -0
- package/tests/unit/tube/tube.spec.ts +501 -0
- package/.oxlintrc.json +0 -5
- package/src/random/uuid.ts +0 -103
- package/tests/unit/random/uuid.spec.ts +0 -37
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type * as Openai from "#Source/openai/index.ts"
|
|
2
|
+
|
|
3
|
+
import type { BaseChatCompletionOptions, ChatCompletionOptions, ChatCompletionResult } from "./chat-completion.ts"
|
|
4
|
+
import { BaseChatCompletion } from "./chat-completion.ts"
|
|
5
|
+
|
|
6
|
+
export interface AihubmixChatCompletionOptions extends BaseChatCompletionOptions {
|
|
7
|
+
openai: Openai.Openai
|
|
8
|
+
}
|
|
9
|
+
export class AihubmixChatCompletion extends BaseChatCompletion {
|
|
10
|
+
protected readonly openai: Openai.Openai
|
|
11
|
+
|
|
12
|
+
constructor(options: AihubmixChatCompletionOptions) {
|
|
13
|
+
super(options)
|
|
14
|
+
this.logger.setDefaultName("AihubmixChatCompletion")
|
|
15
|
+
|
|
16
|
+
this.openai = options.openai
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
protected transformOptions(options: ChatCompletionOptions): Openai.CustomChatCompletionOptions {
|
|
20
|
+
const transformedOptions: Openai.CustomChatCompletionOptions = {
|
|
21
|
+
messages: options.messages.map((message) => {
|
|
22
|
+
const { role, content } = message
|
|
23
|
+
if (role === "system") {
|
|
24
|
+
return message
|
|
25
|
+
}
|
|
26
|
+
if (role === "user") {
|
|
27
|
+
if (typeof content === "string") {
|
|
28
|
+
return {
|
|
29
|
+
role,
|
|
30
|
+
content,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (Array.isArray(content)) {
|
|
34
|
+
return {
|
|
35
|
+
role,
|
|
36
|
+
content: content.map((item) => {
|
|
37
|
+
if (item.type === "image_url") {
|
|
38
|
+
return {
|
|
39
|
+
type: item.type,
|
|
40
|
+
image_url: item.imageUrl,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return item
|
|
45
|
+
}
|
|
46
|
+
}),
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw new Error("Invalid content")
|
|
50
|
+
}
|
|
51
|
+
if (role === "assistant") {
|
|
52
|
+
return message
|
|
53
|
+
}
|
|
54
|
+
throw new Error("Invalid role")
|
|
55
|
+
}),
|
|
56
|
+
model: options.model,
|
|
57
|
+
...(options.frequencyPenalty !== undefined ? { frequency_penalty: options.frequencyPenalty } : {}),
|
|
58
|
+
...(options.logitBias !== undefined ? { logit_bias: options.logitBias } : {}),
|
|
59
|
+
...(options.logprobs !== undefined ? { logprobs: options.logprobs } : {}),
|
|
60
|
+
...(options.maxCompletionTokens !== undefined ? { max_completion_tokens: options.maxCompletionTokens } : {}),
|
|
61
|
+
...(options.maxTokens !== undefined ? { max_tokens: options.maxTokens } : {}),
|
|
62
|
+
...(options.presencePenalty !== undefined ? { presence_penalty: options.presencePenalty } : {}),
|
|
63
|
+
...(options.responseFormat !== undefined ? { response_format: options.responseFormat } : {}),
|
|
64
|
+
...(options.temperature !== undefined ? { temperature: options.temperature } : {}),
|
|
65
|
+
...(options.topLogprobs !== undefined ? { top_logprobs: options.topLogprobs } : {}),
|
|
66
|
+
...(options.topP !== undefined ? { top_p: options.topP } : {}),
|
|
67
|
+
timeout: options.timeoutFirstChunk ?? undefined,
|
|
68
|
+
abortSignal: options.abortSignal,
|
|
69
|
+
}
|
|
70
|
+
return transformedOptions
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async chatCompletion(options: ChatCompletionOptions): Promise<ChatCompletionResult> {
|
|
74
|
+
const transformedOptions = this.transformOptions(options)
|
|
75
|
+
const result = await this.openai.customChatCompletionStreaming(transformedOptions)
|
|
76
|
+
return result
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import type { LoggerFriendly, LoggerFriendlyOptions } from "#Source/log/index.ts"
|
|
2
|
+
import type { AbortManager } from "#Source/abort/index.ts"
|
|
3
|
+
|
|
4
|
+
import { Logger } from "#Source/log/index.ts"
|
|
5
|
+
import { Dispatcher } from "#Source/orchestration/index.ts"
|
|
6
|
+
import { fromWithAbortSignal } from "#Source/abort/index.ts"
|
|
7
|
+
import { controllerFromEitherType, eitherToTuple } from "#Source/result/index.ts"
|
|
8
|
+
import { scheduleMacroTask } from "#Source/basic/index.ts"
|
|
9
|
+
import { connectTube, Tube } from "#Source/tube/index.ts"
|
|
10
|
+
import * as Aio from "#Source/aio/index.ts"
|
|
11
|
+
|
|
12
|
+
import type { BaseChatCompletion, ChatCompletionOptions, ChatCompletionResult, Completion } from "./chat-completion.ts"
|
|
13
|
+
|
|
14
|
+
export interface ChatCompletionAiOptions extends LoggerFriendlyOptions {
|
|
15
|
+
chatCompletionInstanceList: BaseChatCompletion[]
|
|
16
|
+
/**
|
|
17
|
+
* The timeout for the first chunk of data to be received, in milliseconds.
|
|
18
|
+
*
|
|
19
|
+
* @default timeoutPerChunk | 30_000
|
|
20
|
+
*/
|
|
21
|
+
timeoutFirstChunk?: number | undefined
|
|
22
|
+
/**
|
|
23
|
+
* The timeout for each chunk of data to be received, in milliseconds.
|
|
24
|
+
*
|
|
25
|
+
* @default 30_000
|
|
26
|
+
*/
|
|
27
|
+
timeoutPerChunk?: number | undefined
|
|
28
|
+
/**
|
|
29
|
+
* The maximum number of tries for the request.
|
|
30
|
+
*
|
|
31
|
+
* @default 3
|
|
32
|
+
*/
|
|
33
|
+
maxTries?: number | undefined
|
|
34
|
+
}
|
|
35
|
+
interface ResolvedChatCompletionAiOptions {
|
|
36
|
+
chatCompletionInstanceList: BaseChatCompletion[]
|
|
37
|
+
timeoutFirstChunk: number
|
|
38
|
+
timeoutPerChunk: number
|
|
39
|
+
maxTries: number
|
|
40
|
+
}
|
|
41
|
+
export class ChatCompletionAi implements LoggerFriendly {
|
|
42
|
+
protected readonly options: ResolvedChatCompletionAiOptions
|
|
43
|
+
|
|
44
|
+
readonly logger: Logger
|
|
45
|
+
private dispatcher: Dispatcher<BaseChatCompletion>
|
|
46
|
+
|
|
47
|
+
constructor(options: ChatCompletionAiOptions) {
|
|
48
|
+
this.options = {
|
|
49
|
+
chatCompletionInstanceList: options.chatCompletionInstanceList,
|
|
50
|
+
timeoutFirstChunk: options.timeoutFirstChunk ?? options.timeoutPerChunk ?? 30_000,
|
|
51
|
+
timeoutPerChunk: options.timeoutPerChunk ?? 30_000,
|
|
52
|
+
maxTries: options.maxTries ?? 3,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.logger = Logger.fromOptions(options).setDefaultName("ChatCompletionAi")
|
|
56
|
+
|
|
57
|
+
this.dispatcher = new Dispatcher({
|
|
58
|
+
itemList: this.options.chatCompletionInstanceList,
|
|
59
|
+
logger: this.logger,
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async chatCompletion(
|
|
64
|
+
options: ChatCompletionOptions
|
|
65
|
+
): Promise<ChatCompletionResult> {
|
|
66
|
+
const controller = controllerFromEitherType<ChatCompletionResult>()
|
|
67
|
+
|
|
68
|
+
const completionTube = new Tube<Completion>({
|
|
69
|
+
historyCount: Infinity,
|
|
70
|
+
replayHistory: true
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
scheduleMacroTask({
|
|
74
|
+
task: async () => {
|
|
75
|
+
await this.request(options, completionTube)
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
return await controller.returnRight({
|
|
80
|
+
completionTube,
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private async request(
|
|
85
|
+
options: ChatCompletionOptions,
|
|
86
|
+
targetCompletionTube: Tube<Completion>,
|
|
87
|
+
): Promise<void> {
|
|
88
|
+
const { selector, destroy } = this.dispatcher.getSelector({
|
|
89
|
+
filter: (item) => {
|
|
90
|
+
return item.isSupportModel(options.model) === true
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
targetCompletionTube.subscribeEndEvent({
|
|
94
|
+
subscriber: () => {
|
|
95
|
+
destroy()
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
const latestCompletion: Completion = {
|
|
100
|
+
content: {
|
|
101
|
+
deltaList: [],
|
|
102
|
+
total: "",
|
|
103
|
+
},
|
|
104
|
+
token: {
|
|
105
|
+
deltaList: [],
|
|
106
|
+
total: 0,
|
|
107
|
+
},
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const maxTries = options.maxTries ?? this.options.maxTries
|
|
111
|
+
|
|
112
|
+
interface HandleTryErrorOptions {
|
|
113
|
+
tryIndex: number
|
|
114
|
+
abortManager: AbortManager
|
|
115
|
+
}
|
|
116
|
+
const handleTryError = async (options: HandleTryErrorOptions): Promise<void> => {
|
|
117
|
+
const { tryIndex, abortManager } = options
|
|
118
|
+
|
|
119
|
+
this.logger.log(`Handle try error, current failure count: ${tryIndex + 1}, max tries: ${maxTries}`)
|
|
120
|
+
|
|
121
|
+
if (abortManager.isAborted()) {
|
|
122
|
+
this.logger.log("Chat completion aborted by invoker.")
|
|
123
|
+
await targetCompletionTube.pushError(new Error("Chat completion aborted by invoker."))
|
|
124
|
+
abortManager.abort("Chat completion aborted by invoker.")
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
this.logger.log("Chat completion not aborted by invoker.")
|
|
129
|
+
}
|
|
130
|
+
// 清理资源
|
|
131
|
+
abortManager.abort("Failed request")
|
|
132
|
+
|
|
133
|
+
// 重置数据
|
|
134
|
+
latestCompletion.content = Aio.applyDeltaToTextContent(latestCompletion.content, {
|
|
135
|
+
type: "reset",
|
|
136
|
+
})
|
|
137
|
+
latestCompletion.token = Aio.applyDeltaToNumberContent(latestCompletion.token, {
|
|
138
|
+
type: "reset",
|
|
139
|
+
})
|
|
140
|
+
await targetCompletionTube.pushData(structuredClone(latestCompletion))
|
|
141
|
+
|
|
142
|
+
// 如果尝试次数未达到上限,则继续尝试
|
|
143
|
+
const nextTryIndex = tryIndex + 1
|
|
144
|
+
if (nextTryIndex < maxTries) {
|
|
145
|
+
this.logger.log(`Not exceed maximum tries (${maxTries}) for chat completion, try again`)
|
|
146
|
+
scheduleMacroTask({
|
|
147
|
+
task: async () => {
|
|
148
|
+
await startTry(nextTryIndex)
|
|
149
|
+
},
|
|
150
|
+
timeout: 500,
|
|
151
|
+
})
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
this.logger.log(`Exceeded maximum tries (${maxTries}) for chat completion`)
|
|
155
|
+
await targetCompletionTube.pushError(new Error("Exceeded maximum tries."))
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const startTry = async (tryIndex: number): Promise<void> => {
|
|
159
|
+
this.logger.log(`Start try, tries ${tryIndex + 1} of ${maxTries}`)
|
|
160
|
+
|
|
161
|
+
const abortManager = fromWithAbortSignal(options)
|
|
162
|
+
const [getItemLeft, getItemRight] = eitherToTuple(await selector.getItem())
|
|
163
|
+
if (getItemLeft !== undefined) {
|
|
164
|
+
await handleTryError({ tryIndex, abortManager })
|
|
165
|
+
return
|
|
166
|
+
}
|
|
167
|
+
const { item, markUnavailable } = getItemRight
|
|
168
|
+
this.logger.log(`${item.logger.getName()} is selected from pool`)
|
|
169
|
+
const [leftResult, rightResult] = eitherToTuple(await this.requestAndConstrainSpeed(
|
|
170
|
+
{
|
|
171
|
+
...options,
|
|
172
|
+
abortSignal: abortManager.abortSignal,
|
|
173
|
+
},
|
|
174
|
+
item,
|
|
175
|
+
))
|
|
176
|
+
if (leftResult !== undefined) {
|
|
177
|
+
await handleTryError({ tryIndex, abortManager })
|
|
178
|
+
return
|
|
179
|
+
}
|
|
180
|
+
const { completionTube: sourceCompletionTube } = rightResult
|
|
181
|
+
sourceCompletionTube.subscribeEndEvent({
|
|
182
|
+
subscriber: async (): Promise<void> => {
|
|
183
|
+
if (sourceCompletionTube.isError()) {
|
|
184
|
+
this.logger.log("Source completion tube ended with error")
|
|
185
|
+
markUnavailable()
|
|
186
|
+
await handleTryError({ tryIndex, abortManager })
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
this.logger.log("Source completion tube ended normally")
|
|
190
|
+
await targetCompletionTube.end()
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
})
|
|
194
|
+
sourceCompletionTube.subscribeData({
|
|
195
|
+
subscriber: async (data: Completion): Promise<void> => {
|
|
196
|
+
await targetCompletionTube.pushData(data)
|
|
197
|
+
},
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
await startTry(0)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* 发起请求并对返回结果施加时间约束,当发生以下情况时,将被视为请求失败:
|
|
206
|
+
* 1. 首个数据块超时;
|
|
207
|
+
* 2. 相邻数据块超时;
|
|
208
|
+
*/
|
|
209
|
+
private async requestAndConstrainSpeed(
|
|
210
|
+
options: ChatCompletionOptions,
|
|
211
|
+
instance: BaseChatCompletion,
|
|
212
|
+
): Promise<ChatCompletionResult> {
|
|
213
|
+
const controller = controllerFromEitherType<ChatCompletionResult>()
|
|
214
|
+
|
|
215
|
+
const [chatCompletionLeft, chatCompletionRight] = eitherToTuple(await instance.chatCompletion(options))
|
|
216
|
+
if (chatCompletionLeft !== undefined) {
|
|
217
|
+
return await controller.returnLeft(chatCompletionLeft)
|
|
218
|
+
}
|
|
219
|
+
const { completionTube } = chatCompletionRight
|
|
220
|
+
|
|
221
|
+
const newCompletionTube = new Tube<Completion>({ historyCount: Infinity, replayHistory: true })
|
|
222
|
+
// 无异常的情况下,上游数据直接传递给下游即可
|
|
223
|
+
connectTube(completionTube, newCompletionTube)
|
|
224
|
+
|
|
225
|
+
const timeoutFirstChunk = options.timeoutFirstChunk ?? this.options.timeoutFirstChunk
|
|
226
|
+
const timeoutPerChunk = options.timeoutPerChunk ?? this.options.timeoutPerChunk
|
|
227
|
+
|
|
228
|
+
// 定义首个数据块超时的处理逻辑
|
|
229
|
+
let hasReceivedFirstChunk = false
|
|
230
|
+
const firstChunkTimeoutTimer: NodeJS.Timeout = setTimeout(() => {
|
|
231
|
+
if (hasReceivedFirstChunk === false) {
|
|
232
|
+
this.logger.addOnceTags(["ConstrainSpeed"]).log("First chunk timeout")
|
|
233
|
+
void newCompletionTube.pushError(new Error("FirstChunkTimeout"))
|
|
234
|
+
}
|
|
235
|
+
}, timeoutFirstChunk)
|
|
236
|
+
|
|
237
|
+
// 定义相邻数据块超时的处理逻辑
|
|
238
|
+
let perChunkTimeoutTimer: NodeJS.Timeout | undefined
|
|
239
|
+
completionTube.subscribeData({
|
|
240
|
+
subscriber: () => {
|
|
241
|
+
if (hasReceivedFirstChunk === false) {
|
|
242
|
+
this.logger.addOnceTags(["ConstrainSpeed"]).log("Received first chunk, clear first chunk timeout timer")
|
|
243
|
+
hasReceivedFirstChunk = true
|
|
244
|
+
// Clear the timeout timer for the first chunk
|
|
245
|
+
clearTimeout(firstChunkTimeoutTimer)
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
// Reset the timeout timer for each chunk
|
|
249
|
+
clearTimeout(perChunkTimeoutTimer)
|
|
250
|
+
}
|
|
251
|
+
// Set a new timeout timer for the next chunk
|
|
252
|
+
perChunkTimeoutTimer = setTimeout(() => {
|
|
253
|
+
this.logger.addOnceTags(["ConstrainSpeed"]).log("Per chunk timeout")
|
|
254
|
+
void newCompletionTube.pushError(new Error("PerChunkTimeout"))
|
|
255
|
+
}, timeoutPerChunk)
|
|
256
|
+
},
|
|
257
|
+
})
|
|
258
|
+
completionTube.subscribeEndEvent({
|
|
259
|
+
subscriber: () => {
|
|
260
|
+
this.logger.addOnceTags(["ConstrainSpeed"]).log("Source completion tube ended")
|
|
261
|
+
clearTimeout(firstChunkTimeoutTimer)
|
|
262
|
+
clearTimeout(perChunkTimeoutTimer)
|
|
263
|
+
},
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
return await controller.returnRight({
|
|
267
|
+
completionTube: newCompletionTube,
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import type * as Aio from "#Source/aio/index.ts"
|
|
2
|
+
import type { WithAbortSignal } from "#Source/abort/index.ts"
|
|
3
|
+
import type { Either } from "#Source/result/index.ts"
|
|
4
|
+
import type { Tube } from "#Source/tube/index.ts"
|
|
5
|
+
import type { StringWithAutoCompleteOptions } from "#Source/type/index.ts"
|
|
6
|
+
import type { LoggerFriendly, LoggerFriendlyOptions } from "#Source/log/index.ts"
|
|
7
|
+
import { Logger } from "#Source/log/index.ts"
|
|
8
|
+
|
|
9
|
+
export interface ChatCompletionContentPartText {
|
|
10
|
+
/**
|
|
11
|
+
* The text content.
|
|
12
|
+
*/
|
|
13
|
+
text: string
|
|
14
|
+
/**
|
|
15
|
+
* The type of the content part.
|
|
16
|
+
*/
|
|
17
|
+
type: "text"
|
|
18
|
+
}
|
|
19
|
+
export interface ChatCompletionContentPartRefusal {
|
|
20
|
+
/**
|
|
21
|
+
* The refusal message generated by the model.
|
|
22
|
+
*/
|
|
23
|
+
refusal: string
|
|
24
|
+
/**
|
|
25
|
+
* The type of the content part.
|
|
26
|
+
*/
|
|
27
|
+
type: "refusal"
|
|
28
|
+
}
|
|
29
|
+
export interface ChatCompletionContentPartImage {
|
|
30
|
+
imageUrl: {
|
|
31
|
+
/**
|
|
32
|
+
* Either a URL of the image or the base64 encoded image data.
|
|
33
|
+
*/
|
|
34
|
+
url: string
|
|
35
|
+
/**
|
|
36
|
+
* Specifies the detail level of the image. Learn more in the
|
|
37
|
+
* [Vision guide](https://platform.openai.com/docs/guides/vision/low-or-high-fidelity-image-understanding).
|
|
38
|
+
*/
|
|
39
|
+
detail?: "auto" | "low" | "high"
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The type of the content part.
|
|
43
|
+
*/
|
|
44
|
+
type: "image_url"
|
|
45
|
+
}
|
|
46
|
+
export interface ChatCompletionSystemMessage {
|
|
47
|
+
/**
|
|
48
|
+
* The contents of the system message.
|
|
49
|
+
*/
|
|
50
|
+
content: string | ChatCompletionContentPartText[]
|
|
51
|
+
/**
|
|
52
|
+
* The role of the messages author, in this case `system`.
|
|
53
|
+
*/
|
|
54
|
+
role: "system"
|
|
55
|
+
}
|
|
56
|
+
export interface ChatCompletionUserMessage {
|
|
57
|
+
/**
|
|
58
|
+
* The contents of the user message.
|
|
59
|
+
*/
|
|
60
|
+
content: string | Array<ChatCompletionContentPartText | ChatCompletionContentPartImage>
|
|
61
|
+
/**
|
|
62
|
+
* The role of the messages author, in this case `user`.
|
|
63
|
+
*/
|
|
64
|
+
role: "user"
|
|
65
|
+
}
|
|
66
|
+
export interface ChatCompletionAssistantMessage {
|
|
67
|
+
/**
|
|
68
|
+
* The contents of the assistant message. Required unless `tool_calls` or
|
|
69
|
+
* `function_call` is specified.
|
|
70
|
+
*/
|
|
71
|
+
content: string | Array<ChatCompletionContentPartText | ChatCompletionContentPartRefusal>
|
|
72
|
+
/**
|
|
73
|
+
* The role of the messages author, in this case `assistant`.
|
|
74
|
+
*/
|
|
75
|
+
role: "assistant"
|
|
76
|
+
}
|
|
77
|
+
export type ChatCompletionMessage =
|
|
78
|
+
| ChatCompletionSystemMessage
|
|
79
|
+
| ChatCompletionUserMessage
|
|
80
|
+
| ChatCompletionAssistantMessage
|
|
81
|
+
const CHAT_COMPLETION_MODEL_LIST = [
|
|
82
|
+
"o1-preview",
|
|
83
|
+
"o1-preview-2024-09-12",
|
|
84
|
+
"o1-mini",
|
|
85
|
+
"o1-mini-2024-09-12",
|
|
86
|
+
"gpt-4o",
|
|
87
|
+
"gpt-4o-2024-08-06",
|
|
88
|
+
"gpt-4o-2024-05-13",
|
|
89
|
+
"gpt-4o-realtime-preview-2024-10-01",
|
|
90
|
+
"chatgpt-4o-latest",
|
|
91
|
+
"gpt-4o-mini",
|
|
92
|
+
"gpt-4o-mini-2024-07-18",
|
|
93
|
+
"gpt-4-turbo",
|
|
94
|
+
"gpt-4-turbo-2024-04-09",
|
|
95
|
+
"gpt-4-0125-preview",
|
|
96
|
+
"gpt-4-turbo-preview",
|
|
97
|
+
"gpt-4-1106-preview",
|
|
98
|
+
"gpt-4-vision-preview",
|
|
99
|
+
"gpt-4",
|
|
100
|
+
"gpt-4-0314",
|
|
101
|
+
"gpt-4-0613",
|
|
102
|
+
"gpt-4-32k",
|
|
103
|
+
"gpt-4-32k-0314",
|
|
104
|
+
"gpt-4-32k-0613",
|
|
105
|
+
"gpt-3.5-turbo",
|
|
106
|
+
"gpt-3.5-turbo-16k",
|
|
107
|
+
"gpt-3.5-turbo-0301",
|
|
108
|
+
"gpt-3.5-turbo-0613",
|
|
109
|
+
"gpt-3.5-turbo-1106",
|
|
110
|
+
"gpt-3.5-turbo-0125",
|
|
111
|
+
"gpt-3.5-turbo-16k-0613",
|
|
112
|
+
"yi-lightning",
|
|
113
|
+
"hunyuan-standard",
|
|
114
|
+
"grok-3",
|
|
115
|
+
"gemini-2.0-flash-lite-preview-02-05",
|
|
116
|
+
"deepseek-r1",
|
|
117
|
+
"deepseek-v3",
|
|
118
|
+
] as const
|
|
119
|
+
export type ChatCompletionModel = typeof CHAT_COMPLETION_MODEL_LIST[number]
|
|
120
|
+
export interface ResponseFormatText {
|
|
121
|
+
/**
|
|
122
|
+
* The type of response format being defined: `text`
|
|
123
|
+
*/
|
|
124
|
+
type: "text"
|
|
125
|
+
}
|
|
126
|
+
export interface ResponseFormatJSONObject {
|
|
127
|
+
/**
|
|
128
|
+
* The type of response format being defined: `json_object`
|
|
129
|
+
*/
|
|
130
|
+
type: "json_object"
|
|
131
|
+
}
|
|
132
|
+
export type ResponseFormat = ResponseFormatText | ResponseFormatJSONObject
|
|
133
|
+
export interface ChatCompletionOptions extends WithAbortSignal {
|
|
134
|
+
messages: ChatCompletionMessage[]
|
|
135
|
+
model: ChatCompletionModel
|
|
136
|
+
frequencyPenalty?: number | null
|
|
137
|
+
logitBias?: Record<string, number> | null
|
|
138
|
+
logprobs?: boolean | null
|
|
139
|
+
maxCompletionTokens?: number | null
|
|
140
|
+
maxTokens?: number | null
|
|
141
|
+
presencePenalty?: number | null
|
|
142
|
+
responseFormat?: ResponseFormat
|
|
143
|
+
temperature?: number | null
|
|
144
|
+
topLogprobs?: number | null
|
|
145
|
+
topP?: number | null
|
|
146
|
+
/**
|
|
147
|
+
* The timeout for the first chunk of data to be received, in milliseconds.
|
|
148
|
+
*/
|
|
149
|
+
timeoutFirstChunk?: number | undefined
|
|
150
|
+
/**
|
|
151
|
+
* The timeout for each chunk of data to be received, in milliseconds.
|
|
152
|
+
*/
|
|
153
|
+
timeoutPerChunk?: number | undefined
|
|
154
|
+
/**
|
|
155
|
+
* The maximum number of tries for the request.
|
|
156
|
+
*/
|
|
157
|
+
maxTries?: number | undefined
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface ChatCompletionLeft {
|
|
161
|
+
code: StringWithAutoCompleteOptions<never>
|
|
162
|
+
}
|
|
163
|
+
export interface Completion {
|
|
164
|
+
content: Aio.TextContent
|
|
165
|
+
token: Aio.NumberContent
|
|
166
|
+
}
|
|
167
|
+
export interface ChatCompletionRight {
|
|
168
|
+
completionTube: Tube<Completion>
|
|
169
|
+
}
|
|
170
|
+
export type ChatCompletionResult = Either<ChatCompletionLeft, ChatCompletionRight>
|
|
171
|
+
|
|
172
|
+
export interface BaseChatCompletionOptions extends LoggerFriendlyOptions {
|
|
173
|
+
}
|
|
174
|
+
export abstract class BaseChatCompletion implements LoggerFriendly {
|
|
175
|
+
readonly logger: Logger
|
|
176
|
+
private readonly supportedModelList: ChatCompletionModel[]
|
|
177
|
+
|
|
178
|
+
constructor(options: BaseChatCompletionOptions) {
|
|
179
|
+
this.logger = Logger.fromOptions(options).setDefaultName("BaseChatCompletion")
|
|
180
|
+
|
|
181
|
+
this.supportedModelList = [...CHAT_COMPLETION_MODEL_LIST]
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
isSupportModel(model: ChatCompletionModel): boolean {
|
|
185
|
+
return this.supportedModelList.includes(model)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
abstract chatCompletion(options: ChatCompletionOptions): Promise<ChatCompletionResult>
|
|
189
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * as ChatCompletionAi from "./chat-completion-ai.ts"
|
|
2
|
+
|
|
3
|
+
export * as ChatCompletion from "./chat-completion.ts"
|
|
4
|
+
export * as OpenaiNextChatCompletion from "./openai-next-chat-completion.ts"
|
|
5
|
+
export * as OhmygptChatCompletion from "./ohmygpt-chat-completion.ts"
|
|
6
|
+
export * as LingyiwanwuChatCompletion from "./lingyiwanwu-chat-completion.ts"
|
|
7
|
+
export * as AihubmixChatCompletion from "./aihubmix-chat-completion.ts"
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type * as Openai from "#Source/openai/index.ts"
|
|
2
|
+
|
|
3
|
+
import type { BaseChatCompletionOptions, ChatCompletionOptions, ChatCompletionResult } from "./chat-completion.ts"
|
|
4
|
+
import { BaseChatCompletion } from "./chat-completion.ts"
|
|
5
|
+
|
|
6
|
+
export interface LingyiwanwuChatCompletionOptions extends BaseChatCompletionOptions {
|
|
7
|
+
openai: Openai.Openai
|
|
8
|
+
}
|
|
9
|
+
export class LingyiwanwuChatCompletion extends BaseChatCompletion {
|
|
10
|
+
protected readonly openai: Openai.Openai
|
|
11
|
+
|
|
12
|
+
constructor(options: LingyiwanwuChatCompletionOptions) {
|
|
13
|
+
super(options)
|
|
14
|
+
this.logger.setDefaultName("LingyiwanwuChatCompletion")
|
|
15
|
+
|
|
16
|
+
this.openai = options.openai
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
protected transformOptions(options: ChatCompletionOptions): Openai.CustomChatCompletionOptions {
|
|
20
|
+
const transformedOptions: Openai.CustomChatCompletionOptions = {
|
|
21
|
+
messages: options.messages.map((message) => {
|
|
22
|
+
const { role, content } = message
|
|
23
|
+
if (role === "system") {
|
|
24
|
+
return message
|
|
25
|
+
}
|
|
26
|
+
if (role === "user") {
|
|
27
|
+
if (typeof content === "string") {
|
|
28
|
+
return {
|
|
29
|
+
role,
|
|
30
|
+
content,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (Array.isArray(content)) {
|
|
34
|
+
return {
|
|
35
|
+
role,
|
|
36
|
+
content: content.map((item) => {
|
|
37
|
+
if (item.type === "image_url") {
|
|
38
|
+
return {
|
|
39
|
+
type: item.type,
|
|
40
|
+
image_url: item.imageUrl,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return item
|
|
45
|
+
}
|
|
46
|
+
}),
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw new Error("Invalid content")
|
|
50
|
+
}
|
|
51
|
+
if (role === "assistant") {
|
|
52
|
+
return message
|
|
53
|
+
}
|
|
54
|
+
throw new Error("Invalid role")
|
|
55
|
+
}),
|
|
56
|
+
model: options.model,
|
|
57
|
+
...(options.frequencyPenalty !== undefined ? { frequency_penalty: options.frequencyPenalty } : {}),
|
|
58
|
+
...(options.logitBias !== undefined ? { logit_bias: options.logitBias } : {}),
|
|
59
|
+
...(options.logprobs !== undefined ? { logprobs: options.logprobs } : {}),
|
|
60
|
+
...(options.maxCompletionTokens !== undefined ? { max_completion_tokens: options.maxCompletionTokens } : {}),
|
|
61
|
+
...(options.maxTokens !== undefined ? { max_tokens: options.maxTokens } : {}),
|
|
62
|
+
...(options.presencePenalty !== undefined ? { presence_penalty: options.presencePenalty } : {}),
|
|
63
|
+
...(options.responseFormat !== undefined ? { response_format: options.responseFormat } : {}),
|
|
64
|
+
...(options.temperature !== undefined ? { temperature: options.temperature } : {}),
|
|
65
|
+
...(options.topLogprobs !== undefined ? { top_logprobs: options.topLogprobs } : {}),
|
|
66
|
+
...(options.topP !== undefined ? { top_p: options.topP } : {}),
|
|
67
|
+
timeout: options.timeoutFirstChunk ?? undefined,
|
|
68
|
+
abortSignal: options.abortSignal,
|
|
69
|
+
}
|
|
70
|
+
return transformedOptions
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async chatCompletion(options: ChatCompletionOptions): Promise<ChatCompletionResult> {
|
|
74
|
+
const transformedOptions = this.transformOptions(options)
|
|
75
|
+
const result = await this.openai.customChatCompletionStreaming(transformedOptions)
|
|
76
|
+
return result
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type * as Openai from "#Source/openai/index.ts"
|
|
2
|
+
|
|
3
|
+
import type { BaseChatCompletionOptions, ChatCompletionOptions, ChatCompletionResult } from "./chat-completion.ts"
|
|
4
|
+
import { BaseChatCompletion } from "./chat-completion.ts"
|
|
5
|
+
|
|
6
|
+
export interface OhmygptChatCompletionOptions extends BaseChatCompletionOptions {
|
|
7
|
+
openai: Openai.Openai
|
|
8
|
+
}
|
|
9
|
+
export class OhmygptChatCompletion extends BaseChatCompletion {
|
|
10
|
+
protected readonly openai: Openai.Openai
|
|
11
|
+
|
|
12
|
+
constructor(options: OhmygptChatCompletionOptions) {
|
|
13
|
+
super(options)
|
|
14
|
+
this.logger.setDefaultName("OhmygptChatCompletion")
|
|
15
|
+
|
|
16
|
+
this.openai = options.openai
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
protected transformOptions(options: ChatCompletionOptions): Openai.CustomChatCompletionOptions {
|
|
20
|
+
const transformedOptions: Openai.CustomChatCompletionOptions = {
|
|
21
|
+
messages: options.messages.map((message) => {
|
|
22
|
+
const { role, content } = message
|
|
23
|
+
if (role === "system") {
|
|
24
|
+
return message
|
|
25
|
+
}
|
|
26
|
+
if (role === "user") {
|
|
27
|
+
if (typeof content === "string") {
|
|
28
|
+
return {
|
|
29
|
+
role,
|
|
30
|
+
content,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (Array.isArray(content)) {
|
|
34
|
+
return {
|
|
35
|
+
role,
|
|
36
|
+
content: content.map((item) => {
|
|
37
|
+
if (item.type === "image_url") {
|
|
38
|
+
return {
|
|
39
|
+
type: item.type,
|
|
40
|
+
image_url: item.imageUrl,
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return item
|
|
45
|
+
}
|
|
46
|
+
}),
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
throw new Error("Invalid content")
|
|
50
|
+
}
|
|
51
|
+
if (role === "assistant") {
|
|
52
|
+
return message
|
|
53
|
+
}
|
|
54
|
+
throw new Error("Invalid role")
|
|
55
|
+
}),
|
|
56
|
+
model: options.model,
|
|
57
|
+
...(options.frequencyPenalty !== undefined ? { frequency_penalty: options.frequencyPenalty } : {}),
|
|
58
|
+
...(options.logitBias !== undefined ? { logit_bias: options.logitBias } : {}),
|
|
59
|
+
...(options.logprobs !== undefined ? { logprobs: options.logprobs } : {}),
|
|
60
|
+
...(options.maxCompletionTokens !== undefined ? { max_completion_tokens: options.maxCompletionTokens } : {}),
|
|
61
|
+
...(options.maxTokens !== undefined ? { max_tokens: options.maxTokens } : {}),
|
|
62
|
+
...(options.presencePenalty !== undefined ? { presence_penalty: options.presencePenalty } : {}),
|
|
63
|
+
...(options.responseFormat !== undefined ? { response_format: options.responseFormat } : {}),
|
|
64
|
+
...(options.temperature !== undefined ? { temperature: options.temperature } : {}),
|
|
65
|
+
...(options.topLogprobs !== undefined ? { top_logprobs: options.topLogprobs } : {}),
|
|
66
|
+
...(options.topP !== undefined ? { top_p: options.topP } : {}),
|
|
67
|
+
timeout: options.timeoutFirstChunk ?? undefined,
|
|
68
|
+
abortSignal: options.abortSignal,
|
|
69
|
+
}
|
|
70
|
+
return transformedOptions
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async chatCompletion(options: ChatCompletionOptions): Promise<ChatCompletionResult> {
|
|
74
|
+
const transformedOptions = this.transformOptions(options)
|
|
75
|
+
const result = await this.openai.customChatCompletionStreaming(transformedOptions)
|
|
76
|
+
return result
|
|
77
|
+
}
|
|
78
|
+
}
|