ctod 0.2.0 → 0.3.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 +67 -109
- package/dist/index.js +1 -1
- package/examples/chat-demo.ts +65 -0
- package/examples/{applications/cosplay.ts → plugin-demo.ts} +14 -16
- package/lib/broker/chat.ts +277 -0
- package/lib/core/plugin.ts +9 -102
- package/lib/index.ts +15 -35
- package/lib/plugins/index.ts +6 -1
- package/lib/plugins/limiter.ts +4 -56
- package/lib/plugins/print-log.ts +31 -111
- package/lib/plugins/retry.ts +22 -58
- package/lib/plugins/role.ts +26 -62
- package/lib/service/{chatgpt35.ts → openai/chat.ts} +21 -32
- package/lib/service/{chatgpt3.ts → openai/completion.ts} +12 -27
- package/lib/service/{images-generations.ts → openai/images-generation.ts} +7 -22
- package/lib/service/openai/index.ts +53 -0
- package/package.json +2 -2
- package/types/lib/broker/{35.d.ts → chat.d.ts} +42 -17
- package/types/lib/core/plugin.d.ts +9 -73
- package/types/lib/index.d.ts +14 -35
- package/types/lib/plugins/index.d.ts +17 -30
- package/types/lib/plugins/limiter.d.ts +4 -9
- package/types/lib/plugins/print-log.d.ts +4 -22
- package/types/lib/plugins/retry.d.ts +5 -19
- package/types/lib/plugins/role.d.ts +4 -17
- package/types/lib/service/{chatgpt35.d.ts → openai/chat.d.ts} +14 -24
- package/types/lib/service/{chatgpt3.d.ts → openai/completion.d.ts} +9 -19
- package/types/lib/service/{images-generations.d.ts → openai/images-generation.d.ts} +4 -14
- package/types/lib/service/openai/index.d.ts +23 -0
- package/README-TW.md +0 -245
- package/TODO +0 -6
- package/examples/applications/bbc-news-reader.ts +0 -224
- package/examples/applications/story-generations.ts +0 -131
- package/examples/applications/talk-generations.ts +0 -257
- package/examples/chatgpt3.5-broker.ts +0 -79
- package/examples/chatgpt3.5.ts +0 -42
- package/examples/utils/index.ts +0 -56
- package/lib/broker/3.ts +0 -160
- package/lib/broker/35.ts +0 -207
- package/lib/broker/4.ts +0 -207
- package/lib/broker/index.ts +0 -86
- package/lib/service/chatgpt4.ts +0 -137
- package/types/lib/broker/3.d.ts +0 -71
- package/types/lib/broker/4.d.ts +0 -86
- package/types/lib/broker/index.d.ts +0 -31
- package/types/lib/service/chatgpt4.d.ts +0 -89
package/lib/broker/35.ts
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { flow } from 'power-helper'
|
|
2
|
-
import { BaseBroker } from './index'
|
|
3
|
-
import { Translator } from '../core/translator'
|
|
4
|
-
import { Broker35Plugin } from '../core/plugin'
|
|
5
|
-
import { ValidateCallback, ValidateCallbackOutputs } from '../utils/validate'
|
|
6
|
-
import { ChatGPT35, ChatGPT35Message, ChatGPT35TalkResponse } from '../service/chatgpt35'
|
|
7
|
-
|
|
8
|
-
export class ChatGPT35Broker<
|
|
9
|
-
S extends ValidateCallback<any>,
|
|
10
|
-
O extends ValidateCallback<any>,
|
|
11
|
-
P extends Broker35Plugin<any, any>,
|
|
12
|
-
PS extends Record<string, ReturnType<P['use']>>
|
|
13
|
-
> extends BaseBroker<ChatGPT35, S, O, P, PS, {
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @zh 第一次聊天的時候觸發
|
|
17
|
-
* @en Triggered when chatting for the first time
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
talkFirst: {
|
|
21
|
-
id: string
|
|
22
|
-
data: ValidateCallbackOutputs<S>
|
|
23
|
-
plugins: {
|
|
24
|
-
[K in keyof PS]: {
|
|
25
|
-
send: (data: PS[K]['__receiveData']) => void
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
messages: ChatGPT35Message[]
|
|
29
|
-
setPreMessages: (messages: ChatGPT35Message[]) => void
|
|
30
|
-
changeMessages: (messages: ChatGPT35Message[]) => void
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @zh 發送聊天訊息給機器人前觸發
|
|
35
|
-
* @en Triggered before sending chat message to bot
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
talkBefore: {
|
|
39
|
-
id: string
|
|
40
|
-
data: ValidateCallbackOutputs<S>
|
|
41
|
-
messages: ChatGPT35Message[]
|
|
42
|
-
lastUserMessage: string
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* @zh 當聊天機器人回傳資料的時候觸發
|
|
47
|
-
* @en Triggered when the chatbot returns data
|
|
48
|
-
*/
|
|
49
|
-
|
|
50
|
-
talkAfter: {
|
|
51
|
-
id: string
|
|
52
|
-
data: ValidateCallbackOutputs<S>
|
|
53
|
-
response: ChatGPT35TalkResponse
|
|
54
|
-
messages: ChatGPT35Message[]
|
|
55
|
-
parseText: string
|
|
56
|
-
lastUserMessage: string
|
|
57
|
-
changeParseText: (text: string) => void
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* @zh 當回傳資料符合規格時觸發
|
|
62
|
-
* @en Triggered when the returned data meets the specifications
|
|
63
|
-
*/
|
|
64
|
-
|
|
65
|
-
succeeded: {
|
|
66
|
-
id: string
|
|
67
|
-
output: ValidateCallbackOutputs<O>
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* @zh 當回傳資料不符合規格,或是解析錯誤時觸發
|
|
72
|
-
* @en Triggered when the returned data does not meet the specifications or parsing errors
|
|
73
|
-
*/
|
|
74
|
-
|
|
75
|
-
parseFailed: {
|
|
76
|
-
id: string
|
|
77
|
-
error: any
|
|
78
|
-
retry: () => void
|
|
79
|
-
count: number
|
|
80
|
-
response: ChatGPT35TalkResponse
|
|
81
|
-
parserFails: { name: string, error: any }[]
|
|
82
|
-
messages: ChatGPT35Message[]
|
|
83
|
-
lastUserMessage: string
|
|
84
|
-
changeMessages: (messages: ChatGPT35Message[]) => void
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* @zh 不論成功失敗,執行結束的時候會執行。
|
|
89
|
-
* @en It will be executed when the execution is completed, regardless of success or failure.
|
|
90
|
-
*/
|
|
91
|
-
|
|
92
|
-
done: {
|
|
93
|
-
id: string
|
|
94
|
-
}
|
|
95
|
-
}> {
|
|
96
|
-
bot: ChatGPT35 = new ChatGPT35()
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* @zh 將請求發出至聊天機器人。
|
|
100
|
-
* @en Send request to chatbot.
|
|
101
|
-
*/
|
|
102
|
-
|
|
103
|
-
async request<T extends Translator<S, O>>(data: T['__schemeType']): Promise<T['__outputType']> {
|
|
104
|
-
this._install()
|
|
105
|
-
let id = flow.createUuid()
|
|
106
|
-
let output: any = null
|
|
107
|
-
let plugins = {} as any
|
|
108
|
-
let question = await this.translator.compile(data)
|
|
109
|
-
let messages: ChatGPT35Message[] = [
|
|
110
|
-
{
|
|
111
|
-
role: 'user',
|
|
112
|
-
content: question.prompt
|
|
113
|
-
}
|
|
114
|
-
]
|
|
115
|
-
for (let key in this.plugins) {
|
|
116
|
-
plugins[key] = {
|
|
117
|
-
send: (data: any) => this.plugins[key].send({
|
|
118
|
-
id,
|
|
119
|
-
data
|
|
120
|
-
})
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
await this.hook.notify('talkFirst', {
|
|
124
|
-
id,
|
|
125
|
-
data,
|
|
126
|
-
plugins,
|
|
127
|
-
messages,
|
|
128
|
-
setPreMessages: ms => {
|
|
129
|
-
messages = [
|
|
130
|
-
...ms,
|
|
131
|
-
{
|
|
132
|
-
role: 'user',
|
|
133
|
-
content: question.prompt
|
|
134
|
-
}
|
|
135
|
-
]
|
|
136
|
-
},
|
|
137
|
-
changeMessages: ms => {
|
|
138
|
-
messages = ms
|
|
139
|
-
}
|
|
140
|
-
})
|
|
141
|
-
await flow.asyncWhile(async ({ count, doBreak }) => {
|
|
142
|
-
if (count >= 10) {
|
|
143
|
-
return doBreak()
|
|
144
|
-
}
|
|
145
|
-
let response: ChatGPT35TalkResponse = null as any
|
|
146
|
-
let parseText = ''
|
|
147
|
-
let retryFlag = false
|
|
148
|
-
let lastUserMessage = messages.filter(e => e.role === 'user').slice(-1)[0]?.content || ''
|
|
149
|
-
try {
|
|
150
|
-
await this.hook.notify('talkBefore', {
|
|
151
|
-
id,
|
|
152
|
-
data,
|
|
153
|
-
messages,
|
|
154
|
-
lastUserMessage
|
|
155
|
-
})
|
|
156
|
-
response = await this.bot.talk(messages)
|
|
157
|
-
parseText = response.text
|
|
158
|
-
await this.hook.notify('talkAfter', {
|
|
159
|
-
id,
|
|
160
|
-
data,
|
|
161
|
-
response,
|
|
162
|
-
parseText,
|
|
163
|
-
messages: response.newMessages,
|
|
164
|
-
lastUserMessage,
|
|
165
|
-
changeParseText: text => {
|
|
166
|
-
parseText = text
|
|
167
|
-
}
|
|
168
|
-
})
|
|
169
|
-
messages = response.newMessages
|
|
170
|
-
output = (await this.translator.parse(parseText)).output
|
|
171
|
-
await this.hook.notify('succeeded', {
|
|
172
|
-
id,
|
|
173
|
-
output
|
|
174
|
-
})
|
|
175
|
-
await this.hook.notify('done', { id })
|
|
176
|
-
doBreak()
|
|
177
|
-
} catch (error: any) {
|
|
178
|
-
// 如果解析錯誤,可以選擇是否重新解讀
|
|
179
|
-
if (error.isParserError) {
|
|
180
|
-
await this.hook.notify('parseFailed', {
|
|
181
|
-
id,
|
|
182
|
-
error: error.error,
|
|
183
|
-
count,
|
|
184
|
-
response,
|
|
185
|
-
messages,
|
|
186
|
-
lastUserMessage,
|
|
187
|
-
parserFails: error.parserFails,
|
|
188
|
-
retry: () => {
|
|
189
|
-
retryFlag = true
|
|
190
|
-
},
|
|
191
|
-
changeMessages: ms => {
|
|
192
|
-
messages = ms
|
|
193
|
-
}
|
|
194
|
-
})
|
|
195
|
-
if (retryFlag === false) {
|
|
196
|
-
await this.hook.notify('done', { id })
|
|
197
|
-
throw error
|
|
198
|
-
}
|
|
199
|
-
} else {
|
|
200
|
-
await this.hook.notify('done', { id })
|
|
201
|
-
throw error
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
})
|
|
205
|
-
return output
|
|
206
|
-
}
|
|
207
|
-
}
|
package/lib/broker/4.ts
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import { flow } from 'power-helper'
|
|
2
|
-
import { BaseBroker } from './index'
|
|
3
|
-
import { Translator } from '../core/translator'
|
|
4
|
-
import { Broker4Plugin } from '../core/plugin'
|
|
5
|
-
import { ValidateCallback, ValidateCallbackOutputs } from '../utils/validate'
|
|
6
|
-
import { ChatGPT4, ChatGPT4Message, ChatGPT4TalkResponse } from '../service/chatgpt4'
|
|
7
|
-
|
|
8
|
-
export class ChatGPT4Broker<
|
|
9
|
-
S extends ValidateCallback<any>,
|
|
10
|
-
O extends ValidateCallback<any>,
|
|
11
|
-
P extends Broker4Plugin<any, any>,
|
|
12
|
-
PS extends Record<string, ReturnType<P['use']>>
|
|
13
|
-
> extends BaseBroker<ChatGPT4, S, O, P, PS, {
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @zh 第一次聊天的時候觸發
|
|
17
|
-
* @en Triggered when chatting for the first time
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
talkFirst: {
|
|
21
|
-
id: string
|
|
22
|
-
data: ValidateCallbackOutputs<S>
|
|
23
|
-
plugins: {
|
|
24
|
-
[K in keyof PS]: {
|
|
25
|
-
send: (data: PS[K]['__receiveData']) => void
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
messages: ChatGPT4Message[]
|
|
29
|
-
setPreMessages: (messages: ChatGPT4Message[]) => void
|
|
30
|
-
changeMessages: (messages: ChatGPT4Message[]) => void
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @zh 發送聊天訊息給機器人前觸發
|
|
35
|
-
* @en Triggered before sending chat message to bot
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
talkBefore: {
|
|
39
|
-
id: string
|
|
40
|
-
data: ValidateCallbackOutputs<S>
|
|
41
|
-
messages: ChatGPT4Message[]
|
|
42
|
-
lastUserMessage: string
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* @zh 當聊天機器人回傳資料的時候觸發
|
|
47
|
-
* @en Triggered when the chatbot returns data
|
|
48
|
-
*/
|
|
49
|
-
|
|
50
|
-
talkAfter: {
|
|
51
|
-
id: string
|
|
52
|
-
data: ValidateCallbackOutputs<S>
|
|
53
|
-
response: ChatGPT4TalkResponse
|
|
54
|
-
messages: ChatGPT4Message[]
|
|
55
|
-
parseText: string
|
|
56
|
-
lastUserMessage: string
|
|
57
|
-
changeParseText: (text: string) => void
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* @zh 當回傳資料符合規格時觸發
|
|
62
|
-
* @en Triggered when the returned data meets the specifications
|
|
63
|
-
*/
|
|
64
|
-
|
|
65
|
-
succeeded: {
|
|
66
|
-
id: string
|
|
67
|
-
output: ValidateCallbackOutputs<O>
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* @zh 當回傳資料不符合規格,或是解析錯誤時觸發
|
|
72
|
-
* @en Triggered when the returned data does not meet the specifications or parsing errors
|
|
73
|
-
*/
|
|
74
|
-
|
|
75
|
-
parseFailed: {
|
|
76
|
-
id: string
|
|
77
|
-
error: any
|
|
78
|
-
retry: () => void
|
|
79
|
-
count: number
|
|
80
|
-
response: ChatGPT4TalkResponse
|
|
81
|
-
parserFails: { name: string, error: any }[]
|
|
82
|
-
messages: ChatGPT4Message[]
|
|
83
|
-
lastUserMessage: string
|
|
84
|
-
changeMessages: (messages: ChatGPT4Message[]) => void
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* @zh 不論成功失敗,執行結束的時候會執行。
|
|
89
|
-
* @en It will be executed when the execution is completed, regardless of success or failure.
|
|
90
|
-
*/
|
|
91
|
-
|
|
92
|
-
done: {
|
|
93
|
-
id: string
|
|
94
|
-
}
|
|
95
|
-
}> {
|
|
96
|
-
bot: ChatGPT4 = new ChatGPT4()
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* @zh 將請求發出至聊天機器人。
|
|
100
|
-
* @en Send request to chatbot.
|
|
101
|
-
*/
|
|
102
|
-
|
|
103
|
-
async request<T extends Translator<S, O>>(data: T['__schemeType']): Promise<T['__outputType']> {
|
|
104
|
-
this._install()
|
|
105
|
-
let id = flow.createUuid()
|
|
106
|
-
let output: any = null
|
|
107
|
-
let plugins = {} as any
|
|
108
|
-
let question = await this.translator.compile(data)
|
|
109
|
-
let messages: ChatGPT4Message[] = [
|
|
110
|
-
{
|
|
111
|
-
role: 'user',
|
|
112
|
-
content: question.prompt
|
|
113
|
-
}
|
|
114
|
-
]
|
|
115
|
-
for (let key in this.plugins) {
|
|
116
|
-
plugins[key] = {
|
|
117
|
-
send: (data: any) => this.plugins[key].send({
|
|
118
|
-
id,
|
|
119
|
-
data
|
|
120
|
-
})
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
await this.hook.notify('talkFirst', {
|
|
124
|
-
id,
|
|
125
|
-
data,
|
|
126
|
-
plugins,
|
|
127
|
-
messages,
|
|
128
|
-
setPreMessages: ms => {
|
|
129
|
-
messages = [
|
|
130
|
-
...ms,
|
|
131
|
-
{
|
|
132
|
-
role: 'user',
|
|
133
|
-
content: question.prompt
|
|
134
|
-
}
|
|
135
|
-
]
|
|
136
|
-
},
|
|
137
|
-
changeMessages: ms => {
|
|
138
|
-
messages = ms
|
|
139
|
-
}
|
|
140
|
-
})
|
|
141
|
-
await flow.asyncWhile(async ({ count, doBreak }) => {
|
|
142
|
-
if (count >= 10) {
|
|
143
|
-
return doBreak()
|
|
144
|
-
}
|
|
145
|
-
let response: ChatGPT4TalkResponse = null as any
|
|
146
|
-
let parseText = ''
|
|
147
|
-
let retryFlag = false
|
|
148
|
-
let lastUserMessage = messages.filter(e => e.role === 'user').slice(-1)[0]?.content || ''
|
|
149
|
-
try {
|
|
150
|
-
await this.hook.notify('talkBefore', {
|
|
151
|
-
id,
|
|
152
|
-
data,
|
|
153
|
-
messages,
|
|
154
|
-
lastUserMessage
|
|
155
|
-
})
|
|
156
|
-
response = await this.bot.talk(messages)
|
|
157
|
-
parseText = response.text
|
|
158
|
-
await this.hook.notify('talkAfter', {
|
|
159
|
-
id,
|
|
160
|
-
data,
|
|
161
|
-
response,
|
|
162
|
-
parseText,
|
|
163
|
-
messages: response.newMessages,
|
|
164
|
-
lastUserMessage,
|
|
165
|
-
changeParseText: text => {
|
|
166
|
-
parseText = text
|
|
167
|
-
}
|
|
168
|
-
})
|
|
169
|
-
messages = response.newMessages
|
|
170
|
-
output = (await this.translator.parse(parseText)).output
|
|
171
|
-
await this.hook.notify('succeeded', {
|
|
172
|
-
id,
|
|
173
|
-
output
|
|
174
|
-
})
|
|
175
|
-
await this.hook.notify('done', { id })
|
|
176
|
-
doBreak()
|
|
177
|
-
} catch (error: any) {
|
|
178
|
-
// 如果解析錯誤,可以選擇是否重新解讀
|
|
179
|
-
if (error.isParserError) {
|
|
180
|
-
await this.hook.notify('parseFailed', {
|
|
181
|
-
id,
|
|
182
|
-
error: error.error,
|
|
183
|
-
count,
|
|
184
|
-
response,
|
|
185
|
-
messages,
|
|
186
|
-
lastUserMessage,
|
|
187
|
-
parserFails: error.parserFails,
|
|
188
|
-
retry: () => {
|
|
189
|
-
retryFlag = true
|
|
190
|
-
},
|
|
191
|
-
changeMessages: ms => {
|
|
192
|
-
messages = ms
|
|
193
|
-
}
|
|
194
|
-
})
|
|
195
|
-
if (retryFlag === false) {
|
|
196
|
-
await this.hook.notify('done', { id })
|
|
197
|
-
throw error
|
|
198
|
-
}
|
|
199
|
-
} else {
|
|
200
|
-
await this.hook.notify('done', { id })
|
|
201
|
-
throw error
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
})
|
|
205
|
-
return output
|
|
206
|
-
}
|
|
207
|
-
}
|
package/lib/broker/index.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { Hook, Log } from 'power-helper'
|
|
2
|
-
import { ChatGPT3 } from '../service/chatgpt3'
|
|
3
|
-
import { ChatGPT35 } from '../service/chatgpt35'
|
|
4
|
-
import { ChatGPT4 } from '../service/chatgpt4'
|
|
5
|
-
import { TextParser } from '../core/parser'
|
|
6
|
-
import { ValidateCallback } from '../utils/validate'
|
|
7
|
-
import { Translator, TranslatorParams } from '../core/translator'
|
|
8
|
-
import { Broker3Plugin, Broker35Plugin, Broker4Plugin } from '../core/plugin'
|
|
9
|
-
|
|
10
|
-
export type Params<
|
|
11
|
-
B extends ChatGPT3 | ChatGPT35 | ChatGPT4,
|
|
12
|
-
S extends ValidateCallback<any>,
|
|
13
|
-
O extends ValidateCallback<any>,
|
|
14
|
-
C extends Record<string, any>,
|
|
15
|
-
P extends Broker3Plugin<any, any> | Broker35Plugin<any, any> | Broker4Plugin<any, any>,
|
|
16
|
-
PS extends Record<string, ReturnType<P['use']>>
|
|
17
|
-
> = Omit<TranslatorParams<S, O>, 'parsers'> & {
|
|
18
|
-
name?: string
|
|
19
|
-
plugins?: PS | (() => PS)
|
|
20
|
-
install: (context: {
|
|
21
|
-
log: Log
|
|
22
|
-
bot: B
|
|
23
|
-
attach: Hook<C>['attach']
|
|
24
|
-
attachAfter: Hook<C>['attachAfter']
|
|
25
|
-
translator: Translator<S, O>
|
|
26
|
-
}) => void
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export class BaseBroker<
|
|
30
|
-
B extends ChatGPT3 | ChatGPT35 | ChatGPT4,
|
|
31
|
-
S extends ValidateCallback<any>,
|
|
32
|
-
O extends ValidateCallback<any>,
|
|
33
|
-
P extends Broker3Plugin<any, any> | Broker35Plugin<any, any> | Broker4Plugin<any, any>,
|
|
34
|
-
PS extends Record<string, ReturnType<P['use']>>,
|
|
35
|
-
C extends Record<string, any>
|
|
36
|
-
> {
|
|
37
|
-
protected __hookType!: C
|
|
38
|
-
protected log: Log
|
|
39
|
-
protected hook = new Hook<C>()
|
|
40
|
-
protected bot!: B
|
|
41
|
-
protected params: Params<B, S, O, C, P, PS>
|
|
42
|
-
protected plugins = {} as PS
|
|
43
|
-
protected installed = false
|
|
44
|
-
protected translator: Translator<S, O>
|
|
45
|
-
|
|
46
|
-
constructor(params: Params<B, S, O, C, P, PS>) {
|
|
47
|
-
this.log = new Log(params.name ?? 'no name')
|
|
48
|
-
this.params = params
|
|
49
|
-
this.translator = new Translator({
|
|
50
|
-
...params,
|
|
51
|
-
parsers: [
|
|
52
|
-
TextParser.JsonMessage()
|
|
53
|
-
]
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
protected _install(): any {
|
|
58
|
-
if (this.installed === false) {
|
|
59
|
-
this.installed = true
|
|
60
|
-
if (this.bot) {
|
|
61
|
-
const context = {
|
|
62
|
-
bot: this.bot,
|
|
63
|
-
log: this.log,
|
|
64
|
-
attach: this.hook.attach.bind(this.hook),
|
|
65
|
-
attachAfter: this.hook.attachAfter.bind(this.hook),
|
|
66
|
-
translator: this.translator
|
|
67
|
-
}
|
|
68
|
-
this.params.install(context)
|
|
69
|
-
if (this.params.plugins) {
|
|
70
|
-
this.plugins = typeof this.params.plugins === 'function' ? this.params.plugins() : this.params.plugins
|
|
71
|
-
for (let key in this.plugins) {
|
|
72
|
-
this.plugins[key].instance._params.onInstall({
|
|
73
|
-
...context,
|
|
74
|
-
params: this.plugins[key].params,
|
|
75
|
-
receive: this.plugins[key].receive
|
|
76
|
-
})
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
protected request(_data: any): any {
|
|
84
|
-
throw Error('DON\'T CALL THIS!')
|
|
85
|
-
}
|
|
86
|
-
}
|
package/lib/service/chatgpt4.ts
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import axios, { AxiosInstance } from 'axios'
|
|
2
|
-
import { json } from 'power-helper'
|
|
3
|
-
import { PromiseResponseType } from '../types'
|
|
4
|
-
|
|
5
|
-
export type ChatGPT4Message = {
|
|
6
|
-
role: 'system' | 'user' | 'assistant'
|
|
7
|
-
name?: string
|
|
8
|
-
content: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
type ApiResponse = {
|
|
12
|
-
id: string
|
|
13
|
-
object: string
|
|
14
|
-
created: number
|
|
15
|
-
choices: Array<{
|
|
16
|
-
index: number
|
|
17
|
-
finish_reason: string
|
|
18
|
-
message: {
|
|
19
|
-
role: 'system' | 'user' | 'assistant'
|
|
20
|
-
name?: string
|
|
21
|
-
content: string
|
|
22
|
-
}
|
|
23
|
-
}>
|
|
24
|
-
usage: {
|
|
25
|
-
prompt_tokens: number
|
|
26
|
-
completion_tokens: number
|
|
27
|
-
total_tokens: number
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
type Config = {
|
|
32
|
-
/**
|
|
33
|
-
* @zh 一次回應數量
|
|
34
|
-
* @en How many chat completion choices to generate for each input message.
|
|
35
|
-
*/
|
|
36
|
-
n: number
|
|
37
|
-
/**
|
|
38
|
-
* @zh 選擇運行的模型,32k意味著能處理長度為 32768 的文本,而預設為 8192。
|
|
39
|
-
* @en How many chat completion choices to generate for each input message.
|
|
40
|
-
*/
|
|
41
|
-
model: 'gpt-4' | 'gpt-4-32k'
|
|
42
|
-
/**
|
|
43
|
-
* @zh 冒險指數,數值由 0 ~ 2 之間。
|
|
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.
|
|
45
|
-
*/
|
|
46
|
-
temperature: number
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export class ChatGPT4 {
|
|
50
|
-
axios = axios.create()
|
|
51
|
-
apiKey = ''
|
|
52
|
-
config: Config = {
|
|
53
|
-
n: 1,
|
|
54
|
-
model: 'gpt-4',
|
|
55
|
-
temperature: 1
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @zh 如果你有需要特別設定 axios,請使用這方法
|
|
60
|
-
* @en If you need to set axios, use this method
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
|
-
setAxios(axios: AxiosInstance) {
|
|
64
|
-
this.axios = axios
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* @zh 設定 api key
|
|
69
|
-
* @en Set api key
|
|
70
|
-
*/
|
|
71
|
-
|
|
72
|
-
setConfiguration(apiKey: string) {
|
|
73
|
-
this.apiKey = apiKey
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @zh 改變對話的一些設定
|
|
78
|
-
* @en Change some settings of the conversation
|
|
79
|
-
*/
|
|
80
|
-
|
|
81
|
-
setConfig(options: Partial<Config>) {
|
|
82
|
-
Object.assign(this.config, options)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @zh 進行對話
|
|
87
|
-
* @en Talk to the AI
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
async talk(messages: ChatGPT4Message[] = []) {
|
|
91
|
-
const newMessages = json.jpjs(messages)
|
|
92
|
-
const result = await this.axios.post<ApiResponse>('https://api.openai.com/v1/chat/completions', {
|
|
93
|
-
model: this.config.model,
|
|
94
|
-
n: this.config.n,
|
|
95
|
-
messages: newMessages,
|
|
96
|
-
temperature: this.config.temperature
|
|
97
|
-
}, {
|
|
98
|
-
headers: {
|
|
99
|
-
'Content-Type': 'application/json',
|
|
100
|
-
'Authorization': `Bearer ${this.apiKey}`
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
const choices = result.data.choices || []
|
|
104
|
-
const message = choices[0]?.message || {
|
|
105
|
-
role: 'assistant',
|
|
106
|
-
content: ''
|
|
107
|
-
}
|
|
108
|
-
newMessages.push(message)
|
|
109
|
-
return {
|
|
110
|
-
id: result?.data.id as string,
|
|
111
|
-
text: message.content as string,
|
|
112
|
-
isDone: choices[0]?.finish_reason === 'stop',
|
|
113
|
-
newMessages,
|
|
114
|
-
apiReseponse: result.data
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* @zh 開啟持續性對話
|
|
120
|
-
*/
|
|
121
|
-
|
|
122
|
-
async chat(prompt: string | string[], oldMessages: ChatGPT4Message[] = []) {
|
|
123
|
-
const result = await this.talk([
|
|
124
|
-
...oldMessages,
|
|
125
|
-
{
|
|
126
|
-
role: 'user',
|
|
127
|
-
content: Array.isArray(prompt) ? prompt.join('\n') : prompt
|
|
128
|
-
}
|
|
129
|
-
])
|
|
130
|
-
return {
|
|
131
|
-
result,
|
|
132
|
-
nextTalk: (prompt: string | string[]) => this.chat(prompt, result.newMessages)
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export type ChatGPT4TalkResponse = PromiseResponseType<ChatGPT4['talk']>
|
package/types/lib/broker/3.d.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { Translator } from '../core/translator';
|
|
2
|
-
import { BaseBroker } from './index';
|
|
3
|
-
import { Broker3Plugin } from '../core/plugin';
|
|
4
|
-
import { ChatGPT3, ChatGPT3TalkResponse } from '../service/chatgpt3';
|
|
5
|
-
import { ValidateCallback, ValidateCallbackOutputs } from '../utils/validate';
|
|
6
|
-
export declare class ChatGPT3Broker<S extends ValidateCallback<any>, O extends ValidateCallback<any>, P extends Broker3Plugin<any, any>, PS extends Record<string, ReturnType<P['use']>>> extends BaseBroker<ChatGPT3, S, O, P, PS, {
|
|
7
|
-
/**
|
|
8
|
-
* @zh 發送聊天訊息給機器人前觸發
|
|
9
|
-
* @en Triggered before sending chat message to bot
|
|
10
|
-
*/
|
|
11
|
-
talkBefore: {
|
|
12
|
-
id: string;
|
|
13
|
-
data: ValidateCallbackOutputs<S>;
|
|
14
|
-
prompt: string;
|
|
15
|
-
plugins: {
|
|
16
|
-
[K in keyof PS]: {
|
|
17
|
-
send: (data: PS[K]['__receiveData']) => void;
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* @zh 當聊天機器人回傳資料的時候觸發
|
|
23
|
-
* @en Triggered when the chatbot returns data
|
|
24
|
-
*/
|
|
25
|
-
talkAfter: {
|
|
26
|
-
id: string;
|
|
27
|
-
data: ValidateCallbackOutputs<S>;
|
|
28
|
-
prompt: string;
|
|
29
|
-
response: ChatGPT3TalkResponse;
|
|
30
|
-
parseText: string;
|
|
31
|
-
changeParseText: (text: string) => void;
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
|
-
* @zh 當回傳資料符合規格時觸發
|
|
35
|
-
* @en Triggered when the returned data meets the specifications
|
|
36
|
-
*/
|
|
37
|
-
succeeded: {
|
|
38
|
-
id: string;
|
|
39
|
-
output: ValidateCallbackOutputs<O>;
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* @zh 當回傳資料不符合規格,或是解析錯誤時觸發
|
|
43
|
-
* @en Triggered when the returned data does not meet the specifications or parsing errors
|
|
44
|
-
*/
|
|
45
|
-
parseFailed: {
|
|
46
|
-
id: string;
|
|
47
|
-
error: any;
|
|
48
|
-
count: number;
|
|
49
|
-
retry: () => void;
|
|
50
|
-
response: ChatGPT3TalkResponse;
|
|
51
|
-
parserFails: {
|
|
52
|
-
name: string;
|
|
53
|
-
error: any;
|
|
54
|
-
}[];
|
|
55
|
-
changePrompt: (text: string) => void;
|
|
56
|
-
};
|
|
57
|
-
/**
|
|
58
|
-
* @zh 不論成功失敗,執行結束的時候會執行。
|
|
59
|
-
* @en It will be executed when the execution is completed, regardless of success or failure.
|
|
60
|
-
*/
|
|
61
|
-
done: {
|
|
62
|
-
id: string;
|
|
63
|
-
};
|
|
64
|
-
}> {
|
|
65
|
-
bot: ChatGPT3;
|
|
66
|
-
/**
|
|
67
|
-
* @zh 將請求發出至聊天機器人。
|
|
68
|
-
* @en Send request to chatbot.
|
|
69
|
-
*/
|
|
70
|
-
request<T extends Translator<S, O>>(data: T['__schemeType']): Promise<T['__outputType']>;
|
|
71
|
-
}
|