@cicctencent/agent-midway 0.1.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.
Files changed (160) hide show
  1. package/README.md +280 -0
  2. package/dist/adapters/express.d.ts +8 -0
  3. package/dist/adapters/express.js +91 -0
  4. package/dist/adapters/index.d.ts +5 -0
  5. package/dist/adapters/index.js +21 -0
  6. package/dist/adapters/koa.d.ts +3 -0
  7. package/dist/adapters/koa.js +75 -0
  8. package/dist/adapters/midway.d.ts +5 -0
  9. package/dist/adapters/midway.js +11 -0
  10. package/dist/adapters/next.d.ts +12 -0
  11. package/dist/adapters/next.js +89 -0
  12. package/dist/adapters/shared.d.ts +4 -0
  13. package/dist/adapters/shared.js +31 -0
  14. package/dist/channel/dingtalk.d.ts +18 -0
  15. package/dist/channel/dingtalk.js +68 -0
  16. package/dist/channel/feishu.d.ts +20 -0
  17. package/dist/channel/feishu.js +96 -0
  18. package/dist/channel/index.d.ts +46 -0
  19. package/dist/channel/index.js +311 -0
  20. package/dist/channel/types.d.ts +77 -0
  21. package/dist/channel/types.js +7 -0
  22. package/dist/channel/wecom.d.ts +22 -0
  23. package/dist/channel/wecom.js +106 -0
  24. package/dist/component.d.ts +49 -0
  25. package/dist/component.js +129 -0
  26. package/dist/connector/calendar-adapter.d.ts +19 -0
  27. package/dist/connector/calendar-adapter.js +236 -0
  28. package/dist/connector/db-adapter.d.ts +28 -0
  29. package/dist/connector/db-adapter.js +193 -0
  30. package/dist/connector/email-adapter.d.ts +23 -0
  31. package/dist/connector/email-adapter.js +192 -0
  32. package/dist/connector/fs-adapter.d.ts +15 -0
  33. package/dist/connector/fs-adapter.js +199 -0
  34. package/dist/connector/http-adapter.d.ts +29 -0
  35. package/dist/connector/http-adapter.js +181 -0
  36. package/dist/connector/index.d.ts +24 -0
  37. package/dist/connector/index.js +454 -0
  38. package/dist/connector/mcp-adapter.d.ts +27 -0
  39. package/dist/connector/mcp-adapter.js +156 -0
  40. package/dist/connector/mq-adapter.d.ts +25 -0
  41. package/dist/connector/mq-adapter.js +181 -0
  42. package/dist/connector/types.d.ts +205 -0
  43. package/dist/connector/types.js +9 -0
  44. package/dist/controller/a2a.controller.d.ts +41 -0
  45. package/dist/controller/a2a.controller.js +150 -0
  46. package/dist/controller/agent-profile.controller.d.ts +97 -0
  47. package/dist/controller/agent-profile.controller.js +200 -0
  48. package/dist/controller/agent.controller.d.ts +199 -0
  49. package/dist/controller/agent.controller.js +414 -0
  50. package/dist/controller/application.controller.d.ts +113 -0
  51. package/dist/controller/application.controller.js +217 -0
  52. package/dist/controller/automation.controller.d.ts +113 -0
  53. package/dist/controller/automation.controller.js +246 -0
  54. package/dist/controller/channel.controller.d.ts +73 -0
  55. package/dist/controller/channel.controller.js +183 -0
  56. package/dist/controller/chat.controller.d.ts +188 -0
  57. package/dist/controller/chat.controller.js +375 -0
  58. package/dist/controller/connector.controller.d.ts +134 -0
  59. package/dist/controller/connector.controller.js +257 -0
  60. package/dist/controller/knowledge-base.controller.d.ts +157 -0
  61. package/dist/controller/knowledge-base.controller.js +278 -0
  62. package/dist/controller/mcp-server.controller.d.ts +115 -0
  63. package/dist/controller/mcp-server.controller.js +236 -0
  64. package/dist/controller/model-config.controller.d.ts +139 -0
  65. package/dist/controller/model-config.controller.js +274 -0
  66. package/dist/controller/observability.controller.d.ts +124 -0
  67. package/dist/controller/observability.controller.js +142 -0
  68. package/dist/controller/security.controller.d.ts +91 -0
  69. package/dist/controller/security.controller.js +172 -0
  70. package/dist/controller/settings.controller.d.ts +83 -0
  71. package/dist/controller/settings.controller.js +280 -0
  72. package/dist/core/ai-workstation.d.ts +17 -0
  73. package/dist/core/ai-workstation.js +129 -0
  74. package/dist/core/index.d.ts +4 -0
  75. package/dist/core/index.js +20 -0
  76. package/dist/core/service-container.d.ts +12 -0
  77. package/dist/core/service-container.js +54 -0
  78. package/dist/core/sse.d.ts +6 -0
  79. package/dist/core/sse.js +56 -0
  80. package/dist/core/types.d.ts +72 -0
  81. package/dist/core/types.js +2 -0
  82. package/dist/dto/agent.dto.d.ts +21 -0
  83. package/dist/dto/agent.dto.js +79 -0
  84. package/dist/dto/ai-config.dto.d.ts +67 -0
  85. package/dist/dto/ai-config.dto.js +249 -0
  86. package/dist/dto/chat.dto.d.ts +40 -0
  87. package/dist/dto/chat.dto.js +122 -0
  88. package/dist/index.d.ts +101 -0
  89. package/dist/index.js +195 -0
  90. package/dist/memory/db-store.d.ts +33 -0
  91. package/dist/memory/db-store.js +143 -0
  92. package/dist/memory/index.d.ts +187 -0
  93. package/dist/memory/index.js +443 -0
  94. package/dist/model/ai-agent-profile.entity.d.ts +32 -0
  95. package/dist/model/ai-agent-profile.entity.js +289 -0
  96. package/dist/model/ai-application.entity.d.ts +20 -0
  97. package/dist/model/ai-application.entity.js +166 -0
  98. package/dist/model/ai-chat-memory.entity.d.ts +16 -0
  99. package/dist/model/ai-chat-memory.entity.js +123 -0
  100. package/dist/model/ai-chat-message.entity.d.ts +16 -0
  101. package/dist/model/ai-chat-message.entity.js +122 -0
  102. package/dist/model/ai-chat-skill.entity.d.ts +19 -0
  103. package/dist/model/ai-chat-skill.entity.js +155 -0
  104. package/dist/model/ai-chat-thread.entity.d.ts +15 -0
  105. package/dist/model/ai-chat-thread.entity.js +113 -0
  106. package/dist/model/ai-chat-workspace.entity.d.ts +17 -0
  107. package/dist/model/ai-chat-workspace.entity.js +136 -0
  108. package/dist/model/ai-kb-document.entity.d.ts +16 -0
  109. package/dist/model/ai-kb-document.entity.js +122 -0
  110. package/dist/model/ai-knowledge-base.entity.d.ts +22 -0
  111. package/dist/model/ai-knowledge-base.entity.js +185 -0
  112. package/dist/model/ai-mcp-server.entity.d.ts +23 -0
  113. package/dist/model/ai-mcp-server.entity.js +198 -0
  114. package/dist/model/ai-model-config.entity.d.ts +24 -0
  115. package/dist/model/ai-model-config.entity.js +200 -0
  116. package/dist/service/a2a.service.d.ts +142 -0
  117. package/dist/service/a2a.service.js +537 -0
  118. package/dist/service/agent-profile.service.d.ts +34 -0
  119. package/dist/service/agent-profile.service.js +110 -0
  120. package/dist/service/agent-server.service.d.ts +91 -0
  121. package/dist/service/agent-server.service.js +634 -0
  122. package/dist/service/agent-task-queue.service.d.ts +98 -0
  123. package/dist/service/agent-task-queue.service.js +283 -0
  124. package/dist/service/ai-chat.service.d.ts +103 -0
  125. package/dist/service/ai-chat.service.js +431 -0
  126. package/dist/service/ai-skill.service.d.ts +116 -0
  127. package/dist/service/ai-skill.service.js +457 -0
  128. package/dist/service/application.service.d.ts +42 -0
  129. package/dist/service/application.service.js +139 -0
  130. package/dist/service/automation.service.d.ts +37 -0
  131. package/dist/service/automation.service.js +196 -0
  132. package/dist/service/connector.service.d.ts +136 -0
  133. package/dist/service/connector.service.js +524 -0
  134. package/dist/service/knowledge-base.service.d.ts +138 -0
  135. package/dist/service/knowledge-base.service.js +528 -0
  136. package/dist/service/mcp-server.service.d.ts +39 -0
  137. package/dist/service/mcp-server.service.js +143 -0
  138. package/dist/service/model-config.service.d.ts +57 -0
  139. package/dist/service/model-config.service.js +168 -0
  140. package/dist/service/observability.service.d.ts +145 -0
  141. package/dist/service/observability.service.js +281 -0
  142. package/dist/service/openai.service.d.ts +88 -0
  143. package/dist/service/openai.service.js +406 -0
  144. package/dist/service/prompt-builder.service.d.ts +50 -0
  145. package/dist/service/prompt-builder.service.js +246 -0
  146. package/dist/tools/code-exec.tool.d.ts +37 -0
  147. package/dist/tools/code-exec.tool.js +162 -0
  148. package/dist/tools/datetime.tool.d.ts +21 -0
  149. package/dist/tools/datetime.tool.js +379 -0
  150. package/dist/tools/http-request.tool.d.ts +43 -0
  151. package/dist/tools/http-request.tool.js +455 -0
  152. package/dist/tools/registry.d.ts +71 -0
  153. package/dist/tools/registry.js +77 -0
  154. package/dist/tools/text-process.tool.d.ts +7 -0
  155. package/dist/tools/text-process.tool.js +366 -0
  156. package/dist/tools/web-search.tool.d.ts +28 -0
  157. package/dist/tools/web-search.tool.js +304 -0
  158. package/dist/types.d.ts +70 -0
  159. package/dist/types.js +7 -0
  160. package/package.json +69 -0
