@masons/agent-network 0.3.6 → 0.3.8
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 +1 -14
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js +159 -42
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +38 -0
- package/dist/platform-client.d.ts +13 -0
- package/dist/platform-client.d.ts.map +1 -1
- package/dist/platform-client.js +25 -0
- package/dist/plugin.d.ts +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +5 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +40 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/channel.d.ts
CHANGED
|
@@ -32,22 +32,9 @@ interface ChannelGatewayContext<T = unknown> {
|
|
|
32
32
|
cfg: Record<string, unknown>;
|
|
33
33
|
accountId: string;
|
|
34
34
|
account: T;
|
|
35
|
-
runtime:
|
|
35
|
+
runtime: unknown;
|
|
36
36
|
abortSignal: AbortSignal;
|
|
37
37
|
}
|
|
38
|
-
interface GatewayRuntime {
|
|
39
|
-
routeMessage(envelope: MessageEnvelope): void;
|
|
40
|
-
}
|
|
41
|
-
interface MessageEnvelope {
|
|
42
|
-
channelId: string;
|
|
43
|
-
messageId: string;
|
|
44
|
-
senderId: string;
|
|
45
|
-
senderName: string;
|
|
46
|
-
text: string;
|
|
47
|
-
timestamp: number;
|
|
48
|
-
isGroupMessage: boolean;
|
|
49
|
-
metadata?: Record<string, unknown>;
|
|
50
|
-
}
|
|
51
38
|
interface ChannelGatewayAdapter<T = unknown> {
|
|
52
39
|
startAccount?(ctx: ChannelGatewayContext<T>): Promise<unknown>;
|
|
53
40
|
stopAccount?(ctx: ChannelGatewayContext<T>): Promise<void>;
|
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":"AASA,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,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAsDD,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;AAiED,eAAO,MAAM,mBAAmB,EAAE,yBAqWjC,CAAC"}
|
package/dist/channel.js
CHANGED
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import createDebug from "debug";
|
|
3
|
-
import { clearConnectorClient, extractNetworkConfig, initConnectorClient, initToolConfig, } from "./config.js";
|
|
3
|
+
import { clearConnectorClient, extractNetworkConfig, initConnectorClient, initToolConfig, requirePluginRuntime, } from "./config.js";
|
|
4
4
|
import { ConnectorClient } from "./connector-client.js";
|
|
5
5
|
import { checkForUpdate } from "./update-check.js";
|
|
6
6
|
const dbg = createDebug("agent-network:channel");
|
|
7
7
|
// --- Sender identity ---
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Derive a persistent sender identifier from the MSTP address.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* Uses `metadata.from` (the remote agent's MSTP address, e.g.
|
|
12
|
+
* `mstps://masons.ai/alice`) as the conversation key. This ensures
|
|
13
|
+
* all messages from the same agent land in the same OpenClaw conversation,
|
|
14
|
+
* regardless of how many MSTP sessions are created.
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* Falls back to `sessionId` for direct MSTP clients that connect without
|
|
17
|
+
* a Connector (no `metadata.from`). These get ephemeral conversations.
|
|
17
18
|
*
|
|
18
|
-
* The
|
|
19
|
-
*
|
|
19
|
+
* The `activeSession` reverse index in AccountState maps the MSTP address
|
|
20
|
+
* back to the current sessionId for outbound routing (sendText, deliver).
|
|
21
|
+
*
|
|
22
|
+
* See: docs/openclaw/research/session-identity-mapping.md §5
|
|
20
23
|
*/
|
|
21
24
|
function deriveSenderId(event) {
|
|
25
|
+
const from = event.metadata?.from;
|
|
26
|
+
if (typeof from === "string" && from.length > 0) {
|
|
27
|
+
return from;
|
|
28
|
+
}
|
|
22
29
|
return event.sessionId;
|
|
23
30
|
}
|
|
24
31
|
/**
|
|
@@ -89,7 +96,7 @@ export const agentNetworkChannel = {
|
|
|
89
96
|
isConfigured(account) {
|
|
90
97
|
return account.connectorUrl !== "" && account.token !== "";
|
|
91
98
|
},
|
|
92
|
-
isEnabled(
|
|
99
|
+
isEnabled(_account, cfg) {
|
|
93
100
|
const networkCfg = extractNetworkConfig(cfg);
|
|
94
101
|
return networkCfg?.enabled !== false;
|
|
95
102
|
},
|
|
@@ -97,68 +104,176 @@ export const agentNetworkChannel = {
|
|
|
97
104
|
outbound: {
|
|
98
105
|
deliveryMode: "direct",
|
|
99
106
|
async sendText(ctx) {
|
|
100
|
-
// ctx.recipient
|
|
107
|
+
// ctx.recipient is now an MSTP address (senderId = address from deriveSenderId).
|
|
108
|
+
// Resolve to the active sessionId via the reverse index.
|
|
101
109
|
const state = accounts.get(ctx.accountId);
|
|
102
|
-
if (!state
|
|
110
|
+
if (!state)
|
|
103
111
|
return { ok: false };
|
|
112
|
+
let sessionId = state.activeSession.get(ctx.recipient);
|
|
113
|
+
// Fallback: ctx.recipient might be a raw sessionId (direct MSTP client
|
|
114
|
+
// without metadata.from — deriveSenderId fell back to sessionId).
|
|
115
|
+
if (!sessionId && state.sessions.has(ctx.recipient)) {
|
|
116
|
+
sessionId = ctx.recipient;
|
|
104
117
|
}
|
|
105
|
-
|
|
118
|
+
if (!sessionId || !state.sessions.has(sessionId)) {
|
|
119
|
+
return { ok: false };
|
|
120
|
+
}
|
|
121
|
+
const sent = state.client.sendMessage(sessionId, ctx.text, {
|
|
106
122
|
contentType: "text",
|
|
107
123
|
});
|
|
108
|
-
dbg("sendText sessionId=%s contentLength=%d sent=%s", ctx.recipient, ctx.text.length, sent);
|
|
124
|
+
dbg("sendText recipient=%s sessionId=%s contentLength=%d sent=%s", ctx.recipient, sessionId, ctx.text.length, sent);
|
|
109
125
|
return { ok: sent };
|
|
110
126
|
},
|
|
111
127
|
},
|
|
112
128
|
gateway: {
|
|
113
129
|
async startAccount(ctx) {
|
|
114
130
|
dbg("starting account %s", ctx.accountId);
|
|
115
|
-
// Capability check: routeMessage is required for inbound message delivery.
|
|
116
|
-
// Older OpenClaw versions may not provide it on the gateway runtime.
|
|
117
|
-
if (typeof ctx.runtime.routeMessage !== "function") {
|
|
118
|
-
console.error("[agent-network] OpenClaw version too old — ctx.runtime.routeMessage is not available. " +
|
|
119
|
-
"Inbound messages will not be delivered. Please upgrade OpenClaw.");
|
|
120
|
-
}
|
|
121
131
|
const { connectorUrl, token } = ctx.account;
|
|
122
132
|
const client = new ConnectorClient(connectorUrl, token);
|
|
123
133
|
const state = {
|
|
124
134
|
client,
|
|
125
135
|
sessions: new Map(),
|
|
136
|
+
activeSession: new Map(),
|
|
126
137
|
};
|
|
127
138
|
accounts.set(ctx.accountId, state);
|
|
128
|
-
// --- Inbound message routing ---
|
|
129
|
-
|
|
139
|
+
// --- Inbound message routing (4-step channelRuntime dispatch) ---
|
|
140
|
+
// Replaces the non-existent routeMessage() API. Uses PluginRuntime
|
|
141
|
+
// captured in register() via config.ts module-level singleton.
|
|
142
|
+
// Reference: DingTalk plugin (github.com/soimy/openclaw-channel-dingtalk).
|
|
143
|
+
//
|
|
144
|
+
// Concurrency model: this handler is async but EventEmitter fires it
|
|
145
|
+
// synchronously per event. Multiple MESSAGE_RECEIVED on the same session
|
|
146
|
+
// produce concurrent dispatches — replies may arrive out of order.
|
|
147
|
+
// Acceptable for unstructured text conversation (Phase 1). If MSTP adds
|
|
148
|
+
// structured multi-step interactions, add a per-session dispatch queue.
|
|
149
|
+
client.on("message_received", async (event) => {
|
|
130
150
|
dbg("routing inbound message sessionId=%s contentLength=%d", event.sessionId, event.content.length);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
timestamp: Date.now(),
|
|
139
|
-
isGroupMessage: false,
|
|
140
|
-
metadata: {
|
|
141
|
-
...event.metadata,
|
|
142
|
-
contentType: event.contentType,
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
if (typeof ctx.runtime.routeMessage !== "function") {
|
|
146
|
-
dbg("routeMessage not available, dropping inbound message sessionId=%s", event.sessionId);
|
|
151
|
+
// --- Runtime guard ---
|
|
152
|
+
let runtime;
|
|
153
|
+
try {
|
|
154
|
+
runtime = requirePluginRuntime();
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
dbg("plugin runtime not available, dropping message sessionId=%s", event.sessionId);
|
|
147
158
|
return;
|
|
148
159
|
}
|
|
149
|
-
|
|
160
|
+
// channel is required in our PluginRuntime type but may be absent
|
|
161
|
+
// at runtime on older OpenClaw versions (pre-2026.2.19).
|
|
162
|
+
if (!runtime.channel) {
|
|
163
|
+
dbg("channelRuntime not available, dropping message sessionId=%s", event.sessionId);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
// Resolve sender identity from session state, NOT from per-message metadata.
|
|
167
|
+
// metadata.from is reliably present on SESSION_CREATED (Connector sets it
|
|
168
|
+
// server-side) but NOT on MESSAGE_RECEIVED (per-message metadata is
|
|
169
|
+
// pass-through from the remote plugin, which doesn't include `from`).
|
|
170
|
+
// The session_created handler already stored the remoteAddress.
|
|
171
|
+
const sessionMeta = state.sessions.get(event.sessionId);
|
|
172
|
+
const senderId = sessionMeta?.remoteAddress ?? event.sessionId;
|
|
173
|
+
// Derive sender name from the resolved address, not per-message metadata.
|
|
174
|
+
// Build a synthetic event with the session's address for deriveSenderName.
|
|
175
|
+
const senderName = sessionMeta?.remoteAddress
|
|
176
|
+
? deriveSenderName({
|
|
177
|
+
...event,
|
|
178
|
+
metadata: { ...event.metadata, from: sessionMeta.remoteAddress },
|
|
179
|
+
})
|
|
180
|
+
: deriveSenderName(event);
|
|
181
|
+
try {
|
|
182
|
+
// Step 1 — Resolve agent route (await defensively — may be sync or async)
|
|
183
|
+
const route = await runtime.channel.routing.resolveAgentRoute({
|
|
184
|
+
cfg: ctx.cfg,
|
|
185
|
+
channel: "agent-network",
|
|
186
|
+
accountId: ctx.accountId,
|
|
187
|
+
peer: { kind: "direct", id: senderId },
|
|
188
|
+
});
|
|
189
|
+
// Step 2 — Finalize inbound context (builds MsgContext for LLM pipeline)
|
|
190
|
+
const msgCtx = runtime.channel.reply.finalizeInboundContext({
|
|
191
|
+
Body: event.content,
|
|
192
|
+
RawBody: event.content,
|
|
193
|
+
CommandBody: event.content,
|
|
194
|
+
From: senderId,
|
|
195
|
+
To: senderId,
|
|
196
|
+
SessionKey: route.sessionKey,
|
|
197
|
+
AccountId: ctx.accountId,
|
|
198
|
+
ChatType: "direct",
|
|
199
|
+
SenderName: senderName,
|
|
200
|
+
SenderId: senderId,
|
|
201
|
+
Timestamp: Date.now(),
|
|
202
|
+
Provider: "agent-network",
|
|
203
|
+
Surface: "agent-network",
|
|
204
|
+
MessageSid: `mstp:${event.sessionId}:${randomUUID()}`,
|
|
205
|
+
CommandAuthorized: true,
|
|
206
|
+
OriginatingChannel: "agent-network",
|
|
207
|
+
OriginatingTo: senderId,
|
|
208
|
+
});
|
|
209
|
+
// Step 3 — Record inbound session
|
|
210
|
+
const storePath = runtime.channel.session.resolveStorePath(undefined, { agentId: route.agentId });
|
|
211
|
+
const sessionKey = typeof msgCtx.SessionKey === "string"
|
|
212
|
+
? msgCtx.SessionKey
|
|
213
|
+
: route.sessionKey;
|
|
214
|
+
await runtime.channel.session.recordInboundSession({
|
|
215
|
+
storePath,
|
|
216
|
+
sessionKey,
|
|
217
|
+
ctx: msgCtx,
|
|
218
|
+
});
|
|
219
|
+
// Step 4 — Dispatch to LLM pipeline + deliver reply via callback
|
|
220
|
+
await runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
221
|
+
ctx: msgCtx,
|
|
222
|
+
cfg: ctx.cfg,
|
|
223
|
+
dispatcherOptions: {
|
|
224
|
+
deliver: async (payload) => {
|
|
225
|
+
const text = payload.text;
|
|
226
|
+
if (!text)
|
|
227
|
+
return;
|
|
228
|
+
// senderId is now an MSTP address. Resolve to sessionId.
|
|
229
|
+
let deliverSessionId = state.activeSession.get(senderId);
|
|
230
|
+
// Fallback: senderId might be a raw sessionId (direct client).
|
|
231
|
+
if (!deliverSessionId && state.sessions.has(senderId)) {
|
|
232
|
+
deliverSessionId = senderId;
|
|
233
|
+
}
|
|
234
|
+
// Session may have ended while LLM was processing.
|
|
235
|
+
if (!deliverSessionId || !state.sessions.has(deliverSessionId))
|
|
236
|
+
return;
|
|
237
|
+
const sent = state.client.sendMessage(deliverSessionId, text, {
|
|
238
|
+
contentType: "text",
|
|
239
|
+
});
|
|
240
|
+
dbg("deliver reply address=%s sessionId=%s contentLength=%d sent=%s", senderId, deliverSessionId, text.length, sent);
|
|
241
|
+
},
|
|
242
|
+
onError: (err) => {
|
|
243
|
+
console.error(`[agent-network:${ctx.accountId}] dispatch error:`, err);
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
console.error(`[agent-network:${ctx.accountId}] inbound dispatch failed sessionId=${event.sessionId}:`, err);
|
|
250
|
+
}
|
|
150
251
|
});
|
|
151
252
|
// --- Session lifecycle ---
|
|
152
253
|
client.on("session_created", (event) => {
|
|
153
254
|
dbg("session created sessionId=%s direction=%s", event.sessionId, event.direction);
|
|
154
255
|
const from = event.metadata?.from;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
256
|
+
const remoteAddress = typeof from === "string" && from.length > 0 ? from : null;
|
|
257
|
+
state.sessions.set(event.sessionId, { remoteAddress });
|
|
258
|
+
// Update reverse index: this address is now reachable via this session.
|
|
259
|
+
// Last-write-wins: if a new session arrives from the same address,
|
|
260
|
+
// replies go to the newest session (same as XMPP resource binding).
|
|
261
|
+
if (remoteAddress) {
|
|
262
|
+
state.activeSession.set(remoteAddress, event.sessionId);
|
|
263
|
+
}
|
|
158
264
|
});
|
|
159
265
|
client.on("session_ended", (event) => {
|
|
160
266
|
dbg("session ended sessionId=%s", event.sessionId);
|
|
267
|
+
const sessionMeta = state.sessions.get(event.sessionId);
|
|
161
268
|
state.sessions.delete(event.sessionId);
|
|
269
|
+
// Only clear reverse index if this session was the active one.
|
|
270
|
+
// If a newer session replaced it, the index already points elsewhere.
|
|
271
|
+
if (sessionMeta?.remoteAddress) {
|
|
272
|
+
const currentActive = state.activeSession.get(sessionMeta.remoteAddress);
|
|
273
|
+
if (currentActive === event.sessionId) {
|
|
274
|
+
state.activeSession.delete(sessionMeta.remoteAddress);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
162
277
|
});
|
|
163
278
|
// --- Error handling ---
|
|
164
279
|
// Must register before connect() — unhandled "error" events crash the process.
|
|
@@ -169,6 +284,7 @@ export const agentNetworkChannel = {
|
|
|
169
284
|
client.on("disconnected", () => {
|
|
170
285
|
dbg("disconnected, cleared %d sessions", state.sessions.size);
|
|
171
286
|
state.sessions.clear();
|
|
287
|
+
state.activeSession.clear();
|
|
172
288
|
});
|
|
173
289
|
// --- Abort signal ---
|
|
174
290
|
ctx.abortSignal.addEventListener("abort", () => {
|
|
@@ -207,6 +323,7 @@ export const agentNetworkChannel = {
|
|
|
207
323
|
state.client.removeAllListeners();
|
|
208
324
|
state.client.disconnect();
|
|
209
325
|
state.sessions.clear();
|
|
326
|
+
state.activeSession.clear();
|
|
210
327
|
accounts.delete(ctx.accountId);
|
|
211
328
|
}
|
|
212
329
|
},
|
package/dist/config.d.ts
CHANGED
|
@@ -49,6 +49,28 @@ export declare function initConnectorClient(client: ConnectorClient): void;
|
|
|
49
49
|
* operating on a disconnected client.
|
|
50
50
|
*/
|
|
51
51
|
export declare function clearConnectorClient(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Store the OpenClaw PluginRuntime for inbound message dispatch.
|
|
54
|
+
*
|
|
55
|
+
* Called by `register(api)` in plugin.ts — captures `api.runtime` which
|
|
56
|
+
* provides `runtime.channel.*` (routing, reply, session) used by the
|
|
57
|
+
* 4-step inbound dispatch flow in channel.ts.
|
|
58
|
+
*
|
|
59
|
+
* Idempotent: overwrites on re-call. Gateway may hot-reload plugins,
|
|
60
|
+
* calling `register()` again without a teardown counterpart.
|
|
61
|
+
*/
|
|
62
|
+
export declare function initPluginRuntime(runtime: unknown): void;
|
|
63
|
+
/**
|
|
64
|
+
* Clear the stored PluginRuntime reference.
|
|
65
|
+
*/
|
|
66
|
+
export declare function clearPluginRuntime(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Get the stored PluginRuntime. Throws if not initialized.
|
|
69
|
+
*
|
|
70
|
+
* Callers cast the result to `PluginRuntime` (defined in channel.ts)
|
|
71
|
+
* at the usage site. Typed as `unknown` here to avoid circular imports.
|
|
72
|
+
*/
|
|
73
|
+
export declare function requirePluginRuntime(): unknown;
|
|
52
74
|
/**
|
|
53
75
|
* Get platform config. Always returns a valid config — defaults are set
|
|
54
76
|
* at module load time, and overwritten by `initToolConfig()` when
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AA2B9B;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMhC;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAsBjE;AAMD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAOjE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAMD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAExD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAO9C;AAMD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,IAAI,oBAAoB,CAE5D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAKtC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEhD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,eAAe,CAOxD;AAMD,+EAA+E;AAC/E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAgDD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,kBAAkB,EACzB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKrE;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAQvD;AAMD;;;;;GAKG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKvD;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAKzD;AAMD,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,cAAc,EAAE,OAAO,CAAC;IACxB,wDAAwD;IACxD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,4EAA4E;IAC5E,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,YAAY,CAAC,CA2BhE;AAMD,uDAAuD;AACvD,wBAAgB,gBAAgB,IAAI,IAAI,CAMvC"}
|
package/dist/config.js
CHANGED
|
@@ -32,6 +32,9 @@ let storedApiKey = null;
|
|
|
32
32
|
let storedPendingTarget = null;
|
|
33
33
|
// Runtime state (live connection — set by startAccount, cleared by stopAccount)
|
|
34
34
|
let storedConnectorClient = null;
|
|
35
|
+
// PluginRuntime state (set by register() in plugin.ts, used by channel.ts)
|
|
36
|
+
// Typed as unknown to avoid circular imports — channel.ts casts to PluginRuntime.
|
|
37
|
+
let storedPluginRuntime = null;
|
|
35
38
|
// ---------------------------------------------------------------------------
|
|
36
39
|
// Config navigation — shared between channel.ts and config.ts
|
|
37
40
|
// ---------------------------------------------------------------------------
|
|
@@ -106,6 +109,40 @@ export function clearConnectorClient() {
|
|
|
106
109
|
storedConnectorClient = null;
|
|
107
110
|
}
|
|
108
111
|
// ---------------------------------------------------------------------------
|
|
112
|
+
// PluginRuntime injection (called by register() in plugin.ts)
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
/**
|
|
115
|
+
* Store the OpenClaw PluginRuntime for inbound message dispatch.
|
|
116
|
+
*
|
|
117
|
+
* Called by `register(api)` in plugin.ts — captures `api.runtime` which
|
|
118
|
+
* provides `runtime.channel.*` (routing, reply, session) used by the
|
|
119
|
+
* 4-step inbound dispatch flow in channel.ts.
|
|
120
|
+
*
|
|
121
|
+
* Idempotent: overwrites on re-call. Gateway may hot-reload plugins,
|
|
122
|
+
* calling `register()` again without a teardown counterpart.
|
|
123
|
+
*/
|
|
124
|
+
export function initPluginRuntime(runtime) {
|
|
125
|
+
storedPluginRuntime = runtime;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Clear the stored PluginRuntime reference.
|
|
129
|
+
*/
|
|
130
|
+
export function clearPluginRuntime() {
|
|
131
|
+
storedPluginRuntime = null;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get the stored PluginRuntime. Throws if not initialized.
|
|
135
|
+
*
|
|
136
|
+
* Callers cast the result to `PluginRuntime` (defined in channel.ts)
|
|
137
|
+
* at the usage site. Typed as `unknown` here to avoid circular imports.
|
|
138
|
+
*/
|
|
139
|
+
export function requirePluginRuntime() {
|
|
140
|
+
if (storedPluginRuntime == null) {
|
|
141
|
+
throw new Error("Plugin runtime not initialized. register() must be called first.");
|
|
142
|
+
}
|
|
143
|
+
return storedPluginRuntime;
|
|
144
|
+
}
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
109
146
|
// Guard functions (used by tools — fail-fast if not initialized)
|
|
110
147
|
// ---------------------------------------------------------------------------
|
|
111
148
|
/**
|
|
@@ -312,4 +349,5 @@ export function _resetForTesting() {
|
|
|
312
349
|
storedApiKey = null;
|
|
313
350
|
storedPendingTarget = null;
|
|
314
351
|
storedConnectorClient = null;
|
|
352
|
+
storedPluginRuntime = null;
|
|
315
353
|
}
|
|
@@ -120,6 +120,10 @@ export interface ListConnectionsResponse {
|
|
|
120
120
|
address: string;
|
|
121
121
|
}>;
|
|
122
122
|
}
|
|
123
|
+
export interface ConnectionStatusResponse {
|
|
124
|
+
status: "connected" | "pending" | "not_connected";
|
|
125
|
+
canCreateSession: boolean;
|
|
126
|
+
}
|
|
123
127
|
/**
|
|
124
128
|
* `POST /setup/init` — Start Device Code Flow.
|
|
125
129
|
*
|
|
@@ -207,4 +211,13 @@ export declare function updateProfile(cfg: PlatformClientConfig, apiKey: string,
|
|
|
207
211
|
* Returns name + MSTP address for each connected agent.
|
|
208
212
|
*/
|
|
209
213
|
export declare function listConnections(cfg: PlatformClientConfig, apiKey: string): Promise<ListConnectionsResponse>;
|
|
214
|
+
/**
|
|
215
|
+
* `GET /connections/status?target={handle}` — Check connection status.
|
|
216
|
+
*
|
|
217
|
+
* Requires API Key in Authorization header.
|
|
218
|
+
* Returns connection status and whether session creation is possible.
|
|
219
|
+
*
|
|
220
|
+
* Returns null if the request fails (advisory — caller should degrade gracefully).
|
|
221
|
+
*/
|
|
222
|
+
export declare function getConnectionStatus(cfg: PlatformClientConfig, apiKey: string, targetHandle: string): Promise<ConnectionStatusResponse | null>;
|
|
210
223
|
//# sourceMappingURL=platform-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform-client.d.ts","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"platform-client.d.ts","sourceRoot":"","sources":["../src/platform-client.ts"],"names":[],"mappings":"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"}
|
package/dist/platform-client.js
CHANGED
|
@@ -247,3 +247,28 @@ export async function listConnections(cfg, apiKey) {
|
|
|
247
247
|
return handleError(res);
|
|
248
248
|
return (await res.json());
|
|
249
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* `GET /connections/status?target={handle}` — Check connection status.
|
|
252
|
+
*
|
|
253
|
+
* Requires API Key in Authorization header.
|
|
254
|
+
* Returns connection status and whether session creation is possible.
|
|
255
|
+
*
|
|
256
|
+
* Returns null if the request fails (advisory — caller should degrade gracefully).
|
|
257
|
+
*/
|
|
258
|
+
export async function getConnectionStatus(cfg, apiKey, targetHandle) {
|
|
259
|
+
try {
|
|
260
|
+
const controller = new AbortController();
|
|
261
|
+
const timeout = setTimeout(() => controller.abort(), 3000);
|
|
262
|
+
const res = await fetch(`${baseUrl(cfg)}/connections/status?target=${encodeURIComponent(targetHandle)}`, {
|
|
263
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
264
|
+
signal: controller.signal,
|
|
265
|
+
});
|
|
266
|
+
clearTimeout(timeout);
|
|
267
|
+
if (!res.ok)
|
|
268
|
+
return null; // Advisory — degrade gracefully
|
|
269
|
+
return (await res.json());
|
|
270
|
+
}
|
|
271
|
+
catch {
|
|
272
|
+
return null; // Network error or timeout — degrade gracefully
|
|
273
|
+
}
|
|
274
|
+
}
|
package/dist/plugin.d.ts
CHANGED
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAWA,UAAU,iBAAiB;IACzB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;kBA4BI,iBAAiB;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAWA,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;kBA4BI,iBAAiB;CA4GhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// NOT imported by index.ts to avoid pulling ws/typebox into Next.js app bundles.
|
|
4
4
|
import { agentNetworkChannel } from "./channel.js";
|
|
5
5
|
import { configureInteractive } from "./cli-setup.js";
|
|
6
|
-
import { detectPendingState } from "./config.js";
|
|
6
|
+
import { detectPendingState, initPluginRuntime } from "./config.js";
|
|
7
7
|
import { registerTools } from "./tools.js";
|
|
8
8
|
import { PLUGIN_VERSION } from "./version.js";
|
|
9
9
|
const plugin = {
|
|
@@ -32,6 +32,10 @@ const plugin = {
|
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
34
|
register(api) {
|
|
35
|
+
// Capture runtime for inbound message dispatch (Pathway 1: module-level singleton).
|
|
36
|
+
// api.runtime is the full PluginRuntime (includes .channel for routing/reply/session).
|
|
37
|
+
// Idempotent — Gateway may hot-reload, calling register() again.
|
|
38
|
+
initPluginRuntime(api.runtime);
|
|
35
39
|
// Register tools FIRST — they must be available even when the channel
|
|
36
40
|
// has no credentials yet (setup flow needs these tools to GET credentials).
|
|
37
41
|
registerTools(api);
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAqCH,UAAU,WAAW;IACnB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,CACP,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,WAAW,CAAC,CAAC;CAC3B;AAED,UAAU,OAAO;IACf,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACzE;AAmBD,uDAAuD;AACvD,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAED,6DAA6D;AAC7D,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAE7D;AAuJD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAurBhD"}
|
package/dist/tools.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { Type } from "@sinclair/typebox";
|
|
17
17
|
import { clearTargetHandle, getPendingTarget, markProfileComplete, markProfileNeeded, requireApiKey, requireConnectorClient, requirePlatformConfig, writeCredentials, } from "./config.js";
|
|
18
|
-
import { acceptRequest, declineRequest, initSetup, listConnections, listRequests, onboard, PlatformApiError, pollSetup, reconnect, requestConnection, SetupExpiredError, SetupPendingError, updateProfile, } from "./platform-client.js";
|
|
18
|
+
import { acceptRequest, declineRequest, getConnectionStatus, initSetup, listConnections, listRequests, onboard, PlatformApiError, pollSetup, reconnect, requestConnection, SetupExpiredError, SetupPendingError, updateProfile, } from "./platform-client.js";
|
|
19
19
|
import { getUpdateInfo } from "./update-check.js";
|
|
20
20
|
// ---------------------------------------------------------------------------
|
|
21
21
|
// Constants
|
|
@@ -131,19 +131,33 @@ function formatSessionCreated(sessionId, target) {
|
|
|
131
131
|
function waitForSessionCreated(client, requestId) {
|
|
132
132
|
return new Promise((resolve) => {
|
|
133
133
|
const timer = setTimeout(() => {
|
|
134
|
-
|
|
134
|
+
cleanup();
|
|
135
135
|
resolve({
|
|
136
136
|
error: "Session creation timed out. The remote agent may be unavailable.",
|
|
137
137
|
});
|
|
138
138
|
}, sessionTimeoutMs);
|
|
139
|
+
function cleanup() {
|
|
140
|
+
clearTimeout(timer);
|
|
141
|
+
client.off("session_created", onSessionCreated);
|
|
142
|
+
client.off("error", onError);
|
|
143
|
+
}
|
|
139
144
|
function onSessionCreated(event) {
|
|
140
145
|
if (event.requestId === requestId && event.direction === "outbound") {
|
|
141
|
-
|
|
142
|
-
client.off("session_created", onSessionCreated);
|
|
146
|
+
cleanup();
|
|
143
147
|
resolve({ sessionId: event.sessionId });
|
|
144
148
|
}
|
|
145
149
|
}
|
|
150
|
+
// Listen for ERROR events from the Connector (e.g., access control rejection).
|
|
151
|
+
// The Connector sends { event: "ERROR", requestId, message } as a global error
|
|
152
|
+
// when CREATE_SESSION is rejected.
|
|
153
|
+
function onError(err) {
|
|
154
|
+
// ConnectorClient emits Error objects with the server message as err.message.
|
|
155
|
+
// Match by checking if the error message is actionable (not a generic WS error).
|
|
156
|
+
cleanup();
|
|
157
|
+
resolve({ error: err.message });
|
|
158
|
+
}
|
|
146
159
|
client.on("session_created", onSessionCreated);
|
|
160
|
+
client.on("error", onError);
|
|
147
161
|
});
|
|
148
162
|
}
|
|
149
163
|
// ---------------------------------------------------------------------------
|
|
@@ -603,6 +617,28 @@ export function registerTools(api) {
|
|
|
603
617
|
execute: withUpdateNotice(async (_id, params) => {
|
|
604
618
|
const client = requireConnectorClient();
|
|
605
619
|
const target = params.target;
|
|
620
|
+
// --- Pre-flight: check connection status (advisory, not gate) ---
|
|
621
|
+
// If the check fails (network error, API down), proceed anyway —
|
|
622
|
+
// the Connector gate (Layer 2) is the authoritative enforcement.
|
|
623
|
+
try {
|
|
624
|
+
const handle = target
|
|
625
|
+
.replace(/^mstps?:\/\/[^/]+\//, "")
|
|
626
|
+
.replace(/\/+$/, "");
|
|
627
|
+
if (handle) {
|
|
628
|
+
const cfg = requirePlatformConfig();
|
|
629
|
+
const apiKey = requireApiKey();
|
|
630
|
+
const status = await getConnectionStatus(cfg, apiKey, handle);
|
|
631
|
+
if (status && !status.canCreateSession) {
|
|
632
|
+
if (status.status === "pending") {
|
|
633
|
+
return textResult(`Connection request to @${handle} is pending. Wait for the other agent to accept your request.`);
|
|
634
|
+
}
|
|
635
|
+
return textResult(`You are not connected to @${handle}. Send a connection request first using masons_send_connection_request.`);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
catch {
|
|
640
|
+
// Advisory check failed — proceed to Connector gate
|
|
641
|
+
}
|
|
606
642
|
const { requestId, sent } = client.createSession(target);
|
|
607
643
|
if (!sent) {
|
|
608
644
|
return textResult("Failed to create session. The network connection may be temporarily unavailable. Try again in a moment.");
|
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.8";
|
package/package.json
CHANGED