p-api-agent 0.0.1

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 ADDED
@@ -0,0 +1,309 @@
1
+ # P-API-Agent
2
+
3
+ 一个基于 LLM 的智能 Agent 框架,支持工具函数调用和多轮对话。
4
+
5
+ ## 特性
6
+
7
+ - 🤖 **智能对话**: 基于 LLM 的智能对话能力
8
+ - 🔧 **工具调用**: 支持动态注册和调用工具函数
9
+ - 📝 **类型安全**: 完整的 TypeScript 类型定义
10
+ - 🛡️ **错误处理**: 完善的错误处理和日志系统
11
+ - ⚙️ **可配置**: 灵活的配置选项
12
+ - 📊 **日志系统**: 多级别日志输出
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ npm install p-api-agent
18
+ ```
19
+
20
+ ## 快速开始
21
+
22
+ ### 基础用法
23
+
24
+ ```typescript
25
+ import { Agent, FunctionCall } from 'p-api-agent';
26
+
27
+ // 创建 Agent 实例
28
+ const agent = new Agent({
29
+ maxLoop: 20, // 最大循环次数
30
+ debug: false // 调试模式
31
+ });
32
+
33
+ // 注册 LLM 聊天能力
34
+ agent.register_llm_text_ability(async (messages) => {
35
+ // 调用您的 LLM API
36
+ const response = await yourLLMAPI(messages);
37
+ return response;
38
+ });
39
+
40
+ // 注册工具函数(可选)
41
+ const functionCall = new FunctionCall('/path/to/tools');
42
+ agent.register_function_call(functionCall);
43
+
44
+ // 开始对话
45
+ const result = await agent.create_chat('你好,请帮我完成任务');
46
+ console.log(result);
47
+ ```
48
+
49
+ ### 创建工具函数
50
+
51
+ 在工具目录下创建 `.js` 或 `.ts` 文件:
52
+
53
+ ```typescript
54
+ // tools/get_weather.ts
55
+ export function register() {
56
+ return {
57
+ name: 'get_weather',
58
+ description: '获取指定城市的天气信息',
59
+ input_schema: {
60
+ type: 'object',
61
+ properties: {
62
+ city: {
63
+ type: 'string',
64
+ description: '城市名称',
65
+ examples: ['北京', '上海', '深圳']
66
+ }
67
+ },
68
+ required: ['city']
69
+ },
70
+ register_func: async (params: { city: string }) => {
71
+ // 实现您的工具逻辑
72
+ return {
73
+ city: params.city,
74
+ temperature: 25,
75
+ weather: '晴天'
76
+ };
77
+ }
78
+ };
79
+ }
80
+ ```
81
+
82
+ ### 自定义提示词
83
+
84
+ ```typescript
85
+ const agent = new Agent({
86
+ customPresetPrompt: `
87
+ 你是一个专业的助手...
88
+ (自定义提示词内容)
89
+ `
90
+ });
91
+ ```
92
+
93
+ ## API 文档
94
+
95
+ ### Agent 类
96
+
97
+ #### 构造函数
98
+
99
+ ```typescript
100
+ new Agent(options?: AgentOptions)
101
+ ```
102
+
103
+ **选项:**
104
+ - `maxLoop?: number` - 最大循环次数(默认:20)
105
+ - `debug?: boolean` - 是否启用调试模式(默认:false)
106
+ - `customPresetPrompt?: string` - 自定义预置提示词
107
+
108
+ #### 方法
109
+
110
+ ##### register_llm_text_ability(func)
111
+
112
+ 注册 LLM 文字能力
113
+
114
+ ```typescript
115
+ agent.register_llm_text_ability(async (userInput) => {
116
+ // 返回 LLM 响应
117
+ return llmResponse;
118
+ });
119
+ ```
120
+
121
+ ##### register_function_call(functionCall)
122
+
123
+ 注册工具函数管理器
124
+
125
+ ```typescript
126
+ const functionCall = new FunctionCall('/path/to/tools');
127
+ agent.register_function_call(functionCall);
128
+ ```
129
+
130
+ ##### create_chat(userInput)
131
+
132
+ 创建聊天会话
133
+
134
+ ```typescript
135
+ const result = await agent.create_chat('用户输入');
136
+ // 或使用消息数组
137
+ const result = await agent.create_chat([
138
+ {
139
+ role: 'user',
140
+ content: [{ type: 'text', text: '用户输入' }]
141
+ }
142
+ ]);
143
+ ```
144
+
145
+ ##### set_max_loop(maxLoop)
146
+
147
+ 设置最大循环次数
148
+
149
+ ```typescript
150
+ agent.set_max_loop(30);
151
+ ```
152
+
153
+ ##### set_preset_prompt(prompt)
154
+
155
+ 设置自定义预置提示词
156
+
157
+ ```typescript
158
+ agent.set_preset_prompt('自定义提示词内容');
159
+ ```
160
+
161
+ ### FunctionCall 类
162
+
163
+ #### 构造函数
164
+
165
+ ```typescript
166
+ new FunctionCall(toolPath: string)
167
+ ```
168
+
169
+ **参数:**
170
+ - `toolPath` - 工具函数所在目录的绝对路径
171
+
172
+ #### 方法
173
+
174
+ ##### get_tools_list()
175
+
176
+ 获取所有工具函数列表
177
+
178
+ ```typescript
179
+ const tools = functionCall.get_tools_list();
180
+ // [{ name: 'tool1', description: '...' }, ...]
181
+ ```
182
+
183
+ ##### has_tool(name)
184
+
185
+ 检查工具函数是否存在
186
+
187
+ ```typescript
188
+ const exists = functionCall.has_tool('get_weather');
189
+ ```
190
+
191
+ ##### exec_function(name, params)
192
+
193
+ 执行工具函数
194
+
195
+ ```typescript
196
+ const result = await functionCall.exec_function('get_weather', { city: '北京' });
197
+ ```
198
+
199
+ ### Logger 工具
200
+
201
+ ```typescript
202
+ import { Logger, LogLevel } from 'p-api-agent';
203
+
204
+ // 设置日志级别
205
+ Logger.setLevel(LogLevel.DEBUG);
206
+
207
+ // 使用日志
208
+ Logger.debug('调试信息');
209
+ Logger.info('普通信息');
210
+ Logger.warn('警告信息');
211
+ Logger.error('错误信息');
212
+ ```
213
+
214
+ ### 错误类型
215
+
216
+ ```typescript
217
+ import {
218
+ AgentError,
219
+ ToolNotFoundError,
220
+ ToolExecutionError,
221
+ ValidationError,
222
+ LLMError,
223
+ MaxLoopExceededError
224
+ } from 'p-api-agent';
225
+
226
+ try {
227
+ await agent.create_chat('...');
228
+ } catch (error) {
229
+ if (error instanceof ToolNotFoundError) {
230
+ console.error('工具函数不存在');
231
+ } else if (error instanceof MaxLoopExceededError) {
232
+ console.error('超出最大循环次数');
233
+ }
234
+ }
235
+ ```
236
+
237
+ ## 工作原理
238
+
239
+ 1. **用户输入** → Agent 接收用户请求
240
+ 2. **LLM 分析** → LLM 判断是否需要调用工具
241
+ 3. **工具调用** → 如需要,先获取工具文档,再执行工具
242
+ 4. **结果处理** → 整合工具结果,返回给用户
243
+ 5. **循环控制** → 最多循环 maxLoop 次,防止无限循环
244
+
245
+ ## LLM 响应格式
246
+
247
+ LLM 需要返回 JSON 格式的指令:
248
+
249
+ ### 结束指令
250
+ ```json
251
+ {
252
+ "command": "end",
253
+ "result": "最终返回给用户的结果"
254
+ }
255
+ ```
256
+
257
+ ### 获取工具文档
258
+ ```json
259
+ {
260
+ "command": "get_tool_doc",
261
+ "tool_name": "工具函数名称"
262
+ }
263
+ ```
264
+
265
+ ### 调用工具
266
+ ```json
267
+ {
268
+ "command": "use_tool",
269
+ "tool_name": "工具函数名称",
270
+ "params": { "参数名": "参数值" }
271
+ }
272
+ ```
273
+
274
+ ## 最佳实践
275
+
276
+ 1. **错误处理**: 始终使用 try-catch 包裹 Agent 调用
277
+ 2. **日志记录**: 生产环境建议设置为 INFO 或 WARN 级别
278
+ 3. **循环次数**: 根据实际需求调整 maxLoop,避免过多循环
279
+ 4. **工具设计**: 工具函数应该功能单一、职责明确
280
+ 5. **参数验证**: 在工具函数中进行充分的参数验证
281
+
282
+ ## 开发
283
+
284
+ ```bash
285
+ # 安装依赖
286
+ npm install
287
+
288
+ # 构建
289
+ npm run build
290
+
291
+ # 测试
292
+ npm test
293
+ ```
294
+
295
+ ## 许可证
296
+
297
+ ISC
298
+
299
+ ## 贡献
300
+
301
+ 欢迎提交 Issue 和 Pull Request!
302
+
303
+ ## 更新日志
304
+
305
+ ### v0.0.1
306
+ - 初始版本发布
307
+ - 支持基本的 Agent 功能
308
+ - 工具函数调用
309
+ - 完善的类型定义和错误处理
package/dist/index.cjs ADDED
@@ -0,0 +1,273 @@
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
+ });
@@ -0,0 +1,103 @@
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 = string | {
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
+ * 创建聊天
74
+ */
75
+ create_chat(user_input: UserChatInput): Promise<any>;
76
+ /**
77
+ * agent预置提示词
78
+ */
79
+ get_preset_prompt(): string;
80
+ }
81
+
82
+ declare class _LLM_Utils {
83
+ /**
84
+ * 提取大模型返回的markdown
85
+ */
86
+ extract_markdown(content: any): any;
87
+ /**
88
+ * 提取大模型的json格式
89
+ */
90
+ extract_json(content: any): any;
91
+ /**
92
+ * 提取mermaid格式
93
+ */
94
+ extract_mermaid(content: any): any;
95
+ /**
96
+ * 提取svg格式
97
+ */
98
+ extract_svg(content: any): any;
99
+ parse_json(content: string | object): any;
100
+ }
101
+ declare const LLM_Utils: _LLM_Utils;
102
+
103
+ export { Agent, FunctionCall, LLM_Utils, type RegisterInfo };
@@ -0,0 +1,103 @@
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 = string | {
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
+ * 创建聊天
74
+ */
75
+ create_chat(user_input: UserChatInput): Promise<any>;
76
+ /**
77
+ * agent预置提示词
78
+ */
79
+ get_preset_prompt(): string;
80
+ }
81
+
82
+ declare class _LLM_Utils {
83
+ /**
84
+ * 提取大模型返回的markdown
85
+ */
86
+ extract_markdown(content: any): any;
87
+ /**
88
+ * 提取大模型的json格式
89
+ */
90
+ extract_json(content: any): any;
91
+ /**
92
+ * 提取mermaid格式
93
+ */
94
+ extract_mermaid(content: any): any;
95
+ /**
96
+ * 提取svg格式
97
+ */
98
+ extract_svg(content: any): any;
99
+ parse_json(content: string | object): any;
100
+ }
101
+ declare const LLM_Utils: _LLM_Utils;
102
+
103
+ export { Agent, FunctionCall, LLM_Utils, type RegisterInfo };
package/dist/index.js ADDED
@@ -0,0 +1,241 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/agent/index.ts
9
+ import fs from "fs";
10
+
11
+ // src/utils/llm_utils.ts
12
+ import { jsonrepair } from "jsonrepair";
13
+ var _LLM_Utils = class {
14
+ /**
15
+ * 提取大模型返回的markdown
16
+ */
17
+ extract_markdown(content) {
18
+ const regex = /```markdown\n(.*?)\n```/s;
19
+ const match = content.match(regex);
20
+ if (!match) return content;
21
+ return match[1];
22
+ }
23
+ /**
24
+ * 提取大模型的json格式
25
+ */
26
+ extract_json(content) {
27
+ const regex = /```json\n(.*?)\n```/s;
28
+ const match = content.match(regex);
29
+ let json_content = match ? match[1] : content;
30
+ try {
31
+ return JSON.parse(json_content);
32
+ } catch (err) {
33
+ return JSON.parse(jsonrepair(json_content));
34
+ }
35
+ }
36
+ /**
37
+ * 提取mermaid格式
38
+ */
39
+ extract_mermaid(content) {
40
+ const regex = /```mermaid\n(.*?)\n```/s;
41
+ const match = content.match(regex);
42
+ if (!match) return content;
43
+ return match[1];
44
+ }
45
+ /**
46
+ * 提取svg格式
47
+ */
48
+ extract_svg(content) {
49
+ const regex = /```svg\n(.*?)\n```/s;
50
+ const match = content.match(regex);
51
+ if (!match) return content;
52
+ return match[1];
53
+ }
54
+ parse_json(content) {
55
+ if (typeof content === "object") {
56
+ return content;
57
+ }
58
+ try {
59
+ return JSON.parse(content);
60
+ } catch (err) {
61
+ return JSON.parse(jsonrepair(content));
62
+ }
63
+ }
64
+ };
65
+ var LLM_Utils = new _LLM_Utils();
66
+
67
+ // src/agent/index.ts
68
+ import path from "path";
69
+ var Agent = class {
70
+ // 角色定义的提示词
71
+ constructor() {
72
+ this.function_call = null;
73
+ // 工具函数的说明文档, 供模型调用时参考
74
+ this.function_call_doc = "";
75
+ // 模型的聊天能力
76
+ this.llm_chat_func = null;
77
+ // 预置提示词
78
+ this.preset_prompt = this.get_preset_prompt();
79
+ }
80
+ /**
81
+ * 注册工具函数
82
+ */
83
+ register_function_call(function_call) {
84
+ const tools_list = function_call.get_tools_list();
85
+ this.function_call_doc = tools_list.map((val) => `\u5DE5\u5177\u51FD\u6570:${val.name}
86
+ \u5DE5\u5177\u63CF\u8FF0:${val.description}`).join("\n\n");
87
+ this.function_call = function_call;
88
+ return true;
89
+ }
90
+ /**
91
+ * 注册LLM模型文字能力
92
+ */
93
+ register_llm_text_ability(func) {
94
+ this.llm_chat_func = func;
95
+ }
96
+ /**
97
+ * 注册LLM模型图片能力
98
+ */
99
+ register_llm_image_ability() {
100
+ return true;
101
+ }
102
+ /**
103
+ * 创建聊天
104
+ */
105
+ async create_chat(user_input) {
106
+ let dispose_user_input;
107
+ if (typeof user_input === "string") {
108
+ dispose_user_input = [
109
+ {
110
+ role: "user",
111
+ content: [
112
+ { type: "text", text: user_input }
113
+ ]
114
+ }
115
+ ];
116
+ } else {
117
+ dispose_user_input = JSON.parse(JSON.stringify(user_input));
118
+ }
119
+ if (this.function_call_doc) {
120
+ dispose_user_input.unshift({
121
+ role: "system",
122
+ content: [
123
+ { type: "text", text: `# \u5DE5\u5177\u51FD\u6570\u8BF4\u660E\u6587\u6863:
124
+ ${this.function_call_doc}` }
125
+ ]
126
+ });
127
+ }
128
+ dispose_user_input.unshift({
129
+ role: "system",
130
+ content: [
131
+ { type: "text", text: this.preset_prompt }
132
+ ]
133
+ });
134
+ let max_loop = 20;
135
+ let loop_count = 0;
136
+ while (loop_count < max_loop) {
137
+ const llm_res_str = await this.llm_chat_func(dispose_user_input);
138
+ const llm_res = LLM_Utils.extract_json(llm_res_str);
139
+ if (!llm_res.command) throw "\u5F02\u5E38\u6307\u4EE4, \u672A\u5305\u542Bcommand\u5B57\u6BB5";
140
+ if (llm_res.command === "end") {
141
+ return llm_res.result;
142
+ } else if (llm_res.command === "get_tool_doc") {
143
+ const tool_name = llm_res.tool_name;
144
+ const tool_doc = this.function_call.gen_tool_doc(tool_name);
145
+ dispose_user_input.push({
146
+ role: "user",
147
+ content: [
148
+ { type: "text", text: `\u5DE5\u5177\u51FD\u6570${tool_name}\u7684\u8BF4\u660E\u6587\u6863:
149
+ ${tool_doc}` }
150
+ ]
151
+ });
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
+ dispose_user_input.push({
157
+ role: "user",
158
+ content: [
159
+ { type: "text", text: `\u5DE5\u5177\u51FD\u6570${tool_name}\u7684\u8C03\u7528\u7ED3\u679C:
160
+ ${JSON.stringify(tool_result)}` }
161
+ ]
162
+ });
163
+ }
164
+ loop_count++;
165
+ }
166
+ }
167
+ /**
168
+ * agent预置提示词
169
+ */
170
+ get_preset_prompt() {
171
+ const prompt = fs.readFileSync(path.join(__dirname, "./preset_prompt.md"), "utf-8");
172
+ return prompt;
173
+ }
174
+ };
175
+
176
+ // src/function_call/index.ts
177
+ import path2 from "path";
178
+ import fs2 from "fs";
179
+ var FunctionCall = class {
180
+ constructor(tool_path) {
181
+ this.tool_path = tool_path;
182
+ this.tools = {};
183
+ this.init();
184
+ }
185
+ init() {
186
+ for (const file_name of fs2.readdirSync(this.tool_path)) {
187
+ const route_path = path2.join(this.tool_path, file_name);
188
+ const mcp = __require(route_path);
189
+ const info = mcp.register();
190
+ this.tools[info.name] = info;
191
+ }
192
+ }
193
+ /**
194
+ * 生成完整的工具函数说明文档
195
+ */
196
+ gen_tool_doc(name) {
197
+ const info = this.tools[name];
198
+ const schema = info.input_schema;
199
+ const schemaDesc = `\u7C7B\u578B: ${schema.type}`;
200
+ const params = Object.keys(schema.properties).map((key) => {
201
+ const item = schema.properties[key];
202
+ const required = schema.required?.includes(key) ? "\u5FC5\u586B" : "\u53EF\u9009";
203
+ const examples = item.examples && item.examples.length > 0 ? `\u793A\u4F8B\u503C: ${item.examples.join(", ")}` : "\u65E0\u793A\u4F8B";
204
+ return ` - ${key} (${item.type}, ${required})
205
+ \u8BF4\u660E: ${item.description}
206
+ ${examples}`;
207
+ }).join("\n");
208
+ return `\u5DE5\u5177\u51FD\u6570\u540D\u79F0: ${info.name}
209
+ \u529F\u80FD\u63CF\u8FF0: ${info.description}
210
+ \u8F93\u5165\u7ED3\u6784: ${schemaDesc}
211
+ \u53C2\u6570\u5217\u8868:
212
+ ${params}`;
213
+ }
214
+ /**
215
+ * 获取工具函数列表
216
+ */
217
+ get_tools_list() {
218
+ return Object.keys(this.tools).map((key) => {
219
+ const info = this.tools[key];
220
+ return {
221
+ name: info.name,
222
+ description: info.description
223
+ };
224
+ });
225
+ }
226
+ /**
227
+ * 执行工具函数
228
+ */
229
+ async exec_function(name, params) {
230
+ const info = this.tools[name];
231
+ if (!info) {
232
+ throw `\u5DE5\u5177\u51FD\u6570${name}\u4E0D\u5B58\u5728`;
233
+ }
234
+ return await info.register_func(params);
235
+ }
236
+ };
237
+ export {
238
+ Agent,
239
+ FunctionCall,
240
+ LLM_Utils
241
+ };
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "type": "module",
3
+ "name": "p-api-agent",
4
+ "version": "0.0.1",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.mjs",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "types": "dist/index.d.ts",
17
+ "scripts": {
18
+ "build": "tsup"
19
+ },
20
+ "author": "",
21
+ "license": "ISC",
22
+ "description": "",
23
+ "devDependencies": {
24
+ "@types/lodash": "4.17.16",
25
+ "@types/node": "^25.3.5",
26
+ "javascript-obfuscator": "^4.1.1",
27
+ "tsup": "^8.4.0",
28
+ "typescript": "5.8.3"
29
+ },
30
+ "dependencies": {
31
+ "axios": "^1.13.6",
32
+ "jsonrepair": "^3.13.2"
33
+ }
34
+ }