flowmind 1.5.3 → 1.5.6
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/CHANGELOG.md +31 -1
- package/README.md +2 -0
- package/README_CN.md +2 -0
- package/bin/flowmind.js +104 -118
- package/core/adapters/mcp-adapter.js +9 -8
- package/core/ai/providers/mimo.js +1 -1
- package/core/cli-ink.js +79 -0
- package/core/index.js +139 -1
- package/core/log-query-parser.js +324 -0
- package/core/providers/aliyun/dms-adapter.js +7 -35
- package/core/providers/aliyun/redis-adapter.js +4 -20
- package/core/providers/aliyun/sls-adapter.js +3 -10
- package/core/providers/friday/report-adapter.js +5 -25
- package/core/providers/yapi/yapi-adapter.js +6 -30
- package/core/providers/yuque/yuque-adapter.js +7 -35
- package/core/update-notifier.js +74 -0
- package/dashboard/app.jsx +69 -10
- package/dashboard/components/ActivityFeed.jsx +5 -4
- package/dashboard/components/DragonPanel.jsx +17 -1
- package/dashboard/components/McpStatusBar.jsx +19 -1
- package/dashboard/components/StatsRow.jsx +27 -2
- package/package.json +2 -1
- package/scripts/check-update.js +52 -0
- package/skills/auto-flow/index.js +451 -122
- package/skills/log-audit/index.js +146 -25
- package/skills/sls-log-audit/index.js +7 -30
- package/skills/yapi-sync-interface/index.js +146 -13
- package/skills/yuque-sync-design/index.js +132 -13
- package/tui/app.jsx +86 -9
- package/tui/components/ChatPanel.jsx +10 -7
- package/tui/components/DragonTotem.jsx +12 -1
- package/tui/components/Sidebar.jsx +19 -7
- package/tui/components/StatusBar.jsx +28 -1
- package/tui/format-result.js +60 -0
- package/tui/layout.js +60 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
function parseLogQueryParams(input, options = {}) {
|
|
2
|
+
const params = {};
|
|
3
|
+
const text = String(input || '');
|
|
4
|
+
|
|
5
|
+
const traceMatch = text.match(/(?:trace[_-]?id|调用链)\s*[:=]?\s*(\S+)/i);
|
|
6
|
+
if (traceMatch) params.traceId = traceMatch[1];
|
|
7
|
+
|
|
8
|
+
const naturalProjectService = options.allowNaturalService !== false || options.allowNaturalProject !== false
|
|
9
|
+
? extractNaturalProjectServicePair(text)
|
|
10
|
+
: null;
|
|
11
|
+
if (naturalProjectService) {
|
|
12
|
+
if (naturalProjectService.project && !params.project) {
|
|
13
|
+
params.project = naturalProjectService.project;
|
|
14
|
+
}
|
|
15
|
+
if (naturalProjectService.service && !params.service) {
|
|
16
|
+
params.service = naturalProjectService.service;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const serviceMatch = text.match(/(?:服务|service)\s*[:=]?\s*(\S+)/i);
|
|
21
|
+
if (serviceMatch) {
|
|
22
|
+
params.service = serviceMatch[1];
|
|
23
|
+
} else if (!params.service && options.allowNaturalService !== false) {
|
|
24
|
+
const naturalService = extractNaturalService(text);
|
|
25
|
+
if (naturalService) {
|
|
26
|
+
params.service = naturalService;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const levelMatch = text.match(/(?:级别|level)\s*[:=]?\s*(ERROR|WARN|INFO|DEBUG)/i);
|
|
31
|
+
if (levelMatch) {
|
|
32
|
+
params.level = levelMatch[1].toUpperCase();
|
|
33
|
+
} else if (options.allowNaturalLevel !== false) {
|
|
34
|
+
const naturalLevel = extractNaturalLevel(text);
|
|
35
|
+
if (naturalLevel) {
|
|
36
|
+
params.level = naturalLevel;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const projectMatch = text.match(/(?:项目|project)\s*[:=]?\s*([A-Za-z][A-Za-z0-9._-]{2,})\b/i);
|
|
41
|
+
if (projectMatch) {
|
|
42
|
+
params.project = projectMatch[1];
|
|
43
|
+
} else if (!params.project && options.allowNaturalProject !== false) {
|
|
44
|
+
const naturalProject = extractNaturalProject(text);
|
|
45
|
+
if (naturalProject) {
|
|
46
|
+
params.project = naturalProject;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const logstoreMatch = text.match(/(?:logstore|日志库)\s*[:=]?\s*(\S+)/i);
|
|
51
|
+
if (logstoreMatch) params.logstore = logstoreMatch[1];
|
|
52
|
+
|
|
53
|
+
const envMatch = text.match(/(?:环境|env)\s*[:=]?\s*(test|uat|gray|prod)/i);
|
|
54
|
+
if (envMatch) params.env = envMatch[1].toLowerCase();
|
|
55
|
+
|
|
56
|
+
const keywordMatch = text.match(/(?:^|[^A-Za-z0-9._-])(?:关键词|keyword|搜索|search)(?![A-Za-z0-9._-])\s*[:=]?\s*(.+?)(?:\s*$)/i);
|
|
57
|
+
if (keywordMatch) {
|
|
58
|
+
params.keyword = keywordMatch[1].trim();
|
|
59
|
+
} else if (options.allowQuotedKeyword !== false) {
|
|
60
|
+
const quotedKeyword = extractQuotedText(text);
|
|
61
|
+
if (quotedKeyword) {
|
|
62
|
+
params.keyword = quotedKeyword;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!params.keyword && options.allowNaturalKeyword !== false) {
|
|
67
|
+
const naturalKeyword = extractNaturalKeyword(text);
|
|
68
|
+
if (naturalKeyword) {
|
|
69
|
+
params.keyword = naturalKeyword;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const timeWindow = extractTimeWindow(text);
|
|
74
|
+
if (timeWindow) {
|
|
75
|
+
params.timeRange = timeWindow.label;
|
|
76
|
+
params.from = timeWindow.from;
|
|
77
|
+
params.to = timeWindow.to;
|
|
78
|
+
} else {
|
|
79
|
+
const timeMatch = text.match(/(?:最近|last)\s*(\d+)\s*(分钟|小时|天|min|hour|day)/i);
|
|
80
|
+
if (timeMatch) {
|
|
81
|
+
params.timeRange = `last ${timeMatch[1]} ${timeMatch[2]}`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return params;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function extractNaturalLevel(text) {
|
|
89
|
+
const normalized = String(text || '').toLowerCase();
|
|
90
|
+
if (/(错误|异常|报错|失败|宕机|超时|timeout|error|fail)/i.test(normalized)) {
|
|
91
|
+
return 'ERROR';
|
|
92
|
+
}
|
|
93
|
+
if (/(告警|警告|warning|warn)/i.test(normalized)) {
|
|
94
|
+
return 'WARN';
|
|
95
|
+
}
|
|
96
|
+
if (/(信息|info)/i.test(normalized)) {
|
|
97
|
+
return 'INFO';
|
|
98
|
+
}
|
|
99
|
+
if (/(调试|debug)/i.test(normalized)) {
|
|
100
|
+
return 'DEBUG';
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function extractQuotedText(input) {
|
|
106
|
+
const quotedMatches = [...String(input || '').matchAll(/["'“”‘’]([^"'“”‘’]{2,})["'“”‘’]/g)];
|
|
107
|
+
if (quotedMatches.length === 0) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let best = '';
|
|
112
|
+
for (const match of quotedMatches) {
|
|
113
|
+
const candidate = (match[1] || '').trim();
|
|
114
|
+
if (candidate.length > best.length) {
|
|
115
|
+
best = candidate;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return normalizeNaturalKeyword(best);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function extractNaturalKeyword(input) {
|
|
123
|
+
const text = String(input || '').trim();
|
|
124
|
+
if (!text) return null;
|
|
125
|
+
|
|
126
|
+
const patterns = [
|
|
127
|
+
/(?:日志|log(?:s| audit| analysis)?)[,,、::\s]+([^。!?\n]{2,120}?)(?=(?:是\s*什么异常|是什么异常|怎么回事|为什么|什么原因|原因|报错|错误|异常|问题|$))/i,
|
|
128
|
+
/(?:日志|log(?:s| audit| analysis)?)[,,、::\s]+([^。!?\n]{2,120}?)(?=$|\n|[。!?])/i
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
for (const pattern of patterns) {
|
|
132
|
+
const match = text.match(pattern);
|
|
133
|
+
if (!match || !match[1]) continue;
|
|
134
|
+
const candidate = normalizeNaturalKeyword(match[1]);
|
|
135
|
+
if (candidate) {
|
|
136
|
+
return candidate;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function extractNaturalService(input) {
|
|
144
|
+
const text = String(input || '').trim();
|
|
145
|
+
if (!text) return null;
|
|
146
|
+
|
|
147
|
+
const patterns = [
|
|
148
|
+
/([A-Za-z][A-Za-z0-9._-]{2,})\s*项目(?:的)?\s*([A-Za-z][A-Za-z0-9._-]{2,})\s*(?:错误|异常|告警|故障|问题|调试|排查)?(?:日志|log|链路|trace|调用链)(?![A-Za-z0-9._-])/i,
|
|
149
|
+
/([A-Za-z][A-Za-z0-9._-]{2,})\s*(?:的)?\s*(?:错误|异常|告警|故障|问题|调试|排查)?(?:日志|log|链路|trace|调用链)(?![A-Za-z0-9._-])/i,
|
|
150
|
+
/(?:查|查询|查看|排查|分析|定位)?(?:下)?(?:服务|service|应用|app|系统|模块)?\s*([A-Za-z][A-Za-z0-9._-]{2,})\s*(?:的)?(?:错误|异常|告警|故障|问题|调试|排查)?(?:日志|log|链路|trace|调用链)(?![A-Za-z0-9._-])/i,
|
|
151
|
+
/(?:项目|project)\s*(?:的)?\s*([A-Za-z][A-Za-z0-9._-]{2,})\s*(?:错误|异常|告警|故障|问题|调试|排查)?(?:日志|log|链路|trace|调用链)(?![A-Za-z0-9._-])/i,
|
|
152
|
+
/(?:错误|异常|告警|故障|问题|调试|排查)?(?:日志|log|链路|trace)\s*[::\s]*([A-Za-z][A-Za-z0-9._-]{2,})/i
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
for (const pattern of patterns) {
|
|
156
|
+
const match = text.match(pattern);
|
|
157
|
+
if (!match || !match[1]) continue;
|
|
158
|
+
const candidate = normalizeEntityCandidate(match[1]);
|
|
159
|
+
if (candidate) {
|
|
160
|
+
return candidate;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function extractNaturalProject(input) {
|
|
168
|
+
const text = String(input || '').trim();
|
|
169
|
+
if (!text) return null;
|
|
170
|
+
|
|
171
|
+
const patterns = [
|
|
172
|
+
/([A-Za-z][A-Za-z0-9._-]{2,})\s*项目(?:的)?\s*[A-Za-z][A-Za-z0-9._-]{2,}\s*(?:错误|异常|告警|故障|问题|调试|排查)?(?:日志|log|链路|trace|调用链)(?![A-Za-z0-9._-])/i,
|
|
173
|
+
/(?:项目|project)\s*[:=]?\s*([A-Za-z][A-Za-z0-9._-]{2,})/i,
|
|
174
|
+
/([A-Za-z][A-Za-z0-9._-]{2,})\s*(?:项目|project)(?:的)?/i
|
|
175
|
+
];
|
|
176
|
+
|
|
177
|
+
for (const pattern of patterns) {
|
|
178
|
+
const match = text.match(pattern);
|
|
179
|
+
if (!match || !match[1]) continue;
|
|
180
|
+
const candidate = normalizeEntityCandidate(match[1]);
|
|
181
|
+
if (candidate) {
|
|
182
|
+
return candidate;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function normalizeNaturalKeyword(value) {
|
|
190
|
+
const candidate = String(value || '')
|
|
191
|
+
.replace(/^[,,、::\s]+/, '')
|
|
192
|
+
.replace(/[,,、::\s]+$/, '')
|
|
193
|
+
.replace(/^(查询|查|查看|分析|定位|排查)\s*(?:下)?\s*/i, '')
|
|
194
|
+
.replace(/^(最近|近|过去|前)\s*\d+\s*(分钟|小时|天|min|hour|day)\s*的?/i, '')
|
|
195
|
+
.replace(/^(今天|今日|昨天|昨日|本周|这周|近7天|近24小时|近1小时|最近1小时|最近1天)\s*的?/i, '')
|
|
196
|
+
.replace(/^(下|下个|一下|一下子)/, '')
|
|
197
|
+
.trim();
|
|
198
|
+
|
|
199
|
+
if (!candidate) return null;
|
|
200
|
+
if (/^(日志|log|logs|错误|异常|报错|失败|问题|警告|告警|error|warn|info|debug)$/i.test(candidate)) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
if (/(?:项目|服务|日志|log|trace|调用链)/i.test(candidate) && /[A-Za-z][A-Za-z0-9._-]{2,}/.test(candidate)) {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return candidate;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function normalizeEntityCandidate(value) {
|
|
211
|
+
const candidate = String(value || '').trim();
|
|
212
|
+
if (!candidate) return null;
|
|
213
|
+
if (/^(日志|log|logs|错误|异常|报错|失败|问题|警告|告警|error|warn|info|debug)$/i.test(candidate)) {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
return candidate;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function extractNaturalProjectServicePair(input) {
|
|
220
|
+
const text = String(input || '').trim();
|
|
221
|
+
if (!text) return null;
|
|
222
|
+
|
|
223
|
+
const patterns = [
|
|
224
|
+
/([A-Za-z][A-Za-z0-9._-]{2,})\s*项目(?:的)?\s*([A-Za-z][A-Za-z0-9._-]{2,})\b/i,
|
|
225
|
+
/(?:项目|project)\s*(?:的)?\s*([A-Za-z][A-Za-z0-9._-]{2,})\b/i
|
|
226
|
+
];
|
|
227
|
+
|
|
228
|
+
for (const pattern of patterns) {
|
|
229
|
+
const match = text.match(pattern);
|
|
230
|
+
if (!match) continue;
|
|
231
|
+
|
|
232
|
+
if (match.length >= 3) {
|
|
233
|
+
const project = normalizeEntityCandidate(match[1]);
|
|
234
|
+
const service = normalizeEntityCandidate(match[2]);
|
|
235
|
+
if (project || service) {
|
|
236
|
+
return { project, service };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const service = normalizeEntityCandidate(match[1]);
|
|
241
|
+
if (service) {
|
|
242
|
+
return { service };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function extractTimeWindow(input) {
|
|
250
|
+
const text = String(input || '');
|
|
251
|
+
const now = new Date();
|
|
252
|
+
|
|
253
|
+
const recentMatch = text.match(/(?:最近|近|过去|前)\s*(\d+)\s*(分钟|小时|天|min|hour|day)/i);
|
|
254
|
+
if (recentMatch) {
|
|
255
|
+
const amount = Number(recentMatch[1]);
|
|
256
|
+
const unit = normalizeTimeUnit(recentMatch[2]);
|
|
257
|
+
if (Number.isFinite(amount) && amount > 0 && unit) {
|
|
258
|
+
const from = new Date(now.getTime() - amount * unitToMs(unit));
|
|
259
|
+
return {
|
|
260
|
+
label: `last ${amount} ${recentMatch[2]}`,
|
|
261
|
+
from: from.toISOString(),
|
|
262
|
+
to: now.toISOString()
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (/今天|今日/i.test(text)) {
|
|
268
|
+
const from = new Date(now);
|
|
269
|
+
from.setHours(0, 0, 0, 0);
|
|
270
|
+
return {
|
|
271
|
+
label: 'today',
|
|
272
|
+
from: from.toISOString(),
|
|
273
|
+
to: now.toISOString()
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (/昨天|昨日/i.test(text)) {
|
|
278
|
+
const to = new Date(now);
|
|
279
|
+
to.setHours(0, 0, 0, 0);
|
|
280
|
+
const from = new Date(to.getTime() - 24 * 60 * 60 * 1000);
|
|
281
|
+
return {
|
|
282
|
+
label: 'yesterday',
|
|
283
|
+
from: from.toISOString(),
|
|
284
|
+
to: to.toISOString()
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (/本周|这周|近7天/i.test(text)) {
|
|
289
|
+
const to = new Date(now);
|
|
290
|
+
const from = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
291
|
+
return {
|
|
292
|
+
label: 'last 7 days',
|
|
293
|
+
from: from.toISOString(),
|
|
294
|
+
to: to.toISOString()
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function normalizeTimeUnit(unit) {
|
|
302
|
+
const text = String(unit || '').toLowerCase();
|
|
303
|
+
if (text === 'min' || text === 'minute' || text === 'minutes' || text === '分钟') return 'minute';
|
|
304
|
+
if (text === 'hour' || text === 'hours' || text === '小时') return 'hour';
|
|
305
|
+
if (text === 'day' || text === 'days' || text === '天') return 'day';
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function unitToMs(unit) {
|
|
310
|
+
if (unit === 'minute') return 60 * 1000;
|
|
311
|
+
if (unit === 'hour') return 60 * 60 * 1000;
|
|
312
|
+
if (unit === 'day') return 24 * 60 * 60 * 1000;
|
|
313
|
+
return 0;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
module.exports = {
|
|
317
|
+
detectNaturalLevel: extractNaturalLevel,
|
|
318
|
+
extractNaturalProject,
|
|
319
|
+
extractNaturalService,
|
|
320
|
+
extractNaturalKeyword,
|
|
321
|
+
extractQuotedText,
|
|
322
|
+
extractTimeWindow,
|
|
323
|
+
parseLogQueryParams
|
|
324
|
+
};
|
|
@@ -27,43 +27,23 @@ class AliyunDmsAdapter extends DatabaseManagerAdapter {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
async listInstances(params) {
|
|
30
|
-
return {
|
|
31
|
-
mcpServer: this.mcpServer,
|
|
32
|
-
tool: this.resolveTool('listInstances'),
|
|
33
|
-
params: params || {}
|
|
34
|
-
};
|
|
30
|
+
return this.callMcpTool('listInstances', params || {});
|
|
35
31
|
}
|
|
36
32
|
|
|
37
33
|
async executeScript(params) {
|
|
38
|
-
return
|
|
39
|
-
mcpServer: this.mcpServer,
|
|
40
|
-
tool: this.resolveTool('executeScript'),
|
|
41
|
-
params
|
|
42
|
-
};
|
|
34
|
+
return this.callMcpTool('executeScript', params);
|
|
43
35
|
}
|
|
44
36
|
|
|
45
37
|
async searchDatabase(searchKey) {
|
|
46
|
-
return {
|
|
47
|
-
mcpServer: this.mcpServer,
|
|
48
|
-
tool: this.resolveTool('searchDatabase'),
|
|
49
|
-
params: { search_key: searchKey }
|
|
50
|
-
};
|
|
38
|
+
return this.callMcpTool('searchDatabase', { search_key: searchKey });
|
|
51
39
|
}
|
|
52
40
|
|
|
53
41
|
async listTables(databaseId) {
|
|
54
|
-
return {
|
|
55
|
-
mcpServer: this.mcpServer,
|
|
56
|
-
tool: this.resolveTool('listTables'),
|
|
57
|
-
params: { database_id: databaseId }
|
|
58
|
-
};
|
|
42
|
+
return this.callMcpTool('listTables', { database_id: databaseId });
|
|
59
43
|
}
|
|
60
44
|
|
|
61
45
|
async getTableDetail(tableGuid) {
|
|
62
|
-
return {
|
|
63
|
-
mcpServer: this.mcpServer,
|
|
64
|
-
tool: this.resolveTool('getTableDetailInfo'),
|
|
65
|
-
params: { table_guid: tableGuid }
|
|
66
|
-
};
|
|
46
|
+
return this.callMcpTool('getTableDetailInfo', { table_guid: tableGuid });
|
|
67
47
|
}
|
|
68
48
|
|
|
69
49
|
/**
|
|
@@ -73,11 +53,7 @@ class AliyunDmsAdapter extends DatabaseManagerAdapter {
|
|
|
73
53
|
* @returns {Promise<object>}
|
|
74
54
|
*/
|
|
75
55
|
async generateSql(databaseId, question) {
|
|
76
|
-
return {
|
|
77
|
-
mcpServer: this.mcpServer,
|
|
78
|
-
tool: this.resolveTool('generateSql'),
|
|
79
|
-
params: { database_id: databaseId, question }
|
|
80
|
-
};
|
|
56
|
+
return this.callMcpTool('generateSql', { database_id: databaseId, question });
|
|
81
57
|
}
|
|
82
58
|
|
|
83
59
|
/**
|
|
@@ -87,11 +63,7 @@ class AliyunDmsAdapter extends DatabaseManagerAdapter {
|
|
|
87
63
|
* @returns {Promise<object>}
|
|
88
64
|
*/
|
|
89
65
|
async optimizeSql(databaseId, sql) {
|
|
90
|
-
return {
|
|
91
|
-
mcpServer: this.mcpServer,
|
|
92
|
-
tool: this.resolveTool('optimizeSql'),
|
|
93
|
-
params: { database_id: databaseId, sql }
|
|
94
|
-
};
|
|
66
|
+
return this.callMcpTool('optimizeSql', { database_id: databaseId, sql });
|
|
95
67
|
}
|
|
96
68
|
}
|
|
97
69
|
|
|
@@ -34,11 +34,7 @@ class AliyunRedisAdapter extends McpAdapter {
|
|
|
34
34
|
* @returns {Promise<object>}
|
|
35
35
|
*/
|
|
36
36
|
async query(query, time) {
|
|
37
|
-
return {
|
|
38
|
-
mcpServer: this.mcpServer,
|
|
39
|
-
tool: this.resolveTool('query'),
|
|
40
|
-
params: { query, time }
|
|
41
|
-
};
|
|
37
|
+
return this.callMcpTool('query', { query, time });
|
|
42
38
|
}
|
|
43
39
|
|
|
44
40
|
/**
|
|
@@ -50,11 +46,7 @@ class AliyunRedisAdapter extends McpAdapter {
|
|
|
50
46
|
* @returns {Promise<object>}
|
|
51
47
|
*/
|
|
52
48
|
async queryRange(query, start, end, step) {
|
|
53
|
-
return {
|
|
54
|
-
mcpServer: this.mcpServer,
|
|
55
|
-
tool: this.resolveTool('queryRange'),
|
|
56
|
-
params: { query, start, end, step }
|
|
57
|
-
};
|
|
49
|
+
return this.callMcpTool('queryRange', { query, start, end, step });
|
|
58
50
|
}
|
|
59
51
|
|
|
60
52
|
/**
|
|
@@ -63,11 +55,7 @@ class AliyunRedisAdapter extends McpAdapter {
|
|
|
63
55
|
* @returns {Promise<object>}
|
|
64
56
|
*/
|
|
65
57
|
async getLabelNames(params) {
|
|
66
|
-
return {
|
|
67
|
-
mcpServer: this.mcpServer,
|
|
68
|
-
tool: this.resolveTool('getLabelNames'),
|
|
69
|
-
params: params || {}
|
|
70
|
-
};
|
|
58
|
+
return this.callMcpTool('getLabelNames', params || {});
|
|
71
59
|
}
|
|
72
60
|
|
|
73
61
|
/**
|
|
@@ -77,11 +65,7 @@ class AliyunRedisAdapter extends McpAdapter {
|
|
|
77
65
|
* @returns {Promise<object>}
|
|
78
66
|
*/
|
|
79
67
|
async getLabelValues(name, params) {
|
|
80
|
-
return {
|
|
81
|
-
mcpServer: this.mcpServer,
|
|
82
|
-
tool: this.resolveTool('getLabelValues'),
|
|
83
|
-
params: { name, ...(params || {}) }
|
|
84
|
-
};
|
|
68
|
+
return this.callMcpTool('getLabelValues', { name, ...(params || {}) });
|
|
85
69
|
}
|
|
86
70
|
}
|
|
87
71
|
|
|
@@ -11,6 +11,7 @@ class AliyunSlsAdapter extends LogServiceAdapter {
|
|
|
11
11
|
|
|
12
12
|
// Register MCP tool mappings
|
|
13
13
|
this.registerTool('queryLogs', 'queryLogs');
|
|
14
|
+
this.registerTool('listProjects', 'listProject');
|
|
14
15
|
this.registerTool('listProject', 'listProject');
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -46,19 +47,11 @@ class AliyunSlsAdapter extends LogServiceAdapter {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
async queryLogs(params) {
|
|
49
|
-
return {
|
|
50
|
-
mcpServer: this.mcpServer,
|
|
51
|
-
tool: this.resolveTool('queryLogs'),
|
|
52
|
-
params
|
|
53
|
-
};
|
|
50
|
+
return this.callMcpTool('queryLogs', params || {});
|
|
54
51
|
}
|
|
55
52
|
|
|
56
53
|
async listProjects() {
|
|
57
|
-
return {
|
|
58
|
-
mcpServer: this.mcpServer,
|
|
59
|
-
tool: this.resolveTool('listProject'),
|
|
60
|
-
params: {}
|
|
61
|
-
};
|
|
54
|
+
return this.callMcpTool('listProjects', {});
|
|
62
55
|
}
|
|
63
56
|
|
|
64
57
|
/**
|
|
@@ -40,43 +40,23 @@ class FridayReportAdapter extends ReportAdapter {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
async listBuilds(params) {
|
|
43
|
-
return {
|
|
44
|
-
mcpServer: this.mcpServer,
|
|
45
|
-
tool: this.resolveTool('listBuilds'),
|
|
46
|
-
params: params || {}
|
|
47
|
-
};
|
|
43
|
+
return this.callMcpTool('listBuilds', params || {});
|
|
48
44
|
}
|
|
49
45
|
|
|
50
46
|
async getBuildInfo(buildId) {
|
|
51
|
-
return {
|
|
52
|
-
mcpServer: this.mcpServer,
|
|
53
|
-
tool: this.resolveTool('getBuildInfo'),
|
|
54
|
-
params: { id: buildId }
|
|
55
|
-
};
|
|
47
|
+
return this.callMcpTool('getBuildInfo', { id: buildId });
|
|
56
48
|
}
|
|
57
49
|
|
|
58
50
|
async listJacocoReports(params) {
|
|
59
|
-
return {
|
|
60
|
-
mcpServer: this.mcpServer,
|
|
61
|
-
tool: this.resolveTool('listJacoco'),
|
|
62
|
-
params: params || {}
|
|
63
|
-
};
|
|
51
|
+
return this.callMcpTool('listJacoco', params || {});
|
|
64
52
|
}
|
|
65
53
|
|
|
66
54
|
async listUnitReports(params) {
|
|
67
|
-
return {
|
|
68
|
-
mcpServer: this.mcpServer,
|
|
69
|
-
tool: this.resolveTool('listJacocoUnit'),
|
|
70
|
-
params: params || {}
|
|
71
|
-
};
|
|
55
|
+
return this.callMcpTool('listJacocoUnit', params || {});
|
|
72
56
|
}
|
|
73
57
|
|
|
74
58
|
async getJobDetails(jobName) {
|
|
75
|
-
return {
|
|
76
|
-
mcpServer: this.mcpServer,
|
|
77
|
-
tool: this.resolveTool('getJobDetails'),
|
|
78
|
-
params: { jobName }
|
|
79
|
-
};
|
|
59
|
+
return this.callMcpTool('getJobDetails', { jobName });
|
|
80
60
|
}
|
|
81
61
|
}
|
|
82
62
|
|
|
@@ -28,51 +28,27 @@ class YapiAdapter extends ApiDocAdapter {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
async searchApis(params) {
|
|
31
|
-
return
|
|
32
|
-
mcpServer: this.mcpServer,
|
|
33
|
-
tool: this.resolveTool('searchApis'),
|
|
34
|
-
params
|
|
35
|
-
};
|
|
31
|
+
return this.callMcpTool('searchApis', params);
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
async getCategories(projectId) {
|
|
39
|
-
return {
|
|
40
|
-
mcpServer: this.mcpServer,
|
|
41
|
-
tool: this.resolveTool('getCategories'),
|
|
42
|
-
params: { projectId }
|
|
43
|
-
};
|
|
35
|
+
return this.callMcpTool('getCategories', { projectId });
|
|
44
36
|
}
|
|
45
37
|
|
|
46
38
|
async saveApi(apiData) {
|
|
47
|
-
return
|
|
48
|
-
mcpServer: this.mcpServer,
|
|
49
|
-
tool: this.resolveTool('saveApi'),
|
|
50
|
-
params: apiData
|
|
51
|
-
};
|
|
39
|
+
return this.callMcpTool('saveApi', apiData);
|
|
52
40
|
}
|
|
53
41
|
|
|
54
42
|
async importSwagger(projectId, catId, swaggerData) {
|
|
55
|
-
return {
|
|
56
|
-
mcpServer: this.mcpServer,
|
|
57
|
-
tool: this.resolveTool('importSwagger'),
|
|
58
|
-
params: { projectId, catId, swaggerData }
|
|
59
|
-
};
|
|
43
|
+
return this.callMcpTool('importSwagger', { projectId, catId, swaggerData });
|
|
60
44
|
}
|
|
61
45
|
|
|
62
46
|
async exportProject(projectId, type = 'swagger') {
|
|
63
|
-
return {
|
|
64
|
-
mcpServer: this.mcpServer,
|
|
65
|
-
tool: this.resolveTool('exportProject'),
|
|
66
|
-
params: { projectId, type }
|
|
67
|
-
};
|
|
47
|
+
return this.callMcpTool('exportProject', { projectId, type });
|
|
68
48
|
}
|
|
69
49
|
|
|
70
50
|
async listProjects() {
|
|
71
|
-
return {
|
|
72
|
-
mcpServer: this.mcpServer,
|
|
73
|
-
tool: this.resolveTool('listProjects'),
|
|
74
|
-
params: {}
|
|
75
|
-
};
|
|
51
|
+
return this.callMcpTool('listProjects', {});
|
|
76
52
|
}
|
|
77
53
|
}
|
|
78
54
|
|
|
@@ -27,51 +27,27 @@ class YuqueAdapter extends KnowledgeBaseAdapter {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
async getRepos(params) {
|
|
30
|
-
return
|
|
31
|
-
mcpServer: this.mcpServer,
|
|
32
|
-
tool: this.resolveTool('getRepos'),
|
|
33
|
-
params
|
|
34
|
-
};
|
|
30
|
+
return this.callMcpTool('getRepos', params);
|
|
35
31
|
}
|
|
36
32
|
|
|
37
33
|
async getDocs(namespace, params = {}) {
|
|
38
|
-
return {
|
|
39
|
-
mcpServer: this.mcpServer,
|
|
40
|
-
tool: this.resolveTool('getDocs'),
|
|
41
|
-
params: { namespace, ...params }
|
|
42
|
-
};
|
|
34
|
+
return this.callMcpTool('getDocs', { namespace, ...params });
|
|
43
35
|
}
|
|
44
36
|
|
|
45
37
|
async getDoc(namespace, slug) {
|
|
46
|
-
return {
|
|
47
|
-
mcpServer: this.mcpServer,
|
|
48
|
-
tool: this.resolveTool('getDoc'),
|
|
49
|
-
params: { namespace, slug }
|
|
50
|
-
};
|
|
38
|
+
return this.callMcpTool('getDoc', { namespace, slug });
|
|
51
39
|
}
|
|
52
40
|
|
|
53
41
|
async createDoc(namespace, docData) {
|
|
54
|
-
return {
|
|
55
|
-
mcpServer: this.mcpServer,
|
|
56
|
-
tool: this.resolveTool('createDoc'),
|
|
57
|
-
params: { namespace, ...docData }
|
|
58
|
-
};
|
|
42
|
+
return this.callMcpTool('createDoc', { namespace, ...docData });
|
|
59
43
|
}
|
|
60
44
|
|
|
61
45
|
async updateDoc(namespace, slug, docData) {
|
|
62
|
-
return {
|
|
63
|
-
mcpServer: this.mcpServer,
|
|
64
|
-
tool: this.resolveTool('updateDoc'),
|
|
65
|
-
params: { namespace, slug, ...docData }
|
|
66
|
-
};
|
|
46
|
+
return this.callMcpTool('updateDoc', { namespace, slug, ...docData });
|
|
67
47
|
}
|
|
68
48
|
|
|
69
49
|
async search(query, type = 'doc') {
|
|
70
|
-
return {
|
|
71
|
-
mcpServer: this.mcpServer,
|
|
72
|
-
tool: this.resolveTool('search'),
|
|
73
|
-
params: { q: query, type }
|
|
74
|
-
};
|
|
50
|
+
return this.callMcpTool('search', { q: query, type });
|
|
75
51
|
}
|
|
76
52
|
|
|
77
53
|
/**
|
|
@@ -79,11 +55,7 @@ class YuqueAdapter extends KnowledgeBaseAdapter {
|
|
|
79
55
|
* @returns {Promise<object>}
|
|
80
56
|
*/
|
|
81
57
|
async getCurrentUser() {
|
|
82
|
-
return {
|
|
83
|
-
mcpServer: this.mcpServer,
|
|
84
|
-
tool: this.resolveTool('getCurrentUser'),
|
|
85
|
-
params: {}
|
|
86
|
-
};
|
|
58
|
+
return this.callMcpTool('getCurrentUser', {});
|
|
87
59
|
}
|
|
88
60
|
}
|
|
89
61
|
|