@masons/agent-network 0.3.2 → 0.3.3
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/channel.d.ts.map +1 -1
- package/dist/channel.js +10 -0
- package/dist/connector-client.d.ts.map +1 -1
- package/dist/connector-client.js +21 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -1
package/dist/channel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAa9D,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,oBAAoB,CAAC,CAAC;IAC9B,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC;IACvD,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC;IACpE,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;IACjE,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC;CAC/D;AAED,UAAU,sBAAsB;IAC9B,EAAE,EAAE,OAAO,CAAC;CACb;AAED,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,sBAAsB;IAC9B,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC9C,QAAQ,CAAC,CAAC,GAAG,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CACzE;AAED,UAAU,qBAAqB,CAAC,CAAC,GAAG,OAAO;IACzC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,UAAU,cAAc;IACtB,YAAY,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/C;AAED,UAAU,eAAe;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,UAAU,qBAAqB,CAAC,CAAC,GAAG,OAAO;IACzC,YAAY,CAAC,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,WAAW,CAAC,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,UAAU,yBAAyB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,mBAAmB,CAAC;IAClC,MAAM,EAAE,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;IAClD,QAAQ,EAAE,sBAAsB,CAAC;IACjC,OAAO,EAAE,qBAAqB,CAAC,mBAAmB,CAAC,CAAC;CACrD;AAwDD,eAAO,MAAM,mBAAmB,EAAE,yBA2MjC,CAAC"}
|
package/dist/channel.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
import createDebug from "debug";
|
|
2
3
|
import { clearConnectorClient, extractNetworkConfig, initConnectorClient, initToolConfig, } from "./config.js";
|
|
3
4
|
import { ConnectorClient } from "./connector-client.js";
|
|
4
5
|
import { checkForUpdate } from "./update-check.js";
|
|
6
|
+
const dbg = createDebug("agent-network:channel");
|
|
5
7
|
// --- Sender identity ---
|
|
6
8
|
/**
|
|
7
9
|
* Use sessionId as the sender identifier for OpenClaw routing.
|
|
@@ -103,11 +105,13 @@ export const agentNetworkChannel = {
|
|
|
103
105
|
const sent = state.client.sendMessage(ctx.recipient, ctx.text, {
|
|
104
106
|
contentType: "text",
|
|
105
107
|
});
|
|
108
|
+
dbg("sendText sessionId=%s contentLength=%d sent=%s", ctx.recipient, ctx.text.length, sent);
|
|
106
109
|
return { ok: sent };
|
|
107
110
|
},
|
|
108
111
|
},
|
|
109
112
|
gateway: {
|
|
110
113
|
async startAccount(ctx) {
|
|
114
|
+
dbg("starting account %s", ctx.accountId);
|
|
111
115
|
const { connectorUrl, token } = ctx.account;
|
|
112
116
|
const client = new ConnectorClient(connectorUrl, token);
|
|
113
117
|
const state = {
|
|
@@ -117,6 +121,7 @@ export const agentNetworkChannel = {
|
|
|
117
121
|
accounts.set(ctx.accountId, state);
|
|
118
122
|
// --- Inbound message routing ---
|
|
119
123
|
client.on("message_received", (event) => {
|
|
124
|
+
dbg("routing inbound message sessionId=%s contentLength=%d", event.sessionId, event.content.length);
|
|
120
125
|
const senderId = deriveSenderId(event);
|
|
121
126
|
const envelope = {
|
|
122
127
|
channelId: "agent-network",
|
|
@@ -135,12 +140,14 @@ export const agentNetworkChannel = {
|
|
|
135
140
|
});
|
|
136
141
|
// --- Session lifecycle ---
|
|
137
142
|
client.on("session_created", (event) => {
|
|
143
|
+
dbg("session created sessionId=%s direction=%s", event.sessionId, event.direction);
|
|
138
144
|
const from = event.metadata?.from;
|
|
139
145
|
state.sessions.set(event.sessionId, {
|
|
140
146
|
remoteAddress: typeof from === "string" && from.length > 0 ? from : null,
|
|
141
147
|
});
|
|
142
148
|
});
|
|
143
149
|
client.on("session_ended", (event) => {
|
|
150
|
+
dbg("session ended sessionId=%s", event.sessionId);
|
|
144
151
|
state.sessions.delete(event.sessionId);
|
|
145
152
|
});
|
|
146
153
|
// --- Error handling ---
|
|
@@ -150,6 +157,7 @@ export const agentNetworkChannel = {
|
|
|
150
157
|
});
|
|
151
158
|
// --- Disconnect cleanup ---
|
|
152
159
|
client.on("disconnected", () => {
|
|
160
|
+
dbg("disconnected, cleared %d sessions", state.sessions.size);
|
|
153
161
|
state.sessions.clear();
|
|
154
162
|
});
|
|
155
163
|
// --- Abort signal ---
|
|
@@ -165,6 +173,7 @@ export const agentNetworkChannel = {
|
|
|
165
173
|
checkForUpdate(updateCheckEnabled).catch(() => { });
|
|
166
174
|
// --- Connect ---
|
|
167
175
|
await client.connect();
|
|
176
|
+
dbg("connected account=%s", ctx.accountId);
|
|
168
177
|
// --- Expose client to tools (only after WS is connected) ---
|
|
169
178
|
initConnectorClient(client);
|
|
170
179
|
// Park the Promise — DO NOT resolve/return.
|
|
@@ -181,6 +190,7 @@ export const agentNetworkChannel = {
|
|
|
181
190
|
});
|
|
182
191
|
},
|
|
183
192
|
async stopAccount(ctx) {
|
|
193
|
+
dbg("stopping account %s", ctx.accountId);
|
|
184
194
|
const state = accounts.get(ctx.accountId);
|
|
185
195
|
if (state) {
|
|
186
196
|
clearConnectorClient();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connector-client.d.ts","sourceRoot":"","sources":["../src/connector-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"connector-client.d.ts","sourceRoot":"","sources":["../src/connector-client.ts"],"names":[],"mappings":"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"}
|
package/dist/connector-client.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { EventEmitter } from "node:events";
|
|
3
|
+
import createDebug from "debug";
|
|
3
4
|
import WebSocket from "ws";
|
|
4
5
|
import { CURRENT_PROTOCOL_VERSION, isErrorEvent, isMessageReceived, isRegisterAck, isSessionCreated, isSessionEnded, REGISTER_ACK_TIMEOUT_MS, } from "./types.js";
|
|
6
|
+
const dbg = createDebug("agent-network:connector");
|
|
7
|
+
const dbgMsg = createDebug("agent-network:connector:msg");
|
|
5
8
|
// --- Reconnection constants ---
|
|
6
9
|
const BACKOFF_INITIAL_MS = 1_000;
|
|
7
10
|
const BACKOFF_MAX_MS = 30_000;
|
|
@@ -29,10 +32,12 @@ export class ConnectorClient extends EventEmitter {
|
|
|
29
32
|
if (this.ws) {
|
|
30
33
|
return Promise.reject(new Error("Already connecting or connected"));
|
|
31
34
|
}
|
|
35
|
+
dbg("connecting to %s", this.url);
|
|
32
36
|
this.intentionalClose = false;
|
|
33
37
|
return this.doConnect();
|
|
34
38
|
}
|
|
35
39
|
disconnect() {
|
|
40
|
+
dbg("intentional disconnect");
|
|
36
41
|
this.intentionalClose = true;
|
|
37
42
|
this.clearReconnectTimer();
|
|
38
43
|
const wsToClose = this.ws;
|
|
@@ -53,6 +58,7 @@ export class ConnectorClient extends EventEmitter {
|
|
|
53
58
|
metadata: opts?.metadata,
|
|
54
59
|
};
|
|
55
60
|
const sent = this.send(event);
|
|
61
|
+
dbg("createSession target=%s requestId=%s sent=%s", target, requestId, sent);
|
|
56
62
|
return { requestId, sent };
|
|
57
63
|
}
|
|
58
64
|
sendMessage(sessionId, content, opts) {
|
|
@@ -63,7 +69,9 @@ export class ConnectorClient extends EventEmitter {
|
|
|
63
69
|
contentType: opts?.contentType,
|
|
64
70
|
metadata: opts?.metadata,
|
|
65
71
|
};
|
|
66
|
-
|
|
72
|
+
const sent = this.send(event);
|
|
73
|
+
dbgMsg("sendMessage sessionId=%s contentLength=%d sent=%s", sessionId, content.length, sent);
|
|
74
|
+
return sent;
|
|
67
75
|
}
|
|
68
76
|
endSession(sessionId, reason) {
|
|
69
77
|
const event = {
|
|
@@ -71,7 +79,9 @@ export class ConnectorClient extends EventEmitter {
|
|
|
71
79
|
sessionId,
|
|
72
80
|
reason,
|
|
73
81
|
};
|
|
74
|
-
|
|
82
|
+
const sent = this.send(event);
|
|
83
|
+
dbg("endSession sessionId=%s sent=%s", sessionId, sent);
|
|
84
|
+
return sent;
|
|
75
85
|
}
|
|
76
86
|
on(event, listener) {
|
|
77
87
|
return super.on(event, listener);
|
|
@@ -152,24 +162,29 @@ export class ConnectorClient extends EventEmitter {
|
|
|
152
162
|
return;
|
|
153
163
|
}
|
|
154
164
|
if (isSessionCreated(parsed)) {
|
|
165
|
+
dbg("SESSION_CREATED sessionId=%s direction=%s", parsed.sessionId, parsed.direction);
|
|
155
166
|
this.handleSessionCreated(parsed);
|
|
156
167
|
return;
|
|
157
168
|
}
|
|
158
169
|
if (isMessageReceived(parsed)) {
|
|
170
|
+
dbgMsg("MESSAGE_RECEIVED sessionId=%s contentLength=%d", parsed.sessionId, parsed.content.length);
|
|
159
171
|
this.emit("message_received", parsed);
|
|
160
172
|
return;
|
|
161
173
|
}
|
|
162
174
|
if (isSessionEnded(parsed)) {
|
|
175
|
+
dbg("SESSION_ENDED sessionId=%s", parsed.sessionId);
|
|
163
176
|
this.emit("session_ended", parsed);
|
|
164
177
|
return;
|
|
165
178
|
}
|
|
166
179
|
if (isErrorEvent(parsed)) {
|
|
180
|
+
dbg("ERROR message=%s", parsed.message);
|
|
167
181
|
this.handleErrorEvent(parsed);
|
|
168
182
|
return;
|
|
169
183
|
}
|
|
170
184
|
// Unknown event type — silently ignore (forward compatibility)
|
|
171
185
|
};
|
|
172
186
|
handleRegisterAck(ack) {
|
|
187
|
+
dbg("REGISTER_ACK status=%s", ack.status);
|
|
173
188
|
if (ack.status === "ok") {
|
|
174
189
|
this.backoffMs = BACKOFF_INITIAL_MS;
|
|
175
190
|
this.alreadyConnectedRetries = 0;
|
|
@@ -208,6 +223,7 @@ export class ConnectorClient extends EventEmitter {
|
|
|
208
223
|
}
|
|
209
224
|
// --- Connection close ---
|
|
210
225
|
handleClose = () => {
|
|
226
|
+
dbg("connection closed intentional=%s", this.intentionalClose);
|
|
211
227
|
const wasRegistering = this.registerReject !== null;
|
|
212
228
|
this.cleanupConnection();
|
|
213
229
|
if (wasRegistering) {
|
|
@@ -226,6 +242,7 @@ export class ConnectorClient extends EventEmitter {
|
|
|
226
242
|
}
|
|
227
243
|
};
|
|
228
244
|
handleError = (err) => {
|
|
245
|
+
dbg("websocket error: %s", err.message);
|
|
229
246
|
// WebSocket errors are followed by a close event, so just emit
|
|
230
247
|
this.emit("error", err);
|
|
231
248
|
};
|
|
@@ -233,6 +250,7 @@ export class ConnectorClient extends EventEmitter {
|
|
|
233
250
|
scheduleReconnect() {
|
|
234
251
|
this.clearReconnectTimer();
|
|
235
252
|
const delay = this.calculateBackoff();
|
|
253
|
+
dbg("reconnecting in %dms", Math.round(delay));
|
|
236
254
|
this.reconnectTimer = setTimeout(() => {
|
|
237
255
|
this.reconnectTimer = null;
|
|
238
256
|
this.doConnect().catch(() => {
|
|
@@ -283,6 +301,7 @@ export class ConnectorClient extends EventEmitter {
|
|
|
283
301
|
this.ws.send(JSON.stringify(event));
|
|
284
302
|
return true;
|
|
285
303
|
}
|
|
304
|
+
dbg("send failed: ws not open event=%s", event.event);
|
|
286
305
|
return false;
|
|
287
306
|
}
|
|
288
307
|
}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** Plugin version — must match package.json. Validated by prepublishOnly. */
|
|
2
|
-
export const PLUGIN_VERSION = "0.3.
|
|
2
|
+
export const PLUGIN_VERSION = "0.3.3";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masons/agent-network",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "MASONS plugin for OpenClaw — connect your agent to the agent network",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "MASONS.ai <hello@masons.ai> (https://masons.ai)",
|
|
@@ -59,9 +59,11 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@sinclair/typebox": "^0.34",
|
|
62
|
+
"debug": "^4.4.3",
|
|
62
63
|
"ws": "8.18.3"
|
|
63
64
|
},
|
|
64
65
|
"devDependencies": {
|
|
66
|
+
"@types/debug": "^4.1.12",
|
|
65
67
|
"@types/node": "^25",
|
|
66
68
|
"@types/ws": "^8",
|
|
67
69
|
"ts-node": "^10",
|