powr-sdk-api 3.2.2 → 4.0.0
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/dist/index.js +3 -1
- package/dist/routes/feeds.js +1 -1
- package/dist/routes/index.js +11 -1
- package/dist/routes/tools.js +377 -0
- package/dist/services/tools.js +364 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,7 +15,8 @@ const {
|
|
|
15
15
|
} = require("./swagger");
|
|
16
16
|
const {
|
|
17
17
|
createPowrRoutes,
|
|
18
|
-
initializeFunctions
|
|
18
|
+
initializeFunctions,
|
|
19
|
+
initializeTools
|
|
19
20
|
} = require("./routes");
|
|
20
21
|
const {
|
|
21
22
|
verifyToken
|
|
@@ -28,5 +29,6 @@ module.exports = {
|
|
|
28
29
|
notFoundHandler,
|
|
29
30
|
createPowrRoutes,
|
|
30
31
|
initializeFunctions,
|
|
32
|
+
initializeTools,
|
|
31
33
|
verifyToken
|
|
32
34
|
};
|
package/dist/routes/feeds.js
CHANGED
package/dist/routes/index.js
CHANGED
|
@@ -8,6 +8,7 @@ const {
|
|
|
8
8
|
verifyToken
|
|
9
9
|
} = require('../middleware/jwtToken');
|
|
10
10
|
const functionsManager = require('../services/functions');
|
|
11
|
+
const toolsManager = require('../services/tools');
|
|
11
12
|
|
|
12
13
|
// Import all route modules
|
|
13
14
|
const commentsRoutes = require('./comments');
|
|
@@ -26,6 +27,7 @@ const notificationsRoutes = require('./notifications');
|
|
|
26
27
|
const profilesRoutes = require('./profiles');
|
|
27
28
|
const chatRoutes = require('./chat');
|
|
28
29
|
const feedsRoutes = require('./feeds');
|
|
30
|
+
const toolsRoutes = require('./tools');
|
|
29
31
|
|
|
30
32
|
// Synchronous router creation
|
|
31
33
|
const createPowrRoutes = (options = {}) => {
|
|
@@ -49,6 +51,7 @@ const createPowrRoutes = (options = {}) => {
|
|
|
49
51
|
router.use('/profiles', verifyToken, profilesRoutes);
|
|
50
52
|
router.use('/chat', verifyToken, chatRoutes);
|
|
51
53
|
router.use('/feeds', verifyToken, feedsRoutes);
|
|
54
|
+
router.use('/tools', toolsRoutes);
|
|
52
55
|
return router;
|
|
53
56
|
};
|
|
54
57
|
|
|
@@ -57,7 +60,14 @@ const initializeFunctions = async (options = {}) => {
|
|
|
57
60
|
// Initialize Functions manager with options
|
|
58
61
|
await functionsManager.initialize(options);
|
|
59
62
|
};
|
|
63
|
+
|
|
64
|
+
// Async Tools initialization function
|
|
65
|
+
const initializeTools = async (options = {}) => {
|
|
66
|
+
// Initialize Tools manager with options
|
|
67
|
+
await toolsManager.initialize(options);
|
|
68
|
+
};
|
|
60
69
|
module.exports = {
|
|
61
70
|
createPowrRoutes,
|
|
62
|
-
initializeFunctions
|
|
71
|
+
initializeFunctions,
|
|
72
|
+
initializeTools
|
|
63
73
|
};
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const express = require("express");
|
|
4
|
+
const router = express.Router();
|
|
5
|
+
const toolsManager = require("../services/tools");
|
|
6
|
+
const {
|
|
7
|
+
getDb
|
|
8
|
+
} = require("../services/mongo");
|
|
9
|
+
|
|
10
|
+
// Get Tools status
|
|
11
|
+
router.get("/status", async (req, res) => {
|
|
12
|
+
try {
|
|
13
|
+
const stats = toolsManager.getStats();
|
|
14
|
+
return res.status(200).json({
|
|
15
|
+
success: true,
|
|
16
|
+
data: {
|
|
17
|
+
...stats,
|
|
18
|
+
message: stats.isEnabled ? "Tools is running" : "Tools is disabled"
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
} catch (err) {
|
|
22
|
+
console.error("Error getting Tools status:", err);
|
|
23
|
+
return res.status(500).json({
|
|
24
|
+
success: false,
|
|
25
|
+
message: "Error getting Tools status"
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Enable Tools
|
|
31
|
+
router.post("/enable", async (req, res) => {
|
|
32
|
+
try {
|
|
33
|
+
toolsManager.enable();
|
|
34
|
+
return res.status(200).json({
|
|
35
|
+
success: true,
|
|
36
|
+
message: "Tools enabled successfully",
|
|
37
|
+
data: toolsManager.getStats()
|
|
38
|
+
});
|
|
39
|
+
} catch (err) {
|
|
40
|
+
console.error("Error enabling Tools:", err);
|
|
41
|
+
return res.status(500).json({
|
|
42
|
+
success: false,
|
|
43
|
+
message: "Error enabling Tools"
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Disable Tools
|
|
49
|
+
router.post("/disable", async (req, res) => {
|
|
50
|
+
try {
|
|
51
|
+
toolsManager.disable();
|
|
52
|
+
return res.status(200).json({
|
|
53
|
+
success: true,
|
|
54
|
+
message: "Tools disabled successfully",
|
|
55
|
+
data: toolsManager.getStats()
|
|
56
|
+
});
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.error("Error disabling Tools:", err);
|
|
59
|
+
return res.status(500).json({
|
|
60
|
+
success: false,
|
|
61
|
+
message: "Error disabling Tools"
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Toggle Tools
|
|
67
|
+
router.post("/toggle", async (req, res) => {
|
|
68
|
+
try {
|
|
69
|
+
const isEnabled = toolsManager.toggle();
|
|
70
|
+
return res.status(200).json({
|
|
71
|
+
success: true,
|
|
72
|
+
message: isEnabled ? "Tools enabled" : "Tools disabled",
|
|
73
|
+
data: toolsManager.getStats()
|
|
74
|
+
});
|
|
75
|
+
} catch (err) {
|
|
76
|
+
console.error("Error toggling Tools:", err);
|
|
77
|
+
return res.status(500).json({
|
|
78
|
+
success: false,
|
|
79
|
+
message: "Error toggling Tools"
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Get all available tools
|
|
85
|
+
router.get('/', async (req, res) => {
|
|
86
|
+
try {
|
|
87
|
+
const tools = toolsManager.getAllTools();
|
|
88
|
+
return res.status(200).json({
|
|
89
|
+
success: true,
|
|
90
|
+
data: tools,
|
|
91
|
+
total: tools.length
|
|
92
|
+
});
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error("Error retrieving tools:", error);
|
|
95
|
+
return res.status(500).json({
|
|
96
|
+
success: false,
|
|
97
|
+
message: "Failed to retrieve tools."
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Get tool by ID
|
|
103
|
+
router.get('/:toolId', async (req, res) => {
|
|
104
|
+
try {
|
|
105
|
+
const {
|
|
106
|
+
toolId
|
|
107
|
+
} = req.params;
|
|
108
|
+
const tool = toolsManager.getTool(toolId);
|
|
109
|
+
if (!tool) {
|
|
110
|
+
return res.status(404).json({
|
|
111
|
+
success: false,
|
|
112
|
+
message: "Tool not found"
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return res.status(200).json({
|
|
116
|
+
success: true,
|
|
117
|
+
data: tool
|
|
118
|
+
});
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error("Error retrieving tool:", error);
|
|
121
|
+
return res.status(500).json({
|
|
122
|
+
success: false,
|
|
123
|
+
message: "Failed to retrieve tool."
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Get tools by category
|
|
129
|
+
router.get('/category/:category', async (req, res) => {
|
|
130
|
+
try {
|
|
131
|
+
const {
|
|
132
|
+
category
|
|
133
|
+
} = req.params;
|
|
134
|
+
const tools = toolsManager.getToolsByCategory(category);
|
|
135
|
+
return res.status(200).json({
|
|
136
|
+
success: true,
|
|
137
|
+
data: tools,
|
|
138
|
+
category,
|
|
139
|
+
total: tools.length
|
|
140
|
+
});
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error("Error retrieving tools by category:", error);
|
|
143
|
+
return res.status(500).json({
|
|
144
|
+
success: false,
|
|
145
|
+
message: "Failed to retrieve tools by category."
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Configure tool for user
|
|
151
|
+
router.post('/:toolId/configure', async (req, res) => {
|
|
152
|
+
try {
|
|
153
|
+
var _req$user;
|
|
154
|
+
const {
|
|
155
|
+
toolId
|
|
156
|
+
} = req.params;
|
|
157
|
+
const {
|
|
158
|
+
config
|
|
159
|
+
} = req.body;
|
|
160
|
+
const userId = (_req$user = req.user) === null || _req$user === void 0 ? void 0 : _req$user.id; // From JWT token
|
|
161
|
+
|
|
162
|
+
if (!userId) {
|
|
163
|
+
return res.status(401).json({
|
|
164
|
+
success: false,
|
|
165
|
+
message: "User not authenticated"
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (!config) {
|
|
169
|
+
return res.status(400).json({
|
|
170
|
+
success: false,
|
|
171
|
+
message: "Configuration is required"
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const result = await toolsManager.configureTool(userId, toolId, config);
|
|
175
|
+
if (result.success) {
|
|
176
|
+
return res.status(200).json(result);
|
|
177
|
+
} else {
|
|
178
|
+
return res.status(400).json(result);
|
|
179
|
+
}
|
|
180
|
+
} catch (error) {
|
|
181
|
+
console.error("Error configuring tool:", error);
|
|
182
|
+
return res.status(500).json({
|
|
183
|
+
success: false,
|
|
184
|
+
message: "Failed to configure tool."
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// Execute tool action
|
|
190
|
+
router.post('/:toolId/execute', async (req, res) => {
|
|
191
|
+
try {
|
|
192
|
+
var _req$user2;
|
|
193
|
+
const {
|
|
194
|
+
toolId
|
|
195
|
+
} = req.params;
|
|
196
|
+
const {
|
|
197
|
+
actionId,
|
|
198
|
+
params
|
|
199
|
+
} = req.body;
|
|
200
|
+
const userId = (_req$user2 = req.user) === null || _req$user2 === void 0 ? void 0 : _req$user2.id; // From JWT token
|
|
201
|
+
|
|
202
|
+
if (!userId) {
|
|
203
|
+
return res.status(401).json({
|
|
204
|
+
success: false,
|
|
205
|
+
message: "User not authenticated"
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
if (!actionId) {
|
|
209
|
+
return res.status(400).json({
|
|
210
|
+
success: false,
|
|
211
|
+
message: "Action ID is required"
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
const result = await toolsManager.executeToolAction(userId, toolId, actionId, params || {});
|
|
215
|
+
if (result.success) {
|
|
216
|
+
return res.status(200).json(result);
|
|
217
|
+
} else {
|
|
218
|
+
return res.status(400).json(result);
|
|
219
|
+
}
|
|
220
|
+
} catch (error) {
|
|
221
|
+
console.error("Error executing tool action:", error);
|
|
222
|
+
return res.status(500).json({
|
|
223
|
+
success: false,
|
|
224
|
+
message: "Failed to execute tool action."
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Test tool connection
|
|
230
|
+
router.post('/:toolId/test', async (req, res) => {
|
|
231
|
+
try {
|
|
232
|
+
var _req$user3;
|
|
233
|
+
const {
|
|
234
|
+
toolId
|
|
235
|
+
} = req.params;
|
|
236
|
+
const userId = (_req$user3 = req.user) === null || _req$user3 === void 0 ? void 0 : _req$user3.id; // From JWT token
|
|
237
|
+
|
|
238
|
+
if (!userId) {
|
|
239
|
+
return res.status(401).json({
|
|
240
|
+
success: false,
|
|
241
|
+
message: "User not authenticated"
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
const result = await toolsManager.testToolConnection(userId, toolId);
|
|
245
|
+
if (result.success) {
|
|
246
|
+
return res.status(200).json(result);
|
|
247
|
+
} else {
|
|
248
|
+
return res.status(400).json(result);
|
|
249
|
+
}
|
|
250
|
+
} catch (error) {
|
|
251
|
+
console.error("Error testing tool connection:", error);
|
|
252
|
+
return res.status(500).json({
|
|
253
|
+
success: false,
|
|
254
|
+
message: "Failed to test tool connection."
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Get user's configured tools
|
|
260
|
+
router.get('/user/configured', async (req, res) => {
|
|
261
|
+
try {
|
|
262
|
+
var _req$user4;
|
|
263
|
+
const userId = (_req$user4 = req.user) === null || _req$user4 === void 0 ? void 0 : _req$user4.id; // From JWT token
|
|
264
|
+
|
|
265
|
+
if (!userId) {
|
|
266
|
+
return res.status(401).json({
|
|
267
|
+
success: false,
|
|
268
|
+
message: "User not authenticated"
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
const userTools = await toolsManager.getUserTools(userId);
|
|
272
|
+
|
|
273
|
+
// Enrich with tool details
|
|
274
|
+
const enrichedUserTools = userTools.map(userTool => {
|
|
275
|
+
const tool = toolsManager.getTool(userTool.toolId);
|
|
276
|
+
return {
|
|
277
|
+
...userTool,
|
|
278
|
+
tool: tool ? {
|
|
279
|
+
id: tool.id,
|
|
280
|
+
name: tool.name,
|
|
281
|
+
description: tool.description,
|
|
282
|
+
category: tool.category,
|
|
283
|
+
icon: tool.icon,
|
|
284
|
+
version: tool.version,
|
|
285
|
+
actions: tool.actions
|
|
286
|
+
} : null
|
|
287
|
+
};
|
|
288
|
+
});
|
|
289
|
+
return res.status(200).json({
|
|
290
|
+
success: true,
|
|
291
|
+
data: enrichedUserTools,
|
|
292
|
+
total: enrichedUserTools.length
|
|
293
|
+
});
|
|
294
|
+
} catch (error) {
|
|
295
|
+
console.error("Error retrieving user tools:", error);
|
|
296
|
+
return res.status(500).json({
|
|
297
|
+
success: false,
|
|
298
|
+
message: "Failed to retrieve user tools."
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
// Toggle tool for user
|
|
304
|
+
router.post('/user/:toolId/toggle', async (req, res) => {
|
|
305
|
+
try {
|
|
306
|
+
var _req$user5;
|
|
307
|
+
const {
|
|
308
|
+
toolId
|
|
309
|
+
} = req.params;
|
|
310
|
+
const {
|
|
311
|
+
enabled
|
|
312
|
+
} = req.body;
|
|
313
|
+
const userId = (_req$user5 = req.user) === null || _req$user5 === void 0 ? void 0 : _req$user5.id; // From JWT token
|
|
314
|
+
|
|
315
|
+
if (!userId) {
|
|
316
|
+
return res.status(401).json({
|
|
317
|
+
success: false,
|
|
318
|
+
message: "User not authenticated"
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
if (typeof enabled !== 'boolean') {
|
|
322
|
+
return res.status(400).json({
|
|
323
|
+
success: false,
|
|
324
|
+
message: "Enabled must be a boolean"
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
const result = await toolsManager.toggleTool(userId, toolId, enabled);
|
|
328
|
+
if (result.success) {
|
|
329
|
+
return res.status(200).json(result);
|
|
330
|
+
} else {
|
|
331
|
+
return res.status(400).json(result);
|
|
332
|
+
}
|
|
333
|
+
} catch (error) {
|
|
334
|
+
console.error("Error toggling user tool:", error);
|
|
335
|
+
return res.status(500).json({
|
|
336
|
+
success: false,
|
|
337
|
+
message: "Failed to toggle user tool."
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// Get tool execution history
|
|
343
|
+
router.get('/user/:toolId/history', async (req, res) => {
|
|
344
|
+
try {
|
|
345
|
+
var _req$user6;
|
|
346
|
+
const {
|
|
347
|
+
toolId
|
|
348
|
+
} = req.params;
|
|
349
|
+
const userId = (_req$user6 = req.user) === null || _req$user6 === void 0 ? void 0 : _req$user6.id; // From JWT token
|
|
350
|
+
|
|
351
|
+
if (!userId) {
|
|
352
|
+
return res.status(401).json({
|
|
353
|
+
success: false,
|
|
354
|
+
message: "User not authenticated"
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
const db = await getDb();
|
|
358
|
+
const executions = await db.collection("tool_executions").find({
|
|
359
|
+
userId,
|
|
360
|
+
toolId
|
|
361
|
+
}).sort({
|
|
362
|
+
timestamp: -1
|
|
363
|
+
}).limit(50).toArray();
|
|
364
|
+
return res.status(200).json({
|
|
365
|
+
success: true,
|
|
366
|
+
data: executions,
|
|
367
|
+
total: executions.length
|
|
368
|
+
});
|
|
369
|
+
} catch (error) {
|
|
370
|
+
console.error("Error retrieving tool execution history:", error);
|
|
371
|
+
return res.status(500).json({
|
|
372
|
+
success: false,
|
|
373
|
+
message: "Failed to retrieve tool execution history."
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
module.exports = router;
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
getDb
|
|
5
|
+
} = require("./mongo");
|
|
6
|
+
const crypto = require('crypto');
|
|
7
|
+
const config = require('../config');
|
|
8
|
+
class ToolsManager {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.registeredTools = new Map();
|
|
11
|
+
this.isInitialized = false;
|
|
12
|
+
this.isCentralService = false;
|
|
13
|
+
this.isEnabled = false; // Default disabled
|
|
14
|
+
}
|
|
15
|
+
async initialize(options = {}) {
|
|
16
|
+
this.isCentralService = options.isCentralService || false;
|
|
17
|
+
this.isEnabled = options.enableTools === true; // Default false unless explicitly enabled
|
|
18
|
+
|
|
19
|
+
if (!this.isEnabled) {
|
|
20
|
+
console.log("🚫 Tools is disabled");
|
|
21
|
+
this.isInitialized = true;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (this.isCentralService) {
|
|
25
|
+
// Central service: Don't pre-load, load dynamically
|
|
26
|
+
console.log("🔄 Central service mode - loading tools dynamically");
|
|
27
|
+
this.isInitialized = true;
|
|
28
|
+
} else {
|
|
29
|
+
// Individual API: Load all available tools
|
|
30
|
+
console.log("📦 Loading tools registry...");
|
|
31
|
+
try {
|
|
32
|
+
const db = await getDb();
|
|
33
|
+
const tools = await db.collection("tools").find({}).toArray();
|
|
34
|
+
tools.forEach(tool => {
|
|
35
|
+
this.registerTool(tool);
|
|
36
|
+
});
|
|
37
|
+
this.isInitialized = true;
|
|
38
|
+
console.log(`✅ Loaded ${tools.length} tools from registry`);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error("❌ Failed to initialize tools:", error);
|
|
41
|
+
this.isInitialized = true; // Still mark as initialized to prevent blocking
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Register a new tool
|
|
47
|
+
registerTool(tool) {
|
|
48
|
+
var _tool$_id;
|
|
49
|
+
const toolId = tool.id || ((_tool$_id = tool._id) === null || _tool$_id === void 0 ? void 0 : _tool$_id.toString());
|
|
50
|
+
if (!toolId) {
|
|
51
|
+
console.error("❌ Tool must have an ID");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this.registeredTools.set(toolId, {
|
|
55
|
+
...tool,
|
|
56
|
+
registeredAt: new Date(),
|
|
57
|
+
isActive: true
|
|
58
|
+
});
|
|
59
|
+
console.log(`✅ Registered tool: ${tool.name} (${toolId})`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Get all available tools
|
|
63
|
+
getAllTools() {
|
|
64
|
+
return Array.from(this.registeredTools.values()).filter(tool => tool.isActive);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Get tool by ID
|
|
68
|
+
getTool(toolId) {
|
|
69
|
+
return this.registeredTools.get(toolId);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Get tools by category
|
|
73
|
+
getToolsByCategory(category) {
|
|
74
|
+
return this.getAllTools().filter(tool => tool.category === category);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Get user's configured tools
|
|
78
|
+
async getUserTools(userId) {
|
|
79
|
+
if (!this.isEnabled) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
const db = await getDb();
|
|
84
|
+
const userTools = await db.collection("user_tools").find({
|
|
85
|
+
userId
|
|
86
|
+
}).toArray();
|
|
87
|
+
return userTools;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error("❌ Failed to get user tools:", error);
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Configure tool for user
|
|
95
|
+
async configureTool(userId, toolId, config) {
|
|
96
|
+
if (!this.isEnabled) {
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
message: "Tools is disabled"
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const db = await getDb();
|
|
104
|
+
const tool = this.getTool(toolId);
|
|
105
|
+
if (!tool) {
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
message: "Tool not found"
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Validate configuration against tool schema
|
|
113
|
+
if (!this.validateToolConfig(tool, config)) {
|
|
114
|
+
return {
|
|
115
|
+
success: false,
|
|
116
|
+
message: "Invalid configuration"
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Encrypt sensitive data
|
|
121
|
+
const encryptedConfig = this.encryptConfig(config);
|
|
122
|
+
const userTool = {
|
|
123
|
+
userId,
|
|
124
|
+
toolId,
|
|
125
|
+
config: encryptedConfig,
|
|
126
|
+
enabled: true,
|
|
127
|
+
createdAt: new Date(),
|
|
128
|
+
updatedAt: new Date()
|
|
129
|
+
};
|
|
130
|
+
await db.collection("user_tools").updateOne({
|
|
131
|
+
userId,
|
|
132
|
+
toolId
|
|
133
|
+
}, {
|
|
134
|
+
$set: userTool
|
|
135
|
+
}, {
|
|
136
|
+
upsert: true
|
|
137
|
+
});
|
|
138
|
+
console.log(`✅ Configured tool ${toolId} for user ${userId}`);
|
|
139
|
+
return {
|
|
140
|
+
success: true,
|
|
141
|
+
message: "Tool configured successfully"
|
|
142
|
+
};
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.error("❌ Failed to configure tool:", error);
|
|
145
|
+
return {
|
|
146
|
+
success: false,
|
|
147
|
+
message: "Failed to configure tool"
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Execute tool action
|
|
153
|
+
async executeToolAction(userId, toolId, actionId, params) {
|
|
154
|
+
if (!this.isEnabled) {
|
|
155
|
+
return {
|
|
156
|
+
success: false,
|
|
157
|
+
message: "Tools is disabled"
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
const tool = this.getTool(toolId);
|
|
162
|
+
if (!tool) {
|
|
163
|
+
return {
|
|
164
|
+
success: false,
|
|
165
|
+
message: "Tool not found"
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Get user's tool configuration
|
|
170
|
+
const db = await getDb();
|
|
171
|
+
const userTool = await db.collection("user_tools").findOne({
|
|
172
|
+
userId,
|
|
173
|
+
toolId
|
|
174
|
+
});
|
|
175
|
+
if (!userTool || !userTool.enabled) {
|
|
176
|
+
return {
|
|
177
|
+
success: false,
|
|
178
|
+
message: "Tool not configured or disabled"
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Decrypt configuration
|
|
183
|
+
const config = this.decryptConfig(userTool.config);
|
|
184
|
+
|
|
185
|
+
// Execute the action
|
|
186
|
+
const result = await this.executeAction(tool, actionId, params, config);
|
|
187
|
+
|
|
188
|
+
// Log execution
|
|
189
|
+
await this.logToolExecution(userId, toolId, actionId, params, result);
|
|
190
|
+
return result;
|
|
191
|
+
} catch (error) {
|
|
192
|
+
console.error("❌ Failed to execute tool action:", error);
|
|
193
|
+
return {
|
|
194
|
+
success: false,
|
|
195
|
+
message: "Failed to execute tool action"
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Test tool connection
|
|
201
|
+
async testToolConnection(userId, toolId) {
|
|
202
|
+
if (!this.isEnabled) {
|
|
203
|
+
return {
|
|
204
|
+
success: false,
|
|
205
|
+
message: "Tools is disabled"
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
try {
|
|
209
|
+
const tool = this.getTool(toolId);
|
|
210
|
+
if (!tool) {
|
|
211
|
+
return {
|
|
212
|
+
success: false,
|
|
213
|
+
message: "Tool not found"
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Get user's tool configuration
|
|
218
|
+
const db = await getDb();
|
|
219
|
+
const userTool = await db.collection("user_tools").findOne({
|
|
220
|
+
userId,
|
|
221
|
+
toolId
|
|
222
|
+
});
|
|
223
|
+
if (!userTool) {
|
|
224
|
+
return {
|
|
225
|
+
success: false,
|
|
226
|
+
message: "Tool not configured"
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Decrypt configuration
|
|
231
|
+
const config = this.decryptConfig(userTool.config);
|
|
232
|
+
|
|
233
|
+
// Test connection
|
|
234
|
+
const result = await this.testConnection(tool, config);
|
|
235
|
+
return result;
|
|
236
|
+
} catch (error) {
|
|
237
|
+
console.error("❌ Failed to test tool connection:", error);
|
|
238
|
+
return {
|
|
239
|
+
success: false,
|
|
240
|
+
message: "Failed to test tool connection"
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Toggle tool for user
|
|
246
|
+
async toggleTool(userId, toolId, enabled) {
|
|
247
|
+
if (!this.isEnabled) {
|
|
248
|
+
return {
|
|
249
|
+
success: false,
|
|
250
|
+
message: "Tools is disabled"
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
const db = await getDb();
|
|
255
|
+
await db.collection("user_tools").updateOne({
|
|
256
|
+
userId,
|
|
257
|
+
toolId
|
|
258
|
+
}, {
|
|
259
|
+
$set: {
|
|
260
|
+
enabled,
|
|
261
|
+
updatedAt: new Date()
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
console.log(`${enabled ? '✅' : '❌'} Tool ${toolId} ${enabled ? 'enabled' : 'disabled'} for user ${userId}`);
|
|
265
|
+
return {
|
|
266
|
+
success: true,
|
|
267
|
+
message: `Tool ${enabled ? 'enabled' : 'disabled'} successfully`
|
|
268
|
+
};
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.error("❌ Failed to toggle tool:", error);
|
|
271
|
+
return {
|
|
272
|
+
success: false,
|
|
273
|
+
message: "Failed to toggle tool"
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Helper methods
|
|
279
|
+
validateToolConfig(tool, config) {
|
|
280
|
+
// Basic validation - can be extended based on tool schema
|
|
281
|
+
if (!tool.configSchema) return true;
|
|
282
|
+
|
|
283
|
+
// Validate required fields
|
|
284
|
+
for (const [field, schema] of Object.entries(tool.configSchema)) {
|
|
285
|
+
if (schema.required && !config[field]) {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
encryptConfig(config) {
|
|
292
|
+
// Simple encryption - in production, use proper encryption
|
|
293
|
+
return Buffer.from(JSON.stringify(config)).toString('base64');
|
|
294
|
+
}
|
|
295
|
+
decryptConfig(encryptedConfig) {
|
|
296
|
+
// Simple decryption - in production, use proper decryption
|
|
297
|
+
return JSON.parse(Buffer.from(encryptedConfig, 'base64').toString());
|
|
298
|
+
}
|
|
299
|
+
async executeAction(tool, actionId, params, config) {
|
|
300
|
+
// This would be implemented based on the tool type
|
|
301
|
+
// For now, return a mock response
|
|
302
|
+
return {
|
|
303
|
+
success: true,
|
|
304
|
+
message: `Executed ${actionId} on ${tool.name}`,
|
|
305
|
+
data: {
|
|
306
|
+
toolId: tool.id,
|
|
307
|
+
actionId,
|
|
308
|
+
params
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
async testConnection(tool, config) {
|
|
313
|
+
// This would test the actual connection based on tool type
|
|
314
|
+
// For now, return a mock response
|
|
315
|
+
return {
|
|
316
|
+
success: true,
|
|
317
|
+
message: `Connection to ${tool.name} successful`
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
async logToolExecution(userId, toolId, actionId, params, result) {
|
|
321
|
+
try {
|
|
322
|
+
const db = await getDb();
|
|
323
|
+
await db.collection("tool_executions").insertOne({
|
|
324
|
+
userId,
|
|
325
|
+
toolId,
|
|
326
|
+
actionId,
|
|
327
|
+
params,
|
|
328
|
+
result,
|
|
329
|
+
timestamp: new Date()
|
|
330
|
+
});
|
|
331
|
+
} catch (error) {
|
|
332
|
+
console.error("❌ Failed to log tool execution:", error);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Get statistics
|
|
337
|
+
getStats() {
|
|
338
|
+
return {
|
|
339
|
+
isEnabled: this.isEnabled,
|
|
340
|
+
isInitialized: this.isInitialized,
|
|
341
|
+
totalTools: this.registeredTools.size,
|
|
342
|
+
activeTools: this.getAllTools().length
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Enable/disable tools
|
|
347
|
+
enable() {
|
|
348
|
+
this.isEnabled = true;
|
|
349
|
+
console.log("✅ Tools enabled");
|
|
350
|
+
}
|
|
351
|
+
disable() {
|
|
352
|
+
this.isEnabled = false;
|
|
353
|
+
console.log("❌ Tools disabled");
|
|
354
|
+
}
|
|
355
|
+
toggle() {
|
|
356
|
+
this.isEnabled = !this.isEnabled;
|
|
357
|
+
console.log(`${this.isEnabled ? '✅' : '❌'} Tools ${this.isEnabled ? 'enabled' : 'disabled'}`);
|
|
358
|
+
return this.isEnabled;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Create and export singleton instance
|
|
363
|
+
const toolsManager = new ToolsManager();
|
|
364
|
+
module.exports = toolsManager;
|