multiclaws 0.4.25 → 0.4.27
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
|
|
184
|
-
if (details.isComplete
|
|
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", target: "main", 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) {
|
|
@@ -913,12 +922,12 @@ class MulticlawsService extends node_events_1.EventEmitter {
|
|
|
913
922
|
await (0, gateway_client_1.invokeGatewayTool)({
|
|
914
923
|
gateway: this.gatewayConfig,
|
|
915
924
|
tool: "message",
|
|
916
|
-
args: { action: "send", message },
|
|
925
|
+
args: { action: "send", target: "main", message },
|
|
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) {
|