multiclaws 0.4.20 → 0.4.21

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.
@@ -1,3 +1,4 @@
1
1
  import type { GatewayRequestHandler } from "../types/openclaw";
2
2
  import type { MulticlawsService } from "../service/multiclaws-service";
3
- export declare function createGatewayHandlers(getService: () => MulticlawsService): Record<string, GatewayRequestHandler>;
3
+ import type { BasicLogger } from "../infra/logger";
4
+ export declare function createGatewayHandlers(getService: () => MulticlawsService, logger?: BasicLogger): Record<string, GatewayRequestHandler>;
@@ -27,15 +27,27 @@ function safeHandle(respond, code, error) {
27
27
  message: error instanceof Error ? error.message : String(error),
28
28
  });
29
29
  }
30
- function createGatewayHandlers(getService) {
30
+ function createGatewayHandlers(getService, logger) {
31
+ const log = (level, msg) => {
32
+ const fn = level === "debug" ? logger?.debug : logger?.[level];
33
+ fn?.(`[multiclaws:gw] ${msg}`);
34
+ };
31
35
  const handlers = {
32
36
  /* ── Agent handlers ─────────────────────────────────────────── */
33
37
  "multiclaws.agent.list": async ({ respond }) => {
34
- const service = getService();
35
- const agents = await service.listAgents();
36
- respond(true, { agents });
38
+ log("debug", "agent.list");
39
+ try {
40
+ const service = getService();
41
+ const agents = await service.listAgents();
42
+ respond(true, { agents });
43
+ }
44
+ catch (error) {
45
+ log("error", `agent.list failed: ${error instanceof Error ? error.message : String(error)}`);
46
+ safeHandle(respond, "agent_list_failed", error);
47
+ }
37
48
  },
38
49
  "multiclaws.agent.add": async ({ params, respond }) => {
50
+ log("debug", `agent.add(url=${params?.url})`);
39
51
  try {
40
52
  const parsed = agentAddSchema.parse(params);
41
53
  const service = getService();
@@ -43,10 +55,12 @@ function createGatewayHandlers(getService) {
43
55
  respond(true, agent);
44
56
  }
45
57
  catch (error) {
58
+ log("error", `agent.add failed: ${error instanceof Error ? error.message : String(error)}`);
46
59
  safeHandle(respond, "invalid_params", error);
47
60
  }
48
61
  },
49
62
  "multiclaws.agent.remove": async ({ params, respond }) => {
63
+ log("debug", `agent.remove(url=${params?.url})`);
50
64
  try {
51
65
  const parsed = agentRemoveSchema.parse(params);
52
66
  const service = getService();
@@ -54,11 +68,13 @@ function createGatewayHandlers(getService) {
54
68
  respond(true, { removed });
55
69
  }
56
70
  catch (error) {
71
+ log("error", `agent.remove failed: ${error instanceof Error ? error.message : String(error)}`);
57
72
  safeHandle(respond, "invalid_params", error);
58
73
  }
59
74
  },
60
75
  /* ── Task handlers ──────────────────────────────────────────── */
61
76
  "multiclaws.task.delegate": async ({ params, respond }) => {
77
+ log("debug", `task.delegate(agentUrl=${params?.agentUrl})`);
62
78
  try {
63
79
  const parsed = taskDelegateSchema.parse(params);
64
80
  const service = getService();
@@ -66,10 +82,12 @@ function createGatewayHandlers(getService) {
66
82
  respond(true, result);
67
83
  }
68
84
  catch (error) {
85
+ log("error", `task.delegate failed: ${error instanceof Error ? error.message : String(error)}`);
69
86
  safeHandle(respond, "task_delegate_failed", error);
70
87
  }
71
88
  },
72
89
  "multiclaws.task.status": async ({ params, respond }) => {
90
+ log("debug", `task.status(taskId=${params?.taskId})`);
73
91
  try {
74
92
  const parsed = taskStatusSchema.parse(params);
75
93
  const service = getService();
@@ -84,11 +102,13 @@ function createGatewayHandlers(getService) {
84
102
  respond(true, { task });
85
103
  }
86
104
  catch (error) {
105
+ log("error", `task.status failed: ${error instanceof Error ? error.message : String(error)}`);
87
106
  safeHandle(respond, "task_status_failed", error);
88
107
  }
89
108
  },
90
109
  /* ── Team handlers ──────────────────────────────────────────── */
91
110
  "multiclaws.team.create": async ({ params, respond }) => {
111
+ log("debug", `team.create(name=${params?.name})`);
92
112
  try {
93
113
  const parsed = teamCreateSchema.parse(params);
94
114
  const service = getService();
@@ -97,10 +117,12 @@ function createGatewayHandlers(getService) {
97
117
  respond(true, { team, inviteCode: invite });
98
118
  }
99
119
  catch (error) {
120
+ log("error", `team.create failed: ${error instanceof Error ? error.message : String(error)}`);
100
121
  safeHandle(respond, "team_create_failed", error);
101
122
  }
102
123
  },
103
124
  "multiclaws.team.join": async ({ params, respond }) => {
125
+ log("debug", "team.join");
104
126
  try {
105
127
  const parsed = teamJoinSchema.parse(params);
106
128
  const service = getService();
@@ -108,10 +130,12 @@ function createGatewayHandlers(getService) {
108
130
  respond(true, { team });
109
131
  }
110
132
  catch (error) {
133
+ log("error", `team.join failed: ${error instanceof Error ? error.message : String(error)}`);
111
134
  safeHandle(respond, "team_join_failed", error);
112
135
  }
113
136
  },
114
137
  "multiclaws.team.leave": async ({ params, respond }) => {
138
+ log("debug", "team.leave");
115
139
  try {
116
140
  const parsed = teamLeaveSchema.parse(params);
117
141
  const service = getService();
@@ -119,10 +143,12 @@ function createGatewayHandlers(getService) {
119
143
  respond(true, { left: true });
120
144
  }
121
145
  catch (error) {
146
+ log("error", `team.leave failed: ${error instanceof Error ? error.message : String(error)}`);
122
147
  safeHandle(respond, "team_leave_failed", error);
123
148
  }
124
149
  },
125
150
  "multiclaws.team.members": async ({ params, respond }) => {
151
+ log("debug", `team.members(teamId=${params?.teamId})`);
126
152
  try {
127
153
  const parsed = teamMembersSchema.parse(params);
128
154
  const service = getService();
@@ -137,26 +163,49 @@ function createGatewayHandlers(getService) {
137
163
  respond(true, result);
138
164
  }
139
165
  catch (error) {
166
+ log("error", `team.members failed: ${error instanceof Error ? error.message : String(error)}`);
140
167
  safeHandle(respond, "team_members_failed", error);
141
168
  }
142
169
  },
143
170
  /* ── Profile handlers ───────────────────────────────────────── */
144
171
  "multiclaws.profile.show": async ({ respond }) => {
145
- const service = getService();
146
- const profile = await service.getProfile();
147
- respond(true, profile);
172
+ log("debug", "profile.show");
173
+ try {
174
+ const service = getService();
175
+ const profile = await service.getProfile();
176
+ respond(true, profile);
177
+ }
178
+ catch (error) {
179
+ log("error", `profile.show failed: ${error instanceof Error ? error.message : String(error)}`);
180
+ safeHandle(respond, "profile_show_failed", error);
181
+ }
148
182
  },
149
183
  "multiclaws.profile.pending_review": async ({ respond }) => {
150
- const service = getService();
151
- const result = await service.getPendingProfileReview();
152
- respond(true, result);
184
+ log("debug", "profile.pending_review");
185
+ try {
186
+ const service = getService();
187
+ const result = await service.getPendingProfileReview();
188
+ respond(true, result);
189
+ }
190
+ catch (error) {
191
+ log("error", `profile.pending_review failed: ${error instanceof Error ? error.message : String(error)}`);
192
+ safeHandle(respond, "profile_pending_review_failed", error);
193
+ }
153
194
  },
154
195
  "multiclaws.profile.clear_pending_review": async ({ respond }) => {
155
- const service = getService();
156
- await service.clearPendingProfileReview();
157
- respond(true, { cleared: true });
196
+ log("debug", "profile.clear_pending_review");
197
+ try {
198
+ const service = getService();
199
+ await service.clearPendingProfileReview();
200
+ respond(true, { cleared: true });
201
+ }
202
+ catch (error) {
203
+ log("error", `profile.clear_pending_review failed: ${error instanceof Error ? error.message : String(error)}`);
204
+ safeHandle(respond, "profile_clear_pending_review_failed", error);
205
+ }
158
206
  },
159
207
  "multiclaws.profile.set": async ({ params, respond }) => {
208
+ log("debug", "profile.set");
160
209
  try {
161
210
  const parsed = profileSetSchema.parse(params);
162
211
  const service = getService();
@@ -164,6 +213,7 @@ function createGatewayHandlers(getService) {
164
213
  respond(true, profile);
165
214
  }
166
215
  catch (error) {
216
+ log("error", `profile.set failed: ${error instanceof Error ? error.message : String(error)}`);
167
217
  safeHandle(respond, "profile_set_failed", error);
168
218
  }
169
219
  },
package/dist/index.js CHANGED
@@ -55,7 +55,11 @@ function requireService(service) {
55
55
  }
56
56
  return service;
57
57
  }
58
- function createTools(getService) {
58
+ function createTools(getService, logger) {
59
+ const log = (level, msg) => {
60
+ const fn = level === "debug" ? logger.debug : logger[level];
61
+ fn?.(`[multiclaws] ${msg}`);
62
+ };
59
63
  /* ── Agent tools ──────────────────────────────────────────────── */
60
64
  const multiclawsAgents = {
61
65
  name: "multiclaws_agents",
@@ -66,9 +70,16 @@ function createTools(getService) {
66
70
  properties: {},
67
71
  },
68
72
  execute: async () => {
69
- const service = requireService(getService());
70
- const agents = await service.listAgents();
71
- return textResult(JSON.stringify({ agents }, null, 2), { agents });
73
+ log("debug", "tool:multiclaws_agents");
74
+ try {
75
+ const service = requireService(getService());
76
+ const agents = await service.listAgents();
77
+ return textResult(JSON.stringify({ agents }, null, 2), { agents });
78
+ }
79
+ catch (err) {
80
+ log("error", `tool:multiclaws_agents failed: ${err instanceof Error ? err.message : String(err)}`);
81
+ throw err;
82
+ }
72
83
  },
73
84
  };
74
85
  const multiclawsAddAgent = {
@@ -84,13 +95,20 @@ function createTools(getService) {
84
95
  required: ["url"],
85
96
  },
86
97
  execute: async (_toolCallId, args) => {
87
- const service = requireService(getService());
88
98
  const url = typeof args.url === "string" ? args.url.trim() : "";
89
- if (!url)
90
- throw new Error("url is required");
91
- const apiKey = typeof args.apiKey === "string" ? args.apiKey.trim() : undefined;
92
- const agent = await service.addAgent({ url, apiKey });
93
- return textResult(`Agent added: ${agent.name} (${agent.url})`, agent);
99
+ log("debug", `tool:multiclaws_add_agent(url=${url})`);
100
+ try {
101
+ const service = requireService(getService());
102
+ if (!url)
103
+ throw new Error("url is required");
104
+ const apiKey = typeof args.apiKey === "string" ? args.apiKey.trim() : undefined;
105
+ const agent = await service.addAgent({ url, apiKey });
106
+ return textResult(`Agent added: ${agent.name} (${agent.url})`, agent);
107
+ }
108
+ catch (err) {
109
+ log("error", `tool:multiclaws_add_agent failed: ${err instanceof Error ? err.message : String(err)}`);
110
+ throw err;
111
+ }
94
112
  },
95
113
  };
96
114
  const multiclawsRemoveAgent = {
@@ -105,17 +123,26 @@ function createTools(getService) {
105
123
  required: ["url"],
106
124
  },
107
125
  execute: async (_toolCallId, args) => {
108
- const service = requireService(getService());
109
126
  const url = typeof args.url === "string" ? args.url.trim() : "";
110
- if (!url)
111
- throw new Error("url is required");
112
- const removed = await service.removeAgent(url);
113
- return textResult(removed ? `Agent ${url} removed.` : `Agent ${url} not found.`);
127
+ log("debug", `tool:multiclaws_remove_agent(url=${url})`);
128
+ try {
129
+ const service = requireService(getService());
130
+ if (!url)
131
+ throw new Error("url is required");
132
+ const removed = await service.removeAgent(url);
133
+ return textResult(removed ? `Agent ${url} removed.` : `Agent ${url} not found.`);
134
+ }
135
+ catch (err) {
136
+ log("error", `tool:multiclaws_remove_agent failed: ${err instanceof Error ? err.message : String(err)}`);
137
+ throw err;
138
+ }
114
139
  },
115
140
  };
116
141
  const multiclawsDelegate = {
117
142
  name: "multiclaws_delegate",
118
- description: "Delegate a task to a remote A2A agent.",
143
+ description: "Delegate a task to a remote A2A agent. " +
144
+ "Automatically spawns a sub-agent that sends the task, waits for the result, " +
145
+ "and reports back via the message tool. Returns immediately.",
119
146
  parameters: {
120
147
  type: "object",
121
148
  additionalProperties: false,
@@ -126,13 +153,51 @@ function createTools(getService) {
126
153
  required: ["agentUrl", "task"],
127
154
  },
128
155
  execute: async (_toolCallId, args) => {
129
- const service = requireService(getService());
130
156
  const agentUrl = typeof args.agentUrl === "string" ? args.agentUrl.trim() : "";
131
- const task = typeof args.task === "string" ? args.task.trim() : "";
132
- if (!agentUrl || !task)
133
- throw new Error("agentUrl and task are required");
134
- const result = await service.delegateTask({ agentUrl, task });
135
- return textResult(JSON.stringify(result, null, 2), result);
157
+ log("info", `tool:multiclaws_delegate(agentUrl=${agentUrl})`);
158
+ try {
159
+ const service = requireService(getService());
160
+ const task = typeof args.task === "string" ? args.task.trim() : "";
161
+ if (!agentUrl || !task)
162
+ throw new Error("agentUrl and task are required");
163
+ const result = await service.spawnDelegation({ agentUrl, task });
164
+ return textResult(result.message, result);
165
+ }
166
+ catch (err) {
167
+ log("error", `tool:multiclaws_delegate failed: ${err instanceof Error ? err.message : String(err)}`);
168
+ throw err;
169
+ }
170
+ },
171
+ };
172
+ const multiclawsDelegateSend = {
173
+ name: "multiclaws_delegate_send",
174
+ description: "Send a task to a remote A2A agent and wait for the result synchronously. " +
175
+ "Used internally by sub-agents spawned from multiclaws_delegate. " +
176
+ "Do NOT call this directly — use multiclaws_delegate instead.",
177
+ parameters: {
178
+ type: "object",
179
+ additionalProperties: false,
180
+ properties: {
181
+ agentUrl: { type: "string" },
182
+ task: { type: "string" },
183
+ },
184
+ required: ["agentUrl", "task"],
185
+ },
186
+ execute: async (_toolCallId, args) => {
187
+ const agentUrl = typeof args.agentUrl === "string" ? args.agentUrl.trim() : "";
188
+ log("info", `tool:multiclaws_delegate_send(agentUrl=${agentUrl})`);
189
+ try {
190
+ const service = requireService(getService());
191
+ const task = typeof args.task === "string" ? args.task.trim() : "";
192
+ if (!agentUrl || !task)
193
+ throw new Error("agentUrl and task are required");
194
+ const result = await service.delegateTaskSync({ agentUrl, task });
195
+ return textResult(JSON.stringify(result, null, 2), result);
196
+ }
197
+ catch (err) {
198
+ log("error", `tool:multiclaws_delegate_send failed: ${err instanceof Error ? err.message : String(err)}`);
199
+ throw err;
200
+ }
136
201
  },
137
202
  };
138
203
  const multiclawsTaskStatus = {
@@ -147,14 +212,21 @@ function createTools(getService) {
147
212
  required: ["taskId"],
148
213
  },
149
214
  execute: async (_toolCallId, args) => {
150
- const service = requireService(getService());
151
215
  const taskId = typeof args.taskId === "string" ? args.taskId.trim() : "";
152
- if (!taskId)
153
- throw new Error("taskId is required");
154
- const task = service.getTaskStatus(taskId);
155
- if (!task)
156
- throw new Error(`task not found: ${taskId}`);
157
- return textResult(JSON.stringify(task, null, 2), task);
216
+ log("debug", `tool:multiclaws_task_status(taskId=${taskId})`);
217
+ try {
218
+ const service = requireService(getService());
219
+ if (!taskId)
220
+ throw new Error("taskId is required");
221
+ const task = service.getTaskStatus(taskId);
222
+ if (!task)
223
+ throw new Error(`task not found: ${taskId}`);
224
+ return textResult(JSON.stringify(task, null, 2), task);
225
+ }
226
+ catch (err) {
227
+ log("error", `tool:multiclaws_task_status failed: ${err instanceof Error ? err.message : String(err)}`);
228
+ throw err;
229
+ }
158
230
  },
159
231
  };
160
232
  /* ── Team tools ───────────────────────────────────────────────── */
@@ -170,13 +242,20 @@ function createTools(getService) {
170
242
  required: ["name"],
171
243
  },
172
244
  execute: async (_toolCallId, args) => {
173
- const service = requireService(getService());
174
245
  const name = typeof args.name === "string" ? args.name.trim() : "";
175
- if (!name)
176
- throw new Error("name is required");
177
- const team = await service.createTeam(name);
178
- const invite = await service.createInvite(team.teamId);
179
- return textResult(`Team "${team.teamName}" created (${team.teamId}).\nInvite code: ${invite}\n\n⚠️ 请只将邀请码分享给完全信任的用户。持有邀请码的人可以加入团队并向你的 AI 委派任务。权限管理模块正在开发中。`, { team, inviteCode: invite });
246
+ log("info", `tool:multiclaws_team_create(name=${name})`);
247
+ try {
248
+ const service = requireService(getService());
249
+ if (!name)
250
+ throw new Error("name is required");
251
+ const team = await service.createTeam(name);
252
+ const invite = await service.createInvite(team.teamId);
253
+ return textResult(`Team "${team.teamName}" created (${team.teamId}).\nInvite code: ${invite}\n\n⚠️ 请只将邀请码分享给完全信任的用户。持有邀请码的人可以加入团队并向你的 AI 委派任务。权限管理模块正在开发中。`, { team, inviteCode: invite });
254
+ }
255
+ catch (err) {
256
+ log("error", `tool:multiclaws_team_create failed: ${err instanceof Error ? err.message : String(err)}`);
257
+ throw err;
258
+ }
180
259
  },
181
260
  };
182
261
  const multiclawsTeamJoin = {
@@ -191,13 +270,20 @@ function createTools(getService) {
191
270
  required: ["inviteCode"],
192
271
  },
193
272
  execute: async (_toolCallId, args) => {
194
- const service = requireService(getService());
195
- const inviteCode = typeof args.inviteCode === "string" ? args.inviteCode.trim() : "";
196
- if (!inviteCode)
197
- throw new Error("inviteCode is required");
198
- const team = await service.joinTeam(inviteCode);
199
- const memberNames = team.members.map((m) => m.name).join(", ");
200
- return textResult(`Joined team "${team.teamName}" with ${team.members.length} members: ${memberNames}`, { team });
273
+ log("info", "tool:multiclaws_team_join");
274
+ try {
275
+ const service = requireService(getService());
276
+ const inviteCode = typeof args.inviteCode === "string" ? args.inviteCode.trim() : "";
277
+ if (!inviteCode)
278
+ throw new Error("inviteCode is required");
279
+ const team = await service.joinTeam(inviteCode);
280
+ const memberNames = team.members.map((m) => m.name).join(", ");
281
+ return textResult(`Joined team "${team.teamName}" with ${team.members.length} members: ${memberNames}`, { team });
282
+ }
283
+ catch (err) {
284
+ log("error", `tool:multiclaws_team_join failed: ${err instanceof Error ? err.message : String(err)}`);
285
+ throw err;
286
+ }
201
287
  },
202
288
  };
203
289
  const multiclawsTeamLeave = {
@@ -211,10 +297,17 @@ function createTools(getService) {
211
297
  },
212
298
  },
213
299
  execute: async (_toolCallId, args) => {
214
- const service = requireService(getService());
215
300
  const teamId = typeof args.teamId === "string" ? args.teamId.trim() : undefined;
216
- await service.leaveTeam(teamId || undefined);
217
- return textResult("Left team successfully.");
301
+ log("info", `tool:multiclaws_team_leave(teamId=${teamId ?? "first"})`);
302
+ try {
303
+ const service = requireService(getService());
304
+ await service.leaveTeam(teamId || undefined);
305
+ return textResult("Left team successfully.");
306
+ }
307
+ catch (err) {
308
+ log("error", `tool:multiclaws_team_leave failed: ${err instanceof Error ? err.message : String(err)}`);
309
+ throw err;
310
+ }
218
311
  },
219
312
  };
220
313
  const multiclawsTeamMembers = {
@@ -228,13 +321,20 @@ function createTools(getService) {
228
321
  },
229
322
  },
230
323
  execute: async (_toolCallId, args) => {
231
- const service = requireService(getService());
232
- const teamId = typeof args.teamId === "string" ? args.teamId.trim() : undefined;
233
- const result = await service.listTeamMembers(teamId || undefined);
234
- if (!result) {
235
- return textResult("No team found.");
324
+ log("debug", "tool:multiclaws_team_members");
325
+ try {
326
+ const service = requireService(getService());
327
+ const teamId = typeof args.teamId === "string" ? args.teamId.trim() : undefined;
328
+ const result = await service.listTeamMembers(teamId || undefined);
329
+ if (!result) {
330
+ return textResult("No team found.");
331
+ }
332
+ return textResult(JSON.stringify(result, null, 2), result);
333
+ }
334
+ catch (err) {
335
+ log("error", `tool:multiclaws_team_members failed: ${err instanceof Error ? err.message : String(err)}`);
336
+ throw err;
236
337
  }
237
- return textResult(JSON.stringify(result, null, 2), result);
238
338
  },
239
339
  };
240
340
  /* ── Profile tools ──────────────────────────────────────────── */
@@ -250,14 +350,21 @@ function createTools(getService) {
250
350
  },
251
351
  },
252
352
  execute: async (_toolCallId, args) => {
253
- const service = requireService(getService());
254
- const patch = {};
255
- if (typeof args.ownerName === "string")
256
- patch.ownerName = args.ownerName.trim();
257
- if (typeof args.bio === "string")
258
- patch.bio = args.bio;
259
- const profile = await service.setProfile(patch);
260
- return textResult(JSON.stringify(profile, null, 2), profile);
353
+ log("debug", "tool:multiclaws_profile_set");
354
+ try {
355
+ const service = requireService(getService());
356
+ const patch = {};
357
+ if (typeof args.ownerName === "string")
358
+ patch.ownerName = args.ownerName.trim();
359
+ if (typeof args.bio === "string")
360
+ patch.bio = args.bio;
361
+ const profile = await service.setProfile(patch);
362
+ return textResult(JSON.stringify(profile, null, 2), profile);
363
+ }
364
+ catch (err) {
365
+ log("error", `tool:multiclaws_profile_set failed: ${err instanceof Error ? err.message : String(err)}`);
366
+ throw err;
367
+ }
261
368
  },
262
369
  };
263
370
  const multiclawsProfileShow = {
@@ -269,9 +376,16 @@ function createTools(getService) {
269
376
  properties: {},
270
377
  },
271
378
  execute: async () => {
272
- const service = requireService(getService());
273
- const profile = await service.getProfile();
274
- return textResult(JSON.stringify(profile, null, 2), profile);
379
+ log("debug", "tool:multiclaws_profile_show");
380
+ try {
381
+ const service = requireService(getService());
382
+ const profile = await service.getProfile();
383
+ return textResult(JSON.stringify(profile, null, 2), profile);
384
+ }
385
+ catch (err) {
386
+ log("error", `tool:multiclaws_profile_show failed: ${err instanceof Error ? err.message : String(err)}`);
387
+ throw err;
388
+ }
275
389
  },
276
390
  };
277
391
  const multiclawsProfilePendingReview = {
@@ -283,9 +397,16 @@ function createTools(getService) {
283
397
  properties: {},
284
398
  },
285
399
  execute: async () => {
286
- const service = requireService(getService());
287
- const result = await service.getPendingProfileReview();
288
- return textResult(JSON.stringify(result, null, 2), result);
400
+ log("debug", "tool:multiclaws_profile_pending_review");
401
+ try {
402
+ const service = requireService(getService());
403
+ const result = await service.getPendingProfileReview();
404
+ return textResult(JSON.stringify(result, null, 2), result);
405
+ }
406
+ catch (err) {
407
+ log("error", `tool:multiclaws_profile_pending_review failed: ${err instanceof Error ? err.message : String(err)}`);
408
+ throw err;
409
+ }
289
410
  },
290
411
  };
291
412
  const multiclawsProfileClearPendingReview = {
@@ -297,9 +418,16 @@ function createTools(getService) {
297
418
  properties: {},
298
419
  },
299
420
  execute: async () => {
300
- const service = requireService(getService());
301
- await service.clearPendingProfileReview();
302
- return textResult("Pending profile review cleared.");
421
+ log("debug", "tool:multiclaws_profile_clear_pending_review");
422
+ try {
423
+ const service = requireService(getService());
424
+ await service.clearPendingProfileReview();
425
+ return textResult("Pending profile review cleared.");
426
+ }
427
+ catch (err) {
428
+ log("error", `tool:multiclaws_profile_clear_pending_review failed: ${err instanceof Error ? err.message : String(err)}`);
429
+ throw err;
430
+ }
303
431
  },
304
432
  };
305
433
  return [
@@ -307,6 +435,7 @@ function createTools(getService) {
307
435
  multiclawsAddAgent,
308
436
  multiclawsRemoveAgent,
309
437
  multiclawsDelegate,
438
+ multiclawsDelegateSend,
310
439
  multiclawsTaskStatus,
311
440
  multiclawsTeamCreate,
312
441
  multiclawsTeamJoin,
@@ -353,30 +482,45 @@ const plugin = {
353
482
  const pluginService = {
354
483
  id: "multiclaws-service",
355
484
  start: async (ctx) => {
356
- service = new multiclaws_service_1.MulticlawsService({
357
- stateDir: ctx.stateDir,
358
- port: config.port,
359
- displayName: config.displayName,
360
- selfUrl: config.selfUrl,
361
- tunnel: config.tunnel,
362
- gatewayConfig: gatewayConfig ?? undefined,
363
- logger: structured.logger,
364
- });
365
- await service.start();
485
+ structured.logger.info("[multiclaws] service starting");
486
+ try {
487
+ service = new multiclaws_service_1.MulticlawsService({
488
+ stateDir: ctx.stateDir,
489
+ port: config.port,
490
+ displayName: config.displayName,
491
+ selfUrl: config.selfUrl,
492
+ tunnel: config.tunnel,
493
+ gatewayConfig: gatewayConfig ?? undefined,
494
+ logger: structured.logger,
495
+ });
496
+ await service.start();
497
+ }
498
+ catch (err) {
499
+ structured.logger.error(`[multiclaws] service start failed: ${err instanceof Error ? err.message : String(err)}`);
500
+ throw err;
501
+ }
366
502
  },
367
503
  stop: async () => {
368
- if (service) {
369
- await service.stop();
370
- service = null;
504
+ structured.logger.info("[multiclaws] service stopping");
505
+ try {
506
+ if (service) {
507
+ await service.stop();
508
+ service = null;
509
+ }
510
+ structured.logger.info("[multiclaws] service stopped");
511
+ }
512
+ catch (err) {
513
+ structured.logger.error(`[multiclaws] service stop failed: ${err instanceof Error ? err.message : String(err)}`);
514
+ throw err;
371
515
  }
372
516
  },
373
517
  };
374
518
  api.registerService(pluginService);
375
- const gatewayHandlers = (0, handlers_1.createGatewayHandlers)(() => requireService(service));
519
+ const gatewayHandlers = (0, handlers_1.createGatewayHandlers)(() => requireService(service), structured.logger);
376
520
  for (const [method, handler] of Object.entries(gatewayHandlers)) {
377
521
  api.registerGatewayMethod(method, handler);
378
522
  }
379
- for (const tool of createTools(() => service)) {
523
+ for (const tool of createTools(() => service, structured.logger)) {
380
524
  api.registerTool(tool);
381
525
  }
382
526
  api.registerHttpRoute({
@@ -4,6 +4,7 @@ export type BasicLogger = {
4
4
  error: (message: string) => void;
5
5
  debug?: (message: string) => void;
6
6
  };
7
+ export declare const noopLogger: BasicLogger;
7
8
  /**
8
9
  * Creates a structured logger that delegates to OpenClaw's base logger.
9
10
  * Only outputs via baseLogger to avoid duplicate stdout writes.
@@ -1,6 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noopLogger = void 0;
3
4
  exports.createStructuredLogger = createStructuredLogger;
5
+ exports.noopLogger = {
6
+ info: () => { },
7
+ warn: () => { },
8
+ error: () => { },
9
+ debug: () => { },
10
+ };
4
11
  /**
5
12
  * Creates a structured logger that delegates to OpenClaw's base logger.
6
13
  * Only outputs via baseLogger to avoid duplicate stdout writes.