@@ -0,0 +1,455 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.parseUrlTool = exports.httpRequestTool = void 0;
40
+ /**
41
+ * HTTP 请求工具
42
+ *
43
+ * 让 Agent 能够发起任意 HTTP(S) 请求,对接外部 API、Webhook、数据接口等。
44
+ *
45
+ * 工具说明:
46
+ * - http_request:发起通用 HTTP 请求(GET/POST/PUT/DELETE/PATCH)
47
+ * - parse_url:解析 URL 结构与查询参数
48
+ *
49
+ * 特性:
50
+ * - 支持 HTTP / HTTPS,可选忽略 TLS 证书异常(自签名证书场景)
51
+ * - 支持 JSON / Form / Raw / Query String 多种请求体格式
52
+ * - 支持 Basic Auth / Bearer Token / 自定义 Header
53
+ * - 超时控制(默认 15s,最大 60s)
54
+ * - 响应体自动截断(防止超大响应撑爆上下文)
55
+ *
56
+ * 安全机制:
57
+ * - 默认禁止请求内网地址(127.0.0.1、10.x、192.168.x、172.16-31.x)
58
+ * - 可通过环境变量 HTTP_REQUEST_ALLOW_INTERNAL=true 放开
59
+ */
60
+ const axios_1 = __importDefault(require("axios"));
61
+ const https = __importStar(require("https"));
62
+ const url_1 = require("url");
63
+ /** 内网 IP 正则检测 */
64
+ const PRIVATE_IP_RE = /^(127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.|0\.0\.0\.0|localhost|::1|\[::1\])/i;
65
+ /** 校验 URL 是否安全(非内网) */
66
+ function isUrlSafe(url) {
67
+ if (process.env.HTTP_REQUEST_ALLOW_INTERNAL === 'true')
68
+ return true;
69
+ try {
70
+ const parsed = new url_1.URL(url);
71
+ const hostname = parsed.hostname.replace(/^\[|\]$/g, '');
72
+ return !PRIVATE_IP_RE.test(hostname);
73
+ }
74
+ catch {
75
+ return false;
76
+ }
77
+ }
78
+ /** 构建 axios 请求配置 */
79
+ function buildAxiosConfig(input) {
80
+ const config = {
81
+ url: input.url,
82
+ method: (input.method || 'GET'),
83
+ timeout: Math.min(Math.max(Number(input.timeout) || 15000, 1000), 60000),
84
+ validateStatus: () => true, // 不抛出 HTTP 错误,让 Agent 自行判断
85
+ maxRedirects: 5,
86
+ };
87
+ // HTTPS 配置:忽略证书异常
88
+ if (input.ignoreTlsErrors) {
89
+ config.httpsAgent = new https.Agent({ rejectUnauthorized: false });
90
+ }
91
+ // 请求头
92
+ config.headers = { ...(input.headers || {}) };
93
+ if (!config.headers['User-Agent']) {
94
+ config.headers['User-Agent'] = 'OmniInsight-Agent/1.0';
95
+ }
96
+ // 认证
97
+ if (input.auth) {
98
+ if (input.auth.type === 'bearer') {
99
+ config.headers['Authorization'] = `Bearer ${input.auth.token}`;
100
+ }
101
+ else if (input.auth.type === 'basic') {
102
+ const encoded = Buffer.from(`${input.auth.username}:${input.auth.password}`).toString('base64');
103
+ config.headers['Authorization'] = `Basic ${encoded}`;
104
+ }
105
+ else if (input.auth.type === 'apikey') {
106
+ config.headers[input.auth.headerName || 'X-API-Key'] =
107
+ input.auth.key;
108
+ }
109
+ }
110
+ // 查询参数
111
+ if (input.queryParams) {
112
+ config.params = input.queryParams;
113
+ }
114
+ // 请求体
115
+ if (input.body &&
116
+ ['POST', 'PUT', 'PATCH', 'DELETE'].includes(config.method)) {
117
+ const bodyType = input.bodyType || 'json';
118
+ switch (bodyType) {
119
+ case 'json':
120
+ config.data =
121
+ typeof input.body === 'string'
122
+ ? JSON.parse(input.body)
123
+ : input.body;
124
+ if (!config.headers['Content-Type']) {
125
+ config.headers['Content-Type'] = 'application/json';
126
+ }
127
+ break;
128
+ case 'form':
129
+ if (typeof input.body === 'string') {
130
+ config.data = new URLSearchParams(input.body).toString();
131
+ }
132
+ else {
133
+ config.data = new URLSearchParams(input.body).toString();
134
+ }
135
+ if (!config.headers['Content-Type']) {
136
+ config.headers['Content-Type'] =
137
+ 'application/x-www-form-urlencoded';
138
+ }
139
+ break;
140
+ case 'raw':
141
+ config.data = input.body;
142
+ if (!config.headers['Content-Type']) {
143
+ config.headers['Content-Type'] = 'text/plain';
144
+ }
145
+ break;
146
+ }
147
+ }
148
+ // 响应类型
149
+ config.responseType =
150
+ input.responseType === 'arraybuffer' ? 'arraybuffer' : 'json';
151
+ return config;
152
+ }
153
+ // ===================== 工具定义 =====================
154
+ /** HTTP 请求工具 */
155
+ exports.httpRequestTool = {
156
+ id: 'http_request',
157
+ name: 'HTTP 请求',
158
+ description: '发起 HTTP/HTTPS 请求访问外部 API 或 Web 资源。支持 GET/POST/PUT/DELETE/PATCH 方法,JSON/Form/Raw 请求体,Bearer/Basic/APIKey 认证,自定义 Header,HTTPS 证书忽略。用于调用 REST API、Webhook、获取远程数据等场景。',
159
+ category: 'network',
160
+ parameters: {
161
+ type: 'object',
162
+ properties: {
163
+ url: {
164
+ type: 'string',
165
+ description: '请求 URL 地址(必须以 http:// 或 https:// 开头)',
166
+ },
167
+ method: {
168
+ type: 'string',
169
+ description: 'HTTP 方法',
170
+ enum: [
171
+ 'GET',
172
+ 'POST',
173
+ 'PUT',
174
+ 'DELETE',
175
+ 'PATCH',
176
+ 'HEAD',
177
+ 'OPTIONS',
178
+ ],
179
+ default: 'GET',
180
+ },
181
+ headers: {
182
+ type: 'string',
183
+ description: '自定义请求头,JSON 对象格式,如 {"Accept": "application/json"}',
184
+ },
185
+ queryParams: {
186
+ type: 'string',
187
+ description: 'URL 查询参数,JSON 对象格式,如 {"page": "1", "size": "10"}',
188
+ },
189
+ body: {
190
+ type: 'string',
191
+ description: '请求体内容。JSON 对象字符串、表单键值对或纯文本。',
192
+ },
193
+ bodyType: {
194
+ type: 'string',
195
+ description: '请求体格式:json(默认)、form(表单)、raw(纯文本)',
196
+ enum: ['json', 'form', 'raw'],
197
+ default: 'json',
198
+ },
199
+ authType: {
200
+ type: 'string',
201
+ description: '认证方式:bearer(Token)、basic(用户名密码)、apikey(自定义头)',
202
+ enum: ['bearer', 'basic', 'apikey', 'none'],
203
+ default: 'none',
204
+ },
205
+ authToken: {
206
+ type: 'string',
207
+ description: '认证凭证。bearer 时为 token,basic 时为 "user:pass",apikey 时为 key 值',
208
+ },
209
+ authHeaderName: {
210
+ type: 'string',
211
+ description: 'apikey 认证时的自定义 Header 名称,默认 X-API-Key',
212
+ },
213
+ timeout: {
214
+ type: 'integer',
215
+ description: '请求超时时间(毫秒),默认 15000,最大 60000',
216
+ minimum: 1000,
217
+ maximum: 60000,
218
+ default: 15000,
219
+ },
220
+ ignoreTlsErrors: {
221
+ type: 'boolean',
222
+ description: '是否忽略 HTTPS 证书异常(自签名证书场景),默认 false',
223
+ default: false,
224
+ },
225
+ maxResponseLength: {
226
+ type: 'integer',
227
+ description: '响应体最大字符数(超出自动截断),默认 8000,最大 50000',
228
+ minimum: 100,
229
+ maximum: 50000,
230
+ default: 8000,
231
+ },
232
+ },
233
+ required: ['url'],
234
+ },
235
+ async execute(rawInput) {
236
+ const input = rawInput;
237
+ const url = (input.url || '').trim();
238
+ const method = (input.method || 'GET').toUpperCase();
239
+ // URL 校验
240
+ if (!url.startsWith('http://') && !url.startsWith('https://')) {
241
+ return {
242
+ url,
243
+ method,
244
+ statusCode: 0,
245
+ statusText: 'Invalid URL',
246
+ headers: {},
247
+ data: null,
248
+ truncated: false,
249
+ duration: 0,
250
+ error: '无效的 URL,必须以 http:// 或 https:// 开头',
251
+ };
252
+ }
253
+ // 内网安全检测
254
+ if (!isUrlSafe(url)) {
255
+ return {
256
+ url,
257
+ method,
258
+ statusCode: 0,
259
+ statusText: 'Blocked',
260
+ headers: {},
261
+ data: null,
262
+ truncated: false,
263
+ duration: 0,
264
+ error: '禁止请求内网地址。如需放开请设置环境变量 HTTP_REQUEST_ALLOW_INTERNAL=true',
265
+ };
266
+ }
267
+ // 解析嵌套 JSON 字符串参数
268
+ let headers;
269
+ let queryParams;
270
+ let body = input.body;
271
+ try {
272
+ headers = input.headers
273
+ ? typeof input.headers === 'string'
274
+ ? JSON.parse(input.headers)
275
+ : input.headers
276
+ : undefined;
277
+ }
278
+ catch {
279
+ /* ignore */
280
+ }
281
+ try {
282
+ queryParams = input.queryParams
283
+ ? typeof input.queryParams === 'string'
284
+ ? JSON.parse(input.queryParams)
285
+ : input.queryParams
286
+ : undefined;
287
+ }
288
+ catch {
289
+ /* ignore */
290
+ }
291
+ try {
292
+ if (body &&
293
+ typeof body === 'string' &&
294
+ (input.bodyType || 'json') === 'json')
295
+ body = JSON.parse(body);
296
+ }
297
+ catch {
298
+ /* keep as string */
299
+ }
300
+ // 构建认证对象
301
+ let auth;
302
+ if (input.authType && input.authType !== 'none' && input.authToken) {
303
+ if (input.authType === 'basic') {
304
+ const [username, password] = input.authToken.split(':');
305
+ auth = { type: 'basic', username, password: password || '' };
306
+ }
307
+ else if (input.authType === 'apikey') {
308
+ auth = {
309
+ type: 'apikey',
310
+ key: input.authToken,
311
+ headerName: input.authHeaderName || 'X-API-Key',
312
+ };
313
+ }
314
+ else {
315
+ auth = { type: 'bearer', token: input.authToken };
316
+ }
317
+ }
318
+ const requestInput = {
319
+ url,
320
+ method: method,
321
+ headers,
322
+ queryParams,
323
+ body,
324
+ bodyType: input.bodyType,
325
+ auth,
326
+ timeout: input.timeout,
327
+ ignoreTlsErrors: input.ignoreTlsErrors,
328
+ maxResponseLength: input.maxResponseLength,
329
+ };
330
+ const startTime = Date.now();
331
+ try {
332
+ const config = buildAxiosConfig(requestInput);
333
+ const response = await axios_1.default.request(config);
334
+ const duration = Date.now() - startTime;
335
+ // 提取响应头(只保留常用头,避免噪音)
336
+ const respHeaders = {};
337
+ const keepHeaders = [
338
+ 'content-type',
339
+ 'content-length',
340
+ 'x-request-id',
341
+ 'x-ratelimit-remaining',
342
+ 'date',
343
+ ];
344
+ for (const key of keepHeaders) {
345
+ if (response.headers[key])
346
+ respHeaders[key] = String(response.headers[key]);
347
+ }
348
+ // 处理响应体
349
+ let respData = response.data;
350
+ const maxLen = Math.min(Math.max(Number(input.maxResponseLength) || 8000, 100), 50000);
351
+ let truncated = false;
352
+ if (typeof respData === 'string') {
353
+ if (respData.length > maxLen) {
354
+ respData = respData.slice(0, maxLen) + '\n...[已截断]';
355
+ truncated = true;
356
+ }
357
+ }
358
+ else if (respData && typeof respData === 'object') {
359
+ const str = JSON.stringify(respData);
360
+ if (str.length > maxLen) {
361
+ respData = str.slice(0, maxLen) + '\n...[已截断]';
362
+ truncated = true;
363
+ }
364
+ }
365
+ return {
366
+ url,
367
+ method,
368
+ statusCode: response.status,
369
+ statusText: response.statusText,
370
+ headers: respHeaders,
371
+ data: respData,
372
+ truncated,
373
+ duration,
374
+ };
375
+ }
376
+ catch (error) {
377
+ const duration = Date.now() - startTime;
378
+ const message = error?.code === 'ECONNREFUSED'
379
+ ? '连接被拒绝'
380
+ : error?.code === 'ENOTFOUND'
381
+ ? '域名解析失败'
382
+ : error?.code === 'ETIMEDOUT'
383
+ ? '请求超时'
384
+ : error?.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE'
385
+ ? 'TLS 证书验证失败,请设置 ignoreTlsErrors=true'
386
+ : error?.code === 'CERT_HAS_EXPIRED'
387
+ ? 'TLS 证书已过期,请设置 ignoreTlsErrors=true'
388
+ : error?.response?.data?.message ||
389
+ error?.message ||
390
+ String(error);
391
+ return {
392
+ url,
393
+ method,
394
+ statusCode: error?.response?.status || 0,
395
+ statusText: error?.response?.statusText || error?.code || 'Error',
396
+ headers: {},
397
+ data: error?.response?.data || null,
398
+ truncated: false,
399
+ duration,
400
+ error: `请求失败: ${message}`,
401
+ };
402
+ }
403
+ },
404
+ };
405
+ // ===================== URL 解析工具 =====================
406
+ /** URL 解析工具 */
407
+ exports.parseUrlTool = {
408
+ id: 'parse_url',
409
+ name: '解析 URL',
410
+ description: '解析 URL 字符串,提取协议、域名、端口、路径、查询参数、Hash 等结构化信息。用于分析和构造 URL。',
411
+ category: 'network',
412
+ parameters: {
413
+ type: 'object',
414
+ properties: {
415
+ url: {
416
+ type: 'string',
417
+ description: '待解析的 URL 字符串',
418
+ },
419
+ },
420
+ required: ['url'],
421
+ },
422
+ async execute(input) {
423
+ try {
424
+ const parsed = new url_1.URL(input.url.trim());
425
+ const queryParams = {};
426
+ parsed.searchParams.forEach((value, key) => {
427
+ queryParams[key] = value;
428
+ });
429
+ return {
430
+ protocol: parsed.protocol.replace(':', ''),
431
+ hostname: parsed.hostname,
432
+ port: parsed.port ||
433
+ (parsed.protocol === 'https:' ? '443' : '80'),
434
+ pathname: parsed.pathname,
435
+ search: parsed.search,
436
+ hash: parsed.hash,
437
+ queryParams,
438
+ origin: parsed.origin,
439
+ };
440
+ }
441
+ catch {
442
+ return {
443
+ protocol: '',
444
+ hostname: '',
445
+ port: '',
446
+ pathname: '',
447
+ search: '',
448
+ hash: '',
449
+ queryParams: {},
450
+ origin: '',
451
+ ...{ error: '无效的 URL 格式' },
452
+ };
453
+ }
454
+ },
455
+ };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * 工具注册表
3
+ *
4
+ * 参考 Mastra 的 Tool 注册机制:
5
+ * https://mastra.ai/docs/tools/overview
6
+ *
7
+ * 管理所有可用的 Agent 工具,支持动态注册 / 注销 / 按分类查询。
8
+ * 工具通过 JSON Schema 声明参数,Agent(LLM)据此生成调用参数。
9
+ *
10
+ * 工具分类约定:
11
+ * - data:数据源查询类工具
12
+ * - bi:BI 报表生成类工具
13
+ * - search:网络搜索类工具
14
+ * - compute:代码执行 / 数据计算类工具
15
+ * - network:HTTP 请求 / URL 解析类工具
16
+ * - utility:文本处理 / 编解码 / 日期时间等通用工具
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * import { toolRegistry } from './tools/registry';
21
+ *
22
+ * // 注册工具
23
+ * toolRegistry.register(myTool);
24
+ *
25
+ * // 按分类获取
26
+ * const dataTools = toolRegistry.getByCategory('data');
27
+ *
28
+ * // 导出为 OpenAI function calling 格式
29
+ * const openaiTools = toolRegistry.toOpenAITools();
30
+ * ```
31
+ */
32
+ import type { ToolDefinition, ToolParameterSchema } from '../types';
33
+ /**
34
+ * 工具注册表类
35
+ * 基于 Map 实现,支持 O(1) 查找,全局单例通过 toolRegistry 导出。
36
+ */
37
+ declare class ToolRegistry {
38
+ private tools;
39
+ /** 注册工具 */
40
+ register(tool: ToolDefinition): void;
41
+ /** 批量注册 */
42
+ registerAll(tools: ToolDefinition[]): void;
43
+ /** 注销工具 */
44
+ unregister(id: string): boolean;
45
+ /** 获取工具 */
46
+ get<TInput = any, TOutput = any>(id: string): ToolDefinition<TInput, TOutput> | undefined;
47
+ /** 检查工具是否存在 */
48
+ has(id: string): boolean;
49
+ /** 获取所有工具 */
50
+ getAll(): ToolDefinition[];
51
+ /** 按分类过滤工具 */
52
+ getByCategory(category: string): ToolDefinition[];
53
+ /** 获取工具 ID 列表 */
54
+ getIds(): string[];
55
+ /** 转为 OpenAI function calling tools 格式 */
56
+ toOpenAITools(toolIds?: string[]): Array<{
57
+ type: 'function';
58
+ function: {
59
+ name: string;
60
+ description: string;
61
+ parameters: ToolParameterSchema;
62
+ };
63
+ }>;
64
+ /** 获取工具摘要(用于系统提示词) */
65
+ getToolSummary(): string;
66
+ /** 清空所有工具 */
67
+ clear(): void;
68
+ }
69
+ /** 全局工具注册表单例 */
70
+ export declare const toolRegistry: ToolRegistry;
71
+ export { ToolRegistry };
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ToolRegistry = exports.toolRegistry = void 0;
4
+ /**
5
+ * 工具注册表类
6
+ * 基于 Map 实现,支持 O(1) 查找,全局单例通过 toolRegistry 导出。
7
+ */
8
+ class ToolRegistry {
9
+ constructor() {
10
+ this.tools = new Map();
11
+ }
12
+ /** 注册工具 */
13
+ register(tool) {
14
+ if (this.tools.has(tool.id)) {
15
+ console.warn(`[ToolRegistry] 工具 "${tool.id}" 已存在,将被覆盖`);
16
+ }
17
+ this.tools.set(tool.id, tool);
18
+ }
19
+ /** 批量注册 */
20
+ registerAll(tools) {
21
+ tools.forEach(t => this.register(t));
22
+ }
23
+ /** 注销工具 */
24
+ unregister(id) {
25
+ return this.tools.delete(id);
26
+ }
27
+ /** 获取工具 */
28
+ get(id) {
29
+ return this.tools.get(id);
30
+ }
31
+ /** 检查工具是否存在 */
32
+ has(id) {
33
+ return this.tools.has(id);
34
+ }
35
+ /** 获取所有工具 */
36
+ getAll() {
37
+ return Array.from(this.tools.values());
38
+ }
39
+ /** 按分类过滤工具 */
40
+ getByCategory(category) {
41
+ return this.getAll().filter(t => t.category === category);
42
+ }
43
+ /** 获取工具 ID 列表 */
44
+ getIds() {
45
+ return Array.from(this.tools.keys());
46
+ }
47
+ /** 转为 OpenAI function calling tools 格式 */
48
+ toOpenAITools(toolIds) {
49
+ const tools = toolIds
50
+ ? toolIds
51
+ .map(id => this.tools.get(id))
52
+ .filter(Boolean)
53
+ : this.getAll();
54
+ return tools.map(tool => ({
55
+ type: 'function',
56
+ function: {
57
+ name: tool.id,
58
+ description: tool.description,
59
+ parameters: tool.parameters,
60
+ },
61
+ }));
62
+ }
63
+ /** 获取工具摘要(用于系统提示词) */
64
+ getToolSummary() {
65
+ const tools = this.getAll();
66
+ if (!tools.length)
67
+ return '当前无可用工具。';
68
+ return tools.map(t => `- **${t.id}**: ${t.description}`).join('\n');
69
+ }
70
+ /** 清空所有工具 */
71
+ clear() {
72
+ this.tools.clear();
73
+ }
74
+ }
75
+ exports.ToolRegistry = ToolRegistry;
76
+ /** 全局工具注册表单例 */
77
+ exports.toolRegistry = new ToolRegistry();
@@ -0,0 +1,7 @@
1
+ import type { ToolDefinition } from '../types';
2
+ /** 文本处理工具 */
3
+ export declare const textProcessTool: ToolDefinition;
4
+ /** 编解码工具 */
5
+ export declare const encodeDecodeTool: ToolDefinition;
6
+ /** Hash 计算工具 */
7
+ export declare const computeHashTool: ToolDefinition;