multiclaws 0.4.31 → 0.4.32
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
|
@@ -509,7 +509,7 @@ const plugin = {
|
|
|
509
509
|
if (gw) {
|
|
510
510
|
const tools = (gw.tools ?? {});
|
|
511
511
|
const allow = Array.isArray(tools.allow) ? tools.allow : [];
|
|
512
|
-
const adapterRequired = ["sessions_spawn", "sessions_history", "message"];
|
|
512
|
+
const adapterRequired = ["sessions_spawn", "sessions_history", "message", "chat.send"];
|
|
513
513
|
const defaultA2AExecutionTools = ["exec", "read", "write", "edit", "process"];
|
|
514
514
|
const pluginConf = api.pluginConfig ?? {};
|
|
515
515
|
const a2aExecTools = Array.isArray(pluginConf.a2aAllowedTools)
|
|
@@ -595,14 +595,18 @@ const plugin = {
|
|
|
595
595
|
api.on("gateway_stop", () => {
|
|
596
596
|
structured.logger.info("[multiclaws] gateway_stop observed");
|
|
597
597
|
});
|
|
598
|
-
// Collect
|
|
598
|
+
// Collect notification targets from incoming messages (external channels)
|
|
599
599
|
api.on("message_received", (_event, ctx) => {
|
|
600
|
-
if (service && ctx.channelId) {
|
|
601
|
-
service.
|
|
600
|
+
if (service && ctx.channelId && ctx.channelId !== "webchat" && ctx.conversationId) {
|
|
601
|
+
service.addNotificationTarget(`${ctx.channelId}:${ctx.conversationId}`, { type: "channel", conversationId: ctx.conversationId });
|
|
602
602
|
}
|
|
603
603
|
});
|
|
604
604
|
// Inject onboarding prompt when profile is pending first-run setup
|
|
605
|
-
|
|
605
|
+
// Also capture web session targets for notifications
|
|
606
|
+
api.on("before_prompt_build", async (_event, ctx) => {
|
|
607
|
+
if (service && ctx.sessionKey) {
|
|
608
|
+
service.addNotificationTarget(`web:${ctx.sessionKey}`, { type: "web", sessionKey: ctx.sessionKey });
|
|
609
|
+
}
|
|
606
610
|
if (!service)
|
|
607
611
|
return;
|
|
608
612
|
try {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { AgentExecutor, ExecutionEventBus, RequestContext } from "@a2a-js/sdk/server";
|
|
2
2
|
import { type GatewayConfig } from "../infra/gateway-client";
|
|
3
3
|
import type { TaskTracker } from "../task/tracker";
|
|
4
|
+
import type { NotificationTarget } from "./multiclaws-service";
|
|
4
5
|
export type A2AAdapterOptions = {
|
|
5
6
|
gatewayConfig: GatewayConfig | null;
|
|
6
7
|
taskTracker: TaskTracker;
|
|
7
8
|
cwd?: string;
|
|
8
|
-
|
|
9
|
+
getNotificationTargets?: () => ReadonlyMap<string, NotificationTarget>;
|
|
9
10
|
logger: {
|
|
10
11
|
info: (msg: string) => void;
|
|
11
12
|
warn: (msg: string) => void;
|
|
@@ -25,7 +26,7 @@ export type A2AAdapterOptions = {
|
|
|
25
26
|
export declare class OpenClawAgentExecutor implements AgentExecutor {
|
|
26
27
|
private gatewayConfig;
|
|
27
28
|
private readonly taskTracker;
|
|
28
|
-
private readonly
|
|
29
|
+
private readonly getNotificationTargets;
|
|
29
30
|
private readonly logger;
|
|
30
31
|
private readonly cwd;
|
|
31
32
|
private readonly pendingCallbacks;
|
|
@@ -43,7 +44,7 @@ export declare class OpenClawAgentExecutor implements AgentExecutor {
|
|
|
43
44
|
* or rejects on timeout.
|
|
44
45
|
*/
|
|
45
46
|
private createCallback;
|
|
46
|
-
/** Send a notification to all known
|
|
47
|
+
/** Send a notification to all known targets. Individual failures are silently ignored. */
|
|
47
48
|
private notifyUser;
|
|
48
49
|
private publishMessage;
|
|
49
50
|
}
|
|
@@ -23,14 +23,14 @@ function extractTextFromMessage(message) {
|
|
|
23
23
|
class OpenClawAgentExecutor {
|
|
24
24
|
gatewayConfig;
|
|
25
25
|
taskTracker;
|
|
26
|
-
|
|
26
|
+
getNotificationTargets;
|
|
27
27
|
logger;
|
|
28
28
|
cwd;
|
|
29
29
|
pendingCallbacks = new Map();
|
|
30
30
|
constructor(options) {
|
|
31
31
|
this.gatewayConfig = options.gatewayConfig;
|
|
32
32
|
this.taskTracker = options.taskTracker;
|
|
33
|
-
this.
|
|
33
|
+
this.getNotificationTargets = options.getNotificationTargets ?? (() => new Map());
|
|
34
34
|
this.logger = options.logger;
|
|
35
35
|
this.cwd = options.cwd || process.cwd();
|
|
36
36
|
}
|
|
@@ -132,17 +132,24 @@ class OpenClawAgentExecutor {
|
|
|
132
132
|
this.pendingCallbacks.set(taskId, { resolve, reject, timer });
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
|
-
/** Send a notification to all known
|
|
135
|
+
/** Send a notification to all known targets. Individual failures are silently ignored. */
|
|
136
136
|
async notifyUser(message) {
|
|
137
|
-
const
|
|
138
|
-
if (!this.gatewayConfig ||
|
|
137
|
+
const targets = this.getNotificationTargets();
|
|
138
|
+
if (!this.gatewayConfig || targets.size === 0)
|
|
139
139
|
return;
|
|
140
|
-
await Promise.allSettled([...
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
await Promise.allSettled([...targets.values()].map((target) => target.type === "channel"
|
|
141
|
+
? (0, gateway_client_1.invokeGatewayTool)({
|
|
142
|
+
gateway: this.gatewayConfig,
|
|
143
|
+
tool: "message",
|
|
144
|
+
args: { action: "send", target: target.conversationId, message },
|
|
145
|
+
timeoutMs: 5_000,
|
|
146
|
+
})
|
|
147
|
+
: (0, gateway_client_1.invokeGatewayTool)({
|
|
148
|
+
gateway: this.gatewayConfig,
|
|
149
|
+
tool: "chat.send",
|
|
150
|
+
args: { sessionKey: target.sessionKey, message },
|
|
151
|
+
timeoutMs: 5_000,
|
|
152
|
+
})));
|
|
146
153
|
}
|
|
147
154
|
publishMessage(eventBus, text) {
|
|
148
155
|
const message = {
|
|
@@ -27,6 +27,13 @@ export type DelegateTaskResult = {
|
|
|
27
27
|
status: string;
|
|
28
28
|
error?: string;
|
|
29
29
|
};
|
|
30
|
+
export type NotificationTarget = {
|
|
31
|
+
type: "channel";
|
|
32
|
+
conversationId: string;
|
|
33
|
+
} | {
|
|
34
|
+
type: "web";
|
|
35
|
+
sessionKey: string;
|
|
36
|
+
};
|
|
30
37
|
export declare class MulticlawsService extends EventEmitter {
|
|
31
38
|
private readonly options;
|
|
32
39
|
private started;
|
|
@@ -45,7 +52,7 @@ export declare class MulticlawsService extends EventEmitter {
|
|
|
45
52
|
private profileDescription;
|
|
46
53
|
private readonly gatewayConfig;
|
|
47
54
|
private readonly resolvedCwd;
|
|
48
|
-
private readonly
|
|
55
|
+
private readonly notificationTargets;
|
|
49
56
|
constructor(options: MulticlawsServiceOptions);
|
|
50
57
|
start(): Promise<void>;
|
|
51
58
|
stop(): Promise<void>;
|
|
@@ -128,8 +135,8 @@ export declare class MulticlawsService extends EventEmitter {
|
|
|
128
135
|
private fetchWithRetry;
|
|
129
136
|
/** Register a channel ID for notifications. */
|
|
130
137
|
resolveA2ACallback(taskId: string, result: string): boolean;
|
|
131
|
-
|
|
132
|
-
/** Send a notification to all known
|
|
138
|
+
addNotificationTarget(key: string, target: NotificationTarget): void;
|
|
139
|
+
/** Send a notification to all known targets. Individual failures are silently ignored. */
|
|
133
140
|
private notifyUser;
|
|
134
141
|
private log;
|
|
135
142
|
}
|
|
@@ -68,7 +68,7 @@ class MulticlawsService extends node_events_1.EventEmitter {
|
|
|
68
68
|
profileDescription = "OpenClaw agent";
|
|
69
69
|
gatewayConfig;
|
|
70
70
|
resolvedCwd;
|
|
71
|
-
|
|
71
|
+
notificationTargets = new Map();
|
|
72
72
|
constructor(options) {
|
|
73
73
|
super();
|
|
74
74
|
this.options = options;
|
|
@@ -123,7 +123,7 @@ class MulticlawsService extends node_events_1.EventEmitter {
|
|
|
123
123
|
gatewayConfig: this.options.gatewayConfig ?? null,
|
|
124
124
|
taskTracker: this.taskTracker,
|
|
125
125
|
cwd: this.resolvedCwd,
|
|
126
|
-
|
|
126
|
+
getNotificationTargets: () => this.notificationTargets,
|
|
127
127
|
logger,
|
|
128
128
|
});
|
|
129
129
|
this.agentCard = {
|
|
@@ -925,22 +925,29 @@ class MulticlawsService extends node_events_1.EventEmitter {
|
|
|
925
925
|
return false;
|
|
926
926
|
return this.agentExecutor.resolveCallback(taskId, result);
|
|
927
927
|
}
|
|
928
|
-
|
|
929
|
-
if (!this.
|
|
930
|
-
this.
|
|
931
|
-
this.log("debug", `
|
|
928
|
+
addNotificationTarget(key, target) {
|
|
929
|
+
if (!this.notificationTargets.has(key)) {
|
|
930
|
+
this.notificationTargets.set(key, target);
|
|
931
|
+
this.log("debug", `notification target registered: ${key} (total: ${this.notificationTargets.size})`);
|
|
932
932
|
}
|
|
933
933
|
}
|
|
934
|
-
/** Send a notification to all known
|
|
934
|
+
/** Send a notification to all known targets. Individual failures are silently ignored. */
|
|
935
935
|
async notifyUser(message) {
|
|
936
|
-
if (!this.gatewayConfig || this.
|
|
936
|
+
if (!this.gatewayConfig || this.notificationTargets.size === 0)
|
|
937
937
|
return;
|
|
938
|
-
await Promise.allSettled([...this.
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
938
|
+
await Promise.allSettled([...this.notificationTargets.values()].map((target) => target.type === "channel"
|
|
939
|
+
? (0, gateway_client_1.invokeGatewayTool)({
|
|
940
|
+
gateway: this.gatewayConfig,
|
|
941
|
+
tool: "message",
|
|
942
|
+
args: { action: "send", target: target.conversationId, message },
|
|
943
|
+
timeoutMs: 5_000,
|
|
944
|
+
})
|
|
945
|
+
: (0, gateway_client_1.invokeGatewayTool)({
|
|
946
|
+
gateway: this.gatewayConfig,
|
|
947
|
+
tool: "chat.send",
|
|
948
|
+
args: { sessionKey: target.sessionKey, message },
|
|
949
|
+
timeoutMs: 5_000,
|
|
950
|
+
})));
|
|
944
951
|
}
|
|
945
952
|
log(level, message) {
|
|
946
953
|
this.options.logger?.[level]?.(`[multiclaws] ${message}`);
|