ctod 0.6.3 → 0.7.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/.api-key +1 -0
- package/.nyc_output/42919e68-b472-4a5d-b2d3-5d5153f28467.json +1 -0
- package/.nyc_output/processinfo/42919e68-b472-4a5d-b2d3-5d5153f28467.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -0
- package/.output/.output/stores//344/270/200/345/240/264/346/234/237/345/276/205/345/267/262/344/271/205/347/232/204/345/222/214/350/247/243/cover-0.png +1 -0
- package/.output/.output/stores//344/270/200/345/240/264/346/234/237/345/276/205/345/267/262/344/271/205/347/232/204/345/222/214/350/247/243/cover-1.png +1 -0
- package/.output/.output/stores//344/270/200/345/240/264/346/234/237/345/276/205/345/267/262/344/271/205/347/232/204/345/222/214/350/247/243/story-config.json +4 -0
- package/.output/.output/stores//344/270/200/345/240/264/346/234/237/345/276/205/345/267/262/344/271/205/347/232/204/345/222/214/350/247/243/story.json +22 -0
- package/.output/.output/stores//345/276/236/351/273/221/346/232/227/350/265/260/345/220/221/345/205/211/346/230/216/cover-0.png +1 -0
- package/.output/.output/stores//345/276/236/351/273/221/346/232/227/350/265/260/345/220/221/345/205/211/346/230/216/cover-1.png +1 -0
- package/.output/.output/stores//345/276/236/351/273/221/346/232/227/350/265/260/345/220/221/345/205/211/346/230/216/story-config.json +4 -0
- package/.output/.output/stores//345/276/236/351/273/221/346/232/227/350/265/260/345/220/221/345/205/211/346/230/216/story.json +24 -0
- package/.output/.output/stores//347/240/264/347/242/216/347/232/204/345/271/273/350/261/241/cover-0.png +1 -0
- package/.output/.output/stores//347/240/264/347/242/216/347/232/204/345/271/273/350/261/241/cover-1.png +1 -0
- package/.output/.output/stores//347/240/264/347/242/216/347/232/204/345/271/273/350/261/241/story-config.json +4 -0
- package/.output/.output/stores//347/240/264/347/242/216/347/232/204/345/271/273/350/261/241/story.json +24 -0
- package/.output/.output/stores//350/227/235/350/241/223/345/256/266/347/232/204/351/235/210/346/204/237/cover-0.png +1 -0
- package/.output/.output/stores//350/227/235/350/241/223/345/256/266/347/232/204/351/235/210/346/204/237/cover-1.png +1 -0
- package/.output/.output/stores//350/227/235/350/241/223/345/256/266/347/232/204/351/235/210/346/204/237/story-config.json +4 -0
- package/.output/.output/stores//350/227/235/350/241/223/345/256/266/347/232/204/351/235/210/346/204/237/story.json +28 -0
- package/.output/.output/stores//350/250/230/346/206/266/345/225/206/344/272/272/cover-0.png +1 -0
- package/.output/.output/stores//350/250/230/346/206/266/345/225/206/344/272/272/cover-1.png +1 -0
- package/.output/.output/stores//350/250/230/346/206/266/345/225/206/344/272/272/story-config.json +4 -0
- package/.output/.output/stores//350/250/230/346/206/266/345/225/206/344/272/272/story.json +18 -0
- package/.output/.output/stores//350/250/255/350/250/210/350/210/207/351/226/213/347/231/274/347/232/204/346/214/221/346/210/260/content.json +22 -0
- package/.output/.output/talks//344/273/245/347/254/221/350/251/261/347/202/272/345/237/272/347/244/216/347/232/204/351/235/242/350/251/246/content.json +30 -0
- package/.output/.output/talks//344/273/245/347/254/221/350/251/261/347/202/272/345/237/272/347/244/216/347/232/204/351/235/242/350/251/246/cover-1684055229695.png +0 -0
- package/.output/.output/talks//345/234/250/346/224/277/346/262/273/345/200/231/351/201/270/344/272/272/350/276/257/350/253/226/344/270/255/347/232/204/350/252/252/346/234/215/346/200/247/346/272/235/351/200/232/content.json +30 -0
- package/.output/.output/talks//345/234/250/346/224/277/346/262/273/345/200/231/351/201/270/344/272/272/350/276/257/350/253/226/344/270/255/347/232/204/350/252/252/346/234/215/346/200/247/346/272/235/351/200/232/cover-1684056611678.png +0 -0
- package/.output/.output/talks//346/224/276/351/254/206/347/232/204/345/200/231/351/201/270/344/272/272/351/200/262/350/241/214/346/224/277/346/262/273/350/276/257/350/253/226/content.json +36 -0
- package/.output/.output/talks//346/224/276/351/254/206/347/232/204/345/200/231/351/201/270/344/272/272/351/200/262/350/241/214/346/224/277/346/262/273/350/276/257/350/253/226/cover-1684055140609.png +0 -0
- package/.output/.output/talks//346/224/277/346/262/273/347/254/221/350/251/261/content.json +30 -0
- package/.output/.output/talks//346/224/277/346/262/273/347/254/221/350/251/261/cover-1684056246465.png +0 -0
- package/.output/.output/talks//350/251/274/350/253/247/345/256/266/351/225/267/346/225/231/345/270/253/346/234/203/350/255/260/content.json +26 -0
- package/.output/.output/talks//350/251/274/350/253/247/345/256/266/351/225/267/346/225/231/345/270/253/346/234/203/350/255/260/cover-1685785935121.png +0 -0
- package/.output/.output/talks//350/262/241/345/213/231/351/241/247/345/225/217/350/253/256/350/251/242/content.json +26 -0
- package/.output/.output/talks//350/262/241/345/213/231/351/241/247/345/225/217/350/253/256/350/251/242/cover-1685785115833.png +0 -0
- package/.output/.output/talks//351/206/253/347/224/237/345/222/214/347/227/205/344/272/272/350/250/216/350/253/226/346/202/262/345/202/267/content.json +32 -0
- package/.output/.output/talks//351/206/253/347/224/237/345/222/214/347/227/205/344/272/272/350/250/216/350/253/226/346/202/262/345/202/267/cover-1684055075942.png +0 -0
- package/README.md +87 -84
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/examples/chat-demo.ts +0 -89
- package/examples/chat-for-llama.cpp-demo.ts +0 -57
- package/examples/plugin-demo.ts +0 -110
- package/examples/stream-for-llama.cpp-demo.ts +0 -33
- package/examples/vision-demo-ex.png +0 -0
- package/examples/vision-demo.png +0 -0
- package/examples/vision-demo.ts +0 -168
- package/lib/broker/chat.ts +0 -406
- package/lib/core/parser.ts +0 -62
- package/lib/core/plugin.ts +0 -46
- package/lib/core/translator.ts +0 -111
- package/lib/index.ts +0 -38
- package/lib/plugins/index.ts +0 -38
- package/lib/plugins/limiter.ts +0 -103
- package/lib/plugins/print-log.ts +0 -35
- package/lib/plugins/retry.ts +0 -25
- package/lib/plugins/role.ts +0 -28
- package/lib/service/llama3.cpp/completion.ts +0 -313
- package/lib/service/llama3.cpp/index.ts +0 -53
- package/lib/service/openai/chat.ts +0 -244
- package/lib/service/openai/images-generation.ts +0 -64
- package/lib/service/openai/index.ts +0 -97
- package/lib/service/openai/vision.ts +0 -111
- package/lib/shims.d.ts +0 -4
- package/lib/templates.ts +0 -71
- package/lib/types.ts +0 -4
- package/lib/utils/error.ts +0 -14
- package/lib/utils/validate.ts +0 -64
- package/logo.ai +2 -1141
- package/logo.png +0 -0
- package/types/examples/chat-demo.d.ts +0 -2
- package/types/examples/chat-for-llama.cpp-demo.d.ts +0 -2
- package/types/examples/chat-with-json-schema-demo.d.ts +0 -2
- package/types/examples/plugin-demo.d.ts +0 -2
- package/types/examples/stream-for-llama.cpp-demo.d.ts +0 -2
- package/types/examples/vision-demo.d.ts +0 -2
- package/types/lib/broker/chat.d.ts +0 -142
- package/types/lib/core/parser.d.ts +0 -32
- package/types/lib/core/plugin.d.ts +0 -34
- package/types/lib/core/translator.d.ts +0 -68
- package/types/lib/index.d.ts +0 -31
- package/types/lib/plugins/index.d.ts +0 -47
- package/types/lib/plugins/limiter.d.ts +0 -36
- package/types/lib/plugins/print-log.d.ts +0 -5
- package/types/lib/plugins/retry.d.ts +0 -6
- package/types/lib/plugins/role.d.ts +0 -5
- package/types/lib/service/llama3.cpp/completion.d.ts +0 -61
- package/types/lib/service/llama3.cpp/index.d.ts +0 -19
- package/types/lib/service/openai/chat.d.ts +0 -110
- package/types/lib/service/openai/completion.d.ts +0 -59
- package/types/lib/service/openai/images-generation.d.ts +0 -35
- package/types/lib/service/openai/index.d.ts +0 -29
- package/types/lib/service/openai/vision.d.ts +0 -74
- package/types/lib/templates.d.ts +0 -20
- package/types/lib/types.d.ts +0 -1
- package/types/lib/utils/error.d.ts +0 -11
- package/types/lib/utils/validate.d.ts +0 -16
package/lib/broker/chat.ts
DELETED
|
@@ -1,406 +0,0 @@
|
|
|
1
|
-
import { TextParser } from '../core/parser'
|
|
2
|
-
import { ChatBrokerPlugin } from '../core/plugin'
|
|
3
|
-
import { Event, flow, Hook, Log } from 'power-helper'
|
|
4
|
-
import { Translator, TranslatorParams } from '../core/translator'
|
|
5
|
-
import { ValidateCallback, ValidateCallbackOutputs } from '../utils/validate'
|
|
6
|
-
import { ParserError } from '../utils/error'
|
|
7
|
-
|
|
8
|
-
type Message = {
|
|
9
|
-
role: 'system' | 'user' | 'assistant'
|
|
10
|
-
name?: string
|
|
11
|
-
content: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type ChatBrokerHooks<
|
|
15
|
-
S extends ValidateCallback<any>,
|
|
16
|
-
O extends ValidateCallback<any>,
|
|
17
|
-
P extends ChatBrokerPlugin<any, any>,
|
|
18
|
-
PS extends Record<string, ReturnType<P['use']>>
|
|
19
|
-
> = {
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @zh 第一次聊天的時候觸發
|
|
23
|
-
* @en Triggered when chatting for the first time
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
start: {
|
|
27
|
-
id: string
|
|
28
|
-
data: ValidateCallbackOutputs<S>
|
|
29
|
-
plugins: {
|
|
30
|
-
[K in keyof PS]: {
|
|
31
|
-
send: (data: PS[K]['__receiveData']) => void
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
schema: {
|
|
35
|
-
input: S
|
|
36
|
-
output: O
|
|
37
|
-
}
|
|
38
|
-
messages: Message[]
|
|
39
|
-
setPreMessages: (messages: (Omit<Message, 'content'> & { content: string | string[] })[]) => void
|
|
40
|
-
changeMessages: (messages: Message[]) => void
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @zh 發送聊天訊息給機器人前觸發
|
|
45
|
-
* @en Triggered before sending chat message to bot
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
talkBefore: {
|
|
49
|
-
id: string
|
|
50
|
-
data: ValidateCallbackOutputs<S>
|
|
51
|
-
messages: Message[]
|
|
52
|
-
lastUserMessage: string
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @zh 當聊天機器人回傳資料的時候觸發
|
|
57
|
-
* @en Triggered when the chatbot returns data
|
|
58
|
-
*/
|
|
59
|
-
|
|
60
|
-
talkAfter: {
|
|
61
|
-
id: string
|
|
62
|
-
data: ValidateCallbackOutputs<S>
|
|
63
|
-
response: any
|
|
64
|
-
messages: Message[]
|
|
65
|
-
parseText: string
|
|
66
|
-
lastUserMessage: string
|
|
67
|
-
/**
|
|
68
|
-
* @zh 宣告解析失敗
|
|
69
|
-
* @en Declare parsing failure
|
|
70
|
-
*/
|
|
71
|
-
parseFail: (error: any) => void
|
|
72
|
-
changeParseText: (text: string) => void
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* @zh 當回傳資料符合規格時觸發
|
|
77
|
-
* @en Triggered when the returned data meets the specifications
|
|
78
|
-
*/
|
|
79
|
-
|
|
80
|
-
succeeded: {
|
|
81
|
-
id: string
|
|
82
|
-
output: ValidateCallbackOutputs<O>
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @zh 當回傳資料不符合規格,或是解析錯誤時觸發
|
|
87
|
-
* @en Triggered when the returned data does not meet the specifications or parsing errors
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
parseFailed: {
|
|
91
|
-
id: string
|
|
92
|
-
error: any
|
|
93
|
-
retry: () => void
|
|
94
|
-
count: number
|
|
95
|
-
response: any
|
|
96
|
-
parserFails: { name: string, error: any }[]
|
|
97
|
-
messages: Message[]
|
|
98
|
-
lastUserMessage: string
|
|
99
|
-
changeMessages: (messages: Message[]) => void
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* @zh 不論成功失敗,執行結束的時候會執行。
|
|
104
|
-
* @en It will be executed when the execution is completed, regardless of success or failure.
|
|
105
|
-
*/
|
|
106
|
-
|
|
107
|
-
done: {
|
|
108
|
-
id: string
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
type RequestContext = {
|
|
113
|
-
count: number
|
|
114
|
-
isRetry: boolean
|
|
115
|
-
onCancel: (cb: () => void) => void
|
|
116
|
-
schema: {
|
|
117
|
-
input: any
|
|
118
|
-
output: any
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export type Params<
|
|
123
|
-
S extends ValidateCallback<any>,
|
|
124
|
-
O extends ValidateCallback<any>,
|
|
125
|
-
C extends Record<string, any>,
|
|
126
|
-
P extends ChatBrokerPlugin<any, any>,
|
|
127
|
-
PS extends Record<string, ReturnType<P['use']>>
|
|
128
|
-
> = Omit<TranslatorParams<S, O>, 'parsers'> & {
|
|
129
|
-
name?: string
|
|
130
|
-
plugins?: PS | (() => PS)
|
|
131
|
-
request: (messages: Message[], context: RequestContext) => Promise<string>
|
|
132
|
-
install?: (context: {
|
|
133
|
-
log: Log
|
|
134
|
-
attach: Hook<C>['attach']
|
|
135
|
-
attachAfter: Hook<C>['attachAfter']
|
|
136
|
-
translator: Translator<S, O>
|
|
137
|
-
}) => void
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export class ChatBroker<
|
|
141
|
-
S extends ValidateCallback<any>,
|
|
142
|
-
O extends ValidateCallback<any>,
|
|
143
|
-
P extends ChatBrokerPlugin<any, any>,
|
|
144
|
-
PS extends Record<string, ReturnType<P['use']>>,
|
|
145
|
-
C extends ChatBrokerHooks<S, O, P, PS> = ChatBrokerHooks<S, O, P, PS>
|
|
146
|
-
> {
|
|
147
|
-
protected __hookType!: C
|
|
148
|
-
protected log: Log
|
|
149
|
-
protected hook = new Hook<C>()
|
|
150
|
-
protected params: Params<S, O, C, P, PS>
|
|
151
|
-
protected plugins = {} as PS
|
|
152
|
-
protected installed = false
|
|
153
|
-
protected translator: Translator<S, O>
|
|
154
|
-
protected event = new Event<{
|
|
155
|
-
cancel: {
|
|
156
|
-
requestId: string
|
|
157
|
-
}
|
|
158
|
-
cancelAll: any
|
|
159
|
-
}>()
|
|
160
|
-
|
|
161
|
-
constructor(params: Params<S, O, C, P, PS>) {
|
|
162
|
-
this.log = new Log(params.name ?? 'no name')
|
|
163
|
-
this.params = params
|
|
164
|
-
this.translator = new Translator({
|
|
165
|
-
...params,
|
|
166
|
-
parsers: [
|
|
167
|
-
TextParser.JsonMessage()
|
|
168
|
-
]
|
|
169
|
-
})
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
protected _install(): any {
|
|
173
|
-
if (this.installed === false) {
|
|
174
|
-
this.installed = true
|
|
175
|
-
const context = {
|
|
176
|
-
log: this.log,
|
|
177
|
-
attach: this.hook.attach.bind(this.hook),
|
|
178
|
-
attachAfter: this.hook.attachAfter.bind(this.hook),
|
|
179
|
-
translator: this.translator
|
|
180
|
-
}
|
|
181
|
-
if (this.params.plugins) {
|
|
182
|
-
this.plugins = typeof this.params.plugins === 'function' ? this.params.plugins() : this.params.plugins
|
|
183
|
-
for (let key in this.plugins) {
|
|
184
|
-
this.plugins[key].instance._params.onInstall({
|
|
185
|
-
...context,
|
|
186
|
-
params: this.plugins[key].params,
|
|
187
|
-
receive: this.plugins[key].receive
|
|
188
|
-
})
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
this.params.install?.(context)
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
async cancel(requestId?: string) {
|
|
196
|
-
if (requestId) {
|
|
197
|
-
this.event.emit('cancel', {
|
|
198
|
-
requestId
|
|
199
|
-
})
|
|
200
|
-
} else {
|
|
201
|
-
this.event.emit('cancelAll', {})
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
requestWithId<T extends Translator<S, O>>(data: T['__schemeType']): {
|
|
206
|
-
id: string
|
|
207
|
-
request: Promise<T['__outputType']>
|
|
208
|
-
} {
|
|
209
|
-
this._install()
|
|
210
|
-
let id = flow.createUuid()
|
|
211
|
-
let waitCancel = null as (() => void) | null
|
|
212
|
-
let isCancel = false
|
|
213
|
-
let isSending = false
|
|
214
|
-
|
|
215
|
-
// =================
|
|
216
|
-
//
|
|
217
|
-
// event
|
|
218
|
-
//
|
|
219
|
-
|
|
220
|
-
let listeners = [
|
|
221
|
-
this.event.on('cancel', ({ requestId }) => {
|
|
222
|
-
if (requestId === id) {
|
|
223
|
-
cancelTrigger()
|
|
224
|
-
}
|
|
225
|
-
}),
|
|
226
|
-
this.event.on('cancelAll', () => {
|
|
227
|
-
cancelTrigger()
|
|
228
|
-
})
|
|
229
|
-
]
|
|
230
|
-
let eventOff = () => listeners.forEach(e => e.off())
|
|
231
|
-
let cancelTrigger = () => {
|
|
232
|
-
if (isCancel === false) {
|
|
233
|
-
if (isSending && waitCancel) {
|
|
234
|
-
waitCancel()
|
|
235
|
-
}
|
|
236
|
-
isCancel = true
|
|
237
|
-
eventOff()
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
let onCancel = (cb: () => void) => {
|
|
241
|
-
waitCancel = cb
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// =================
|
|
245
|
-
//
|
|
246
|
-
// main
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
let request = async() => {
|
|
250
|
-
let schema = this.translator.getValidate()
|
|
251
|
-
let output: any = null
|
|
252
|
-
let plugins = {} as any
|
|
253
|
-
let question = await this.translator.compile(data, {
|
|
254
|
-
schema
|
|
255
|
-
})
|
|
256
|
-
let messages: Message[] = [
|
|
257
|
-
{
|
|
258
|
-
role: 'user',
|
|
259
|
-
content: question.prompt
|
|
260
|
-
}
|
|
261
|
-
]
|
|
262
|
-
for (let key in this.plugins) {
|
|
263
|
-
plugins[key] = {
|
|
264
|
-
send: (data: any) => this.plugins[key].send({
|
|
265
|
-
id,
|
|
266
|
-
data
|
|
267
|
-
})
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
await this.hook.notify('start', {
|
|
271
|
-
id,
|
|
272
|
-
data,
|
|
273
|
-
schema,
|
|
274
|
-
plugins,
|
|
275
|
-
messages,
|
|
276
|
-
setPreMessages: ms => {
|
|
277
|
-
const newMessage = ms.map(e => {
|
|
278
|
-
return {
|
|
279
|
-
...e,
|
|
280
|
-
content: Array.isArray(e.content) ? e.content.join('\n') : e.content
|
|
281
|
-
}
|
|
282
|
-
})
|
|
283
|
-
messages = [
|
|
284
|
-
...newMessage,
|
|
285
|
-
{
|
|
286
|
-
role: 'user',
|
|
287
|
-
content: question.prompt
|
|
288
|
-
}
|
|
289
|
-
]
|
|
290
|
-
},
|
|
291
|
-
changeMessages: ms => {
|
|
292
|
-
messages = ms
|
|
293
|
-
}
|
|
294
|
-
})
|
|
295
|
-
await flow.asyncWhile(async ({ count, doBreak }) => {
|
|
296
|
-
if (count >= 10) {
|
|
297
|
-
return doBreak()
|
|
298
|
-
}
|
|
299
|
-
let response = ''
|
|
300
|
-
let parseText = ''
|
|
301
|
-
let retryFlag = false
|
|
302
|
-
let lastUserMessage = messages.filter(e => e.role === 'user').slice(-1)[0]?.content || ''
|
|
303
|
-
try {
|
|
304
|
-
await this.hook.notify('talkBefore', {
|
|
305
|
-
id,
|
|
306
|
-
data,
|
|
307
|
-
messages,
|
|
308
|
-
lastUserMessage
|
|
309
|
-
})
|
|
310
|
-
const sender = this.params.request(messages, {
|
|
311
|
-
count,
|
|
312
|
-
schema,
|
|
313
|
-
onCancel,
|
|
314
|
-
isRetry: retryFlag
|
|
315
|
-
})
|
|
316
|
-
if (isCancel) {
|
|
317
|
-
if (waitCancel) {
|
|
318
|
-
waitCancel()
|
|
319
|
-
}
|
|
320
|
-
} else {
|
|
321
|
-
try {
|
|
322
|
-
isSending = true
|
|
323
|
-
response = await sender
|
|
324
|
-
parseText = response
|
|
325
|
-
} finally {
|
|
326
|
-
isSending = false
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
if (isCancel === false) {
|
|
330
|
-
await this.hook.notify('talkAfter', {
|
|
331
|
-
id,
|
|
332
|
-
data,
|
|
333
|
-
response,
|
|
334
|
-
messages,
|
|
335
|
-
parseText,
|
|
336
|
-
lastUserMessage,
|
|
337
|
-
parseFail: (error) => {
|
|
338
|
-
throw new ParserError(error, [])
|
|
339
|
-
},
|
|
340
|
-
changeParseText: text => {
|
|
341
|
-
parseText = text
|
|
342
|
-
}
|
|
343
|
-
})
|
|
344
|
-
output = (await this.translator.parse(parseText)).output
|
|
345
|
-
await this.hook.notify('succeeded', {
|
|
346
|
-
id,
|
|
347
|
-
output
|
|
348
|
-
})
|
|
349
|
-
}
|
|
350
|
-
await this.hook.notify('done', { id })
|
|
351
|
-
doBreak()
|
|
352
|
-
} catch (error: any) {
|
|
353
|
-
// 如果解析錯誤,可以選擇是否重新解讀
|
|
354
|
-
if (error instanceof ParserError) {
|
|
355
|
-
await this.hook.notify('parseFailed', {
|
|
356
|
-
id,
|
|
357
|
-
error: error.error,
|
|
358
|
-
count,
|
|
359
|
-
response,
|
|
360
|
-
messages,
|
|
361
|
-
lastUserMessage,
|
|
362
|
-
parserFails: error.parserFails,
|
|
363
|
-
retry: () => {
|
|
364
|
-
retryFlag = true
|
|
365
|
-
},
|
|
366
|
-
changeMessages: ms => {
|
|
367
|
-
messages = ms
|
|
368
|
-
}
|
|
369
|
-
})
|
|
370
|
-
if (retryFlag === false) {
|
|
371
|
-
await this.hook.notify('done', { id })
|
|
372
|
-
throw error
|
|
373
|
-
}
|
|
374
|
-
} else {
|
|
375
|
-
await this.hook.notify('done', { id })
|
|
376
|
-
throw error
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
})
|
|
380
|
-
return output
|
|
381
|
-
}
|
|
382
|
-
const send = async() => {
|
|
383
|
-
try {
|
|
384
|
-
const result = await request()
|
|
385
|
-
return result
|
|
386
|
-
} finally {
|
|
387
|
-
eventOff()
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
return {
|
|
391
|
-
id,
|
|
392
|
-
request: send()
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
* @zh 將請求發出至聊天機器人。
|
|
398
|
-
* @en Send request to chatbot.
|
|
399
|
-
*/
|
|
400
|
-
|
|
401
|
-
async request<T extends Translator<S, O>>(data: T['__schemeType']): Promise<T['__outputType']> {
|
|
402
|
-
const { request } = this.requestWithId(data)
|
|
403
|
-
const output = await request
|
|
404
|
-
return output
|
|
405
|
-
}
|
|
406
|
-
}
|
package/lib/core/parser.ts
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import JSON5 from 'json5'
|
|
2
|
-
|
|
3
|
-
type TextParserParams = {
|
|
4
|
-
/**
|
|
5
|
-
* @zh 解讀器名字。
|
|
6
|
-
* @en The name of the parser.
|
|
7
|
-
*/
|
|
8
|
-
name: string
|
|
9
|
-
/**
|
|
10
|
-
* @zh 解讀文本。
|
|
11
|
-
* @en Read the text.
|
|
12
|
-
*/
|
|
13
|
-
handler: (text: string) => Promise<any>
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export class TextParser {
|
|
17
|
-
private params: TextParserParams
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @zh 盡可能將文字內的 json 解讀出來。
|
|
21
|
-
* @en Try to read the json in the text as much as possible.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
static JsonMessage() {
|
|
25
|
-
return new TextParser({
|
|
26
|
-
name: 'JsonMessage',
|
|
27
|
-
handler: async (text) => {
|
|
28
|
-
try {
|
|
29
|
-
const result = JSON.parse(text)
|
|
30
|
-
return result
|
|
31
|
-
} catch (error) {
|
|
32
|
-
const jsonRegex = /{(?:[^{}]|(?:{[^{}]*}))*}/
|
|
33
|
-
const matchedText = text.match(jsonRegex)?.[0] || ''
|
|
34
|
-
return JSON5.parse(matchedText)
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
constructor(params: TextParserParams) {
|
|
41
|
-
this.params = params
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @zh 解讀器名字。
|
|
46
|
-
* @en The name of the parser.
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
get name() {
|
|
50
|
-
return this.params.name
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* @zh 解讀文本。
|
|
55
|
-
* @en Read the text.
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
async read(text: string) {
|
|
59
|
-
const result = await this.params.handler(text)
|
|
60
|
-
return result
|
|
61
|
-
}
|
|
62
|
-
}
|
package/lib/core/plugin.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { Translator } from './translator'
|
|
2
|
-
import { ChatBrokerHooks } from '../broker/chat'
|
|
3
|
-
import { Log, Hook, Event } from 'power-helper'
|
|
4
|
-
import { ValidateCallback, ValidateCallbackOutputs } from '../utils/validate'
|
|
5
|
-
|
|
6
|
-
type BrokerHooks = ChatBrokerHooks<any, any, any, any>
|
|
7
|
-
type BrokerPluginParams<
|
|
8
|
-
T extends ValidateCallback<any>,
|
|
9
|
-
R extends ValidateCallback<any>
|
|
10
|
-
> = {
|
|
11
|
-
name: string
|
|
12
|
-
params: T
|
|
13
|
-
receiveData: R
|
|
14
|
-
onInstall: (context: {
|
|
15
|
-
log: Log
|
|
16
|
-
params: ValidateCallbackOutputs<T>
|
|
17
|
-
attach: Hook<BrokerHooks>['attach']
|
|
18
|
-
attachAfter: Hook<BrokerHooks>['attachAfter']
|
|
19
|
-
translator: Translator<any, any>
|
|
20
|
-
receive: (callback: (params: {
|
|
21
|
-
id: string
|
|
22
|
-
data: ValidateCallbackOutputs<R>
|
|
23
|
-
}) => void) => void
|
|
24
|
-
}) => void
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export class ChatBrokerPlugin<
|
|
28
|
-
T extends ValidateCallback<any>,
|
|
29
|
-
R extends ValidateCallback<any>
|
|
30
|
-
> {
|
|
31
|
-
_event = new Event()
|
|
32
|
-
_params: BrokerPluginParams<T, R>
|
|
33
|
-
constructor(params: BrokerPluginParams<T, R>) {
|
|
34
|
-
this._params = params
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
use(params: ValidateCallbackOutputs<T>) {
|
|
38
|
-
return {
|
|
39
|
-
instance: this as any,
|
|
40
|
-
params,
|
|
41
|
-
send: (data: ValidateCallbackOutputs<R>) => { this._event.emit('receive', data) },
|
|
42
|
-
receive: (callback: any) => { this._event.on('receive', callback) },
|
|
43
|
-
__receiveData: null as unknown as ValidateCallbackOutputs<R>
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
package/lib/core/translator.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { TextParser } from './parser'
|
|
2
|
-
import { validate, ValidateCallback, ValidateCallbackOutputs } from '../utils/validate'
|
|
3
|
-
import { ParserError } from '../utils/error'
|
|
4
|
-
|
|
5
|
-
export type TranslatorParams<
|
|
6
|
-
S extends ValidateCallback<any>,
|
|
7
|
-
O extends ValidateCallback<any>
|
|
8
|
-
> = {
|
|
9
|
-
/**
|
|
10
|
-
* @zh 輸入的資料格式。
|
|
11
|
-
* @en The input data format.
|
|
12
|
-
*/
|
|
13
|
-
input: S
|
|
14
|
-
/**
|
|
15
|
-
* @zh 輸出的資料格式。
|
|
16
|
-
* @en The output data format.
|
|
17
|
-
*/
|
|
18
|
-
output: O
|
|
19
|
-
/**
|
|
20
|
-
* @zh 註冊解讀文字的解析器。
|
|
21
|
-
* @en Register the parser to interpret the text.
|
|
22
|
-
*/
|
|
23
|
-
parsers: TextParser[]
|
|
24
|
-
/**
|
|
25
|
-
* @zh 組合輸入資料成為提示文字。
|
|
26
|
-
* @en Combine the input data into a prompt.
|
|
27
|
-
*/
|
|
28
|
-
question: (data: ValidateCallbackOutputs<S>, context: {
|
|
29
|
-
schema: {
|
|
30
|
-
input: S
|
|
31
|
-
output: O
|
|
32
|
-
}
|
|
33
|
-
}) => Promise<string | string[]>
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export class Translator<
|
|
37
|
-
S extends ValidateCallback<any>,
|
|
38
|
-
O extends ValidateCallback<any>
|
|
39
|
-
> {
|
|
40
|
-
private params: TranslatorParams<S, O>
|
|
41
|
-
|
|
42
|
-
constructor(params: TranslatorParams<S, O>) {
|
|
43
|
-
this.params = params
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
get __schemeType(): ValidateCallbackOutputs<S> {
|
|
47
|
-
return null as any
|
|
48
|
-
}
|
|
49
|
-
get __outputType(): ValidateCallbackOutputs<O> {
|
|
50
|
-
return null as any
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* @zh 組合輸入資料成為提示文字。
|
|
55
|
-
* @en Combine the input data into a prompt.
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
async compile(data: ValidateCallbackOutputs<S>, context: {
|
|
59
|
-
schema: {
|
|
60
|
-
input: S
|
|
61
|
-
output: O
|
|
62
|
-
}
|
|
63
|
-
}) {
|
|
64
|
-
const scheme = validate(data, this.params.input)
|
|
65
|
-
const prompt = await this.params.question(scheme, context)
|
|
66
|
-
return {
|
|
67
|
-
scheme,
|
|
68
|
-
prompt: Array.isArray(prompt) ? prompt.join('\n') : prompt
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
getValidate() {
|
|
73
|
-
return {
|
|
74
|
-
input: this.params.input,
|
|
75
|
-
output: this.params.output
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* @zh 將文字轉換成序列化資料。
|
|
81
|
-
* @en Convert text to serialized data.
|
|
82
|
-
*/
|
|
83
|
-
|
|
84
|
-
async parse(text: string) {
|
|
85
|
-
let result: any = undefined
|
|
86
|
-
let parserName = ''
|
|
87
|
-
let parserFails: { name: string, error: any }[] = []
|
|
88
|
-
for (let parse of this.params.parsers) {
|
|
89
|
-
try {
|
|
90
|
-
result = await parse.read(text)
|
|
91
|
-
parserName = parse.name
|
|
92
|
-
} catch (error) {
|
|
93
|
-
result = undefined
|
|
94
|
-
parserFails.push({
|
|
95
|
-
name: parse.name,
|
|
96
|
-
error
|
|
97
|
-
})
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
try {
|
|
101
|
-
let output = validate(result, this.params.output)
|
|
102
|
-
return {
|
|
103
|
-
output,
|
|
104
|
-
parserName,
|
|
105
|
-
parserFails
|
|
106
|
-
}
|
|
107
|
-
} catch (error) {
|
|
108
|
-
throw new ParserError(error, parserFails)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
package/lib/index.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
export * as plugins from './plugins'
|
|
2
|
-
export * as templates from './templates'
|
|
3
|
-
export { validateToJsonSchema, defineYupSchema } from './utils/validate'
|
|
4
|
-
export { OpenAI } from './service/openai'
|
|
5
|
-
export { Llama3Cpp } from './service/llama3.cpp'
|
|
6
|
-
export { TextParser } from './core/parser'
|
|
7
|
-
export { ChatGPTMessage } from './service/openai/chat'
|
|
8
|
-
export { ChatBroker } from './broker/chat'
|
|
9
|
-
export { ChatBrokerPlugin } from './core/plugin'
|
|
10
|
-
export { Translator, TranslatorParams } from './core/translator'
|
|
11
|
-
|
|
12
|
-
import * as plugins from './plugins'
|
|
13
|
-
import * as templates from './templates'
|
|
14
|
-
import { OpenAI } from './service/openai'
|
|
15
|
-
import { Llama3Cpp } from './service/llama3.cpp'
|
|
16
|
-
import { Translator } from './core/translator'
|
|
17
|
-
import { TextParser } from './core/parser'
|
|
18
|
-
import { ChatBroker } from './broker/chat'
|
|
19
|
-
import { ChatBrokerPlugin } from './core/plugin'
|
|
20
|
-
import { validateToJsonSchema, defineYupSchema } from './utils/validate'
|
|
21
|
-
|
|
22
|
-
export const ctod = {
|
|
23
|
-
OpenAI,
|
|
24
|
-
Llama3Cpp,
|
|
25
|
-
plugins,
|
|
26
|
-
templates,
|
|
27
|
-
ChatBroker,
|
|
28
|
-
Translator,
|
|
29
|
-
TextParser,
|
|
30
|
-
ChatBrokerPlugin,
|
|
31
|
-
defineYupSchema,
|
|
32
|
-
validateToJsonSchema
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
module.exports = ctod
|
|
36
|
-
module.exports.ctod = ctod
|
|
37
|
-
|
|
38
|
-
export default ctod
|
package/lib/plugins/index.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import Retry from './retry'
|
|
2
|
-
import PrintLog from './print-log'
|
|
3
|
-
import Limiter from './limiter'
|
|
4
|
-
import Role from './role'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @zh 一個基於印出 log 的 plugin。
|
|
8
|
-
* @en A plugin based on printing log.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export const PrintLogPlugin = PrintLog
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @zh 當解析失敗時,會自動重試的對話。
|
|
15
|
-
* @en A conversation that will automatically retry when parsing fails.
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
export const RetryPlugin = Retry
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @zh 限制使用流量,這個 plugin 可以有效讓所有對話不會再限制內同時發送,可用於在開發過程中遭遇伺服器因頻率過高而阻擋請求。
|
|
22
|
-
* @en Limit the use of traffic. This plugin can effectively prevent all conversations from being sent at the same time within the limit, and can be used when the server blocks requests due to high frequency during development.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
export const LimiterPlugin = Limiter.plugin
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @zh 排程系統將全域託管,有什麼必要設定可以來更動它的狀態,例如:關閉排程。
|
|
29
|
-
* @en The scheduling system will be globally hosted. What is necessary to set can come to change its status, for example: close the schedule.
|
|
30
|
-
*/
|
|
31
|
-
export const LimiterPluginGlobState = Limiter
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @zh 設定角色扮演。
|
|
35
|
-
* @en Set role play.
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
export const RolePlugin = Role
|