multiclaws 0.4.25 → 0.4.26

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 CHANGED
@@ -463,7 +463,7 @@ const plugin = {
463
463
  if (gw) {
464
464
  const tools = (gw.tools ?? {});
465
465
  const allow = Array.isArray(tools.allow) ? tools.allow : [];
466
- const required = ["sessions_spawn", "sessions_history"];
466
+ const required = ["sessions_spawn", "sessions_history", "message"];
467
467
  const missing = required.filter((t) => !allow.includes(t));
468
468
  if (missing.length > 0) {
469
469
  tools.allow = [...allow, ...missing];
@@ -43,5 +43,7 @@ export declare class OpenClawAgentExecutor implements AgentExecutor {
43
43
  private extractTextFromHistoryMessage;
44
44
  cancelTask(taskId: string, eventBus: ExecutionEventBus): Promise<void>;
45
45
  updateGatewayConfig(config: GatewayConfig): void;
46
+ /** Send a notification to the local user via the gateway message tool. */
47
+ private notifyUser;
46
48
  private publishMessage;
47
49
  }
@@ -68,6 +68,8 @@ class OpenClawAgentExecutor {
68
68
  eventBus.finished();
69
69
  return;
70
70
  }
71
+ // Notify local user about incoming task
72
+ void this.notifyUser(`📨 收到来自 **${fromAgent}** 的委派任务:${taskText.slice(0, 200)}`);
71
73
  try {
72
74
  this.logger.info(`[a2a-adapter] executing task ${taskId}: ${taskText.slice(0, 100)}`);
73
75
  // 1. Spawn the subagent
@@ -171,17 +173,14 @@ class OpenClawAgentExecutor {
171
173
  const details = extractDetails(histResult);
172
174
  if (!details)
173
175
  return null;
174
- // Respect explicit completion flag from gateway
175
- if (details.isComplete === false)
176
- return null;
177
176
  // Check for session-level error/status from gateway
178
177
  const sessionError = details.error;
179
178
  const sessionStatus = details.status;
180
179
  const messages = (details.messages ?? []);
181
180
  if (messages.length === 0 && !details.isComplete)
182
181
  return null;
183
- // If no explicit isComplete flag, use heuristic: check if the session is still executing
184
- if (details.isComplete === undefined) {
182
+ // If session is not explicitly complete, use heuristic: check if the session is still executing
183
+ if (details.isComplete !== true) {
185
184
  if (messages.length === 0)
186
185
  return null;
187
186
  const lastMsg = messages[messages.length - 1];
@@ -250,6 +249,22 @@ class OpenClawAgentExecutor {
250
249
  updateGatewayConfig(config) {
251
250
  this.gatewayConfig = config;
252
251
  }
252
+ /** Send a notification to the local user via the gateway message tool. */
253
+ async notifyUser(message) {
254
+ if (!this.gatewayConfig)
255
+ return;
256
+ try {
257
+ await (0, gateway_client_1.invokeGatewayTool)({
258
+ gateway: this.gatewayConfig,
259
+ tool: "message",
260
+ args: { action: "send", message },
261
+ timeoutMs: 5_000,
262
+ });
263
+ }
264
+ catch {
265
+ this.logger.warn(`[a2a-adapter] notifyUser failed: ${message.slice(0, 80)}`);
266
+ }
267
+ }
253
268
  publishMessage(eventBus, text) {
254
269
  const message = {
255
270
  kind: "message",
@@ -638,33 +638,40 @@ class MulticlawsService extends node_events_1.EventEmitter {
638
638
  try {
639
639
  const team = await this.teamStore.getTeam(req.params.id);
640
640
  if (!team) {
641
+ this.log("debug", `announce: team ${req.params.id} not found`);
641
642
  res.status(404).json({ error: "team not found" });
642
643
  return;
643
644
  }
644
645
  const parsed = announceBodySchema.safeParse(req.body);
645
646
  if (!parsed.success) {
647
+ this.log("debug", `announce: invalid body: ${parsed.error.message}`);
646
648
  res.status(400).json({ error: parsed.error.message });
647
649
  return;
648
650
  }
649
651
  const member = parsed.data;
652
+ this.log("debug", `announce: member=${member.name}, url=${member.url}`);
650
653
  const normalizedUrl = member.url.replace(/\/+$/, "");
651
654
  const alreadyKnown = team.members.some((m) => m.url.replace(/\/+$/, "") === normalizedUrl);
655
+ this.log("debug", `announce: alreadyKnown=${alreadyKnown}`);
652
656
  await this.teamStore.addMember(team.teamId, {
653
657
  url: normalizedUrl,
654
658
  name: member.name,
655
659
  description: member.description,
656
660
  joinedAtMs: member.joinedAtMs ?? Date.now(),
657
661
  });
662
+ this.log("debug", `announce: addMember completed`);
658
663
  await this.agentRegistry.add({
659
664
  url: normalizedUrl,
660
665
  name: member.name,
661
666
  description: member.description,
662
667
  });
668
+ this.log("debug", `announce: agentRegistry.add completed`);
663
669
  // Broadcast to other members if new
664
670
  if (!alreadyKnown) {
665
671
  const selfNormalized = this.selfUrl.replace(/\/+$/, "");
666
672
  const others = team.members.filter((m) => m.url.replace(/\/+$/, "") !== normalizedUrl &&
667
673
  m.url.replace(/\/+$/, "") !== selfNormalized);
674
+ this.log("debug", `announce: broadcasting to ${others.length} other members`);
668
675
  for (const other of others) {
669
676
  void this.fetchWithRetry(`${other.url}/team/${team.teamId}/announce`, {
670
677
  method: "POST",
@@ -675,13 +682,15 @@ class MulticlawsService extends node_events_1.EventEmitter {
675
682
  description: member.description,
676
683
  joinedAtMs: member.joinedAtMs ?? Date.now(),
677
684
  }),
678
- }).catch(() => {
679
- this.log("warn", `broadcast to ${other.url} failed`);
685
+ }).catch((err) => {
686
+ this.log("warn", `broadcast to ${other.url} failed: ${err instanceof Error ? err.message : String(err)}`);
680
687
  });
681
688
  }
682
689
  // Notify local user that a new member joined
690
+ this.log("debug", `announce: notifying local user about ${member.name}`);
683
691
  void this.notifyUser(`📢 **${member.name}** 已加入团队「${team.teamName}」`);
684
692
  }
693
+ this.log("debug", `announce: completed for ${member.name}`);
685
694
  res.json({ ok: true });
686
695
  }
687
696
  catch (err) {
@@ -917,8 +926,8 @@ class MulticlawsService extends node_events_1.EventEmitter {
917
926
  timeoutMs: 5_000,
918
927
  });
919
928
  }
920
- catch {
921
- this.log("warn", `notifyUser failed: ${message.slice(0, 80)}`);
929
+ catch (err) {
930
+ this.log("warn", `notifyUser failed: ${err instanceof Error ? err.message : String(err)} | msg=${message.slice(0, 80)}`);
922
931
  }
923
932
  }
924
933
  log(level, message) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multiclaws",
3
- "version": "0.4.25",
3
+ "version": "0.4.26",
4
4
  "description": "MultiClaws plugin for OpenClaw collaboration via A2A protocol",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",