@aidejs/core 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG +4 -0
- package/LICENSE +21 -0
- package/README.md +107 -0
- package/package.json +26 -0
- package/src/Tool.js +32 -0
- package/src/index.js +123 -0
- package/src/utils/OpenAI.js +41 -0
- package/src/utils/toJSON.js +8 -0
- package/types/index.d.ts +31 -0
package/CHANGELOG
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) zxl20070701 走一步,再走一步
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<img src="./docs/images/logo.png" />
|
|
2
|
+
|
|
3
|
+
# [Aidejs](https://github.com/NN-Studio/Aidejs)
|
|
4
|
+
一个用于构建人工智能代理的JavaScript框架,它提供了一组工具和库,使创建智能应用程序变得轻松和高效
|
|
5
|
+
|
|
6
|
+
## 功能列表
|
|
7
|
+
|
|
8
|
+
通过类似拼积木的方式,你可以轻松地组合各个模块完成个性化的 AI 应用开发。
|
|
9
|
+
|
|
10
|
+
下面是可用模块:
|
|
11
|
+
|
|
12
|
+
<p>
|
|
13
|
+
<a href="https://github.com/NN-Studio/Aidejs/issues">
|
|
14
|
+
<img src="https://img.shields.io/github/issues/NN-Studio/Aidejs" alt="issue">
|
|
15
|
+
</a>
|
|
16
|
+
<a href="https://github.com/NN-Studio/Aidejs" target='_blank'>
|
|
17
|
+
<img alt="GitHub repo stars" src="https://img.shields.io/github/stars/NN-Studio/Aidejs?style=social">
|
|
18
|
+
</a>
|
|
19
|
+
<a href="https://github.com/NN-Studio/Aidejs">
|
|
20
|
+
<img src="https://img.shields.io/github/forks/NN-Studio/Aidejs" alt="forks">
|
|
21
|
+
</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<table>
|
|
25
|
+
<thead>
|
|
26
|
+
<tr>
|
|
27
|
+
<td>名称</td>
|
|
28
|
+
<td>简介</td>
|
|
29
|
+
<td>地址</td>
|
|
30
|
+
</tr>
|
|
31
|
+
</thead>
|
|
32
|
+
<tbody>
|
|
33
|
+
<tr>
|
|
34
|
+
<td>@aidejs/core</td>
|
|
35
|
+
<td>必选项,基础库,提供了最核心的LLM交互功能和插件系统</td>
|
|
36
|
+
<td>
|
|
37
|
+
<a href="https://www.npmjs.com/package/@aidejs/core" target="_blank">访问</a>
|
|
38
|
+
</td>
|
|
39
|
+
</tr>
|
|
40
|
+
<tr>
|
|
41
|
+
<td>@aidejs/tools</td>
|
|
42
|
+
<td>非必选,工具库,提供了各种实用的工具函数</td>
|
|
43
|
+
<td>
|
|
44
|
+
<a href="https://www.npmjs.com/package/@aidejs/tools" target="_blank">访问</a>
|
|
45
|
+
</td>
|
|
46
|
+
</tr>
|
|
47
|
+
</tbody>
|
|
48
|
+
</table>
|
|
49
|
+
|
|
50
|
+
更多模块我们将持续维护,你也可以[ 提issue ](https://github.com/NN-Studio/Aidejs/issues)告诉我们你希望提供或丰富优化的。
|
|
51
|
+
|
|
52
|
+
## 如何使用?
|
|
53
|
+
|
|
54
|
+
比如我们希望智能体告诉我们 ./mailmap 文件中的内容,怎么办?
|
|
55
|
+
|
|
56
|
+
首先,安装必要的依赖:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm i @aidejs/core @aidejs/tools
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
然后在文件index.js中写入如下代码:
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
const Aidejs = require("@aidejs/core");
|
|
66
|
+
const Tools = require("@aidejs/tools");
|
|
67
|
+
|
|
68
|
+
// 注册插件
|
|
69
|
+
Aidejs.use(Tools);
|
|
70
|
+
|
|
71
|
+
let agent = new Aidejs({
|
|
72
|
+
model: "qwen3",
|
|
73
|
+
url: "http://localhost:11434/v1",
|
|
74
|
+
apiKey: ""
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
agent.task("告诉我文件./.mailmap中的内容是什么", function (message) {
|
|
78
|
+
process.stdout.write(message);
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
然后直接运行:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
node ./index.js
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
运行以后,就可以看见智能体的回答了:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
文件 `./.mailmap` 的内容如下:
|
|
92
|
+
|
|
93
|
+
` ` `
|
|
94
|
+
zxl20070701 <1904314465@qq.com>
|
|
95
|
+
` ` `
|
|
96
|
+
|
|
97
|
+
这通常是一个邮件映射配置文件,用于将作者名(`zxl20070701`)映射到具体的邮箱地址(`1904314465@qq.com`),
|
|
98
|
+
常见于 Git 等工具的签名配置中。需要我帮你修改或解释吗?
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
更多细节,你可以访问[ 《Aidejs官方文档》 ](https://NN-Studio.github.io/Aidejs/)进行了解或学习。
|
|
102
|
+
|
|
103
|
+
## 版权
|
|
104
|
+
|
|
105
|
+
MIT License
|
|
106
|
+
|
|
107
|
+
Copyright (c) [zxl20070701](https://zxl20070701.github.io/notebook/home.html) 走一步,再走一步
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aidejs/core",
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
|
+
"description": "@aidejs/core",
|
|
5
|
+
"main": "./src/index.js",
|
|
6
|
+
"typings": "./types/index.d.ts",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"scripts": {},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/NN-Studio/Aidejs.git",
|
|
12
|
+
"directory": "packages/core"
|
|
13
|
+
},
|
|
14
|
+
"author": {
|
|
15
|
+
"name": "zxl20070701",
|
|
16
|
+
"url": "https://zxl20070701.github.io/notebook/home.html"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/NN-Studio/Aidejs/issues"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/NN-Studio/Aidejs",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"oipage": "^2.0.0"
|
|
25
|
+
}
|
|
26
|
+
}
|
package/src/Tool.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module.exports = class Tool {
|
|
2
|
+
|
|
3
|
+
constructor() {
|
|
4
|
+
this.tools = {};
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// 注册
|
|
8
|
+
register(name, value) {
|
|
9
|
+
if (this.tools[name]) {
|
|
10
|
+
console.warn(`工具${name}已存在,将被覆盖`);
|
|
11
|
+
}
|
|
12
|
+
this.tools[name] = value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// 工具列表
|
|
16
|
+
valueOf() {
|
|
17
|
+
let toolList = [];
|
|
18
|
+
for (let name in this.tools) {
|
|
19
|
+
toolList.push(this.tools[name].description);
|
|
20
|
+
}
|
|
21
|
+
return toolList;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 工具调用
|
|
25
|
+
invoke(name, args) {
|
|
26
|
+
if (!this.tools[name]) {
|
|
27
|
+
throw new Error(`工具${name}不存在`);
|
|
28
|
+
}
|
|
29
|
+
return this.tools[name].valueOf(args);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
};
|
package/src/index.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const { initOption } = require("oipage/nodejs/option/index");
|
|
2
|
+
const OpenAI = require("./utils/OpenAI");
|
|
3
|
+
const Tool = require("./Tool.js");
|
|
4
|
+
|
|
5
|
+
module.exports = class Aidejs {
|
|
6
|
+
|
|
7
|
+
// 工具管理对象
|
|
8
|
+
static tool = new Tool();
|
|
9
|
+
|
|
10
|
+
constructor(options = {}) {
|
|
11
|
+
this.options = initOption(options, {
|
|
12
|
+
model: "",
|
|
13
|
+
url: "http://localhost:11434/v1",
|
|
14
|
+
apiKey: ""
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
if (!this.options.model) {
|
|
18
|
+
throw new Error("model is required");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 注册工具
|
|
23
|
+
static registerTool(name, value) {
|
|
24
|
+
Aidejs.tool.register(name, value);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 安装插件,比如可用工具tool或技能skill等
|
|
28
|
+
static use(plugin) {
|
|
29
|
+
plugin.install(Aidejs);
|
|
30
|
+
return Aidejs;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 执行任务
|
|
34
|
+
task(message, logback, inputback) {
|
|
35
|
+
let messages = [], lastIndex = -1, toolCalls = false;
|
|
36
|
+
|
|
37
|
+
let resetLastIndex = () => {
|
|
38
|
+
messages.push({
|
|
39
|
+
role: "assistant",
|
|
40
|
+
content: ""
|
|
41
|
+
});
|
|
42
|
+
lastIndex = messages.length - 1;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
let runInputback = () => {
|
|
46
|
+
if (inputback) {
|
|
47
|
+
inputback().then(message => {
|
|
48
|
+
messages.push({
|
|
49
|
+
role: "user",
|
|
50
|
+
content: message
|
|
51
|
+
});
|
|
52
|
+
runChat();
|
|
53
|
+
}).catch(() => {
|
|
54
|
+
console.log("任务完成,未继续输入,已结束。");
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
console.log("任务完成,未提供输入回调,已结束。");
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
let runChat = () => {
|
|
62
|
+
OpenAI(this.options.url + "/chat/completions", {
|
|
63
|
+
header: {
|
|
64
|
+
Authorization: `Bearer ${this.options.apiKey}`
|
|
65
|
+
},
|
|
66
|
+
params: {
|
|
67
|
+
model: this.options.model,
|
|
68
|
+
messages,
|
|
69
|
+
tools: Aidejs.tool.valueOf(),
|
|
70
|
+
stream: true
|
|
71
|
+
}
|
|
72
|
+
}, function (chunk) {
|
|
73
|
+
try {
|
|
74
|
+
for (let choice of chunk.choices) {
|
|
75
|
+
|
|
76
|
+
if (choice.finish_reason) {
|
|
77
|
+
if (toolCalls) {
|
|
78
|
+
toolCalls = false;
|
|
79
|
+
runChat();
|
|
80
|
+
} else {
|
|
81
|
+
runInputback();
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
logback(choice.delta.content || "");
|
|
85
|
+
|
|
86
|
+
if (choice.delta.tool_calls) {
|
|
87
|
+
for (let tool_call of choice.delta.tool_calls) {
|
|
88
|
+
let result = Aidejs.tool.invoke(tool_call.function.name, JSON.parse(tool_call.function.arguments));
|
|
89
|
+
messages.push({
|
|
90
|
+
role: "tool",
|
|
91
|
+
tool_name: tool_call.function.name,
|
|
92
|
+
content: typeof result === "string" ? result : (JSON.stringify(result) + "")
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
toolCalls = true;
|
|
96
|
+
} else {
|
|
97
|
+
if (messages[lastIndex].role !== "assistant") resetLastIndex();
|
|
98
|
+
messages[lastIndex].content += choice.delta.content || "";
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
console.error("处理智能体响应时发生错误:", e);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
resetLastIndex();
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
if (message) {
|
|
111
|
+
messages.push({
|
|
112
|
+
role: "user",
|
|
113
|
+
content: message
|
|
114
|
+
});
|
|
115
|
+
runChat();
|
|
116
|
+
} else {
|
|
117
|
+
runInputback();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return this;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const https = require('https');
|
|
2
|
+
const http = require('http');
|
|
3
|
+
const toJSON = require("./toJSON");
|
|
4
|
+
|
|
5
|
+
module.exports = function (url, options = {}, databack, callback, errorback) {
|
|
6
|
+
|
|
7
|
+
let handler = /^https/.test(url) ? https : http;
|
|
8
|
+
|
|
9
|
+
let execArray = /https*:\/\/([^\/]+)(.+)?/.exec(url);
|
|
10
|
+
let hostport = execArray[1].split(":");
|
|
11
|
+
|
|
12
|
+
const req = handler.request({
|
|
13
|
+
hostname: hostport[0],
|
|
14
|
+
port: hostport[1] || 80,
|
|
15
|
+
path: execArray[2] || "/",
|
|
16
|
+
method: "POST",
|
|
17
|
+
headers: options.header || {}
|
|
18
|
+
}, (res) => {
|
|
19
|
+
|
|
20
|
+
let data = "";
|
|
21
|
+
res.on('data', (chunk) => {
|
|
22
|
+
chunk = chunk.toString().replace(/^data: /, "");
|
|
23
|
+
|
|
24
|
+
// 没有callback的情况下,data不累积,直接把chunk传给databack,适合流式处理
|
|
25
|
+
// 有callback的情况下,data累积chunk,等end事件触发时一次性调用callback,适合非流式处理
|
|
26
|
+
if (callback) data += chunk;
|
|
27
|
+
|
|
28
|
+
if (databack) databack(toJSON(chunk));
|
|
29
|
+
});
|
|
30
|
+
res.on('end', () => {
|
|
31
|
+
if (callback) callback(toJSON(data));
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
req.write(JSON.stringify(options.params || {}));
|
|
36
|
+
|
|
37
|
+
req.on('error', (e) => {
|
|
38
|
+
if (errorback) errorback(e);
|
|
39
|
+
});
|
|
40
|
+
req.end();
|
|
41
|
+
};
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description: Aidejs核心类
|
|
3
|
+
*/
|
|
4
|
+
export default class Aidejs {
|
|
5
|
+
|
|
6
|
+
constructor(options: {
|
|
7
|
+
model: string,
|
|
8
|
+
url?: string,
|
|
9
|
+
apiKey?: string
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 注册工具
|
|
14
|
+
* @param name
|
|
15
|
+
* @param value
|
|
16
|
+
*/
|
|
17
|
+
static registerTool(name: string, value: any): void
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 安装插件
|
|
21
|
+
* @param plugin
|
|
22
|
+
*/
|
|
23
|
+
static use(plugin: any): Aidejs
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 执行任务
|
|
27
|
+
* @param message
|
|
28
|
+
*/
|
|
29
|
+
task(message: string, logback: (message: string) => void, inputback: () => Promise<string>): this
|
|
30
|
+
|
|
31
|
+
}
|