@masons/agent-network 0.3.6 → 0.3.7

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 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: GatewayRuntime;
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>;
@@ -1 +1 @@
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,yBA4NjC,CAAC"}
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;AAwDD,eAAO,MAAM,mBAAmB,EAAE,yBAiTjC,CAAC"}
package/dist/channel.js CHANGED
@@ -1,6 +1,6 @@
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");
@@ -89,7 +89,7 @@ export const agentNetworkChannel = {
89
89
  isConfigured(account) {
90
90
  return account.connectorUrl !== "" && account.token !== "";
91
91
  },
92
- isEnabled(account, cfg) {
92
+ isEnabled(_account, cfg) {
93
93
  const networkCfg = extractNetworkConfig(cfg);
94
94
  return networkCfg?.enabled !== false;
95
95
  },
@@ -97,7 +97,7 @@ export const agentNetworkChannel = {
97
97
  outbound: {
98
98
  deliveryMode: "direct",
99
99
  async sendText(ctx) {
100
- // ctx.recipient = sessionId — Gateway echoes back the senderId from routeMessage
100
+ // ctx.recipient = sessionId — Gateway echoes back SenderId from finalizeInboundContext
101
101
  const state = accounts.get(ctx.accountId);
102
102
  if (!state?.sessions.has(ctx.recipient)) {
103
103
  return { ok: false };
@@ -112,12 +112,6 @@ export const agentNetworkChannel = {
112
112
  gateway: {
113
113
  async startAccount(ctx) {
114
114
  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
115
  const { connectorUrl, token } = ctx.account;
122
116
  const client = new ConnectorClient(connectorUrl, token);
123
117
  const state = {
@@ -125,28 +119,102 @@ export const agentNetworkChannel = {
125
119
  sessions: new Map(),
126
120
  };
127
121
  accounts.set(ctx.accountId, state);
128
- // --- Inbound message routing ---
129
- client.on("message_received", (event) => {
122
+ // --- Inbound message routing (4-step channelRuntime dispatch) ---
123
+ // Replaces the non-existent routeMessage() API. Uses PluginRuntime
124
+ // captured in register() via config.ts module-level singleton.
125
+ // Reference: DingTalk plugin (github.com/soimy/openclaw-channel-dingtalk).
126
+ //
127
+ // Concurrency model: this handler is async but EventEmitter fires it
128
+ // synchronously per event. Multiple MESSAGE_RECEIVED on the same session
129
+ // produce concurrent dispatches — replies may arrive out of order.
130
+ // Acceptable for unstructured text conversation (Phase 1). If MSTP adds
131
+ // structured multi-step interactions, add a per-session dispatch queue.
132
+ client.on("message_received", async (event) => {
130
133
  dbg("routing inbound message sessionId=%s contentLength=%d", event.sessionId, event.content.length);
131
- const senderId = deriveSenderId(event);
132
- const envelope = {
133
- channelId: "agent-network",
134
- messageId: `mstp:${event.sessionId}:${randomUUID()}`,
135
- senderId,
136
- senderName: deriveSenderName(event),
137
- text: event.content,
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);
134
+ // --- Runtime guard ---
135
+ let runtime;
136
+ try {
137
+ runtime = requirePluginRuntime();
138
+ }
139
+ catch {
140
+ dbg("plugin runtime not available, dropping message sessionId=%s", event.sessionId);
141
+ return;
142
+ }
143
+ // channel is required in our PluginRuntime type but may be absent
144
+ // at runtime on older OpenClaw versions (pre-2026.2.19).
145
+ if (!runtime.channel) {
146
+ dbg("channelRuntime not available, dropping message sessionId=%s", event.sessionId);
147
147
  return;
148
148
  }
149
- ctx.runtime.routeMessage(envelope);
149
+ const senderId = deriveSenderId(event);
150
+ const senderName = deriveSenderName(event);
151
+ try {
152
+ // Step 1 — Resolve agent route (await defensively — may be sync or async)
153
+ const route = await runtime.channel.routing.resolveAgentRoute({
154
+ cfg: ctx.cfg,
155
+ channel: "agent-network",
156
+ accountId: ctx.accountId,
157
+ peer: { kind: "direct", id: senderId },
158
+ });
159
+ // Step 2 — Finalize inbound context (builds MsgContext for LLM pipeline)
160
+ const msgCtx = runtime.channel.reply.finalizeInboundContext({
161
+ Body: event.content,
162
+ RawBody: event.content,
163
+ CommandBody: event.content,
164
+ From: senderId,
165
+ To: senderId,
166
+ SessionKey: route.sessionKey,
167
+ AccountId: ctx.accountId,
168
+ ChatType: "direct",
169
+ SenderName: senderName,
170
+ SenderId: senderId,
171
+ Timestamp: Date.now(),
172
+ Provider: "agent-network",
173
+ Surface: "agent-network",
174
+ MessageSid: `mstp:${event.sessionId}:${randomUUID()}`,
175
+ CommandAuthorized: true,
176
+ OriginatingChannel: "agent-network",
177
+ OriginatingTo: senderId,
178
+ });
179
+ // Step 3 — Record inbound session
180
+ const storePath = runtime.channel.session.resolveStorePath(undefined, { agentId: route.agentId });
181
+ const sessionKey = typeof msgCtx.SessionKey === "string"
182
+ ? msgCtx.SessionKey
183
+ : route.sessionKey;
184
+ await runtime.channel.session.recordInboundSession({
185
+ storePath,
186
+ sessionKey,
187
+ ctx: msgCtx,
188
+ });
189
+ // Step 4 — Dispatch to LLM pipeline + deliver reply via callback
190
+ await runtime.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
191
+ ctx: msgCtx,
192
+ cfg: ctx.cfg,
193
+ dispatcherOptions: {
194
+ deliver: async (payload) => {
195
+ const text = payload.text;
196
+ if (!text)
197
+ return;
198
+ // Session may have ended while LLM was processing.
199
+ // Skip the send to avoid a needless Connector round-trip.
200
+ if (!state.sessions.has(senderId))
201
+ return;
202
+ // Send LLM reply back through the MSTP session.
203
+ // senderId === sessionId (deriveSenderId invariant).
204
+ const sent = state.client.sendMessage(senderId, text, {
205
+ contentType: "text",
206
+ });
207
+ dbg("deliver reply sessionId=%s contentLength=%d sent=%s", senderId, text.length, sent);
208
+ },
209
+ onError: (err) => {
210
+ console.error(`[agent-network:${ctx.accountId}] dispatch error:`, err);
211
+ },
212
+ },
213
+ });
214
+ }
215
+ catch (err) {
216
+ console.error(`[agent-network:${ctx.accountId}] inbound dispatch failed sessionId=${event.sessionId}:`, err);
217
+ }
150
218
  });
151
219
  // --- Session lifecycle ---
152
220
  client.on("session_created", (event) => {
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
@@ -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;AAuB9B;;;;;;;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;;;;;;;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,CAKvC"}
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
  }
package/dist/plugin.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  interface OpenClawPluginApi {
2
+ runtime: unknown;
2
3
  registerChannel(opts: {
3
4
  plugin: unknown;
4
5
  }): void;
@@ -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;CAuGhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
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/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Plugin version — must match package.json. Validated by prepublishOnly. */
2
- export declare const PLUGIN_VERSION = "0.3.6";
2
+ export declare const PLUGIN_VERSION = "0.3.7";
3
3
  //# sourceMappingURL=version.d.ts.map
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.6";
2
+ export const PLUGIN_VERSION = "0.3.7";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masons/agent-network",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
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)",