p-api-agent 0.0.2 → 0.0.4
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 +204 -208
- package/dist/index.cjs +372 -0
- package/dist/index.d.cts +148 -0
- package/dist/index.d.ts +68 -38
- package/dist/index.js +188 -245
- package/package.json +3 -3
- package/dist/index.d.mts +0 -118
- package/dist/index.mjs +0 -369
package/dist/index.js
CHANGED
|
@@ -1,47 +1,18 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
1
|
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
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
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');
|
|
37
8
|
});
|
|
38
|
-
|
|
9
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
39
10
|
|
|
40
11
|
// src/agent/index.ts
|
|
41
|
-
|
|
12
|
+
import fs from "fs";
|
|
42
13
|
|
|
43
14
|
// src/utils/llm_utils.ts
|
|
44
|
-
|
|
15
|
+
import { jsonrepair } from "jsonrepair";
|
|
45
16
|
var _LLM_Utils = class {
|
|
46
17
|
/**
|
|
47
18
|
* 提取大模型返回的markdown
|
|
@@ -62,7 +33,7 @@ var _LLM_Utils = class {
|
|
|
62
33
|
try {
|
|
63
34
|
return JSON.parse(json_content);
|
|
64
35
|
} catch (err) {
|
|
65
|
-
return JSON.parse(
|
|
36
|
+
return JSON.parse(jsonrepair(json_content));
|
|
66
37
|
}
|
|
67
38
|
}
|
|
68
39
|
/**
|
|
@@ -90,246 +61,206 @@ var _LLM_Utils = class {
|
|
|
90
61
|
try {
|
|
91
62
|
return JSON.parse(content);
|
|
92
63
|
} catch (err) {
|
|
93
|
-
return JSON.parse(
|
|
64
|
+
return JSON.parse(jsonrepair(content));
|
|
94
65
|
}
|
|
95
66
|
}
|
|
96
67
|
};
|
|
97
68
|
var LLM_Utils = new _LLM_Utils();
|
|
98
69
|
|
|
99
70
|
// src/agent/index.ts
|
|
100
|
-
|
|
71
|
+
import path from "path";
|
|
101
72
|
var Agent = class {
|
|
102
|
-
|
|
103
|
-
constructor() {
|
|
73
|
+
constructor(options = {}) {
|
|
104
74
|
__publicField(this, "function_call", null);
|
|
105
|
-
// 工具函数的说明文档, 供模型调用时参考
|
|
106
|
-
__publicField(this, "function_call_doc", "");
|
|
107
|
-
// 模型的聊天能力
|
|
108
75
|
__publicField(this, "llm_chat_func", null);
|
|
109
|
-
|
|
110
|
-
__publicField(this, "
|
|
76
|
+
__publicField(this, "max_loop");
|
|
77
|
+
__publicField(this, "retry_times");
|
|
78
|
+
__publicField(this, "custom_system_prompt", null);
|
|
79
|
+
this.max_loop = options.maxLoop ?? 20;
|
|
80
|
+
this.retry_times = options.retryTimes ?? 2;
|
|
81
|
+
if (options.customSystemPrompt) {
|
|
82
|
+
this.custom_system_prompt = options.customSystemPrompt;
|
|
83
|
+
}
|
|
111
84
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.function_call_doc = tools_list.map((val) => `\u5DE5\u5177\u51FD\u6570:${val.name}
|
|
118
|
-
\u5DE5\u5177\u63CF\u8FF0:${val.description}`).join("\n\n");
|
|
119
|
-
this.function_call = function_call;
|
|
120
|
-
return true;
|
|
85
|
+
// ─────────── Registration ───────────
|
|
86
|
+
/** 注册工具函数集合,支持链式调用 */
|
|
87
|
+
register_function_call(fc) {
|
|
88
|
+
this.function_call = fc;
|
|
89
|
+
return this;
|
|
121
90
|
}
|
|
122
|
-
/**
|
|
123
|
-
* 注册LLM模型文字能力
|
|
124
|
-
*/
|
|
91
|
+
/** 注册 LLM 文字能力,支持链式调用 */
|
|
125
92
|
register_llm_text_ability(func) {
|
|
126
93
|
this.llm_chat_func = func;
|
|
94
|
+
return this;
|
|
127
95
|
}
|
|
128
|
-
/**
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return true;
|
|
96
|
+
/** 覆盖系统提示词 */
|
|
97
|
+
set_system_prompt(prompt) {
|
|
98
|
+
this.custom_system_prompt = prompt;
|
|
99
|
+
return this;
|
|
133
100
|
}
|
|
134
|
-
/**
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
{
|
|
159
|
-
role: "system",
|
|
160
|
-
content: [
|
|
161
|
-
{ type: "text", text: role_prompt }
|
|
162
|
-
]
|
|
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;
|
|
181
|
-
}
|
|
182
|
-
check_use_prompt.push({
|
|
183
|
-
role: "assistant",
|
|
184
|
-
content: [
|
|
185
|
-
{ type: "text", text: check_res }
|
|
186
|
-
]
|
|
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
|
-
};
|
|
101
|
+
/** 动态修改最大循环次数 */
|
|
102
|
+
set_max_loop(n) {
|
|
103
|
+
this.max_loop = n;
|
|
104
|
+
return this;
|
|
214
105
|
}
|
|
106
|
+
// ─────────── Main ReAct Loop ───────────
|
|
215
107
|
/**
|
|
216
|
-
*
|
|
108
|
+
* 发起对话。
|
|
109
|
+
*
|
|
110
|
+
* 架构:ReAct 单调用循环
|
|
111
|
+
* 每轮只调用一次 LLM,LLM 在拥有完整工具 schema 的系统提示词下
|
|
112
|
+
* 直接输出 end / use_tool / no_ability 三种指令,
|
|
113
|
+
* 彻底消除了旧版 "判断→查文档→生成参数→再生成答案" 的多次调用开销。
|
|
217
114
|
*/
|
|
218
115
|
async create_chat(user_input) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const
|
|
223
|
-
|
|
224
|
-
|
|
116
|
+
if (!this.llm_chat_func) {
|
|
117
|
+
return { result: "\u672A\u6CE8\u518CLLM\u80FD\u529B", use_tools: [] };
|
|
118
|
+
}
|
|
119
|
+
const history = this.normalize_input(user_input);
|
|
120
|
+
const system_msg = {
|
|
121
|
+
role: "system",
|
|
122
|
+
content: [{ type: "text", text: this.build_system_prompt() }]
|
|
225
123
|
};
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
124
|
+
const result = { result: "", use_tools: [] };
|
|
125
|
+
const tool_fail_count = {};
|
|
126
|
+
for (let turn = 0; turn < this.max_loop; turn++) {
|
|
127
|
+
let raw;
|
|
128
|
+
try {
|
|
129
|
+
raw = await this.call_llm_with_retry([system_msg, ...history]);
|
|
130
|
+
} catch (err) {
|
|
131
|
+
result.result = `LLM\u8C03\u7528\u5931\u8D25: ${err?.message ?? String(err)}`;
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
const cmd = this.parse_command(raw);
|
|
135
|
+
if (!cmd) {
|
|
136
|
+
result.result = raw;
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
if (cmd.command === "end") {
|
|
140
|
+
result.result = cmd.result;
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
if (cmd.command === "no_ability") {
|
|
144
|
+
result.result = cmd.result || "\u65E0\u6CD5\u6267\u884C\u6B64\u64CD\u4F5C";
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
if (cmd.command === "use_tool") {
|
|
148
|
+
const { tool_name, params } = cmd;
|
|
149
|
+
if (!this.function_call) {
|
|
150
|
+
result.result = "\u672A\u6CE8\u518C\u5DE5\u5177\u51FD\u6570\u96C6\u5408\uFF0C\u65E0\u6CD5\u6267\u884C\u5DE5\u5177\u8C03\u7528";
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
history.push({
|
|
232
154
|
role: "assistant",
|
|
233
|
-
content: [
|
|
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
|
-
}
|
|
240
|
-
]
|
|
241
|
-
});
|
|
242
|
-
dispose_user_input.push({
|
|
243
|
-
role: "user",
|
|
244
|
-
content: [
|
|
245
|
-
{ type: "text", text: `\u8C03\u7528\u7ED3\u679C:
|
|
246
|
-
${JSON.stringify(tool_result)}` }
|
|
247
|
-
]
|
|
248
|
-
});
|
|
249
|
-
loop_count++;
|
|
250
|
-
return_data.use_tools.push({
|
|
251
|
-
tool_name,
|
|
252
|
-
params,
|
|
253
|
-
exec_result: tool_result
|
|
155
|
+
content: [{ type: "text", text: raw }]
|
|
254
156
|
});
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
157
|
+
let tool_result;
|
|
158
|
+
try {
|
|
159
|
+
tool_result = await this.function_call.exec_function(tool_name, params);
|
|
160
|
+
} catch (err) {
|
|
161
|
+
const err_msg = err?.message ?? String(err);
|
|
162
|
+
tool_fail_count[tool_name] = (tool_fail_count[tool_name] ?? 0) + 1;
|
|
163
|
+
history.push({
|
|
164
|
+
role: "user",
|
|
165
|
+
content: [{
|
|
263
166
|
type: "text",
|
|
264
|
-
text:
|
|
265
|
-
|
|
266
|
-
|
|
167
|
+
text: `[\u5DE5\u5177\u6267\u884C\u5931\u8D25] ${tool_name}
|
|
168
|
+
\u9519\u8BEF\u4FE1\u606F: ${err_msg}
|
|
169
|
+
\u8BF7\u6839\u636E\u9519\u8BEF\u8C03\u6574\u7B56\u7565\u540E\u7EE7\u7EED`
|
|
170
|
+
}]
|
|
171
|
+
});
|
|
172
|
+
if (tool_fail_count[tool_name] >= 2) {
|
|
173
|
+
result.result = `\u5DE5\u5177 "${tool_name}" \u8FDE\u7EED\u8C03\u7528\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5`;
|
|
174
|
+
return result;
|
|
175
|
+
}
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
history.push({
|
|
179
|
+
role: "user",
|
|
180
|
+
content: [{
|
|
181
|
+
type: "text",
|
|
182
|
+
text: `[\u5DE5\u5177\u8C03\u7528\u7ED3\u679C] ${tool_name}
|
|
183
|
+
${JSON.stringify(tool_result, null, 2)}`
|
|
184
|
+
}]
|
|
267
185
|
});
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
return return_data;
|
|
271
|
-
} else {
|
|
272
|
-
return_data.result = "\u5F02\u5E38\u6307\u5B9A";
|
|
273
|
-
return return_data;
|
|
186
|
+
result.use_tools.push({ tool_name, params, exec_result: tool_result });
|
|
187
|
+
continue;
|
|
274
188
|
}
|
|
275
189
|
}
|
|
190
|
+
result.result = "\u8D85\u51FA\u6700\u5927\u63A8\u7406\u8F6E\u6B21\uFF0C\u8BF7\u7CBE\u7B80\u95EE\u9898\u540E\u91CD\u8BD5";
|
|
191
|
+
return result;
|
|
276
192
|
}
|
|
193
|
+
// ─────────── System Prompt ───────────
|
|
277
194
|
/**
|
|
278
|
-
*
|
|
195
|
+
* 构建系统提示词。
|
|
196
|
+
* 将所有工具的完整 schema(含参数类型、必填项、示例值)
|
|
197
|
+
* 直接注入系统提示词,让 LLM 在单次调用中就能做出准确的工具选择和参数填写。
|
|
279
198
|
*/
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
199
|
+
build_system_prompt() {
|
|
200
|
+
if (this.custom_system_prompt) return this.custom_system_prompt;
|
|
201
|
+
const base = this.load_preset_prompt();
|
|
202
|
+
if (!this.function_call) return base;
|
|
203
|
+
const tool_schemas = this.function_call.get_tools_with_schema().map((t) => {
|
|
204
|
+
const props = Object.entries(t.input_schema.properties).map(([k, v]) => {
|
|
205
|
+
const req = t.input_schema.required?.includes(k) ? "\u5FC5\u586B" : "\u53EF\u9009";
|
|
206
|
+
const ex = v.examples?.length ? `\uFF0C\u793A\u4F8B: ${v.examples.join(" / ")}` : "";
|
|
207
|
+
return ` - ${k} (${v.type}, ${req}): ${v.description}${ex}`;
|
|
208
|
+
}).join("\n");
|
|
209
|
+
return `### ${t.name}
|
|
210
|
+
\u63CF\u8FF0: ${t.description}
|
|
211
|
+
\u53C2\u6570:
|
|
212
|
+
${props}`;
|
|
213
|
+
}).join("\n\n");
|
|
214
|
+
return `${base}
|
|
215
|
+
|
|
216
|
+
## \u53EF\u7528\u5DE5\u5177\u5217\u8868
|
|
217
|
+
|
|
218
|
+
${tool_schemas}`;
|
|
283
219
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return [
|
|
290
|
-
{
|
|
291
|
-
role: "user",
|
|
292
|
-
content: [
|
|
293
|
-
{ type: "text", text: user_input }
|
|
294
|
-
]
|
|
295
|
-
}
|
|
296
|
-
];
|
|
220
|
+
load_preset_prompt() {
|
|
221
|
+
try {
|
|
222
|
+
return fs.readFileSync(path.join(__dirname, "./preset_prompt.md"), "utf-8");
|
|
223
|
+
} catch {
|
|
224
|
+
return "";
|
|
297
225
|
}
|
|
298
|
-
return user_input;
|
|
299
226
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
if (obj === null || typeof obj !== "object") {
|
|
305
|
-
return obj;
|
|
227
|
+
// ─────────── Helpers ───────────
|
|
228
|
+
normalize_input(input) {
|
|
229
|
+
if (typeof input === "string") {
|
|
230
|
+
return [{ role: "user", content: [{ type: "text", text: input }] }];
|
|
306
231
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
232
|
+
return [...input];
|
|
233
|
+
}
|
|
234
|
+
parse_command(raw) {
|
|
235
|
+
const json = this.safe_extract_json(raw);
|
|
236
|
+
if (!json || typeof json.command !== "string") return null;
|
|
237
|
+
return json;
|
|
238
|
+
}
|
|
239
|
+
safe_extract_json(content) {
|
|
240
|
+
try {
|
|
241
|
+
return LLM_Utils.extract_json(content);
|
|
242
|
+
} catch {
|
|
243
|
+
return null;
|
|
316
244
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
245
|
+
}
|
|
246
|
+
async call_llm_with_retry(input) {
|
|
247
|
+
let last_error;
|
|
248
|
+
for (let i = 0; i <= this.retry_times; i++) {
|
|
249
|
+
try {
|
|
250
|
+
const res = await this.llm_chat_func(input);
|
|
251
|
+
if (typeof res === "string" && res.trim()) return res;
|
|
252
|
+
throw new Error("\u7A7A\u54CD\u5E94");
|
|
253
|
+
} catch (err) {
|
|
254
|
+
last_error = err;
|
|
323
255
|
}
|
|
324
|
-
return cloneObj;
|
|
325
256
|
}
|
|
326
|
-
throw new Error("
|
|
257
|
+
throw last_error ?? new Error("LLM\u8C03\u7528\u5931\u8D25");
|
|
327
258
|
}
|
|
328
259
|
};
|
|
329
260
|
|
|
330
261
|
// src/function_call/index.ts
|
|
331
|
-
|
|
332
|
-
|
|
262
|
+
import path2 from "path";
|
|
263
|
+
import fs2 from "fs";
|
|
333
264
|
var FunctionCall = class {
|
|
334
265
|
constructor(tool_path) {
|
|
335
266
|
this.tool_path = tool_path;
|
|
@@ -337,9 +268,9 @@ var FunctionCall = class {
|
|
|
337
268
|
this.init();
|
|
338
269
|
}
|
|
339
270
|
init() {
|
|
340
|
-
for (const file_name of
|
|
341
|
-
const route_path =
|
|
342
|
-
const mcp =
|
|
271
|
+
for (const file_name of fs2.readdirSync(this.tool_path)) {
|
|
272
|
+
const route_path = path2.join(this.tool_path, file_name);
|
|
273
|
+
const mcp = __require(route_path);
|
|
343
274
|
const info = mcp.register();
|
|
344
275
|
this.tools[info.name] = info;
|
|
345
276
|
}
|
|
@@ -369,7 +300,7 @@ var FunctionCall = class {
|
|
|
369
300
|
${params}`;
|
|
370
301
|
}
|
|
371
302
|
/**
|
|
372
|
-
*
|
|
303
|
+
* 获取工具函数列表(仅名称 + 描述)
|
|
373
304
|
*/
|
|
374
305
|
get_tools_list() {
|
|
375
306
|
return Object.keys(this.tools).map((key) => {
|
|
@@ -380,6 +311,19 @@ ${params}`;
|
|
|
380
311
|
};
|
|
381
312
|
});
|
|
382
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* 获取工具函数列表(含完整 input_schema),供 Agent 注入系统提示词
|
|
316
|
+
*/
|
|
317
|
+
get_tools_with_schema() {
|
|
318
|
+
return Object.keys(this.tools).map((key) => {
|
|
319
|
+
const info = this.tools[key];
|
|
320
|
+
return {
|
|
321
|
+
name: info.name,
|
|
322
|
+
description: info.description,
|
|
323
|
+
input_schema: info.input_schema
|
|
324
|
+
};
|
|
325
|
+
});
|
|
326
|
+
}
|
|
383
327
|
/**
|
|
384
328
|
* 执行工具函数
|
|
385
329
|
*/
|
|
@@ -391,9 +335,8 @@ ${params}`;
|
|
|
391
335
|
return await info.register_func(params);
|
|
392
336
|
}
|
|
393
337
|
};
|
|
394
|
-
|
|
395
|
-
0 && (module.exports = {
|
|
338
|
+
export {
|
|
396
339
|
Agent,
|
|
397
340
|
FunctionCall,
|
|
398
341
|
LLM_Utils
|
|
399
|
-
}
|
|
342
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"type": "commonjs",
|
|
3
2
|
"name": "p-api-agent",
|
|
4
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
5
4
|
"main": "./dist/index.cjs",
|
|
6
5
|
"module": "./dist/index.mjs",
|
|
7
6
|
"files": [
|
|
@@ -33,5 +32,6 @@
|
|
|
33
32
|
"dependencies": {
|
|
34
33
|
"axios": "^1.13.6",
|
|
35
34
|
"jsonrepair": "^3.13.2"
|
|
36
|
-
}
|
|
35
|
+
},
|
|
36
|
+
"type": "module"
|
|
37
37
|
}
|
package/dist/index.d.mts
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
interface RegisterInfo {
|
|
2
|
-
name: string;
|
|
3
|
-
description: string;
|
|
4
|
-
input_schema: {
|
|
5
|
-
type: string;
|
|
6
|
-
properties: {
|
|
7
|
-
[key: string]: {
|
|
8
|
-
type: string;
|
|
9
|
-
description: string;
|
|
10
|
-
examples?: string[];
|
|
11
|
-
};
|
|
12
|
-
};
|
|
13
|
-
required?: string[];
|
|
14
|
-
};
|
|
15
|
-
register_func: (...args: any[]) => Promise<any>;
|
|
16
|
-
}
|
|
17
|
-
declare class FunctionCall {
|
|
18
|
-
tool_path: string;
|
|
19
|
-
private tools;
|
|
20
|
-
constructor(tool_path: string);
|
|
21
|
-
private init;
|
|
22
|
-
/**
|
|
23
|
-
* 生成完整的工具函数说明文档
|
|
24
|
-
*/
|
|
25
|
-
gen_tool_doc(name: string): string;
|
|
26
|
-
/**
|
|
27
|
-
* 获取工具函数列表
|
|
28
|
-
*/
|
|
29
|
-
get_tools_list(): {
|
|
30
|
-
name: string;
|
|
31
|
-
description: string;
|
|
32
|
-
}[];
|
|
33
|
-
/**
|
|
34
|
-
* 执行工具函数
|
|
35
|
-
*/
|
|
36
|
-
exec_function(name: string, params: any): Promise<any>;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
interface TextContent {
|
|
40
|
-
type: 'text';
|
|
41
|
-
text: string;
|
|
42
|
-
}
|
|
43
|
-
interface ImageContent {
|
|
44
|
-
type: 'image_url';
|
|
45
|
-
image_url: {
|
|
46
|
-
url: string;
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
type Content = TextContent | ImageContent;
|
|
50
|
-
type UserChatInput = {
|
|
51
|
-
role: 'system' | 'user' | 'assistant';
|
|
52
|
-
content: Content[];
|
|
53
|
-
}[];
|
|
54
|
-
declare class Agent {
|
|
55
|
-
private function_call;
|
|
56
|
-
private function_call_doc;
|
|
57
|
-
private llm_chat_func;
|
|
58
|
-
preset_prompt: string;
|
|
59
|
-
constructor();
|
|
60
|
-
/**
|
|
61
|
-
* 注册工具函数
|
|
62
|
-
*/
|
|
63
|
-
register_function_call(function_call: FunctionCall): boolean;
|
|
64
|
-
/**
|
|
65
|
-
* 注册LLM模型文字能力
|
|
66
|
-
*/
|
|
67
|
-
register_llm_text_ability(func: (user_input: UserChatInput) => Promise<string>): void;
|
|
68
|
-
/**
|
|
69
|
-
* 注册LLM模型图片能力
|
|
70
|
-
*/
|
|
71
|
-
register_llm_image_ability(): boolean;
|
|
72
|
-
/**
|
|
73
|
-
* 判断是否需要调用function_call, 以及调用哪个工具函数
|
|
74
|
-
*/
|
|
75
|
-
check_whether_use_function_call(user_input: UserChatInput): Promise<any>;
|
|
76
|
-
/**
|
|
77
|
-
* 创建聊天
|
|
78
|
-
*/
|
|
79
|
-
create_chat(user_input: string | UserChatInput): Promise<{
|
|
80
|
-
result: string;
|
|
81
|
-
use_tools: any[];
|
|
82
|
-
}>;
|
|
83
|
-
/**
|
|
84
|
-
* agent预置提示词
|
|
85
|
-
*/
|
|
86
|
-
get_preset_prompt(): string;
|
|
87
|
-
/**
|
|
88
|
-
* 预处理用户输入
|
|
89
|
-
*/
|
|
90
|
-
pre_dispose_user_input(user_input: string | UserChatInput): UserChatInput;
|
|
91
|
-
/**
|
|
92
|
-
* 深拷贝方法
|
|
93
|
-
*/
|
|
94
|
-
private deepClone;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
declare class _LLM_Utils {
|
|
98
|
-
/**
|
|
99
|
-
* 提取大模型返回的markdown
|
|
100
|
-
*/
|
|
101
|
-
extract_markdown(content: any): any;
|
|
102
|
-
/**
|
|
103
|
-
* 提取大模型的json格式
|
|
104
|
-
*/
|
|
105
|
-
extract_json(content: any): any;
|
|
106
|
-
/**
|
|
107
|
-
* 提取mermaid格式
|
|
108
|
-
*/
|
|
109
|
-
extract_mermaid(content: any): any;
|
|
110
|
-
/**
|
|
111
|
-
* 提取svg格式
|
|
112
|
-
*/
|
|
113
|
-
extract_svg(content: any): any;
|
|
114
|
-
parse_json(content: string | object): any;
|
|
115
|
-
}
|
|
116
|
-
declare const LLM_Utils: _LLM_Utils;
|
|
117
|
-
|
|
118
|
-
export { Agent, FunctionCall, LLM_Utils, type RegisterInfo };
|