ctod 0.7.2 → 0.8.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/README.md +6 -1
- package/dist/index.js +40 -1
- package/dist/index.js.map +7 -0
- package/esbuild.mjs +21 -0
- package/eslint.config.mjs +29 -0
- package/examples/google.ts +97 -0
- package/examples/llama.cpp.ts +2 -4
- package/examples/{basic.ts → openai.ts} +3 -3
- package/examples/plugin.ts +2 -5
- package/lib/core/parser.ts +2 -2
- package/lib/core/translator.ts +2 -1
- package/lib/ctod.ts +2 -2
- package/lib/index.ts +10 -34
- package/lib/plugins/index.ts +1 -1
- package/lib/service/google/chat.ts +110 -0
- package/lib/service/google/index.ts +101 -0
- package/lib/service/llama3.cpp/completion.ts +5 -5
- package/lib/service/llama3.cpp/index.ts +4 -4
- package/lib/service/openai/chat.ts +13 -14
- package/lib/service/openai/images-generation.ts +3 -3
- package/lib/service/openai/index.ts +7 -8
- package/lib/service/openai/vision.ts +5 -5
- package/lib/types.ts +2 -2
- package/lib/utils/validate.ts +2 -2
- package/package.json +13 -13
- package/types/examples/google.d.ts +1 -0
- package/types/examples/llama.cpp.d.ts +0 -1
- package/types/examples/openai.d.ts +1 -0
- package/types/examples/plugin.d.ts +0 -1
- package/types/lib/index.d.ts +8 -28
- package/types/lib/service/google/chat.d.ts +58 -0
- package/types/lib/service/google/index.d.ts +25 -0
- package/types/lib/service/llama3.cpp/completion.d.ts +3 -3
- package/types/lib/service/llama3.cpp/index.d.ts +2 -2
- package/types/lib/service/openai/chat.d.ts +11 -11
- package/types/lib/service/openai/images-generation.d.ts +2 -2
- package/types/lib/service/openai/index.d.ts +1 -1
- package/types/lib/service/openai/vision.d.ts +5 -5
- package/types/lib/types.d.ts +1 -1
- package/types/lib/utils/validate.d.ts +1 -1
- package/.eslintrc.js +0 -30
- package/lib/shims.d.ts +0 -4
- package/webpack.config.ts +0 -45
package/examples/plugin.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
|
|
2
|
-
/// <reference path="../lib/shims.d.ts" />
|
|
3
|
-
|
|
4
1
|
import fs from 'fs'
|
|
5
2
|
import { flow } from 'power-helper'
|
|
6
3
|
import { prompt } from 'inquirer'
|
|
7
|
-
import { CtoD, ChatBrokerPlugin, plugins,
|
|
4
|
+
import { CtoD, ChatBrokerPlugin, plugins, OpenAICtodService } from '../lib/index'
|
|
8
5
|
|
|
9
6
|
/**
|
|
10
7
|
* @test npx esno ./examples/plugin.ts
|
|
@@ -71,7 +68,7 @@ flow.run(async () => {
|
|
|
71
68
|
})
|
|
72
69
|
}
|
|
73
70
|
},
|
|
74
|
-
request:
|
|
71
|
+
request: OpenAICtodService.createChatRequestWithJsonSchema({
|
|
75
72
|
apiKey,
|
|
76
73
|
config: {
|
|
77
74
|
model: 'gpt-4o'
|
package/lib/core/parser.ts
CHANGED
|
@@ -3,7 +3,7 @@ import JSON5 from 'json5'
|
|
|
3
3
|
type TextParserParams = {
|
|
4
4
|
/**
|
|
5
5
|
* @zh 解讀器名字。
|
|
6
|
-
* @en The name of the parser.
|
|
6
|
+
* @en The name of the parser.
|
|
7
7
|
*/
|
|
8
8
|
name: string
|
|
9
9
|
/**
|
|
@@ -43,7 +43,7 @@ export class TextParser {
|
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* @zh 解讀器名字。
|
|
46
|
-
* @en The name of the parser.
|
|
46
|
+
* @en The name of the parser.
|
|
47
47
|
*/
|
|
48
48
|
|
|
49
49
|
get name() {
|
package/lib/core/translator.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type TranslatorParams<
|
|
|
13
13
|
input?: S
|
|
14
14
|
/**
|
|
15
15
|
* @zh 輸出的資料格式。
|
|
16
|
-
* @en The output data format.
|
|
16
|
+
* @en The output data format.
|
|
17
17
|
*/
|
|
18
18
|
output: O
|
|
19
19
|
/**
|
|
@@ -46,6 +46,7 @@ export class Translator<
|
|
|
46
46
|
get __schemeType(): ValidateCallbackOutputs<S> {
|
|
47
47
|
return null as any
|
|
48
48
|
}
|
|
49
|
+
|
|
49
50
|
get __outputType(): ValidateCallbackOutputs<O> {
|
|
50
51
|
return null as any
|
|
51
52
|
}
|
package/lib/ctod.ts
CHANGED
|
@@ -39,7 +39,7 @@ export class CtoD<
|
|
|
39
39
|
P,
|
|
40
40
|
PS,
|
|
41
41
|
ChatBrokerHooks<() => I, () => O, P, PS>
|
|
42
|
-
|
|
42
|
+
>({
|
|
43
43
|
output: () => ({} as any),
|
|
44
44
|
install: (context) => {
|
|
45
45
|
params?.install?.(context)
|
|
@@ -62,7 +62,7 @@ export class CtoD<
|
|
|
62
62
|
changeOutputSchema(() => schema)
|
|
63
63
|
})
|
|
64
64
|
},
|
|
65
|
-
plugins: this.params.plugins ? (
|
|
65
|
+
plugins: this.params.plugins ? () => this.params.plugins!() : undefined,
|
|
66
66
|
request: this.params.request
|
|
67
67
|
})
|
|
68
68
|
}
|
package/lib/index.ts
CHANGED
|
@@ -1,41 +1,17 @@
|
|
|
1
1
|
export * as plugins from './plugins'
|
|
2
2
|
export * as templates from './templates'
|
|
3
3
|
export { CtoD } from './ctod'
|
|
4
|
-
export { validateToJsonSchema, defineYupSchema
|
|
5
|
-
|
|
6
|
-
export {
|
|
4
|
+
export { validateToJsonSchema, defineYupSchema } from './utils/validate'
|
|
5
|
+
|
|
6
|
+
export { OpenAICtodService } from './service/openai'
|
|
7
|
+
export { Llama3CppCtodService } from './service/llama3.cpp'
|
|
8
|
+
export { GoogleCtodService } from './service/google'
|
|
9
|
+
|
|
7
10
|
export { TextParser } from './core/parser'
|
|
8
|
-
export { ChatGPTMessage } from './service/openai/chat'
|
|
9
11
|
export { ChatBroker } from './broker/chat'
|
|
10
12
|
export { ChatBrokerPlugin } from './core/plugin'
|
|
11
|
-
export { Translator
|
|
12
|
-
|
|
13
|
-
import * as plugins from './plugins'
|
|
14
|
-
import * as templates from './templates'
|
|
15
|
-
import { OpenAI } from './service/openai'
|
|
16
|
-
import { CtoD } from './ctod'
|
|
17
|
-
import { Llama3Cpp } from './service/llama3.cpp'
|
|
18
|
-
import { Translator } from './core/translator'
|
|
19
|
-
import { TextParser } from './core/parser'
|
|
20
|
-
import { ChatBroker } from './broker/chat'
|
|
21
|
-
import { ChatBrokerPlugin } from './core/plugin'
|
|
22
|
-
import { validateToJsonSchema, defineYupSchema } from './utils/validate'
|
|
23
|
-
|
|
24
|
-
export const ctod = {
|
|
25
|
-
CtoD,
|
|
26
|
-
OpenAI,
|
|
27
|
-
Llama3Cpp,
|
|
28
|
-
plugins,
|
|
29
|
-
templates,
|
|
30
|
-
ChatBroker,
|
|
31
|
-
Translator,
|
|
32
|
-
TextParser,
|
|
33
|
-
ChatBrokerPlugin,
|
|
34
|
-
defineYupSchema,
|
|
35
|
-
validateToJsonSchema
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
module.exports = ctod
|
|
39
|
-
module.exports.ctod = ctod
|
|
13
|
+
export { Translator } from './core/translator'
|
|
40
14
|
|
|
41
|
-
export
|
|
15
|
+
export type { ValidateCallback } from './utils/validate'
|
|
16
|
+
export type { TranslatorParams } from './core/translator'
|
|
17
|
+
export type { ChatGPTMessage } from './service/openai/chat'
|
package/lib/plugins/index.ts
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { json } from 'power-helper'
|
|
2
|
+
import { GoogleCtodService } from './index'
|
|
3
|
+
import { PromiseResponseType } from '../../types'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* if data:
|
|
7
|
+
* data: base64 string,
|
|
8
|
+
* mimeType: image/jpeg,
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
type Part = {
|
|
12
|
+
text: string
|
|
13
|
+
} | {
|
|
14
|
+
inlineData: {
|
|
15
|
+
data: string
|
|
16
|
+
mimeType: string
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type GoogleMessage = {
|
|
21
|
+
role: 'model' | 'user'
|
|
22
|
+
parts: Part[]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type Config = {
|
|
26
|
+
/**
|
|
27
|
+
* @zh 選擇運行的模型。
|
|
28
|
+
* @en What model to use.
|
|
29
|
+
*/
|
|
30
|
+
model: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export class GoogleChat {
|
|
34
|
+
google: GoogleCtodService
|
|
35
|
+
config: Config = {
|
|
36
|
+
model: 'gemini-1.5-flash'
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
constructor(google: GoogleCtodService) {
|
|
40
|
+
this.google = google
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @zh 改變對話的一些設定
|
|
45
|
+
* @en Change some settings of the conversation
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
setConfig(options: Partial<Config>) {
|
|
49
|
+
Object.assign(this.config, options)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @zh 進行對話
|
|
54
|
+
* @en Talk to the AI
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
async talk(messages: GoogleMessage[] = []) {
|
|
58
|
+
const newMessages = json.jpjs(messages)
|
|
59
|
+
const model = this.google.generativeAI.getGenerativeModel({
|
|
60
|
+
model: this.config.model
|
|
61
|
+
})
|
|
62
|
+
const result = await model.generateContent({
|
|
63
|
+
contents: newMessages
|
|
64
|
+
})
|
|
65
|
+
const text = result.response.text()
|
|
66
|
+
return {
|
|
67
|
+
text,
|
|
68
|
+
newMessages: [
|
|
69
|
+
...newMessages,
|
|
70
|
+
{
|
|
71
|
+
role: 'model',
|
|
72
|
+
parts: [
|
|
73
|
+
{
|
|
74
|
+
text
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
talkStream(params: {
|
|
83
|
+
messages: GoogleMessage[]
|
|
84
|
+
onMessage: (_message: string) => void
|
|
85
|
+
onEnd: () => void
|
|
86
|
+
onWarn: (_warn: any) => void
|
|
87
|
+
onError: (_error: any) => void
|
|
88
|
+
}) {
|
|
89
|
+
const model = this.google.generativeAI.getGenerativeModel({
|
|
90
|
+
model: this.config.model
|
|
91
|
+
})
|
|
92
|
+
const context = {
|
|
93
|
+
contents: params.messages
|
|
94
|
+
}
|
|
95
|
+
model
|
|
96
|
+
.generateContentStream(context)
|
|
97
|
+
.then(async({ stream }) => {
|
|
98
|
+
for await (const chunk of stream) {
|
|
99
|
+
const chunkText = chunk.text()
|
|
100
|
+
params.onMessage(chunkText)
|
|
101
|
+
}
|
|
102
|
+
params.onEnd()
|
|
103
|
+
})
|
|
104
|
+
.catch((error) => {
|
|
105
|
+
params.onError(error)
|
|
106
|
+
})
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export type GoogleChatTalkResponse = PromiseResponseType<GoogleChat['talk']>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { validateToJsonSchema } from '../../utils/validate'
|
|
2
|
+
import { GoogleMessage, GoogleChat } from './chat'
|
|
3
|
+
import type { GoogleGenerativeAI } from '@google/generative-ai'
|
|
4
|
+
|
|
5
|
+
type GPTContent = {
|
|
6
|
+
type: 'image_url' | 'text'
|
|
7
|
+
text?: string
|
|
8
|
+
image_url?: {
|
|
9
|
+
url: string
|
|
10
|
+
detail?: string
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type GPTMessage = {
|
|
15
|
+
role: 'system' | 'user' | 'assistant'
|
|
16
|
+
content: string | GPTContent[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class GoogleCtodService {
|
|
20
|
+
generativeAI: GoogleGenerativeAI
|
|
21
|
+
|
|
22
|
+
constructor(generativeAI: GoogleGenerativeAI) {
|
|
23
|
+
this.generativeAI = generativeAI
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static chatGPTMessageToGoogleChatMessage(messages: GPTMessage[]): GoogleMessage[] {
|
|
27
|
+
const contentToParts = (content: string | GPTMessage['content']): GoogleMessage['parts'] => {
|
|
28
|
+
if (typeof content === 'string') {
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
text: content
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
} else if (Array.isArray(content)) {
|
|
35
|
+
return content.map(({ type, image_url, text }): GoogleMessage['parts'][number] => {
|
|
36
|
+
if (type === 'image_url') {
|
|
37
|
+
return {
|
|
38
|
+
inlineData: {
|
|
39
|
+
data: image_url?.url || '',
|
|
40
|
+
mimeType: 'image/jpeg'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
return {
|
|
45
|
+
text: text || ''
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
return []
|
|
51
|
+
}
|
|
52
|
+
return messages.map((message) => {
|
|
53
|
+
if (message.role === 'user' || message.role === 'system') {
|
|
54
|
+
return {
|
|
55
|
+
role: 'user',
|
|
56
|
+
parts: contentToParts(message.content)
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
return {
|
|
60
|
+
role: 'model',
|
|
61
|
+
parts: contentToParts(message.content)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static createChatRequestWithJsonSchema(params: {
|
|
68
|
+
googleGenerativeAI: GoogleGenerativeAI
|
|
69
|
+
model: string
|
|
70
|
+
}) {
|
|
71
|
+
const removeAdditionalProperties = (schema: any) => {
|
|
72
|
+
if (schema.type === 'object') {
|
|
73
|
+
delete schema.additionalProperties
|
|
74
|
+
Object.keys(schema.properties).forEach((key) => {
|
|
75
|
+
removeAdditionalProperties(schema.properties[key])
|
|
76
|
+
})
|
|
77
|
+
} else if (schema.type === 'array') {
|
|
78
|
+
removeAdditionalProperties(schema.items)
|
|
79
|
+
}
|
|
80
|
+
return schema
|
|
81
|
+
}
|
|
82
|
+
return async (messages: any[], { schema }: any) => {
|
|
83
|
+
const responseSchema = removeAdditionalProperties(validateToJsonSchema(schema.output))
|
|
84
|
+
const model = params.googleGenerativeAI.getGenerativeModel({
|
|
85
|
+
model: params.model,
|
|
86
|
+
generationConfig: {
|
|
87
|
+
responseMimeType: 'application/json',
|
|
88
|
+
responseSchema
|
|
89
|
+
}
|
|
90
|
+
})
|
|
91
|
+
const result = await model.generateContent({
|
|
92
|
+
contents: GoogleCtodService.chatGPTMessageToGoogleChatMessage(messages)
|
|
93
|
+
})
|
|
94
|
+
return result.response.text()
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
createChat() {
|
|
99
|
+
return new GoogleChat(this)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Llama3CppCtodService } from './index'
|
|
2
2
|
import { flow } from 'power-helper'
|
|
3
|
-
import { tify, sify } from 'chinese-conv'
|
|
3
|
+
import { tify, sify } from 'chinese-conv/dist'
|
|
4
4
|
|
|
5
5
|
type Message = {
|
|
6
6
|
role: string
|
|
@@ -150,14 +150,14 @@ class Requester {
|
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
export class Llama3CppCompletion {
|
|
153
|
-
core:
|
|
153
|
+
core: Llama3CppCtodService
|
|
154
154
|
config: Config = {
|
|
155
155
|
baseUrl: '',
|
|
156
156
|
headers: {},
|
|
157
157
|
autoConvertTraditionalChinese: true
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
constructor(core:
|
|
160
|
+
constructor(core: Llama3CppCtodService) {
|
|
161
161
|
this.core = core
|
|
162
162
|
}
|
|
163
163
|
|
|
@@ -248,7 +248,7 @@ export class Llama3CppCompletion {
|
|
|
248
248
|
options?: Options
|
|
249
249
|
messages: Message[]
|
|
250
250
|
response_format?: {
|
|
251
|
-
type: 'json_object'
|
|
251
|
+
type: 'json_object'
|
|
252
252
|
schema: any
|
|
253
253
|
}
|
|
254
254
|
}) {
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import axios, { AxiosInstance } from 'axios'
|
|
2
|
-
import { sify } from 'chinese-conv'
|
|
2
|
+
import { sify } from 'chinese-conv/dist'
|
|
3
3
|
import { validateToJsonSchema } from '../../utils/validate'
|
|
4
4
|
import { Llama3CppCompletion, Config } from './completion'
|
|
5
5
|
|
|
6
|
-
export class
|
|
6
|
+
export class Llama3CppCtodService {
|
|
7
7
|
_axios = axios.create()
|
|
8
8
|
|
|
9
|
-
static
|
|
9
|
+
static createChatRequestWithJsonSchema(params: {
|
|
10
10
|
config: Partial<Config> | (() => Promise<Partial<Config>>)
|
|
11
11
|
talkOptions?: any
|
|
12
12
|
}) {
|
|
13
13
|
return async(messages: any[], { schema, onCancel }: any) => {
|
|
14
|
-
const ll3cpp = new
|
|
14
|
+
const ll3cpp = new Llama3CppCtodService()
|
|
15
15
|
const chat = ll3cpp.createCompletion()
|
|
16
16
|
const config = typeof params.config === 'function' ? await params.config() : params.config
|
|
17
17
|
chat.setConfig(config)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { json } from 'power-helper'
|
|
2
|
-
import {
|
|
2
|
+
import { OpenAICtodService } from './index'
|
|
3
3
|
import { PromiseResponseType } from '../../types'
|
|
4
4
|
|
|
5
5
|
export type ChatGPTMessage = {
|
|
@@ -35,10 +35,10 @@ export type Config = {
|
|
|
35
35
|
*/
|
|
36
36
|
n: number
|
|
37
37
|
/**
|
|
38
|
-
* @zh
|
|
39
|
-
* @en
|
|
38
|
+
* @zh 選擇運行的模型,建議: 'gpt-4' | 'gpt-3.5-turbo' | 'gpt-4-turbo' | 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1' | 'o1-mini'
|
|
39
|
+
* @en What model to use, recommended: 'gpt-4' | 'gpt-3.5-turbo' | 'gpt-4-turbo' | 'gpt-4o' | 'gpt-4o-mini' | 'o1-preview' | 'o1' | 'o1-mini'
|
|
40
40
|
*/
|
|
41
|
-
model:
|
|
41
|
+
model: string
|
|
42
42
|
/**
|
|
43
43
|
* @zh 冒險指數,數值由 0 ~ 2 之間,越低回應越穩定。
|
|
44
44
|
* @en What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.
|
|
@@ -57,7 +57,7 @@ export type Config = {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export class OpenAIChat {
|
|
60
|
-
openai:
|
|
60
|
+
openai: OpenAICtodService
|
|
61
61
|
config: Config = {
|
|
62
62
|
n: 1,
|
|
63
63
|
model: 'gpt-4o',
|
|
@@ -66,7 +66,7 @@ export class OpenAIChat {
|
|
|
66
66
|
forceJsonFormat: true
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
constructor(openai:
|
|
69
|
+
constructor(openai: OpenAICtodService) {
|
|
70
70
|
this.openai = openai
|
|
71
71
|
}
|
|
72
72
|
|
|
@@ -110,7 +110,7 @@ export class OpenAIChat {
|
|
|
110
110
|
abortController?: AbortController
|
|
111
111
|
}) {
|
|
112
112
|
const newMessages = json.jpjs(messages)
|
|
113
|
-
const isSupportJson =
|
|
113
|
+
const isSupportJson = [
|
|
114
114
|
'gpt-4-turbo-preview',
|
|
115
115
|
'gpt-4-turbo',
|
|
116
116
|
'gpt-4o',
|
|
@@ -153,23 +153,23 @@ export class OpenAIChat {
|
|
|
153
153
|
text: message.content as string,
|
|
154
154
|
newMessages,
|
|
155
155
|
isDone: choices[0]?.finish_reason === 'stop',
|
|
156
|
-
|
|
156
|
+
apiResponse: result.data
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
talkStream(params: {
|
|
161
161
|
messages: any[]
|
|
162
|
-
onMessage: (
|
|
162
|
+
onMessage: (_message: string) => void
|
|
163
163
|
onEnd: () => void
|
|
164
|
-
onWarn: (
|
|
165
|
-
onError: (
|
|
164
|
+
onWarn: (_warn: any) => void
|
|
165
|
+
onError: (_error: any) => void
|
|
166
166
|
}) {
|
|
167
167
|
const controller = new AbortController()
|
|
168
168
|
fetch('https://api.openai.com/v1/chat/completions', {
|
|
169
169
|
method: 'POST',
|
|
170
170
|
headers: {
|
|
171
171
|
'Content-Type': 'application/json',
|
|
172
|
-
Authorization: `Bearer ${this.openai._apiKey}`
|
|
172
|
+
'Authorization': `Bearer ${this.openai._apiKey}`
|
|
173
173
|
},
|
|
174
174
|
body: JSON.stringify({
|
|
175
175
|
model: this.config.model,
|
|
@@ -178,12 +178,11 @@ export class OpenAIChat {
|
|
|
178
178
|
}),
|
|
179
179
|
signal: controller.signal
|
|
180
180
|
}).then(async response => {
|
|
181
|
-
// eslint-disable-next-line no-undef
|
|
182
181
|
const reader = response.body?.pipeThrough(new TextDecoderStream()).getReader()
|
|
183
182
|
if (!reader) {
|
|
184
183
|
throw new Error('Can not get reader')
|
|
185
184
|
}
|
|
186
|
-
|
|
185
|
+
|
|
187
186
|
while (true) {
|
|
188
187
|
const { value, done } = await reader.read()
|
|
189
188
|
if (done) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OpenAICtodService } from './index'
|
|
2
2
|
|
|
3
3
|
type ApiResponse = {
|
|
4
4
|
created: string
|
|
@@ -21,13 +21,13 @@ type Config = {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
export class OpenAIImagesGeneration {
|
|
24
|
-
private openai:
|
|
24
|
+
private openai: OpenAICtodService
|
|
25
25
|
private config: Config = {
|
|
26
26
|
model: 'dall-e-2',
|
|
27
27
|
size: '1024x1024'
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
constructor(openai:
|
|
30
|
+
constructor(openai: OpenAICtodService) {
|
|
31
31
|
this.openai = openai
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -4,7 +4,7 @@ import { OpenAIChat, Config } from './chat'
|
|
|
4
4
|
import { OpenAIImagesGeneration } from './images-generation'
|
|
5
5
|
import { validateToJsonSchema } from '../../utils/validate'
|
|
6
6
|
|
|
7
|
-
export class
|
|
7
|
+
export class OpenAICtodService {
|
|
8
8
|
_axios = axios.create()
|
|
9
9
|
_apiKey = ''
|
|
10
10
|
|
|
@@ -13,10 +13,10 @@ export class OpenAI {
|
|
|
13
13
|
config: Partial<Config> | (() => Promise<Partial<Config>>) = {},
|
|
14
14
|
options?: {
|
|
15
15
|
axios?: any
|
|
16
|
-
}
|
|
16
|
+
}
|
|
17
17
|
) {
|
|
18
18
|
return async(messages: any[], { onCancel }: any) => {
|
|
19
|
-
const openai = new
|
|
19
|
+
const openai = new OpenAICtodService(typeof apiKey === 'string' ? apiKey : await apiKey())
|
|
20
20
|
const chat = openai.createChat()
|
|
21
21
|
const abortController = new AbortController()
|
|
22
22
|
if (options && options.axios) {
|
|
@@ -31,13 +31,13 @@ export class OpenAI {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
static createChatRequestWithJsonSchema(params:{
|
|
35
|
-
axios?: any
|
|
36
|
-
apiKey: string | (() => Promise<string>)
|
|
34
|
+
static createChatRequestWithJsonSchema(params: {
|
|
35
|
+
axios?: any
|
|
36
|
+
apiKey: string | (() => Promise<string>)
|
|
37
37
|
config?: Partial<Pick<Config, 'model' | 'temperature'>> | (() => Promise<Partial<Pick<Config, 'model' | 'temperature'>>>)
|
|
38
38
|
}) {
|
|
39
39
|
return async(messages: any[], { schema, onCancel }: any) => {
|
|
40
|
-
const openai = new
|
|
40
|
+
const openai = new OpenAICtodService(typeof params.apiKey === 'string' ? params.apiKey : await params.apiKey())
|
|
41
41
|
const chat = openai.createChat()
|
|
42
42
|
const abortController = new AbortController()
|
|
43
43
|
if (params.config) {
|
|
@@ -60,7 +60,6 @@ export class OpenAI {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
|
|
64
63
|
constructor(apiKey = '') {
|
|
65
64
|
this._apiKey = apiKey
|
|
66
65
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OpenAICtodService } from './index'
|
|
2
2
|
import { PromiseResponseType } from '../../types'
|
|
3
3
|
|
|
4
4
|
type ImageContent = {
|
|
@@ -10,7 +10,7 @@ type ImageContent = {
|
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
type VisionMessage = {
|
|
13
|
+
export type VisionMessage = {
|
|
14
14
|
role: 'system' | 'user' | 'assistant'
|
|
15
15
|
name?: string
|
|
16
16
|
content: string | ImageContent[]
|
|
@@ -57,14 +57,14 @@ export type Config = {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export class OpenAIVision {
|
|
60
|
-
openai:
|
|
60
|
+
openai: OpenAICtodService
|
|
61
61
|
config: Config = {
|
|
62
62
|
model: 'gpt-4-vision-preview',
|
|
63
63
|
maxTokens: undefined,
|
|
64
64
|
temperature: 1
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
constructor(openai:
|
|
67
|
+
constructor(openai: OpenAICtodService) {
|
|
68
68
|
this.openai = openai
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -103,7 +103,7 @@ export class OpenAIVision {
|
|
|
103
103
|
return {
|
|
104
104
|
id: result?.data.id as string,
|
|
105
105
|
text: message.content as string,
|
|
106
|
-
|
|
106
|
+
apiResponse: result.data
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
}
|
package/lib/types.ts
CHANGED
package/lib/utils/validate.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type ValidateCallbackOutputs<
|
|
|
10
10
|
T extends ValidateCallback<any>,
|
|
11
11
|
R = ReturnType<T>
|
|
12
12
|
> = {
|
|
13
|
-
[K in keyof R]: R[K] extends {
|
|
13
|
+
[K in keyof R]: R[K] extends { __outputType: any } ? R[K]['__outputType'] : R[K]
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export function definedValidateSchema<T extends ValidateCallback<any>>(cb: T): T {
|
|
@@ -22,7 +22,7 @@ export function validate<
|
|
|
22
22
|
R = ReturnType<T>
|
|
23
23
|
>(target: any, schemaCallback: T) {
|
|
24
24
|
return Yup.object(schemaCallback(Yup)).required().validateSync(target || {}) as {
|
|
25
|
-
[K in keyof R]: R[K] extends {
|
|
25
|
+
[K in keyof R]: R[K] extends { __outputType: any } ? R[K]['__outputType'] : R[K]
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|