@aidejs/core 0.1.0-alpha.1 → 0.1.0-alpha.3

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 CHANGED
@@ -13,6 +13,12 @@
13
13
  <a href="https://github.com/NN-Studio/Aidejs">
14
14
  <img src="https://img.shields.io/github/forks/NN-Studio/Aidejs" alt="forks">
15
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>
16
22
  </p>
17
23
 
18
24
  ## 功能列表
@@ -26,7 +32,8 @@
26
32
  <tr>
27
33
  <td>名称</td>
28
34
  <td>简介</td>
29
- <td>地址</td>
35
+ <td>下周统计</td>
36
+ <td>最新版本</td>
30
37
  </tr>
31
38
  </thead>
32
39
  <tbody>
@@ -34,14 +41,28 @@
34
41
  <td>@aidejs/core</td>
35
42
  <td>必选项,基础库,提供了最核心的LLM交互功能和插件系统</td>
36
43
  <td>
37
- <a href="https://www.npmjs.com/package/@aidejs/core" target="_blank">访问</a>
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://www.npmjs.com/package/@aidejs/tools" target="_blank">访问</a>
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aidejs/core",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.1.0-alpha.3",
4
4
  "description": "@aidejs/core",
5
5
  "main": "./src/index.js",
6
6
  "typings": "./types/index.d.ts",
