@becrafter/prompt-manager 0.1.21 → 0.1.31
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/package.json +23 -23
- package/packages/resources/tools/agent-browser/README.md +640 -0
- package/packages/resources/tools/agent-browser/agent-browser.tool.js +1388 -0
- package/packages/resources/tools/thinking/README.md +324 -0
- package/packages/resources/tools/thinking/thinking.tool.js +911 -0
- package/packages/server/README.md +3 -4
- package/packages/server/api/admin.routes.js +668 -664
- package/packages/server/api/open.routes.js +68 -67
- package/packages/server/api/surge.routes.js +5 -6
- package/packages/server/api/tool.routes.js +70 -71
- package/packages/server/app.js +70 -73
- package/packages/server/configs/authors.json +40 -0
- package/packages/server/configs/models/built-in/bigmodel.yaml +6 -6
- package/packages/server/configs/models/providers.yaml +4 -4
- package/packages/server/configs/templates/built-in/general-iteration.yaml +1 -1
- package/packages/server/configs/templates/built-in/general-optimize.yaml +1 -1
- package/packages/server/configs/templates/built-in/output-format-optimize.yaml +1 -1
- package/packages/server/index.js +3 -9
- package/packages/server/mcp/heartbeat-patch.js +1 -3
- package/packages/server/mcp/mcp.server.js +64 -134
- package/packages/server/mcp/prompt.handler.js +101 -95
- package/packages/server/middlewares/auth.middleware.js +31 -31
- package/packages/server/server.js +60 -45
- package/packages/server/services/TerminalService.js +156 -70
- package/packages/server/services/WebSocketService.js +35 -34
- package/packages/server/services/author-config.service.js +199 -0
- package/packages/server/services/manager.js +66 -60
- package/packages/server/services/model.service.js +5 -9
- package/packages/server/services/optimization.service.js +25 -22
- package/packages/server/services/template.service.js +3 -8
- package/packages/server/toolm/author-sync.service.js +97 -0
- package/packages/server/toolm/index.js +1 -2
- package/packages/server/toolm/package-installer.service.js +47 -50
- package/packages/server/toolm/tool-context.service.js +64 -62
- package/packages/server/toolm/tool-dependency.service.js +28 -30
- package/packages/server/toolm/tool-description-generator-optimized.service.js +55 -55
- package/packages/server/toolm/tool-description-generator.service.js +20 -23
- package/packages/server/toolm/tool-environment.service.js +45 -44
- package/packages/server/toolm/tool-execution.service.js +49 -48
- package/packages/server/toolm/tool-loader.service.js +13 -18
- package/packages/server/toolm/tool-logger.service.js +33 -39
- package/packages/server/toolm/tool-manager.handler.js +17 -15
- package/packages/server/toolm/tool-manual-generator.service.js +107 -87
- package/packages/server/toolm/tool-mode-handlers.service.js +52 -59
- package/packages/server/toolm/tool-storage.service.js +11 -12
- package/packages/server/toolm/tool-sync.service.js +36 -39
- package/packages/server/toolm/tool-utils.js +0 -1
- package/packages/server/toolm/tool-yaml-parser.service.js +12 -11
- package/packages/server/toolm/validate-system.js +56 -84
- package/packages/server/utils/config.js +98 -13
- package/packages/server/utils/logger.js +1 -1
- package/packages/server/utils/port-checker.js +8 -8
- package/packages/server/utils/util.js +470 -467
- package/packages/resources/tools/cognitive-thinking/README.md +0 -284
- package/packages/resources/tools/cognitive-thinking/cognitive-thinking.tool.js +0 -837
- package/packages/server/mcp/sequential-thinking.handler.js +0 -318
- package/packages/server/mcp/think-plan.handler.js +0 -274
- package/packages/server/mcp/thinking-toolkit.handler.js +0 -380
- package/packages/web/0.d1c5a72339dfc32ad86a.js +0 -1
- package/packages/web/112.8807b976372b2b0541a8.js +0 -1
- package/packages/web/130.584c7e365da413f5d9be.js +0 -1
- package/packages/web/142.72c985bc29720f975cca.js +0 -1
- package/packages/web/165.a05fc53bf84d18db36b8.js +0 -2
- package/packages/web/165.a05fc53bf84d18db36b8.js.LICENSE.txt +0 -9
- package/packages/web/203.724ab9f717b80554c397.js +0 -1
- package/packages/web/241.bf941d4f02866795f64a.js +0 -1
- package/packages/web/249.54cfb224af63f5f5ec55.js +0 -1
- package/packages/web/291.6df35042f8f296fca7cd.js +0 -1
- package/packages/web/319.2fab900a31b29873f666.js +0 -1
- package/packages/web/32.c78d866281995ec33a7b.js +0 -1
- package/packages/web/325.9ca297d0f73f38468ce9.js +0 -1
- package/packages/web/366.2f9b48fdbf8eee039e57.js +0 -1
- package/packages/web/378.6be08c612cd5a3ef97dc.js +0 -1
- package/packages/web/393.7a2f817515c5e90623d7.js +0 -1
- package/packages/web/412.062df5f732d5ba203415.js +0 -1
- package/packages/web/426.08656fef4918b3fb19ad.js +0 -1
- package/packages/web/465.2be8018327130a3bd798.js +0 -1
- package/packages/web/48.8ca96fc93667a715e67a.js +0 -1
- package/packages/web/480.44c1f1a2927486ac3d4f.js +0 -1
- package/packages/web/489.e041a8d0db15dc96d607.js +0 -1
- package/packages/web/490.9ffb26c907de020d671b.js +0 -1
- package/packages/web/492.58781369e348d91fc06a.js +0 -1
- package/packages/web/495.ed63e99791a87167c6b3.js +0 -1
- package/packages/web/510.4cc07ab7d30d5c1cd17f.js +0 -1
- package/packages/web/543.3af155ed4fa237664308.js +0 -1
- package/packages/web/567.f04ab60f8e2c2fb0745a.js +0 -1
- package/packages/web/592.f3ad085fa9c1849daa06.js +0 -1
- package/packages/web/616.b03fb801b3433b17750f.js +0 -1
- package/packages/web/617.d88def54921d2c4dc44c.js +0 -1
- package/packages/web/641.d30787d674f548928261.js +0 -1
- package/packages/web/672.5269c8399fa42a5af95d.js +0 -1
- package/packages/web/731.97cab92b71811c502bda.js +0 -1
- package/packages/web/746.3947c6f0235407e420fb.js +0 -1
- package/packages/web/756.a53233b3f3913900d5ac.js +0 -1
- package/packages/web/77.68801af593a28a631fbf.js +0 -1
- package/packages/web/802.53b2bff3cf2a69f7b80c.js +0 -1
- package/packages/web/815.b6dfab82265f56c7e046.js +0 -1
- package/packages/web/821.f5a13e5c735aac244eb9.js +0 -1
- package/packages/web/846.b9bf97d5f559270675ce.js +0 -1
- package/packages/web/869.7c10403f500e6201407f.js +0 -1
- package/packages/web/885.135050364f99e6924fb5.js +0 -1
- package/packages/web/901.fd5aeb9df630609a2b43.js +0 -1
- package/packages/web/928.f67e590de3caa4daa3ae.js +0 -1
- package/packages/web/955.d833403521ba4dd567ee.js +0 -1
- package/packages/web/981.a45cb745cf424044c8c8.js +0 -1
- package/packages/web/992.645320b60c74c8787482.js +0 -1
- package/packages/web/996.ed9a963dc9e7439eca9a.js +0 -1
- package/packages/web/css/codemirror-theme_xq-light.css +0 -43
- package/packages/web/css/codemirror.css +0 -344
- package/packages/web/css/main.196f434e6a88cd448158.css +0 -7278
- package/packages/web/css/terminal-fix.css +0 -571
- package/packages/web/index.html +0 -3
- package/packages/web/main.dceff50c7307dda04873.js +0 -2
- package/packages/web/main.dceff50c7307dda04873.js.LICENSE.txt +0 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 工具手册生成服务
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* 职责:
|
|
5
5
|
* 1. 生成格式化的工具手册(manual模式)
|
|
6
6
|
* 2. 生成错误帮助信息(execute模式出错时)
|
|
@@ -14,19 +14,39 @@
|
|
|
14
14
|
* @returns {string} Markdown格式的手册
|
|
15
15
|
*/
|
|
16
16
|
export function generateManual(toolName, tool) {
|
|
17
|
+
// 如果工具实现了自定义的 generateManual 方法,优先使用它
|
|
18
|
+
if (tool.module && tool.module.generateManual && typeof tool.module.generateManual === 'function') {
|
|
19
|
+
try {
|
|
20
|
+
const result = tool.module.generateManual();
|
|
21
|
+
// 如果返回的是字符串,直接返回
|
|
22
|
+
if (typeof result === 'string') {
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
// 如果返回的是对象(MCP格式),提取text内容
|
|
26
|
+
if (result && result.content && result.content[0] && result.content[0].text) {
|
|
27
|
+
return result.content[0].text;
|
|
28
|
+
}
|
|
29
|
+
// 其他情况转换为字符串
|
|
30
|
+
return String(result);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
// 如果自定义方法出错,回退到通用生成器
|
|
33
|
+
console.warn(`工具 ${toolName} 的自定义 generateManual 方法出错,使用通用生成器:`, error.message);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
17
37
|
const { metadata, schema, businessErrors } = tool;
|
|
18
38
|
|
|
19
39
|
let manual = '';
|
|
20
|
-
|
|
40
|
+
|
|
21
41
|
// 标题和基本信息
|
|
22
42
|
manual += `# 📚 ${metadata.name || toolName}\n\n`;
|
|
23
|
-
|
|
43
|
+
|
|
24
44
|
if (metadata.description) {
|
|
25
45
|
manual += `## 📋 工具描述\n\n${metadata.description}\n\n`;
|
|
26
46
|
}
|
|
27
47
|
|
|
28
48
|
// 基本信息卡片
|
|
29
|
-
manual +=
|
|
49
|
+
manual += '## ℹ️ 基本信息\n\n';
|
|
30
50
|
if (metadata.version) {
|
|
31
51
|
manual += `- **版本**: ${metadata.version}\n`;
|
|
32
52
|
}
|
|
@@ -36,11 +56,11 @@ export function generateManual(toolName, tool) {
|
|
|
36
56
|
if (metadata.tags && metadata.tags.length > 0) {
|
|
37
57
|
manual += `- **标签**: ${metadata.tags.map(t => `\`${t}\``).join(', ')}\n`;
|
|
38
58
|
}
|
|
39
|
-
manual +=
|
|
59
|
+
manual += '\n';
|
|
40
60
|
|
|
41
61
|
// 使用场景
|
|
42
62
|
if (metadata.scenarios && metadata.scenarios.length > 0) {
|
|
43
|
-
manual +=
|
|
63
|
+
manual += '## 🎯 使用场景\n\n';
|
|
44
64
|
metadata.scenarios.forEach(scenario => {
|
|
45
65
|
manual += `- ✅ ${scenario}\n`;
|
|
46
66
|
});
|
|
@@ -49,14 +69,14 @@ export function generateManual(toolName, tool) {
|
|
|
49
69
|
|
|
50
70
|
// 参数说明
|
|
51
71
|
if (schema.parameters) {
|
|
52
|
-
manual +=
|
|
53
|
-
|
|
72
|
+
manual += '## 📝 参数说明\n\n';
|
|
73
|
+
|
|
54
74
|
const props = schema.parameters.properties || {};
|
|
55
75
|
const required = schema.parameters.required || [];
|
|
56
|
-
|
|
76
|
+
|
|
57
77
|
// 必需参数
|
|
58
78
|
if (required.length > 0) {
|
|
59
|
-
manual +=
|
|
79
|
+
manual += '### ✅ 必需参数\n\n';
|
|
60
80
|
for (const key of required) {
|
|
61
81
|
const prop = props[key];
|
|
62
82
|
if (prop) {
|
|
@@ -64,22 +84,22 @@ export function generateManual(toolName, tool) {
|
|
|
64
84
|
if (prop.enum) {
|
|
65
85
|
manual += ` - 可选值: ${prop.enum.map(v => `\`${v}\``).join(', ')}`;
|
|
66
86
|
}
|
|
67
|
-
manual +=
|
|
87
|
+
manual += '\n';
|
|
68
88
|
if (prop.description) {
|
|
69
89
|
manual += ` > ${prop.description}\n`;
|
|
70
90
|
}
|
|
71
91
|
if (prop.default !== undefined) {
|
|
72
92
|
manual += ` > 💡 默认值: \`${prop.default}\`\n`;
|
|
73
93
|
}
|
|
74
|
-
manual +=
|
|
94
|
+
manual += '\n';
|
|
75
95
|
}
|
|
76
96
|
}
|
|
77
97
|
}
|
|
78
|
-
|
|
98
|
+
|
|
79
99
|
// 可选参数
|
|
80
100
|
const optional = Object.keys(props).filter(k => !required.includes(k));
|
|
81
101
|
if (optional.length > 0) {
|
|
82
|
-
manual +=
|
|
102
|
+
manual += '### 📌 可选参数\n\n';
|
|
83
103
|
for (const key of optional) {
|
|
84
104
|
const prop = props[key];
|
|
85
105
|
if (prop) {
|
|
@@ -90,11 +110,11 @@ export function generateManual(toolName, tool) {
|
|
|
90
110
|
if (prop.enum) {
|
|
91
111
|
manual += ` - 可选值: ${prop.enum.map(v => `\`${v}\``).join(', ')}`;
|
|
92
112
|
}
|
|
93
|
-
manual +=
|
|
113
|
+
manual += '\n';
|
|
94
114
|
if (prop.description) {
|
|
95
115
|
manual += ` > ${prop.description}\n`;
|
|
96
116
|
}
|
|
97
|
-
manual +=
|
|
117
|
+
manual += '\n';
|
|
98
118
|
}
|
|
99
119
|
}
|
|
100
120
|
}
|
|
@@ -102,7 +122,7 @@ export function generateManual(toolName, tool) {
|
|
|
102
122
|
|
|
103
123
|
// 环境变量
|
|
104
124
|
if (schema.environment && schema.environment.properties) {
|
|
105
|
-
manual +=
|
|
125
|
+
manual += '## ⚙️ 环境变量配置\n\n';
|
|
106
126
|
const envProps = schema.environment.properties;
|
|
107
127
|
for (const [key, value] of Object.entries(envProps)) {
|
|
108
128
|
manual += `### \`${key}\`\n\n`;
|
|
@@ -113,13 +133,13 @@ export function generateManual(toolName, tool) {
|
|
|
113
133
|
manual += `**默认值**: \`${value.default}\`\n\n`;
|
|
114
134
|
}
|
|
115
135
|
}
|
|
116
|
-
|
|
117
|
-
manual +=
|
|
136
|
+
|
|
137
|
+
manual += '> 💡 使用 `mode: configure` 可以配置这些环境变量\n\n';
|
|
118
138
|
}
|
|
119
139
|
|
|
120
140
|
// 错误处理
|
|
121
141
|
if (businessErrors && businessErrors.length > 0) {
|
|
122
|
-
manual +=
|
|
142
|
+
manual += '## ⚠️ 常见错误处理\n\n';
|
|
123
143
|
businessErrors.forEach(error => {
|
|
124
144
|
manual += `### ${error.code}\n\n`;
|
|
125
145
|
manual += `- **描述**: ${error.description}\n`;
|
|
@@ -130,7 +150,7 @@ export function generateManual(toolName, tool) {
|
|
|
130
150
|
|
|
131
151
|
// 限制说明
|
|
132
152
|
if (metadata.limitations && metadata.limitations.length > 0) {
|
|
133
|
-
manual +=
|
|
153
|
+
manual += '## ⚠️ 限制说明\n\n';
|
|
134
154
|
metadata.limitations.forEach(limitation => {
|
|
135
155
|
manual += `- ⚠️ ${limitation}\n`;
|
|
136
156
|
});
|
|
@@ -138,27 +158,28 @@ export function generateManual(toolName, tool) {
|
|
|
138
158
|
}
|
|
139
159
|
|
|
140
160
|
// 使用示例
|
|
141
|
-
manual +=
|
|
142
|
-
manual +=
|
|
143
|
-
manual +=
|
|
161
|
+
manual += '## 💡 使用示例\n\n';
|
|
162
|
+
manual += '### 基础使用\n\n';
|
|
163
|
+
manual += '```yaml\n';
|
|
144
164
|
manual += `tool: tool://${toolName}\n`;
|
|
145
|
-
manual +=
|
|
146
|
-
manual +=
|
|
147
|
-
|
|
165
|
+
manual += 'mode: execute\n';
|
|
166
|
+
manual += 'parameters:\n';
|
|
167
|
+
|
|
148
168
|
// 生成示例参数
|
|
149
169
|
if (schema.parameters && schema.parameters.properties) {
|
|
150
170
|
const props = schema.parameters.properties;
|
|
151
171
|
const required = schema.parameters.required || [];
|
|
152
|
-
|
|
172
|
+
|
|
153
173
|
// 添加必需参数示例
|
|
154
|
-
for (const key of required.slice(0, 3)) {
|
|
174
|
+
for (const key of required.slice(0, 3)) {
|
|
175
|
+
// 最多显示3个必需参数
|
|
155
176
|
const prop = props[key];
|
|
156
177
|
if (prop) {
|
|
157
178
|
const exampleValue = generateExampleValue(key, prop);
|
|
158
179
|
manual += ` ${key}: ${exampleValue} # ${prop.description || ''}\n`;
|
|
159
180
|
}
|
|
160
181
|
}
|
|
161
|
-
|
|
182
|
+
|
|
162
183
|
// 添加可选参数示例(最多2个)
|
|
163
184
|
const optional = Object.keys(props).filter(k => !required.includes(k));
|
|
164
185
|
for (const key of optional.slice(0, 2)) {
|
|
@@ -169,8 +190,8 @@ export function generateManual(toolName, tool) {
|
|
|
169
190
|
}
|
|
170
191
|
}
|
|
171
192
|
}
|
|
172
|
-
|
|
173
|
-
manual +=
|
|
193
|
+
|
|
194
|
+
manual += '```\n\n';
|
|
174
195
|
|
|
175
196
|
return manual;
|
|
176
197
|
}
|
|
@@ -186,43 +207,43 @@ export function generateManual(toolName, tool) {
|
|
|
186
207
|
*/
|
|
187
208
|
export function generateHelpInfo(toolName, error, tool, parameters = {}, businessError = null) {
|
|
188
209
|
const { metadata, schema } = tool;
|
|
189
|
-
|
|
210
|
+
|
|
190
211
|
let helpText = '';
|
|
191
|
-
|
|
212
|
+
|
|
192
213
|
// 错误提示
|
|
193
|
-
helpText +=
|
|
214
|
+
helpText += '# ⚠️ 工具执行错误\n\n';
|
|
194
215
|
helpText += `**工具**: ${metadata.name || toolName}\n\n`;
|
|
195
216
|
helpText += `**错误信息**: \`${error.message}\`\n\n`;
|
|
196
|
-
|
|
217
|
+
|
|
197
218
|
if (businessError) {
|
|
198
219
|
helpText += `**错误类型**: ${businessError.description}\n\n`;
|
|
199
220
|
helpText += `**解决方案**: ${businessError.solution}\n\n`;
|
|
200
221
|
}
|
|
201
|
-
|
|
202
|
-
helpText +=
|
|
203
|
-
|
|
222
|
+
|
|
223
|
+
helpText += '---\n\n';
|
|
224
|
+
|
|
204
225
|
// 工具基本信息
|
|
205
|
-
helpText +=
|
|
226
|
+
helpText += '## 📋 工具信息\n\n';
|
|
206
227
|
if (metadata.description) {
|
|
207
228
|
helpText += `**描述**: ${metadata.description}\n\n`;
|
|
208
229
|
}
|
|
209
|
-
|
|
230
|
+
|
|
210
231
|
// 当前参数
|
|
211
232
|
if (parameters && Object.keys(parameters).length > 0) {
|
|
212
|
-
helpText +=
|
|
233
|
+
helpText += '## 📥 当前参数\n\n';
|
|
213
234
|
helpText += `\`\`\`json\n${JSON.stringify(parameters, null, 2)}\n\`\`\`\n\n`;
|
|
214
235
|
}
|
|
215
|
-
|
|
236
|
+
|
|
216
237
|
// 参数说明
|
|
217
238
|
if (schema.parameters) {
|
|
218
|
-
helpText +=
|
|
219
|
-
|
|
239
|
+
helpText += '## 📝 参数说明\n\n';
|
|
240
|
+
|
|
220
241
|
const props = schema.parameters.properties || {};
|
|
221
242
|
const required = schema.parameters.required || [];
|
|
222
|
-
|
|
243
|
+
|
|
223
244
|
// 必需参数
|
|
224
245
|
if (required.length > 0) {
|
|
225
|
-
helpText +=
|
|
246
|
+
helpText += '### ✅ 必需参数\n\n';
|
|
226
247
|
for (const key of required) {
|
|
227
248
|
const prop = props[key];
|
|
228
249
|
if (prop) {
|
|
@@ -230,19 +251,19 @@ export function generateHelpInfo(toolName, error, tool, parameters = {}, busines
|
|
|
230
251
|
if (prop.enum) {
|
|
231
252
|
helpText += ` - 可选值: ${prop.enum.map(v => `\`${v}\``).join(', ')}`;
|
|
232
253
|
}
|
|
233
|
-
helpText +=
|
|
254
|
+
helpText += '\n';
|
|
234
255
|
if (prop.description) {
|
|
235
256
|
helpText += ` > ${prop.description}\n`;
|
|
236
257
|
}
|
|
237
258
|
}
|
|
238
259
|
}
|
|
239
|
-
helpText +=
|
|
260
|
+
helpText += '\n';
|
|
240
261
|
}
|
|
241
|
-
|
|
262
|
+
|
|
242
263
|
// 可选参数
|
|
243
264
|
const optional = Object.keys(props).filter(k => !required.includes(k));
|
|
244
265
|
if (optional.length > 0) {
|
|
245
|
-
helpText +=
|
|
266
|
+
helpText += '### 📌 可选参数\n\n';
|
|
246
267
|
for (const key of optional) {
|
|
247
268
|
const prop = props[key];
|
|
248
269
|
if (prop) {
|
|
@@ -253,58 +274,58 @@ export function generateHelpInfo(toolName, error, tool, parameters = {}, busines
|
|
|
253
274
|
if (prop.enum) {
|
|
254
275
|
helpText += ` - 可选值: ${prop.enum.map(v => `\`${v}\``).join(', ')}`;
|
|
255
276
|
}
|
|
256
|
-
helpText +=
|
|
277
|
+
helpText += '\n';
|
|
257
278
|
if (prop.description) {
|
|
258
279
|
helpText += ` > ${prop.description}\n`;
|
|
259
280
|
}
|
|
260
281
|
}
|
|
261
282
|
}
|
|
262
|
-
helpText +=
|
|
283
|
+
helpText += '\n';
|
|
263
284
|
}
|
|
264
285
|
}
|
|
265
|
-
|
|
286
|
+
|
|
266
287
|
// 使用示例
|
|
267
|
-
helpText +=
|
|
268
|
-
|
|
288
|
+
helpText += '## 💡 使用示例\n\n';
|
|
289
|
+
|
|
269
290
|
// 根据错误类型生成不同的示例
|
|
270
291
|
if (error.message.includes('不支持的方法')) {
|
|
271
292
|
// 方法错误,显示所有支持的方法
|
|
272
293
|
if (schema.parameters && schema.parameters.properties && schema.parameters.properties.method) {
|
|
273
294
|
const methodEnum = schema.parameters.properties.method.enum || [];
|
|
274
295
|
if (methodEnum.length > 0) {
|
|
275
|
-
helpText +=
|
|
276
|
-
helpText +=
|
|
296
|
+
helpText += '### ❌ 错误:不支持的方法\n\n';
|
|
297
|
+
helpText += '**支持的方法列表**:\n\n';
|
|
277
298
|
methodEnum.forEach(method => {
|
|
278
299
|
helpText += `- \`${method}\`\n`;
|
|
279
300
|
});
|
|
280
|
-
helpText +=
|
|
301
|
+
helpText += '\n';
|
|
281
302
|
}
|
|
282
303
|
}
|
|
283
304
|
}
|
|
284
|
-
|
|
305
|
+
|
|
285
306
|
if (error.message.includes('缺少必需参数') || error.message.includes('缺少参数')) {
|
|
286
307
|
// 提取缺失的参数名
|
|
287
308
|
const missingMatch = error.message.match(/缺少.*参数[::]\s*([^\n]+)/i);
|
|
288
309
|
if (missingMatch) {
|
|
289
310
|
const missingParams = missingMatch[1].split(',').map(p => p.trim());
|
|
290
|
-
helpText +=
|
|
311
|
+
helpText += '### ❌ 错误:缺少必需参数\n\n';
|
|
291
312
|
helpText += `**缺失的参数**:${missingParams.map(p => `\`${p}\``).join(', ')}\n\n`;
|
|
292
|
-
helpText +=
|
|
313
|
+
helpText += '**这些参数是必需的,必须提供**\n\n';
|
|
293
314
|
}
|
|
294
315
|
}
|
|
295
|
-
|
|
316
|
+
|
|
296
317
|
// 生成正确的使用示例
|
|
297
|
-
helpText +=
|
|
298
|
-
helpText +=
|
|
318
|
+
helpText += '### ✅ 正确使用方式\n\n';
|
|
319
|
+
helpText += '```yaml\n';
|
|
299
320
|
helpText += `tool: tool://${toolName}\n`;
|
|
300
|
-
helpText +=
|
|
301
|
-
helpText +=
|
|
302
|
-
|
|
321
|
+
helpText += 'mode: execute\n';
|
|
322
|
+
helpText += 'parameters:\n';
|
|
323
|
+
|
|
303
324
|
// 根据schema生成示例参数
|
|
304
325
|
if (schema.parameters && schema.parameters.properties) {
|
|
305
326
|
const props = schema.parameters.properties;
|
|
306
327
|
const required = schema.parameters.required || [];
|
|
307
|
-
|
|
328
|
+
|
|
308
329
|
// 先添加必需参数
|
|
309
330
|
for (const key of required) {
|
|
310
331
|
const prop = props[key];
|
|
@@ -313,7 +334,7 @@ export function generateHelpInfo(toolName, error, tool, parameters = {}, busines
|
|
|
313
334
|
helpText += ` ${key}: ${exampleValue} # ${prop.description || ''}\n`;
|
|
314
335
|
}
|
|
315
336
|
}
|
|
316
|
-
|
|
337
|
+
|
|
317
338
|
// 添加一些常用的可选参数(最多3个)
|
|
318
339
|
const optional = Object.keys(props).filter(k => !required.includes(k));
|
|
319
340
|
let shownOptional = 0;
|
|
@@ -332,18 +353,18 @@ export function generateHelpInfo(toolName, error, tool, parameters = {}, busines
|
|
|
332
353
|
}
|
|
333
354
|
}
|
|
334
355
|
}
|
|
335
|
-
|
|
336
|
-
helpText +=
|
|
337
|
-
|
|
356
|
+
|
|
357
|
+
helpText += '```\n\n';
|
|
358
|
+
|
|
338
359
|
// 查看完整手册的提示
|
|
339
|
-
helpText +=
|
|
340
|
-
helpText +=
|
|
341
|
-
helpText +=
|
|
342
|
-
helpText +=
|
|
360
|
+
helpText += '---\n\n';
|
|
361
|
+
helpText += '## 🔍 需要更多帮助?\n\n';
|
|
362
|
+
helpText += '使用以下命令查看完整的工具手册:\n\n';
|
|
363
|
+
helpText += '```yaml\n';
|
|
343
364
|
helpText += `tool: tool://${toolName}\n`;
|
|
344
|
-
helpText +=
|
|
345
|
-
helpText +=
|
|
346
|
-
|
|
365
|
+
helpText += 'mode: manual\n';
|
|
366
|
+
helpText += '```\n\n';
|
|
367
|
+
|
|
347
368
|
return helpText;
|
|
348
369
|
}
|
|
349
370
|
|
|
@@ -357,7 +378,7 @@ function generateExampleValue(key, prop) {
|
|
|
357
378
|
if (prop.enum && prop.enum.length > 0) {
|
|
358
379
|
return prop.enum[0];
|
|
359
380
|
}
|
|
360
|
-
|
|
381
|
+
|
|
361
382
|
if (prop.type === 'string') {
|
|
362
383
|
// 根据参数名提供更合适的示例值
|
|
363
384
|
if (key.includes('path') || key.includes('url') || key.includes('file')) {
|
|
@@ -367,23 +388,22 @@ function generateExampleValue(key, prop) {
|
|
|
367
388
|
}
|
|
368
389
|
return '"示例值"';
|
|
369
390
|
}
|
|
370
|
-
|
|
391
|
+
|
|
371
392
|
if (prop.type === 'number') {
|
|
372
393
|
return '0';
|
|
373
394
|
}
|
|
374
|
-
|
|
395
|
+
|
|
375
396
|
if (prop.type === 'boolean') {
|
|
376
397
|
return 'true';
|
|
377
398
|
}
|
|
378
|
-
|
|
399
|
+
|
|
379
400
|
if (prop.type === 'array') {
|
|
380
401
|
return '[]';
|
|
381
402
|
}
|
|
382
|
-
|
|
403
|
+
|
|
383
404
|
if (prop.type === 'object') {
|
|
384
405
|
return '{}';
|
|
385
406
|
}
|
|
386
|
-
|
|
407
|
+
|
|
387
408
|
return '# 请填写';
|
|
388
409
|
}
|
|
389
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 工具模式处理器服务
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* 职责:
|
|
5
5
|
* 1. 处理 manual 模式 - 显示工具手册
|
|
6
6
|
* 2. 处理 configure 模式 - 配置工具环境变量
|
|
@@ -9,13 +9,13 @@
|
|
|
9
9
|
|
|
10
10
|
import fs from 'fs-extra';
|
|
11
11
|
import path from 'path';
|
|
12
|
-
import os from 'os';
|
|
13
12
|
import { logger } from '../utils/logger.js';
|
|
14
13
|
import { toolLoaderService } from './tool-loader.service.js';
|
|
15
14
|
import { saveToolEnvironment, getToolEnvironmentInfo } from './tool-environment.service.js';
|
|
16
15
|
import { flushAllLogQueues } from './tool-logger.service.js';
|
|
17
16
|
import { pathExists } from './tool-utils.js';
|
|
18
17
|
import { executeTool } from './tool-execution.service.js';
|
|
18
|
+
import { config } from '../utils/config.js';
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* 处理 manual 模式 - 显示工具手册
|
|
@@ -24,14 +24,14 @@ import { executeTool } from './tool-execution.service.js';
|
|
|
24
24
|
*/
|
|
25
25
|
export function handleManualMode(toolName) {
|
|
26
26
|
logger.info(`显示工具手册: ${toolName}`);
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
try {
|
|
29
29
|
const manual = toolLoaderService.generateManual(toolName);
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
return {
|
|
32
32
|
content: [
|
|
33
33
|
{
|
|
34
|
-
type:
|
|
34
|
+
type: 'text',
|
|
35
35
|
text: manual
|
|
36
36
|
}
|
|
37
37
|
]
|
|
@@ -60,14 +60,14 @@ export async function handleExecuteMode(toolName, parameters) {
|
|
|
60
60
|
*/
|
|
61
61
|
export async function handleConfigureMode(toolName, parameters) {
|
|
62
62
|
logger.info(`配置工具: ${toolName}`, { parameters });
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
try {
|
|
65
65
|
const tool = toolLoaderService.getTool(toolName);
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
// 获取工具的环境变量定义
|
|
68
68
|
const schema = tool.schema || {};
|
|
69
69
|
const envProps = schema.environment?.properties || {};
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
// 如果有配置参数,保存配置
|
|
72
72
|
if (parameters && Object.keys(parameters).length > 0) {
|
|
73
73
|
// 验证配置参数
|
|
@@ -78,77 +78,72 @@ export async function handleConfigureMode(toolName, parameters) {
|
|
|
78
78
|
}
|
|
79
79
|
configuredVars[key] = value;
|
|
80
80
|
}
|
|
81
|
-
|
|
81
|
+
|
|
82
82
|
// 保存到 .env 文件
|
|
83
83
|
await saveToolEnvironment(toolName, configuredVars);
|
|
84
|
-
|
|
84
|
+
|
|
85
85
|
logger.info(`工具配置成功: ${toolName}`, { configured: Object.keys(configuredVars) });
|
|
86
86
|
}
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
// 获取当前配置信息
|
|
89
89
|
const envInfo = await getToolEnvironmentInfo(toolName, schema);
|
|
90
90
|
const metadata = tool.metadata || {};
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
// 生成格式化的配置信息
|
|
93
|
-
let configText =
|
|
94
|
-
configText +=
|
|
93
|
+
let configText = '# 工具配置信息\n\n';
|
|
94
|
+
configText += '## 工具信息\n\n';
|
|
95
95
|
configText += `**工具名称**: ${toolName}\n`;
|
|
96
96
|
configText += `**工具版本**: ${metadata.version || '1.0.0'}\n`;
|
|
97
97
|
configText += `**配置状态**: ${envInfo.configured.length > 0 ? '✅ 已配置' : '⚠️ 未配置'}\n\n`;
|
|
98
|
-
|
|
99
|
-
configText +=
|
|
98
|
+
|
|
99
|
+
configText += '## 环境配置路径\n\n';
|
|
100
100
|
configText += `**配置文件路径**: \`${envInfo.envFilePath}\`\n\n`;
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
if (envInfo.configured.length > 0) {
|
|
103
|
-
configText +=
|
|
104
|
-
configText +=
|
|
105
|
-
configText +=
|
|
106
|
-
configText +=
|
|
103
|
+
configText += '## 当前配置\n\n';
|
|
104
|
+
configText += '### 已配置项\n\n';
|
|
105
|
+
configText += '| 配置项 | 当前值 | 说明 | 状态 |\n';
|
|
106
|
+
configText += '|--------|--------|------|------|\n';
|
|
107
107
|
for (const item of envInfo.configured) {
|
|
108
|
-
const value = String(item.value).length > 50
|
|
109
|
-
? String(item.value).substring(0, 50) + '...'
|
|
110
|
-
: String(item.value);
|
|
108
|
+
const value = String(item.value).length > 50 ? `${String(item.value).substring(0, 50)}...` : String(item.value);
|
|
111
109
|
configText += `| ${item.key} | ${value} | ${item.description} | ${item.status} |\n`;
|
|
112
110
|
}
|
|
113
|
-
configText +=
|
|
111
|
+
configText += '\n';
|
|
114
112
|
}
|
|
115
|
-
|
|
113
|
+
|
|
116
114
|
if (envInfo.unconfigured.length > 0) {
|
|
117
|
-
configText +=
|
|
118
|
-
configText +=
|
|
119
|
-
configText +=
|
|
115
|
+
configText += '### 未配置项(使用默认值)\n\n';
|
|
116
|
+
configText += '| 配置项 | 默认值 | 说明 | 状态 |\n';
|
|
117
|
+
configText += '|--------|--------|------|------|\n';
|
|
120
118
|
for (const item of envInfo.unconfigured) {
|
|
121
|
-
const defaultValue = item.defaultValue !== undefined
|
|
122
|
-
? String(item.defaultValue)
|
|
123
|
-
: '(无)';
|
|
119
|
+
const defaultValue = item.defaultValue !== undefined ? String(item.defaultValue) : '(无)';
|
|
124
120
|
configText += `| ${item.key} | ${defaultValue} | ${item.description} | ${item.status} |\n`;
|
|
125
121
|
}
|
|
126
|
-
configText +=
|
|
122
|
+
configText += '\n';
|
|
127
123
|
}
|
|
128
|
-
|
|
129
|
-
configText +=
|
|
130
|
-
configText +=
|
|
131
|
-
configText +=
|
|
132
|
-
configText +=
|
|
124
|
+
|
|
125
|
+
configText += '## 配置操作\n\n';
|
|
126
|
+
configText += '### 如何更新配置\n\n';
|
|
127
|
+
configText += '使用以下命令更新配置:\n\n';
|
|
128
|
+
configText += '```yaml\n';
|
|
133
129
|
configText += `tool: tool://${toolName}\n`;
|
|
134
|
-
configText +=
|
|
135
|
-
configText +=
|
|
130
|
+
configText += 'mode: configure\n';
|
|
131
|
+
configText += 'parameters:\n';
|
|
136
132
|
if (envProps && Object.keys(envProps).length > 0) {
|
|
137
133
|
const firstKey = Object.keys(envProps)[0];
|
|
138
134
|
const firstDef = envProps[firstKey];
|
|
139
135
|
configText += ` ${firstKey}: ${firstDef.default || 'value'}\n`;
|
|
140
136
|
}
|
|
141
|
-
configText +=
|
|
142
|
-
|
|
137
|
+
configText += '```\n\n';
|
|
138
|
+
|
|
143
139
|
return {
|
|
144
140
|
content: [
|
|
145
141
|
{
|
|
146
|
-
type:
|
|
142
|
+
type: 'text',
|
|
147
143
|
text: configText
|
|
148
144
|
}
|
|
149
145
|
]
|
|
150
146
|
};
|
|
151
|
-
|
|
152
147
|
} catch (error) {
|
|
153
148
|
logger.error(`工具配置失败: ${toolName}`, { error: error.message });
|
|
154
149
|
throw error;
|
|
@@ -163,35 +158,35 @@ export async function handleConfigureMode(toolName, parameters) {
|
|
|
163
158
|
*/
|
|
164
159
|
export async function handleLogMode(toolName, parameters) {
|
|
165
160
|
logger.info(`查看工具日志: ${toolName}`, { parameters });
|
|
166
|
-
|
|
161
|
+
|
|
167
162
|
try {
|
|
168
163
|
// 先刷新日志队列,确保最新日志已写入
|
|
169
164
|
await flushAllLogQueues();
|
|
170
|
-
|
|
171
|
-
const toolDir =
|
|
165
|
+
|
|
166
|
+
const toolDir = config.getToolDir(toolName);
|
|
172
167
|
const logFilePath = path.join(toolDir, 'run.log');
|
|
173
|
-
|
|
168
|
+
|
|
174
169
|
// 检查日志文件是否存在
|
|
175
|
-
if (!await pathExists(logFilePath)) {
|
|
170
|
+
if (!(await pathExists(logFilePath))) {
|
|
176
171
|
return {
|
|
177
172
|
content: [
|
|
178
173
|
{
|
|
179
|
-
type:
|
|
174
|
+
type: 'text',
|
|
180
175
|
text: `工具 ${toolName} 暂无日志文件\n\n日志文件路径: \`${logFilePath}\``
|
|
181
176
|
}
|
|
182
177
|
]
|
|
183
178
|
};
|
|
184
179
|
}
|
|
185
|
-
|
|
180
|
+
|
|
186
181
|
// 读取日志文件
|
|
187
182
|
const logContent = await fs.readFile(logFilePath, 'utf-8');
|
|
188
183
|
const logLines = logContent.split('\n').filter(line => line.trim());
|
|
189
|
-
|
|
184
|
+
|
|
190
185
|
const action = parameters.action || 'tail';
|
|
191
186
|
const lines = parameters.lines || 50;
|
|
192
|
-
|
|
187
|
+
|
|
193
188
|
let selectedLines = [];
|
|
194
|
-
|
|
189
|
+
|
|
195
190
|
if (action === 'tail') {
|
|
196
191
|
// 取最后N行
|
|
197
192
|
selectedLines = logLines.slice(-lines);
|
|
@@ -204,21 +199,19 @@ export async function handleLogMode(toolName, parameters) {
|
|
|
204
199
|
} else {
|
|
205
200
|
throw new Error(`不支持的操作: ${action},支持的操作: tail, head, all`);
|
|
206
201
|
}
|
|
207
|
-
|
|
202
|
+
|
|
208
203
|
const logText = selectedLines.join('\n');
|
|
209
|
-
|
|
204
|
+
|
|
210
205
|
return {
|
|
211
206
|
content: [
|
|
212
207
|
{
|
|
213
|
-
type:
|
|
208
|
+
type: 'text',
|
|
214
209
|
text: `# 工具日志\n\n**工具**: ${toolName}\n**日志文件**: \`${logFilePath}\`\n**操作**: ${action}\n**行数**: ${selectedLines.length}\n\n\`\`\`\n${logText}\n\`\`\``
|
|
215
210
|
}
|
|
216
211
|
]
|
|
217
212
|
};
|
|
218
|
-
|
|
219
213
|
} catch (error) {
|
|
220
214
|
logger.error(`查看工具日志失败: ${toolName}`, { error: error.message });
|
|
221
215
|
throw error;
|
|
222
216
|
}
|
|
223
217
|
}
|
|
224
|
-
|