@ebowwa/glm-daemon 0.3.2 → 0.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebowwa/glm-daemon",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "Autonomous GLM 4.7 daemon with hooks, tools, teammates, and communication channels (Telegram, Discord)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -57,11 +57,11 @@
57
57
  "status": "bun run dist/bin/manager.js status"
58
58
  },
59
59
  "dependencies": {
60
- "@ebowwa/ai": "^0.1.0",
60
+ "@ebowwa/ai": "^0.1.2",
61
61
  "@ebowwa/channel-types": "^0.1.1",
62
- "@ebowwa/codespaces-types": "^1.3.0",
63
- "@ebowwa/structured-prompts": "^0.2.9",
64
- "@ebowwa/teammates": "^0.1.0",
62
+ "@ebowwa/codespaces-types": "^1.4.0",
63
+ "@ebowwa/structured-prompts": "^0.3.2",
64
+ "@ebowwa/teammates": "^0.1.2",
65
65
  "discord.js": "^14.16.3",
66
66
  "node-telegram-bot-api": "^0.66.0",
67
67
  "zod": "^4.3.5"
package/src/agent.js ADDED
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ /**
3
+ * GLM Agent - Individual GLM-powered agent
4
+ *
5
+ * Wraps GLM 4.7 API with tool access and hook integration.
6
+ */
7
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
9
+ return new (P || (P = Promise))(function (resolve, reject) {
10
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
11
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
12
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
14
+ });
15
+ };
16
+ var __generator = (this && this.__generator) || function (thisArg, body) {
17
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
18
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
19
+ function verb(n) { return function (v) { return step([n, v]); }; }
20
+ function step(op) {
21
+ if (f) throw new TypeError("Generator is already executing.");
22
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
23
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
24
+ if (y = 0, t) op = [op[0] & 2, t.value];
25
+ switch (op[0]) {
26
+ case 0: case 1: t = op; break;
27
+ case 4: _.label++; return { value: op[1], done: false };
28
+ case 5: _.label++; y = op[1]; op = [0]; continue;
29
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
30
+ default:
31
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
32
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
33
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
34
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
35
+ if (t[2]) _.ops.pop();
36
+ _.trys.pop(); continue;
37
+ }
38
+ op = body.call(thisArg, _);
39
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
40
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
41
+ }
42
+ };
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.GLMAgent = void 0;
45
+ var client_1 = require("@ebowwa/ai/client");
46
+ var GLMAgent = /** @class */ (function () {
47
+ function GLMAgent(config) {
48
+ this.tools = new Map();
49
+ this.config = config;
50
+ this.client = new client_1.GLMClient();
51
+ }
52
+ /**
53
+ * Execute a prompt and get response
54
+ */
55
+ GLMAgent.prototype.execute = function (prompt, tools) {
56
+ return __awaiter(this, void 0, void 0, function () {
57
+ var messages, response;
58
+ var _a, _b;
59
+ return __generator(this, function (_c) {
60
+ switch (_c.label) {
61
+ case 0:
62
+ messages = [
63
+ {
64
+ role: "system",
65
+ content: this.config.prompt,
66
+ },
67
+ {
68
+ role: "user",
69
+ content: prompt,
70
+ },
71
+ ];
72
+ // Add tool context if provided
73
+ if (tools) {
74
+ messages.push({
75
+ role: "user",
76
+ content: "\nAvailable tools: ".concat(Object.keys(tools).join(", ")),
77
+ });
78
+ }
79
+ return [4 /*yield*/, this.client.chatCompletion(messages, {
80
+ model: this.config.model || "glm-4.7",
81
+ temperature: this.config.temperature || 0.7,
82
+ maxTokens: this.config.maxTokens || 4096,
83
+ })];
84
+ case 1:
85
+ response = _c.sent();
86
+ return [2 /*return*/, ((_b = (_a = response.choices[0]) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b.content) || ""];
87
+ }
88
+ });
89
+ });
90
+ };
91
+ /**
92
+ * Execute a tool call
93
+ */
94
+ GLMAgent.prototype.executeTool = function (toolName, args) {
95
+ return __awaiter(this, void 0, void 0, function () {
96
+ var start, tool, result, error_1;
97
+ return __generator(this, function (_a) {
98
+ switch (_a.label) {
99
+ case 0:
100
+ start = Date.now();
101
+ tool = this.tools.get(toolName);
102
+ if (!tool) {
103
+ return [2 /*return*/, {
104
+ success: false,
105
+ error: "Tool not found: ".concat(toolName),
106
+ duration: Date.now() - start,
107
+ }];
108
+ }
109
+ _a.label = 1;
110
+ case 1:
111
+ _a.trys.push([1, 3, , 4]);
112
+ return [4 /*yield*/, tool(args)];
113
+ case 2:
114
+ result = _a.sent();
115
+ return [2 /*return*/, {
116
+ success: true,
117
+ result: result,
118
+ duration: Date.now() - start,
119
+ }];
120
+ case 3:
121
+ error_1 = _a.sent();
122
+ return [2 /*return*/, {
123
+ success: false,
124
+ error: error_1 instanceof Error ? error_1.message : String(error_1),
125
+ duration: Date.now() - start,
126
+ }];
127
+ case 4: return [2 /*return*/];
128
+ }
129
+ });
130
+ });
131
+ };
132
+ /**
133
+ * Register a tool
134
+ */
135
+ GLMAgent.prototype.registerTool = function (name, handler) {
136
+ this.tools.set(name, handler);
137
+ };
138
+ /**
139
+ * Get available tools
140
+ */
141
+ GLMAgent.prototype.getAvailableTools = function () {
142
+ return Array.from(this.tools.keys());
143
+ };
144
+ Object.defineProperty(GLMAgent.prototype, "agentId", {
145
+ /**
146
+ * Get agent ID
147
+ */
148
+ get: function () {
149
+ return this.config.agentId;
150
+ },
151
+ enumerable: false,
152
+ configurable: true
153
+ });
154
+ Object.defineProperty(GLMAgent.prototype, "name", {
155
+ /**
156
+ * Get agent name
157
+ */
158
+ get: function () {
159
+ return this.config.name;
160
+ },
161
+ enumerable: false,
162
+ configurable: true
163
+ });
164
+ return GLMAgent;
165
+ }());
166
+ exports.GLMAgent = GLMAgent;
@@ -0,0 +1,349 @@
1
+ "use strict";
2
+ /**
3
+ * GLM Daemon - Built-in Tools
4
+ *
5
+ * Filesystem, shell, git, and system tools for GLM agents.
6
+ * These tools are available to all GLM daemon instances.
7
+ */
8
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
+ return new (P || (P = Promise))(function (resolve, reject) {
11
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15
+ });
16
+ };
17
+ var __generator = (this && this.__generator) || function (thisArg, body) {
18
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
19
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
20
+ function verb(n) { return function (v) { return step([n, v]); }; }
21
+ function step(op) {
22
+ if (f) throw new TypeError("Generator is already executing.");
23
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
24
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
25
+ if (y = 0, t) op = [op[0] & 2, t.value];
26
+ switch (op[0]) {
27
+ case 0: case 1: t = op; break;
28
+ case 4: _.label++; return { value: op[1], done: false };
29
+ case 5: _.label++; y = op[1]; op = [0]; continue;
30
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
31
+ default:
32
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
33
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
34
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
35
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
36
+ if (t[2]) _.ops.pop();
37
+ _.trys.pop(); continue;
38
+ }
39
+ op = body.call(thisArg, _);
40
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
41
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
42
+ }
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.BUILTIN_TOOLS = void 0;
46
+ exports.getBuiltinTool = getBuiltinTool;
47
+ exports.getBuiltinToolNames = getBuiltinToolNames;
48
+ exports.toGLMFormat = toGLMFormat;
49
+ exports.executeBuiltinTool = executeBuiltinTool;
50
+ var child_process_1 = require("child_process");
51
+ var fs_1 = require("fs");
52
+ var structured_prompts_1 = require("@ebowwa/structured-prompts");
53
+ /**
54
+ * All built-in tools available to GLM daemon
55
+ */
56
+ exports.BUILTIN_TOOLS = [
57
+ {
58
+ name: 'read_file',
59
+ description: 'Read a file from the filesystem. Use for checking configs, logs, code.',
60
+ parameters: {
61
+ type: 'object',
62
+ properties: {
63
+ path: { type: 'string', description: 'Absolute file path to read' }
64
+ },
65
+ required: ['path']
66
+ },
67
+ handler: function (args) { return __awaiter(void 0, void 0, void 0, function () {
68
+ var path, content;
69
+ return __generator(this, function (_a) {
70
+ path = args.path;
71
+ try {
72
+ if (!(0, fs_1.existsSync)(path))
73
+ return [2 /*return*/, "File not found: ".concat(path)];
74
+ content = (0, fs_1.readFileSync)(path, 'utf-8');
75
+ return [2 /*return*/, content.length > 4000 ? content.slice(0, 4000) + '\n...[truncated]' : content];
76
+ }
77
+ catch (e) {
78
+ return [2 /*return*/, "Error reading file: ".concat(e.message)];
79
+ }
80
+ return [2 /*return*/];
81
+ });
82
+ }); }
83
+ },
84
+ {
85
+ name: 'write_file',
86
+ description: 'Write content to a file. Creates the file if it does not exist, overwrites if it does.',
87
+ parameters: {
88
+ type: 'object',
89
+ properties: {
90
+ path: { type: 'string', description: 'Absolute file path to write' },
91
+ content: { type: 'string', description: 'Content to write to the file' }
92
+ },
93
+ required: ['path', 'content']
94
+ },
95
+ handler: function (args) { return __awaiter(void 0, void 0, void 0, function () {
96
+ var path, content;
97
+ return __generator(this, function (_a) {
98
+ path = args.path;
99
+ content = args.content;
100
+ try {
101
+ (0, fs_1.writeFileSync)(path, content, 'utf-8');
102
+ return [2 /*return*/, "Successfully wrote ".concat(content.length, " bytes to ").concat(path)];
103
+ }
104
+ catch (e) {
105
+ return [2 /*return*/, "Error writing file: ".concat(e.message)];
106
+ }
107
+ return [2 /*return*/];
108
+ });
109
+ }); }
110
+ },
111
+ {
112
+ name: 'edit_file',
113
+ description: 'Edit a file by replacing a specific string with new content.',
114
+ parameters: {
115
+ type: 'object',
116
+ properties: {
117
+ path: { type: 'string', description: 'Absolute file path to edit' },
118
+ old_string: { type: 'string', description: 'The exact text to find and replace' },
119
+ new_string: { type: 'string', description: 'The text to replace it with' }
120
+ },
121
+ required: ['path', 'old_string', 'new_string']
122
+ },
123
+ handler: function (args) { return __awaiter(void 0, void 0, void 0, function () {
124
+ var path, oldStr, newStr, content, newContent;
125
+ return __generator(this, function (_a) {
126
+ path = args.path;
127
+ oldStr = args.old_string;
128
+ newStr = args.new_string;
129
+ try {
130
+ if (!(0, fs_1.existsSync)(path))
131
+ return [2 /*return*/, "File not found: ".concat(path)];
132
+ content = (0, fs_1.readFileSync)(path, 'utf-8');
133
+ if (!content.includes(oldStr)) {
134
+ return [2 /*return*/, "String not found in file. First 500 chars:\n".concat(content.slice(0, 500))];
135
+ }
136
+ newContent = content.replace(oldStr, newStr);
137
+ (0, fs_1.writeFileSync)(path, newContent, 'utf-8');
138
+ return [2 /*return*/, "Successfully edited ".concat(path)];
139
+ }
140
+ catch (e) {
141
+ return [2 /*return*/, "Error editing file: ".concat(e.message)];
142
+ }
143
+ return [2 /*return*/];
144
+ });
145
+ }); }
146
+ },
147
+ {
148
+ name: 'append_file',
149
+ description: 'Append content to the end of a file. Creates the file if it does not exist.',
150
+ parameters: {
151
+ type: 'object',
152
+ properties: {
153
+ path: { type: 'string', description: 'Absolute file path to append to' },
154
+ content: { type: 'string', description: 'Content to append to the file' }
155
+ },
156
+ required: ['path', 'content']
157
+ },
158
+ handler: function (args) { return __awaiter(void 0, void 0, void 0, function () {
159
+ var path, content;
160
+ return __generator(this, function (_a) {
161
+ path = args.path;
162
+ content = args.content;
163
+ try {
164
+ (0, fs_1.appendFileSync)(path, content, 'utf-8');
165
+ return [2 /*return*/, "Successfully appended ".concat(content.length, " bytes to ").concat(path)];
166
+ }
167
+ catch (e) {
168
+ return [2 /*return*/, "Error appending to file: ".concat(e.message)];
169
+ }
170
+ return [2 /*return*/];
171
+ });
172
+ }); }
173
+ },
174
+ {
175
+ name: 'list_dir',
176
+ description: 'List contents of a directory. Shows files and subdirectories.',
177
+ parameters: {
178
+ type: 'object',
179
+ properties: {
180
+ path: { type: 'string', description: 'Directory path to list (default: current working directory)' }
181
+ }
182
+ },
183
+ handler: function (args) { return __awaiter(void 0, void 0, void 0, function () {
184
+ var path, items;
185
+ return __generator(this, function (_a) {
186
+ path = args.path || process.cwd();
187
+ try {
188
+ items = (0, child_process_1.execSync)("ls -la \"".concat(path, "\" 2>&1")).toString();
189
+ return [2 /*return*/, items];
190
+ }
191
+ catch (e) {
192
+ return [2 /*return*/, "Error listing directory: ".concat(e.message)];
193
+ }
194
+ return [2 /*return*/];
195
+ });
196
+ }); }
197
+ },
198
+ {
199
+ name: 'run_command',
200
+ description: 'Execute a shell command. Use for git, system info, etc. BE CAREFUL with destructive commands.',
201
+ parameters: {
202
+ type: 'object',
203
+ properties: {
204
+ command: { type: 'string', description: 'Shell command to execute' },
205
+ cwd: { type: 'string', description: 'Working directory (optional)' }
206
+ },
207
+ required: ['command']
208
+ },
209
+ handler: function (args) { return __awaiter(void 0, void 0, void 0, function () {
210
+ var cmd, cwd, blocked, result;
211
+ var _a;
212
+ return __generator(this, function (_b) {
213
+ cmd = args.command;
214
+ cwd = args.cwd || process.cwd();
215
+ blocked = ['rm -rf', 'mkfs', 'dd if=', '> /dev/', 'chmod 777'];
216
+ if (blocked.some(function (b) { return cmd.includes(b); })) {
217
+ return [2 /*return*/, "Blocked: command contains dangerous pattern"]; // TODO: AI SHOULD REREVIEW ALL AT THIS POINT, YES WE DO WANT AT TIME BUT WE NEED CAUTION AND RESTRAINT AND COMPLETE UNDERSTANDING
218
+ }
219
+ try {
220
+ result = (0, child_process_1.execSync)(cmd, { timeout: 10000, cwd: cwd }).toString();
221
+ return [2 /*return*/, result || '(no output)'];
222
+ }
223
+ catch (e) {
224
+ return [2 /*return*/, ((_a = e.stdout) === null || _a === void 0 ? void 0 : _a.toString()) || e.message];
225
+ }
226
+ return [2 /*return*/];
227
+ });
228
+ }); }
229
+ },
230
+ {
231
+ name: 'git_status',
232
+ description: 'Check git repository status',
233
+ parameters: {
234
+ type: 'object',
235
+ properties: {
236
+ cwd: { type: 'string', description: 'Repository path (optional)' }
237
+ }
238
+ },
239
+ handler: function (args) { return __awaiter(void 0, void 0, void 0, function () {
240
+ var cwd, status_1, branch;
241
+ return __generator(this, function (_a) {
242
+ cwd = args.cwd || process.cwd();
243
+ try {
244
+ status_1 = (0, child_process_1.execSync)('git status 2>&1', { cwd: cwd }).toString();
245
+ branch = (0, child_process_1.execSync)('git branch --show-current 2>&1', { cwd: cwd }).toString();
246
+ return [2 /*return*/, "Branch: ".concat(branch, "\n\n").concat(status_1)];
247
+ }
248
+ catch (e) {
249
+ return [2 /*return*/, "Error: ".concat(e.message)];
250
+ }
251
+ return [2 /*return*/];
252
+ });
253
+ }); }
254
+ },
255
+ {
256
+ name: 'get_prompt',
257
+ description: 'Get a prompt template from the prompt store',
258
+ parameters: {
259
+ type: 'object',
260
+ properties: {
261
+ id: { type: 'string', description: 'Prompt ID to retrieve' }
262
+ },
263
+ required: ['id']
264
+ },
265
+ handler: function (args) { return __awaiter(void 0, void 0, void 0, function () {
266
+ var store, prompt;
267
+ return __generator(this, function (_a) {
268
+ store = (0, structured_prompts_1.getStore)(process.env.PROMPTS_FILE);
269
+ prompt = store.get(args.id);
270
+ return [2 /*return*/, prompt ? JSON.stringify(prompt, null, 2) : "Prompt not found: ".concat(args.id)];
271
+ });
272
+ }); }
273
+ },
274
+ {
275
+ name: 'list_prompts',
276
+ description: 'List all available prompt templates',
277
+ parameters: { type: 'object', properties: {} },
278
+ handler: function () { return __awaiter(void 0, void 0, void 0, function () {
279
+ var store, prompts;
280
+ return __generator(this, function (_a) {
281
+ store = (0, structured_prompts_1.getStore)(process.env.PROMPTS_FILE);
282
+ prompts = store.list();
283
+ return [2 /*return*/, prompts.map(function (p) { return "- ".concat(p.id, ": ").concat(p.name); }).join('\n') || 'No prompts found'];
284
+ });
285
+ }); }
286
+ },
287
+ {
288
+ name: 'system_info',
289
+ description: 'Get system resource info (CPU, memory, disk, uptime)',
290
+ parameters: { type: 'object', properties: {} },
291
+ handler: function () { return __awaiter(void 0, void 0, void 0, function () {
292
+ var cpu, mem, disk, uptime;
293
+ return __generator(this, function (_a) {
294
+ try {
295
+ cpu = (0, child_process_1.execSync)('nproc 2>/dev/null || echo "unknown"').toString().trim();
296
+ mem = (0, child_process_1.execSync)('free -h 2>/dev/null | grep Mem || echo "unknown"').toString().trim();
297
+ disk = (0, child_process_1.execSync)('df -h / 2>/dev/null | tail -1 || echo "unknown"').toString().trim();
298
+ uptime = (0, child_process_1.execSync)('uptime -p 2>/dev/null || uptime 2>/dev/null || echo "unknown"').toString().trim();
299
+ return [2 /*return*/, "CPU cores: ".concat(cpu, "\nMemory: ").concat(mem, "\nDisk: ").concat(disk, "\nUptime: ").concat(uptime)];
300
+ }
301
+ catch (e) {
302
+ return [2 /*return*/, "Error: ".concat(e.message)];
303
+ }
304
+ return [2 /*return*/];
305
+ });
306
+ }); }
307
+ }
308
+ ];
309
+ /**
310
+ * Get tool by name
311
+ */
312
+ function getBuiltinTool(name) {
313
+ return exports.BUILTIN_TOOLS.find(function (t) { return t.name === name; });
314
+ }
315
+ /**
316
+ * Get all tool names
317
+ */
318
+ function getBuiltinToolNames() {
319
+ return exports.BUILTIN_TOOLS.map(function (t) { return t.name; });
320
+ }
321
+ /**
322
+ * Convert builtin tools to GLM API format
323
+ */
324
+ function toGLMFormat(tools) {
325
+ if (tools === void 0) { tools = exports.BUILTIN_TOOLS; }
326
+ return tools.map(function (t) { return ({
327
+ type: 'function',
328
+ function: {
329
+ name: t.name,
330
+ description: t.description,
331
+ parameters: t.parameters
332
+ }
333
+ }); });
334
+ }
335
+ /**
336
+ * Execute a builtin tool by name
337
+ */
338
+ function executeBuiltinTool(name, args) {
339
+ return __awaiter(this, void 0, void 0, function () {
340
+ var tool;
341
+ return __generator(this, function (_a) {
342
+ tool = getBuiltinTool(name);
343
+ if (!tool) {
344
+ return [2 /*return*/, "Unknown tool: ".concat(name)];
345
+ }
346
+ return [2 /*return*/, tool.handler(args)];
347
+ });
348
+ });
349
+ }