package/src/Tool.js CHANGED
@@ -1,3 +1,5 @@
1
+ const debug = require("./utils/debug");
2
+
1
3
  module.exports = class Tool {
2
4
 
3
5
  constructor() {
@@ -22,11 +24,17 @@ module.exports = class Tool {
22
24
  }
23
25
 
24
26
  // 工具调用
25
- invoke(name, args) {
27
+ invoke(aidejs, name, args) {
26
28
  if (!this.tools[name]) {
27
29
  throw new Error(`工具${name}不存在`);
28
30
  }
29
- return this.tools[name].valueOf(args);
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,6 +1,7 @@
1
1
  const { initOption } = require("oipage/nodejs/option/index");
2
2
  const OpenAI = require("./utils/OpenAI");
3
- const Tool = require("./Tool.js");
3
+ const Tool = require("./Tool");
4
+ const debug = require("./utils/debug");
4
5
 
5
6
  module.exports = class Aidejs {
6
7
 
@@ -9,9 +10,11 @@ module.exports = class Aidejs {
9
10
 
10
11
  constructor(options = {}) {
11
12
  this.options = initOption(options, {
13
+ debug: false,
12
14
  model: "",
13
15
  url: "http://localhost:11434/v1",
14
- apiKey: ""
16
+ apiKey: "",
17
+ messages: []
15
18
  });
16
19
 
17
20
  if (!this.options.model) {
@@ -25,15 +28,17 @@ module.exports = class Aidejs {
25
28
  return Aidejs;
26
29
  }
27
30
 
28
- // 安装插件,比如可用工具tool或技能skill等
29
- static use(plugin) {
30
- plugin.install(Aidejs);
31
+ // 安装插件
32
+ static use(plugin, options = {}) {
33
+ plugin.install(Aidejs, options);
31
34
  return Aidejs;
32
35
  }
33
36
 
34
37
  // 执行任务
35
- task(message, logback, inputback) {
36
- let messages = [], lastIndex = -1, toolCalls = false;
38
+ task(message, logback, inputback, thinkback) {
39
+ let _this = this;
40
+
41
+ let messages = [..._this.options.messages], lastIndex = -1, toolCalls = false;
37
42
 
38
43
  let resetLastIndex = () => {
39
44
  messages.push({
@@ -60,79 +65,152 @@ module.exports = class Aidejs {
60
65
  };
61
66
 
62
67
  let runChat = () => {
68
+ let tools = Aidejs.tool.valueOf();
69
+
70
+ if (this.options.debug) {
71
+ debug("OpenAI messages", messages);
72
+ debug("OpenAI tools", tools.map(function (funItem) {
73
+ return funItem.function.name + " " + funItem.function.description;
74
+ }));
75
+ }
76
+
63
77
  OpenAI(this.options.url + "/chat/completions", {
64
78
  header: {
65
79
  Authorization: `Bearer ${this.options.apiKey}`
66
80
  },
67
81
  params: {
82
+
83
+ // 必需,模型ID,也就是你选择的具体哪个模型
68
84
  model: this.options.model,
85
+
86
+ // 必需,提供的array类型的消息列表,包含从头到尾的对话历史
87
+ // 比如值是一个数组,每个条目可以是下列类型之一:
88
+ // (所有的类型其实都应该是一个json对象,下面列出的都是其包含的字段)
89
+ // 1、System message
90
+ // content:必须提供的string类型,表示system的消息内容
91
+ // role:必须提供的string类型,表示消息作者的角色,对于system message应该是"system"
92
+ // name:可选的string类型,表示对话参与者的名称
93
+ // 2、User message
94
+ // content:必须提供的string或array类型,二选一,表示user的消息内容
95
+ // 为string类型时,表示消息的文本内容
96
+ // 为array类型时,用来包含多个内容部分的数组,而此数组的每个条目都是一个json对象,可以分别是如下类型之一
97
+ // 1)文本
98
+ // type:必须提供的string类型,表示内容部分的类型,一般是“text”
99
+ // text:必须提供的string类型,文字内容
100
+ // 2)图片
101
+ // type:必须提供的string类型,表示内容部分的类型,一般是"image_url"
102
+ // image_url:必须提供的string类型,图像的 URL 或 Base64 编码的图像数据
103
+ // role:必须提供的string类型,表示消息作者的角色,对于user message应该是"user"
104
+ // name:可选的string类型,表示对话参与者的名称
105
+ // 3、Assistant message(实际代码就是下面的choice.delta的值)
106
+ // content:必须提供(指定 tool_calls 时除外)的string类型,表示助手消息的内容
107
+ // role:必须提供的string类型,表示消息作者的角色,对于assistant message应该是"assistant"
108
+ // name:可选的string类型,表示对话参与者的名称
109
+ // tool_calls:可选的array类型,大模型生成的工具调用,例如函数调用,用这里代码打印的例子:
110
+ // [
111
+ // {
112
+ // id: 'call_graj8v5e', // 必须提供,表示函数调用的id
113
+ // index: 0,
114
+ // type: 'function', // 必须提供,表示工具调用的类型(目前仅支持“function”类型)。
115
+ // function: {
116
+ // name: 'aidejs_disk_readPlain', // 必须提供,要调用的函数的名称
117
+ // arguments: '{"filepath":"./.mailmap"}' // 必须提供,表示调用函数所用的参数
118
+ // }
119
+ // }
120
+ // ]
121
+ // 4、Tool message
122
+ // 一个json对象,在用户根据assistant的tool_calls内容调用了某个函数后,
123
+ // 用户可能还需要再把函数调用结果反馈给大模型,让大模型根据函数调用结果给出最终的总结性的答复
124
+ // content:必须提供的string类型,表示工具消息的内容,一般是把函数调用的结果描述在这里
125
+ // role:必须提供的string类型,表示消息作者的角色,对于tool message应该是"tool"
126
+ // tool_call_id:必须提供的string类型,表示本次消息是对哪个函数调用的结果反馈
69
127
  messages,
70
- tools: Aidejs.tool.valueOf(),
71
- stream: true
128
+
129
+ // 用户可选的一个字段,是array类型,表示可供模型选择的一个工具列表
130
+ // 列表中最多支持 128 个tool
131
+ // 具体说明可以查看 /packages/tools/src/disk/readPlain.js
132
+ tools,
133
+
134
+ // 可选的bool值,如果设置了true,将会流式的返回消息
135
+ stream: true,
136
+
137
+ // softmax 函数中的除数,温度越低,生成的结果越确定,温度越高,生成的结果越随机
138
+ // temperature: 0.7,
139
+
140
+ // 类似的有这些策略:TopP、TopK、MinP,分别表示前若干个累积积累和、前K名、最低概率
141
+ // top_p: 0.8,
72
142
  }
73
143
  }, function (chunk) {
74
144
  try {
75
145
 
76
146
  // 执行一次回复
77
147
  let runChoice = (choiceIndex) => {
78
- if (choiceIndex >= chunk.choices.length) return;
148
+ if (choiceIndex >= chunk.choices.length) { return; }
79
149
 
80
150
  let choice = chunk.choices[choiceIndex];
81
151
 
82
- if (choice.finish_reason) {
83
- if (toolCalls) {
84
- toolCalls = false;
85
- runChat();
86
- } else {
87
- runInputback();
88
- }
89
- } else {
90
- logback(choice.delta.content || "");
91
-
92
- if (choice.delta.tool_calls) {
152
+ if (choice.delta.content) {
153
+ if (logback) logback(choice.delta.content);
154
+ } else if (choice.delta.reasoning) {
155
+ if (thinkback) thinkback(choice.delta.reasoning);
156
+ }
93
157
 
94
- // 执行一次工具
95
- let runTool = (toolIndex) => {
96
- if (toolIndex >= choice.delta.tool_calls.length) {
97
- toolCalls = true;
98
- runChoice(choiceIndex + 1);
158
+ if (choice.delta.tool_calls) {
159
+ if (_this.options.debug) debug("tool_calls", choice.delta.tool_calls);
160
+
161
+ // 执行一次工具
162
+ let runTool = (toolIndex) => {
163
+ if (toolIndex >= choice.delta.tool_calls.length) {
164
+ toolCalls = true;
165
+ runChoice(choiceIndex + 1);
166
+ } else {
167
+ let tool_call = choice.delta.tool_calls[toolIndex];
168
+ let result = Aidejs.tool.invoke(_this, tool_call.function.name, JSON.parse(tool_call.function.arguments));
169
+
170
+ let toolback = function (value) {
171
+ messages.push({
172
+ role: "tool",
173
+ tool_call_id: tool_call.id,
174
+ tool_name: tool_call.function.name,
175
+ content: typeof value === "string" ? value : (JSON.stringify(value) + "")
176
+ });
177
+ runTool(toolIndex + 1);
178
+ };
179
+
180
+ if (typeof result === "object" && result.constructor === Promise) {
181
+ result.then(function (value) {
182
+ toolback(value);
183
+ }).catch(function (error) {
184
+ toolback(error + "");
185
+ });
99
186
  } else {
100
- let tool_call = choice.delta.tool_calls[toolIndex];
101
- let result = Aidejs.tool.invoke(tool_call.function.name, JSON.parse(tool_call.function.arguments));
102
-
103
- let toolback = function (value) {
104
- messages.push({
105
- role: "tool",
106
- tool_name: tool_call.function.name,
107
- content: typeof value === "string" ? value : (JSON.stringify(value) + "")
108
- });
109
- runTool(toolIndex + 1);
110
- };
111
-
112
- if (typeof result === "object" && result.constructor === Promise) {
113
- result.then(function (value) {
114
- toolback(value);
115
- }).catch(function (error) {
116
- toolback(error + "");
117
- });
118
- } else {
119
- toolback(result);
120
- }
187
+ toolback(result);
121
188
  }
122
- };
123
- runTool(0);
124
- } else {
125
- if (messages[lastIndex].role !== "assistant") resetLastIndex();
126
- messages[lastIndex].content += choice.delta.content || "";
127
- runChoice(choiceIndex + 1);
128
- }
189
+ }
190
+ };
191
+ runTool(0);
192
+ } else {
193
+ if (messages[lastIndex].role !== "assistant") resetLastIndex();
194
+ messages[lastIndex].content += choice.delta.content || "";
195
+ runChoice(choiceIndex + 1);
129
196
  }
130
197
 
131
198
  };
132
199
  runChoice(0);
133
200
  } catch (e) {
134
- console.error("处理智能体响应时发生错误:", e);
201
+ debug("处理智能体响应时发生错误", e);
202
+ }
203
+ }, function () {
204
+ if (toolCalls) {
205
+ toolCalls = false;
206
+ runChat();
207
+ } else {
208
+ runInputback();
135
209
  }
210
+ }, function (e) {
211
+ debug("对接LLM解答问题时发生错误", e);
212
+ toolCalls = false;
213
+ runInputback();
136
214
  });
137
215
 
138
216
  resetLastIndex();
@@ -16,19 +16,13 @@ module.exports = function (url, options = {}, databack, callback, errorback) {
16
16
  method: "POST",
17
17
  headers: options.header || {}
18
18
  }, (res) => {
19
-
20
- let data = "";
21
19
  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));
20
+ // 这里data不累积,直接把chunk传给databack,流式处理
21
+ // 如何后续希望callback中返回数据,那么data累积chunk,等end事件触发时一次性调用callback,非流式处理
22
+ if (databack) databack(toJSON(chunk.toString().replace(/^data: /, "")));
29
23
  });
30
24
  res.on('end', () => {
31
- if (callback) callback(toJSON(data));
25
+ if (callback) callback();
32
26
  });
33
27
  });
34
28
 
@@ -0,0 +1,5 @@
1
+ module.exports = function (name, content) {
2
+ console.log("\n\x1b[33m【" + name + "】 " + new Date().toString() + "\x1b[0m");
3
+ console.log(content);
4
+ console.log("\x1b[33m---------------------------------------------------------------------\x1b[0m\n");
5
+ }
package/types/index.d.ts CHANGED
@@ -4,9 +4,11 @@
4
4
  export default class Aidejs {
5
5
 
6
6
  constructor(options: {
7
- model: string,
8
- url?: string,
7
+ debug?: boolean
8
+ model: string
9
+ url?: string
9
10
  apiKey?: string
11
+ messages?: Array<any>
10
12
  })
11
13
 
12
14
  /**
@@ -20,12 +22,12 @@ export default class Aidejs {
20
22
  * 安装插件
21
23
  * @param plugin
22
24
  */
23
- static use(plugin: any): Aidejs
25
+ static use(plugin: any, options?: any): Aidejs
24
26
 
25
27
  /**
26
28
  * 执行任务
27
29
  * @param message
28
30
  */
29
- task(message: string, logback: (message: string) => void, inputback: () => Promise<string>): this
31
+ task(message?: string, logback?: (message: string) => void, inputback?: () => Promise<string>, thinkback?: (think: string) => void): this
30
32
 
31
33
  }