p-api-agent 0.0.1 → 0.0.2
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/dist/{index.d.cts → index.d.mts} +17 -2
- package/dist/index.d.ts +17 -2
- package/dist/index.js +223 -65
- package/dist/index.mjs +369 -0
- package/package.json +5 -2
- package/dist/index.cjs +0 -273
|
@@ -47,7 +47,7 @@ interface ImageContent {
|
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
type Content = TextContent | ImageContent;
|
|
50
|
-
type UserChatInput =
|
|
50
|
+
type UserChatInput = {
|
|
51
51
|
role: 'system' | 'user' | 'assistant';
|
|
52
52
|
content: Content[];
|
|
53
53
|
}[];
|
|
@@ -69,14 +69,29 @@ declare class Agent {
|
|
|
69
69
|
* 注册LLM模型图片能力
|
|
70
70
|
*/
|
|
71
71
|
register_llm_image_ability(): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* 判断是否需要调用function_call, 以及调用哪个工具函数
|
|
74
|
+
*/
|
|
75
|
+
check_whether_use_function_call(user_input: UserChatInput): Promise<any>;
|
|
72
76
|
/**
|
|
73
77
|
* 创建聊天
|
|
74
78
|
*/
|
|
75
|
-
create_chat(user_input: UserChatInput): Promise<
|
|
79
|
+
create_chat(user_input: string | UserChatInput): Promise<{
|
|
80
|
+
result: string;
|
|
81
|
+
use_tools: any[];
|
|
82
|
+
}>;
|
|
76
83
|
/**
|
|
77
84
|
* agent预置提示词
|
|
78
85
|
*/
|
|
79
86
|
get_preset_prompt(): string;
|
|
87
|
+
/**
|
|
88
|
+
* 预处理用户输入
|
|
89
|
+
*/
|
|
90
|
+
pre_dispose_user_input(user_input: string | UserChatInput): UserChatInput;
|
|
91
|
+
/**
|
|
92
|
+
* 深拷贝方法
|
|
93
|
+
*/
|
|
94
|
+
private deepClone;
|
|
80
95
|
}
|
|
81
96
|
|
|
82
97
|
declare class _LLM_Utils {
|
package/dist/index.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ interface ImageContent {
|
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
type Content = TextContent | ImageContent;
|
|
50
|
-
type UserChatInput =
|
|
50
|
+
type UserChatInput = {
|
|
51
51
|
role: 'system' | 'user' | 'assistant';
|
|
52
52
|
content: Content[];
|
|
53
53
|
}[];
|
|
@@ -69,14 +69,29 @@ declare class Agent {
|
|
|
69
69
|
* 注册LLM模型图片能力
|
|
70
70
|
*/
|
|
71
71
|
register_llm_image_ability(): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* 判断是否需要调用function_call, 以及调用哪个工具函数
|
|
74
|
+
*/
|
|
75
|
+
check_whether_use_function_call(user_input: UserChatInput): Promise<any>;
|
|
72
76
|
/**
|
|
73
77
|
* 创建聊天
|
|
74
78
|
*/
|
|
75
|
-
create_chat(user_input: UserChatInput): Promise<
|
|
79
|
+
create_chat(user_input: string | UserChatInput): Promise<{
|
|
80
|
+
result: string;
|
|
81
|
+
use_tools: any[];
|
|
82
|
+
}>;
|
|
76
83
|
/**
|
|
77
84
|
* agent预置提示词
|
|
78
85
|
*/
|
|
79
86
|
get_preset_prompt(): string;
|
|
87
|
+
/**
|
|
88
|
+
* 预处理用户输入
|
|
89
|
+
*/
|
|
90
|
+
pre_dispose_user_input(user_input: string | UserChatInput): UserChatInput;
|
|
91
|
+
/**
|
|
92
|
+
* 深拷贝方法
|
|
93
|
+
*/
|
|
94
|
+
private deepClone;
|
|
80
95
|
}
|
|
81
96
|
|
|
82
97
|
declare class _LLM_Utils {
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,47 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
30
|
+
|
|
31
|
+
// src/index.ts
|
|
32
|
+
var index_exports = {};
|
|
33
|
+
__export(index_exports, {
|
|
34
|
+
Agent: () => Agent,
|
|
35
|
+
FunctionCall: () => FunctionCall,
|
|
36
|
+
LLM_Utils: () => LLM_Utils
|
|
6
37
|
});
|
|
38
|
+
module.exports = __toCommonJS(index_exports);
|
|
7
39
|
|
|
8
40
|
// src/agent/index.ts
|
|
9
|
-
|
|
41
|
+
var import_fs = __toESM(require("fs"));
|
|
10
42
|
|
|
11
43
|
// src/utils/llm_utils.ts
|
|
12
|
-
|
|
44
|
+
var import_jsonrepair = require("jsonrepair");
|
|
13
45
|
var _LLM_Utils = class {
|
|
14
46
|
/**
|
|
15
47
|
* 提取大模型返回的markdown
|
|
@@ -30,7 +62,7 @@ var _LLM_Utils = class {
|
|
|
30
62
|
try {
|
|
31
63
|
return JSON.parse(json_content);
|
|
32
64
|
} catch (err) {
|
|
33
|
-
return JSON.parse(jsonrepair(json_content));
|
|
65
|
+
return JSON.parse((0, import_jsonrepair.jsonrepair)(json_content));
|
|
34
66
|
}
|
|
35
67
|
}
|
|
36
68
|
/**
|
|
@@ -58,24 +90,24 @@ var _LLM_Utils = class {
|
|
|
58
90
|
try {
|
|
59
91
|
return JSON.parse(content);
|
|
60
92
|
} catch (err) {
|
|
61
|
-
return JSON.parse(jsonrepair(content));
|
|
93
|
+
return JSON.parse((0, import_jsonrepair.jsonrepair)(content));
|
|
62
94
|
}
|
|
63
95
|
}
|
|
64
96
|
};
|
|
65
97
|
var LLM_Utils = new _LLM_Utils();
|
|
66
98
|
|
|
67
99
|
// src/agent/index.ts
|
|
68
|
-
|
|
100
|
+
var import_path = __toESM(require("path"));
|
|
69
101
|
var Agent = class {
|
|
70
102
|
// 角色定义的提示词
|
|
71
103
|
constructor() {
|
|
72
|
-
this
|
|
104
|
+
__publicField(this, "function_call", null);
|
|
73
105
|
// 工具函数的说明文档, 供模型调用时参考
|
|
74
|
-
this
|
|
106
|
+
__publicField(this, "function_call_doc", "");
|
|
75
107
|
// 模型的聊天能力
|
|
76
|
-
this
|
|
108
|
+
__publicField(this, "llm_chat_func", null);
|
|
77
109
|
// 预置提示词
|
|
78
|
-
this
|
|
110
|
+
__publicField(this, "preset_prompt", this.get_preset_prompt());
|
|
79
111
|
}
|
|
80
112
|
/**
|
|
81
113
|
* 注册工具函数
|
|
@@ -100,92 +132,214 @@ var Agent = class {
|
|
|
100
132
|
return true;
|
|
101
133
|
}
|
|
102
134
|
/**
|
|
103
|
-
*
|
|
135
|
+
* 判断是否需要调用function_call, 以及调用哪个工具函数
|
|
104
136
|
*/
|
|
105
|
-
async
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
137
|
+
async check_whether_use_function_call(user_input) {
|
|
138
|
+
const role_prompt = `
|
|
139
|
+
\u6211\u662F\u4E00\u4E2A\u667A\u80FD\u52A9\u624B, \u6211\u4F1A\u5224\u65AD\u7528\u6237\u8F93\u5165\u662F\u5426\u9700\u8981\u8C03\u7528\u5DE5\u5177\u51FD\u6570\u6765\u8F85\u52A9\u5B8C\u6210\u4EFB\u52A1
|
|
140
|
+
- \u5982\u679C\u9700\u8981\u8C03\u7528, \u6211\u4F1A\u9996\u5148\u5224\u65AD\u81EA\u5DF1\u662F\u5426\u80FD\u89E3\u51B3,
|
|
141
|
+
- \u5982\u679C\u80FD\u89E3\u51B3, \u6211\u5C31\u8FD4\u56DE {"command": "no_use", "result": "\u4E0D\u9700\u8981\u8C03\u7528\u5DE5\u5177\u51FD\u6570"}
|
|
142
|
+
- \u5982\u679C\u4E0D\u80FD\u89E3\u51B3, \u6211\u5C31\u4F1A\u6839\u636E\u5DF2\u6709\u7684\u5DE5\u5177\u51FD\u6570\u5217\u8868\u9009\u62E9\u5DE5\u5177\u51FD\u6570 \u5E76\u4E14\u6839\u636E\u7528\u6237\u8F93\u5165\u7684\u5DE5\u5177\u51FD\u6570\u8BF4\u660E\u6587\u6863\u751F\u6210\u8C03\u7528\u53C2\u6570:
|
|
143
|
+
- \u6211\u7EDD\u5BF9\u4E0D\u4F1A\u65E0\u4E2D\u751F\u6709\u4E00\u4E2A\u5DE5\u5177\u51FD\u6570
|
|
144
|
+
- \u6211\u4E0D\u4F1A\u9020\u5047\u6570\u636E / \u865A\u62DF\u6570\u636E / \u634F\u9020\u6570\u636E
|
|
145
|
+
- \u6CA1\u6709\u7684\u5DE5\u5177\u51FD\u6570,\u6211\u4F1A\u544A\u77E5\u4F60, \u65E0\u6CD5\u6EE1\u8DB3\u4F60\u7684\u64CD\u4F5C
|
|
146
|
+
## \u6211\u53EF\u4EE5\u8C03\u7528\u5DE5\u5177\u51FD\u6570\u5217\u8868:
|
|
147
|
+
---
|
|
148
|
+
${this.function_call_doc}
|
|
149
|
+
|
|
150
|
+
## \u8F93\u51FA\u8981\u6C42
|
|
151
|
+
---
|
|
152
|
+
\u5982\u679C\u9700\u8981\u8C03\u7528\u5DE5\u5177\u51FD\u6570, \u6211\u4F1A\u8FD4\u56DE{"command": "get_tool_doc", "tool_name": "\u5DE5\u5177\u51FD\u6570\u540D\u79F0"}
|
|
153
|
+
\u5982\u679C\u4E0D\u9700\u8981\u8C03\u7528, \u8BF7\u4F1A\u8FD4\u56DE{"command": "no_use", "result": "\u4E0D\u9700\u8981\u8C03\u7528\u5DE5\u5177\u51FD\u6570"}
|
|
154
|
+
\u5982\u679C\u81EA\u8EAB\u6CA1\u80FD\u529B\u5904\u7406,\u4E14\u6CA1\u6709\u5408\u9002\u7684\u5DE5\u5177\u51FD\u6570, \u8BF7\u4F1A\u8FD4\u56DE{"command": "no_ability", "result": "\u6211\u6CA1\u80FD\u529B\u6267\u884C\u8FD9\u4E2A\u64CD\u4F5C"}
|
|
155
|
+
---
|
|
156
|
+
`;
|
|
157
|
+
const check_use_prompt = [
|
|
158
|
+
{
|
|
121
159
|
role: "system",
|
|
122
160
|
content: [
|
|
123
|
-
{ type: "text", text:
|
|
124
|
-
${this.function_call_doc}` }
|
|
161
|
+
{ type: "text", text: role_prompt }
|
|
125
162
|
]
|
|
126
|
-
}
|
|
163
|
+
},
|
|
164
|
+
...this.deepClone(user_input)
|
|
165
|
+
];
|
|
166
|
+
const check_res = await this.llm_chat_func([
|
|
167
|
+
...check_use_prompt,
|
|
168
|
+
{
|
|
169
|
+
role: "user",
|
|
170
|
+
content: [
|
|
171
|
+
{
|
|
172
|
+
type: "text",
|
|
173
|
+
text: "\u4F60\u5FC5\u987B\u8FD4\u56DEJSON\u683C\u5F0F, \u4E0D\u80FD\u8FD4\u56DE\u591A\u4F59\u5B57\u7B26, \u4E0D\u7136\u6211\u4F1A\u89E3\u6790\u5931\u8D25\u7684"
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
]);
|
|
178
|
+
const check_res_json = LLM_Utils.extract_json(check_res);
|
|
179
|
+
if (check_res_json.command === "no_use" || check_res_json.command === "no_ability") {
|
|
180
|
+
return check_res_json;
|
|
127
181
|
}
|
|
128
|
-
|
|
129
|
-
role: "
|
|
182
|
+
check_use_prompt.push({
|
|
183
|
+
role: "assistant",
|
|
130
184
|
content: [
|
|
131
|
-
{ type: "text", text:
|
|
185
|
+
{ type: "text", text: check_res }
|
|
132
186
|
]
|
|
133
187
|
});
|
|
188
|
+
const tool_name = check_res_json.tool_name;
|
|
189
|
+
const doc = await this.function_call.gen_tool_doc(tool_name);
|
|
190
|
+
const gen_params_prompt = `
|
|
191
|
+
## \u5DE5\u5177\u51FD\u6570
|
|
192
|
+
${tool_name}
|
|
193
|
+
## \u5DE5\u5177\u51FD\u6570\u8BF4\u660E\u6587\u6863:
|
|
194
|
+
---
|
|
195
|
+
${doc}
|
|
196
|
+
---
|
|
197
|
+
\u8BF7\u4E25\u683C\u6309\u7167\u5DE5\u5177\u51FD\u6570\u7684\u8F93\u5165\u8981\u6C42, \u6839\u636E\u7528\u6237\u8F93\u5165\u548C\u5DE5\u5177\u51FD\u6570\u8BF4\u660E\u6587\u6863\u751F\u6210\u8C03\u7528\u53C2\u6570,
|
|
198
|
+
\u8F93\u51FA\u683C\u5F0F\u5FC5\u987B\u4E3Ajson\u683C\u5F0F, \u4F8B\u5982{"\u53C2\u65701": "\u503C1", "\u53C2\u65702": "\u503C2"}, \u4E0D\u80FD\u8FD4\u56DE\u591A\u4F59\u5B57\u7B26
|
|
199
|
+
`;
|
|
200
|
+
check_use_prompt.push({
|
|
201
|
+
role: "user",
|
|
202
|
+
content: [
|
|
203
|
+
{ type: "text", text: gen_params_prompt },
|
|
204
|
+
{ type: "text", text: "\u4F60\u5FC5\u987B\u8FD4\u56DEJSON\u683C\u5F0F, \u4E0D\u80FD\u8FD4\u56DE\u591A\u4F59\u5B57\u7B26, \u4E0D\u7136\u6211\u4F1A\u89E3\u6790\u5931\u8D25\u7684" }
|
|
205
|
+
]
|
|
206
|
+
});
|
|
207
|
+
const gen_params_res = await this.llm_chat_func(check_use_prompt);
|
|
208
|
+
const gen_params_json = LLM_Utils.extract_json(gen_params_res);
|
|
209
|
+
return {
|
|
210
|
+
command: "use_tool",
|
|
211
|
+
tool_name,
|
|
212
|
+
params: gen_params_json
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 创建聊天
|
|
217
|
+
*/
|
|
218
|
+
async create_chat(user_input) {
|
|
219
|
+
const dispose_user_input = this.pre_dispose_user_input(user_input);
|
|
134
220
|
let max_loop = 20;
|
|
135
|
-
let loop_count =
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const tool_name =
|
|
144
|
-
const
|
|
221
|
+
let loop_count = 1;
|
|
222
|
+
const return_data = {
|
|
223
|
+
result: "",
|
|
224
|
+
use_tools: []
|
|
225
|
+
};
|
|
226
|
+
while (loop_count <= max_loop) {
|
|
227
|
+
const check_use_tools = await this.check_whether_use_function_call(dispose_user_input);
|
|
228
|
+
if (check_use_tools.command == "use_tool") {
|
|
229
|
+
const { tool_name, params } = check_use_tools;
|
|
230
|
+
const tool_result = await this.function_call.exec_function(tool_name, params);
|
|
145
231
|
dispose_user_input.push({
|
|
146
|
-
role: "
|
|
232
|
+
role: "assistant",
|
|
147
233
|
content: [
|
|
148
|
-
{
|
|
149
|
-
|
|
234
|
+
{
|
|
235
|
+
type: "text",
|
|
236
|
+
text: `\u6211\u8981\u8C03\u7528, \u5DE5\u5177\u51FD\u6570${tool_name}
|
|
237
|
+
\u8C03\u7528\u53C2\u6570\u4E3A:
|
|
238
|
+
${JSON.stringify(params)}`
|
|
239
|
+
}
|
|
150
240
|
]
|
|
151
241
|
});
|
|
152
|
-
} else if (llm_res.command === "use_tool") {
|
|
153
|
-
const tool_name = llm_res.tool_name;
|
|
154
|
-
const tool_params = LLM_Utils.parse_json(llm_res.params);
|
|
155
|
-
const tool_result = await this.function_call.exec_function(tool_name, tool_params);
|
|
156
242
|
dispose_user_input.push({
|
|
157
243
|
role: "user",
|
|
158
244
|
content: [
|
|
159
|
-
{ type: "text", text: `\
|
|
245
|
+
{ type: "text", text: `\u8C03\u7528\u7ED3\u679C:
|
|
160
246
|
${JSON.stringify(tool_result)}` }
|
|
161
247
|
]
|
|
162
248
|
});
|
|
249
|
+
loop_count++;
|
|
250
|
+
return_data.use_tools.push({
|
|
251
|
+
tool_name,
|
|
252
|
+
params,
|
|
253
|
+
exec_result: tool_result
|
|
254
|
+
});
|
|
255
|
+
} else if (check_use_tools.command == "no_ability") {
|
|
256
|
+
return_data.result = "\u65E0\u6CD5\u6267\u884C\u6B64\u64CD\u4F5C";
|
|
257
|
+
return return_data;
|
|
258
|
+
} else if (check_use_tools.command == "no_use") {
|
|
259
|
+
dispose_user_input.push({
|
|
260
|
+
role: "user",
|
|
261
|
+
content: [
|
|
262
|
+
{
|
|
263
|
+
type: "text",
|
|
264
|
+
text: "\u4F60\u6839\u636E\u4E0A\u4E0B\u6587\u8FD4\u56DE\u7ED3\u679C\u5C31\u597D, \u4F60\u7684\u601D\u8003\u8FC7\u7A0B\u65E0\u9700\u8FD4\u56DE\u7ED9\u6211, \u4F60\u53EA\u9700\u8981\u56DE\u7B54\u6211\u7684\u95EE\u9898, \u4E0D\u8981\u5C06\u591A\u4F59\u7684\u4FE1\u606F\u8FD4\u56DE\u7ED9\u6211, \u4E0D\u80FD\u6267\u884C\u64CD\u4F5C\u5C31\u56DE\u590D\u65E0\u6CD5\u64CD\u4F5C"
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
});
|
|
268
|
+
const llm_chat_res = await this.llm_chat_func(dispose_user_input);
|
|
269
|
+
return_data.result = llm_chat_res;
|
|
270
|
+
return return_data;
|
|
271
|
+
} else {
|
|
272
|
+
return_data.result = "\u5F02\u5E38\u6307\u5B9A";
|
|
273
|
+
return return_data;
|
|
163
274
|
}
|
|
164
|
-
loop_count++;
|
|
165
275
|
}
|
|
166
276
|
}
|
|
167
277
|
/**
|
|
168
278
|
* agent预置提示词
|
|
169
279
|
*/
|
|
170
280
|
get_preset_prompt() {
|
|
171
|
-
const prompt =
|
|
281
|
+
const prompt = import_fs.default.readFileSync(import_path.default.join(__dirname, "./preset_prompt.md"), "utf-8");
|
|
172
282
|
return prompt;
|
|
173
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* 预处理用户输入
|
|
286
|
+
*/
|
|
287
|
+
pre_dispose_user_input(user_input) {
|
|
288
|
+
if (typeof user_input === "string") {
|
|
289
|
+
return [
|
|
290
|
+
{
|
|
291
|
+
role: "user",
|
|
292
|
+
content: [
|
|
293
|
+
{ type: "text", text: user_input }
|
|
294
|
+
]
|
|
295
|
+
}
|
|
296
|
+
];
|
|
297
|
+
}
|
|
298
|
+
return user_input;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* 深拷贝方法
|
|
302
|
+
*/
|
|
303
|
+
deepClone(obj) {
|
|
304
|
+
if (obj === null || typeof obj !== "object") {
|
|
305
|
+
return obj;
|
|
306
|
+
}
|
|
307
|
+
if (obj instanceof Date) {
|
|
308
|
+
return new Date(obj.getTime());
|
|
309
|
+
}
|
|
310
|
+
if (obj instanceof Array) {
|
|
311
|
+
const cloneArray = [];
|
|
312
|
+
obj.forEach((item) => {
|
|
313
|
+
cloneArray.push(this.deepClone(item));
|
|
314
|
+
});
|
|
315
|
+
return cloneArray;
|
|
316
|
+
}
|
|
317
|
+
if (obj instanceof Object) {
|
|
318
|
+
const cloneObj = {};
|
|
319
|
+
for (const key in obj) {
|
|
320
|
+
if (obj.hasOwnProperty(key)) {
|
|
321
|
+
cloneObj[key] = this.deepClone(obj[key]);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return cloneObj;
|
|
325
|
+
}
|
|
326
|
+
throw new Error("Unable to copy object");
|
|
327
|
+
}
|
|
174
328
|
};
|
|
175
329
|
|
|
176
330
|
// src/function_call/index.ts
|
|
177
|
-
|
|
178
|
-
|
|
331
|
+
var import_path2 = __toESM(require("path"));
|
|
332
|
+
var import_fs2 = __toESM(require("fs"));
|
|
179
333
|
var FunctionCall = class {
|
|
180
334
|
constructor(tool_path) {
|
|
181
335
|
this.tool_path = tool_path;
|
|
182
|
-
this
|
|
336
|
+
__publicField(this, "tools", {});
|
|
183
337
|
this.init();
|
|
184
338
|
}
|
|
185
339
|
init() {
|
|
186
|
-
for (const file_name of
|
|
187
|
-
const route_path =
|
|
188
|
-
const mcp =
|
|
340
|
+
for (const file_name of import_fs2.default.readdirSync(this.tool_path)) {
|
|
341
|
+
const route_path = import_path2.default.join(this.tool_path, file_name);
|
|
342
|
+
const mcp = require(route_path);
|
|
189
343
|
const info = mcp.register();
|
|
190
344
|
this.tools[info.name] = info;
|
|
191
345
|
}
|
|
@@ -195,6 +349,9 @@ var FunctionCall = class {
|
|
|
195
349
|
*/
|
|
196
350
|
gen_tool_doc(name) {
|
|
197
351
|
const info = this.tools[name];
|
|
352
|
+
if (!info) {
|
|
353
|
+
throw `${name}\u5DE5\u5177\u51FD\u6570\u4E0D\u5B58\u5728`;
|
|
354
|
+
}
|
|
198
355
|
const schema = info.input_schema;
|
|
199
356
|
const schemaDesc = `\u7C7B\u578B: ${schema.type}`;
|
|
200
357
|
const params = Object.keys(schema.properties).map((key) => {
|
|
@@ -234,8 +391,9 @@ ${params}`;
|
|
|
234
391
|
return await info.register_func(params);
|
|
235
392
|
}
|
|
236
393
|
};
|
|
237
|
-
export
|
|
394
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
395
|
+
0 && (module.exports = {
|
|
238
396
|
Agent,
|
|
239
397
|
FunctionCall,
|
|
240
398
|
LLM_Utils
|
|
241
|
-
};
|
|
399
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
+
}) : x)(function(x) {
|
|
6
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
+
});
|
|
9
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
10
|
+
|
|
11
|
+
// src/agent/index.ts
|
|
12
|
+
import fs from "fs";
|
|
13
|
+
|
|
14
|
+
// src/utils/llm_utils.ts
|
|
15
|
+
import { jsonrepair } from "jsonrepair";
|
|
16
|
+
var _LLM_Utils = class {
|
|
17
|
+
/**
|
|
18
|
+
* 提取大模型返回的markdown
|
|
19
|
+
*/
|
|
20
|
+
extract_markdown(content) {
|
|
21
|
+
const regex = /```markdown\n(.*?)\n```/s;
|
|
22
|
+
const match = content.match(regex);
|
|
23
|
+
if (!match) return content;
|
|
24
|
+
return match[1];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 提取大模型的json格式
|
|
28
|
+
*/
|
|
29
|
+
extract_json(content) {
|
|
30
|
+
const regex = /```json\n(.*?)\n```/s;
|
|
31
|
+
const match = content.match(regex);
|
|
32
|
+
let json_content = match ? match[1] : content;
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(json_content);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
return JSON.parse(jsonrepair(json_content));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 提取mermaid格式
|
|
41
|
+
*/
|
|
42
|
+
extract_mermaid(content) {
|
|
43
|
+
const regex = /```mermaid\n(.*?)\n```/s;
|
|
44
|
+
const match = content.match(regex);
|
|
45
|
+
if (!match) return content;
|
|
46
|
+
return match[1];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 提取svg格式
|
|
50
|
+
*/
|
|
51
|
+
extract_svg(content) {
|
|
52
|
+
const regex = /```svg\n(.*?)\n```/s;
|
|
53
|
+
const match = content.match(regex);
|
|
54
|
+
if (!match) return content;
|
|
55
|
+
return match[1];
|
|
56
|
+
}
|
|
57
|
+
parse_json(content) {
|
|
58
|
+
if (typeof content === "object") {
|
|
59
|
+
return content;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
return JSON.parse(content);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
return JSON.parse(jsonrepair(content));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var LLM_Utils = new _LLM_Utils();
|
|
69
|
+
|
|
70
|
+
// src/agent/index.ts
|
|
71
|
+
import path from "path";
|
|
72
|
+
var Agent = class {
|
|
73
|
+
// 角色定义的提示词
|
|
74
|
+
constructor() {
|
|
75
|
+
__publicField(this, "function_call", null);
|
|
76
|
+
// 工具函数的说明文档, 供模型调用时参考
|
|
77
|
+
__publicField(this, "function_call_doc", "");
|
|
78
|
+
// 模型的聊天能力
|
|
79
|
+
__publicField(this, "llm_chat_func", null);
|
|
80
|
+
// 预置提示词
|
|
81
|
+
__publicField(this, "preset_prompt", this.get_preset_prompt());
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 注册工具函数
|
|
85
|
+
*/
|
|
86
|
+
register_function_call(function_call) {
|
|
87
|
+
const tools_list = function_call.get_tools_list();
|
|
88
|
+
this.function_call_doc = tools_list.map((val) => `\u5DE5\u5177\u51FD\u6570:${val.name}
|
|
89
|
+
\u5DE5\u5177\u63CF\u8FF0:${val.description}`).join("\n\n");
|
|
90
|
+
this.function_call = function_call;
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 注册LLM模型文字能力
|
|
95
|
+
*/
|
|
96
|
+
register_llm_text_ability(func) {
|
|
97
|
+
this.llm_chat_func = func;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 注册LLM模型图片能力
|
|
101
|
+
*/
|
|
102
|
+
register_llm_image_ability() {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 判断是否需要调用function_call, 以及调用哪个工具函数
|
|
107
|
+
*/
|
|
108
|
+
async check_whether_use_function_call(user_input) {
|
|
109
|
+
const role_prompt = `
|
|
110
|
+
\u6211\u662F\u4E00\u4E2A\u667A\u80FD\u52A9\u624B, \u6211\u4F1A\u5224\u65AD\u7528\u6237\u8F93\u5165\u662F\u5426\u9700\u8981\u8C03\u7528\u5DE5\u5177\u51FD\u6570\u6765\u8F85\u52A9\u5B8C\u6210\u4EFB\u52A1
|
|
111
|
+
- \u5982\u679C\u9700\u8981\u8C03\u7528, \u6211\u4F1A\u9996\u5148\u5224\u65AD\u81EA\u5DF1\u662F\u5426\u80FD\u89E3\u51B3,
|
|
112
|
+
- \u5982\u679C\u80FD\u89E3\u51B3, \u6211\u5C31\u8FD4\u56DE {"command": "no_use", "result": "\u4E0D\u9700\u8981\u8C03\u7528\u5DE5\u5177\u51FD\u6570"}
|
|
113
|
+
- \u5982\u679C\u4E0D\u80FD\u89E3\u51B3, \u6211\u5C31\u4F1A\u6839\u636E\u5DF2\u6709\u7684\u5DE5\u5177\u51FD\u6570\u5217\u8868\u9009\u62E9\u5DE5\u5177\u51FD\u6570 \u5E76\u4E14\u6839\u636E\u7528\u6237\u8F93\u5165\u7684\u5DE5\u5177\u51FD\u6570\u8BF4\u660E\u6587\u6863\u751F\u6210\u8C03\u7528\u53C2\u6570:
|
|
114
|
+
- \u6211\u7EDD\u5BF9\u4E0D\u4F1A\u65E0\u4E2D\u751F\u6709\u4E00\u4E2A\u5DE5\u5177\u51FD\u6570
|
|
115
|
+
- \u6211\u4E0D\u4F1A\u9020\u5047\u6570\u636E / \u865A\u62DF\u6570\u636E / \u634F\u9020\u6570\u636E
|
|
116
|
+
- \u6CA1\u6709\u7684\u5DE5\u5177\u51FD\u6570,\u6211\u4F1A\u544A\u77E5\u4F60, \u65E0\u6CD5\u6EE1\u8DB3\u4F60\u7684\u64CD\u4F5C
|
|
117
|
+
## \u6211\u53EF\u4EE5\u8C03\u7528\u5DE5\u5177\u51FD\u6570\u5217\u8868:
|
|
118
|
+
---
|
|
119
|
+
${this.function_call_doc}
|
|
120
|
+
|
|
121
|
+
## \u8F93\u51FA\u8981\u6C42
|
|
122
|
+
---
|
|
123
|
+
\u5982\u679C\u9700\u8981\u8C03\u7528\u5DE5\u5177\u51FD\u6570, \u6211\u4F1A\u8FD4\u56DE{"command": "get_tool_doc", "tool_name": "\u5DE5\u5177\u51FD\u6570\u540D\u79F0"}
|
|
124
|
+
\u5982\u679C\u4E0D\u9700\u8981\u8C03\u7528, \u8BF7\u4F1A\u8FD4\u56DE{"command": "no_use", "result": "\u4E0D\u9700\u8981\u8C03\u7528\u5DE5\u5177\u51FD\u6570"}
|
|
125
|
+
\u5982\u679C\u81EA\u8EAB\u6CA1\u80FD\u529B\u5904\u7406,\u4E14\u6CA1\u6709\u5408\u9002\u7684\u5DE5\u5177\u51FD\u6570, \u8BF7\u4F1A\u8FD4\u56DE{"command": "no_ability", "result": "\u6211\u6CA1\u80FD\u529B\u6267\u884C\u8FD9\u4E2A\u64CD\u4F5C"}
|
|
126
|
+
---
|
|
127
|
+
`;
|
|
128
|
+
const check_use_prompt = [
|
|
129
|
+
{
|
|
130
|
+
role: "system",
|
|
131
|
+
content: [
|
|
132
|
+
{ type: "text", text: role_prompt }
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
...this.deepClone(user_input)
|
|
136
|
+
];
|
|
137
|
+
const check_res = await this.llm_chat_func([
|
|
138
|
+
...check_use_prompt,
|
|
139
|
+
{
|
|
140
|
+
role: "user",
|
|
141
|
+
content: [
|
|
142
|
+
{
|
|
143
|
+
type: "text",
|
|
144
|
+
text: "\u4F60\u5FC5\u987B\u8FD4\u56DEJSON\u683C\u5F0F, \u4E0D\u80FD\u8FD4\u56DE\u591A\u4F59\u5B57\u7B26, \u4E0D\u7136\u6211\u4F1A\u89E3\u6790\u5931\u8D25\u7684"
|
|
145
|
+
}
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
]);
|
|
149
|
+
const check_res_json = LLM_Utils.extract_json(check_res);
|
|
150
|
+
if (check_res_json.command === "no_use" || check_res_json.command === "no_ability") {
|
|
151
|
+
return check_res_json;
|
|
152
|
+
}
|
|
153
|
+
check_use_prompt.push({
|
|
154
|
+
role: "assistant",
|
|
155
|
+
content: [
|
|
156
|
+
{ type: "text", text: check_res }
|
|
157
|
+
]
|
|
158
|
+
});
|
|
159
|
+
const tool_name = check_res_json.tool_name;
|
|
160
|
+
const doc = await this.function_call.gen_tool_doc(tool_name);
|
|
161
|
+
const gen_params_prompt = `
|
|
162
|
+
## \u5DE5\u5177\u51FD\u6570
|
|
163
|
+
${tool_name}
|
|
164
|
+
## \u5DE5\u5177\u51FD\u6570\u8BF4\u660E\u6587\u6863:
|
|
165
|
+
---
|
|
166
|
+
${doc}
|
|
167
|
+
---
|
|
168
|
+
\u8BF7\u4E25\u683C\u6309\u7167\u5DE5\u5177\u51FD\u6570\u7684\u8F93\u5165\u8981\u6C42, \u6839\u636E\u7528\u6237\u8F93\u5165\u548C\u5DE5\u5177\u51FD\u6570\u8BF4\u660E\u6587\u6863\u751F\u6210\u8C03\u7528\u53C2\u6570,
|
|
169
|
+
\u8F93\u51FA\u683C\u5F0F\u5FC5\u987B\u4E3Ajson\u683C\u5F0F, \u4F8B\u5982{"\u53C2\u65701": "\u503C1", "\u53C2\u65702": "\u503C2"}, \u4E0D\u80FD\u8FD4\u56DE\u591A\u4F59\u5B57\u7B26
|
|
170
|
+
`;
|
|
171
|
+
check_use_prompt.push({
|
|
172
|
+
role: "user",
|
|
173
|
+
content: [
|
|
174
|
+
{ type: "text", text: gen_params_prompt },
|
|
175
|
+
{ type: "text", text: "\u4F60\u5FC5\u987B\u8FD4\u56DEJSON\u683C\u5F0F, \u4E0D\u80FD\u8FD4\u56DE\u591A\u4F59\u5B57\u7B26, \u4E0D\u7136\u6211\u4F1A\u89E3\u6790\u5931\u8D25\u7684" }
|
|
176
|
+
]
|
|
177
|
+
});
|
|
178
|
+
const gen_params_res = await this.llm_chat_func(check_use_prompt);
|
|
179
|
+
const gen_params_json = LLM_Utils.extract_json(gen_params_res);
|
|
180
|
+
return {
|
|
181
|
+
command: "use_tool",
|
|
182
|
+
tool_name,
|
|
183
|
+
params: gen_params_json
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* 创建聊天
|
|
188
|
+
*/
|
|
189
|
+
async create_chat(user_input) {
|
|
190
|
+
const dispose_user_input = this.pre_dispose_user_input(user_input);
|
|
191
|
+
let max_loop = 20;
|
|
192
|
+
let loop_count = 1;
|
|
193
|
+
const return_data = {
|
|
194
|
+
result: "",
|
|
195
|
+
use_tools: []
|
|
196
|
+
};
|
|
197
|
+
while (loop_count <= max_loop) {
|
|
198
|
+
const check_use_tools = await this.check_whether_use_function_call(dispose_user_input);
|
|
199
|
+
if (check_use_tools.command == "use_tool") {
|
|
200
|
+
const { tool_name, params } = check_use_tools;
|
|
201
|
+
const tool_result = await this.function_call.exec_function(tool_name, params);
|
|
202
|
+
dispose_user_input.push({
|
|
203
|
+
role: "assistant",
|
|
204
|
+
content: [
|
|
205
|
+
{
|
|
206
|
+
type: "text",
|
|
207
|
+
text: `\u6211\u8981\u8C03\u7528, \u5DE5\u5177\u51FD\u6570${tool_name}
|
|
208
|
+
\u8C03\u7528\u53C2\u6570\u4E3A:
|
|
209
|
+
${JSON.stringify(params)}`
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
});
|
|
213
|
+
dispose_user_input.push({
|
|
214
|
+
role: "user",
|
|
215
|
+
content: [
|
|
216
|
+
{ type: "text", text: `\u8C03\u7528\u7ED3\u679C:
|
|
217
|
+
${JSON.stringify(tool_result)}` }
|
|
218
|
+
]
|
|
219
|
+
});
|
|
220
|
+
loop_count++;
|
|
221
|
+
return_data.use_tools.push({
|
|
222
|
+
tool_name,
|
|
223
|
+
params,
|
|
224
|
+
exec_result: tool_result
|
|
225
|
+
});
|
|
226
|
+
} else if (check_use_tools.command == "no_ability") {
|
|
227
|
+
return_data.result = "\u65E0\u6CD5\u6267\u884C\u6B64\u64CD\u4F5C";
|
|
228
|
+
return return_data;
|
|
229
|
+
} else if (check_use_tools.command == "no_use") {
|
|
230
|
+
dispose_user_input.push({
|
|
231
|
+
role: "user",
|
|
232
|
+
content: [
|
|
233
|
+
{
|
|
234
|
+
type: "text",
|
|
235
|
+
text: "\u4F60\u6839\u636E\u4E0A\u4E0B\u6587\u8FD4\u56DE\u7ED3\u679C\u5C31\u597D, \u4F60\u7684\u601D\u8003\u8FC7\u7A0B\u65E0\u9700\u8FD4\u56DE\u7ED9\u6211, \u4F60\u53EA\u9700\u8981\u56DE\u7B54\u6211\u7684\u95EE\u9898, \u4E0D\u8981\u5C06\u591A\u4F59\u7684\u4FE1\u606F\u8FD4\u56DE\u7ED9\u6211, \u4E0D\u80FD\u6267\u884C\u64CD\u4F5C\u5C31\u56DE\u590D\u65E0\u6CD5\u64CD\u4F5C"
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
});
|
|
239
|
+
const llm_chat_res = await this.llm_chat_func(dispose_user_input);
|
|
240
|
+
return_data.result = llm_chat_res;
|
|
241
|
+
return return_data;
|
|
242
|
+
} else {
|
|
243
|
+
return_data.result = "\u5F02\u5E38\u6307\u5B9A";
|
|
244
|
+
return return_data;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* agent预置提示词
|
|
250
|
+
*/
|
|
251
|
+
get_preset_prompt() {
|
|
252
|
+
const prompt = fs.readFileSync(path.join(__dirname, "./preset_prompt.md"), "utf-8");
|
|
253
|
+
return prompt;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* 预处理用户输入
|
|
257
|
+
*/
|
|
258
|
+
pre_dispose_user_input(user_input) {
|
|
259
|
+
if (typeof user_input === "string") {
|
|
260
|
+
return [
|
|
261
|
+
{
|
|
262
|
+
role: "user",
|
|
263
|
+
content: [
|
|
264
|
+
{ type: "text", text: user_input }
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
];
|
|
268
|
+
}
|
|
269
|
+
return user_input;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* 深拷贝方法
|
|
273
|
+
*/
|
|
274
|
+
deepClone(obj) {
|
|
275
|
+
if (obj === null || typeof obj !== "object") {
|
|
276
|
+
return obj;
|
|
277
|
+
}
|
|
278
|
+
if (obj instanceof Date) {
|
|
279
|
+
return new Date(obj.getTime());
|
|
280
|
+
}
|
|
281
|
+
if (obj instanceof Array) {
|
|
282
|
+
const cloneArray = [];
|
|
283
|
+
obj.forEach((item) => {
|
|
284
|
+
cloneArray.push(this.deepClone(item));
|
|
285
|
+
});
|
|
286
|
+
return cloneArray;
|
|
287
|
+
}
|
|
288
|
+
if (obj instanceof Object) {
|
|
289
|
+
const cloneObj = {};
|
|
290
|
+
for (const key in obj) {
|
|
291
|
+
if (obj.hasOwnProperty(key)) {
|
|
292
|
+
cloneObj[key] = this.deepClone(obj[key]);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return cloneObj;
|
|
296
|
+
}
|
|
297
|
+
throw new Error("Unable to copy object");
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
// src/function_call/index.ts
|
|
302
|
+
import path2 from "path";
|
|
303
|
+
import fs2 from "fs";
|
|
304
|
+
var FunctionCall = class {
|
|
305
|
+
constructor(tool_path) {
|
|
306
|
+
this.tool_path = tool_path;
|
|
307
|
+
__publicField(this, "tools", {});
|
|
308
|
+
this.init();
|
|
309
|
+
}
|
|
310
|
+
init() {
|
|
311
|
+
for (const file_name of fs2.readdirSync(this.tool_path)) {
|
|
312
|
+
const route_path = path2.join(this.tool_path, file_name);
|
|
313
|
+
const mcp = __require(route_path);
|
|
314
|
+
const info = mcp.register();
|
|
315
|
+
this.tools[info.name] = info;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* 生成完整的工具函数说明文档
|
|
320
|
+
*/
|
|
321
|
+
gen_tool_doc(name) {
|
|
322
|
+
const info = this.tools[name];
|
|
323
|
+
if (!info) {
|
|
324
|
+
throw `${name}\u5DE5\u5177\u51FD\u6570\u4E0D\u5B58\u5728`;
|
|
325
|
+
}
|
|
326
|
+
const schema = info.input_schema;
|
|
327
|
+
const schemaDesc = `\u7C7B\u578B: ${schema.type}`;
|
|
328
|
+
const params = Object.keys(schema.properties).map((key) => {
|
|
329
|
+
const item = schema.properties[key];
|
|
330
|
+
const required = schema.required?.includes(key) ? "\u5FC5\u586B" : "\u53EF\u9009";
|
|
331
|
+
const examples = item.examples && item.examples.length > 0 ? `\u793A\u4F8B\u503C: ${item.examples.join(", ")}` : "\u65E0\u793A\u4F8B";
|
|
332
|
+
return ` - ${key} (${item.type}, ${required})
|
|
333
|
+
\u8BF4\u660E: ${item.description}
|
|
334
|
+
${examples}`;
|
|
335
|
+
}).join("\n");
|
|
336
|
+
return `\u5DE5\u5177\u51FD\u6570\u540D\u79F0: ${info.name}
|
|
337
|
+
\u529F\u80FD\u63CF\u8FF0: ${info.description}
|
|
338
|
+
\u8F93\u5165\u7ED3\u6784: ${schemaDesc}
|
|
339
|
+
\u53C2\u6570\u5217\u8868:
|
|
340
|
+
${params}`;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* 获取工具函数列表
|
|
344
|
+
*/
|
|
345
|
+
get_tools_list() {
|
|
346
|
+
return Object.keys(this.tools).map((key) => {
|
|
347
|
+
const info = this.tools[key];
|
|
348
|
+
return {
|
|
349
|
+
name: info.name,
|
|
350
|
+
description: info.description
|
|
351
|
+
};
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* 执行工具函数
|
|
356
|
+
*/
|
|
357
|
+
async exec_function(name, params) {
|
|
358
|
+
const info = this.tools[name];
|
|
359
|
+
if (!info) {
|
|
360
|
+
throw `\u5DE5\u5177\u51FD\u6570${name}\u4E0D\u5B58\u5728`;
|
|
361
|
+
}
|
|
362
|
+
return await info.register_func(params);
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
export {
|
|
366
|
+
Agent,
|
|
367
|
+
FunctionCall,
|
|
368
|
+
LLM_Utils
|
|
369
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"type": "
|
|
2
|
+
"type": "commonjs",
|
|
3
3
|
"name": "p-api-agent",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
7
7
|
"files": [
|
|
@@ -24,7 +24,10 @@
|
|
|
24
24
|
"@types/lodash": "4.17.16",
|
|
25
25
|
"@types/node": "^25.3.5",
|
|
26
26
|
"javascript-obfuscator": "^4.1.1",
|
|
27
|
+
"lodash": "^4.17.23",
|
|
28
|
+
"ts-node": "^10.9.2",
|
|
27
29
|
"tsup": "^8.4.0",
|
|
30
|
+
"tsx": "^4.21.0",
|
|
28
31
|
"typescript": "5.8.3"
|
|
29
32
|
},
|
|
30
33
|
"dependencies": {
|
package/dist/index.cjs
DELETED
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
-
for (let key of __getOwnPropNames(from))
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
-
}
|
|
18
|
-
return to;
|
|
19
|
-
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
|
|
30
|
-
// src/index.ts
|
|
31
|
-
var index_exports = {};
|
|
32
|
-
__export(index_exports, {
|
|
33
|
-
Agent: () => Agent,
|
|
34
|
-
FunctionCall: () => FunctionCall,
|
|
35
|
-
LLM_Utils: () => LLM_Utils
|
|
36
|
-
});
|
|
37
|
-
module.exports = __toCommonJS(index_exports);
|
|
38
|
-
|
|
39
|
-
// src/agent/index.ts
|
|
40
|
-
var import_fs = __toESM(require("fs"), 1);
|
|
41
|
-
|
|
42
|
-
// src/utils/llm_utils.ts
|
|
43
|
-
var import_jsonrepair = require("jsonrepair");
|
|
44
|
-
var _LLM_Utils = class {
|
|
45
|
-
/**
|
|
46
|
-
* 提取大模型返回的markdown
|
|
47
|
-
*/
|
|
48
|
-
extract_markdown(content) {
|
|
49
|
-
const regex = /```markdown\n(.*?)\n```/s;
|
|
50
|
-
const match = content.match(regex);
|
|
51
|
-
if (!match) return content;
|
|
52
|
-
return match[1];
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* 提取大模型的json格式
|
|
56
|
-
*/
|
|
57
|
-
extract_json(content) {
|
|
58
|
-
const regex = /```json\n(.*?)\n```/s;
|
|
59
|
-
const match = content.match(regex);
|
|
60
|
-
let json_content = match ? match[1] : content;
|
|
61
|
-
try {
|
|
62
|
-
return JSON.parse(json_content);
|
|
63
|
-
} catch (err) {
|
|
64
|
-
return JSON.parse((0, import_jsonrepair.jsonrepair)(json_content));
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* 提取mermaid格式
|
|
69
|
-
*/
|
|
70
|
-
extract_mermaid(content) {
|
|
71
|
-
const regex = /```mermaid\n(.*?)\n```/s;
|
|
72
|
-
const match = content.match(regex);
|
|
73
|
-
if (!match) return content;
|
|
74
|
-
return match[1];
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* 提取svg格式
|
|
78
|
-
*/
|
|
79
|
-
extract_svg(content) {
|
|
80
|
-
const regex = /```svg\n(.*?)\n```/s;
|
|
81
|
-
const match = content.match(regex);
|
|
82
|
-
if (!match) return content;
|
|
83
|
-
return match[1];
|
|
84
|
-
}
|
|
85
|
-
parse_json(content) {
|
|
86
|
-
if (typeof content === "object") {
|
|
87
|
-
return content;
|
|
88
|
-
}
|
|
89
|
-
try {
|
|
90
|
-
return JSON.parse(content);
|
|
91
|
-
} catch (err) {
|
|
92
|
-
return JSON.parse((0, import_jsonrepair.jsonrepair)(content));
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
var LLM_Utils = new _LLM_Utils();
|
|
97
|
-
|
|
98
|
-
// src/agent/index.ts
|
|
99
|
-
var import_path = __toESM(require("path"), 1);
|
|
100
|
-
var Agent = class {
|
|
101
|
-
// 角色定义的提示词
|
|
102
|
-
constructor() {
|
|
103
|
-
this.function_call = null;
|
|
104
|
-
// 工具函数的说明文档, 供模型调用时参考
|
|
105
|
-
this.function_call_doc = "";
|
|
106
|
-
// 模型的聊天能力
|
|
107
|
-
this.llm_chat_func = null;
|
|
108
|
-
// 预置提示词
|
|
109
|
-
this.preset_prompt = this.get_preset_prompt();
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* 注册工具函数
|
|
113
|
-
*/
|
|
114
|
-
register_function_call(function_call) {
|
|
115
|
-
const tools_list = function_call.get_tools_list();
|
|
116
|
-
this.function_call_doc = tools_list.map((val) => `\u5DE5\u5177\u51FD\u6570:${val.name}
|
|
117
|
-
\u5DE5\u5177\u63CF\u8FF0:${val.description}`).join("\n\n");
|
|
118
|
-
this.function_call = function_call;
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* 注册LLM模型文字能力
|
|
123
|
-
*/
|
|
124
|
-
register_llm_text_ability(func) {
|
|
125
|
-
this.llm_chat_func = func;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* 注册LLM模型图片能力
|
|
129
|
-
*/
|
|
130
|
-
register_llm_image_ability() {
|
|
131
|
-
return true;
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* 创建聊天
|
|
135
|
-
*/
|
|
136
|
-
async create_chat(user_input) {
|
|
137
|
-
let dispose_user_input;
|
|
138
|
-
if (typeof user_input === "string") {
|
|
139
|
-
dispose_user_input = [
|
|
140
|
-
{
|
|
141
|
-
role: "user",
|
|
142
|
-
content: [
|
|
143
|
-
{ type: "text", text: user_input }
|
|
144
|
-
]
|
|
145
|
-
}
|
|
146
|
-
];
|
|
147
|
-
} else {
|
|
148
|
-
dispose_user_input = JSON.parse(JSON.stringify(user_input));
|
|
149
|
-
}
|
|
150
|
-
if (this.function_call_doc) {
|
|
151
|
-
dispose_user_input.unshift({
|
|
152
|
-
role: "system",
|
|
153
|
-
content: [
|
|
154
|
-
{ type: "text", text: `# \u5DE5\u5177\u51FD\u6570\u8BF4\u660E\u6587\u6863:
|
|
155
|
-
${this.function_call_doc}` }
|
|
156
|
-
]
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
dispose_user_input.unshift({
|
|
160
|
-
role: "system",
|
|
161
|
-
content: [
|
|
162
|
-
{ type: "text", text: this.preset_prompt }
|
|
163
|
-
]
|
|
164
|
-
});
|
|
165
|
-
let max_loop = 20;
|
|
166
|
-
let loop_count = 0;
|
|
167
|
-
while (loop_count < max_loop) {
|
|
168
|
-
const llm_res_str = await this.llm_chat_func(dispose_user_input);
|
|
169
|
-
const llm_res = LLM_Utils.extract_json(llm_res_str);
|
|
170
|
-
if (!llm_res.command) throw "\u5F02\u5E38\u6307\u4EE4, \u672A\u5305\u542Bcommand\u5B57\u6BB5";
|
|
171
|
-
if (llm_res.command === "end") {
|
|
172
|
-
return llm_res.result;
|
|
173
|
-
} else if (llm_res.command === "get_tool_doc") {
|
|
174
|
-
const tool_name = llm_res.tool_name;
|
|
175
|
-
const tool_doc = this.function_call.gen_tool_doc(tool_name);
|
|
176
|
-
dispose_user_input.push({
|
|
177
|
-
role: "user",
|
|
178
|
-
content: [
|
|
179
|
-
{ type: "text", text: `\u5DE5\u5177\u51FD\u6570${tool_name}\u7684\u8BF4\u660E\u6587\u6863:
|
|
180
|
-
${tool_doc}` }
|
|
181
|
-
]
|
|
182
|
-
});
|
|
183
|
-
} else if (llm_res.command === "use_tool") {
|
|
184
|
-
const tool_name = llm_res.tool_name;
|
|
185
|
-
const tool_params = LLM_Utils.parse_json(llm_res.params);
|
|
186
|
-
const tool_result = await this.function_call.exec_function(tool_name, tool_params);
|
|
187
|
-
dispose_user_input.push({
|
|
188
|
-
role: "user",
|
|
189
|
-
content: [
|
|
190
|
-
{ type: "text", text: `\u5DE5\u5177\u51FD\u6570${tool_name}\u7684\u8C03\u7528\u7ED3\u679C:
|
|
191
|
-
${JSON.stringify(tool_result)}` }
|
|
192
|
-
]
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
loop_count++;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* agent预置提示词
|
|
200
|
-
*/
|
|
201
|
-
get_preset_prompt() {
|
|
202
|
-
const prompt = import_fs.default.readFileSync(import_path.default.join(__dirname, "./preset_prompt.md"), "utf-8");
|
|
203
|
-
return prompt;
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
// src/function_call/index.ts
|
|
208
|
-
var import_path2 = __toESM(require("path"), 1);
|
|
209
|
-
var import_fs2 = __toESM(require("fs"), 1);
|
|
210
|
-
var FunctionCall = class {
|
|
211
|
-
constructor(tool_path) {
|
|
212
|
-
this.tool_path = tool_path;
|
|
213
|
-
this.tools = {};
|
|
214
|
-
this.init();
|
|
215
|
-
}
|
|
216
|
-
init() {
|
|
217
|
-
for (const file_name of import_fs2.default.readdirSync(this.tool_path)) {
|
|
218
|
-
const route_path = import_path2.default.join(this.tool_path, file_name);
|
|
219
|
-
const mcp = require(route_path);
|
|
220
|
-
const info = mcp.register();
|
|
221
|
-
this.tools[info.name] = info;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
/**
|
|
225
|
-
* 生成完整的工具函数说明文档
|
|
226
|
-
*/
|
|
227
|
-
gen_tool_doc(name) {
|
|
228
|
-
const info = this.tools[name];
|
|
229
|
-
const schema = info.input_schema;
|
|
230
|
-
const schemaDesc = `\u7C7B\u578B: ${schema.type}`;
|
|
231
|
-
const params = Object.keys(schema.properties).map((key) => {
|
|
232
|
-
const item = schema.properties[key];
|
|
233
|
-
const required = schema.required?.includes(key) ? "\u5FC5\u586B" : "\u53EF\u9009";
|
|
234
|
-
const examples = item.examples && item.examples.length > 0 ? `\u793A\u4F8B\u503C: ${item.examples.join(", ")}` : "\u65E0\u793A\u4F8B";
|
|
235
|
-
return ` - ${key} (${item.type}, ${required})
|
|
236
|
-
\u8BF4\u660E: ${item.description}
|
|
237
|
-
${examples}`;
|
|
238
|
-
}).join("\n");
|
|
239
|
-
return `\u5DE5\u5177\u51FD\u6570\u540D\u79F0: ${info.name}
|
|
240
|
-
\u529F\u80FD\u63CF\u8FF0: ${info.description}
|
|
241
|
-
\u8F93\u5165\u7ED3\u6784: ${schemaDesc}
|
|
242
|
-
\u53C2\u6570\u5217\u8868:
|
|
243
|
-
${params}`;
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* 获取工具函数列表
|
|
247
|
-
*/
|
|
248
|
-
get_tools_list() {
|
|
249
|
-
return Object.keys(this.tools).map((key) => {
|
|
250
|
-
const info = this.tools[key];
|
|
251
|
-
return {
|
|
252
|
-
name: info.name,
|
|
253
|
-
description: info.description
|
|
254
|
-
};
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* 执行工具函数
|
|
259
|
-
*/
|
|
260
|
-
async exec_function(name, params) {
|
|
261
|
-
const info = this.tools[name];
|
|
262
|
-
if (!info) {
|
|
263
|
-
throw `\u5DE5\u5177\u51FD\u6570${name}\u4E0D\u5B58\u5728`;
|
|
264
|
-
}
|
|
265
|
-
return await info.register_func(params);
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
269
|
-
0 && (module.exports = {
|
|
270
|
-
Agent,
|
|
271
|
-
FunctionCall,
|
|
272
|
-
LLM_Utils
|
|
273
|
-
});
|