p-api-agent 0.0.2 → 0.0.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/dist/index.mjs DELETED
@@ -1,369 +0,0 @@
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
- };