@aidejs/core 0.1.0-alpha.2 → 0.1.0-beta.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/README.md +32 -11
- package/package.json +1 -1
- package/src/Memory.js +41 -0
- package/src/{utils/OpenAI.js → OpenAI.js} +1 -1
- package/src/Tool.js +9 -1
- package/src/index.js +94 -33
- package/src/utils.js +17 -0
- package/types/index.d.ts +6 -4
- package/src/utils/toJSON.js +0 -8
package/README.md
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
|
-
<img src="
|
|
1
|
+
<img src="https://NN-Studio.github.io/Aidejs/images/logo.png" />
|
|
2
2
|
|
|
3
3
|
# [Aidejs](https://github.com/NN-Studio/Aidejs)
|
|
4
4
|
一个用于构建人工智能代理的JavaScript框架,它提供了一组工具和库,使创建智能应用程序变得轻松和高效
|
|
5
5
|
|
|
6
|
-
## 功能列表
|
|
7
|
-
|
|
8
|
-
通过类似拼积木的方式,你可以轻松地组合各个模块完成个性化的 AI 应用开发。
|
|
9
|
-
|
|
10
|
-
下面是可用模块:
|
|
11
|
-
|
|
12
6
|
<p>
|
|
13
7
|
<a href="https://github.com/NN-Studio/Aidejs/issues">
|
|
14
8
|
<img src="https://img.shields.io/github/issues/NN-Studio/Aidejs" alt="issue">
|
|
@@ -19,29 +13,56 @@
|
|
|
19
13
|
<a href="https://github.com/NN-Studio/Aidejs">
|
|
20
14
|
<img src="https://img.shields.io/github/forks/NN-Studio/Aidejs" alt="forks">
|
|
21
15
|
</a>
|
|
16
|
+
<a href="https://gitee.com/NN-Studio/Aidejs" target='_blank'>
|
|
17
|
+
<img alt="Gitee repo stars" src="https://gitee.com/NN-Studio/Aidejs/badge/star.svg">
|
|
18
|
+
</a>
|
|
19
|
+
<a href="https://gitee.com/NN-Studio/Aidejs">
|
|
20
|
+
<img src="https://gitee.com/NN-Studio/Aidejs/badge/fork.svg" alt="forks">
|
|
21
|
+
</a>
|
|
22
22
|
</p>
|
|
23
23
|
|
|
24
|
+
## 功能列表
|
|
25
|
+
|
|
26
|
+
通过类似拼积木的方式,你可以轻松地组合各个模块完成个性化的 AI 应用开发。
|
|
27
|
+
|
|
28
|
+
下面是可用模块:
|
|
29
|
+
|
|
24
30
|
<table>
|
|
25
31
|
<thead>
|
|
26
32
|
<tr>
|
|
27
33
|
<td>名称</td>
|
|
28
34
|
<td>简介</td>
|
|
29
|
-
<td
|
|
35
|
+
<td>下周统计</td>
|
|
36
|
+
<td>最新版本</td>
|
|
30
37
|
</tr>
|
|
31
38
|
</thead>
|
|
32
39
|
<tbody>
|
|
33
40
|
<tr>
|
|
34
41
|
<td>@aidejs/core</td>
|
|
35
|
-
<td
|
|
42
|
+
<td>必选项,核心库,提供了最核心的LLM交互功能和插件系统</td>
|
|
36
43
|
<td>
|
|
37
|
-
<a href="https://
|
|
44
|
+
<a href="https://zxl20070701.github.io/toolbox/#/npm-download?packages=@aidejs/core&interval=7">
|
|
45
|
+
<img src="https://img.shields.io/npm/dm/@aidejs/core.svg" alt="downloads">
|
|
46
|
+
</a>
|
|
47
|
+
</td>
|
|
48
|
+
<td>
|
|
49
|
+
<a href="https://www.npmjs.com/package/@aidejs/core">
|
|
50
|
+
<img src="https://img.shields.io/npm/v/@aidejs/core.svg" alt="npm">
|
|
51
|
+
</a>
|
|
38
52
|
</td>
|
|
39
53
|
</tr>
|
|
40
54
|
<tr>
|
|
41
55
|
<td>@aidejs/tools</td>
|
|
42
56
|
<td>非必选,工具库,提供了各种实用的工具函数</td>
|
|
43
57
|
<td>
|
|
44
|
-
<a href="https://
|
|
58
|
+
<a href="https://zxl20070701.github.io/toolbox/#/npm-download?packages=@aidejs/tools&interval=7">
|
|
59
|
+
<img src="https://img.shields.io/npm/dm/@aidejs/tools.svg" alt="downloads">
|
|
60
|
+
</a>
|
|
61
|
+
</td>
|
|
62
|
+
<td>
|
|
63
|
+
<a href="https://www.npmjs.com/package/@aidejs/tools">
|
|
64
|
+
<img src="https://img.shields.io/npm/v/@aidejs/tools.svg" alt="npm">
|
|
65
|
+
</a>
|
|
45
66
|
</td>
|
|
46
67
|
</tr>
|
|
47
68
|
</tbody>
|
package/package.json
CHANGED
package/src/Memory.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module.exports = class Memory {
|
|
2
|
+
|
|
3
|
+
constructor(messages = []) {
|
|
4
|
+
this.messages = messages;
|
|
5
|
+
this.message_value = ""; // 当前流缓存值
|
|
6
|
+
this.message_type = ""; // 当前流类型
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// 直接添加一次新信息
|
|
10
|
+
// 前置的流会关闭,开始一次新的待整理流
|
|
11
|
+
push(value) {
|
|
12
|
+
this.generate("");
|
|
13
|
+
this.messages.push(value);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// 完结或整理一次流信息
|
|
17
|
+
generate(newType) {
|
|
18
|
+
if (this.message_value) {
|
|
19
|
+
this.messages.push({
|
|
20
|
+
role: this.message_type,
|
|
21
|
+
content: this.message_value
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.message_type = newType;
|
|
26
|
+
this.message_value = "";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 输入一个词元的助手信息
|
|
30
|
+
assistant(lexeme) {
|
|
31
|
+
if (this.message_type !== "assistant") this.generate("assistant");
|
|
32
|
+
this.message_value += lexeme;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 获取记忆内容
|
|
36
|
+
valueOf() {
|
|
37
|
+
this.generate("");
|
|
38
|
+
return this.messages;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
}
|
package/src/Tool.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const { debug } = require("./utils");
|
|
2
|
+
|
|
1
3
|
module.exports = class Tool {
|
|
2
4
|
|
|
3
5
|
constructor() {
|
|
@@ -26,7 +28,13 @@ module.exports = class Tool {
|
|
|
26
28
|
if (!this.tools[name]) {
|
|
27
29
|
throw new Error(`工具${name}不存在`);
|
|
28
30
|
}
|
|
29
|
-
|
|
31
|
+
let value = this.tools[name].valueOf.call(aidejs, args);
|
|
32
|
+
if (aidejs.options.debug) {
|
|
33
|
+
debug("工具调用", {
|
|
34
|
+
name, args, value
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return value;
|
|
30
38
|
}
|
|
31
39
|
|
|
32
40
|
};
|
package/src/index.js
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
const { initOption } = require("oipage/nodejs/option/index");
|
|
2
|
-
const OpenAI = require("./
|
|
3
|
-
const Tool = require("./Tool
|
|
2
|
+
const OpenAI = require("./OpenAI");
|
|
3
|
+
const Tool = require("./Tool");
|
|
4
|
+
const Memory = require("./Memory");
|
|
5
|
+
const { debug } = require("./utils");
|
|
4
6
|
|
|
5
7
|
module.exports = class Aidejs {
|
|
6
8
|
|
|
7
|
-
// 工具管理对象
|
|
8
|
-
static
|
|
9
|
+
static tool = new Tool(); // 工具管理对象
|
|
10
|
+
static messages = [];
|
|
9
11
|
|
|
10
12
|
constructor(options = {}) {
|
|
11
13
|
this.options = initOption(options, {
|
|
14
|
+
debug: false,
|
|
12
15
|
model: "",
|
|
13
16
|
url: "http://localhost:11434/v1",
|
|
14
|
-
apiKey: ""
|
|
17
|
+
apiKey: "",
|
|
18
|
+
messages: []
|
|
15
19
|
});
|
|
16
20
|
|
|
17
21
|
if (!this.options.model) {
|
|
@@ -33,22 +37,15 @@ module.exports = class Aidejs {
|
|
|
33
37
|
|
|
34
38
|
// 执行任务
|
|
35
39
|
task(message, logback, inputback, thinkback) {
|
|
36
|
-
let _this = this;
|
|
40
|
+
let _this = this, toolCalls = false;
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
let resetLastIndex = () => {
|
|
41
|
-
messages.push({
|
|
42
|
-
role: "assistant",
|
|
43
|
-
content: ""
|
|
44
|
-
});
|
|
45
|
-
lastIndex = messages.length - 1;
|
|
46
|
-
};
|
|
42
|
+
// 记忆管理对象
|
|
43
|
+
let memory = new Memory([...Aidejs.messages, ..._this.options.messages]);
|
|
47
44
|
|
|
48
45
|
let runInputback = () => {
|
|
49
46
|
if (inputback) {
|
|
50
47
|
inputback().then(message => {
|
|
51
|
-
|
|
48
|
+
memory.push({
|
|
52
49
|
role: "user",
|
|
53
50
|
content: message
|
|
54
51
|
});
|
|
@@ -62,15 +59,80 @@ module.exports = class Aidejs {
|
|
|
62
59
|
};
|
|
63
60
|
|
|
64
61
|
let runChat = () => {
|
|
65
|
-
|
|
62
|
+
let tools = Aidejs.tool.valueOf();
|
|
63
|
+
|
|
64
|
+
if (_this.options.debug) {
|
|
65
|
+
debug("OpenAI messages", memory.valueOf());
|
|
66
|
+
debug("OpenAI tools", tools.map(function (funItem) {
|
|
67
|
+
return funItem.function.name + " " + funItem.function.description;
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
OpenAI(_this.options.url + "/chat/completions", {
|
|
66
72
|
header: {
|
|
67
|
-
Authorization: `Bearer ${
|
|
73
|
+
Authorization: `Bearer ${_this.options.apiKey}`
|
|
68
74
|
},
|
|
69
75
|
params: {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
|
|
77
|
+
// 必需,模型ID,也就是你选择的具体哪个模型
|
|
78
|
+
model: _this.options.model,
|
|
79
|
+
|
|
80
|
+
// 必需,提供的array类型的消息列表,包含从头到尾的对话历史
|
|
81
|
+
// 比如值是一个数组,每个条目可以是下列类型之一:
|
|
82
|
+
// (所有的类型其实都应该是一个json对象,下面列出的都是其包含的字段)
|
|
83
|
+
// 1、System message
|
|
84
|
+
// content:必须提供的string类型,表示system的消息内容
|
|
85
|
+
// role:必须提供的string类型,表示消息作者的角色,对于system message应该是"system"
|
|
86
|
+
// name:可选的string类型,表示对话参与者的名称
|
|
87
|
+
// 2、User message
|
|
88
|
+
// content:必须提供的string或array类型,二选一,表示user的消息内容
|
|
89
|
+
// 为string类型时,表示消息的文本内容
|
|
90
|
+
// 为array类型时,用来包含多个内容部分的数组,而此数组的每个条目都是一个json对象,可以分别是如下类型之一
|
|
91
|
+
// 1)文本
|
|
92
|
+
// type:必须提供的string类型,表示内容部分的类型,一般是“text”
|
|
93
|
+
// text:必须提供的string类型,文字内容
|
|
94
|
+
// 2)图片
|
|
95
|
+
// type:必须提供的string类型,表示内容部分的类型,一般是"image_url"
|
|
96
|
+
// image_url:必须提供的string类型,图像的 URL 或 Base64 编码的图像数据
|
|
97
|
+
// role:必须提供的string类型,表示消息作者的角色,对于user message应该是"user"
|
|
98
|
+
// name:可选的string类型,表示对话参与者的名称
|
|
99
|
+
// 3、Assistant message(实际代码就是下面的choice.delta的值)
|
|
100
|
+
// content:必须提供(指定 tool_calls 时除外)的string类型,表示助手消息的内容
|
|
101
|
+
// role:必须提供的string类型,表示消息作者的角色,对于assistant message应该是"assistant"
|
|
102
|
+
// name:可选的string类型,表示对话参与者的名称
|
|
103
|
+
// tool_calls:可选的array类型,大模型生成的工具调用,例如函数调用,用这里代码打印的例子:
|
|
104
|
+
// [
|
|
105
|
+
// {
|
|
106
|
+
// id: 'call_graj8v5e', // 必须提供,表示函数调用的id
|
|
107
|
+
// index: 0,
|
|
108
|
+
// type: 'function', // 必须提供,表示工具调用的类型(目前仅支持“function”类型)。
|
|
109
|
+
// function: {
|
|
110
|
+
// name: 'aidejs_disk_readPlain', // 必须提供,要调用的函数的名称
|
|
111
|
+
// arguments: '{"filepath":"./.mailmap"}' // 必须提供,表示调用函数所用的参数
|
|
112
|
+
// }
|
|
113
|
+
// }
|
|
114
|
+
// ]
|
|
115
|
+
// 4、Tool message
|
|
116
|
+
// 一个json对象,在用户根据assistant的tool_calls内容调用了某个函数后,
|
|
117
|
+
// 用户可能还需要再把函数调用结果反馈给大模型,让大模型根据函数调用结果给出最终的总结性的答复
|
|
118
|
+
// content:必须提供的string类型,表示工具消息的内容,一般是把函数调用的结果描述在这里
|
|
119
|
+
// role:必须提供的string类型,表示消息作者的角色,对于tool message应该是"tool"
|
|
120
|
+
// tool_call_id:必须提供的string类型,表示本次消息是对哪个函数调用的结果反馈
|
|
121
|
+
messages: memory.valueOf(),
|
|
122
|
+
|
|
123
|
+
// 用户可选的一个字段,是array类型,表示可供模型选择的一个工具列表
|
|
124
|
+
// 列表中最多支持 128 个tool
|
|
125
|
+
// 具体说明可以查看 /packages/tools/src/disk/readPlain.js
|
|
126
|
+
tools,
|
|
127
|
+
|
|
128
|
+
// 可选的bool值,如果设置了true,将会流式的返回消息
|
|
129
|
+
stream: true,
|
|
130
|
+
|
|
131
|
+
// softmax 函数中的除数,温度越低,生成的结果越确定,温度越高,生成的结果越随机
|
|
132
|
+
// temperature: 0.7,
|
|
133
|
+
|
|
134
|
+
// 类似的有这些策略:TopP、TopK、MinP,分别表示前若干个累积积累和、前K名、最低概率
|
|
135
|
+
// top_p: 0.8,
|
|
74
136
|
}
|
|
75
137
|
}, function (chunk) {
|
|
76
138
|
try {
|
|
@@ -83,11 +145,15 @@ module.exports = class Aidejs {
|
|
|
83
145
|
|
|
84
146
|
if (choice.delta.content) {
|
|
85
147
|
if (logback) logback(choice.delta.content);
|
|
148
|
+
memory.assistant(choice.delta.content);
|
|
86
149
|
} else if (choice.delta.reasoning) {
|
|
87
150
|
if (thinkback) thinkback(choice.delta.reasoning);
|
|
88
151
|
}
|
|
89
152
|
|
|
90
153
|
if (choice.delta.tool_calls) {
|
|
154
|
+
memory.push(choice.delta);
|
|
155
|
+
|
|
156
|
+
if (_this.options.debug) debug("tool_calls", choice.delta.tool_calls);
|
|
91
157
|
|
|
92
158
|
// 执行一次工具
|
|
93
159
|
let runTool = (toolIndex) => {
|
|
@@ -99,8 +165,9 @@ module.exports = class Aidejs {
|
|
|
99
165
|
let result = Aidejs.tool.invoke(_this, tool_call.function.name, JSON.parse(tool_call.function.arguments));
|
|
100
166
|
|
|
101
167
|
let toolback = function (value) {
|
|
102
|
-
|
|
168
|
+
memory.push({
|
|
103
169
|
role: "tool",
|
|
170
|
+
tool_call_id: tool_call.id,
|
|
104
171
|
tool_name: tool_call.function.name,
|
|
105
172
|
content: typeof value === "string" ? value : (JSON.stringify(value) + "")
|
|
106
173
|
});
|
|
@@ -111,7 +178,7 @@ module.exports = class Aidejs {
|
|
|
111
178
|
result.then(function (value) {
|
|
112
179
|
toolback(value);
|
|
113
180
|
}).catch(function (error) {
|
|
114
|
-
toolback(error
|
|
181
|
+
toolback(error || "失败");
|
|
115
182
|
});
|
|
116
183
|
} else {
|
|
117
184
|
toolback(result);
|
|
@@ -120,15 +187,13 @@ module.exports = class Aidejs {
|
|
|
120
187
|
};
|
|
121
188
|
runTool(0);
|
|
122
189
|
} else {
|
|
123
|
-
if (messages[lastIndex].role !== "assistant") resetLastIndex();
|
|
124
|
-
messages[lastIndex].content += choice.delta.content || "";
|
|
125
190
|
runChoice(choiceIndex + 1);
|
|
126
191
|
}
|
|
127
192
|
|
|
128
193
|
};
|
|
129
194
|
runChoice(0);
|
|
130
195
|
} catch (e) {
|
|
131
|
-
|
|
196
|
+
debug("处理智能体响应时发生错误", e);
|
|
132
197
|
}
|
|
133
198
|
}, function () {
|
|
134
199
|
if (toolCalls) {
|
|
@@ -138,16 +203,14 @@ module.exports = class Aidejs {
|
|
|
138
203
|
runInputback();
|
|
139
204
|
}
|
|
140
205
|
}, function (e) {
|
|
141
|
-
|
|
206
|
+
debug("对接LLM解答问题时发生错误", e);
|
|
142
207
|
toolCalls = false;
|
|
143
208
|
runInputback();
|
|
144
209
|
});
|
|
145
|
-
|
|
146
|
-
resetLastIndex();
|
|
147
210
|
};
|
|
148
211
|
|
|
149
212
|
if (message) {
|
|
150
|
-
|
|
213
|
+
memory.push({
|
|
151
214
|
role: "user",
|
|
152
215
|
content: message
|
|
153
216
|
});
|
|
@@ -155,8 +218,6 @@ module.exports = class Aidejs {
|
|
|
155
218
|
} else {
|
|
156
219
|
runInputback();
|
|
157
220
|
}
|
|
158
|
-
|
|
159
|
-
return this;
|
|
160
221
|
}
|
|
161
222
|
|
|
162
223
|
};
|
package/src/utils.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// 打印调试语句
|
|
2
|
+
exports.debug = function (name, content) {
|
|
3
|
+
console.log("\n\x1b[33m【" + name + "】 " + new Date().toString() + "\x1b[0m");
|
|
4
|
+
console.log(content);
|
|
5
|
+
console.log("\x1b[33m[DONE]\x1b[0m\n");
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// 字符串转JSON
|
|
9
|
+
// 适配LLM返回数据格式
|
|
10
|
+
exports.toJSON = function (value) {
|
|
11
|
+
try {
|
|
12
|
+
value = value.trim().replace(/data: \[DONE\]$/, "");
|
|
13
|
+
return JSON.parse(value);
|
|
14
|
+
} catch (e) {
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
};
|
package/types/index.d.ts
CHANGED
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
export default class Aidejs {
|
|
5
5
|
|
|
6
6
|
constructor(options: {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
debug?: boolean
|
|
8
|
+
model: string
|
|
9
|
+
url?: string
|
|
9
10
|
apiKey?: string
|
|
11
|
+
messages?: Array<any>
|
|
10
12
|
})
|
|
11
13
|
|
|
12
14
|
/**
|
|
@@ -14,7 +16,7 @@ export default class Aidejs {
|
|
|
14
16
|
* @param name
|
|
15
17
|
* @param value
|
|
16
18
|
*/
|
|
17
|
-
static registerTool(name: string, value: any):
|
|
19
|
+
static registerTool(name: string, value: any): Aidejs
|
|
18
20
|
|
|
19
21
|
/**
|
|
20
22
|
* 安装插件
|
|
@@ -26,6 +28,6 @@ export default class Aidejs {
|
|
|
26
28
|
* 执行任务
|
|
27
29
|
* @param message
|
|
28
30
|
*/
|
|
29
|
-
task(message
|
|
31
|
+
task(message?: string, logback?: (message: string) => void, inputback?: () => Promise<string>, thinkback?: (think: string) => void): void
|
|
30
32
|
|
|
31
33
|
}
|